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

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'io_scene_obj/export_obj.py')
-rw-r--r--io_scene_obj/export_obj.py231
1 files changed, 86 insertions, 145 deletions
diff --git a/io_scene_obj/export_obj.py b/io_scene_obj/export_obj.py
index 05ff4db2..0e905141 100644
--- a/io_scene_obj/export_obj.py
+++ b/io_scene_obj/export_obj.py
@@ -21,8 +21,8 @@
import os
import bpy
-import mathutils
-import bpy_extras.io_utils
+from mathutils import Matrix, Vector, Color
+from bpy_extras import io_utils, node_shader_utils
from bpy_extras.wm_utils.progress_report import (
ProgressReport,
@@ -47,13 +47,8 @@ def mesh_triangulate(me):
def write_mtl(scene, filepath, path_mode, copy_set, mtl_dict):
- from mathutils import Color, Vector
-
world = scene.world
- if world:
- world_amb = world.ambient_color
- else:
- world_amb = Color((0.0, 0.0, 0.0))
+ world_amb = Color((0.8, 0.8, 0.8))
source_dir = os.path.dirname(bpy.data.filepath)
dest_dir = os.path.dirname(filepath)
@@ -69,133 +64,100 @@ def write_mtl(scene, filepath, path_mode, copy_set, mtl_dict):
# Write material/image combinations we have used.
# Using mtl_dict.values() directly gives un-predictable order.
- for mtl_mat_name, mat, face_img in mtl_dict_values:
+ for mtl_mat_name, mat in mtl_dict_values:
# Get the Blender data for the material and the image.
# Having an image named None will make a bug, dont do it :)
fw('\nnewmtl %s\n' % mtl_mat_name) # Define a new material: matname_imgname
- if mat:
- use_mirror = mat.raytrace_mirror.use and mat.raytrace_mirror.reflect_factor != 0.0
+ mat_wrap = node_shader_utils.PrincipledBSDFWrapper(mat) if mat else None
- # convert from blenders spec to 0 - 1000 range.
- if mat.specular_shader == 'WARDISO':
- tspec = (0.4 - mat.specular_slope) / 0.0004
- else:
- tspec = (mat.specular_hardness - 1) / 0.51
- fw('Ns %.6f\n' % tspec)
- del tspec
+ if mat_wrap:
+ use_mirror = mat_wrap.metallic != 0.0
+ use_transparency = mat_wrap.transmission != 0.0
+
+ # XXX Totally empirical conversion, trying to adapt it
+ # (from 1.0 - 0.0 Principled BSDF range to 0.0 - 900.0 OBJ specular exponent range)...
+ spec = (1.0 - mat_wrap.roughness) * 30
+ spec *= spec
+ fw('Ns %.6f\n' % spec)
# Ambient
if use_mirror:
- fw('Ka %.6f %.6f %.6f\n' % (mat.raytrace_mirror.reflect_factor * mat.mirror_color)[:])
+ fw('Ka %.6f %.6f %.6f\n' % (mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic))
else:
- fw('Ka %.6f %.6f %.6f\n' % (mat.ambient, mat.ambient, mat.ambient)) # Do not use world color!
- fw('Kd %.6f %.6f %.6f\n' % (mat.diffuse_intensity * mat.diffuse_color)[:]) # Diffuse
- fw('Ks %.6f %.6f %.6f\n' % (mat.specular_intensity * mat.specular_color)[:]) # Specular
+ fw('Ka %.6f %.6f %.6f\n' % (1.0, 1.0, 1.0))
+ fw('Kd %.6f %.6f %.6f\n' % mat_wrap.base_color[:3]) # Diffuse
+ # XXX TODO Find a way to handle tint and diffuse color, in a consistent way with import...
+ fw('Ks %.6f %.6f %.6f\n' % (mat_wrap.specular, mat_wrap.specular, mat_wrap.specular)) # Specular
# Emission, not in original MTL standard but seems pretty common, see T45766.
- # XXX Blender has no color emission, it's using diffuse color instead...
- fw('Ke %.6f %.6f %.6f\n' % (mat.emit * mat.diffuse_color)[:])
- if hasattr(mat, "raytrace_transparency") and hasattr(mat.raytrace_transparency, "ior"):
- fw('Ni %.6f\n' % mat.raytrace_transparency.ior) # Refraction index
- else:
- fw('Ni %.6f\n' % 1.0)
- fw('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve)
+ # XXX Not supported by current Principled-based shader.
+ fw('Ke 0.0 0.0 0.0\n')
+ fw('Ni %.6f\n' % mat_wrap.ior) # Refraction index
+ fw('d %.6f\n' % (1.0 - mat_wrap.transmission)) # Alpha (obj uses 'd' for dissolve)
# See http://en.wikipedia.org/wiki/Wavefront_.obj_file for whole list of values...
# Note that mapping is rather fuzzy sometimes, trying to do our best here.
- if mat.use_shadeless:
- fw('illum 0\n') # ignore lighting
- elif mat.specular_intensity == 0:
+ if mat_wrap.specular == 0:
fw('illum 1\n') # no specular.
elif use_mirror:
- if mat.use_transparency and mat.transparency_method == 'RAYTRACE':
- if mat.raytrace_mirror.fresnel != 0.0:
- fw('illum 7\n') # Reflection, Transparency, Ray trace and Fresnel
- else:
- fw('illum 6\n') # Reflection, Transparency, Ray trace
- elif mat.raytrace_mirror.fresnel != 0.0:
- fw('illum 5\n') # Reflection, Ray trace and Fresnel
+ if use_transparency:
+ fw('illum 6\n') # Reflection, Transparency, Ray trace
else:
fw('illum 3\n') # Reflection and Ray trace
- elif mat.use_transparency and mat.transparency_method == 'RAYTRACE':
+ elif use_transparency:
fw('illum 9\n') # 'Glass' transparency and no Ray trace reflection... fuzzy matching, but...
else:
fw('illum 2\n') # light normally
- else:
- # Write a dummy material here?
- fw('Ns 0\n')
- fw('Ka %.6f %.6f %.6f\n' % world_amb[:]) # Ambient, uses mirror color,
- fw('Kd 0.8 0.8 0.8\n')
- fw('Ks 0.8 0.8 0.8\n')
- fw('d 1\n') # No alpha
- fw('illum 2\n') # light normally
-
- # Write images!
- if face_img: # We have an image on the face!
- filepath = face_img.filepath
- if filepath: # may be '' for generated images
- # write relative image path
- filepath = bpy_extras.io_utils.path_reference(filepath, source_dir, dest_dir,
- path_mode, "", copy_set, face_img.library)
- fw('map_Kd %s\n' % filepath) # Diffuse mapping image
- del filepath
- else:
- # so we write the materials image.
- face_img = None
-
- if mat: # No face image. if we havea material search for MTex image.
- image_map = {}
- # backwards so topmost are highest priority
- for mtex in reversed(mat.texture_slots):
- if mtex and mtex.texture and mtex.texture.type == 'IMAGE':
- image = mtex.texture.image
- if image:
- # texface overrides others
- if (mtex.use_map_color_diffuse and (face_img is None) and
- (mtex.use_map_warp is False) and (mtex.texture_coords != 'REFLECTION')):
- image_map["map_Kd"] = (mtex, image)
- if mtex.use_map_ambient:
- image_map["map_Ka"] = (mtex, image)
- # this is the Spec intensity channel but Ks stands for specular Color
- '''
- if mtex.use_map_specular:
- image_map["map_Ks"] = (mtex, image)
- '''
- if mtex.use_map_color_spec: # specular color
- image_map["map_Ks"] = (mtex, image)
- if mtex.use_map_hardness: # specular hardness/glossiness
- image_map["map_Ns"] = (mtex, image)
- if mtex.use_map_alpha:
- image_map["map_d"] = (mtex, image)
- if mtex.use_map_translucency:
- image_map["map_Tr"] = (mtex, image)
- if mtex.use_map_normal:
- image_map["map_Bump"] = (mtex, image)
- if mtex.use_map_displacement:
- image_map["disp"] = (mtex, image)
- if mtex.use_map_color_diffuse and (mtex.texture_coords == 'REFLECTION'):
- image_map["refl"] = (mtex, image)
- if mtex.use_map_emit:
- image_map["map_Ke"] = (mtex, image)
-
- for key, (mtex, image) in sorted(image_map.items()):
- filepath = bpy_extras.io_utils.path_reference(image.filepath, source_dir, dest_dir,
- path_mode, "", copy_set, image.library)
+ #### And now, the image textures...
+ image_map = {
+ "map_Kd": "base_color_texture",
+ "map_Ka": None, # ambient...
+ "map_Ks": "specular_texture",
+ "map_Ns": "roughness_texture",
+ "map_d": "transmission_texture",
+ "map_Tr": None, # transmission roughness?
+ "map_Bump": "normalmap_texture",
+ "disp": None, # displacement...
+ "refl": "metallic_texture",
+ "map_Ke": None # emission...
+ }
+
+ for key, mat_wrap_key in sorted(image_map.items()):
+ if mat_wrap_key is None:
+ continue
+ tex_wrap = getattr(mat_wrap, mat_wrap_key, None)
+ if tex_wrap is None:
+ continue
+ image = tex_wrap.image
+ if image is None:
+ continue
+
+ filepath = io_utils.path_reference(image.filepath, source_dir, dest_dir,
+ path_mode, "", copy_set, image.library)
options = []
if key == "map_Bump":
- if mtex.normal_factor != 1.0:
- options.append('-bm %.6f' % mtex.normal_factor)
- if mtex.offset != Vector((0.0, 0.0, 0.0)):
- options.append('-o %.6f %.6f %.6f' % mtex.offset[:])
- if mtex.scale != Vector((1.0, 1.0, 1.0)):
- options.append('-s %.6f %.6f %.6f' % mtex.scale[:])
+ if mat_wrap.normalmap_strengh != 1.0:
+ options.append('-bm %.6f' % mat_wrap.normalmap_strengh)
+ if tex_wrap.translation != Vector((0.0, 0.0, 0.0)):
+ options.append('-o %.6f %.6f %.6f' % tex_wrap.translation[:])
+ if tex_wrap.scale != Vector((1.0, 1.0, 1.0)):
+ options.append('-s %.6f %.6f %.6f' % tex_wrap.scale[:])
if options:
fw('%s %s %s\n' % (key, " ".join(options), repr(filepath)[1:-1]))
else:
fw('%s %s\n' % (key, repr(filepath)[1:-1]))
+ else:
+ # Write a dummy material here?
+ fw('Ns 500\n')
+ fw('Ka 0.8 0.8 0.8\n')
+ fw('Kd 0.8 0.8 0.8\n')
+ fw('Ks 0.8 0.8 0.8\n')
+ fw('d 1\n') # No alpha
+ fw('illum 2\n') # light normally
+
def test_nurbs_compat(ob):
if ob.type != 'CURVE':
@@ -236,7 +198,7 @@ def write_nurb(fw, ob, ob_mat):
do_endpoints = (do_closed == 0) and nu.use_endpoint_u
for pt in nu.points:
- fw('v %.6f %.6f %.6f\n' % (ob_mat * pt.co.to_3d())[:])
+ fw('v %.6f %.6f %.6f\n' % (ob_mat @ pt.co.to_3d())[:])
pt_num += 1
tot_verts += pt_num
@@ -274,7 +236,7 @@ def write_nurb(fw, ob, ob_mat):
return tot_verts
-def write_file(filepath, objects, scene,
+def write_file(filepath, objects, depsgraph, scene,
EXPORT_TRI=False,
EXPORT_EDGES=False,
EXPORT_SMOOTH_GROUPS=False,
@@ -301,7 +263,7 @@ def write_file(filepath, objects, scene,
write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options.
"""
if EXPORT_GLOBAL_MATRIX is None:
- EXPORT_GLOBAL_MATRIX = mathutils.Matrix()
+ EXPORT_GLOBAL_MATRIX = Matrix()
def veckey3d(v):
return round(v.x, 4), round(v.y, 4), round(v.z, 4)
@@ -362,13 +324,13 @@ def write_file(filepath, objects, scene,
subprogress1.enter_substeps(len(objects))
for i, ob_main in enumerate(objects):
# ignore dupli children
- if ob_main.parent and ob_main.parent.dupli_type in {'VERTS', 'FACES'}:
+ if ob_main.parent and ob_main.parent.instance_type in {'VERTS', 'FACES'}:
# XXX
subprogress1.step("Ignoring %s, dupli child..." % ob_main.name)
continue
obs = [(ob_main, ob_main.matrix_world)]
- if ob_main.dupli_type != 'NONE':
+ if ob_main.instance_type != 'NONE':
# XXX
print('creating dupli_list on', ob_main.name)
ob_main.dupli_list_create(scene)
@@ -385,14 +347,13 @@ def write_file(filepath, objects, scene,
# Nurbs curve support
if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob):
- ob_mat = EXPORT_GLOBAL_MATRIX * ob_mat
+ ob_mat = EXPORT_GLOBAL_MATRIX @ ob_mat
totverts += write_nurb(fw, ob, ob_mat)
continue
# END NURBS
try:
- me = ob.to_mesh(scene, EXPORT_APPLY_MODIFIERS, calc_tessface=False,
- settings='RENDER' if EXPORT_APPLY_MODIFIERS_RENDER else 'PREVIEW')
+ me = ob.to_mesh(depsgraph, EXPORT_APPLY_MODIFIERS)
except RuntimeError:
me = None
@@ -404,15 +365,14 @@ def write_file(filepath, objects, scene,
# _must_ do this first since it re-allocs arrays
mesh_triangulate(me)
- me.transform(EXPORT_GLOBAL_MATRIX * ob_mat)
+ me.transform(EXPORT_GLOBAL_MATRIX @ ob_mat)
# If negative scaling, we have to invert the normals...
if ob_mat.determinant() < 0.0:
me.flip_normals()
if EXPORT_UV:
- faceuv = len(me.uv_textures) > 0
+ faceuv = len(me.uv_layers) > 0
if faceuv:
- uv_texture = me.uv_textures.active.data[:]
uv_layer = me.uv_layers.active.data[:]
else:
faceuv = False
@@ -421,7 +381,6 @@ def write_file(filepath, objects, scene,
# Make our own list so it can be sorted to reduce context switching
face_index_pairs = [(face, index) for index, face in enumerate(me.polygons)]
- # faces = [ f for f in me.tessfaces ]
if EXPORT_EDGES:
edges = me.edges
@@ -459,16 +418,7 @@ def write_file(filepath, objects, scene,
if EXPORT_KEEP_VERT_ORDER:
pass
else:
- if faceuv:
- if smooth_groups:
- sort_func = lambda a: (a[0].material_index,
- hash(uv_texture[a[1]].image),
- smooth_groups[a[1]] if a[0].use_smooth else False)
- else:
- sort_func = lambda a: (a[0].material_index,
- hash(uv_texture[a[1]].image),
- a[0].use_smooth)
- elif len(materials) > 1:
+ if len(materials) > 1:
if smooth_groups:
sort_func = lambda a: (a[0].material_index,
smooth_groups[a[1]] if a[0].use_smooth else False)
@@ -562,9 +512,6 @@ def write_file(filepath, objects, scene,
else:
loops_to_normals = []
- if not faceuv:
- f_image = None
-
subprogress2.step()
# XXX
@@ -584,15 +531,8 @@ def write_file(filepath, objects, scene,
f_smooth = smooth_groups[f_index]
f_mat = min(f.material_index, len(materials) - 1)
- if faceuv:
- tface = uv_texture[f_index]
- f_image = tface.image
-
# MAKE KEY
- if faceuv and f_image: # Object is always true.
- key = material_names[f_mat], f_image.name
- else:
- key = material_names[f_mat], None # No image, use None instead.
+ key = material_names[f_mat], None # No image, use None instead.
# Write the vertex group
if EXPORT_POLYGROUPS:
@@ -638,7 +578,7 @@ def write_file(filepath, objects, scene,
i += 1
tmp_ext = "_%3d" % i
mtl_name += tmp_ext
- mat_data = mtl_dict[key] = mtl_name, materials[f_mat], f_image
+ mat_data = mtl_dict[key] = mtl_name, materials[f_mat]
mtl_rev_dict[mtl_name] = key
if EXPORT_GROUP_BY_MAT:
@@ -704,7 +644,7 @@ def write_file(filepath, objects, scene,
# clean up
bpy.data.meshes.remove(me)
- if ob_main.dupli_type != 'NONE':
+ if ob_main.instance_type != 'NONE':
ob_main.dupli_list_clear()
subprogress1.leave_substeps("Finished writing geometry of '%s'." % ob_main.name)
@@ -717,7 +657,7 @@ def write_file(filepath, objects, scene,
write_mtl(scene, mtlfilepath, EXPORT_PATH_MODE, copy_set, mtl_dict)
# copy all collected files.
- bpy_extras.io_utils.path_reference_copy(copy_set)
+ io_utils.path_reference_copy(copy_set)
def _write(context, filepath,
@@ -746,6 +686,7 @@ def _write(context, filepath,
base_name, ext = os.path.splitext(filepath)
context_name = [base_name, '', '', ext] # Base name, scene name, frame number, extension
+ depsgraph = context.depsgraph
scene = context.scene
# Exit edit mode before exporting, so current object states are exported properly.
@@ -766,7 +707,7 @@ def _write(context, filepath,
if EXPORT_ANIMATION: # Add frame to the filepath.
context_name[2] = '_%.6d' % frame
- scene.frame_set(frame, 0.0)
+ scene.frame_set(frame, subframe=0.0)
if EXPORT_SEL_ONLY:
objects = context.selected_objects
else:
@@ -777,7 +718,7 @@ def _write(context, filepath,
# erm... bit of a problem here, this can overwrite files when exporting frames. not too bad.
# EXPORT THE FILE.
progress.enter_substeps(1)
- write_file(full_path, objects, scene,
+ write_file(full_path, objects, depsgraph, scene,
EXPORT_TRI,
EXPORT_EDGES,
EXPORT_SMOOTH_GROUPS,
@@ -799,7 +740,7 @@ def _write(context, filepath,
)
progress.leave_substeps()
- scene.frame_set(orig_frame, 0.0)
+ scene.frame_set(orig_frame, subframe=0.0)
progress.leave_substeps()