Skip to content
Snippets Groups Projects
import_obj.py 50.1 KiB
Newer Older
# ##### 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>

# Script copyright (C) Campbell Barton
# Contributors: Campbell Barton, Jiri Hnidek, Paolo Ciccone

"""
This script imports a Wavefront OBJ files to Blender.

Usage:
Run this script from "File->Import" menu and then load the desired OBJ file.
Note, This loads mesh objects and materials only, nurbs and curves are not supported.

http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj
"""

import os
import time
import bpy
import mathutils
from bpy_extras.io_utils import unpack_list
from bpy_extras.image_utils import load_image
from progress_report import ProgressReport, ProgressReportSubstep

    Returns 1 string representing the value for this line
    None will be returned if theres only 1 word
Campbell Barton's avatar
Campbell Barton committed
    length = len(line_split)
    if length == 1:
        return None

    elif length == 2:
        return line_split[1]

    elif length > 2:
        return b' '.join(line_split[1:])
def obj_image_load(imagepath, DIR, recursive, relpath):
    Mainly uses comprehensiveImageLoad
    but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores.
    if "_" in imagepath:
        image = load_image(imagepath.replace("_", " "), DIR, recursive=recursive, relpath=relpath)
    return load_image(imagepath, DIR, recursive=recursive, place_holder=True, relpath=relpath)
def create_materials(filepath, relpath,
                     material_libs, unique_materials, unique_material_images,
                     use_image_search, float_func):
    Create all the used materials in this obj,
    assign colors and images to the materials from all referenced material libs
Campbell Barton's avatar
Campbell Barton committed
    DIR = os.path.dirname(filepath)
    def load_material_image(blender_material, context_material_name, img_data, type):
        """
        Set textures defined in .mtl file.
        """
        imagepath = os.fsdecode(img_data[-1])
        map_options = {}

        curr_token = []
        for token in img_data[:-1]:
            if token.startswith(b'-'):
                if curr_token:
                    map_options[curr_token[0]] = curr_token[1:]
                curr_token[:] = []
            curr_token.append(token)

Campbell Barton's avatar
Campbell Barton committed
        texture = bpy.data.textures.new(name=type, type='IMAGE')

        # Absolute path - c:\.. etc would work here
        image = obj_image_load(imagepath, DIR, use_image_search, relpath)
        if image is not None:
            texture.image = image

        # Adds textures for materials (rendering)
        if type == 'Kd':
            mtex = blender_material.texture_slots.add()
            mtex.texture = texture
            mtex.texture_coords = 'UV'
            mtex.use_map_color_diffuse = True

            # 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  # set the texface image

        elif type == 'Ka':
            mtex = blender_material.texture_slots.add()
            mtex.use_map_color_diffuse = False

            mtex.texture = texture
            mtex.texture_coords = 'UV'
            mtex.use_map_ambient = True

        elif type == 'Ks':
            mtex = blender_material.texture_slots.add()
            mtex.use_map_color_diffuse = False

            mtex.texture = texture
            mtex.texture_coords = 'UV'
            mtex.use_map_color_spec = True
        elif type == 'Ke':
            mtex = blender_material.texture_slots.add()
            mtex.use_map_color_diffuse = False

            mtex.texture = texture
            mtex.texture_coords = 'UV'
            mtex.use_map_emit = True

        elif type == 'Bump':
            mtex = blender_material.texture_slots.add()
            mtex.use_map_color_diffuse = False

            mtex.texture = texture
            mtex.texture_coords = 'UV'
            mtex.use_map_normal = True

            bump_mult = map_options.get(b'-bm')
            if bump_mult:
                mtex.normal_factor = bump_mult[0]

        elif type == 'D':
            mtex = blender_material.texture_slots.add()
            mtex.use_map_color_diffuse = False

            mtex.texture = texture
            mtex.texture_coords = 'UV'
            mtex.use_map_alpha = True
            blender_material.use_transparency = True
            blender_material.transparency_method = 'Z_TRANSPARENCY'
            if "alpha" not in context_material_vars:
                blender_material.alpha = 0.0
            # Todo, unset deffuse material alpha if it has an alpha channel

        elif type == 'disp':
            mtex = blender_material.texture_slots.add()
            mtex.use_map_color_diffuse = False

            mtex.texture = texture
            mtex.texture_coords = 'UV'
            mtex.use_map_displacement = True

        elif type == 'refl':
            mtex = blender_material.texture_slots.add()
            mtex.use_map_color_diffuse = False

            mtex.texture_coords = 'REFLECTION'
            mtex.use_map_color_diffuse = True

            map_type = map_options.get(b'-type')
            if map_type and map_type != [b'sphere']:
                print("WARNING, unsupported reflection type '%s', defaulting to 'sphere'"
                      "" % ' '.join(i.decode() for i in map_type))
            mtex.mapping = 'SPHERE'
            raise Exception("invalid type %r" % type)
        map_offset = map_options.get(b'-o')
        map_scale = map_options.get(b'-s')
        if map_offset:
            mtex.offset.x = float(map_offset[0])
            if len(map_offset) >= 2:
                mtex.offset.y = float(map_offset[1])
            if len(map_offset) >= 3:
                mtex.offset.z = float(map_offset[2])
        if map_scale:
            mtex.scale.x = float(map_scale[0])
Loading
Loading full blame...