Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/io')
-rw-r--r--release/scripts/io/engine_render_pov.py1001
-rw-r--r--release/scripts/io/export_3ds.py55
-rw-r--r--release/scripts/io/export_fbx.py154
-rw-r--r--release/scripts/io/export_mdd.py41
-rw-r--r--release/scripts/io/export_obj.py467
-rw-r--r--release/scripts/io/export_ply.py33
-rw-r--r--release/scripts/io/export_x3d.py124
-rw-r--r--release/scripts/io/import_anim_bvh.py14
-rw-r--r--release/scripts/io/import_scene_3ds.py252
-rw-r--r--release/scripts/io/import_scene_obj.py196
-rw-r--r--release/scripts/io/import_shape_mdd.py11
-rw-r--r--release/scripts/io/netrender/__init__.py42
-rw-r--r--release/scripts/io/netrender/client.py29
-rw-r--r--release/scripts/io/netrender/master.py21
-rw-r--r--release/scripts/io/netrender/master_html.py7
-rw-r--r--release/scripts/io/netrender/operators.py93
-rw-r--r--[-rwxr-xr-x]release/scripts/io/netrender/repath.py25
-rw-r--r--release/scripts/io/netrender/slave.py43
-rw-r--r--release/scripts/io/netrender/ui.py344
-rw-r--r--release/scripts/io/netrender/utils.py17
20 files changed, 923 insertions, 2046 deletions
diff --git a/release/scripts/io/engine_render_pov.py b/release/scripts/io/engine_render_pov.py
deleted file mode 100644
index 9cda4375ecc..00000000000
--- a/release/scripts/io/engine_render_pov.py
+++ /dev/null
@@ -1,1001 +0,0 @@
-# ##### 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-import bpy
-
-from math import atan, pi, degrees
-import subprocess
-import os
-import sys
-import time
-
-import platform as pltfrm
-
-if pltfrm.architecture()[0] == '64bit':
- bitness = 64
-else:
- bitness = 32
-
-
-def write_pov(filename, scene=None, info_callback=None):
- file = open(filename, 'w')
-
- # Only for testing
- if not scene:
- scene = bpy.data.scenes[0]
-
- render = scene.render
- world = scene.world
-
- def uniqueName(name, nameSeq):
-
- if name not in nameSeq:
- return name
-
- name_orig = name
- i = 1
- while name in nameSeq:
- name = '%s_%.3d' % (name_orig, i)
- i += 1
-
- return name
-
- def writeMatrix(matrix):
- file.write('\tmatrix <%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f>\n' %\
- (matrix[0][0], matrix[0][1], matrix[0][2], matrix[1][0], matrix[1][1], matrix[1][2], matrix[2][0], matrix[2][1], matrix[2][2], matrix[3][0], matrix[3][1], matrix[3][2]))
-
- def writeObjectMaterial(material):
- if material and material.transparency_method == 'RAYTRACE':
- file.write('\tinterior { ior %.6f }\n' % material.raytrace_transparency.ior)
-
- # Other interior args
- # fade_distance 2
- # fade_power [Value]
- # fade_color
-
- # dispersion
- # dispersion_samples
-
- materialNames = {}
- DEF_MAT_NAME = 'Default'
-
- def writeMaterial(material):
- # Assumes only called once on each material
-
- if material:
- name_orig = material.name
- else:
- name_orig = DEF_MAT_NAME
-
- name = materialNames[name_orig] = uniqueName(bpy.utils.clean_name(name_orig), materialNames)
-
- file.write('#declare %s = finish {\n' % name)
-
- if material:
- file.write('\tdiffuse %.3g\n' % material.diffuse_intensity)
- file.write('\tspecular %.3g\n' % material.specular_intensity)
-
- file.write('\tambient %.3g\n' % material.ambient)
- #file.write('\tambient rgb <%.3g, %.3g, %.3g>\n' % tuple([c*material.ambient for c in world.ambient_color])) # povray blends the global value
-
- # map hardness between 0.0 and 1.0
- roughness = ((1.0 - ((material.specular_hardness - 1.0) / 510.0)))
- # scale from 0.0 to 0.1
- roughness *= 0.1
- # add a small value because 0.0 is invalid
- roughness += (1 / 511.0)
-
- file.write('\troughness %.3g\n' % roughness)
-
- # 'phong 70.0 '
-
- if material.raytrace_mirror.enabled:
- raytrace_mirror = material.raytrace_mirror
- if raytrace_mirror.reflect_factor:
- file.write('\treflection {\n')
- file.write('\t\trgb <%.3g, %.3g, %.3g>' % tuple(material.mirror_color))
- file.write('\t\tfresnel 1 falloff %.3g exponent %.3g metallic %.3g} ' % (raytrace_mirror.fresnel, raytrace_mirror.fresnel_factor, raytrace_mirror.reflect_factor))
-
- else:
- file.write('\tdiffuse 0.8\n')
- file.write('\tspecular 0.2\n')
-
-
- # This is written into the object
- '''
- if material and material.transparency_method=='RAYTRACE':
- 'interior { ior %.3g} ' % material.raytrace_transparency.ior
- '''
-
- #file.write('\t\t\tcrand 1.0\n') # Sand granyness
- #file.write('\t\t\tmetallic %.6f\n' % material.spec)
- #file.write('\t\t\tphong %.6f\n' % material.spec)
- #file.write('\t\t\tphong_size %.6f\n' % material.spec)
- #file.write('\t\t\tbrilliance %.6f ' % (material.specular_hardness/256.0) # Like hardness
-
- file.write('}\n')
-
- def exportCamera():
- camera = scene.camera
- matrix = camera.matrix_world
-
- # compute resolution
- Qsize = float(render.resolution_x) / float(render.resolution_y)
-
- file.write('camera {\n')
- file.write('\tlocation <0, 0, 0>\n')
- file.write('\tlook_at <0, 0, -1>\n')
- file.write('\tright <%s, 0, 0>\n' % - Qsize)
- file.write('\tup <0, 1, 0>\n')
- file.write('\tangle %f \n' % (360.0 * atan(16.0 / camera.data.lens) / pi))
-
- file.write('\trotate <%.6f, %.6f, %.6f>\n' % tuple([degrees(e) for e in matrix.rotation_part().to_euler()]))
- file.write('\ttranslate <%.6f, %.6f, %.6f>\n' % (matrix[3][0], matrix[3][1], matrix[3][2]))
- file.write('}\n')
-
- def exportLamps(lamps):
- # Get all lamps
- for ob in lamps:
- lamp = ob.data
-
- matrix = ob.matrix_world
-
- color = tuple([c * lamp.energy for c in lamp.color]) # Colour is modified by energy
-
- file.write('light_source {\n')
- file.write('\t< 0,0,0 >\n')
- file.write('\tcolor rgb<%.3g, %.3g, %.3g>\n' % color)
-
- if lamp.type == 'POINT': # Point Lamp
- pass
- elif lamp.type == 'SPOT': # Spot
- file.write('\tspotlight\n')
-
- # Falloff is the main radius from the centre line
- file.write('\tfalloff %.2f\n' % (degrees(lamp.spot_size) / 2.0)) # 1 TO 179 FOR BOTH
- file.write('\tradius %.6f\n' % ((degrees(lamp.spot_size) / 2.0) * (1.0 - lamp.spot_blend)))
-
- # Blender does not have a tightness equivilent, 0 is most like blender default.
- file.write('\ttightness 0\n') # 0:10f
-
- file.write('\tpoint_at <0, 0, -1>\n')
- elif lamp.type == 'SUN':
- file.write('\tparallel\n')
- file.write('\tpoint_at <0, 0, -1>\n') # *must* be after 'parallel'
-
- elif lamp.type == 'AREA':
-
- size_x = lamp.size
- samples_x = lamp.shadow_ray_samples_x
- if lamp.shape == 'SQUARE':
- size_y = size_x
- samples_y = samples_x
- else:
- size_y = lamp.size_y
- samples_y = lamp.shadow_ray_samples_y
-
- file.write('\tarea_light <%d,0,0>,<0,0,%d> %d, %d\n' % (size_x, size_y, samples_x, samples_y))
- if lamp.shadow_ray_sampling_method == 'CONSTANT_JITTERED':
- if lamp.jitter:
- file.write('\tjitter\n')
- else:
- file.write('\tadaptive 1\n')
- file.write('\tjitter\n')
-
- if lamp.shadow_method == 'NOSHADOW':
- file.write('\tshadowless\n')
-
- file.write('\tfade_distance %.6f\n' % lamp.distance)
- file.write('\tfade_power %d\n' % 1) # Could use blenders lamp quad?
- writeMatrix(matrix)
-
- file.write('}\n')
-
- def exportMeta(metas):
-
- # TODO - blenders 'motherball' naming is not supported.
-
- for ob in metas:
- meta = ob.data
-
- file.write('blob {\n')
- file.write('\t\tthreshold %.4g\n' % meta.threshold)
-
- try:
- material = meta.materials[0] # lame! - blender cant do enything else.
- except:
- material = None
-
- for elem in meta.elements:
-
- if elem.type not in ('BALL', 'ELLIPSOID'):
- continue # Not supported
-
- loc = elem.location
-
- stiffness = elem.stiffness
- if elem.negative:
- stiffness = - stiffness
-
- if elem.type == 'BALL':
-
- file.write('\tsphere { <%.6g, %.6g, %.6g>, %.4g, %.4g ' % (loc.x, loc.y, loc.z, elem.radius, stiffness))
-
- # After this wecould do something simple like...
- # "pigment {Blue} }"
- # except we'll write the color
-
- elif elem.type == 'ELLIPSOID':
- # location is modified by scale
- file.write('\tsphere { <%.6g, %.6g, %.6g>, %.4g, %.4g ' % (loc.x / elem.size_x, loc.y / elem.size_y, loc.z / elem.size_z, elem.radius, stiffness))
- file.write('scale <%.6g, %.6g, %.6g> ' % (elem.size_x, elem.size_y, elem.size_z))
-
- if material:
- diffuse_color = material.diffuse_color
-
- if material.transparency and material.transparency_method == 'RAYTRACE':
- trans = 1.0 - material.raytrace_transparency.filter
- else:
- trans = 0.0
-
- file.write('pigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} finish {%s} }\n' % \
- (diffuse_color[0], diffuse_color[1], diffuse_color[2], 1.0 - material.alpha, trans, materialNames[material.name]))
-
- else:
- file.write('pigment {rgb<1 1 1>} finish {%s} }\n' % DEF_MAT_NAME) # Write the finish last.
-
- writeObjectMaterial(material)
-
- writeMatrix(ob.matrix_world)
-
- file.write('}\n')
-
- def exportMeshs(scene, sel):
-
- ob_num = 0
-
- for ob in sel:
- ob_num += 1
-
- if ob.type in ('LAMP', 'CAMERA', 'EMPTY', 'META', 'ARMATURE'):
- continue
-
- me = ob.data
- me_materials = me.materials
-
- me = ob.create_mesh(scene, True, 'RENDER')
-
- if not me:
- continue
-
- if info_callback:
- info_callback('Object %2.d of %2.d (%s)' % (ob_num, len(sel), ob.name))
-
- #if ob.type!='MESH':
- # continue
- # me = ob.data
-
- matrix = ob.matrix_world
- try:
- uv_layer = me.active_uv_texture.data
- except:
- uv_layer = None
-
- try:
- vcol_layer = me.active_vertex_color.data
- except:
- vcol_layer = None
-
- faces_verts = [f.verts for f in me.faces]
- faces_normals = [tuple(f.normal) for f in me.faces]
- verts_normals = [tuple(v.normal) for v in me.verts]
-
- # quads incur an extra face
- quadCount = len([f for f in faces_verts if len(f) == 4])
-
- file.write('mesh2 {\n')
- file.write('\tvertex_vectors {\n')
- file.write('\t\t%s' % (len(me.verts))) # vert count
- for v in me.verts:
- file.write(',\n\t\t<%.6f, %.6f, %.6f>' % tuple(v.co)) # vert count
- file.write('\n }\n')
-
-
- # Build unique Normal list
- uniqueNormals = {}
- for fi, f in enumerate(me.faces):
- fv = faces_verts[fi]
- # [-1] is a dummy index, use a list so we can modify in place
- if f.smooth: # Use vertex normals
- for v in fv:
- key = verts_normals[v]
- uniqueNormals[key] = [-1]
- else: # Use face normal
- key = faces_normals[fi]
- uniqueNormals[key] = [-1]
-
- file.write('\tnormal_vectors {\n')
- file.write('\t\t%d' % len(uniqueNormals)) # vert count
- idx = 0
- for no, index in uniqueNormals.items():
- file.write(',\n\t\t<%.6f, %.6f, %.6f>' % no) # vert count
- index[0] = idx
- idx += 1
- file.write('\n }\n')
-
-
- # Vertex colours
- vertCols = {} # Use for material colours also.
-
- if uv_layer:
- # Generate unique UV's
- uniqueUVs = {}
-
- for fi, uv in enumerate(uv_layer):
-
- if len(faces_verts[fi]) == 4:
- uvs = uv.uv1, uv.uv2, uv.uv3, uv.uv4
- else:
- uvs = uv.uv1, uv.uv2, uv.uv3
-
- for uv in uvs:
- uniqueUVs[tuple(uv)] = [-1]
-
- file.write('\tuv_vectors {\n')
- #print unique_uvs
- file.write('\t\t%s' % (len(uniqueUVs))) # vert count
- idx = 0
- for uv, index in uniqueUVs.items():
- file.write(',\n\t\t<%.6f, %.6f>' % uv)
- index[0] = idx
- idx += 1
- '''
- else:
- # Just add 1 dummy vector, no real UV's
- file.write('\t\t1') # vert count
- file.write(',\n\t\t<0.0, 0.0>')
- '''
- file.write('\n }\n')
-
-
- if me.vertex_colors:
-
- for fi, f in enumerate(me.faces):
- material_index = f.material_index
- material = me_materials[material_index]
-
- if material and material.vertex_color_paint:
-
- col = vcol_layer[fi]
-
- if len(faces_verts[fi]) == 4:
- cols = col.color1, col.color2, col.color3, col.color4
- else:
- cols = col.color1, col.color2, col.color3
-
- for col in cols:
- key = col[0], col[1], col[2], material_index # Material index!
- vertCols[key] = [-1]
-
- else:
- if material:
- diffuse_color = tuple(material.diffuse_color)
- key = diffuse_color[0], diffuse_color[1], diffuse_color[2], material_index
- vertCols[key] = [-1]
-
-
- else:
- # No vertex colours, so write material colours as vertex colours
- for i, material in enumerate(me_materials):
-
- if material:
- diffuse_color = tuple(material.diffuse_color)
- key = diffuse_color[0], diffuse_color[1], diffuse_color[2], i # i == f.mat
- vertCols[key] = [-1]
-
-
- # Vert Colours
- file.write('\ttexture_list {\n')
- file.write('\t\t%s' % (len(vertCols))) # vert count
- idx = 0
- for col, index in vertCols.items():
-
- if me_materials:
- material = me_materials[col[3]]
- material_finish = materialNames[material.name]
-
- if material.transparency and material.transparency_method == 'RAYTRACE':
- trans = 1.0 - material.raytrace_transparency.filter
- else:
- trans = 0.0
-
- else:
- material_finish = DEF_MAT_NAME # not working properly,
- trans = 0.0
-
- #print material.apl
- file.write(',\n\t\ttexture { pigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} finish {%s}}' %
- (col[0], col[1], col[2], 1.0 - material.alpha, trans, material_finish))
-
- index[0] = idx
- idx += 1
-
- file.write('\n }\n')
-
- # Face indicies
- file.write('\tface_indices {\n')
- file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count
- for fi, f in enumerate(me.faces):
- fv = faces_verts[fi]
- material_index = f.material_index
- if len(fv) == 4:
- indicies = (0, 1, 2), (0, 2, 3)
- else:
- indicies = ((0, 1, 2),)
-
- if vcol_layer:
- col = vcol_layer[fi]
-
- if len(fv) == 4:
- cols = col.color1, col.color2, col.color3, col.color4
- else:
- cols = col.color1, col.color2, col.color3
-
-
- if not me_materials or me_materials[material_index] == None: # No materials
- for i1, i2, i3 in indicies:
- file.write(',\n\t\t<%d,%d,%d>' % (fv[i1], fv[i2], fv[i3])) # vert count
- else:
- material = me_materials[material_index]
- for i1, i2, i3 in indicies:
- if me.vertex_colors and material.vertex_color_paint:
- # Colour per vertex - vertex colour
-
- col1 = cols[i1]
- col2 = cols[i2]
- col3 = cols[i3]
-
- ci1 = vertCols[col1[0], col1[1], col1[2], material_index][0]
- ci2 = vertCols[col2[0], col2[1], col2[2], material_index][0]
- ci3 = vertCols[col3[0], col3[1], col3[2], material_index][0]
- else:
- # Colour per material - flat material colour
- diffuse_color = material.diffuse_color
- ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], diffuse_color[2], f.material_index][0]
-
- file.write(',\n\t\t<%d,%d,%d>, %d,%d,%d' % (fv[i1], fv[i2], fv[i3], ci1, ci2, ci3)) # vert count
-
-
- file.write('\n }\n')
-
- # normal_indices indicies
- file.write('\tnormal_indices {\n')
- file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count
- for fi, fv in enumerate(faces_verts):
-
- if len(fv) == 4:
- indicies = (0, 1, 2), (0, 2, 3)
- else:
- indicies = ((0, 1, 2),)
-
- for i1, i2, i3 in indicies:
- if f.smooth:
- file.write(',\n\t\t<%d,%d,%d>' %\
- (uniqueNormals[verts_normals[fv[i1]]][0],\
- uniqueNormals[verts_normals[fv[i2]]][0],\
- uniqueNormals[verts_normals[fv[i3]]][0])) # vert count
- else:
- idx = uniqueNormals[faces_normals[fi]][0]
- file.write(',\n\t\t<%d,%d,%d>' % (idx, idx, idx)) # vert count
-
- file.write('\n }\n')
-
- if uv_layer:
- file.write('\tuv_indices {\n')
- file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count
- for fi, fv in enumerate(faces_verts):
-
- if len(fv) == 4:
- indicies = (0, 1, 2), (0, 2, 3)
- else:
- indicies = ((0, 1, 2),)
-
- uv = uv_layer[fi]
- if len(faces_verts[fi]) == 4:
- uvs = tuple(uv.uv1), tuple(uv.uv2), tuple(uv.uv3), tuple(uv.uv4)
- else:
- uvs = tuple(uv.uv1), tuple(uv.uv2), tuple(uv.uv3)
-
- for i1, i2, i3 in indicies:
- file.write(',\n\t\t<%d,%d,%d>' %\
- (uniqueUVs[uvs[i1]][0],\
- uniqueUVs[uvs[i2]][0],\
- uniqueUVs[uvs[i2]][0])) # vert count
- file.write('\n }\n')
-
- if me.materials:
- material = me.materials[0] # dodgy
- writeObjectMaterial(material)
-
- writeMatrix(matrix)
- file.write('}\n')
-
- bpy.data.meshes.remove(me)
-
- def exportWorld(world):
- if not world:
- return
-
- mist = world.mist
-
- if mist.use_mist:
- file.write('fog {\n')
- file.write('\tdistance %.6f\n' % mist.depth)
- file.write('\tcolor rgbt<%.3g, %.3g, %.3g, %.3g>\n' % (tuple(world.horizon_color) + (1 - mist.intensity,)))
- #file.write('\tfog_offset %.6f\n' % mist.start)
- #file.write('\tfog_alt 5\n')
- #file.write('\tturbulence 0.2\n')
- #file.write('\tturb_depth 0.3\n')
- file.write('\tfog_type 1\n')
- file.write('}\n')
-
- def exportGlobalSettings(scene):
-
- file.write('global_settings {\n')
-
- if scene.pov_radio_enable:
- file.write('\tradiosity {\n')
- file.write("\t\tadc_bailout %.4g\n" % scene.pov_radio_adc_bailout)
- file.write("\t\talways_sample %d\n" % scene.pov_radio_always_sample)
- file.write("\t\tbrightness %.4g\n" % scene.pov_radio_brightness)
- file.write("\t\tcount %d\n" % scene.pov_radio_count)
- file.write("\t\terror_bound %.4g\n" % scene.pov_radio_error_bound)
- file.write("\t\tgray_threshold %.4g\n" % scene.pov_radio_gray_threshold)
- file.write("\t\tlow_error_factor %.4g\n" % scene.pov_radio_low_error_factor)
- file.write("\t\tmedia %d\n" % scene.pov_radio_media)
- file.write("\t\tminimum_reuse %.4g\n" % scene.pov_radio_minimum_reuse)
- file.write("\t\tnearest_count %d\n" % scene.pov_radio_nearest_count)
- file.write("\t\tnormal %d\n" % scene.pov_radio_normal)
- file.write("\t\trecursion_limit %d\n" % scene.pov_radio_recursion_limit)
- file.write('\t}\n')
-
- if world:
- file.write("\tambient_light rgb<%.3g, %.3g, %.3g>\n" % tuple(world.ambient_color))
-
- file.write('}\n')
-
-
- # Convert all materials to strings we can access directly per vertex.
- writeMaterial(None) # default material
-
- for material in bpy.data.materials:
- writeMaterial(material)
-
- exportCamera()
- #exportMaterials()
- sel = scene.objects
- exportLamps([l for l in sel if l.type == 'LAMP'])
- exportMeta([l for l in sel if l.type == 'META'])
- exportMeshs(scene, sel)
- exportWorld(scene.world)
- exportGlobalSettings(scene)
-
- file.close()
-
-
-def write_pov_ini(filename_ini, filename_pov, filename_image):
- scene = bpy.data.scenes[0]
- render = scene.render
-
- x = int(render.resolution_x * render.resolution_percentage * 0.01)
- y = int(render.resolution_y * render.resolution_percentage * 0.01)
-
- file = open(filename_ini, 'w')
-
- file.write('Input_File_Name="%s"\n' % filename_pov)
- file.write('Output_File_Name="%s"\n' % filename_image)
-
- file.write('Width=%d\n' % x)
- file.write('Height=%d\n' % y)
-
- # Needed for border render.
- '''
- file.write('Start_Column=%d\n' % part.x)
- file.write('End_Column=%d\n' % (part.x+part.w))
-
- file.write('Start_Row=%d\n' % (part.y))
- file.write('End_Row=%d\n' % (part.y+part.h))
- '''
-
- file.write('Display=0\n')
- file.write('Pause_When_Done=0\n')
- file.write('Output_File_Type=T\n') # TGA, best progressive loading
- file.write('Output_Alpha=1\n')
-
- if render.render_antialiasing:
- aa_mapping = {'5': 2, '8': 3, '11': 4, '16': 5} # method 1 assumed
- file.write('Antialias=1\n')
- file.write('Antialias_Depth=%d\n' % aa_mapping[render.antialiasing_samples])
- else:
- file.write('Antialias=0\n')
-
- file.close()
-
-# Radiosity panel, use in the scene for now.
-FloatProperty = bpy.types.Scene.FloatProperty
-IntProperty = bpy.types.Scene.IntProperty
-BoolProperty = bpy.types.Scene.BoolProperty
-
-# Not a real pov option, just to know if we should write
-BoolProperty(attr="pov_radio_enable",
- name="Enable Radiosity",
- description="Enable povrays radiosity calculation",
- default=False)
-BoolProperty(attr="pov_radio_display_advanced",
- name="Advanced Options",
- description="Show advanced options",
- default=False)
-
-# Real pov options
-FloatProperty(attr="pov_radio_adc_bailout",
- name="ADC Bailout",
- description="The adc_bailout for radiosity rays. Use adc_bailout = 0.01 / brightest_ambient_object for good results",
- min=0.0, max=1000.0, soft_min=0.0, soft_max=1.0, default=0.01)
-
-BoolProperty(attr="pov_radio_always_sample",
- name="Always Sample",
- description="Only use the data from the pretrace step and not gather any new samples during the final radiosity pass",
- default=True)
-
-FloatProperty(attr="pov_radio_brightness",
- name="Brightness",
- description="Amount objects are brightened before being returned upwards to the rest of the system",
- min=0.0, max=1000.0, soft_min=0.0, soft_max=10.0, default=1.0)
-
-IntProperty(attr="pov_radio_count",
- name="Ray Count",
- description="Number of rays that are sent out whenever a new radiosity value has to be calculated",
- min=1, max=1600, default=35)
-
-FloatProperty(attr="pov_radio_error_bound",
- name="Error Bound",
- description="One of the two main speed/quality tuning values, lower values are more accurate",
- min=0.0, max=1000.0, soft_min=0.1, soft_max=10.0, default=1.8)
-
-FloatProperty(attr="pov_radio_gray_threshold",
- name="Gray Threshold",
- description="One of the two main speed/quality tuning values, lower values are more accurate",
- min=0.0, max=1.0, soft_min=0, soft_max=1, default=0.0)
-
-FloatProperty(attr="pov_radio_low_error_factor",
- name="Low Error Factor",
- description="If you calculate just enough samples, but no more, you will get an image which has slightly blotchy lighting",
- min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, default=0.5)
-
-# max_sample - not available yet
-BoolProperty(attr="pov_radio_media",
- name="Media",
- description="Radiosity estimation can be affected by media",
- default=False)
-
-FloatProperty(attr="pov_radio_minimum_reuse",
- name="Minimum Reuse",
- description="Fraction of the screen width which sets the minimum radius of reuse for each sample point (At values higher than 2% expect errors)",
- min=0.0, max=1.0, soft_min=0.1, soft_max=0.1, default=0.015)
-
-IntProperty(attr="pov_radio_nearest_count",
- name="Nearest Count",
- description="Number of old ambient values blended together to create a new interpolated value",
- min=1, max=20, default=5)
-
-BoolProperty(attr="pov_radio_normal",
- name="Normals",
- description="Radiosity estimation can be affected by normals",
- default=False)
-
-IntProperty(attr="pov_radio_recursion_limit",
- name="Recursion Limit",
- description="how many recursion levels are used to calculate the diffuse inter-reflection",
- min=1, max=20, default=3)
-
-
-class PovrayRender(bpy.types.RenderEngine):
- bl_idname = 'POVRAY_RENDER'
- bl_label = "Povray"
- DELAY = 0.02
-
- def _export(self, scene):
- import tempfile
-
- self._temp_file_in = tempfile.mktemp(suffix='.pov')
- self._temp_file_out = tempfile.mktemp(suffix='.tga')
- self._temp_file_ini = tempfile.mktemp(suffix='.ini')
- '''
- self._temp_file_in = '/test.pov'
- self._temp_file_out = '/test.tga'
- self._temp_file_ini = '/test.ini'
- '''
-
- def info_callback(txt):
- self.update_stats("", "POVRAY: " + txt)
-
- write_pov(self._temp_file_in, scene, info_callback)
-
- def _render(self):
-
- try:
- os.remove(self._temp_file_out) # so as not to load the old file
- except:
- pass
-
- write_pov_ini(self._temp_file_ini, self._temp_file_in, self._temp_file_out)
-
- print ("***-STARTING-***")
-
- pov_binary = "povray"
-
- if sys.platform == 'win32':
- import winreg
- regKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\POV-Ray\\v3.6\\Windows')
-
- if bitness == 64:
- pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine64'
- else:
- pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine'
-
- if 1:
- # TODO, when povray isnt found this gives a cryptic error, would be nice to be able to detect if it exists
- try:
- self._process = subprocess.Popen([pov_binary, self._temp_file_ini]) # stdout=subprocess.PIPE, stderr=subprocess.PIPE
- except OSError:
- # TODO, report api
- print("POVRAY: could not execute '%s', possibly povray isn't installed" % pov_binary)
- import traceback
- traceback.print_exc()
- print ("***-DONE-***")
- return False
-
- else:
- # This works too but means we have to wait until its done
- os.system('%s %s' % (pov_binary, self._temp_file_ini))
-
- print ("***-DONE-***")
- return True
-
- def _cleanup(self):
- for f in (self._temp_file_in, self._temp_file_ini, self._temp_file_out):
- try:
- os.remove(f)
- except:
- pass
-
- self.update_stats("", "")
-
- def render(self, scene):
-
- self.update_stats("", "POVRAY: Exporting data from Blender")
- self._export(scene)
- self.update_stats("", "POVRAY: Parsing File")
-
- if not self._render():
- self.update_stats("", "POVRAY: Not found")
- return
-
- r = scene.render
-
- # compute resolution
- x = int(r.resolution_x * r.resolution_percentage * 0.01)
- y = int(r.resolution_y * r.resolution_percentage * 0.01)
-
- # Wait for the file to be created
- while not os.path.exists(self._temp_file_out):
- if self.test_break():
- try:
- self._process.terminate()
- except:
- pass
- break
-
- if self._process.poll() != None:
- self.update_stats("", "POVRAY: Failed")
- break
-
- time.sleep(self.DELAY)
-
- if os.path.exists(self._temp_file_out):
-
- self.update_stats("", "POVRAY: Rendering")
-
- prev_size = -1
-
- def update_image():
- result = self.begin_result(0, 0, x, y)
- lay = result.layers[0]
- # possible the image wont load early on.
- try:
- lay.load_from_file(self._temp_file_out)
- except:
- pass
- self.end_result(result)
-
- # Update while povray renders
- while True:
-
- # test if povray exists
- if self._process.poll() is not None:
- update_image()
- break
-
- # user exit
- if self.test_break():
- try:
- self._process.terminate()
- except:
- pass
-
- break
-
- # Would be nice to redirect the output
- # stdout_value, stderr_value = self._process.communicate() # locks
-
-
- # check if the file updated
- new_size = os.path.getsize(self._temp_file_out)
-
- if new_size != prev_size:
- update_image()
- prev_size = new_size
-
- time.sleep(self.DELAY)
-
- self._cleanup()
-
-
-# Use some of the existing buttons.
-import properties_render
-properties_render.RENDER_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER')
-properties_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER')
-properties_render.RENDER_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER')
-properties_render.RENDER_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER')
-del properties_render
-
-# Use only a subset of the world panels
-import properties_world
-properties_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER')
-properties_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_RENDER')
-properties_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER')
-properties_world.WORLD_PT_mist.COMPAT_ENGINES.add('POVRAY_RENDER')
-del properties_world
-
-# Example of wrapping every class 'as is'
-import properties_material
-for member in dir(properties_material):
- subclass = getattr(properties_material, member)
- try:
- subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
- except:
- pass
-del properties_material
-import properties_data_mesh
-for member in dir(properties_data_mesh):
- subclass = getattr(properties_data_mesh, member)
- try:
- subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
- except:
- pass
-del properties_data_mesh
-import properties_texture
-for member in dir(properties_texture):
- subclass = getattr(properties_texture, member)
- try:
- subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
- except:
- pass
-del properties_texture
-import properties_data_camera
-for member in dir(properties_data_camera):
- subclass = getattr(properties_data_camera, member)
- try:
- subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
- except:
- pass
-del properties_data_camera
-
-
-class RenderButtonsPanel(bpy.types.Panel):
- bl_space_type = 'PROPERTIES'
- bl_region_type = 'WINDOW'
- bl_context = "render"
- # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
-
- def poll(self, context):
- rd = context.scene.render
- return (rd.use_game_engine == False) and (rd.engine in self.COMPAT_ENGINES)
-
-
-class RENDER_PT_povray_radiosity(RenderButtonsPanel):
- bl_label = "Radiosity"
- COMPAT_ENGINES = {'POVRAY_RENDER'}
-
- def draw_header(self, context):
- scene = context.scene
-
- self.layout.prop(scene, "pov_radio_enable", text="")
-
- def draw(self, context):
- layout = self.layout
-
- scene = context.scene
- rd = scene.render
-
- layout.active = scene.pov_radio_enable
-
- split = layout.split()
-
- col = split.column()
- col.prop(scene, "pov_radio_count", text="Rays")
- col.prop(scene, "pov_radio_recursion_limit", text="Recursions")
- col = split.column()
- col.prop(scene, "pov_radio_error_bound", text="Error")
-
- layout.prop(scene, "pov_radio_display_advanced")
-
- if scene.pov_radio_display_advanced:
- split = layout.split()
-
- col = split.column()
- col.prop(scene, "pov_radio_adc_bailout", slider=True)
- col.prop(scene, "pov_radio_gray_threshold", slider=True)
- col.prop(scene, "pov_radio_low_error_factor", slider=True)
-
- col = split.column()
- col.prop(scene, "pov_radio_brightness")
- col.prop(scene, "pov_radio_minimum_reuse", text="Min Reuse")
- col.prop(scene, "pov_radio_nearest_count")
-
- split = layout.split()
-
- col = split.column()
- col.label(text="Estimation Influence:")
- col.prop(scene, "pov_radio_media")
- col.prop(scene, "pov_radio_normal")
-
- col = split.column()
- col.prop(scene, "pov_radio_always_sample")
-
-
-classes = [
- PovrayRender,
- RENDER_PT_povray_radiosity]
-
-
-def register():
- register = bpy.types.register
- for cls in classes:
- register(cls)
-
-
-def unregister():
- unregister = bpy.types.unregister
- for cls in classes:
- unregister(cls)
-
-if __name__ == "__main__":
- register()
diff --git a/release/scripts/io/export_3ds.py b/release/scripts/io/export_3ds.py
index 4fd889c75c6..4a5521bd9e9 100644
--- a/release/scripts/io/export_3ds.py
+++ b/release/scripts/io/export_3ds.py
@@ -564,14 +564,14 @@ def extract_triangles(mesh):
img = None
for i, face in enumerate(mesh.faces):
- f_v = face.verts
+ f_v = face.vertices
# f_v = face.v
uf = mesh.active_uv_texture.data[i] if do_uv else None
if do_uv:
f_uv = uf.uv
- # f_uv = (uf.uv1, uf.uv2, uf.uv3, uf.uv4) if face.verts[3] else (uf.uv1, uf.uv2, uf.uv3)
+ # f_uv = (uf.uv1, uf.uv2, uf.uv3, uf.uv4) if face.vertices[3] else (uf.uv1, uf.uv2, uf.uv3)
# f_uv = face.uv
img = uf.image if uf else None
# img = face.image
@@ -761,18 +761,18 @@ def make_mesh_chunk(mesh, materialDict):
if len(mesh.uv_textures):
# if mesh.faceUV:
# Remove the face UVs and convert it to vertex UV:
- vert_array, uv_array, tri_list = remove_face_uv(mesh.verts, tri_list)
+ vert_array, uv_array, tri_list = remove_face_uv(mesh.vertices, tri_list)
else:
# Add the vertices to the vertex array:
vert_array = _3ds_array()
- for vert in mesh.verts:
+ for vert in mesh.vertices:
vert_array.add(_3ds_point_3d(vert.co))
# If the mesh has vertex UVs, create an array of UVs:
if len(mesh.sticky):
# if mesh.vertexUV:
uv_array = _3ds_array()
for uv in mesh.sticky:
-# for vert in mesh.verts:
+# for vert in mesh.vertices:
uv_array.add(_3ds_point_uv(uv.co))
# uv_array.add(_3ds_point_uv(vert.uvco))
else:
@@ -922,7 +922,7 @@ def make_kf_obj_node(obj, name_to_id):
"""
# import BPyMessages
-def save_3ds(filename, context):
+def write(filename, context):
'''Save the Blender scene to a 3ds file.'''
# Time the export
@@ -941,7 +941,8 @@ def save_3ds(filename, context):
sce = context.scene
# sce= bpy.data.scenes.active
- bpy.ops.object.mode_set(mode='OBJECT')
+ if context.object:
+ bpy.ops.object.mode_set(mode='OBJECT')
# Initialize the main chunk (primary):
primary = _3ds_chunk(PRIMARY)
@@ -1006,7 +1007,7 @@ def save_3ds(filename, context):
mat = mat_ls[mat_index]
if mat: mat_name = mat.name
else: mat_name = None
- # else there alredy set to none
+ # else there already set to none
img = uf.image
# img = f.image
@@ -1064,7 +1065,7 @@ def save_3ds(filename, context):
'''
if not blender_mesh.users:
bpy.data.meshes.remove(blender_mesh)
-# blender_mesh.verts = None
+# blender_mesh.vertices = None
i+=i
@@ -1106,50 +1107,46 @@ def save_3ds(filename, context):
#primary.dump()
-# if __name__=='__main__':
-# if struct:
-# Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds'))
-# else:
-# Blender.Draw.PupMenu("Error%t|This script requires a full python installation")
-# # save_3ds('/test_b.3ds')
+# # write('/test_b.3ds')
from bpy.props import *
class Export3DS(bpy.types.Operator):
'''Export to 3DS file format (.3ds)'''
bl_idname = "export.autodesk_3ds"
bl_label = 'Export 3DS'
- # List of operator properties, the attributes will be assigned
- # to the class instance from the operator settings before calling.
-
-
filepath = StringProperty(name="File Path", description="Filepath used for exporting the 3DS file", maxlen= 1024, default= "")
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
+ @classmethod
+ def poll(cls, context): # Poll isnt working yet
+ return context.active_object != None
+
def execute(self, context):
- save_3ds(self.properties.filepath, context)
+ filepath = self.properties.filepath
+ filepath = bpy.path.ensure_ext(filepath, ".3ds")
+
+ write(filepath, context)
return {'FINISHED'}
def invoke(self, context, event):
- wm = context.manager
- wm.add_fileselect(self)
- return {'RUNNING_MODAL'}
+ import os
+ if not self.properties.is_property_set("filepath"):
+ self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".3ds"
- def poll(self, context): # Poll isnt working yet
- return context.active_object != None
+ context.manager.add_fileselect(self)
+ return {'RUNNING_MODAL'}
# Add to a menu
def menu_func(self, context):
- default_path = os.path.splitext(bpy.data.filepath)[0] + ".3ds"
- self.layout.operator(Export3DS.bl_idname, text="3D Studio (.3ds)").filepath = default_path
+ self.layout.operator(Export3DS.bl_idname, text="3D Studio (.3ds)")
def register():
- bpy.types.register(Export3DS)
bpy.types.INFO_MT_file_export.append(menu_func)
+
def unregister():
- bpy.types.unregister(Export3DS)
bpy.types.INFO_MT_file_export.remove(menu_func)
if __name__ == "__main__":
diff --git a/release/scripts/io/export_fbx.py b/release/scripts/io/export_fbx.py
index 4505b56b41c..60e9e90e11b 100644
--- a/release/scripts/io/export_fbx.py
+++ b/release/scripts/io/export_fbx.py
@@ -55,7 +55,7 @@ import math # math.pi
import shutil # for file copying
import bpy
-from mathutils import Vector, Euler, Matrix, RotationMatrix
+from mathutils import Vector, Euler, Matrix
def copy_file(source, dest):
# XXX - remove, can use shutil
@@ -75,7 +75,7 @@ def copy_images(dest_dir, textures):
image_paths = set()
for tex in textures:
- image_paths.add(bpy.utils.expandpath(tex.filepath))
+ image_paths.add(bpy.path.abspath(tex.filepath))
# Now copy images
copyCount = 0
@@ -83,7 +83,7 @@ def copy_images(dest_dir, textures):
if Blender.sys.exists(image_path):
# Make a name for the target path.
dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
- if not Blender.sys.exists(dest_image_path): # Image isnt alredy there
+ if not Blender.sys.exists(dest_image_path): # Image isnt already there
print('\tCopying "%s" > "%s"' % (image_path, dest_image_path))
try:
copy_file(image_path, dest_image_path)
@@ -107,19 +107,19 @@ def eulerRadToDeg(eul):
mtx4_identity = Matrix()
# testing
-mtx_x90 = RotationMatrix( math.pi/2, 3, 'X') # used
-#mtx_x90n = RotationMatrix(-90, 3, 'x')
-#mtx_y90 = RotationMatrix( 90, 3, 'y')
-#mtx_y90n = RotationMatrix(-90, 3, 'y')
-#mtx_z90 = RotationMatrix( 90, 3, 'z')
-#mtx_z90n = RotationMatrix(-90, 3, 'z')
-
-#mtx4_x90 = RotationMatrix( 90, 4, 'x')
-mtx4_x90n = RotationMatrix(-math.pi/2, 4, 'X') # used
-#mtx4_y90 = RotationMatrix( 90, 4, 'y')
-mtx4_y90n = RotationMatrix(-math.pi/2, 4, 'Y') # used
-mtx4_z90 = RotationMatrix( math.pi/2, 4, 'Z') # used
-mtx4_z90n = RotationMatrix(-math.pi/2, 4, 'Z') # used
+mtx_x90 = Matrix.Rotation( math.pi/2, 3, 'X') # used
+#mtx_x90n = Matrix.Rotation(-90, 3, 'x')
+#mtx_y90 = Matrix.Rotation( 90, 3, 'y')
+#mtx_y90n = Matrix.Rotation(-90, 3, 'y')
+#mtx_z90 = Matrix.Rotation( 90, 3, 'z')
+#mtx_z90n = Matrix.Rotation(-90, 3, 'z')
+
+#mtx4_x90 = Matrix.Rotation( 90, 4, 'x')
+mtx4_x90n = Matrix.Rotation(-math.pi/2, 4, 'X') # used
+#mtx4_y90 = Matrix.Rotation( 90, 4, 'y')
+mtx4_y90n = Matrix.Rotation(-math.pi/2, 4, 'Y') # used
+mtx4_z90 = Matrix.Rotation( math.pi/2, 4, 'Z') # used
+mtx4_z90n = Matrix.Rotation(-math.pi/2, 4, 'Z') # used
# def strip_path(p):
# return p.split('\\')[-1].split('/')[-1]
@@ -176,7 +176,7 @@ def sane_name(data, dct):
name = 'unnamed' # blank string, ASKING FOR TROUBLE!
else:
- name = bpy.utils.clean_name(name) # use our own
+ name = bpy.path.clean_name(name) # use our own
while name in iter(dct.values()): name = increment_string(name)
@@ -200,14 +200,14 @@ def sane_groupname(data): return sane_name(data, sane_name_mapping_group)
# FORCE_CWD - dont use the basepath, just add a ./ to the filename.
# use when we know the file will be in the basepath.
# '''
-# fname = bpy.utils.expandpath(fname_orig)
+# fname = bpy.path.abspath(fname_orig)
# # fname = Blender.sys.expandpath(fname_orig)
# fname_strip = os.path.basename(fname)
# # fname_strip = strip_path(fname)
# if FORCE_CWD:
# fname_rel = '.' + os.sep + fname_strip
# else:
-# fname_rel = bpy.utils.relpath(fname, basepath)
+# fname_rel = bpy.path.relpath(fname, basepath)
# # fname_rel = Blender.sys.relpath(fname, basepath)
# if fname_rel.startswith('//'): fname_rel = '.' + os.sep + fname_rel[2:]
# return fname, fname_strip, fname_rel
@@ -221,7 +221,7 @@ def mat4x4str(mat):
def getVertsFromGroup(me, group_index):
ret = []
- for i, v in enumerate(me.verts):
+ for i, v in enumerate(me.vertices):
for g in v.groups:
if g.group == group_index:
ret.append((i, g.weight))
@@ -243,11 +243,11 @@ def BPyMesh_meshWeight2List(ob):
if not len_groupNames:
# no verts? return a vert aligned empty list
- return [[] for i in range(len(me.verts))], []
+ return [[] for i in range(len(me.vertices))], []
else:
- vWeightList= [[0.0]*len_groupNames for i in range(len(me.verts))]
+ vWeightList= [[0.0]*len_groupNames for i in range(len(me.vertices))]
- for i, v in enumerate(me.verts):
+ for i, v in enumerate(me.vertices):
for g in v.groups:
vWeightList[i][g.group] = g.weight
@@ -305,7 +305,8 @@ def write(filename, batch_objects = None, \
BATCH_OWN_DIR = False
):
- bpy.ops.object.mode_set(mode='OBJECT')
+ if bpy.context.object:
+ bpy.ops.object.mode_set(mode='OBJECT')
# ----------------- Batch support!
if BATCH_ENABLE:
@@ -353,13 +354,13 @@ def write(filename, batch_objects = None, \
new_fbxpath = fbxpath # own dir option modifies, we need to keep an original
for data in data_seq: # scene or group
- newname = BATCH_FILE_PREFIX + bpy.utils.clean_name(data.name)
-# newname = BATCH_FILE_PREFIX + BPySys.bpy.utils.clean_name(data.name)
+ newname = BATCH_FILE_PREFIX + bpy.path.clean_name(data.name)
+# newname = BATCH_FILE_PREFIX + BPySys.bpy.path.clean_name(data.name)
if BATCH_OWN_DIR:
new_fbxpath = fbxpath + newname + os.sep
- # path may alredy exist
+ # path may already exist
# TODO - might exist but be a file. unlikely but should probably account for it.
if bpy.utils.exists(new_fbxpath) == 0:
@@ -391,7 +392,7 @@ def write(filename, batch_objects = None, \
# Call self with modified args
- # Dont pass batch options since we alredy usedt them
+ # Dont pass batch options since we already usedt them
write(filename, data.objects,
context,
False,
@@ -561,7 +562,7 @@ def write(filename, batch_objects = None, \
elif type =='CAMERA':
# elif ob and type =='Camera':
y = matrix_rot * Vector((0.0, 1.0, 0.0))
- matrix_rot = RotationMatrix(math.pi/2, 3, y) * matrix_rot
+ matrix_rot = Matrix.Rotation(math.pi/2, 3, y) * matrix_rot
return matrix_rot
@@ -663,7 +664,7 @@ def write(filename, batch_objects = None, \
rot = tuple(matrix_rot.to_euler())
elif ob and ob.type =='Camera':
y = matrix_rot * Vector((0.0, 1.0, 0.0))
- matrix_rot = RotationMatrix(math.pi/2, 3, y) * matrix_rot
+ matrix_rot = Matrix.Rotation(math.pi/2, 3, y) * matrix_rot
rot = tuple(matrix_rot.to_euler())
else:
rot = tuple(matrix_rot.to_euler())
@@ -947,10 +948,7 @@ def write(filename, batch_objects = None, \
render = scene.render
width = render.resolution_x
height = render.resolution_y
-# render = scene.render
-# width = render.sizeX
-# height = render.sizeY
- aspect = float(width)/height
+ aspect = width / height
data = my_cam.blenObject.data
@@ -962,11 +960,9 @@ def write(filename, batch_objects = None, \
file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",%.6f' % math.degrees(data.angle))
file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1')
file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1')
- file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",14.0323972702026')
+ # file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",14.0323972702026')
file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shift_x) # not sure if this is in the correct units?
-# file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shiftX) # not sure if this is in the correct units?
file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shift_y) # ditto
-# file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shiftY) # ditto
file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0,0,0')
file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0')
file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1')
@@ -975,7 +971,7 @@ def write(filename, batch_objects = None, \
file.write('\n\t\t\tProperty: "UseRealTimeMotionBlur", "bool", "",1')
file.write('\n\t\t\tProperty: "ResolutionMode", "enum", "",0')
file.write('\n\t\t\tProperty: "ApertureMode", "enum", "",2')
- file.write('\n\t\t\tProperty: "GateFit", "enum", "",0')
+ file.write('\n\t\t\tProperty: "GateFit", "enum", "",2')
file.write('\n\t\t\tProperty: "CameraFormat", "enum", "",0')
file.write('\n\t\t\tProperty: "AspectW", "double", "",%i' % width)
file.write('\n\t\t\tProperty: "AspectH", "double", "",%i' % height)
@@ -1086,7 +1082,7 @@ def write(filename, batch_objects = None, \
else:
do_shadow = 0
- if light.only_shadow or (not light.diffuse and not light.specular):
+ if light.use_only_shadow or (not light.diffuse and not light.specular):
# if mode & Blender.Lamp.Modes.OnlyShadow or (mode & Blender.Lamp.Modes.NoDiffuse and mode & Blender.Lamp.Modes.NoSpecular):
do_light = 0
else:
@@ -1194,7 +1190,7 @@ def write(filename, batch_objects = None, \
# mat_spec = mat.spec/2.0
mat_alpha = mat.alpha
mat_emit = mat.emit
- mat_shadeless = mat.shadeless
+ mat_shadeless = mat.use_shadeless
# mat_shadeless = mat.mode & Blender.Material.Modes.SHADELESS
if mat_shadeless:
mat_shader = 'Lambert'
@@ -1254,7 +1250,7 @@ def write(filename, batch_objects = None, \
file.write('\n\t}')
def copy_image(image):
- fn = bpy.utils.expandpath(image.filepath)
+ fn = bpy.path.abspath(image.filepath)
fn_strip = os.path.basename(fn)
if EXP_IMAGE_COPY:
@@ -1331,9 +1327,9 @@ def write(filename, batch_objects = None, \
Property: "CurrentMappingType", "enum", "",0
Property: "UVSwap", "bool", "",0''')
- file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clamp_x)
+ file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.use_clamp_x)
# file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clampX)
- file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clamp_y)
+ file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.use_clamp_y)
# file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clampY)
file.write('''
@@ -1402,7 +1398,7 @@ def write(filename, batch_objects = None, \
# TODO - this is a bit lazy, we could have a simple write loop
# for this case because all weights are 1.0 but for now this is ok
# Parent Bones arent used all that much anyway.
- vgroup_data = [(j, 1.0) for j in range(len(my_mesh.blenData.verts))]
+ vgroup_data = [(j, 1.0) for j in range(len(my_mesh.blenData.vertices))]
else:
# This bone is not a parent of this mesh object, no weights
vgroup_data = []
@@ -1491,7 +1487,7 @@ def write(filename, batch_objects = None, \
file.write('\n\t\tVertices: ')
i=-1
- for v in me.verts:
+ for v in me.vertices:
if i==-1:
file.write('%.6f,%.6f,%.6f' % tuple(v.co)); i=0
else:
@@ -1503,7 +1499,7 @@ def write(filename, batch_objects = None, \
file.write('\n\t\tPolygonVertexIndex: ')
i=-1
for f in me.faces:
- fi = f.verts[:]
+ fi = f.vertices[:]
# last index XORd w. -1 indicates end of face
fi[-1] = fi[-1] ^ -1
@@ -1523,8 +1519,8 @@ def write(filename, batch_objects = None, \
# write loose edges as faces.
for ed in me.edges:
- if ed.loose:
- ed_val = ed.verts[:]
+ if ed.is_loose:
+ ed_val = ed.vertices[:]
ed_val = ed_val[0], ed_val[-1] ^ -1
if i==-1:
@@ -1542,14 +1538,14 @@ def write(filename, batch_objects = None, \
i=-1
for ed in me.edges:
if i==-1:
- file.write('%i,%i' % (ed.verts[0], ed.verts[1]))
+ file.write('%i,%i' % (ed.vertices[0], ed.vertices[1]))
# file.write('%i,%i' % (ed.v1.index, ed.v2.index))
i=0
else:
if i==13:
file.write('\n\t\t')
i=0
- file.write(',%i,%i' % (ed.verts[0], ed.verts[1]))
+ file.write(',%i,%i' % (ed.vertices[0], ed.vertices[1]))
# file.write(',%i,%i' % (ed.v1.index, ed.v2.index))
i+=1
@@ -1564,7 +1560,7 @@ def write(filename, batch_objects = None, \
Normals: ''')
i=-1
- for v in me.verts:
+ for v in me.vertices:
if i==-1:
file.write('%.15f,%.15f,%.15f' % tuple(v.normal)); i=0
# file.write('%.15f,%.15f,%.15f' % tuple(v.no)); i=0
@@ -1588,11 +1584,11 @@ def write(filename, batch_objects = None, \
i=-1
for f in me.faces:
if i==-1:
- file.write('%i' % f.smooth); i=0
+ file.write('%i' % f.use_smooth); i=0
else:
if i==54:
file.write('\n '); i=0
- file.write(',%i' % f.smooth)
+ file.write(',%i' % f.use_smooth)
i+=1
file.write('\n\t\t}')
@@ -1606,27 +1602,23 @@ def write(filename, batch_objects = None, \
ReferenceInformationType: "Direct"
Smoothing: ''')
-# SHARP = Blender.Mesh.EdgeFlags.SHARP
i=-1
for ed in me.edges:
if i==-1:
- file.write('%i' % (ed.sharp)); i=0
-# file.write('%i' % ((ed.flag&SHARP)!=0)); i=0
+ file.write('%i' % (ed.use_edge_sharp)); i=0
else:
if i==54:
file.write('\n '); i=0
- file.write(',%i' % (ed.sharp))
-# file.write(',%i' % ((ed.flag&SHARP)!=0))
+ file.write(',%i' % (ed.use_edge_sharp))
i+=1
file.write('\n\t\t}')
-# del SHARP
# small utility function
# returns a slice of data depending on number of face verts
# data is either a MeshTextureFace or MeshColor
def face_data(data, face):
- totvert = len(f.verts)
+ totvert = len(f.vertices)
return data[:totvert]
@@ -2076,7 +2068,7 @@ def write(filename, batch_objects = None, \
# ob.copy().link(me)
# # If new mesh has no vgroups we can try add if verts are teh same
# if not me.getVertGroupNames(): # vgroups were not kept by the modifier
-# if len(me.verts) == len(orig_mesh.verts):
+# if len(me.vertices) == len(orig_mesh.vertices):
# groupNames, vWeightDict = BPyMesh.meshWeight2Dict(orig_mesh)
# BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
@@ -2763,7 +2755,7 @@ Takes: {''')
act_end = end
else:
# use existing name
- if blenAction == blenActionDefault: # have we alredy got the name
+ if blenAction == blenActionDefault: # have we already got the name
file.write('\n\tTake: "%s" {' % sane_name_mapping_take[blenAction.name])
else:
file.write('\n\tTake: "%s" {' % sane_takename(blenAction))
@@ -2782,7 +2774,7 @@ Takes: {''')
# Set the action active
for my_bone in ob_arms:
- if blenAction in my_bone.blenActionList:
+ if ob.animation_data and blenAction in my_bone.blenActionList:
ob.animation_data.action = blenAction
# print '\t\tSetting Action!', blenAction
# scene.update(1)
@@ -2918,7 +2910,7 @@ Takes: {''')
for val, frame in context_bone_anim_keys:
if frame != context_bone_anim_keys[0][1]: # not the first
file.write(',')
- # frame is alredy one less then blenders frame
+ # frame is already one less then blenders frame
file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame), val ))
if i==0: file.write('\n\t\t\t\t\t\tColor: 1,0,0')
@@ -2940,7 +2932,8 @@ Takes: {''')
# end action loop. set original actions
# do this after every loop incase actions effect eachother.
for my_bone in ob_arms:
- my_bone.blenObject.animation_data.action = my_bone.blenAction
+ if my_bone.blenObject.animation_data:
+ my_bone.blenObject.animation_data.action = my_bone.blenAction
file.write('\n}')
@@ -2964,7 +2957,7 @@ Takes: {''')
# Clear mesh data Only when writing with modifiers applied
for me in meshes_to_clear:
bpy.data.meshes.remove(me)
-# me.verts = None
+# me.vertices = None
# --------------------------- Footer
if world:
@@ -3037,7 +3030,7 @@ Takes: {''')
# --------------------------------------------
# UI Function - not a part of the exporter.
-# this is to seperate the user interface from the rest of the exporter.
+# this is to separate the user interface from the rest of the exporter.
# from Blender import Draw, Window
EVENT_NONE = 0
EVENT_EXIT = 1
@@ -3364,20 +3357,24 @@ class ExportFBX(bpy.types.Operator):
BATCH_FILE_PREFIX = StringProperty(name="Prefix", description="Prefix each file with this name", maxlen=1024, default="")
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return context.active_object
def execute(self, context):
if not self.properties.filepath:
raise Exception("filepath not set")
+ filepath = self.properties.filepath
+ filepath = bpy.path.ensure_ext(filepath, ".fbx")
+
GLOBAL_MATRIX = mtx4_identity
GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self.properties.TX_SCALE
if self.properties.TX_XROT90: GLOBAL_MATRIX = mtx4_x90n * GLOBAL_MATRIX
if self.properties.TX_YROT90: GLOBAL_MATRIX = mtx4_y90n * GLOBAL_MATRIX
if self.properties.TX_ZROT90: GLOBAL_MATRIX = mtx4_z90n * GLOBAL_MATRIX
- write(self.properties.filepath,
+ write(filepath,
None, # XXX
context,
self.properties.EXP_OBS_SELECTED,
@@ -3397,13 +3394,17 @@ class ExportFBX(bpy.types.Operator):
self.properties.BATCH_ENABLE,
self.properties.BATCH_GROUP,
self.properties.BATCH_FILE_PREFIX,
- self.properties.BATCH_OWN_DIR)
+ self.properties.BATCH_OWN_DIR,
+ )
return {'FINISHED'}
def invoke(self, context, event):
- wm = context.manager
- wm.add_fileselect(self)
+ import os
+ if not self.properties.is_property_set("filepath"):
+ self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".fbx"
+
+ context.manager.add_fileselect(self)
return {'RUNNING_MODAL'}
@@ -3415,7 +3416,7 @@ class ExportFBX(bpy.types.Operator):
# NOTES (all line numbers correspond to original export_fbx.py (under release/scripts)
# - Draw.PupMenu alternative in 2.5?, temporarily replaced PupMenu with print
-# - get rid of bpy.utils.clean_name somehow
+# - get rid of bpy.path.clean_name somehow
# + fixed: isinstance(inst, bpy.types.*) doesn't work on RNA objects: line 565
# + get rid of BPyObject_getObjectArmature, move it in RNA?
# - BATCH_ENABLE and BATCH_GROUP options: line 327
@@ -3430,24 +3431,21 @@ class ExportFBX(bpy.types.Operator):
# - bpy.data.remove_scene: line 366
# - bpy.sys.time move to bpy.sys.util?
# - new scene creation, activation: lines 327-342, 368
-# - uses bpy.utils.expandpath, *.relpath - replace at least relpath
+# - uses bpy.path.abspath, *.relpath - replace at least relpath
# SMALL or COSMETICAL
# - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version')
def menu_func(self, context):
- default_path = os.path.splitext(bpy.data.filepath)[0] + ".fbx"
- self.layout.operator(ExportFBX.bl_idname, text="Autodesk FBX (.fbx)").filepath = default_path
+ self.layout.operator(ExportFBX.bl_idname, text="Autodesk FBX (.fbx)")
def register():
- bpy.types.register(ExportFBX)
bpy.types.INFO_MT_file_export.append(menu_func)
def unregister():
- bpy.types.unregister(ExportFBX)
bpy.types.INFO_MT_file_export.remove(menu_func)
if __name__ == "__main__":
diff --git a/release/scripts/io/export_mdd.py b/release/scripts/io/export_mdd.py
index d2e53070910..b2eda13fc8f 100644
--- a/release/scripts/io/export_mdd.py
+++ b/release/scripts/io/export_mdd.py
@@ -65,7 +65,7 @@ def check_vertcount(mesh, vertcount):
'''
check and make sure the vertcount is consistent throughout the frame range
'''
- if len(mesh.verts) != vertcount:
+ if len(mesh.vertices) != vertcount:
raise Exception('Error, number of verts has changed during animation, cannot export')
f.close()
zero_file(filepath)
@@ -94,7 +94,7 @@ def write(filename, sce, ob, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS):
[0.0, 0.0, 0.0, 1.0],\
)
- numverts = len(me.verts)
+ numverts = len(me.vertices)
numframes = PREF_ENDFRAME - PREF_STARTFRAME + 1
PREF_FPS = float(PREF_FPS)
@@ -114,7 +114,7 @@ def write(filename, sce, ob, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS):
check_vertcount(me, numverts)
me.transform(mat_flip * ob.matrix_world)
- f.write(pack(">%df" % (numverts * 3), *[axis for v in me.verts for axis in v.co]))
+ f.write(pack(">%df" % (numverts * 3), *[axis for v in me.vertices for axis in v.co]))
for frame in range(PREF_STARTFRAME, PREF_ENDFRAME + 1):#in order to start at desired frame
"""
@@ -128,10 +128,10 @@ def write(filename, sce, ob, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS):
me.transform(mat_flip * ob.matrix_world)
# Write the vertex data
- f.write(pack(">%df" % (numverts * 3), *[axis for v in me.verts for axis in v.co]))
+ f.write(pack(">%df" % (numverts * 3), *[axis for v in me.vertices for axis in v.co]))
"""
- me_tmp.verts= None
+ me_tmp.vertices= None
"""
f.close()
@@ -165,36 +165,43 @@ class ExportMDD(bpy.types.Operator):
frame_start = IntProperty(name="Start Frame", description="Start frame for baking", min=minframe, max=maxframe, default=1)
frame_end = IntProperty(name="End Frame", description="End frame for baking", min=minframe, max=maxframe, default=250)
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
ob = context.active_object
return (ob and ob.type == 'MESH')
def execute(self, context):
- if not self.properties.filepath:
- raise Exception("filename not set")
- write(self.properties.filepath, context.scene, context.active_object,
- self.properties.frame_start, self.properties.frame_end, self.properties.fps)
+ filepath = self.properties.filepath
+ filepath = bpy.path.ensure_ext(filepath, ".mdd")
+
+ write(filepath,
+ context.scene,
+ context.active_object,
+ self.properties.frame_start,
+ self.properties.frame_end,
+ self.properties.fps,
+ )
+
return {'FINISHED'}
def invoke(self, context, event):
- wm = context.manager
- wm.add_fileselect(self)
+ import os
+ if not self.properties.is_property_set("filepath"):
+ self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".mdd"
+
+ context.manager.add_fileselect(self)
return {'RUNNING_MODAL'}
def menu_func(self, context):
- import os
- default_path = os.path.splitext(bpy.data.filepath)[0] + ".mdd"
- self.layout.operator(ExportMDD.bl_idname, text="Lightwave Point Cache (.mdd)").filepath = default_path
+ self.layout.operator(ExportMDD.bl_idname, text="Lightwave Point Cache (.mdd)")
def register():
- bpy.types.register(ExportMDD)
bpy.types.INFO_MT_file_export.append(menu_func)
def unregister():
- bpy.types.unregister(ExportMDD)
bpy.types.INFO_MT_file_export.remove(menu_func)
if __name__ == "__main__":
diff --git a/release/scripts/io/export_obj.py b/release/scripts/io/export_obj.py
index 626b92c3591..53c4a324ed1 100644
--- a/release/scripts/io/export_obj.py
+++ b/release/scripts/io/export_obj.py
@@ -18,13 +18,6 @@
# <pep8 compliant>
-"""
-Name: 'Wavefront (.obj)...'
-Blender: 248
-Group: 'Export'
-Tooltip: 'Save a Wavefront OBJ File'
-"""
-
__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone"
__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org']
__version__ = "1.21"
@@ -49,16 +42,6 @@ import shutil
import bpy
import mathutils
-
-# Returns a tuple - path,extension.
-# 'hello.obj' > ('hello', '.obj')
-def splitExt(path):
- dotidx = path.rfind('.')
- if dotidx == -1:
- return path, ''
- else:
- return path[:dotidx], path[dotidx:]
-
def fixName(name):
if name == None:
return 'None'
@@ -73,7 +56,7 @@ def write_mtl(scene, filepath, copy_images, mtl_dict):
dest_dir = os.path.dirname(filepath)
def copy_image(image):
- fn = bpy.utils.expandpath(image.filepath)
+ fn = bpy.path.abspath(image.filepath)
fn_strip = os.path.basename(fn)
if copy_images:
rel = fn_strip
@@ -88,7 +71,7 @@ def write_mtl(scene, filepath, copy_images, mtl_dict):
file = open(filepath, "w")
# XXX
-# file.write('# Blender MTL File: %s\n' % Blender.Get('filepath').split('\\')[-1].split('/')[-1])
+# file.write('# Blender MTL File: %s\n' % Blender.Get('filepath').split('\\')[-1].split('/')[-1])
file.write('# Material Count: %i\n' % len(mtl_dict))
# Write material/image combinations we have used.
for key, (mtl_mat_name, mat, img) in mtl_dict.items():
@@ -100,7 +83,7 @@ def write_mtl(scene, filepath, copy_images, mtl_dict):
if mat:
file.write('Ns %.6f\n' % ((mat.specular_hardness-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's
- file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.ambient for c in worldAmb]) ) # Ambient, uses mirror colour,
+ file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.ambient for c in worldAmb]) ) # Ambient, uses mirror colour,
file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.diffuse_intensity for c in mat.diffuse_color]) ) # Diffuse
file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.specular_intensity for c in mat.specular_color]) ) # Specular
if hasattr(mat, "ior"):
@@ -110,7 +93,7 @@ def write_mtl(scene, filepath, copy_images, mtl_dict):
file.write('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve)
# 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting.
- if mat.shadeless:
+ if mat.use_shadeless:
file.write('illum 0\n') # ignore lighting
elif mat.specular_intensity == 0:
file.write('illum 1\n') # no specular.
@@ -120,25 +103,25 @@ def write_mtl(scene, filepath, copy_images, mtl_dict):
else:
#write a dummy material here?
file.write('Ns 0\n')
- file.write('Ka %.6f %.6f %.6f\n' % tuple([c for c in worldAmb]) ) # Ambient, uses mirror colour,
+ file.write('Ka %.6f %.6f %.6f\n' % tuple([c for c in worldAmb]) ) # Ambient, uses mirror colour,
file.write('Kd 0.8 0.8 0.8\n')
file.write('Ks 0.8 0.8 0.8\n')
file.write('d 1\n') # No alpha
file.write('illum 2\n') # light normaly
# Write images!
- if img: # We have an image on the face!
+ if img: # We have an image on the face!
# write relative image path
rel = copy_image(img)
file.write('map_Kd %s\n' % rel) # Diffuse mapping image
-# file.write('map_Kd %s\n' % img.filepath.split('\\')[-1].split('/')[-1]) # Diffuse mapping image
+# file.write('map_Kd %s\n' % img.filepath.split('\\')[-1].split('/')[-1]) # Diffuse mapping image
elif mat: # No face image. if we havea material search for MTex image.
for mtex in mat.texture_slots:
if mtex and mtex.texture.type == 'IMAGE':
try:
filepath = copy_image(mtex.texture.image)
-# filepath = mtex.texture.image.filepath.split('\\')[-1].split('/')[-1]
+# filepath = mtex.texture.image.filepath.split('\\')[-1].split('/')[-1]
file.write('map_Kd %s\n' % filepath) # Diffuse mapping image
break
except:
@@ -164,8 +147,8 @@ def copy_file(source, dest):
def copy_images(dest_dir):
if dest_dir[-1] != os.sep:
dest_dir += os.sep
-# if dest_dir[-1] != sys.sep:
-# dest_dir += sys.sep
+# if dest_dir[-1] != sys.sep:
+# dest_dir += sys.sep
# Get unique image names
uniqueImages = {}
@@ -188,20 +171,20 @@ def copy_images(dest_dir):
# Now copy images
copyCount = 0
-# for bImage in uniqueImages.values():
-# image_path = bpy.utils.expandpath(bImage.filepath)
-# if bpy.sys.exists(image_path):
-# # Make a name for the target path.
-# dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
-# if not bpy.utils.exists(dest_image_path): # Image isnt alredy there
-# print('\tCopying "%s" > "%s"' % (image_path, dest_image_path))
-# copy_file(image_path, dest_image_path)
-# copyCount+=1
+# for bImage in uniqueImages.values():
+# image_path = bpy.path.abspath(bImage.filepath)
+# if bpy.sys.exists(image_path):
+# # Make a name for the target path.
+# dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
+# if not bpy.utils.exists(dest_image_path): # Image isnt already there
+# print('\tCopying "%s" > "%s"' % (image_path, dest_image_path))
+# copy_file(image_path, dest_image_path)
+# copyCount+=1
-# paths= bpy.util.copy_images(uniqueImages.values(), dest_dir)
+# paths= bpy.util.copy_images(uniqueImages.values(), dest_dir)
print('\tCopied %d images' % copyCount)
-# print('\tCopied %d images' % copyCount)
+# print('\tCopied %d images' % copyCount)
# XXX not converted
def test_nurbs_compat(ob):
@@ -224,8 +207,8 @@ def write_nurb(file, ob, ob_mat):
Vector = Blender.mathutils.Vector
for nu in cu:
- if nu.type==0: DEG_ORDER_U = 1
- else: DEG_ORDER_U = nu.orderU-1 # Tested to be correct
+ if nu.type==0: DEG_ORDER_U = 1
+ else: DEG_ORDER_U = nu.orderU-1 # Tested to be correct
if nu.type==1:
print("\tWarning, bezier curve:", ob.name, "only poly and nurbs curves supported")
@@ -282,7 +265,7 @@ def write_nurb(file, ob, ob_mat):
return tot_verts
-def write(filepath, objects, scene,
+def write_file(filepath, objects, scene,
EXPORT_TRI=False,
EXPORT_EDGES=False,
EXPORT_NORMALS=False,
@@ -299,7 +282,7 @@ def write(filepath, objects, scene,
EXPORT_POLYGROUPS=False,
EXPORT_CURVE_AS_NURBS=True):
'''
- Basic write function. The context and options must be alredy set
+ Basic write function. The context and options must be already set
This can be accessed externaly
eg.
write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options.
@@ -325,10 +308,10 @@ def write(filepath, objects, scene,
of vertices is the face's group
"""
weightDict = {}
- for vert_index in face.verts:
-# for vert in face:
+ for vert_index in face.vertices:
+# for vert in face:
vWeights = vWeightMap[vert_index]
-# vWeights = vWeightMap[vert]
+# vWeights = vWeightMap[vert]
for vGroupName, weight in vWeights:
weightDict[vGroupName] = weightDict.get(vGroupName, 0) + weight
@@ -343,7 +326,7 @@ def write(filepath, objects, scene,
def getVertsFromGroup(me, group_index):
ret = []
- for i, v in enumerate(me.verts):
+ for i, v in enumerate(me.vertices):
for g in v.groups:
if g.group == group_index:
ret.append((i, g.weight))
@@ -355,8 +338,8 @@ def write(filepath, objects, scene,
temp_mesh_name = '~tmp-mesh'
time1 = time.clock()
-# time1 = sys.time()
-# scn = Scene.GetCurrent()
+# time1 = sys.time()
+# scn = Scene.GetCurrent()
file = open(filepath, "w")
@@ -370,7 +353,7 @@ def write(filepath, objects, scene,
file.write('mtllib %s\n' % ( mtlfilepath.split('\\')[-1].split('/')[-1] ))
if EXPORT_ROTX90:
- mat_xrot90= mathutils.RotationMatrix(-math.pi/2, 4, 'X')
+ mat_xrot90= mathutils.Matrix.Rotation(-math.pi/2, 4, 'X')
# Initialize totals, these are updated each object
totverts = totuvco = totno = 1
@@ -408,15 +391,15 @@ def write(filepath, objects, scene,
for ob, ob_mat in obs:
# XXX postponed
-# # Nurbs curve support
-# if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob):
-# if EXPORT_ROTX90:
-# ob_mat = ob_mat * mat_xrot90
+# # Nurbs curve support
+# if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob):
+# if EXPORT_ROTX90:
+# ob_mat = ob_mat * mat_xrot90
-# totverts += write_nurb(file, ob, ob_mat)
+# totverts += write_nurb(file, ob, ob_mat)
-# continue
-# end nurbs
+# continue
+# end nurbs
if ob.type != 'MESH':
continue
@@ -428,16 +411,19 @@ def write(filepath, objects, scene,
else:
me.transform(ob_mat)
-# # Will work for non meshes now! :)
-# me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn)
-# if not me:
-# continue
+# # Will work for non meshes now! :)
+# me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn)
+# if not me:
+# continue
if EXPORT_UV:
faceuv = len(me.uv_textures) > 0
+ uv_layer = me.active_uv_texture.data[:]
else:
faceuv = False
+ me_verts = me.vertices[:]
+
# XXX - todo, find a better way to do triangulation
# ...removed convert_to_triface because it relies on editmesh
'''
@@ -446,7 +432,7 @@ def write(filepath, objects, scene,
# Add a dummy object to it.
has_quads = False
for f in me.faces:
- if f.verts[3] != 0:
+ if f.vertices[3] != 0:
has_quads = True
break
@@ -468,7 +454,7 @@ def write(filepath, objects, scene,
else:
edges = []
- if not (len(face_index_pairs)+len(edges)+len(me.verts)): # Make sure there is somthing to write
+ if not (len(face_index_pairs)+len(edges)+len(me.vertices)): # Make sure there is somthing to write
# clean up
bpy.data.meshes.remove(me)
@@ -479,13 +465,13 @@ def write(filepath, objects, scene,
# High Quality Normals
if EXPORT_NORMALS and face_index_pairs:
me.calc_normals()
-# if EXPORT_NORMALS_HQ:
-# BPyMesh.meshCalcNormals(me)
-# else:
-# # transforming normals is incorrect
-# # when the matrix is scaled,
-# # better to recalculate them
-# me.calcNormals()
+# if EXPORT_NORMALS_HQ:
+# BPyMesh.meshCalcNormals(me)
+# else:
+# # transforming normals is incorrect
+# # when the matrix is scaled,
+# # better to recalculate them
+# me.calcNormals()
materials = me.materials
@@ -510,29 +496,24 @@ def write(filepath, objects, scene,
if EXPORT_KEEP_VERT_ORDER:
pass
elif faceuv:
- # XXX update
- tface = me.active_uv_texture.data
-
- face_index_pairs.sort(key=lambda a: (a[0].material_index, hash(tface[a[1]].image), a[0].smooth))
+ face_index_pairs.sort(key=lambda a: (a[0].material_index, hash(uv_layer[a[1]].image), a[0].use_smooth))
elif len(materials) > 1:
- face_index_pairs.sort(key = lambda a: (a[0].material_index, a[0].smooth))
+ face_index_pairs.sort(key = lambda a: (a[0].material_index, a[0].use_smooth))
else:
# no materials
- face_index_pairs.sort(key = lambda a: a[0].smooth)
-# if EXPORT_KEEP_VERT_ORDER:
-# pass
-# elif faceuv:
-# try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth))
-# except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth)))
-# elif len(materials) > 1:
-# try: faces.sort(key = lambda a: (a.mat, a.smooth))
-# except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth)))
-# else:
-# # no materials
-# try: faces.sort(key = lambda a: a.smooth)
-# except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth))
-
- faces = [pair[0] for pair in face_index_pairs]
+ face_index_pairs.sort(key = lambda a: a[0].use_smooth)
+# if EXPORT_KEEP_VERT_ORDER:
+# pass
+# elif faceuv:
+# try: faces.sort(key = lambda a: (a.mat, a.image, a.use_smooth))
+# except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.use_smooth), (b.mat, b.image, b.use_smooth)))
+# elif len(materials) > 1:
+# try: faces.sort(key = lambda a: (a.mat, a.use_smooth))
+# except: faces.sort(lambda a,b: cmp((a.mat, a.use_smooth), (b.mat, b.use_smooth)))
+# else:
+# # no materials
+# try: faces.sort(key = lambda a: a.use_smooth)
+# except: faces.sort(lambda a,b: cmp(a.use_smooth, b.use_smooth))
# Set the default mat to no material and no image.
contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get.
@@ -553,28 +534,17 @@ def write(filepath, objects, scene,
# Vert
- for v in me.verts:
+ for v in me_verts:
file.write('v %.6f %.6f %.6f\n' % tuple(v.co))
# UV
if faceuv:
- uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/
+ uv_face_mapping = [[0,0,0,0] for i in range(len(face_index_pairs))] # a bit of a waste for tri's :/
uv_dict = {} # could use a set() here
- uv_layer = me.active_uv_texture
+ uv_layer = me.active_uv_texture.data
for f, f_index in face_index_pairs:
-
- tface = uv_layer.data[f_index]
-
- # workaround, since tface.uv iteration is wrong atm
- uvs = tface.uv
- # uvs = [tface.uv1, tface.uv2, tface.uv3]
-
- # # add another UV if it's a quad
- # if len(f.verts) == 4:
- # uvs.append(tface.uv4)
-
- for uv_index, uv in enumerate(uvs):
+ for uv_index, uv in enumerate(uv_layer[f_index].uv):
uvkey = veckey2d(uv)
try:
uv_face_mapping[f_index][uv_index] = uv_dict[uvkey]
@@ -582,27 +552,16 @@ def write(filepath, objects, scene,
uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict)
file.write('vt %.6f %.6f\n' % tuple(uv))
-# uv_dict = {} # could use a set() here
-# for f_index, f in enumerate(faces):
-
-# for uv_index, uv in enumerate(f.uv):
-# uvkey = veckey2d(uv)
-# try:
-# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey]
-# except:
-# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict)
-# file.write('vt %.6f %.6f\n' % tuple(uv))
-
uv_unique_count = len(uv_dict)
-# del uv, uvkey, uv_dict, f_index, uv_index
+# del uv, uvkey, uv_dict, f_index, uv_index
# Only need uv_unique_count and uv_face_mapping
# NORMAL, Smooth/Non smoothed.
if EXPORT_NORMALS:
- for f in faces:
- if f.smooth:
- for vIdx in f.verts:
- v = me.verts[vIdx]
+ for f, f_index in face_index_pairs:
+ if f.use_smooth:
+ for v_idx in f.vertices:
+ v = me_verts[v_idx]
noKey = veckey3d(v.normal)
if noKey not in globalNormals:
globalNormals[noKey] = totno
@@ -622,66 +581,66 @@ def write(filepath, objects, scene,
# XXX
if EXPORT_POLYGROUPS:
# Retrieve the list of vertex groups
-# vertGroupNames = me.getVertGroupNames()
+# vertGroupNames = me.getVertGroupNames()
currentVGroup = ''
# Create a dictionary keyed by face id and listing, for each vertex, the vertex groups it belongs to
- vgroupsMap = [[] for _i in range(len(me.verts))]
-# vgroupsMap = [[] for _i in xrange(len(me.verts))]
+ vgroupsMap = [[] for _i in range(len(me_verts))]
+# vgroupsMap = [[] for _i in xrange(len(me_verts))]
for g in ob.vertex_groups:
-# for vertexGroupName in vertGroupNames:
- for vIdx, vWeight in getVertsFromGroup(me, g.index):
-# for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1):
- vgroupsMap[vIdx].append((g.name, vWeight))
+# for vertexGroupName in vertGroupNames:
+ for v_idx, vWeight in getVertsFromGroup(me, g.index):
+# for v_idx, vWeight in me.getVertsFromGroup(vertexGroupName, 1):
+ vgroupsMap[v_idx].append((g.name, vWeight))
- for f_index, f in enumerate(faces):
- f_v = [{"index": index, "vertex": me.verts[index]} for index in f.verts]
+ for f, f_index in face_index_pairs:
+ f_v = [me_verts[v_idx] for v_idx in f.vertices]
- # if f.verts[3] == 0:
- # f_v.pop()
+ # if f.vertices[3] == 0:
+ # f_v.pop()
-# f_v= f.v
- f_smooth= f.smooth
+# f_v= f.v
+ f_smooth= f.use_smooth
f_mat = min(f.material_index, len(materialNames)-1)
-# f_mat = min(f.mat, len(materialNames)-1)
+# f_mat = min(f.mat, len(materialNames)-1)
if faceuv:
- tface = me.active_uv_texture.data[face_index_pairs[f_index][1]]
+ tface = uv_layer[f_index]
f_image = tface.image
f_uv = tface.uv
# f_uv= [tface.uv1, tface.uv2, tface.uv3]
- # if len(f.verts) == 4:
- # f_uv.append(tface.uv4)
-# f_image = f.image
-# f_uv= f.uv
+ # if len(f.vertices) == 4:
+ # f_uv.append(tface.uv4)
+# f_image = f.image
+# f_uv= f.uv
# MAKE KEY
if faceuv and f_image: # Object is always true.
- key = materialNames[f_mat], f_image.name
+ key = materialNames[f_mat], f_image.name
else:
- key = materialNames[f_mat], None # No image, use None instead.
+ key = materialNames[f_mat], None # No image, use None instead.
# Write the vertex group
if EXPORT_POLYGROUPS:
if len(ob.vertex_groups):
# find what vertext group the face belongs to
theVGroup = findVertexGroupName(f,vgroupsMap)
- if theVGroup != currentVGroup:
+ if theVGroup != currentVGroup:
currentVGroup = theVGroup
file.write('g %s\n' % theVGroup)
-# # Write the vertex group
-# if EXPORT_POLYGROUPS:
-# if vertGroupNames:
-# # find what vertext group the face belongs to
-# theVGroup = findVertexGroupName(f,vgroupsMap)
-# if theVGroup != currentVGroup:
-# currentVGroup = theVGroup
-# file.write('g %s\n' % theVGroup)
+# # Write the vertex group
+# if EXPORT_POLYGROUPS:
+# if vertGroupNames:
+# # find what vertext group the face belongs to
+# theVGroup = findVertexGroupName(f,vgroupsMap)
+# if theVGroup != currentVGroup:
+# currentVGroup = theVGroup
+# file.write('g %s\n' % theVGroup)
# CHECK FOR CONTEXT SWITCH
if key == contextMat:
- pass # Context alredy switched, dont do anything
+ pass # Context already switched, dont do anything
else:
if key[0] == None and key[1] == None:
# Write a null material, since we know the context has changed.
@@ -725,21 +684,21 @@ def write(filepath, objects, scene,
if f_smooth: # Smoothed, use vertex normals
for vi, v in enumerate(f_v):
file.write( ' %d/%d/%d' % \
- (v["index"] + totverts,
+ (v.index + totverts,
totuvco + uv_face_mapping[f_index][vi],
- globalNormals[ veckey3d(v["vertex"].normal) ]) ) # vert, uv, normal
+ globalNormals[ veckey3d(v.normal) ]) ) # vert, uv, normal
else: # No smoothing, face normals
no = globalNormals[ veckey3d(f.normal) ]
for vi, v in enumerate(f_v):
file.write( ' %d/%d/%d' % \
- (v["index"] + totverts,
+ (v.index + totverts,
totuvco + uv_face_mapping[f_index][vi],
no) ) # vert, uv, normal
else: # No Normals
for vi, v in enumerate(f_v):
file.write( ' %d/%d' % (\
- v["index"] + totverts,\
+ v.index + totverts,\
totuvco + uv_face_mapping[f_index][vi])) # vert, uv
face_vert_index += len(f_v)
@@ -749,25 +708,25 @@ def write(filepath, objects, scene,
if f_smooth: # Smoothed, use vertex normals
for v in f_v:
file.write( ' %d//%d' %
- (v["index"] + totverts, globalNormals[ veckey3d(v["vertex"].normal) ]) )
+ (v.index + totverts, globalNormals[ veckey3d(v.normal) ]) )
else: # No smoothing, face normals
no = globalNormals[ veckey3d(f.normal) ]
for v in f_v:
- file.write( ' %d//%d' % (v["index"] + totverts, no) )
+ file.write( ' %d//%d' % (v.index + totverts, no) )
else: # No Normals
for v in f_v:
- file.write( ' %d' % (v["index"] + totverts) )
+ file.write( ' %d' % (v.index + totverts) )
file.write('\n')
# Write edges.
if EXPORT_EDGES:
for ed in edges:
- if ed.loose:
- file.write('f %d %d\n' % (ed.verts[0] + totverts, ed.verts[1] + totverts))
+ if ed.is_loose:
+ file.write('f %d %d\n' % (ed.vertices[0] + totverts, ed.vertices[1] + totverts))
# Make the indicies global rather then per mesh
- totverts += len(me.verts)
+ totverts += len(me_verts)
if faceuv:
totuvco += uv_unique_count
@@ -783,52 +742,52 @@ def write(filepath, objects, scene,
# Now we have all our materials, save them
if EXPORT_MTL:
write_mtl(scene, mtlfilepath, EXPORT_COPY_IMAGES, mtl_dict)
-# if EXPORT_COPY_IMAGES:
-# dest_dir = os.path.basename(filepath)
-# # dest_dir = filepath
-# # # Remove chars until we are just the path.
-# # while dest_dir and dest_dir[-1] not in '\\/':
-# # dest_dir = dest_dir[:-1]
-# if dest_dir:
-# copy_images(dest_dir, mtl_dict)
-# else:
-# print('\tError: "%s" could not be used as a base for an image path.' % filepath)
+# if EXPORT_COPY_IMAGES:
+# dest_dir = os.path.basename(filepath)
+# # dest_dir = filepath
+# # # Remove chars until we are just the path.
+# # while dest_dir and dest_dir[-1] not in '\\/':
+# # dest_dir = dest_dir[:-1]
+# if dest_dir:
+# copy_images(dest_dir, mtl_dict)
+# else:
+# print('\tError: "%s" could not be used as a base for an image path.' % filepath)
print("OBJ Export time: %.2f" % (time.clock() - time1))
-# print "OBJ Export time: %.2f" % (sys.time() - time1)
-
-def do_export(filepath, context,
- EXPORT_APPLY_MODIFIERS = True, # not used
- EXPORT_ROTX90 = True, # wrong
- EXPORT_TRI = False, # ok
- EXPORT_EDGES = False,
- EXPORT_NORMALS = False, # not yet
- EXPORT_NORMALS_HQ = False, # not yet
- EXPORT_UV = True, # ok
- EXPORT_MTL = True,
- EXPORT_SEL_ONLY = True, # ok
- EXPORT_ALL_SCENES = False, # XXX not working atm
- EXPORT_ANIMATION = False,
- EXPORT_COPY_IMAGES = False,
- EXPORT_BLEN_OBS = True,
- EXPORT_GROUP_BY_OB = False,
- EXPORT_GROUP_BY_MAT = False,
- EXPORT_KEEP_VERT_ORDER = False,
- EXPORT_POLYGROUPS = False,
- EXPORT_CURVE_AS_NURBS = True):
+
+def write(filepath, context,
+ EXPORT_TRI, # ok
+ EXPORT_EDGES,
+ EXPORT_NORMALS, # not yet
+ EXPORT_NORMALS_HQ, # not yet
+ EXPORT_UV, # ok
+ EXPORT_MTL,
+ EXPORT_COPY_IMAGES,
+ EXPORT_APPLY_MODIFIERS, # ok
+ EXPORT_ROTX90, # wrong
+ EXPORT_BLEN_OBS,
+ EXPORT_GROUP_BY_OB,
+ EXPORT_GROUP_BY_MAT,
+ EXPORT_KEEP_VERT_ORDER,
+ EXPORT_POLYGROUPS,
+ EXPORT_CURVE_AS_NURBS,
+ EXPORT_SEL_ONLY, # ok
+ EXPORT_ALL_SCENES, # XXX not working atm
+ EXPORT_ANIMATION): # Not used
- base_name, ext = splitExt(filepath)
+ base_name, ext = os.path.splitext(filepath)
context_name = [base_name, '', '', ext] # Base name, scene name, frame number, extension
orig_scene = context.scene
# Exit edit mode before exporting, so current object states are exported properly.
- bpy.ops.object.mode_set(mode='OBJECT')
+ if context.object:
+ bpy.ops.object.mode_set(mode='OBJECT')
-# if EXPORT_ALL_SCENES:
-# export_scenes = bpy.data.scenes
-# else:
-# export_scenes = [orig_scene]
+# if EXPORT_ALL_SCENES:
+# export_scenes = bpy.data.scenes
+# else:
+# export_scenes = [orig_scene]
# XXX only exporting one scene atm since changing
# current scene is not possible.
@@ -837,17 +796,17 @@ def do_export(filepath, context,
export_scenes = [orig_scene]
# Export all scenes.
- for scn in export_scenes:
- # scn.makeCurrent() # If already current, this is not slow.
- # context = scn.getRenderingContext()
- orig_frame = scn.frame_current
+ for scene in export_scenes:
+ # scene.makeCurrent() # If already current, this is not slow.
+ # context = scene.getRenderingContext()
+ orig_frame = scene.frame_current
if EXPORT_ALL_SCENES: # Add scene name into the context_name
- context_name[1] = '_%s' % bpy.utils.clean_name(scn.name) # WARNING, its possible that this could cause a collision. we could fix if were feeling parranoied.
+ context_name[1] = '_%s' % bpy.path.clean_name(scene.name) # WARNING, its possible that this could cause a collision. we could fix if were feeling parranoied.
# Export an animation?
if EXPORT_ANIMATION:
- scene_frames = range(scn.frame_start, context.frame_end + 1) # Up to and including the end frame.
+ scene_frames = range(scene.frame_start, context.frame_end + 1) # Up to and including the end frame.
else:
scene_frames = [orig_frame] # Dont export an animation.
@@ -856,30 +815,39 @@ def do_export(filepath, context,
if EXPORT_ANIMATION: # Add frame to the filepath.
context_name[2] = '_%.6d' % frame
- scn.frame_current = frame
+ scene.frame_current = frame
if EXPORT_SEL_ONLY:
- export_objects = context.selected_objects
+ objects = context.selected_objects
else:
- export_objects = scn.objects
+ objects = scene.objects
full_path= ''.join(context_name)
# erm... bit of a problem here, this can overwrite files when exporting frames. not too bad.
# EXPORT THE FILE.
- write(full_path, export_objects, scn,
- EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS,
- EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL,
- EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS,
- EXPORT_ROTX90, EXPORT_BLEN_OBS,
- EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,
- EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS)
-
-
- scn.frame_current = orig_frame
+ write_file(full_path, objects, scene,
+ EXPORT_TRI,
+ EXPORT_EDGES,
+ EXPORT_NORMALS,
+ EXPORT_NORMALS_HQ,
+ EXPORT_UV,
+ EXPORT_MTL,
+ EXPORT_COPY_IMAGES,
+ EXPORT_APPLY_MODIFIERS,
+ EXPORT_ROTX90,
+ EXPORT_BLEN_OBS,
+ EXPORT_GROUP_BY_OB,
+ EXPORT_GROUP_BY_MAT,
+ EXPORT_KEEP_VERT_ORDER,
+ EXPORT_POLYGROUPS,
+ EXPORT_CURVE_AS_NURBS)
+
+
+ scene.frame_current = orig_frame
# Restore old active scene.
-# orig_scene.makeCurrent()
-# Window.WaitCursor(0)
+# orig_scene.makeCurrent()
+# Window.WaitCursor(0)
'''
@@ -904,12 +872,12 @@ class ExportOBJ(bpy.types.Operator):
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
# context group
- use_selection = BoolProperty(name="Selection Only", description="", default= False)
+ use_selection = BoolProperty(name="Selection Only", description="Export selected objects only", default= False)
use_all_scenes = BoolProperty(name="All Scenes", description="", default= False)
- use_animation = BoolProperty(name="All Animation", description="", default= False)
+ use_animation = BoolProperty(name="Animation", description="", default= False)
# object group
- use_modifiers = BoolProperty(name="Apply Modifiers", description="", default= True)
+ use_modifiers = BoolProperty(name="Apply Modifiers", description="Apply modifiers (preview resolution)", default= True)
use_rotate90 = BoolProperty(name="Rotate X90", description="", default= True)
# extra data group
@@ -933,47 +901,47 @@ class ExportOBJ(bpy.types.Operator):
def execute(self, context):
filepath = self.properties.filepath
- if not filepath.lower().endswith(".obj"):
- filepath += ".obj"
-
- do_export(filepath, context,
- EXPORT_TRI=self.properties.use_triangles,
- EXPORT_EDGES=self.properties.use_edges,
- EXPORT_NORMALS=self.properties.use_normals,
- EXPORT_NORMALS_HQ=self.properties.use_hq_normals,
- EXPORT_UV=self.properties.use_uvs,
- EXPORT_MTL=self.properties.use_materials,
- EXPORT_COPY_IMAGES=self.properties.copy_images,
- EXPORT_APPLY_MODIFIERS=self.properties.use_modifiers,
- EXPORT_ROTX90=self.properties.use_rotate90,
- EXPORT_BLEN_OBS=self.properties.use_blen_objects,
- EXPORT_GROUP_BY_OB=self.properties.group_by_object,
- EXPORT_GROUP_BY_MAT=self.properties.group_by_material,
- EXPORT_KEEP_VERT_ORDER=self.properties.keep_vertex_order,
- EXPORT_POLYGROUPS=self.properties.use_vertex_groups,
- EXPORT_CURVE_AS_NURBS=self.properties.use_nurbs,
- EXPORT_SEL_ONLY=self.properties.use_selection,
- EXPORT_ALL_SCENES=self.properties.use_all_scenes)
+ filepath = bpy.path.ensure_ext(filepath, ".obj")
+
+ write(filepath, context,
+ EXPORT_TRI=self.properties.use_triangles,
+ EXPORT_EDGES=self.properties.use_edges,
+ EXPORT_NORMALS=self.properties.use_normals,
+ EXPORT_NORMALS_HQ=self.properties.use_hq_normals,
+ EXPORT_UV=self.properties.use_uvs,
+ EXPORT_MTL=self.properties.use_materials,
+ EXPORT_COPY_IMAGES=self.properties.copy_images,
+ EXPORT_APPLY_MODIFIERS=self.properties.use_modifiers,
+ EXPORT_ROTX90=self.properties.use_rotate90,
+ EXPORT_BLEN_OBS=self.properties.use_blen_objects,
+ EXPORT_GROUP_BY_OB=self.properties.group_by_object,
+ EXPORT_GROUP_BY_MAT=self.properties.group_by_material,
+ EXPORT_KEEP_VERT_ORDER=self.properties.keep_vertex_order,
+ EXPORT_POLYGROUPS=self.properties.use_vertex_groups,
+ EXPORT_CURVE_AS_NURBS=self.properties.use_nurbs,
+ EXPORT_SEL_ONLY=self.properties.use_selection,
+ EXPORT_ALL_SCENES=self.properties.use_all_scenes,
+ EXPORT_ANIMATION=self.properties.use_animation)
return {'FINISHED'}
def invoke(self, context, event):
- wm = context.manager
- wm.add_fileselect(self)
+ import os
+ if not self.properties.is_property_set("filepath"):
+ self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".obj"
+
+ context.manager.add_fileselect(self)
return {'RUNNING_MODAL'}
def menu_func(self, context):
- default_path = os.path.splitext(bpy.data.filepath)[0] + ".obj"
- self.layout.operator(ExportOBJ.bl_idname, text="Wavefront (.obj)").filepath = default_path
+ self.layout.operator(ExportOBJ.bl_idname, text="Wavefront (.obj)")
def register():
- bpy.types.register(ExportOBJ)
bpy.types.INFO_MT_file_export.append(menu_func)
def unregister():
- bpy.types.unregister(ExportOBJ)
bpy.types.INFO_MT_file_export.remove(menu_func)
@@ -986,4 +954,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/io/export_ply.py b/release/scripts/io/export_ply.py
index 0b936bdceb2..1a4fd7a6ff9 100644
--- a/release/scripts/io/export_ply.py
+++ b/release/scripts/io/export_ply.py
@@ -99,7 +99,8 @@ def write(filename, scene, ob, \
Window.WaitCursor(1)
"""
- bpy.ops.object.mode_set(mode='OBJECT')
+ if scene.objects.active:
+ bpy.ops.object.mode_set(mode='OBJECT')
#mesh = BPyMesh.getMeshFromObject(ob, None, EXPORT_APPLY_MODIFIERS, False, scn) # XXX
if EXPORT_APPLY_MODIFIERS:
@@ -146,7 +147,7 @@ def write(filename, scene, ob, \
# incase
color = uvcoord = uvcoord_key = normal = normal_key = None
- mesh_verts = mesh.verts # save a lookup
+ mesh_verts = mesh.vertices # save a lookup
ply_verts = [] # list of dictionaries
# vdict = {} # (index, normal, uv) -> new index
vdict = [{} for i in range(len(mesh_verts))]
@@ -155,7 +156,7 @@ def write(filename, scene, ob, \
for i, f in enumerate(mesh.faces):
- smooth = f.smooth
+ smooth = f.use_smooth
if not smooth:
normal = tuple(f.normal)
normal_key = rvec3d(normal)
@@ -167,7 +168,7 @@ def write(filename, scene, ob, \
col = active_col_layer[i]
col = col.color1, col.color2, col.color3, col.color4
- f_verts = f.verts
+ f_verts = f.vertices
pf = ply_faces[i]
for j, vidx in enumerate(f_verts):
@@ -274,16 +275,15 @@ class ExportPLY(bpy.types.Operator):
use_uvs = BoolProperty(name="UVs", description="Exort the active UV layer", default=True)
use_colors = BoolProperty(name="Vertex Colors", description="Exort the active vertex color layer", default=True)
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return context.active_object != None
def execute(self, context):
- # print("Selected: " + context.active_object.name)
+ filepath = self.properties.filepath
+ filepath = bpy.path.ensure_ext(filepath, ".ply")
- if not self.properties.filepath:
- raise Exception("filename not set")
-
- write(self.properties.filepath, context.scene, context.active_object,\
+ write(filepath, context.scene, context.active_object,\
EXPORT_APPLY_MODIFIERS=self.properties.use_modifiers,
EXPORT_NORMALS=self.properties.use_normals,
EXPORT_UV=self.properties.use_uvs,
@@ -293,8 +293,11 @@ class ExportPLY(bpy.types.Operator):
return {'FINISHED'}
def invoke(self, context, event):
- wm = context.manager
- wm.add_fileselect(self)
+ import os
+ if not self.properties.is_property_set("filepath"):
+ self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".ply"
+
+ context.manager.add_fileselect(self)
return {'RUNNING_MODAL'}
def draw(self, context):
@@ -310,18 +313,14 @@ class ExportPLY(bpy.types.Operator):
def menu_func(self, context):
- import os
- default_path = os.path.splitext(bpy.data.filepath)[0] + ".ply"
- self.layout.operator(ExportPLY.bl_idname, text="Stanford (.ply)").filepath = default_path
+ self.layout.operator(ExportPLY.bl_idname, text="Stanford (.ply)")
def register():
- bpy.types.register(ExportPLY)
bpy.types.INFO_MT_file_export.append(menu_func)
def unregister():
- bpy.types.unregister(ExportPLY)
bpy.types.INFO_MT_file_export.remove(menu_func)
if __name__ == "__main__":
diff --git a/release/scripts/io/export_x3d.py b/release/scripts/io/export_x3d.py
index 1bad80f6d8e..aafb7c922a1 100644
--- a/release/scripts/io/export_x3d.py
+++ b/release/scripts/io/export_x3d.py
@@ -81,7 +81,7 @@ from export_3ds import create_derived_objects, free_derived_objects
#
DEG2RAD=0.017453292519943295
-MATWORLD= mathutils.RotationMatrix(-90, 4, 'X')
+MATWORLD= mathutils.Matrix.Rotation(-90, 4, 'X')
####################################
# Global Variables
@@ -406,13 +406,13 @@ class x3d_class:
# if mesh.faceUV:
for face in mesh.active_uv_texture.data:
# for face in mesh.faces:
- if face.halo and 'HALO' not in mode:
+ if face.use_halo and 'HALO' not in mode:
mode += ['HALO']
- if face.billboard and 'BILLBOARD' not in mode:
+ if face.use_billboard and 'BILLBOARD' not in mode:
mode += ['BILLBOARD']
- if face.object_color and 'OBJECT_COLOR' not in mode:
+ if face.use_object_color and 'OBJECT_COLOR' not in mode:
mode += ['OBJECT_COLOR']
- if face.collision and 'COLLISION' not in mode:
+ if face.use_collision and 'COLLISION' not in mode:
mode += ['COLLISION']
# mode |= face.mode
@@ -461,7 +461,7 @@ class x3d_class:
self.writeIndented("<Shape>\n",1)
maters=mesh.materials
hasImageTexture=0
- issmooth=0
+ is_smooth = False
if len(maters) > 0 or mesh.active_uv_texture:
# if len(maters) > 0 or mesh.faceUV:
@@ -470,7 +470,7 @@ class x3d_class:
if len(maters) >= 1:
mat=maters[0]
# matFlags = mat.getMode()
- if not mat.face_texture:
+ if not mat.use_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)
@@ -516,11 +516,11 @@ class x3d_class:
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)
+ if face.use_smooth:
+ is_smooth = True
+ break
+ if is_smooth == True:
+ creaseAngle=(mesh.auto_smooth_angle)*(math.pi/180.0)
# creaseAngle=(mesh.degr)*(math.pi/180.0)
self.file.write("creaseAngle=\"%s\" " % (round(creaseAngle,self.cp)))
@@ -581,7 +581,7 @@ class x3d_class:
if self.writingcoords == 0:
self.file.write('coordIndex="')
for face in mesh.faces:
- fv = face.verts
+ fv = face.vertices
# fv = face.v
if len(fv)==3:
@@ -604,7 +604,7 @@ class x3d_class:
# mesh.transform(ob.matrix_world)
self.writeIndented("<Coordinate DEF=\"%s%s\" \n" % ("coord_",meshName), 1)
self.file.write("\t\t\t\tpoint=\"")
- for v in mesh.verts:
+ for v in mesh.vertices:
self.file.write("%.6f %.6f %.6f, " % tuple(v.co))
self.file.write("\" />")
self.writeIndented("\n", -1)
@@ -618,7 +618,7 @@ class x3d_class:
# for face in mesh.faces:
# workaround, since tface.uv iteration is wrong atm
uvs = face.uv
- # uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.verts[3] else [face.uv1, face.uv2, face.uv3]
+ # uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.vertices[3] else [face.uv1, face.uv2, face.uv3]
for uv in uvs:
# for uv in face.uv:
@@ -699,7 +699,7 @@ class x3d_class:
# specB = (mat.specCol[2]+0.001)/(1.25/(mat.spec+0.001))
transp = 1-mat.alpha
# matFlags = mat.getMode()
- if mat.shadeless:
+ if mat.use_shadeless:
# if matFlags & Blender.Material.Modes['SHADELESS']:
ambient = 1
shine = 1
@@ -731,7 +731,7 @@ class x3d_class:
def writeBackground(self, world, alltextures):
if world: worldname = world.name
else: return
- blending = (world.blend_sky, world.paper_sky, world.real_sky)
+ blending = (world.blend_sky, world.paper_sky, world.use_sky_real)
# blending = world.getSkytype()
grd = world.horizon_color
# grd = world.getHor()
@@ -794,7 +794,7 @@ class x3d_class:
pic = tex.image
# using .expandpath just in case, os.path may not expect //
- basename = os.path.basename(bpy.utils.expandpath(pic.filepath))
+ basename = os.path.basename(bpy.path.abspath(pic.filepath))
pic = alltextures[i].image
# pic = alltextures[i].getImage()
@@ -912,7 +912,7 @@ class x3d_class:
# if EXPORT_APPLY_MODIFIERS:
# if containerMesh:
- # containerMesh.verts = None
+ # containerMesh.vertices = None
self.cleanup()
@@ -964,13 +964,8 @@ class x3d_class:
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'
+ # for face in mesh.faces
+ sidename = "two" if face.use_twoside else "one"
if sidename in sided:
sided[sidename]+=1
@@ -1003,8 +998,8 @@ class x3d_class:
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=0x%x (enum)" % face.blend_type)
+ if face.blend_type == Mesh.FaceTranspModes.SOLID:
print("Debug: face.transp.SOLID")
if face.image:
@@ -1030,7 +1025,7 @@ class x3d_class:
# 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.vertices=%d" % len(mesh.vertices))
print("Debug: mesh.faces=%d" % len(mesh.faces))
print("Debug: mesh.materials=%d" % len(mesh.materials))
@@ -1140,7 +1135,7 @@ class x3d_class:
# Callbacks, needed before Main
##########################################################
-def x3d_export(filename,
+def write(filename,
context,
EXPORT_APPLY_MODIFIERS=False,
EXPORT_TRI=False,
@@ -1156,8 +1151,9 @@ def x3d_export(filename,
scene = context.scene
world = scene.world
-
- bpy.ops.object.mode_set(mode='OBJECT')
+
+ if scene.objects.active:
+ bpy.ops.object.mode_set(mode='OBJECT')
# XXX these are global textures while .Get() returned only scene's?
alltextures = bpy.data.textures
@@ -1174,47 +1170,6 @@ def x3d_export(filename,
)
-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
-#########################################################
-
-
from bpy.props import *
class ExportX3D(bpy.types.Operator):
@@ -1232,26 +1187,35 @@ class ExportX3D(bpy.types.Operator):
compress = BoolProperty(name="Compress", description="GZip the resulting file, requires a full python install", default=False)
def execute(self, context):
- x3d_export(self.properties.filepath, context, self.properties.apply_modifiers, self.properties.triangulate, self.properties.compress)
+ filepath = self.properties.filepath
+ filepath = bpy.path.ensure_ext(filepath, ".x3d")
+
+ write(filepath,
+ context,
+ self.properties.apply_modifiers,
+ self.properties.triangulate,
+ self.properties.compress,
+ )
+
return {'FINISHED'}
def invoke(self, context, event):
- wm = context.manager
- wm.add_fileselect(self)
+ import os
+ if not self.properties.is_property_set("filepath"):
+ self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".x3d"
+
+ context.manager.add_fileselect(self)
return {'RUNNING_MODAL'}
def menu_func(self, context):
- default_path = os.path.splitext(bpy.data.filepath)[0] + ".x3d"
- self.layout.operator(ExportX3D.bl_idname, text="X3D Extensible 3D (.x3d)").filepath = default_path
+ self.layout.operator(ExportX3D.bl_idname, text="X3D Extensible 3D (.x3d)")
def register():
- bpy.types.register(ExportX3D)
bpy.types.INFO_MT_file_export.append(menu_func)
def unregister():
- bpy.types.unregister(ExportX3D)
bpy.types.INFO_MT_file_export.remove(menu_func)
# NOTES
diff --git a/release/scripts/io/import_anim_bvh.py b/release/scripts/io/import_anim_bvh.py
index d497ac47065..04cae915a49 100644
--- a/release/scripts/io/import_anim_bvh.py
+++ b/release/scripts/io/import_anim_bvh.py
@@ -23,7 +23,7 @@ from math import radians
import bpy
import mathutils
-from mathutils import Vector, Euler, Matrix, RotationMatrix, TranslationMatrix
+from mathutils import Vector, Euler, Matrix
class bvh_node_class(object):
@@ -78,7 +78,7 @@ MATRIX_IDENTITY_4x4 = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0,
def eulerRotate(x, y, z, rot_order):
# Clamp all values between 0 and 360, values outside this raise an error.
- mats = [RotationMatrix(x, 3, 'X'), RotationMatrix(y, 3, 'Y'), RotationMatrix(z, 3, 'Z')]
+ mats = [Matrix.Rotation(x, 3, 'X'), Matrix.Rotation(y, 3, 'Y'), Matrix.Rotation(z, 3, 'Z')]
return (MATRIX_IDENTITY_3x3 * mats[rot_order[0]] * (mats[rot_order[1]] * (mats[rot_order[2]]))).to_euler()
# Should work but doesnt!
@@ -347,7 +347,7 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
scn = context.scene
#XXX scn.objects.selected = []
for ob in scn.objects:
- ob.selected = False
+ ob.select = False
scn.set_frame(IMPORT_START_FRAME)
@@ -356,7 +356,7 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
scn.objects.link(arm_ob)
- arm_ob.selected = True
+ arm_ob.select = True
scn.objects.active = arm_ob
print(scn.objects.active)
@@ -426,7 +426,7 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
bvh_node.parent and\
bvh_node.parent.temp.name not in ZERO_AREA_BONES and\
bvh_node.parent.rest_tail_local == bvh_node.rest_head_local:
- bvh_node.temp.connected = True
+ bvh_node.temp.use_connect = True
# Replace the editbone with the editbone name,
# to avoid memory errors accessing the editbone outside editmode
@@ -529,7 +529,7 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
prev_euler[i] = euler
if bvh_node.has_loc:
- pose_bone.location = (bone_rest_matrix_inv * TranslationMatrix(Vector((lx, ly, lz)) - bvh_node.rest_head_local)).translation_part()
+ pose_bone.location = (bone_rest_matrix_inv * Matrix.Translation(Vector((lx, ly, lz)) - bvh_node.rest_head_local)).translation_part()
if bvh_node.has_loc:
pose_bone.keyframe_insert("location")
@@ -612,12 +612,10 @@ def menu_func(self, context):
def register():
- bpy.types.register(BvhImporter)
bpy.types.INFO_MT_file_import.append(menu_func)
def unregister():
- bpy.types.unregister(BvhImporter)
bpy.types.INFO_MT_file_import.remove(menu_func)
if __name__ == "__main__":
diff --git a/release/scripts/io/import_scene_3ds.py b/release/scripts/io/import_scene_3ds.py
index 7b3004d4f52..6378d93df62 100644
--- a/release/scripts/io/import_scene_3ds.py
+++ b/release/scripts/io/import_scene_3ds.py
@@ -141,7 +141,7 @@ import os
import time
import struct
-from import_scene_obj import unpack_face_list, load_image
+from import_scene_obj import load_image
import bpy
import mathutils
@@ -312,10 +312,10 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
contextMaterial = None
contextMatrix_rot = None # Blender.mathutils.Matrix(); contextMatrix.identity()
#contextMatrix_tx = None # Blender.mathutils.Matrix(); contextMatrix.identity()
- contextMesh_vertls = None
+ contextMesh_vertls = None # flat array: (verts * 3)
contextMesh_facels = None
contextMeshMaterials = {} # matname:[face_idxs]
- contextMeshUV = None
+ contextMeshUV = None # flat array (verts * 2)
TEXTURE_DICT = {}
MATDICT = {}
@@ -333,113 +333,69 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
# print STRUCT_SIZE_4x3MAT, ' STRUCT_SIZE_4x3MAT'
def putContextMesh(myContextMesh_vertls, myContextMesh_facels, myContextMeshMaterials):
-
- materialFaces = set() # faces that have a material. Can optimize?
-
- # Now make copies with assigned materils.
-
- def makeMeshMaterialCopy(matName, faces):
- '''
- Make a new mesh with only face the faces that use this material.
- faces can be any iterable object - containing ints.
- '''
-
- faceVertUsers = [False] * len(myContextMesh_vertls)
- ok = 0
- for fIdx in faces:
- for vindex in myContextMesh_facels[fIdx]:
- faceVertUsers[vindex] = True
- if matName != None: # if matName is none then this is a set(), meaning we are using the untextured faces and do not need to store textured faces.
- materialFaces.add(fIdx)
- ok = 1
-
- if not ok:
- return
-
- myVertMapping = {}
- vertMappingIndex = 0
-
- vertsToUse = [i for i in range(len(myContextMesh_vertls)) if faceVertUsers[i]]
- myVertMapping = {ii: i for i, ii in enumerate(vertsToUse)}
-
- tempName= '%s_%s' % (contextObName, matName) # matName may be None.
- bmesh = bpy.data.meshes.new(tempName)
-
- if matName == None:
- img = None
+
+ bmesh = bpy.data.meshes.new(contextObName)
+ if myContextMesh_vertls:
+
+ bmesh.add_geometry(len(myContextMesh_vertls)//3, 0, len(myContextMesh_facels))
+ bmesh.vertices.foreach_set("co", myContextMesh_vertls)
+
+ eekadoodle_faces = []
+ for v1, v2, v3 in myContextMesh_facels:
+ eekadoodle_faces.extend([v3, v1, v2, 0] if v3 == 0 else [v1, v2, v3, 0])
+ bmesh.faces.foreach_set("vertices_raw", eekadoodle_faces)
+
+ if bmesh.faces and contextMeshUV:
+ bmesh.add_uv_texture()
+ uv_faces = bmesh.active_uv_texture.data[:]
else:
- bmat = MATDICT[matName][1]
- bmesh.add_material(bmat)
-# bmesh.materials = [bmat]
- try: img = TEXTURE_DICT[bmat.name]
- except: img = None
-
-# bmesh_verts = bmesh.verts
- if len(vertsToUse):
- bmesh.add_geometry(len(vertsToUse), 0, len(faces))
-
- # XXX why add extra vertex?
-# bmesh_verts.extend( [Vector()] )
- bmesh.verts.foreach_set("co", [x for tup in [myContextMesh_vertls[i] for i in vertsToUse] for x in tup])
-# bmesh_verts.extend( [myContextMesh_vertls[i] for i in vertsToUse] )
-
- # +1 because of DUMMYVERT
- bmesh.faces.foreach_set("verts_raw", unpack_face_list([[myVertMapping[vindex] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces]))
-# face_mapping = bmesh.faces.extend( [ [ bmesh_verts[ myVertMapping[vindex]+1] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces ], indexList=True )
-
- if bmesh.faces and (contextMeshUV or img):
- bmesh.add_uv_texture()
- for ii, i in enumerate(faces):
-
- # Mapped index- faces may have not been added- if so, then map to the correct index
- # BUGGY API - face_mapping is not always the right length
-# map_index = face_mapping[ii]
-
- if 1:
-# if map_index != None:
- targetFace = bmesh.faces[ii]
-# targetFace = bmesh.faces[map_index]
-
- uf = bmesh.active_uv_texture.data[ii]
-
- if contextMeshUV:
- # v.index-1 because of the DUMMYVERT
- uvs = [contextMeshUV[vindex] for vindex in myContextMesh_facels[i]]
-
- if len(myContextMesh_facels[i]) == 3:
- uf.uv1, uf.uv2, uf.uv3, uf.uv4 = uvs + [(0.0, 0.0)]
- else:
- uf.uv1, uf.uv2, uf.uv3, uf.uv4 = uvs
-# targetFace.uv = [contextMeshUV[vindex] for vindex in myContextMesh_facels[i]]
- if img:
- uf.image = img
-
- # to get this image to show up in 'Textured' shading mode
- uf.tex = True
-
- # bmesh.transform(contextMatrix)
- ob = bpy.data.objects.new(tempName, bmesh)
- SCN.objects.link(ob)
-# ob = SCN_OBJECTS.new(bmesh, tempName)
- '''
- if contextMatrix_tx:
- ob.setMatrix(contextMatrix_tx)
- '''
-
- if contextMatrix_rot:
- ob.matrix_world = contextMatrix_rot
-
- importedObjects.append(ob)
- bmesh.update()
-# bmesh.calcNormals()
-
- for matName, faces in myContextMeshMaterials.items():
- makeMeshMaterialCopy(matName, faces)
-
- if len(materialFaces) != len(myContextMesh_facels):
- # Invert material faces.
- makeMeshMaterialCopy(None, set(range(len( myContextMesh_facels ))) - materialFaces)
- #raise 'Some UnMaterialed faces', len(contextMesh.faces)
+ uv_faces = None
+
+ for mat_idx, (matName, faces) in enumerate(myContextMeshMaterials.items()):
+ if matName is None:
+ bmesh.add_material(None)
+ else:
+ bmat = MATDICT[matName][1]
+ bmesh.add_material(bmat) # can be None
+ img = TEXTURE_DICT.get(bmat.name)
+
+ if uv_faces and img:
+ for fidx in faces:
+ bmesh.faces[fidx].material_index = mat_idx
+ uf = uv_faces[fidx]
+ uf.image = img
+ uf.use_image = True
+ else:
+ for fidx in faces:
+ bmesh.faces[fidx].material_index = mat_idx
+
+ if uv_faces:
+ for fidx, uf in enumerate(uv_faces):
+ face = myContextMesh_facels[fidx]
+ v1, v2, v3 = face
+
+ # eekadoodle
+ if v3 == 0:
+ v1, v2, v3 = v3, v1, v2
+
+ uf.uv1 = contextMeshUV[v1 * 2:(v1 * 2) + 2]
+ uf.uv2 = contextMeshUV[v2 * 2:(v2 * 2) + 2]
+ uf.uv3 = contextMeshUV[v3 * 2:(v3 * 2) + 2]
+ # always a tri
+
+ ob = bpy.data.objects.new(tempName, bmesh)
+ SCN.objects.link(ob)
+
+ '''
+ if contextMatrix_tx:
+ ob.setMatrix(contextMatrix_tx)
+ '''
+
+ if contextMatrix_rot:
+ ob.matrix_world = contextMatrix_rot
+
+ importedObjects.append(ob)
+ bmesh.update()
#a spare chunk
new_chunk = chunk()
@@ -667,14 +623,10 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
new_chunk.bytes_read += 2
# print 'number of verts: ', num_verts
- def getvert():
- temp_data = struct.unpack('<3f', file.read(STRUCT_SIZE_3FLOAT))
- new_chunk.bytes_read += STRUCT_SIZE_3FLOAT #12: 3 floats x 4 bytes each
- return temp_data
-
- #contextMesh.verts.extend( [Vector(),] ) # DUMMYVERT! - remove when blenders internals are fixed.
- contextMesh_vertls = [getvert() for i in range(num_verts)]
-
+ contextMesh_vertls = struct.unpack('<%df' % (num_verts * 3), file.read(STRUCT_SIZE_3FLOAT * num_verts))
+ new_chunk.bytes_read += STRUCT_SIZE_3FLOAT * num_verts
+ # dummyvert is not used atm!
+
#print 'object verts: bytes read: ', new_chunk.bytes_read
elif (new_chunk.ID == OBJECT_FACES):
@@ -684,15 +636,11 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
new_chunk.bytes_read += 2
#print 'number of faces: ', num_faces
- def getface():
- # print '\ngetting a face'
- temp_data = file.read(STRUCT_SIZE_4UNSIGNED_SHORT)
- new_chunk.bytes_read += STRUCT_SIZE_4UNSIGNED_SHORT #4 short ints x 2 bytes each
- v1,v2,v3,dummy = struct.unpack('<4H', temp_data)
- return v1, v2, v3
-
- contextMesh_facels = [ getface() for i in range(num_faces) ]
-
+ # print '\ngetting a face'
+ temp_data = file.read(STRUCT_SIZE_4UNSIGNED_SHORT * num_faces)
+ new_chunk.bytes_read += STRUCT_SIZE_4UNSIGNED_SHORT * num_faces #4 short ints x 2 bytes each
+ contextMesh_facels = struct.unpack('<%dH' % (num_faces * 4), temp_data)
+ contextMesh_facels = [contextMesh_facels[i - 3:i] for i in range(3, (num_faces * 4) + 3, 4)]
elif (new_chunk.ID == OBJECT_MATERIAL):
# print 'elif (new_chunk.ID == OBJECT_MATERIAL):'
@@ -703,12 +651,11 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
num_faces_using_mat = struct.unpack('<H', temp_data)[0]
new_chunk.bytes_read += STRUCT_SIZE_UNSIGNED_SHORT
- def getmat():
- temp_data = file.read(STRUCT_SIZE_UNSIGNED_SHORT)
- new_chunk.bytes_read += STRUCT_SIZE_UNSIGNED_SHORT
- return struct.unpack('<H', temp_data)[0]
+
+ temp_data = file.read(STRUCT_SIZE_UNSIGNED_SHORT * num_faces_using_mat)
+ new_chunk.bytes_read += STRUCT_SIZE_UNSIGNED_SHORT * num_faces_using_mat
- contextMeshMaterials[material_name]= [ getmat() for i in range(num_faces_using_mat) ]
+ contextMeshMaterials[material_name]= struct.unpack("<%dH" % (num_faces_using_mat), temp_data)
#look up the material in all the materials
@@ -717,12 +664,9 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
num_uv = struct.unpack('<H', temp_data)[0]
new_chunk.bytes_read += 2
- def getuv():
- temp_data = file.read(STRUCT_SIZE_2FLOAT)
- new_chunk.bytes_read += STRUCT_SIZE_2FLOAT #2 float x 4 bytes each
- return mathutils.Vector( struct.unpack('<2f', temp_data) )
-
- contextMeshUV = [ getuv() for i in range(num_uv) ]
+ temp_data = file.read(STRUCT_SIZE_2FLOAT * num_uv)
+ new_chunk.bytes_read += STRUCT_SIZE_2FLOAT * num_uv
+ contextMeshUV = struct.unpack('<%df' % (num_uv * 2), temp_data)
elif (new_chunk.ID == OBJECT_TRANS_MATRIX):
# How do we know the matrix size? 54 == 4x4 48 == 4x3
@@ -771,7 +715,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
#print contextMatrix_rot
contextMatrix_rot.invert()
#print contextMatrix_rot
- #contextMatrix_tx = Blender.mathutils.TranslationMatrix(0.5 * Blender.mathutils.Vector(data[9:]))
+ #contextMatrix_tx = mathutils.Matrix.Translation(0.5 * Blender.mathutils.Vector(data[9:]))
#contextMatrix_tx.invert()
#tx.invert()
@@ -806,7 +750,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
# FINISHED LOOP
# There will be a number of objects still not added
- if contextMesh_facels != None:
+ if CreateBlenderObject:
putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)
def load_3ds(filename, context, IMPORT_CONSTRAIN_BOUNDS=10.0, IMAGE_SEARCH=True, APPLY_MATRIX=False):
@@ -883,14 +827,12 @@ def load_3ds(filename, context, IMPORT_CONSTRAIN_BOUNDS=10.0, IMAGE_SEARCH=True,
# REMOVE DUMMYVERT, - remove this in the next release when blenders internal are fixed.
-
-# for ob in importedObjects:
-# if ob.type == 'MESH':
-# # if ob.type=='Mesh':
-# me = ob.getData(mesh=1)
-# me.verts.delete([me.verts[0],])
-# if not APPLY_MATRIX:
-# me.transform(ob.matrix_world.copy().invert())
+ for ob in importedObjects:
+ if ob.type == 'MESH':
+ me = ob.data
+# me.vertices.delete([me.vertices[0],]) # XXX, todo
+ if not APPLY_MATRIX:
+ me.transform(ob.matrix_world.copy().invert())
# Done DUMMYVERT
"""
@@ -1009,15 +951,19 @@ class IMPORT_OT_autodesk_3ds(bpy.types.Operator):
# List of operator properties, the attributes will be assigned
# to the class instance from the operator settings before calling.
-
filepath = StringProperty(name="File Path", description="Filepath used for importing the 3DS file", maxlen= 1024, default= "")
-# size_constraint = FloatProperty(name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0),
-# search_images = BoolProperty(name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True),
-# apply_matrix = BoolProperty(name="Transform Fix", description="Workaround for object transformations importing incorrectly", default=False),
+ constrain_size = FloatProperty(name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0)
+ search_images = BoolProperty(name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True)
+ apply_transform = BoolProperty(name="Apply Transform", description="Workaround for object transformations importing incorrectly", default=False)
def execute(self, context):
- load_3ds(self.properties.filepath, context, 0.0, False, False)
+ load_3ds(self.properties.filepath,
+ context,
+ IMPORT_CONSTRAIN_BOUNDS=self.properties.constrain_size,
+ IMAGE_SEARCH=self.properties.search_images,
+ APPLY_MATRIX=self.properties.apply_transform)
+
return {'FINISHED'}
def invoke(self, context, event):
@@ -1030,11 +976,9 @@ def menu_func(self, context):
self.layout.operator(IMPORT_OT_autodesk_3ds.bl_idname, text="3D Studio (.3ds)")
def register():
- bpy.types.register(IMPORT_OT_autodesk_3ds)
bpy.types.INFO_MT_file_import.append(menu_func)
def unregister():
- bpy.types.unregister(IMPORT_OT_autodesk_3ds)
bpy.types.INFO_MT_file_import.remove(menu_func)
# NOTES:
diff --git a/release/scripts/io/import_scene_obj.py b/release/scripts/io/import_scene_obj.py
index afe82410557..655f797750e 100644
--- a/release/scripts/io/import_scene_obj.py
+++ b/release/scripts/io/import_scene_obj.py
@@ -82,23 +82,21 @@ def unpack_list(list_of_tuples):
# same as above except that it adds 0 for triangle faces
def unpack_face_list(list_of_tuples):
- l = []
- for t in list_of_tuples:
- face = [i for i in t]
-
- if len(face) != 3 and len(face) != 4:
- raise RuntimeError("{0} vertices in face.".format(len(face)))
-
- # rotate indices if the 4th is 0
- if len(face) == 4 and face[3] == 0:
- face = [face[3], face[0], face[1], face[2]]
+ # allocate the entire list
+ flat_ls = [0] * (len(list_of_tuples) * 4)
+ i = 0
- if len(face) == 3:
- face.append(0)
-
- l.extend(face)
+ for t in list_of_tuples:
+ if len(t) == 3:
+ if t[2] == 0:
+ t = t[1], t[2], t[0]
+ else: # assuem quad
+ if t[3] == 0 or t[2] == 0:
+ t = t[2], t[3], t[0], t[1]
- return l
+ flat_ls[i:i + len(t)] = t
+ i += 4
+ return flat_ls
def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True):
'''
@@ -139,7 +137,7 @@ def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True):
if type(from_data) in (tuple, list):
verts= [Vector(from_data[i]) for ii, i in enumerate(indices)]
else:
- verts= [from_data.verts[i].co for ii, i in enumerate(indices)]
+ verts= [from_data.vertices[i].co for ii, i in enumerate(indices)]
for i in range(len(verts)-1, 0, -1): # same as reversed(xrange(1, len(verts))):
if verts[i][1]==verts[i-1][0]:
@@ -156,7 +154,7 @@ def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True):
if type(from_data) in (tuple, list):
verts= [vert_treplet(Vector(from_data[i]), ii) for ii, i in enumerate(indices)]
else:
- verts= [vert_treplet(from_data.verts[i].co, ii) for ii, i in enumerate(indices)]
+ verts= [vert_treplet(from_data.vertices[i].co, ii) for ii, i in enumerate(indices)]
edges= [(i, i-1) for i in range(len(verts))]
if edges:
@@ -305,24 +303,28 @@ def load_image(imagepath, dirname):
if os.path.exists(imagepath):
return bpy.data.images.load(imagepath)
- variants = [os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))]
+ variants = [imagepath, os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))]
- for path in variants:
- if os.path.exists(path):
- return bpy.data.images.load(path)
- else:
- print(path, "doesn't exist")
+ for filepath in variants:
+ for nfilepath in (filepath, bpy.path.resolve_ncase(filepath)):
+ if os.path.exists(nfilepath):
+ return bpy.data.images.load(nfilepath)
# TODO comprehensiveImageLoad also searched in bpy.config.textureDir
return None
def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
-
if '_' in imagepath:
image= load_image(imagepath.replace('_', ' '), DIR)
- if image: return image
+ if image:
+ return image
- return load_image(imagepath, DIR)
+ image = load_image(imagepath, DIR)
+ if image:
+ return image
+
+ print("failed to load '%s' doesn't exist", imagepath)
+ return None
# def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
# '''
@@ -373,38 +375,32 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
# Image has alpha
# XXX bitmask won't work?
- blender_material.add_texture(texture, "UV", ("COLOR", "ALPHA"))
+ blender_material.add_texture(texture, 'UV', {'COLOR', 'ALPHA'})
texture.mipmap = True
texture.interpolation = True
texture.use_alpha = True
- blender_material.z_transparency = True
+ blender_material.use_transparency = True
blender_material.alpha = 0.0
-
-# blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL | Texture.MapTo.ALPHA)
-# texture.setImageFlags('MipMap', 'InterPol', 'UseAlpha')
-# blender_material.mode |= Material.Modes.ZTRANSP
-# blender_material.alpha = 0.0
else:
- blender_material.add_texture(texture, "UV", "COLOR")
-# blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL)
+ blender_material.add_texture(texture, 'UV', 'COLOR')
# adds textures to faces (Textured/Alt-Z mode)
# Only apply the diffuse texture to the face if the image has not been set with the inline usemat func.
unique_material_images[context_material_name]= image, has_data # set the texface image
elif type == 'Ka':
- blender_material.add_texture(texture, "UV", "AMBIENT")
+ blender_material.add_texture(texture, 'UV', 'AMBIENT')
# blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API
elif type == 'Ks':
- blender_material.add_texture(texture, "UV", "SPECULARITY")
+ blender_material.add_texture(texture, 'UV', 'SPECULARITY')
# blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC)
elif type == 'Bump':
- blender_material.add_texture(texture, "UV", "NORMAL")
+ blender_material.add_texture(texture, 'UV', 'NORMAL')
# blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR)
elif type == 'D':
- blender_material.add_texture(texture, "UV", "ALPHA")
+ blender_material.add_texture(texture, 'UV', 'ALPHA')
blender_material.z_transparency = True
blender_material.alpha = 0.0
# blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA)
@@ -413,15 +409,14 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
# Todo, unset deffuse material alpha if it has an alpha channel
elif type == 'refl':
- blender_material.add_texture(texture, "UV", "REFLECTION")
+ blender_material.add_texture(texture, 'UV', 'REFLECTION')
# blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF)
# Add an MTL with the same name as the obj if no MTLs are spesified.
temp_mtl = os.path.splitext((os.path.basename(filepath)))[0] + '.mtl'
- if os.path.exists(DIR + temp_mtl) and temp_mtl not in material_libs:
-# if sys.exists(DIR + temp_mtl) and temp_mtl not in material_libs:
+ if os.path.exists(os.path.join(DIR, temp_mtl)) and temp_mtl not in material_libs:
material_libs.append( temp_mtl )
del temp_mtl
@@ -435,11 +430,9 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
unique_material_images[None]= None, False
for libname in material_libs:
- mtlpath= DIR + libname
+ mtlpath= os.path.join(DIR, libname)
if not os.path.exists(mtlpath):
-# if not sys.exists(mtlpath):
- #print '\tError Missing MTL: "%s"' % mtlpath
- pass
+ print ("\tError Missing MTL: '%s'" % mtlpath)
else:
#print '\t\tloading mtl: "%s"' % mtlpath
context_material= None
@@ -504,49 +497,32 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
-def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS):
+def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP):
'''
- Takes vert_loc and faces, and seperates into multiple sets of
+ Takes vert_loc and faces, and separates into multiple sets of
(verts_loc, faces, unique_materials, dataname)
'''
filename = os.path.splitext((os.path.basename(filepath)))[0]
- if not SPLIT_OB_OR_GROUP and not SPLIT_MATERIALS:
+ if not SPLIT_OB_OR_GROUP:
# use the filename for the object name since we arnt chopping up the mesh.
return [(verts_loc, faces, unique_materials, filename)]
-
def key_to_name(key):
# if the key is a tuple, join it to make a string
- if type(key) == tuple:
- return '%s_%s' % key
- elif not key:
+ if not key:
return filename # assume its a string. make sure this is true if the splitting code is changed
else:
return key
# Return a key that makes the faces unique.
- if SPLIT_OB_OR_GROUP and not SPLIT_MATERIALS:
- def face_key(face):
- return face[4] # object
-
- elif not SPLIT_OB_OR_GROUP and SPLIT_MATERIALS:
- def face_key(face):
- return face[2] # material
-
- else: # Both
- def face_key(face):
- return face[4], face[2] # object,material
-
-
face_split_dict= {}
oldkey= -1 # initialize to a value that will never match the key
for face in faces:
-
- key= face_key(face)
+ key= face[4]
if oldkey != key:
# Check the key has changed.
@@ -571,7 +547,6 @@ def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP,
vert_remap[i]= new_index # set the new remapped index so we only add once and can reference next time.
face_vert_loc_indicies[enum] = new_index # remap to the local index
verts_split.append( verts_loc[i] ) # add the vert to the local verts
-
else:
face_vert_loc_indicies[enum] = vert_remap[i] # remap to the local index
@@ -581,12 +556,11 @@ def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP,
faces_split.append(face)
-
# remove one of the itemas and reorder
return [(value[0], value[1], value[2], key_to_name(key)) for key, value in list(face_split_dict.items())]
-def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, vertex_groups, dataname):
+def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, vertex_groups, dataname):
'''
Takes all the data gathered and generates a mesh, adding the new object to new_objects
deals with fgons, sharp edges and assigning materials
@@ -703,18 +677,18 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
# make sure the list isnt too big
for material in materials:
me.add_material(material)
- #me.verts.extend([(0,0,0)]) # dummy vert
+ #me.vertices.extend([(0,0,0)]) # dummy vert
me.add_geometry(len(verts_loc), 0, len(faces))
# verts_loc is a list of (x, y, z) tuples
- me.verts.foreach_set("co", unpack_list(verts_loc))
-# me.verts.extend(verts_loc)
+ me.vertices.foreach_set("co", unpack_list(verts_loc))
+# me.vertices.extend(verts_loc)
# faces is a list of (vert_indices, texco_indices, ...) tuples
# XXX faces should contain either 3 or 4 verts
# XXX no check for valid face indices
- me.faces.foreach_set("verts_raw", unpack_face_list([f[0] for f in faces]))
+ me.faces.foreach_set("vertices_raw", unpack_face_list([f[0] for f in faces]))
# face_mapping= me.faces.extend([f[0] for f in faces], indexList=True)
if verts_tex and me.faces:
@@ -752,7 +726,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
if context_smooth_group:
- blender_face.smooth= True
+ blender_face.use_smooth = True
if context_material:
if context_material_old is not context_material:
@@ -768,14 +742,12 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
blender_tface= me.uv_textures[0].data[i]
if context_material:
- image, has_data= unique_material_images[context_material]
+ image, has_data = unique_material_images[context_material]
if image: # Can be none if the material dosnt have an image.
- blender_tface.image= image
-# blender_face.image= image
- if has_data:
-# if has_data and image.depth == 32:
- blender_tface.transp = 'ALPHA'
-# blender_face.transp |= ALPHA
+ blender_tface.image = image
+ blender_tface.use_image = True
+ if has_data and image.depth == 32:
+ blender_tface.blend_type = 'ALPHA'
# BUG - Evil eekadoodle problem where faces that have vert index 0 location at 3 or 4 are shuffled.
if len(face_vert_loc_indicies)==4:
@@ -804,7 +776,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
me.add_geometry(0, len(edges), 0)
# edges should be a list of (a, b) tuples
- me.edges.foreach_set("verts", unpack_list(edges))
+ me.edges.foreach_set("vertices", unpack_list(edges))
# me_edges.extend( edges )
# del me_edges
@@ -819,8 +791,8 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
# if CREATE_FGONS and fgon_edges:
# for fgon_edge in fgon_edges.keys():
# for ed in me.edges:
-# if edges_match(fgon_edge, ed.verts):
-# ed.fgon = True
+# if edges_match(fgon_edge, ed.vertices):
+# ed.is_fgon = True
# if CREATE_FGONS and fgon_edges:
# FGON= Mesh.EdgeFlags.FGON
@@ -833,8 +805,8 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
# if unique_smooth_groups and sharp_edges:
# for sharp_edge in sharp_edges.keys():
# for ed in me.edges:
-# if edges_match(sharp_edge, ed.verts):
-# ed.sharp = True
+# if edges_match(sharp_edge, ed.vertices):
+# ed.use_edge_sharp = True
# if unique_smooth_groups and sharp_edges:
# SHARP= Mesh.EdgeFlags.SHARP
@@ -847,7 +819,6 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
# me.calcNormals()
ob= bpy.data.objects.new("Mesh", me)
- scn.objects.link(ob)
new_objects.append(ob)
# Create the vertex groups. No need to have the flag passed here since we test for the
@@ -861,7 +832,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
# me.assignVertsToGroup(group_name, group_indicies, 1.00, Mesh.AssignModes.REPLACE)
-def create_nurbs(scn, context_nurbs, vert_loc, new_objects):
+def create_nurbs(context_nurbs, vert_loc, new_objects):
'''
Add nurbs object to blender, only support one type at the moment
'''
@@ -936,8 +907,9 @@ def create_nurbs(scn, context_nurbs, vert_loc, new_objects):
if do_closed:
nu.flagU |= 1
'''
+
+ ob= bpy.data.objects.new("Mesh", me)
- ob = scn.objects.new(cu)
new_objects.append(ob)
@@ -1262,7 +1234,6 @@ def load_obj(filepath,
# bpy.ops.OBJECT_OT_select_all()
scene = context.scene
-# scn = bpy.data.scenes.active
# scn.objects.selected = []
new_objects= [] # put new objects here
@@ -1271,14 +1242,20 @@ def load_obj(filepath,
if SPLIT_OBJECTS or SPLIT_GROUPS: SPLIT_OB_OR_GROUP = True
else: SPLIT_OB_OR_GROUP = False
- for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS):
+ for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP):
# Create meshes from the data, warning 'vertex_groups' wont support splitting
- create_mesh(scene, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname)
+ create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname)
# nurbs support
# for context_nurbs in nurbs:
# create_nurbs(scn, context_nurbs, verts_loc, new_objects)
+ # Create new obj
+ for obj in new_objects:
+ scene.objects.link(obj)
+
+ scene.update()
+
axis_min= [ 1000000000]*3
axis_max= [-1000000000]*3
@@ -1320,14 +1297,13 @@ def load_obj_ui(filepath, BATCH_LOAD= False):
if BPyMessages.Error_NoFile(filepath):
return
- global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90
+ global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90
CREATE_SMOOTH_GROUPS= Draw.Create(0)
CREATE_FGONS= Draw.Create(1)
CREATE_EDGES= Draw.Create(1)
SPLIT_OBJECTS= Draw.Create(0)
SPLIT_GROUPS= Draw.Create(0)
- SPLIT_MATERIALS= Draw.Create(0)
CLAMP_SIZE= Draw.Create(10.0)
IMAGE_SEARCH= Draw.Create(1)
POLYGROUPS= Draw.Create(0)
@@ -1346,7 +1322,6 @@ def load_obj_ui(filepath, BATCH_LOAD= False):
'Separate objects from obj...',\
('Object', SPLIT_OBJECTS, 'Import OBJ Objects into Blender Objects'),\
('Group', SPLIT_GROUPS, 'Import OBJ Groups into Blender Objects'),\
- ('Split Materials', SPLIT_MATERIALS, 'Import each material into a seperate mesh'),\
'Options...',\
('Keep Vert Order', KEEP_VERT_ORDER, 'Keep vert and face order, disables some other options.'),\
('Clamp Scale:', CLAMP_SIZE, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)'),\
@@ -1359,7 +1334,6 @@ def load_obj_ui(filepath, BATCH_LOAD= False):
if KEEP_VERT_ORDER.val:
SPLIT_OBJECTS.val = False
SPLIT_GROUPS.val = False
- SPLIT_MATERIALS.val = False
'''
@@ -1381,25 +1355,25 @@ def load_obj_ui(filepath, BATCH_LOAD= False):
GLOBALS['EVENT'] = e
def do_split(e,v):
- global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER, POLYGROUPS
- if SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val:
+ global SPLIT_OBJECTS, SPLIT_GROUPS, KEEP_VERT_ORDER, POLYGROUPS
+ if SPLIT_OBJECTS.val or SPLIT_GROUPS.val:
KEEP_VERT_ORDER.val = 0
POLYGROUPS.val = 0
else:
KEEP_VERT_ORDER.val = 1
def do_vertorder(e,v):
- global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER
+ global SPLIT_OBJECTS, SPLIT_GROUPS, KEEP_VERT_ORDER
if KEEP_VERT_ORDER.val:
- SPLIT_OBJECTS.val = SPLIT_GROUPS.val = SPLIT_MATERIALS.val = 0
+ SPLIT_OBJECTS.val = SPLIT_GROUPS.val = 0
else:
- if not (SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val):
+ if not (SPLIT_OBJECTS.val or SPLIT_GROUPS.val):
KEEP_VERT_ORDER.val = 1
def do_polygroups(e,v):
- global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER, POLYGROUPS
+ global SPLIT_OBJECTS, SPLIT_GROUPS, KEEP_VERT_ORDER, POLYGROUPS
if POLYGROUPS.val:
- SPLIT_OBJECTS.val = SPLIT_GROUPS.val = SPLIT_MATERIALS.val = 0
+ SPLIT_OBJECTS.val = SPLIT_GROUPS.val = 0
def do_help(e,v):
url = __url__[0]
@@ -1419,7 +1393,7 @@ def load_obj_ui(filepath, BATCH_LOAD= False):
ui_x -= 165
ui_y -= 90
- global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90
+ global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90
Draw.Label('Import...', ui_x+9, ui_y+159, 220, 21)
Draw.BeginAlign()
@@ -1432,7 +1406,6 @@ def load_obj_ui(filepath, BATCH_LOAD= False):
Draw.BeginAlign()
SPLIT_OBJECTS = Draw.Toggle('Object', EVENT_REDRAW, ui_x+9, ui_y+89, 55, 21, SPLIT_OBJECTS.val, 'Import OBJ Objects into Blender Objects', do_split)
SPLIT_GROUPS = Draw.Toggle('Group', EVENT_REDRAW, ui_x+64, ui_y+89, 55, 21, SPLIT_GROUPS.val, 'Import OBJ Groups into Blender Objects', do_split)
- SPLIT_MATERIALS = Draw.Toggle('Split Materials', EVENT_REDRAW, ui_x+119, ui_y+89, 60, 21, SPLIT_MATERIALS.val, 'Import each material into a seperate mesh', do_split)
Draw.EndAlign()
# Only used for user feedback
@@ -1492,7 +1465,6 @@ def load_obj_ui(filepath, BATCH_LOAD= False):
CREATE_EDGES.val,\
SPLIT_OBJECTS.val,\
SPLIT_GROUPS.val,\
- SPLIT_MATERIALS.val,\
ROTATE_X90.val,\
IMAGE_SEARCH.val,\
POLYGROUPS.val
@@ -1506,7 +1478,6 @@ def load_obj_ui(filepath, BATCH_LOAD= False):
CREATE_EDGES.val,\
SPLIT_OBJECTS.val,\
SPLIT_GROUPS.val,\
- SPLIT_MATERIALS.val,\
ROTATE_X90.val,\
IMAGE_SEARCH.val,\
POLYGROUPS.val
@@ -1570,7 +1541,6 @@ class IMPORT_OT_obj(bpy.types.Operator):
CREATE_EDGES = BoolProperty(name="Lines as Edges", description="Import lines and faces with 2 verts as edge", default= True)
SPLIT_OBJECTS = BoolProperty(name="Object", description="Import OBJ Objects into Blender Objects", default= True)
SPLIT_GROUPS = BoolProperty(name="Group", description="Import OBJ Groups into Blender Objects", default= True)
- SPLIT_MATERIALS = BoolProperty(name="Split Materials", description="Import each material into a seperate mesh", default= False)
# old comment: only used for user feedback
# disabled this option because in old code a handler for it disabled SPLIT* params, it's not passed to load_obj
# KEEP_VERT_ORDER = BoolProperty(name="Keep Vert Order", description="Keep vert and face order, disables split options, enable for morph targets", default= True)
@@ -1591,7 +1561,6 @@ class IMPORT_OT_obj(bpy.types.Operator):
self.properties.CREATE_EDGES,
self.properties.SPLIT_OBJECTS,
self.properties.SPLIT_GROUPS,
- self.properties.SPLIT_MATERIALS,
self.properties.ROTATE_X90,
self.properties.IMAGE_SEARCH,
self.properties.POLYGROUPS)
@@ -1599,8 +1568,7 @@ class IMPORT_OT_obj(bpy.types.Operator):
return {'FINISHED'}
def invoke(self, context, event):
- wm = context.manager
- wm.add_fileselect(self)
+ context.manager.add_fileselect(self)
return {'RUNNING_MODAL'}
@@ -1609,11 +1577,9 @@ def menu_func(self, context):
def register():
- bpy.types.register(IMPORT_OT_obj)
bpy.types.INFO_MT_file_import.append(menu_func)
def unregister():
- bpy.types.unregister(IMPORT_OT_obj)
bpy.types.INFO_MT_file_import.remove(menu_func)
diff --git a/release/scripts/io/import_shape_mdd.py b/release/scripts/io/import_shape_mdd.py
index ec0e7696630..c7b199918a2 100644
--- a/release/scripts/io/import_shape_mdd.py
+++ b/release/scripts/io/import_shape_mdd.py
@@ -12,7 +12,7 @@
#
# 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.
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENCE BLOCK *****
@@ -66,7 +66,7 @@ def mdd_import(filepath, ob, scene, PREF_START_FRAME=0, PREF_JUMP=1):
ob.active_shape_key_index = len(ob.data.shape_keys.keys)-1
index = len(ob.data.shape_keys.keys)-1
- ob.shape_key_lock = True
+ ob.show_shape_key = True
verts = ob.data.shape_keys.keys[len(ob.data.shape_keys.keys)-1].data
@@ -74,7 +74,7 @@ def mdd_import(filepath, ob, scene, PREF_START_FRAME=0, PREF_JUMP=1):
for v in verts: # 12 is the size of 3 floats
v.co[:] = unpack('>3f', file.read(12))
#me.update()
- ob.shape_key_lock = False
+ ob.show_shape_key = False
# insert keyframes
@@ -120,7 +120,8 @@ class importMDD(bpy.types.Operator):
#fps = IntProperty(name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default=25)
frame_start = IntProperty(name="Start Frame", description="Start frame for inserting animation", min=minframe, max=maxframe, default=0)
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
ob = context.active_object
return (ob and ob.type == 'MESH')
@@ -143,12 +144,10 @@ def menu_func(self, context):
def register():
- bpy.types.register(importMDD)
bpy.types.INFO_MT_file_import.append(menu_func)
def unregister():
- bpy.types.unregister(importMDD)
bpy.types.INFO_MT_file_import.remove(menu_func)
if __name__ == "__main__":
diff --git a/release/scripts/io/netrender/__init__.py b/release/scripts/io/netrender/__init__.py
index f5f104d6d92..5a705e95aa8 100644
--- a/release/scripts/io/netrender/__init__.py
+++ b/release/scripts/io/netrender/__init__.py
@@ -18,16 +18,31 @@
# This directory is a Python package.
-from netrender import model
-from netrender import operators
-from netrender import client
-from netrender import slave
-from netrender import master
-from netrender import master_html
-from netrender import utils
-from netrender import balancing
-from netrender import ui
-from netrender import repath
+# To support reload properly, try to access a package var, if it's there, reload everything
+try:
+ init_data
+
+ reload(model)
+ reload(operators)
+ reload(client)
+ reload(slave)
+ reload(master)
+ reload(master_html)
+ reload(utils)
+ reload(balancing)
+ reload(ui)
+ reload(repath)
+except:
+ from netrender import model
+ from netrender import operators
+ from netrender import client
+ from netrender import slave
+ from netrender import master
+ from netrender import master_html
+ from netrender import utils
+ from netrender import balancing
+ from netrender import ui
+ from netrender import repath
jobs = []
slaves = []
@@ -38,11 +53,10 @@ init_data = True
init_address = True
def register():
- pass # TODO
+ ui.addProperties()
+
def unregister():
import bpy
- bpy.types.unregister(ui.NetRenderJob)
- bpy.types.unregister(ui.NetRenderSettings)
- bpy.types.unregister(ui.NetRenderSlave)
+ bpy.types.Scene.RemoveProperty("network_render")
diff --git a/release/scripts/io/netrender/client.py b/release/scripts/io/netrender/client.py
index 9f6d1a7639e..6f0f6460ae1 100644
--- a/release/scripts/io/netrender/client.py
+++ b/release/scripts/io/netrender/client.py
@@ -41,7 +41,7 @@ def addFluidFiles(job, path):
job.addFile(path + fluid_file, current_frame, current_frame)
def addPointCache(job, ob, point_cache, default_path):
- if not point_cache.disk_cache:
+ if not point_cache.use_disk_cache:
return
@@ -49,7 +49,7 @@ def addPointCache(job, ob, point_cache, default_path):
if name == "":
name = "".join(["%02X" % ord(c) for c in ob.name])
- cache_path = bpy.utils.expandpath(point_cache.filepath) if point_cache.external else default_path
+ cache_path = bpy.path.abspath(point_cache.filepath) if point_cache.use_external else default_path
index = "%02i" % point_cache.index
@@ -113,7 +113,7 @@ def clientSendJob(conn, scene, anim = False):
# LIBRARIES
###########################
for lib in bpy.data.libraries:
- file_path = bpy.utils.expandpath(lib.filepath)
+ file_path = bpy.path.abspath(lib.filepath)
if os.path.exists(file_path):
job.addFile(file_path)
@@ -122,7 +122,7 @@ def clientSendJob(conn, scene, anim = False):
###########################
for image in bpy.data.images:
if image.source == "FILE" and not image.packed_file:
- file_path = bpy.utils.expandpath(image.filepath)
+ file_path = bpy.path.abspath(image.filepath)
if os.path.exists(file_path):
job.addFile(file_path)
@@ -139,17 +139,17 @@ def clientSendJob(conn, scene, anim = False):
for object in bpy.data.objects:
for modifier in object.modifiers:
if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN":
- addFluidFiles(job, bpy.utils.expandpath(modifier.settings.path))
+ addFluidFiles(job, bpy.path.abspath(modifier.settings.path))
elif modifier.type == "CLOTH":
addPointCache(job, object, modifier.point_cache, default_path)
elif modifier.type == "SOFT_BODY":
addPointCache(job, object, modifier.point_cache, default_path)
elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN":
addPointCache(job, object, modifier.domain_settings.point_cache_low, default_path)
- if modifier.domain_settings.highres:
+ if modifier.domain_settings.use_high_resolution:
addPointCache(job, object, modifier.domain_settings.point_cache_high, default_path)
- elif modifier.type == "MULTIRES" and modifier.external:
- file_path = bpy.utils.expandpath(modifier.filepath)
+ elif modifier.type == "MULTIRES" and modifier.is_external:
+ file_path = bpy.path.abspath(modifier.filepath)
job.addFile(file_path)
# particles modifier are stupid and don't contain data
@@ -171,6 +171,7 @@ def clientSendJob(conn, scene, anim = False):
# try to send path first
conn.request("POST", "/job", repr(job.serialize()))
response = conn.getresponse()
+ response.read()
job_id = response.getheader("job-id")
@@ -181,6 +182,7 @@ def clientSendJob(conn, scene, anim = False):
conn.request("PUT", fileURL(job_id, rfile.index), f)
f.close()
response = conn.getresponse()
+ response.read()
# server will reply with ACCEPTED until all files are found
@@ -189,7 +191,6 @@ def clientSendJob(conn, scene, anim = False):
def requestResult(conn, job_id, frame):
conn.request("GET", renderURL(job_id, frame))
-@rnaType
class NetworkRenderEngine(bpy.types.RenderEngine):
bl_idname = 'NET_RENDER'
bl_label = "Network Render"
@@ -209,7 +210,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
address = "" if netsettings.server_address == "[default]" else netsettings.server_address
- master.runMaster((address, netsettings.server_port), netsettings.master_broadcast, netsettings.master_clear, netsettings.path, self.update_stats, self.test_break)
+ master.runMaster((address, netsettings.server_port), netsettings.master_broadcast, netsettings.use_master_clear, netsettings.path, self.update_stats, self.test_break)
def render_slave(self, scene):
@@ -237,6 +238,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
requestResult(conn, job_id, scene.frame_current)
response = conn.getresponse()
+ response.read()
if response.status == http.client.NO_CONTENT:
new_job = True
@@ -245,16 +247,19 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
requestResult(conn, job_id, scene.frame_current)
response = conn.getresponse()
+ response.read()
while response.status == http.client.ACCEPTED and not self.test_break():
time.sleep(1)
requestResult(conn, job_id, scene.frame_current)
response = conn.getresponse()
+ response.read()
# cancel new jobs (animate on network) on break
if self.test_break() and new_job:
conn.request("POST", cancelURL(job_id))
response = conn.getresponse()
+ response.read()
print( response.status, response.reason )
netsettings.job_id = 0
@@ -266,7 +271,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
x= int(r.resolution_x*r.resolution_percentage*0.01)
y= int(r.resolution_y*r.resolution_percentage*0.01)
- f = open(netsettings.path + "output.exr", "wb")
+ f = open(os.path.join(netsettings.path, "output.exr"), "wb")
buf = response.read(1024)
while buf:
@@ -276,7 +281,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
f.close()
result = self.begin_result(0, 0, x, y)
- result.load_from_file(netsettings.path + "output.exr")
+ result.load_from_file(os.path.join(netsettings.path, "output.exr"))
self.end_result(result)
conn.close()
diff --git a/release/scripts/io/netrender/master.py b/release/scripts/io/netrender/master.py
index f227f61a536..6deb925420b 100644
--- a/release/scripts/io/netrender/master.py
+++ b/release/scripts/io/netrender/master.py
@@ -89,7 +89,7 @@ class MRenderJob(netrender.model.RenderJob):
def save(self):
if self.save_path:
- f = open(self.save_path + "job.txt", "w")
+ f = open(os.path.join(self.save_path, "job.txt"), "w")
f.write(repr(self.serialize()))
f.close()
@@ -134,8 +134,8 @@ class MRenderJob(netrender.model.RenderJob):
self.status = JOB_QUEUED
def addLog(self, frames):
- log_name = "_".join(("%04d" % f for f in frames)) + ".log"
- log_path = self.save_path + log_name
+ log_name = "_".join(("%06d" % f for f in frames)) + ".log"
+ log_path = os.path.join(self.save_path, log_name)
for number in frames:
frame = self[number]
@@ -260,7 +260,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
elif frame.status == DONE:
self.server.stats("", "Sending result to client")
- filename = job.save_path + "%04d" % frame_number + ".exr"
+ filename = os.path.join(job.save_path, "%06d.exr" % frame_number)
f = open(filename, 'rb')
self.send_head(content = "image/x-exr")
@@ -294,7 +294,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
if frame.status in (QUEUED, DISPATCHED):
self.send_head(http.client.ACCEPTED)
elif frame.status == DONE:
- filename = job.save_path + "%04d" % frame_number + ".exr"
+ filename = os.path.join(job.save_path, "%06d.exr" % frame_number)
thumbname = thumbnail(filename)
@@ -716,7 +716,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
if file_index > 0:
file_path = prefixPath(job.save_path, render_file.filepath, main_path)
else:
- file_path = job.save_path + main_name
+ file_path = os.path.join(job.save_path, main_name)
buf = self.rfile.read(length)
@@ -772,7 +772,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
if job_result == DONE:
length = int(self.headers['content-length'])
buf = self.rfile.read(length)
- f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb')
+ f = open(os.path.join(job.save_path, "%06d.exr" % job_frame), 'wb')
f.write(buf)
f.close()
@@ -822,13 +822,12 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
if job.type == netrender.model.JOB_BLENDER:
length = int(self.headers['content-length'])
buf = self.rfile.read(length)
- f = open(job.save_path + "%04d" % job_frame + ".jpg", 'wb')
+ f = open(os.path.join(job.save_path, "%06d.jpg" % job_frame), 'wb')
f.write(buf)
f.close()
del buf
- self.send_head()
else: # frame not found
self.send_head(http.client.NO_CONTENT)
else: # job not found
@@ -880,7 +879,7 @@ class RenderMasterServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
self.job_id = 0
if subdir:
- self.path = path + "master_" + str(os.getpid()) + os.sep
+ self.path = os.path.join(path, "master_" + str(os.getpid()))
else:
self.path = path
@@ -1007,7 +1006,7 @@ class RenderMasterServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
self.jobs_map[job.id] = job
# create job directory
- job.save_path = self.path + "job_" + job.id + os.sep
+ job.save_path = os.path.join(self.path, "job_" + job.id)
if not os.path.exists(job.save_path):
os.mkdir(job.save_path)
diff --git a/release/scripts/io/netrender/master_html.py b/release/scripts/io/netrender/master_html.py
index c3695cd4f0f..74155f6bd66 100644
--- a/release/scripts/io/netrender/master_html.py
+++ b/release/scripts/io/netrender/master_html.py
@@ -27,9 +27,10 @@ def get(handler):
def output(text):
handler.wfile.write(bytes(text, encoding='utf8'))
- def head(title):
+ def head(title, refresh = False):
output("<html><head>")
- output("<meta http-equiv='refresh' content=5>")
+ if refresh:
+ output("<meta http-equiv='refresh' content=5>")
output("<script src='/html/netrender.js' type='text/javascript'></script>")
# output("<script src='/html/json2.js' type='text/javascript'></script>")
output("<title>")
@@ -104,7 +105,7 @@ def get(handler):
f.close()
elif handler.path == "/html" or handler.path == "/":
handler.send_head(content = "text/html")
- head("NetRender")
+ head("NetRender", refresh = True)
output("<h2>Jobs</h2>")
diff --git a/release/scripts/io/netrender/operators.py b/release/scripts/io/netrender/operators.py
index 858ec800dbc..252b1146b67 100644
--- a/release/scripts/io/netrender/operators.py
+++ b/release/scripts/io/netrender/operators.py
@@ -26,13 +26,13 @@ from netrender.utils import *
import netrender.client as client
import netrender.model
-@rnaType
class RENDER_OT_netslave_bake(bpy.types.Operator):
'''NEED DESCRIPTION'''
bl_idname = "render.netslavebake"
bl_label = "Bake all in file"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -52,27 +52,27 @@ class RENDER_OT_netslave_bake(bpy.types.Operator):
modifier.settings.path = relative_path
bpy.ops.fluid.bake({"active_object": object, "scene": scene})
elif modifier.type == "CLOTH":
- modifier.point_cache.step = 1
- modifier.point_cache.disk_cache = True
- modifier.point_cache.external = False
+ modifier.point_cache.frame_step = 1
+ modifier.point_cache.use_disk_cache = True
+ modifier.point_cache.use_external = False
elif modifier.type == "SOFT_BODY":
- modifier.point_cache.step = 1
- modifier.point_cache.disk_cache = True
- modifier.point_cache.external = False
+ modifier.point_cache.frame_step = 1
+ modifier.point_cache.use_disk_cache = True
+ modifier.point_cache.use_external = False
elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN":
- modifier.domain_settings.point_cache_low.step = 1
- modifier.domain_settings.point_cache_low.disk_cache = True
- modifier.domain_settings.point_cache_low.external = False
- modifier.domain_settings.point_cache_high.step = 1
- modifier.domain_settings.point_cache_high.disk_cache = True
- modifier.domain_settings.point_cache_high.external = False
+ modifier.domain_settings.point_cache_low.use_step = 1
+ modifier.domain_settings.point_cache_low.use_disk_cache = True
+ modifier.domain_settings.point_cache_low.use_external = False
+ modifier.domain_settings.point_cache_high.use_step = 1
+ modifier.domain_settings.point_cache_high.use_disk_cache = True
+ modifier.domain_settings.point_cache_high.use_external = False
# particles modifier are stupid and don't contain data
# we have to go through the object property
for psys in object.particle_systems:
- psys.point_cache.step = 1
- psys.point_cache.disk_cache = True
- psys.point_cache.external = False
+ psys.point_cache.use_step = 1
+ psys.point_cache.use_disk_cache = True
+ psys.point_cache.use_external = False
psys.point_cache.filepath = relative_path
bpy.ops.ptcache.bake_all()
@@ -84,13 +84,13 @@ class RENDER_OT_netslave_bake(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientanim(bpy.types.Operator):
'''Start rendering an animation on network'''
bl_idname = "render.netclientanim"
bl_label = "Animation on network"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -111,13 +111,13 @@ class RENDER_OT_netclientanim(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientrun(bpy.types.Operator):
'''Start network rendering service'''
bl_idname = "render.netclientstart"
bl_label = "Start Service"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -128,13 +128,13 @@ class RENDER_OT_netclientrun(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientsend(bpy.types.Operator):
'''Send Render Job to the Network'''
bl_idname = "render.netclientsend"
bl_label = "Send job"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -158,13 +158,13 @@ class RENDER_OT_netclientsend(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientsendframe(bpy.types.Operator):
'''Send Render Job with current frame to the Network'''
bl_idname = "render.netclientsendframe"
bl_label = "Send current frame job"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -188,13 +188,13 @@ class RENDER_OT_netclientsendframe(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientstatus(bpy.types.Operator):
'''Refresh the status of the current jobs'''
bl_idname = "render.netclientstatus"
bl_label = "Client Status"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -205,6 +205,7 @@ class RENDER_OT_netclientstatus(bpy.types.Operator):
conn.request("GET", "/status")
response = conn.getresponse()
+ response.read()
print( response.status, response.reason )
jobs = (netrender.model.RenderJob.materialize(j) for j in eval(str(response.read(), encoding='utf8')))
@@ -228,13 +229,13 @@ class RENDER_OT_netclientstatus(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientblacklistslave(bpy.types.Operator):
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
bl_idname = "render.netclientblacklistslave"
bl_label = "Client Blacklist Slave"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -258,13 +259,13 @@ class RENDER_OT_netclientblacklistslave(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientwhitelistslave(bpy.types.Operator):
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
bl_idname = "render.netclientwhitelistslave"
bl_label = "Client Whitelist Slave"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -289,13 +290,13 @@ class RENDER_OT_netclientwhitelistslave(bpy.types.Operator):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientslaves(bpy.types.Operator):
'''Refresh status about available Render slaves'''
bl_idname = "render.netclientslaves"
bl_label = "Client Slaves"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -306,6 +307,7 @@ class RENDER_OT_netclientslaves(bpy.types.Operator):
conn.request("GET", "/slaves")
response = conn.getresponse()
+ response.read()
print( response.status, response.reason )
slaves = (netrender.model.RenderSlave.materialize(s) for s in eval(str(response.read(), encoding='utf8')))
@@ -334,13 +336,13 @@ class RENDER_OT_netclientslaves(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientcancel(bpy.types.Operator):
'''Cancel the selected network rendering job.'''
bl_idname = "render.netclientcancel"
bl_label = "Client Cancel"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
netsettings = context.scene.network_render
return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0
@@ -354,6 +356,7 @@ class RENDER_OT_netclientcancel(bpy.types.Operator):
conn.request("POST", cancelURL(job.id))
response = conn.getresponse()
+ response.read()
print( response.status, response.reason )
netsettings.jobs.remove(netsettings.active_job_index)
@@ -363,13 +366,13 @@ class RENDER_OT_netclientcancel(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientcancelall(bpy.types.Operator):
'''Cancel all running network rendering jobs.'''
bl_idname = "render.netclientcancelall"
bl_label = "Client Cancel All"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -380,6 +383,7 @@ class RENDER_OT_netclientcancelall(bpy.types.Operator):
conn.request("POST", "/clear")
response = conn.getresponse()
+ response.read()
print( response.status, response.reason )
while(len(netsettings.jobs) > 0):
@@ -390,13 +394,13 @@ class RENDER_OT_netclientcancelall(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class netclientdownload(bpy.types.Operator):
'''Download render results from the network'''
bl_idname = "render.netclientdownload"
bl_label = "Client Download"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
netsettings = context.scene.network_render
return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0
@@ -412,6 +416,7 @@ class netclientdownload(bpy.types.Operator):
for frame in job.frames:
client.requestResult(conn, job.id, frame.number)
response = conn.getresponse()
+ response.read()
if response.status != http.client.OK:
print("missing", frame.number)
@@ -419,7 +424,7 @@ class netclientdownload(bpy.types.Operator):
print("got back", frame.number)
- f = open(netsettings.path + "%06d" % frame.number + ".exr", "wb")
+ f = open(os.path.join(netsettings.path, "%06d.exr" % frame.number), "wb")
buf = response.read(1024)
while buf:
@@ -435,13 +440,13 @@ class netclientdownload(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class netclientscan(bpy.types.Operator):
'''Listen on network for master server broadcasting its address and port.'''
bl_idname = "render.netclientscan"
bl_label = "Client Scan"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -458,13 +463,13 @@ class netclientscan(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class netclientweb(bpy.types.Operator):
'''Open new window with information about running rendering jobs'''
bl_idname = "render.netclientweb"
bl_label = "Open Master Monitor"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
netsettings = context.scene.network_render
return netsettings.server_address != "[default]"
diff --git a/release/scripts/io/netrender/repath.py b/release/scripts/io/netrender/repath.py
index 7f9befd34fb..3ac9636b628 100755..100644
--- a/release/scripts/io/netrender/repath.py
+++ b/release/scripts/io/netrender/repath.py
@@ -66,10 +66,10 @@ def update(job):
def process(paths):
def processPointCache(point_cache):
- point_cache.external = False
+ point_cache.use_external = False
def processFluid(fluid):
- new_path = path_map.get(fluid.path, None)
+ new_path = path_map.get(fluid.filepath, None)
if new_path:
fluid.path = new_path
@@ -83,14 +83,17 @@ def process(paths):
elif paths[i].endswith(".bobj.gz"):
path_map[os.path.split(paths[i])[0]] = os.path.split(paths[i+1])[0]
else:
- path_map[paths[i]] = paths[i+1]
+ path_map[os.path.split(paths[i])[1]] = paths[i+1]
+
+ # TODO original paths aren't really the orignal path (they are the normalized path
+ # so we repath using the filenames only.
###########################
# LIBRARIES
###########################
for lib in bpy.data.libraries:
- file_path = bpy.utils.expandpath(lib.filepath)
- new_path = path_map.get(file_path, None)
+ file_path = bpy.path.abspath(lib.filepath)
+ new_path = path_map.get(os.path.split(file_path)[1], None)
if new_path:
lib.filepath = new_path
@@ -99,8 +102,8 @@ def process(paths):
###########################
for image in bpy.data.images:
if image.source == "FILE" and not image.packed_file:
- file_path = bpy.utils.expandpath(image.filepath)
- new_path = path_map.get(file_path, None)
+ file_path = bpy.path.abspath(image.filepath)
+ new_path = path_map.get(os.path.split(file_path)[1], None)
if new_path:
image.filepath = new_path
@@ -118,10 +121,10 @@ def process(paths):
processPointCache(modifier.point_cache)
elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN":
processPointCache(modifier.domain_settings.point_cache_low)
- if modifier.domain_settings.highres:
+ if modifier.domain_settings.use_high_resolution:
processPointCache(modifier.domain_settings.point_cache_high)
- elif modifier.type == "MULTIRES" and modifier.external:
- file_path = bpy.utils.expandpath(modifier.filepath)
+ elif modifier.type == "MULTIRES" and modifier.is_external:
+ file_path = bpy.path.abspath(modifier.filepath)
new_path = path_map.get(file_path, None)
if new_path:
modifier.filepath = new_path
@@ -144,4 +147,4 @@ if __name__ == "__main__":
process(args)
- bpy.ops.wm.save_as_mainfile(path=new_path, check_existing=False)
+ bpy.ops.wm.save_as_mainfile(filepath=new_path, check_existing=False)
diff --git a/release/scripts/io/netrender/slave.py b/release/scripts/io/netrender/slave.py
index 9fd00152dc1..b383481824b 100644
--- a/release/scripts/io/netrender/slave.py
+++ b/release/scripts/io/netrender/slave.py
@@ -59,8 +59,8 @@ def slave_Info():
def testCancel(conn, job_id, frame_number):
conn.request("HEAD", "/status", headers={"job-id":job_id, "job-frame": str(frame_number)})
- # cancelled if job isn't found anymore
- if conn.getresponse().status == http.client.NO_CONTENT:
+ # canceled if job isn't found anymore
+ if responseStatus(conn) == http.client.NO_CONTENT:
return True
else:
return False
@@ -79,7 +79,9 @@ def testFile(conn, job_id, slave_id, rfile, JOB_PREFIX, main_path = None):
job_full_path = prefixPath(JOB_PREFIX, rfile.filepath, main_path, force = True)
if not found:
- temp_path = JOB_PREFIX + "slave.temp"
+ # Force prefix path if not found
+ job_full_path = prefixPath(JOB_PREFIX, rfile.filepath, main_path, force = True)
+ temp_path = os.path.join(JOB_PREFIX, "slave.temp")
conn.request("GET", fileURL(job_id, rfile.index), headers={"slave-id":slave_id})
response = conn.getresponse()
@@ -111,10 +113,11 @@ def render_slave(engine, netsettings, threads):
if conn:
conn.request("POST", "/slave", repr(slave_Info().serialize()))
response = conn.getresponse()
+ response.read()
slave_id = response.getheader("slave-id")
- NODE_PREFIX = netsettings.path + "slave_" + slave_id + os.sep
+ NODE_PREFIX = os.path.join(netsettings.path, "slave_" + slave_id)
if not os.path.exists(NODE_PREFIX):
os.mkdir(NODE_PREFIX)
@@ -130,7 +133,7 @@ def render_slave(engine, netsettings, threads):
job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8')))
engine.update_stats("", "Network render processing job from master")
- JOB_PREFIX = NODE_PREFIX + "job_" + job.id + os.sep
+ JOB_PREFIX = os.path.join(NODE_PREFIX, "job_" + job.id)
if not os.path.exists(JOB_PREFIX):
os.mkdir(JOB_PREFIX)
@@ -155,6 +158,7 @@ def render_slave(engine, netsettings, threads):
logfile = netrender.model.LogFile(job.id, slave_id, [frame.number for frame in job.frames])
conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'))
response = conn.getresponse()
+ response.read()
first_frame = job.frames[0].number
@@ -170,7 +174,7 @@ def render_slave(engine, netsettings, threads):
frame_args += ["-f", str(frame.number)]
val = SetErrorMode()
- process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-t", str(threads), "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-t", str(threads), "-o", os.path.join(JOB_PREFIX, "######"), "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
RestoreErrorMode(val)
elif job.type == netrender.model.JOB_PROCESS:
command = job.frames[0].command
@@ -194,9 +198,10 @@ def render_slave(engine, netsettings, threads):
# (only need to update on one frame, they are linked
conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
response = conn.getresponse()
+ response.read()
# Also output on console
- if netsettings.slave_thumb:
+ if netsettings.use_slave_output_log:
print(str(stdout, encoding='utf8'), end="")
stdout = bytes()
@@ -214,18 +219,21 @@ def render_slave(engine, netsettings, threads):
if cancelled:
# kill process if needed
if process.poll() == None:
- process.terminate()
+ try:
+ process.terminate()
+ except OSError:
+ pass
continue # to next frame
# flush the rest of the logs
if stdout:
# Also output on console
- if netsettings.slave_thumb:
+ if netsettings.use_slave_thumb:
print(str(stdout, encoding='utf8'), end="")
# (only need to update on one frame, they are linked
conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
- if conn.getresponse().status == http.client.NO_CONTENT:
+ if responseStatus(conn) == http.client.NO_CONTENT:
continue
total_t = time.time() - start_t
@@ -246,26 +254,27 @@ def render_slave(engine, netsettings, threads):
if job.type == netrender.model.JOB_BLENDER:
# send image back to server
- filename = JOB_PREFIX + "%06d" % frame.number + ".exr"
+ filename = os.path.join(JOB_PREFIX, "%06d.exr" % frame.number)
# thumbnail first
- if netsettings.slave_thumb:
+ if netsettings.use_slave_thumb:
thumbname = thumbnail(filename)
f = open(thumbname, 'rb')
conn.request("PUT", "/thumb", f, headers=headers)
f.close()
- conn.getresponse()
+ responseStatus(conn)
+
f = open(filename, 'rb')
conn.request("PUT", "/render", f, headers=headers)
f.close()
- if conn.getresponse().status == http.client.NO_CONTENT:
+ if responseStatus(conn) == http.client.NO_CONTENT:
continue
elif job.type == netrender.model.JOB_PROCESS:
conn.request("PUT", "/render", headers=headers)
- if conn.getresponse().status == http.client.NO_CONTENT:
+ if responseStatus(conn) == http.client.NO_CONTENT:
continue
else:
headers["job-result"] = str(ERROR)
@@ -273,7 +282,7 @@ def render_slave(engine, netsettings, threads):
headers["job-frame"] = str(frame.number)
# send error result back to server
conn.request("PUT", "/render", headers=headers)
- if conn.getresponse().status == http.client.NO_CONTENT:
+ if responseStatus(conn) == http.client.NO_CONTENT:
continue
engine.update_stats("", "Network render connected to master, waiting for jobs")
@@ -288,7 +297,7 @@ def render_slave(engine, netsettings, threads):
conn.close()
- if netsettings.slave_clear:
+ if netsettings.use_slave_clear:
clearSlave(NODE_PREFIX)
if __name__ == "__main__":
diff --git a/release/scripts/io/netrender/ui.py b/release/scripts/io/netrender/ui.py
index c60b10c484a..c2d943f63f8 100644
--- a/release/scripts/io/netrender/ui.py
+++ b/release/scripts/io/netrender/ui.py
@@ -36,6 +36,11 @@ DISPATCHED = 1
DONE = 2
ERROR = 3
+def base_poll(cls, context):
+ rd = context.scene.render
+ return (rd.use_game_engine==False) and (rd.engine in cls.COMPAT_ENGINES)
+
+
def init_file():
if netrender.init_file != bpy.data.filepath:
netrender.init_file = bpy.data.filepath
@@ -81,17 +86,21 @@ class RenderButtonsPanel():
bl_region_type = "WINDOW"
bl_context = "render"
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
-
- def poll(self, context):
+
+ @classmethod
+ def poll(cls, context):
rd = context.scene.render
- return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES)
+ return (rd.use_game_engine==False) and (rd.engine in cls.COMPAT_ENGINES)
# Setting panel, use in the scene for now.
-@rnaType
class RENDER_PT_network_settings(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Network Settings"
COMPAT_ENGINES = {'NET_RENDER'}
+ @classmethod
+ def poll(cls, context):
+ return super(RENDER_PT_network_settings, cls).poll(context)
+
def draw(self, context):
layout = self.layout
@@ -122,15 +131,14 @@ class RENDER_PT_network_settings(bpy.types.Panel, RenderButtonsPanel):
layout.operator("render.netclientweb", icon='QUESTION')
-@rnaType
class RENDER_PT_network_slave_settings(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Slave Settings"
COMPAT_ENGINES = {'NET_RENDER'}
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
scene = context.scene
- return (super().poll(context)
- and scene.network_render.mode == "RENDER_SLAVE")
+ return super(RENDER_PT_network_slave_settings, cls).poll(context) and scene.network_render.mode == "RENDER_SLAVE"
def draw(self, context):
layout = self.layout
@@ -139,23 +147,23 @@ class RENDER_PT_network_slave_settings(bpy.types.Panel, RenderButtonsPanel):
rd = scene.render
netsettings = scene.network_render
- layout.prop(netsettings, "slave_clear")
- layout.prop(netsettings, "slave_thumb")
- layout.prop(netsettings, "slave_outputlog")
+ layout.prop(netsettings, "use_slave_clear")
+ layout.prop(netsettings, "use_slave_thumb")
+ layout.prop(netsettings, "use_slave_output_log")
layout.label(text="Threads:")
layout.prop(rd, "threads_mode", expand=True)
sub = layout.column()
sub.enabled = rd.threads_mode == 'FIXED'
sub.prop(rd, "threads")
-@rnaType
+
class RENDER_PT_network_master_settings(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Master Settings"
COMPAT_ENGINES = {'NET_RENDER'}
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
scene = context.scene
- return (super().poll(context)
- and scene.network_render.mode == "RENDER_MASTER")
+ return super(RENDER_PT_network_master_settings, cls).poll(context) and scene.network_render.mode == "RENDER_MASTER"
def draw(self, context):
layout = self.layout
@@ -163,18 +171,17 @@ class RENDER_PT_network_master_settings(bpy.types.Panel, RenderButtonsPanel):
scene = context.scene
netsettings = scene.network_render
- layout.prop(netsettings, "master_broadcast")
- layout.prop(netsettings, "master_clear")
+ layout.prop(netsettings, "use_master_broadcast")
+ layout.prop(netsettings, "use_master_clear")
-@rnaType
class RENDER_PT_network_job(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Job Settings"
COMPAT_ENGINES = {'NET_RENDER'}
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
scene = context.scene
- return (super().poll(context)
- and scene.network_render.mode == "RENDER_CLIENT")
+ return super(RENDER_PT_network_job, cls).poll(context) and scene.network_render.mode == "RENDER_CLIENT"
def draw(self, context):
layout = self.layout
@@ -207,19 +214,18 @@ class RENDER_PT_network_job(bpy.types.Panel, RenderButtonsPanel):
row.prop(netsettings, "priority")
row.prop(netsettings, "chunks")
-@rnaType
class RENDER_PT_network_slaves(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Slaves Status"
COMPAT_ENGINES = {'NET_RENDER'}
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
scene = context.scene
netsettings = scene.network_render
if netsettings.mode != "RENDER_CLIENT":
return False
verify_address(netsettings)
- return (super().poll(context)
- and netsettings.server_address != "[default]")
+ return super(RENDER_PT_network_slaves, cls).poll(context) and netsettings.server_address != "[default]"
def draw(self, context):
layout = self.layout
@@ -246,19 +252,18 @@ class RENDER_PT_network_slaves(bpy.types.Panel, RenderButtonsPanel):
layout.label(text="Seen: " + time.ctime(slave.last_seen))
layout.label(text="Stats: " + slave.stats)
-@rnaType
class RENDER_PT_network_slaves_blacklist(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Slaves Blacklist"
COMPAT_ENGINES = {'NET_RENDER'}
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
scene = context.scene
netsettings = scene.network_render
if netsettings.mode != "RENDER_CLIENT":
return False
verify_address(netsettings)
- return (super().poll(context)
- and netsettings.server_address != "[default]")
+ return super(RENDER_PT_network_slaves_blacklist, cls).poll(context) and netsettings.server_address != "[default]"
def draw(self, context):
layout = self.layout
@@ -284,19 +289,18 @@ class RENDER_PT_network_slaves_blacklist(bpy.types.Panel, RenderButtonsPanel):
layout.label(text="Seen: " + time.ctime(slave.last_seen))
layout.label(text="Stats: " + slave.stats)
-@rnaType
class RENDER_PT_network_jobs(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Jobs"
COMPAT_ENGINES = {'NET_RENDER'}
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
scene = context.scene
netsettings = scene.network_render
if netsettings.mode != "RENDER_CLIENT":
return False
verify_address(netsettings)
- return (super().poll(context)
- and netsettings.server_address != "[default]")
+ return super(RENDER_PT_network_jobs, cls).poll(context) and netsettings.server_address != "[default]"
def draw(self, context):
layout = self.layout
@@ -325,150 +329,148 @@ class RENDER_PT_network_jobs(bpy.types.Panel, RenderButtonsPanel):
layout.label(text="Done: %04i" % job.results[DONE])
layout.label(text="Error: %04i" % job.results[ERROR])
-@rnaType
class NetRenderSettings(bpy.types.IDPropertyGroup):
pass
-@rnaType
class NetRenderSlave(bpy.types.IDPropertyGroup):
pass
-@rnaType
class NetRenderJob(bpy.types.IDPropertyGroup):
pass
-bpy.types.Scene.PointerProperty(attr="network_render", type=NetRenderSettings, name="Network Render", description="Network Render Settings")
-
-NetRenderSettings.StringProperty( attr="server_address",
- name="Server address",
- description="IP or name of the master render server",
- maxlen = 128,
- default = "[default]")
-
-NetRenderSettings.IntProperty( attr="server_port",
- name="Server port",
- description="port of the master render server",
- default = 8000,
- min=1,
- max=65535)
-
-NetRenderSettings.BoolProperty( attr="master_broadcast",
- name="Broadcast",
- description="broadcast master server address on local network",
- default = True)
-
-NetRenderSettings.BoolProperty( attr="slave_clear",
- name="Clear on exit",
- description="delete downloaded files on exit",
- default = True)
-
-NetRenderSettings.BoolProperty( attr="slave_thumb",
- name="Generate thumbnails",
- description="Generate thumbnails on slaves instead of master",
- default = False)
-
-NetRenderSettings.BoolProperty( attr="slave_outputlog",
- name="Output render log on console",
- description="Output render text log to console as well as sending it to the master",
- default = True)
-
-NetRenderSettings.BoolProperty( attr="master_clear",
- name="Clear on exit",
- description="delete saved files on exit",
- default = False)
-
-default_path = os.environ.get("TEMP")
-
-if not default_path:
- if os.name == 'nt':
- default_path = "c:/tmp/"
- else:
- default_path = "/tmp/"
-elif not default_path.endswith(os.sep):
- default_path += os.sep
-
-NetRenderSettings.StringProperty( attr="path",
- name="Path",
- description="Path for temporary files",
- maxlen = 128,
- default = default_path,
- subtype='FILE_PATH')
-
-NetRenderSettings.StringProperty( attr="job_name",
- name="Job name",
- description="Name of the job",
- maxlen = 128,
- default = "[default]")
-
-NetRenderSettings.StringProperty( attr="job_category",
- name="Job category",
- description="Category of the job",
- maxlen = 128,
- default = "")
-
-NetRenderSettings.IntProperty( attr="chunks",
- name="Chunks",
- description="Number of frame to dispatch to each slave in one chunk",
- default = 5,
- min=1,
- max=65535)
-
-NetRenderSettings.IntProperty( attr="priority",
- name="Priority",
- description="Priority of the job",
- default = 1,
- min=1,
- max=10)
-
-NetRenderSettings.StringProperty( attr="job_id",
- name="Network job id",
- description="id of the last sent render job",
- maxlen = 64,
- default = "")
-
-NetRenderSettings.IntProperty( attr="active_slave_index",
- name="Index of the active slave",
- description="",
- default = -1,
- min= -1,
- max=65535)
-
-NetRenderSettings.IntProperty( attr="active_blacklisted_slave_index",
- name="Index of the active slave",
- description="",
- default = -1,
- min= -1,
- max=65535)
-
-NetRenderSettings.IntProperty( attr="active_job_index",
- name="Index of the active job",
- description="",
- default = -1,
- min= -1,
- max=65535)
-
-NetRenderSettings.EnumProperty(attr="mode",
- items=(
- ("RENDER_CLIENT", "Client", "Act as render client"),
- ("RENDER_MASTER", "Master", "Act as render master"),
- ("RENDER_SLAVE", "Slave", "Act as render slave"),
- ),
- name="Network mode",
- description="Mode of operation of this instance",
- default="RENDER_CLIENT")
-
-NetRenderSettings.CollectionProperty(attr="slaves", type=NetRenderSlave, name="Slaves", description="")
-NetRenderSettings.CollectionProperty(attr="slaves_blacklist", type=NetRenderSlave, name="Slaves Blacklist", description="")
-NetRenderSettings.CollectionProperty(attr="jobs", type=NetRenderJob, name="Job List", description="")
-
-NetRenderSlave.StringProperty( attr="name",
- name="Name of the slave",
- description="",
- maxlen = 64,
- default = "")
-
-NetRenderJob.StringProperty( attr="name",
- name="Name of the job",
- description="",
- maxlen = 128,
- default = "")
+def addProperties():
+ bpy.types.Scene.PointerProperty(attr="network_render", type=NetRenderSettings, name="Network Render", description="Network Render Settings")
+
+ NetRenderSettings.StringProperty( attr="server_address",
+ name="Server address",
+ description="IP or name of the master render server",
+ maxlen = 128,
+ default = "[default]")
+
+ NetRenderSettings.IntProperty( attr="server_port",
+ name="Server port",
+ description="port of the master render server",
+ default = 8000,
+ min=1,
+ max=65535)
+
+ NetRenderSettings.BoolProperty( attr="use_master_broadcast",
+ name="Broadcast",
+ description="broadcast master server address on local network",
+ default = True)
+
+ NetRenderSettings.BoolProperty( attr="use_slave_clear",
+ name="Clear on exit",
+ description="delete downloaded files on exit",
+ default = True)
+
+ NetRenderSettings.BoolProperty( attr="use_slave_thumb",
+ name="Generate thumbnails",
+ description="Generate thumbnails on slaves instead of master",
+ default = False)
+
+ NetRenderSettings.BoolProperty( attr="use_slave_output_log",
+ name="Output render log on console",
+ description="Output render text log to console as well as sending it to the master",
+ default = True)
+
+ NetRenderSettings.BoolProperty( attr="use_master_clear",
+ name="Clear on exit",
+ description="delete saved files on exit",
+ default = False)
+
+ default_path = os.environ.get("TEMP")
+
+ if not default_path:
+ if os.name == 'nt':
+ default_path = "c:/tmp/"
+ else:
+ default_path = "/tmp/"
+ elif not default_path.endswith(os.sep):
+ default_path += os.sep
+
+ NetRenderSettings.StringProperty( attr="path",
+ name="Path",
+ description="Path for temporary files",
+ maxlen = 128,
+ default = default_path,
+ subtype='FILE_PATH')
+
+ NetRenderSettings.StringProperty( attr="job_name",
+ name="Job name",
+ description="Name of the job",
+ maxlen = 128,
+ default = "[default]")
+
+ NetRenderSettings.StringProperty( attr="job_category",
+ name="Job category",
+ description="Category of the job",
+ maxlen = 128,
+ default = "")
+
+ NetRenderSettings.IntProperty( attr="chunks",
+ name="Chunks",
+ description="Number of frame to dispatch to each slave in one chunk",
+ default = 5,
+ min=1,
+ max=65535)
+
+ NetRenderSettings.IntProperty( attr="priority",
+ name="Priority",
+ description="Priority of the job",
+ default = 1,
+ min=1,
+ max=10)
+
+ NetRenderSettings.StringProperty( attr="job_id",
+ name="Network job id",
+ description="id of the last sent render job",
+ maxlen = 64,
+ default = "")
+
+ NetRenderSettings.IntProperty( attr="active_slave_index",
+ name="Index of the active slave",
+ description="",
+ default = -1,
+ min= -1,
+ max=65535)
+
+ NetRenderSettings.IntProperty( attr="active_blacklisted_slave_index",
+ name="Index of the active slave",
+ description="",
+ default = -1,
+ min= -1,
+ max=65535)
+
+ NetRenderSettings.IntProperty( attr="active_job_index",
+ name="Index of the active job",
+ description="",
+ default = -1,
+ min= -1,
+ max=65535)
+
+ NetRenderSettings.EnumProperty(attr="mode",
+ items=(
+ ("RENDER_CLIENT", "Client", "Act as render client"),
+ ("RENDER_MASTER", "Master", "Act as render master"),
+ ("RENDER_SLAVE", "Slave", "Act as render slave"),
+ ),
+ name="Network mode",
+ description="Mode of operation of this instance",
+ default="RENDER_CLIENT")
+
+ NetRenderSettings.CollectionProperty(attr="slaves", type=NetRenderSlave, name="Slaves", description="")
+ NetRenderSettings.CollectionProperty(attr="slaves_blacklist", type=NetRenderSlave, name="Slaves Blacklist", description="")
+ NetRenderSettings.CollectionProperty(attr="jobs", type=NetRenderJob, name="Job List", description="")
+
+ NetRenderSlave.StringProperty( attr="name",
+ name="Name of the slave",
+ description="",
+ maxlen = 64,
+ default = "")
+
+ NetRenderJob.StringProperty( attr="name",
+ name="Name of the job",
+ description="",
+ maxlen = 128,
+ default = "")
diff --git a/release/scripts/io/netrender/utils.py b/release/scripts/io/netrender/utils.py
index 6288b9747c0..81617ac0d30 100644
--- a/release/scripts/io/netrender/utils.py
+++ b/release/scripts/io/netrender/utils.py
@@ -57,9 +57,10 @@ FRAME_STATUS_TEXT = {
ERROR: "Error"
}
-def rnaType(rna_type):
- if bpy: bpy.types.register(rna_type)
- return rna_type
+def responseStatus(conn):
+ response = conn.getresponse()
+ response.read()
+ return response.status
def reporting(report, message, errorType = None):
if errorType:
@@ -171,20 +172,20 @@ def prefixPath(prefix_directory, file_path, prefix_path, force = False):
# if an absolute path, make sure path exists, if it doesn't, use relative local path
full_path = file_path
if force or not os.path.exists(full_path):
- p, n = os.path.split(full_path)
+ p, n = os.path.split(os.path.normpath(full_path))
if prefix_path and p.startswith(prefix_path):
if len(prefix_path) < len(p):
- directory = prefix_directory + p[len(prefix_path)+1:] + os.sep # +1 to remove separator
+ directory = os.path.join(prefix_directory, p[len(prefix_path)+1:]) # +1 to remove separator
if not os.path.exists(directory):
os.mkdir(directory)
else:
directory = prefix_directory
- full_path = directory + n
+ full_path = os.path.join(directory, n)
else:
- full_path = prefix_directory + n
+ full_path = os.path.join(prefix_directory, n)
else:
- full_path = prefix_directory + file_path
+ full_path = (prefix_directory, file_path)
return full_path