Skip to content
Snippets Groups Projects
import_fbx.py 41.4 KiB
Newer Older
  • Learn to ignore specific revisions
  •                 continue
                if fbx_item[1] is None:
                    continue  # no object loaded.. ignore
    
    
                for (fbx_lnk,
                     fbx_lnk_item,
                     fbx_lnk_type) in connection_filter_forward(fbx_uuid, b'Model'):
    
    
                    fbx_item[1].parent = fbx_lnk_item
        _(); del _
    
        def _():
            if global_matrix is not None:
                # Apply global matrix last (after parenting)
                for fbx_uuid, fbx_item in fbx_table_nodes.items():
                    fbx_obj, blen_data = fbx_item
                    if fbx_obj.id != b'Model':
                        continue
                    if fbx_item[1] is None:
                        continue  # no object loaded.. ignore
    
                    if fbx_item[1].parent is None:
                        fbx_item[1].matrix_basis = global_matrix * fbx_item[1].matrix_basis
    
        def _():
            # link Material's to Geometry (via Model's)
            for fbx_uuid, fbx_item in fbx_table_nodes.items():
                fbx_obj, blen_data = fbx_item
                if fbx_obj.id != b'Geometry':
                    continue
    
                mesh = fbx_table_nodes[fbx_uuid][1]
    
                for (fbx_lnk,
                     fbx_lnk_item,
                     fbx_lnk_type) in connection_filter_forward(fbx_uuid, b'Model'):
    
    
                    # link materials
                    fbx_lnk_uuid = elem_uuid(fbx_lnk)
    
                    for (fbx_lnk_material,
                         material,
                         fbx_lnk_material_type) in connection_filter_reverse(fbx_lnk_uuid, b'Material'):
    
    
                        mesh.materials.append(material)
    
            fbx_tmpl = fbx_template_get((b'Material', b'KFbxSurfacePhong'))
            # b'KFbxSurfaceLambert'
    
    
            # textures that use this material
            def texture_bumpfac_get(fbx_obj):
    
                fbx_props = (elem_find_first(fbx_obj, b'Properties70'),
                             elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil))
                assert(fbx_props[0] is not None)
    
                return elem_props_get_number(fbx_props, b'BumpFactor', 1.0)
    
    
            if not use_cycles:
                # Simple function to make a new mtex and set defaults
                def material_mtex_new(material, image):
                    tex = texture_cache.get(image)
                    if tex is None:
                        tex = bpy.data.textures.new(name=image.name, type='IMAGE')
                        tex.image = image
                        texture_cache[image] = tex
    
                    mtex = material.texture_slots.add()
                    mtex.texture = tex
                    mtex.texture_coords = 'UV'
                    mtex.use_map_color_diffuse = False
                    return mtex
    
    
            for fbx_uuid, fbx_item in fbx_table_nodes.items():
                fbx_obj, blen_data = fbx_item
                if fbx_obj.id != b'Material':
                    continue
    
                material = fbx_table_nodes[fbx_uuid][1]
    
                for (fbx_lnk,
                     image,
                     fbx_lnk_type) in connection_filter_reverse(fbx_uuid, b'Texture'):
    
    
                    if use_cycles:
                        if fbx_lnk_type.props[0] == b'OP':
                            lnk_type = fbx_lnk_type.props[3]
    
                            ma_wrap = cycles_material_wrap_map[material]
    
                            if lnk_type == b'DiffuseColor':
                                ma_wrap.diffuse_image_set(image)
                            elif lnk_type == b'SpecularColor':
                                ma_wrap.specular_image_set(image)
                            elif lnk_type == b'ReflectionColor':
                                ma_wrap.reflect_image_set(image)
    
                            elif lnk_type == b'TransparentColor':  # alpha
    
                                ma_wrap.alpha_image_set(image)
    
                                if use_alpha_decals:
                                    material_decals.add(material)
    
                            elif lnk_type == b'DiffuseFactor':
                                pass  # TODO
                            elif lnk_type == b'ShininessExponent':
                                ma_wrap.hardness_image_set(image)
                            elif lnk_type == b'NormalMap':
                                ma_wrap.normal_image_set(image)
                                ma_wrap.normal_factor_set(texture_bumpfac_get(fbx_obj))
                            elif lnk_type == b'Bump':
                                ma_wrap.bump_image_set(image)
                                ma_wrap.bump_factor_set(texture_bumpfac_get(fbx_obj))
    
                            else:
                                print("WARNING: material link %r ignored" % lnk_type)
    
                            material_images.setdefault(material, {})[lnk_type] = image
    
                    else:
                        if fbx_lnk_type.props[0] == b'OP':
                            lnk_type = fbx_lnk_type.props[3]
    
    
                            mtex = material_mtex_new(material, image)
    
    
                            if lnk_type == b'DiffuseColor':
                                mtex.use_map_color_diffuse = True
                                mtex.blend_type = 'MULTIPLY'
                            elif lnk_type == b'SpecularColor':
                                mtex.use_map_color_spec = True
                                mtex.blend_type = 'MULTIPLY'
                            elif lnk_type == b'ReflectionColor':
                                mtex.use_map_raymir = True
    
                            elif lnk_type == b'TransparentColor':  # alpha
                                material.use_transparency = True
                                material.transparency_method = 'RAYTRACE'
                                material.alpha = 0.0
                                mtex.use_map_alpha = True
                                mtex.alpha_factor = 1.0
                                if use_alpha_decals:
                                    material_decals.add(material)
    
                            elif lnk_type == b'DiffuseFactor':
                                mtex.use_map_diffuse = True
                            elif lnk_type == b'ShininessExponent':
                                mtex.use_map_hardness = True
                            elif lnk_type == b'NormalMap':
    
                                mtex.texture.use_normal_map = True  # not ideal!
    
                                mtex.use_map_normal = True
                                mtex.normal_factor = texture_bumpfac_get(fbx_obj)
                            elif lnk_type == b'Bump':
                                mtex.use_map_normal = True
                                mtex.normal_factor = texture_bumpfac_get(fbx_obj)
                            else:
                                print("WARNING: material link %r ignored" % lnk_type)
    
    
                            material_images.setdefault(material, {})[lnk_type] = image
    
            # Check if the diffuse image has an alpha channel,
            # if so, use the alpha channel.
    
            # Note: this could be made optional since images may have alpha but be entirely opaque
            for fbx_uuid, fbx_item in fbx_table_nodes.items():
                fbx_obj, blen_data = fbx_item
                if fbx_obj.id != b'Material':
                    continue
                material = fbx_table_nodes[fbx_uuid][1]
                image = material_images.get(material, {}).get(b'DiffuseColor')
                # do we have alpha?
                if image and image.depth == 32:
                    if use_alpha_decals:
                        material_decals.add(material)
    
                    if use_cycles:
                        ma_wrap = cycles_material_wrap_map[material]
                        if ma_wrap.node_bsdf_alpha.mute:
                            ma_wrap.alpha_image_set_from_diffuse()
                    else:
                        if not any((True for mtex in material.texture_slots if mtex and mtex.use_map_alpha)):
                            mtex = material_mtex_new(material, image)
    
                            material.use_transparency = True
                            material.transparency_method = 'RAYTRACE'
                            material.alpha = 0.0
                            mtex.use_map_alpha = True
                            mtex.alpha_factor = 1.0
    
    
        def _():
            # Annoying workaround for cycles having no z-offset
            if material_decals and use_alpha_decals:
                for fbx_uuid, fbx_item in fbx_table_nodes.items():
                    fbx_obj, blen_data = fbx_item
                    if fbx_obj.id != b'Geometry':
                        continue
                    if fbx_obj.props[-1] == b'Mesh':
                        mesh = fbx_item[1]
    
                        if decal_offset != 0.0:
                            for material in mesh.materials:
                                if material in material_decals:
                                    for v in mesh.vertices:
                                        v.co += v.normal * decal_offset
                                    break
    
                        if use_cycles:
                            for obj in (obj for obj in bpy.data.objects if obj.data == mesh):
                                obj.cycles_visibility.shadow = False
                        else:
                            for material in mesh.materials:
                                if material in material_decals:
                                    # recieve but dont cast shadows
                                    material.use_raytrace = False
        _(); del _
    
        # print(list(sorted(locals().keys())))