2007-03-28 07:08:18 +00:00
#!BPY
"""
Name : ' Autodesk FBX (.fbx)... '
Blender : 243
Group : ' Export '
Tooltip : ' Selection to an ASCII Autodesk FBX '
"""
2007-03-31 12:23:46 +00:00
__author__ = " Campbell Barton "
2007-03-28 07:08:18 +00:00
__url__ = [ ' www.blender.org ' , ' blenderartists.org ' ]
__version__ = " 1.1 "
__bpydoc__ = """ \
This script is an exporter to the FBX file format .
Usage :
Select the objects you wish to export and run this script from " File->Export " menu .
All objects that can be represented as a mesh ( mesh , curve , metaball , surface , text3d )
will be exported as mesh data .
"""
# --------------------------------------------------------------------------
# FBX Export v0.1 by Campbell Barton (AKA Ideasman)
# --------------------------------------------------------------------------
# ***** 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 *****
# --------------------------------------------------------------------------
import Blender
2007-04-20 18:48:30 +00:00
import BPyObject
2007-03-28 07:08:18 +00:00
import BPyMesh
2007-04-19 20:58:09 +00:00
import BPySys
2007-03-29 17:51:32 +00:00
import BPyMessages
2007-03-28 07:08:18 +00:00
import time
2007-04-05 17:55:07 +00:00
from math import degrees
2007-03-28 07:08:18 +00:00
# Used to add the scene name into the filename without using odd chars
sane_name_mapping_ob = { }
sane_name_mapping_mat = { }
sane_name_mapping_tex = { }
2007-04-20 18:48:30 +00:00
sane_name_mapping_arm = { }
2007-03-28 07:08:18 +00:00
2007-04-20 18:48:30 +00:00
def strip_path ( p ) :
return p . split ( ' \\ ' ) [ - 1 ] . split ( ' / ' ) [ - 1 ]
def sane_name ( data , dct ) :
if not data : return None
name = data . name
try : return dct [ name ]
except : pass
orig_name = name
name = BPySys . cleanName ( name )
dct [ orig_name ] = name
return name
def sane_obname ( data ) :
return sane_name ( data , sane_name_mapping_ob )
def sane_matname ( data ) :
return sane_name ( data , sane_name_mapping_mat )
def sane_texname ( data ) :
return sane_name ( data , sane_name_mapping_tex )
def sane_armname ( data ) :
return sane_name ( data , sane_name_mapping_arm )
# May use this later
"""
# Auto class, use for datastorage only, a like a dictionary but with limited slots
def auto_class ( slots ) :
exec ( ' class container_class(object): __slots__= %s ' % slots )
return container_class
"""
header_comment = \
''' ; FBX 6.1.0 project file
; Created by Blender FBX Exporter
; for support mail cbarton @metavr.com
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'''
def write_header ( file ) :
file . write ( header_comment )
curtime = time . localtime ( ) [ 0 : 6 ]
#
file . write ( \
''' FBXHeaderExtension: {
FBXHeaderVersion : 1003
FBXVersion : 6100
CreationTimeStamp : {
Version : 1000
Year : % .4 i
Month : % .2 i
Day : % .2 i
Hour : % .2 i
Minute : % .2 i
Second : % .2 i
Millisecond : 0
2007-03-28 07:08:18 +00:00
}
2007-04-20 18:48:30 +00:00
Creator : " FBX SDK/FBX Plugins build 20070228 "
OtherFlags : {
FlagPLE : 0
2007-03-28 07:08:18 +00:00
}
2007-04-21 11:23:45 +00:00
} ''' % (curtime))
2007-04-20 18:48:30 +00:00
2007-04-21 11:23:45 +00:00
file . write ( ' \n CreationTime: " %.4i - %.2i - %.2i %.2i : %.2i : %.2i :000 " ' % curtime )
file . write ( ' \n Creator: " Blender3D version %.2f " ' % Blender . Get ( ' version ' ) )
2007-04-20 18:48:30 +00:00
def write_scene ( file , sce , world ) :
2007-04-21 11:23:45 +00:00
def write_object_tx ( ob , loc , matrix ) :
2007-04-20 23:33:56 +00:00
'''
We have loc to set the location if non blender objects that have a location
'''
2007-04-21 11:23:45 +00:00
if ob and not matrix : matrix = ob . matrixWorld
2007-04-20 23:33:56 +00:00
2007-04-21 11:23:45 +00:00
if matrix :
loc = tuple ( matrix . translationPart ( ) )
scale = tuple ( matrix . scalePart ( ) )
# Lamps need to be rotated
if ob and ob . type == ' Lamp ' :
matrix = Blender . Mathutils . RotationMatrix ( 90 , 4 , ' x ' ) * matrix
rot = tuple ( matrix . rotationPart ( ) . toEuler ( ) )
2007-04-20 23:33:56 +00:00
else :
2007-04-21 11:23:45 +00:00
if not loc :
loc = 0 , 0 , 0
scale = 1 , 1 , 1
rot = 0 , 0 , 0
file . write ( ' \n \t \t \t Property: " Lcl Translation " , " Lcl Translation " , " A+ " , %.15f , %.15f , %.15f ' % loc )
file . write ( ' \n \t \t \t Property: " Lcl Rotation " , " Lcl Rotation " , " A+ " , %.15f , %.15f , %.15f ' % rot )
file . write ( ' \n \t \t \t Property: " Lcl Scaling " , " Lcl Scaling " , " A+ " , %.15f , %.15f , %.15f ' % scale )
2007-04-20 23:33:56 +00:00
2007-04-21 11:23:45 +00:00
def write_object_props ( ob = None , loc = None , matrix = None ) :
2007-04-20 23:33:56 +00:00
# if the type is 0 its an empty otherwise its a mesh
# only difference at the moment is one has a color
2007-04-20 18:48:30 +00:00
file . write ( '''
2007-03-28 07:08:18 +00:00
Properties60 : {
Property : " QuaternionInterpolate " , " bool " , " " , 0
2007-04-20 23:33:56 +00:00
Property : " Visibility " , " Visibility " , " A+ " , 1 ''' )
2007-04-21 11:23:45 +00:00
write_object_tx ( ob , loc , matrix )
# Rotation order
# eEULER_XYZ
# eEULER_XZY
# eEULER_YZX
# eEULER_YXZ
# eEULER_ZXY
# eEULER_ZYX
2007-04-20 23:33:56 +00:00
file . write ( '''
2007-03-28 07:08:18 +00:00
Property : " RotationOffset " , " Vector3D " , " " , 0 , 0 , 0
Property : " RotationPivot " , " Vector3D " , " " , 0 , 0 , 0
Property : " ScalingOffset " , " Vector3D " , " " , 0 , 0 , 0
Property : " ScalingPivot " , " Vector3D " , " " , 0 , 0 , 0
Property : " TranslationActive " , " bool " , " " , 0
Property : " TranslationMin " , " Vector3D " , " " , 0 , 0 , 0
Property : " TranslationMax " , " Vector3D " , " " , 0 , 0 , 0
Property : " TranslationMinX " , " bool " , " " , 0
Property : " TranslationMinY " , " bool " , " " , 0
Property : " TranslationMinZ " , " bool " , " " , 0
Property : " TranslationMaxX " , " bool " , " " , 0
Property : " TranslationMaxY " , " bool " , " " , 0
Property : " TranslationMaxZ " , " bool " , " " , 0
2007-04-21 11:23:45 +00:00
Property : " RotationOrder " , " enum " , " " , 1
2007-03-28 07:08:18 +00:00
Property : " RotationSpaceForLimitOnly " , " bool " , " " , 0
Property : " AxisLen " , " double " , " " , 10
Property : " PreRotation " , " Vector3D " , " " , 0 , 0 , 0
Property : " PostRotation " , " Vector3D " , " " , 0 , 0 , 0
Property : " RotationActive " , " bool " , " " , 0
Property : " RotationMin " , " Vector3D " , " " , 0 , 0 , 0
Property : " RotationMax " , " Vector3D " , " " , 0 , 0 , 0
Property : " RotationMinX " , " bool " , " " , 0
Property : " RotationMinY " , " bool " , " " , 0
Property : " RotationMinZ " , " bool " , " " , 0
Property : " RotationMaxX " , " bool " , " " , 0
Property : " RotationMaxY " , " bool " , " " , 0
Property : " RotationMaxZ " , " bool " , " " , 0
Property : " RotationStiffnessX " , " double " , " " , 0
Property : " RotationStiffnessY " , " double " , " " , 0
Property : " RotationStiffnessZ " , " double " , " " , 0
Property : " MinDampRangeX " , " double " , " " , 0
Property : " MinDampRangeY " , " double " , " " , 0
Property : " MinDampRangeZ " , " double " , " " , 0
Property : " MaxDampRangeX " , " double " , " " , 0
Property : " MaxDampRangeY " , " double " , " " , 0
Property : " MaxDampRangeZ " , " double " , " " , 0
Property : " MinDampStrengthX " , " double " , " " , 0
Property : " MinDampStrengthY " , " double " , " " , 0
Property : " MinDampStrengthZ " , " double " , " " , 0
Property : " MaxDampStrengthX " , " double " , " " , 0
Property : " MaxDampStrengthY " , " double " , " " , 0
Property : " MaxDampStrengthZ " , " double " , " " , 0
Property : " PreferedAngleX " , " double " , " " , 0
Property : " PreferedAngleY " , " double " , " " , 0
Property : " PreferedAngleZ " , " double " , " " , 0
Property : " InheritType " , " enum " , " " , 0
Property : " ScalingActive " , " bool " , " " , 0
Property : " ScalingMin " , " Vector3D " , " " , 1 , 1 , 1
Property : " ScalingMax " , " Vector3D " , " " , 1 , 1 , 1
Property : " ScalingMinX " , " bool " , " " , 0
Property : " ScalingMinY " , " bool " , " " , 0
Property : " ScalingMinZ " , " bool " , " " , 0
Property : " ScalingMaxX " , " bool " , " " , 0
Property : " ScalingMaxY " , " bool " , " " , 0
Property : " ScalingMaxZ " , " bool " , " " , 0
Property : " GeometricTranslation " , " Vector3D " , " " , 0 , 0 , 0
Property : " GeometricRotation " , " Vector3D " , " " , 0 , 0 , 0
Property : " GeometricScaling " , " Vector3D " , " " , 1 , 1 , 1
Property : " LookAtProperty " , " object " , " "
Property : " UpVectorProperty " , " object " , " "
2007-04-20 23:33:56 +00:00
Property : " Show " , " bool " , " " , 1
2007-03-28 07:08:18 +00:00
Property : " NegativePercentShapeSupport " , " bool " , " " , 1
2007-04-20 23:33:56 +00:00
Property : " DefaultAttributeIndex " , " int " , " " , 0 ''' )
if ob :
# Only mesh objects have color
file . write ( ' \n \t \t \t Property: " Color " , " Color " , " A " ,0.8,0.8,0.8 ' )
file . write ( ' \n \t \t \t Property: " Size " , " double " , " " ,100 ' )
file . write ( ' \n \t \t \t Property: " Look " , " enum " , " " ,1 ' )
def write_camera_switch ( ) :
file . write ( '''
Model : " Model::Camera Switcher " , " CameraSwitcher " {
2007-04-21 11:23:45 +00:00
Version : 232 ''' )
2007-04-20 23:33:56 +00:00
write_object_props ( )
file . write ( '''
2007-03-28 07:08:18 +00:00
Property : " Color " , " Color " , " A " , 0.8 , 0.8 , 0.8
2007-04-20 18:48:30 +00:00
Property : " Camera Index " , " Integer " , " A+ " , 100
2007-03-28 07:08:18 +00:00
}
MultiLayer : 0
2007-04-20 18:48:30 +00:00
MultiTake : 1
2007-03-28 07:08:18 +00:00
Hidden : " True "
2007-04-20 18:48:30 +00:00
Shading : W
2007-03-28 07:08:18 +00:00
Culling : " CullingOff "
2007-04-20 18:48:30 +00:00
Version : 101
Name : " Model::Camera Switcher "
CameraId : 0
CameraName : 100
CameraIndexName :
2007-03-28 07:08:18 +00:00
} ''' )
2007-04-20 18:48:30 +00:00
def write_camera ( name , loc , near , far , proj_type , up ) :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t Model: " Model:: %s " , " Camera " { ' % name )
file . write ( ' \n \t \t Version: 232 ' )
2007-04-20 23:33:56 +00:00
write_object_props ( None , loc )
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t \t \t Property: " Color " , " Color " , " A " ,0.8,0.8,0.8 ' )
file . write ( ' \n \t \t \t Property: " Roll " , " Roll " , " A+ " ,0 ' )
file . write ( ' \n \t \t \t Property: " FieldOfView " , " FieldOfView " , " A+ " ,40 ' )
file . write ( ' \n \t \t \t Property: " FieldOfViewX " , " FieldOfView " , " A+ " ,1 ' )
file . write ( ' \n \t \t \t Property: " FieldOfViewY " , " FieldOfView " , " A+ " ,1 ' )
file . write ( ' \n \t \t \t Property: " OpticalCenterX " , " Real " , " A+ " ,0 ' )
file . write ( ' \n \t \t \t Property: " OpticalCenterY " , " Real " , " A+ " ,0 ' )
file . write ( ' \n \t \t \t Property: " BackgroundColor " , " Color " , " A+ " ,0.63,0.63,0.63 ' )
file . write ( ' \n \t \t \t Property: " TurnTable " , " Real " , " A+ " ,0 ' )
file . write ( ' \n \t \t \t Property: " DisplayTurnTableIcon " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " Motion Blur Intensity " , " Real " , " A+ " ,1 ' )
file . write ( ' \n \t \t \t Property: " UseMotionBlur " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " UseRealTimeMotionBlur " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " ResolutionMode " , " enum " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " ApertureMode " , " enum " , " " ,2 ' )
file . write ( ' \n \t \t \t Property: " GateFit " , " enum " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " FocalLength " , " Real " , " A+ " ,21.3544940948486 ' )
file . write ( ' \n \t \t \t Property: " CameraFormat " , " enum " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " AspectW " , " double " , " " ,320 ' )
file . write ( ' \n \t \t \t Property: " AspectH " , " double " , " " ,200 ' )
file . write ( ' \n \t \t \t Property: " PixelAspectRatio " , " double " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " UseFrameColor " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " FrameColor " , " ColorRGB " , " " ,0.3,0.3,0.3 ' )
file . write ( ' \n \t \t \t Property: " ShowName " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " ShowGrid " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " ShowOpticalCenter " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " ShowAzimut " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " ShowTimeCode " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " NearPlane " , " double " , " " , %.6f ' % near )
file . write ( ' \n \t \t \t Property: " FarPlane " , " double " , " " , %.6f ' % far )
file . write ( ' \n \t \t \t Property: " FilmWidth " , " double " , " " ,0.816 ' )
file . write ( ' \n \t \t \t Property: " FilmHeight " , " double " , " " ,0.612 ' )
file . write ( ' \n \t \t \t Property: " FilmAspectRatio " , " double " , " " ,1.33333333333333 ' )
file . write ( ' \n \t \t \t Property: " FilmSqueezeRatio " , " double " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " FilmFormatIndex " , " enum " , " " ,4 ' )
file . write ( ' \n \t \t \t Property: " ViewFrustum " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " ViewFrustumNearFarPlane " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " ViewFrustumBackPlaneMode " , " enum " , " " ,2 ' )
file . write ( ' \n \t \t \t Property: " BackPlaneDistance " , " double " , " " ,100 ' )
file . write ( ' \n \t \t \t Property: " BackPlaneDistanceMode " , " enum " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " ViewCameraToLookAt " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " LockMode " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " LockInterestNavigation " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " FitImage " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " Crop " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " Center " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " KeepRatio " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " BackgroundMode " , " enum " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " BackgroundAlphaTreshold " , " double " , " " ,0.5 ' )
file . write ( ' \n \t \t \t Property: " ForegroundTransparent " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " DisplaySafeArea " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " SafeAreaDisplayStyle " , " enum " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " SafeAreaAspectRatio " , " double " , " " ,1.33333333333333 ' )
file . write ( ' \n \t \t \t Property: " Use2DMagnifierZoom " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " 2D Magnifier Zoom " , " Real " , " A+ " ,100 ' )
file . write ( ' \n \t \t \t Property: " 2D Magnifier X " , " Real " , " A+ " ,50 ' )
file . write ( ' \n \t \t \t Property: " 2D Magnifier Y " , " Real " , " A+ " ,50 ' )
file . write ( ' \n \t \t \t Property: " CameraProjectionType " , " enum " , " " , %i ' % proj_type )
file . write ( ' \n \t \t \t Property: " UseRealTimeDOFAndAA " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " UseDepthOfField " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " FocusSource " , " enum " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " FocusAngle " , " double " , " " ,3.5 ' )
file . write ( ' \n \t \t \t Property: " FocusDistance " , " double " , " " ,200 ' )
file . write ( ' \n \t \t \t Property: " UseAntialiasing " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " AntialiasingIntensity " , " double " , " " ,0.77777 ' )
file . write ( ' \n \t \t \t Property: " UseAccumulationBuffer " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " FrameSamplingCount " , " int " , " " ,7 ' )
file . write ( ' \n \t \t } ' )
file . write ( ' \n \t \t MultiLayer: 0 ' )
file . write ( ' \n \t \t MultiTake: 0 ' )
file . write ( ' \n \t \t Hidden: " True " ' )
file . write ( ' \n \t \t Shading: Y ' )
file . write ( ' \n \t \t Culling: " CullingOff " ' )
file . write ( ' \n \t \t TypeFlags: " Camera " ' )
file . write ( ' \n \t \t GeometryVersion: 124 ' )
file . write ( ' \n \t \t Position: %.6f , %.6f , %.6f ' % loc )
file . write ( ' \n \t \t Up: %i , %i , %i ' % up )
file . write ( ' \n \t \t LookAt: 0,0,0 ' )
file . write ( ' \n \t \t ShowInfoOnMoving: 1 ' )
file . write ( ' \n \t \t ShowAudio: 0 ' )
file . write ( ' \n \t \t AudioColor: 0,1,0 ' )
file . write ( ' \n \t \t CameraOrthoZoom: 1 ' )
file . write ( ' \n \t } ' )
2007-04-20 18:48:30 +00:00
def write_camera_default ( ) :
# This sucks but to match FBX converter its easier to
# write the cameras though they are not needed.
2007-04-20 23:33:56 +00:00
write_camera ( ' Producer Perspective ' , ( 0 , 71.3 , 287.5 ) , 10 , 4000 , 0 , ( 0 , 1 , 0 ) )
write_camera ( ' Producer Top ' , ( 0 , 4000 , 0 ) , 1 , 30000 , 1 , ( 0 , 0 , - 1 ) )
write_camera ( ' Producer Bottom ' , ( 0 , - 4000 , 0 ) , 1 , 30000 , 1 , ( 0 , 0 , - 1 ) )
write_camera ( ' Producer Front ' , ( 0 , 0 , 4000 ) , 1 , 30000 , 1 , ( 0 , 1 , 0 ) )
write_camera ( ' Producer Back ' , ( 0 , 0 , - 4000 ) , 1 , 30000 , 1 , ( 0 , 1 , 0 ) )
write_camera ( ' Producer Right ' , ( 4000 , 0 , 0 ) , 1 , 30000 , 1 , ( 0 , 1 , 0 ) )
write_camera ( ' Producer Left ' , ( - 4000 , 0 , 0 ) , 1 , 30000 , 1 , ( 0 , 1 , 0 ) )
2007-03-28 07:08:18 +00:00
2007-04-20 23:33:56 +00:00
def write_light ( ob , name ) :
light = ob . data
file . write ( ' \n \t Model: " Model:: %s " , " Light " { ' % name )
file . write ( ' \n \t \t Version: 232 ' )
2007-04-05 17:55:07 +00:00
2007-04-20 23:33:56 +00:00
write_object_props ( ob )
2007-04-05 17:55:07 +00:00
2007-04-20 23:33:56 +00:00
# Why are these values here twice?????? - oh well, follow the holy sdk's output
2007-03-28 07:08:18 +00:00
2007-04-20 23:33:56 +00:00
# Blender light types match FBX's, funny coincidence, we just need to
# be sure that all unsupported types are made into a point light
#ePOINT,
#eDIRECTIONAL
#eSPOT
light_type = light . type
if light_type > 3 : light_type = 0
file . write ( ' \n \t \t \t Property: " LightType " , " enum " , " " , %i ' % light_type )
file . write ( ' \n \t \t \t Property: " CastLightOnObject " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " DrawVolumetricLight " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " DrawGroundProjection " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " DrawFrontFacingVolumetricLight " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " GoboProperty " , " object " , " " ' )
file . write ( ' \n \t \t \t Property: " Color " , " Color " , " A+ " ,1,1,1 ' )
file . write ( ' \n \t \t \t Property: " Intensity " , " Intensity " , " A+ " , %.2f ' % ( light . energy * 100 ) )
file . write ( ' \n \t \t \t Property: " Cone angle " , " Cone angle " , " A+ " , %.2f ' % light . spotSize )
file . write ( ' \n \t \t \t Property: " Fog " , " Fog " , " A+ " ,50 ' )
file . write ( ' \n \t \t \t Property: " Color " , " Color " , " A " , %.2f , %.2f , %.2f ' % tuple ( light . col ) )
file . write ( ' \n \t \t \t Property: " Intensity " , " Intensity " , " A+ " , %.2f ' % ( light . energy * 100 ) )
file . write ( ' \n \t \t \t Property: " Cone angle " , " Cone angle " , " A+ " , %.2f ' % light . spotSize )
file . write ( ' \n \t \t \t Property: " Fog " , " Fog " , " A+ " ,50 ' )
file . write ( ' \n \t \t \t Property: " LightType " , " enum " , " " , %i ' % light_type )
file . write ( ' \n \t \t \t Property: " CastLightOnObject " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " DrawGroundProjection " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " DrawFrontFacingVolumetricLight " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " DrawVolumetricLight " , " bool " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " GoboProperty " , " object " , " " ' )
file . write ( ' \n \t \t \t Property: " DecayType " , " enum " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " DecayStart " , " double " , " " , %.2f ' % light . dist )
file . write ( ' \n \t \t \t Property: " EnableNearAttenuation " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " NearAttenuationStart " , " double " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " NearAttenuationEnd " , " double " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " EnableFarAttenuation " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " FarAttenuationStart " , " double " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " FarAttenuationEnd " , " double " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " CastShadows " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " ShadowColor " , " ColorRGBA " , " " ,0,0,0,1 ' )
file . write ( ' \n \t \t } ' )
file . write ( ' \n \t \t MultiLayer: 0 ' )
file . write ( ' \n \t \t MultiTake: 0 ' )
file . write ( ' \n \t \t Shading: Y ' )
file . write ( ' \n \t \t Culling: " CullingOff " ' )
file . write ( ' \n \t \t TypeFlags: " Light " ' )
file . write ( ' \n \t \t GeometryVersion: 124 ' )
file . write ( ' \n \t } ' )
2007-03-28 07:08:18 +00:00
# Material Settings
if world :
world_amb = world . getAmb ( )
else :
world_amb = ( 0 , 0 , 0 ) # Default value
def write_material ( matname , mat ) :
2007-04-19 17:27:18 +00:00
file . write ( ' \n \t Material: " Material:: %s " , " " { ' % matname )
2007-03-28 07:08:18 +00:00
# Todo, add more material Properties.
if mat :
mat_cold = tuple ( mat . rgbCol )
2007-04-19 17:27:18 +00:00
mat_cols = tuple ( mat . specCol )
#mat_colm = tuple(mat.mirCol)
mat_colamb = tuple ( [ c for c in world_amb ] )
mat_dif = mat . ref
mat_amb = mat . amb
mat_hard = ( float ( mat . hard ) - 1 ) / 5.10
mat_spec = mat . spec / 2.0
mat_alpha = mat . alpha
mat_shadeless = mat . mode & Blender . Material . Modes . SHADELESS
if mat_shadeless :
mat_shader = ' Lambert '
else :
if mat . diffuseShader == Blender . Material . Shaders . DIFFUSE_LAMBERT :
mat_shader = ' Lambert '
else :
mat_shader = ' Phong '
2007-03-28 07:08:18 +00:00
else :
mat_cols = mat_cold = 0.8 , 0.8 , 0.8
2007-04-19 17:27:18 +00:00
mat_colamb = 0.0 , 0.0 , 0.0
# mat_colm
mat_dif = 1.0
mat_amb = 0.5
mat_hard = 20.0
mat_spec = 0.2
mat_alpha = 1.0
mat_shadeless = False
mat_shader = ' Phong '
2007-03-28 07:08:18 +00:00
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t \t Version: 102 ' )
file . write ( ' \n \t \t ShadingModel: " %s " ' % mat_shader . lower ( ) )
file . write ( ' \n \t \t MultiLayer: 0 ' )
file . write ( ' \n \t \t Properties60: { ' )
file . write ( ' \n \t \t \t Property: " ShadingModel " , " KString " , " " , " %s " ' % mat_shader )
file . write ( ' \n \t \t \t Property: " MultiLayer " , " bool " , " " ,0 ' )
file . write ( ' \n \t \t \t Property: " EmissiveColor " , " ColorRGB " , " " ,0,0,0 ' )
file . write ( ' \n \t \t \t Property: " EmissiveFactor " , " double " , " " ,1 ' )
2007-04-19 17:27:18 +00:00
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t \t \t Property: " AmbientColor " , " ColorRGB " , " " , %.1f , %.1f , %.1f ' % mat_colamb )
file . write ( ' \n \t \t \t Property: " AmbientFactor " , " double " , " " , %.1f ' % mat_amb )
file . write ( ' \n \t \t \t Property: " DiffuseColor " , " ColorRGB " , " " , %.1f , %.1f , %.1f ' % mat_cold )
file . write ( ' \n \t \t \t Property: " DiffuseFactor " , " double " , " " , %.1f ' % mat_dif )
file . write ( ' \n \t \t \t Property: " Bump " , " Vector3D " , " " ,0,0,0 ' )
file . write ( ' \n \t \t \t Property: " TransparentColor " , " ColorRGB " , " " ,1,1,1 ' )
file . write ( ' \n \t \t \t Property: " TransparencyFactor " , " double " , " " ,0 ' )
2007-04-19 17:27:18 +00:00
if not mat_shadeless :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t \t \t Property: " SpecularColor " , " ColorRGB " , " " , %.1f , %.1f , %.1f ' % mat_cols )
file . write ( ' \n \t \t \t Property: " SpecularFactor " , " double " , " " , %.1f ' % mat_spec )
file . write ( ' \n \t \t \t Property: " ShininessExponent " , " double " , " " ,80.0 ' )
file . write ( ' \n \t \t \t Property: " ReflectionColor " , " ColorRGB " , " " ,0,0,0 ' )
file . write ( ' \n \t \t \t Property: " ReflectionFactor " , " double " , " " ,1 ' )
file . write ( ' \n \t \t \t Property: " Emissive " , " Vector3D " , " " ,0,0,0 ' )
file . write ( ' \n \t \t \t Property: " Ambient " , " Vector3D " , " " , %.1f , %.1f , %.1f ' % mat_colamb )
file . write ( ' \n \t \t \t Property: " Diffuse " , " Vector3D " , " " , %.1f , %.1f , %.1f ' % mat_cold )
2007-04-19 17:27:18 +00:00
if not mat_shadeless :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t \t \t Property: " Specular " , " Vector3D " , " " , %.1f , %.1f , %.1f ' % mat_cols )
file . write ( ' \n \t \t \t Property: " Shininess " , " double " , " " , %.1f ' % mat_hard )
file . write ( ' \n \t \t \t Property: " Opacity " , " double " , " " , %.1f ' % mat_alpha )
2007-04-19 17:27:18 +00:00
if not mat_shadeless :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t \t \t Property: " Reflectivity " , " double " , " " ,0 ' )
2007-04-19 17:27:18 +00:00
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t \t } ' )
file . write ( ' \n \t } ' )
2007-03-28 07:08:18 +00:00
def write_video ( texname , tex ) :
# Same as texture really!
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t Video: " Video:: %s " , " Clip " { ' % texname )
2007-03-28 07:08:18 +00:00
file . write ( '''
Type : " Clip "
Properties60 : {
Property : " FrameRate " , " double " , " " , 0
Property : " LastFrame " , " int " , " " , 0
Property : " Width " , " int " , " " , 0
Property : " Height " , " int " , " " , 0 ''' )
if tex :
fname = tex . filename
fname_strip = strip_path ( fname )
else :
fname = fname_strip = ' '
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t \t \t Property: " Path " , " charptr " , " " , " %s " ' % fname_strip )
2007-03-28 07:08:18 +00:00
file . write ( '''
Property : " StartFrame " , " int " , " " , 0
Property : " StopFrame " , " int " , " " , 0
Property : " PlaySpeed " , " double " , " " , 1
Property : " Offset " , " KTime " , " " , 0
Property : " InterlaceMode " , " enum " , " " , 0
Property : " FreeRunning " , " bool " , " " , 0
Property : " Loop " , " bool " , " " , 0
Property : " AccessMode " , " enum " , " " , 0
}
UseMipMap : 0 ''' )
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t \t Filename: " %s " ' % fname_strip )
2007-03-28 07:08:18 +00:00
if fname_strip : fname_strip = ' / ' + fname_strip
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t \t RelativeFilename: " fbx %s " ' % fname_strip ) # make relative
file . write ( ' \n \t } ' )
2007-03-28 07:08:18 +00:00
def write_texture ( texname , tex , num ) :
# if tex == None then this is a dummy tex
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t Texture: " Texture:: %s " , " TextureVideoClip " { ' % texname )
file . write ( ' \n \t \t Type: " TextureVideoClip " ' )
file . write ( ' \n \t \t Version: 202 ' )
2007-03-28 07:08:18 +00:00
# TODO, rare case _empty_ exists as a name.
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t \t TextureName: " Texture:: %s " ' % texname )
2007-03-28 07:08:18 +00:00
file . write ( '''
Properties60 : {
Property : " Translation " , " Vector " , " A+ " , 0 , 0 , 0
Property : " Rotation " , " Vector " , " A+ " , 0 , 0 , 0
Property : " Scaling " , " Vector " , " A+ " , 1 , 1 , 1 ''' )
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t \t \t Property: " Texture alpha " , " Number " , " A+ " , %i ' % num )
2007-03-28 07:08:18 +00:00
file . write ( '''
Property : " TextureTypeUse " , " enum " , " " , 0
Property : " CurrentTextureBlendMode " , " enum " , " " , 1
Property : " UseMaterial " , " bool " , " " , 0
Property : " UseMipMap " , " bool " , " " , 0
Property : " CurrentMappingType " , " enum " , " " , 0
Property : " UVSwap " , " bool " , " " , 0
Property : " WrapModeU " , " enum " , " " , 0
Property : " WrapModeV " , " enum " , " " , 0
Property : " TextureRotationPivot " , " Vector3D " , " " , 0 , 0 , 0
Property : " TextureScalingPivot " , " Vector3D " , " " , 0 , 0 , 0
Property : " VideoProperty " , " object " , " "
} ''' )
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t \t Media: " Video:: %s " ' % texname )
2007-03-28 07:08:18 +00:00
if tex :
fname = tex . filename
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t \t FileName: " %s " ' % strip_path ( fname ) )
file . write ( ' \n \t \t RelativeFilename: " fbx/ %s " ' % strip_path ( fname ) ) # need some make relative command
2007-03-28 07:08:18 +00:00
else :
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t \t FileName: " " ' )
file . write ( ' \n \t \t RelativeFilename: " fbx " ' )
2007-03-28 07:08:18 +00:00
file . write ( '''
ModelUVTranslation : 0 , 0
ModelUVScaling : 1 , 1
Texture_Alpha_Source : " None "
Cropping : 0 , 0 , 0 , 0
} ''' )
2007-04-20 23:33:56 +00:00
ob_meshes = [ ]
ob_lights = [ ]
2007-03-28 07:08:18 +00:00
materials = { }
textures = { }
2007-04-20 18:48:30 +00:00
armatures = [ ] # We should export standalone armatures also
armatures_totbones = 0 # we need this because each bone is a model
2007-04-21 11:23:45 +00:00
for ob_base in sce . objects . context :
for ob , mtx in BPyObject . getDerivedObjects ( ob_base ) :
#for ob in [ob_base,]:
ob_type = ob . type
2007-04-20 18:48:30 +00:00
2007-04-21 11:23:45 +00:00
if ob_type == ' Lamp ' :
ob_lights . append ( ( sane_obname ( ob ) , ob ) )
else :
if ob_type == ' Mesh ' : me = ob . getData ( mesh = 1 )
else : me = BPyMesh . getMeshFromObject ( ob )
2007-04-20 23:33:56 +00:00
2007-04-21 11:23:45 +00:00
if me :
mats = me . materials
for mat in mats :
# 2.44 use mat.lib too for uniqueness
if mat : materials [ mat . name ] = mat
if me . faceUV :
uvlayer_orig = me . activeUVLayer
for uvlayer in me . getUVLayerNames ( ) :
me . activeUVLayer = uvlayer
for f in me . faces :
img = f . image
if img : textures [ img . name ] = img
me . activeUVLayer = uvlayer_orig
arm = BPyObject . getObjectArmature ( ob )
if arm :
armname = sane_armname ( arm )
bones = arm . bones . values ( )
armatures_totbones + = len ( bones )
armatures . append ( ( arm , armname , bones ) )
else :
armname = None
#### me.transform(ob.matrixWorld) # Export real ob coords.
#### High Quality, not realy needed for now.
#BPyMesh.meshCalcNormals(me) # high quality normals nice for realtime engines.
ob_meshes . append ( ( sane_obname ( ob ) , ob , mtx , me , mats , arm , armname ) )
2007-04-20 23:33:56 +00:00
del ob_type
2007-03-28 07:08:18 +00:00
2007-04-20 18:48:30 +00:00
materials = [ ( sane_matname ( mat ) , mat ) for mat in materials . itervalues ( ) ]
textures = [ ( sane_texname ( img ) , img ) for img in textures . itervalues ( ) ]
2007-03-28 07:08:18 +00:00
materials . sort ( ) # sort by name
textures . sort ( )
if not materials :
materials = [ ( ' null ' , None ) ]
material_mapping = { } # blen name : index
if textures :
texture_mapping_local = { None : 0 } # ditto
i = 0
for texname , tex in textures :
texture_mapping_local [ tex . name ] = i
i + = 1
textures . insert ( 0 , ( ' _empty_ ' , None ) )
i = 0
for matname , mat in materials :
2007-03-29 06:01:03 +00:00
if mat : mat = mat . name
material_mapping [ mat ] = i
2007-03-28 07:08:18 +00:00
i + = 1
2007-04-21 11:23:45 +00:00
2007-03-28 07:08:18 +00:00
camera_count = 8
2007-04-21 11:23:45 +00:00
file . write ( '''
2007-03-28 07:08:18 +00:00
; Object definitions
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Definitions : {
Version : 100
2007-04-20 23:33:56 +00:00
Count : % i ''' % (1+1+camera_count+len(ob_meshes)+len(ob_lights)+len(armatures)+armatures_totbones+len(materials)+(len(textures)*2))) # add 1 for the root model 1 for global settings
2007-03-28 07:08:18 +00:00
file . write ( '''
ObjectType : " Model " {
Count : % i
2007-04-20 23:33:56 +00:00
} ''' % (1+camera_count+len(ob_meshes)+len(ob_lights)+len(armatures)+armatures_totbones)) # add 1 for the root model
2007-03-28 07:08:18 +00:00
file . write ( '''
ObjectType : " Geometry " {
Count : % i
2007-04-20 23:33:56 +00:00
} ''' % le n(ob_meshes))
2007-03-28 07:08:18 +00:00
if materials :
file . write ( '''
ObjectType : " Material " {
Count : % i
} ''' % le n(materials))
if textures :
file . write ( '''
ObjectType : " Texture " {
Count : % i
} ''' % le n(textures)) # add 1 for an empty tex
file . write ( '''
ObjectType : " Video " {
Count : % i
} ''' % le n(textures)) # add 1 for an empty tex
file . write ( '''
ObjectType : " GlobalSettings " {
Count : 1
}
}
''' )
file . write ( \
'''
; Object properties
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Objects : { ''' )
# To comply with other FBX FILES
write_camera_switch ( )
# Write the null object
file . write ( '''
Model : " Model::blend_root " , " Null " {
Version : 232 ''' )
2007-04-20 23:33:56 +00:00
write_object_props ( )
2007-04-21 11:23:45 +00:00
file . write ( '''
}
MultiLayer : 0
2007-03-28 07:08:18 +00:00
MultiTake : 1
Shading : Y
2007-03-29 14:35:01 +00:00
Culling : " CullingOff "
2007-03-28 07:08:18 +00:00
TypeFlags : " Null "
} ''' )
2007-04-20 23:33:56 +00:00
for obname , ob in ob_lights :
write_light ( ob , obname )
2007-04-21 11:23:45 +00:00
for obname , ob , mtx , me , mats , arm , armname in ob_meshes :
file . write ( ' \n \t Model: " Model:: %s " , " Mesh " { ' % sane_obname ( ob ) )
file . write ( ' \n \t \t Version: 232 ' ) # newline is added in write_object_props
write_object_props ( ob , None , mtx )
file . write ( ' \n \t \t } ' )
file . write ( ' \n \t \t MultiLayer: 0 ' )
file . write ( ' \n \t \t MultiTake: 1 ' )
file . write ( ' \n \t \t Shading: Y ' )
file . write ( ' \n \t \t Culling: " CullingOff " ' )
2007-03-28 07:08:18 +00:00
# Write the Real Mesh data here
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t \t Vertices: ' )
2007-03-28 07:08:18 +00:00
i = - 1
for v in me . verts :
if i == - 1 :
file . write ( ' %.6f , %.6f , %.6f ' % tuple ( v . co ) )
i = 0
else :
if i == 7 :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t \t ' )
2007-03-28 07:08:18 +00:00
i = 0
file . write ( ' , %.6f , %.6f , %.6f ' % tuple ( v . co ) )
i + = 1
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t \t PolygonVertexIndex: ' )
2007-03-28 07:08:18 +00:00
i = - 1
for f in me . faces :
fi = [ v . index for v in f ]
# flip the last index, odd but it looks like
# this is how fbx tells one face from another
fi [ - 1 ] = - ( fi [ - 1 ] + 1 )
fi = tuple ( fi )
if i == - 1 :
if len ( f ) == 3 : file . write ( ' %i , %i , %i ' % fi )
else : file . write ( ' %i , %i , %i , %i ' % fi )
i = 0
else :
if i == 13 :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t \t ' )
2007-03-28 07:08:18 +00:00
i = 0
if len ( f ) == 3 : file . write ( ' , %i , %i , %i ' % fi )
else : file . write ( ' , %i , %i , %i , %i ' % fi )
i + = 1
2007-04-21 11:23:45 +00:00
ed_val = [ None , None ]
LOOSE = Blender . Mesh . EdgeFlags . LOOSE
for ed in me . edges :
if ed . flag & LOOSE :
ed_val [ 0 ] = ed . v1 . index
ed_val [ 1 ] = - ( ed . v2 . index + 1 )
if i == - 1 :
file . write ( ' %i , %i ' % tuple ( ed_val ) )
i = 0
else :
if i == 13 :
file . write ( ' \n \t \t ' )
i = 0
file . write ( ' , %i , %i ' % tuple ( ed_val ) )
i + = 1
del LOOSE
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t \t GeometryVersion: 124 ' )
2007-03-28 07:08:18 +00:00
2007-03-29 17:51:32 +00:00
file . write ( '''
2007-03-28 07:08:18 +00:00
LayerElementNormal : 0 {
Version : 101
Name : " "
MappingInformationType : " ByVertice "
ReferenceInformationType : " Direct "
Normals : ''' )
i = - 1
for v in me . verts :
if i == - 1 :
file . write ( ' %.15f , %.15f , %.15f ' % tuple ( v . no ) )
i = 0
else :
if i == 2 :
file . write ( ' \n ' )
i = 0
file . write ( ' , %.15f , %.15f , %.15f ' % tuple ( v . no ) )
i + = 1
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t \t } ' )
2007-03-28 07:08:18 +00:00
2007-03-31 12:23:46 +00:00
# Write VertexColor Layers
collayers = [ ]
if me . vertexColors :
collayers = me . getColorLayerNames ( )
collayer_orig = me . activeColorLayer
for colindex , collayer in enumerate ( collayers ) :
me . activeColorLayer = collayer
file . write ( ' \n \t \t LayerElementColor: %i { ' % colindex )
file . write ( ' \n \t \t \t Version: 101 ' )
file . write ( ' \n \t \t \t Name: " %s " ' % collayer )
file . write ( '''
MappingInformationType : " ByPolygonVertex "
ReferenceInformationType : " IndexToDirect "
Colors : ''' )
i = - 1
ii = 0 # Count how many Colors we write
for f in me . faces :
for col in f . col :
if i == - 1 :
file . write ( ' %i , %i , %i ' % ( col [ 0 ] , col [ 1 ] , col [ 2 ] ) )
i = 0
else :
if i == 7 :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t \t \t \t ' )
2007-03-31 12:23:46 +00:00
i = 0
file . write ( ' , %i , %i , %i ' % ( col [ 0 ] , col [ 1 ] , col [ 2 ] ) )
i + = 1
ii + = 1 # One more Color
file . write ( ' \n \t \t \t ColorIndex: ' )
i = - 1
for j in xrange ( ii ) :
if i == - 1 :
file . write ( ' %i ' % j )
i = 0
else :
if i == 55 :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t \t \t \t ' )
2007-03-31 12:23:46 +00:00
i = 0
file . write ( ' , %i ' % j )
i + = 1
file . write ( ' \n \t \t } ' )
2007-03-29 17:51:32 +00:00
# Write UV and texture layers.
2007-03-31 12:23:46 +00:00
uvlayers = [ ]
2007-03-28 07:08:18 +00:00
if me . faceUV :
2007-03-29 17:51:32 +00:00
uvlayers = me . getUVLayerNames ( )
uvlayer_orig = me . activeUVLayer
for uvindex , uvlayer in enumerate ( uvlayers ) :
me . activeUVLayer = uvlayer
file . write ( ' \n \t \t LayerElementUV: %i { ' % uvindex )
file . write ( ' \n \t \t \t Version: 101 ' )
file . write ( ' \n \t \t \t Name: " %s " ' % uvlayer )
file . write ( '''
2007-03-28 07:08:18 +00:00
MappingInformationType : " ByPolygonVertex "
ReferenceInformationType : " IndexToDirect "
UV : ''' )
2007-03-29 17:51:32 +00:00
i = - 1
ii = 0 # Count how many UVs we write
for f in me . faces :
for uv in f . uv :
if i == - 1 :
file . write ( ' %.6f , %.6f ' % tuple ( uv ) )
i = 0
else :
if i == 7 :
file . write ( ' \n ' )
i = 0
file . write ( ' , %.6f , %.6f ' % tuple ( uv ) )
i + = 1
ii + = 1 # One more UV
2007-03-31 12:23:46 +00:00
file . write ( ' \n \t \t \t UVIndex: ' )
2007-03-29 17:51:32 +00:00
i = - 1
for j in xrange ( ii ) :
if i == - 1 :
file . write ( ' %i ' % j )
2007-03-28 07:08:18 +00:00
i = 0
else :
2007-03-29 17:51:32 +00:00
if i == 55 :
2007-03-31 12:23:46 +00:00
file . write ( ' \n \t \t \t \t ' )
2007-03-28 07:08:18 +00:00
i = 0
2007-03-29 17:51:32 +00:00
file . write ( ' , %i ' % j )
2007-03-28 07:08:18 +00:00
i + = 1
2007-03-29 17:51:32 +00:00
2007-03-31 12:23:46 +00:00
file . write ( ' \n \t \t } ' )
2007-03-29 17:51:32 +00:00
if textures :
file . write ( ' \n \t \t LayerElementTexture: %i { ' % uvindex )
file . write ( ' \n \t \t \t Version: 101 ' )
file . write ( ' \n \t \t \t Name: " %s " ' % uvlayer )
file . write ( '''
MappingInformationType : " ByPolygon "
ReferenceInformationType : " IndexToDirect "
BlendMode : " Translucent "
TextureAlpha : 1
TextureId : ''' )
i = - 1
for f in me . faces :
img_key = f . image
if img_key : img_key = img_key . name
if i == - 1 :
i = 0
file . write ( ' %s ' % texture_mapping_local [ img_key ] )
else :
if i == 55 :
file . write ( ' \n ' )
i = 0
file . write ( ' , %s ' % texture_mapping_local [ img_key ] )
i + = 1
2007-03-29 06:01:03 +00:00
else :
2007-03-29 17:51:32 +00:00
file . write ( '''
LayerElementTexture : 0 {
Version : 101
Name : " "
MappingInformationType : " NoMappingInformation "
ReferenceInformationType : " IndexToDirect "
BlendMode : " Translucent "
TextureAlpha : 1
TextureId : ''' )
file . write ( ' \n \t \t } ' )
2007-03-28 07:08:18 +00:00
2007-03-29 17:51:32 +00:00
me . activeUVLayer = uvlayer_orig
# Done with UV/textures.
2007-03-28 07:08:18 +00:00
if materials :
file . write ( '''
LayerElementMaterial : 0 {
Version : 101
Name : " "
MappingInformationType : " ByPolygon "
ReferenceInformationType : " IndexToDirect "
Materials : ''' )
# Build a material mapping for this
material_mapping_local = { } # local-index : global index.
2007-04-20 18:48:30 +00:00
for i , mat in enumerate ( mats ) :
2007-03-28 07:08:18 +00:00
if mat :
material_mapping_local [ i ] = material_mapping [ mat . name ]
else :
material_mapping_local [ i ] = 0 # None material is zero for now.
if not material_mapping_local :
material_mapping_local [ 0 ] = 0
2007-03-29 06:01:03 +00:00
len_material_mapping_local = len ( material_mapping_local )
2007-03-28 07:08:18 +00:00
i = - 1
for f in me . faces :
2007-04-21 11:23:45 +00:00
f_mat = f . mat
if f_mat > = len_material_mapping_local :
f_mat = 0
2007-03-28 07:08:18 +00:00
if i == - 1 :
i = 0
2007-03-29 06:01:03 +00:00
file . write ( ' %s ' % material_mapping_local [ f_mat ] )
2007-03-28 07:08:18 +00:00
else :
2007-03-29 06:01:03 +00:00
if i == 55 :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t \t \t \t ' )
2007-03-29 06:01:03 +00:00
i = 0
file . write ( ' , %s ' % material_mapping_local [ f_mat ] )
2007-03-28 07:08:18 +00:00
i + = 1
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t \t } ' )
2007-03-28 07:08:18 +00:00
file . write ( '''
Layer : 0 {
Version : 100
LayerElement : {
Type : " LayerElementNormal "
TypedIndex : 0
} ''' )
if materials :
file . write ( '''
LayerElement : {
Type : " LayerElementMaterial "
TypedIndex : 0
} ''' )
# Always write this
if textures :
file . write ( '''
LayerElement : {
Type : " LayerElementTexture "
TypedIndex : 0
} ''' )
2007-03-31 12:23:46 +00:00
if me . vertexColors :
file . write ( '''
LayerElement : {
Type : " LayerElementColor "
TypedIndex : 0
} ''' )
2007-03-28 07:08:18 +00:00
if me . faceUV :
file . write ( '''
LayerElement : {
Type : " LayerElementUV "
TypedIndex : 0
} ''' )
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t \t } ' )
2007-03-31 12:23:46 +00:00
if len ( uvlayers ) > 1 :
2007-03-29 17:51:32 +00:00
for i in xrange ( 1 , len ( uvlayers ) ) :
file . write ( ' \n \t \t Layer: %i { ' % i )
file . write ( ' \n \t \t \t Version: 100 ' )
file . write ( '''
LayerElement : {
Type : " LayerElementUV " ''' )
file . write ( ' \n \t \t \t \t TypedIndex: %i ' % i )
file . write ( ' \n \t \t \t } ' )
if textures :
file . write ( '''
LayerElement : {
Type : " LayerElementTexture " ''' )
file . write ( ' \n \t \t \t \t TypedIndex: %i ' % i )
file . write ( ' \n \t \t \t } ' )
file . write ( ' \n \t \t } ' )
2007-03-31 12:23:46 +00:00
if len ( collayers ) > 1 :
# Take into account any UV layers
layer_offset = 0
if uvlayers : layer_offset = len ( uvlayers ) - 1
for i in xrange ( layer_offset , len ( collayers ) + layer_offset ) :
file . write ( ' \n \t \t Layer: %i { ' % i )
file . write ( ' \n \t \t \t Version: 100 ' )
file . write ( '''
LayerElement : {
Type : " LayerElementColor " ''' )
file . write ( ' \n \t \t \t \t TypedIndex: %i ' % i )
file . write ( ' \n \t \t \t } ' )
file . write ( ' \n \t \t } ' )
2007-03-29 17:51:32 +00:00
file . write ( ' \n \t } ' )
2007-04-20 18:48:30 +00:00
write_camera_default ( )
2007-03-28 07:08:18 +00:00
for matname , mat in materials :
write_material ( matname , mat )
# each texture uses a video, odd
for texname , tex in textures :
write_video ( texname , tex )
i = 0
for texname , tex in textures :
write_texture ( texname , tex , i )
i + = 1
# Finish Writing Objects
# Write global settings
file . write ( '''
GlobalSettings : {
Version : 1000
Properties60 : {
Property : " UpAxis " , " int " , " " , 1
Property : " UpAxisSign " , " int " , " " , 1
Property : " FrontAxis " , " int " , " " , 2
Property : " FrontAxisSign " , " int " , " " , 1
Property : " CoordAxis " , " int " , " " , 0
Property : " CoordAxisSign " , " int " , " " , 1
Property : " UnitScaleFactor " , " double " , " " , 1
}
}
''' )
2007-04-21 11:23:45 +00:00
file . write ( ' } ' )
2007-03-28 07:08:18 +00:00
2007-04-21 11:23:45 +00:00
file . write ( '''
; Object relations
2007-03-28 07:08:18 +00:00
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2007-04-21 11:23:45 +00:00
Relations : { ''' )
2007-03-28 07:08:18 +00:00
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t Model: " Model::blend_root " , " Null " { \n \t } ' )
2007-04-20 23:33:56 +00:00
for obname , ob in ob_lights :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t Model: " Model:: %s " , " Light " { \n \t } ' % obname )
2007-03-28 07:08:18 +00:00
2007-04-21 11:23:45 +00:00
for obname , ob , mtx , me , mats , arm , armname in ob_meshes :
file . write ( ' \n \t Model: " Model:: %s " , " Mesh " { \n \t } ' % obname )
2007-03-28 07:08:18 +00:00
2007-04-21 11:23:45 +00:00
file . write ( '''
Model : " Model::Producer Perspective " , " Camera " {
2007-03-28 07:08:18 +00:00
}
Model : " Model::Producer Top " , " Camera " {
}
Model : " Model::Producer Bottom " , " Camera " {
}
Model : " Model::Producer Front " , " Camera " {
}
Model : " Model::Producer Back " , " Camera " {
}
Model : " Model::Producer Right " , " Camera " {
}
Model : " Model::Producer Left " , " Camera " {
}
Model : " Model::Camera Switcher " , " CameraSwitcher " {
2007-04-21 11:23:45 +00:00
} ''' )
2007-03-28 07:08:18 +00:00
for matname , mat in materials :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t Material: " Material:: %s " , " " { \n \t } ' % matname )
2007-03-28 07:08:18 +00:00
if textures :
for texname , tex in textures :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t Texture: " Texture:: %s " , " TextureVideoClip " { \n \t } ' % texname )
2007-03-28 07:08:18 +00:00
for texname , tex in textures :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t Video: " Video:: %s " , " Clip " { \n \t } ' % texname )
file . write ( ' \n } ' )
file . write ( '''
2007-03-28 07:08:18 +00:00
; Object connections
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2007-04-21 11:23:45 +00:00
Connections : { ''' )
2007-03-28 07:08:18 +00:00
# write the fake root node
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t Connect: " OO " , " Model::blend_root " , " Model::Scene " ' )
2007-03-28 07:08:18 +00:00
2007-04-20 23:33:56 +00:00
for obname , ob in ob_lights :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t Connect: " OO " , " Model:: %s " , " Model::blend_root " ' % obname )
2007-04-20 23:33:56 +00:00
2007-04-21 11:23:45 +00:00
for obname , ob , mtx , me , mats , arm , armname in ob_meshes :
file . write ( ' \n \t Connect: " OO " , " Model:: %s " , " Model::blend_root " ' % obname )
2007-03-28 07:08:18 +00:00
2007-04-21 11:23:45 +00:00
for obname , ob , mtx , me , mats , arm , armname in ob_meshes :
2007-03-28 07:08:18 +00:00
# Connect all materials to all objects, not good form but ok for now.
2007-04-20 18:48:30 +00:00
for mat in mats :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t Connect: " OO " , " Material:: %s " , " Model:: %s " ' % ( sane_matname ( mat ) , obname ) )
2007-03-28 07:08:18 +00:00
if textures :
2007-04-21 11:23:45 +00:00
for obname , ob , mtx , me , mats , arm , armname in ob_meshes :
2007-03-28 07:08:18 +00:00
for texname , tex in textures :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t Connect: " OO " , " Texture:: %s " , " Model:: %s " ' % ( texname , obname ) )
2007-03-28 07:08:18 +00:00
for texname , tex in textures :
2007-04-21 11:23:45 +00:00
file . write ( ' \n \t Connect: " OO " , " Video:: %s " , " Texture:: %s " ' % ( texname , texname ) )
2007-03-28 07:08:18 +00:00
2007-04-21 11:23:45 +00:00
file . write ( ' \n } ' )
2007-03-29 06:01:03 +00:00
2007-04-20 18:48:30 +00:00
# Clear mesh data Only when writing with modifiers applied
#for obname, ob, me, mats, arm, armname in objects:
# me.verts = None
2007-03-28 07:08:18 +00:00
2007-04-20 18:48:30 +00:00
def write_footer ( file , sce , world ) :
tuple ( world . hor )
tuple ( world . amb )
has_mist = world . mode & 1
mist_intense , mist_start , mist_end , mist_height = world . mist
2007-04-21 11:23:45 +00:00
render = sce . render
2007-04-20 18:48:30 +00:00
2007-04-21 11:23:45 +00:00
file . write ( ' \n ;Takes and animation section ' )
file . write ( ' \n ;---------------------------------------------------- ' )
file . write ( ' \n ' )
file . write ( ' \n Takes: { ' )
file . write ( ' \n \t Current: " " ' )
file . write ( ' \n } ' )
file . write ( ' \n ;Version 5 settings ' )
file . write ( ' \n ;------------------------------------------------------------------ ' )
2007-04-20 18:48:30 +00:00
file . write ( ' \n ' )
2007-04-21 11:23:45 +00:00
file . write ( ' \n Version5: { ' )
file . write ( ' \n \t AmbientRenderSettings: { ' )
file . write ( ' \n \t \t Version: 101 ' )
file . write ( ' \n \t \t AmbientLightColor: %.1f , %.1f , %.1f ,0 ' % tuple ( world . amb ) )
file . write ( ' \n \t } ' )
file . write ( ' \n \t FogOptions: { ' )
file . write ( ' \n \t \t FlogEnable: %i ' % has_mist )
file . write ( ' \n \t \t FogMode: 0 ' )
file . write ( ' \n \t \t FogDensity: %.3f ' % mist_intense )
file . write ( ' \n \t \t FogStart: %.3f ' % mist_start )
file . write ( ' \n \t \t FogEnd: %.3f ' % mist_end )
file . write ( ' \n \t \t FogColor: %.1f , %.1f , %.1f ,1 ' % tuple ( world . hor ) )
file . write ( ' \n \t } ' )
file . write ( ' \n \t Settings: { ' )
file . write ( ' \n \t \t FrameRate: " %i " ' % render . fps )
file . write ( ' \n \t \t TimeFormat: 1 ' )
file . write ( ' \n \t \t SnapOnFrames: 0 ' )
file . write ( ' \n \t \t ReferenceTimeIndex: -1 ' )
file . write ( ' \n \t \t TimeLineStartTime: %i ' % render . sFrame )
file . write ( ' \n \t \t TimeLineStopTime: %i ' % render . eFrame )
file . write ( ' \n \t } ' )
file . write ( ' \n \t RendererSetting: { ' )
file . write ( ' \n \t \t DefaultCamera: " Producer Perspective " ' )
file . write ( ' \n \t \t DefaultViewingMode: 0 ' )
file . write ( ' \n \t } ' )
file . write ( ' \n } ' )
2007-04-20 18:48:30 +00:00
file . write ( ' \n ' )
2007-03-28 07:08:18 +00:00
2007-04-21 11:23:45 +00:00
import bpy
2007-03-28 07:08:18 +00:00
def write_ui ( filename ) :
2007-03-29 17:51:32 +00:00
if not BPyMessages . Warning_SaveOver ( filename ) :
return
2007-04-21 11:23:45 +00:00
sce = bpy . data . scenes . active
world = sce . world
2007-03-29 17:51:32 +00:00
2007-03-28 07:08:18 +00:00
Blender . Window . WaitCursor ( 1 )
file = open ( filename , ' w ' )
write_header ( file )
2007-04-20 18:48:30 +00:00
write_scene ( file , sce , world )
write_footer ( file , sce , world )
2007-03-28 07:08:18 +00:00
Blender . Window . WaitCursor ( 0 )
if __name__ == ' __main__ ' :
Blender . Window . FileSelector ( write_ui , ' Export FBX ' , Blender . sys . makename ( ext = ' .fbx ' ) )