Ejemplo n.º 1
0
def import_surface(asset_directory,
                   target_ctx=None,
                   ior=DEFAULT_IOR,
                   metallic_ior=DEFAULT_METALLIC_IOR,
                   projection_type="triplanar",
                   object_space=0,
                   clip_opacity=True,
                   color_spaces=(),
                   triplanar_blend=0.5,
                   **kwargs):
    # Initial data
    ix = get_ix(kwargs.get("ix"))
    if not target_ctx:
        target_ctx = ix.application.get_working_context()
    if not check_context(target_ctx, ix=ix):
        return None
    asset_directory = os.path.normpath(asset_directory)
    if not os.path.isdir(asset_directory):
        ix.log_warning("Invalid directory specified: " + asset_directory)
        return None
    logging.debug("Asset directory: " + asset_directory)

    logging.debug("Importing generic surface:")
    surface_height = DEFAULT_DISPLACEMENT_HEIGHT
    scan_area = DEFAULT_UV_SCALE
    tileable = True
    asset_name = os.path.basename(os.path.normpath(asset_directory))

    textures = get_textures_from_directory(asset_directory)
    if not textures:
        ix.log_warning("No textures found in directory.")
        return None
    logging.debug("Found textures: ")
    logging.debug(str(textures))
    streamed_maps = get_stream_map_files(textures)
    if streamed_maps:
        logging.debug("Streamed maps: ")
        logging.debug(str(streamed_maps))

    surface = Surface(ix,
                      projection=projection_type,
                      uv_scale=scan_area,
                      height=surface_height,
                      tile=tileable,
                      object_space=object_space,
                      triplanar_blend=triplanar_blend,
                      ior=ior,
                      metallic_ior=metallic_ior)
    mtl = surface.create_mtl(asset_name, target_ctx)
    surface.create_textures(textures,
                            color_spaces,
                            streamed_maps,
                            clip_opacity=clip_opacity)

    logging.debug("Finished importing surface.")
    logging.debug("+++++++++++++++++++++++++++++++")
    return surface
Ejemplo n.º 2
0
def import_surface(asset_directory,
                   target_ctx=None,
                   ior=DEFAULT_IOR,
                   projection_type='triplanar',
                   object_space=0,
                   clip_opacity=True,
                   color_spaces=None,
                   triplanar_blend=0.5,
                   resolution=None,
                   lod=None,
                   **kwargs):
    """Imports a Megascans surface."""
    logging.debug("++++++++++++++++++++++.")
    logging.debug("Import Megascans surface called.")
    ix = get_ix(kwargs.get('ix'))
    if not target_ctx:
        target_ctx = ix.application.get_working_context()
    if not check_context(target_ctx, ix=ix):
        return None
    if not os.path.isdir(asset_directory):
        return ix.log_warning('Invalid directory specified: ' +
                              asset_directory)
    if not color_spaces:
        color_spaces = get_color_spaces(MEGASCANS_COLOR_SPACES, ix=ix)
    logging.debug('Asset directory: ' + asset_directory)

    # Initial data
    json_data = get_json_data_from_directory(asset_directory)
    logging.debug('JSON data:')
    logging.debug(str(json_data))
    if not json_data:
        ix.log_warning(
            'Could not find a Megascans JSON file. Defaulting to standard settings.'
        )
    surface_height = json_data.get('surface_height',
                                   DEFAULT_DISPLACEMENT_HEIGHT)
    displacement_offset = DEFAULT_DISPLACEMENT_OFFSET
    logging.debug('Surface height JSON test: ' + str(surface_height))
    scan_area = json_data.get('scan_area', DEFAULT_UV_SCALE)
    logging.debug('Scan area JSON test: ' + str(scan_area))
    tileable = json_data.get('tileable', True)
    asset_name = os.path.basename(os.path.normpath(asset_directory))
    logging.debug('Asset name: ' + asset_name)
    if scan_area[0] >= 2 and scan_area[1] >= 2:
        height = 0.2
    else:
        height = 0.02

    # All assets except 3dplant have the material in the root directory of the asset.
    logging.debug('Searching for textures: ')
    lod_match_template = r'(?:_LOD(?P<lod>[0-9]*)|_NormalBump$)'
    textures = get_textures_from_directory(
        asset_directory,
        resolution=resolution,
        lod=lod,
        lod_match_template=lod_match_template)
    if not textures:
        ix.log_warning(
            'No textures found in directory. Directory is empty or resolution is invalid.'
        )
        return None
    logging.debug('Found textures: ')
    logging.debug(str(textures))
    streamed_maps = get_stream_map_files(textures)
    if streamed_maps:
        logging.debug('Streamed maps: ')
        logging.debug(str(streamed_maps))

    surface = Surface(ix,
                      projection=projection_type,
                      uv_scale=scan_area,
                      height=height,
                      tile=tileable,
                      object_space=object_space,
                      triplanar_blend=triplanar_blend,
                      ior=ior,
                      specular_strength=1,
                      displacement_offset=displacement_offset)
    mtl = surface.create_mtl(asset_name, target_ctx)
    surface.create_textures(textures,
                            color_spaces=color_spaces,
                            streamed_maps=streamed_maps,
                            clip_opacity=clip_opacity)
    logging.debug("Import Megascans surface done.")
    logging.debug("++++++++++++++++++++++.")
    return surface
Ejemplo n.º 3
0
def import_3dplant(asset_directory,
                   target_ctx=None,
                   ior=DEFAULT_IOR,
                   object_space=0,
                   clip_opacity=True,
                   use_displacement=True,
                   color_spaces=MEGASCANS_COLOR_SPACES,
                   triplanar_blend=0.5,
                   resolution=None,
                   lod=None,
                   **kwargs):
    """Imports a Megascans 3D object."""
    ix = get_ix(kwargs.get('ix'))
    logging.debug("*******************")
    logging.debug("Setting up 3d plant...")

    # Megascans 3dplant importer. The 3dplant importer requires 2 materials to be created.
    # Let's first find the textures of the Atlas and create the material.
    if not target_ctx:
        target_ctx = ix.application.get_working_context()
    if not check_context(target_ctx, ix=ix):
        return None
    asset_directory = os.path.normpath(asset_directory)
    if not os.path.isdir(asset_directory):
        return ix.log_warning("Invalid directory specified: " +
                              asset_directory)
    logging.debug("Asset directory: " + asset_directory)

    # Initial data
    json_data = get_json_data_from_directory(asset_directory)
    logging.debug("JSON data:")
    logging.debug(str(json_data))
    if not json_data:
        ix.log_warning(
            "Could not find a Megascans JSON file. Defaulting to standard settings."
        )
    asset_type = json_data.get('type', 'surface')
    logging.debug("Asset type from JSON test: " + asset_type)
    surface_height = json_data.get('surface_height',
                                   DEFAULT_DISPLACEMENT_HEIGHT)
    logging.debug("Surface height JSON test: " + str(surface_height))
    scan_area = json_data.get('scan_area', DEFAULT_UV_SCALE)
    logging.debug("Scan area JSON test: " + str(scan_area))
    tileable = json_data.get('tileable', True)
    asset_name = os.path.basename(os.path.normpath(asset_directory))
    logging.debug("Asset name: " + asset_name)
    logging.debug(os.path.join(asset_directory, 'Textures/Atlas/'))
    atlas_textures = get_textures_from_directory(os.path.join(
        asset_directory, 'Textures/Atlas/'),
                                                 resolution=resolution)
    if not atlas_textures:
        ix.log_warning(
            "No atlas textures found in directory. Files might have been exported flattened from Bridge.\n"
            "Testing import as Atlas.")
        import_atlas(asset_directory,
                     target_ctx=target_ctx,
                     use_displacement=use_displacement,
                     clip_opacity=clip_opacity,
                     resolution=resolution,
                     **kwargs)
        return None
    logging.debug("Atlas textures: ")
    logging.debug(str(atlas_textures))
    streamed_maps = get_stream_map_files(atlas_textures)
    logging.debug("Atlas streamed maps: ")
    logging.debug(str(streamed_maps))

    atlas_surface = Surface(ix,
                            projection='uv',
                            uv_scale=scan_area,
                            height=scan_area[0],
                            tile=tileable,
                            object_space=object_space,
                            triplanar_blend=triplanar_blend,
                            ior=ior,
                            double_sided=True,
                            specular_strength=1,
                            displacement_multiplier=0.1)
    plant_root_ctx = ix.cmds.CreateContext(asset_name, "Global",
                                           str(target_ctx))
    atlas_mtl = atlas_surface.create_mtl(ATLAS_CTX, plant_root_ctx)
    atlas_surface.create_textures(atlas_textures,
                                  color_spaces=color_spaces,
                                  streamed_maps=streamed_maps,
                                  clip_opacity=clip_opacity)
    atlas_ctx = atlas_surface.ctx
    # Find the textures of the Billboard and create the material.
    billboard_textures = get_textures_from_directory(os.path.join(
        asset_directory, 'Textures/Billboard/'),
                                                     resolution=resolution)
    if not billboard_textures:
        ix.log_warning("No Billboard textures found in directory.")
    else:
        logging.debug("Billboard textures: ")
        logging.debug(str(billboard_textures))

        streamed_maps = get_stream_map_files(billboard_textures)
        logging.debug("Billboard streamed maps: ")
        logging.debug(str(streamed_maps))
        billboard_surface = Surface(ix,
                                    projection='uv',
                                    uv_scale=scan_area,
                                    height=scan_area[0],
                                    tile=tileable,
                                    object_space=object_space,
                                    triplanar_blend=triplanar_blend,
                                    ior=ior,
                                    double_sided=True,
                                    specular_strength=1,
                                    displacement_multiplier=0.1)
        billboard_mtl = billboard_surface.create_mtl(BILLBOARD_CTX,
                                                     plant_root_ctx)
        billboard_surface.create_textures(billboard_textures,
                                          color_spaces=color_spaces,
                                          streamed_maps=streamed_maps,
                                          clip_opacity=clip_opacity)
        billboard_ctx = billboard_surface.ctx

    for dir_name in os.listdir(asset_directory):
        variation_dir = os.path.join(asset_directory, dir_name)
        if os.path.isdir(variation_dir) and dir_name.startswith('Var'):
            logging.debug("Variation dir found: " + variation_dir)
            files = [
                f for f in os.listdir(variation_dir)
                if os.path.isfile(os.path.join(variation_dir, f))
            ]
            # Search for models files and apply material
            for f in files:
                filename, extension = os.path.splitext(f)
                if extension.lower() == ".obj":
                    logging.debug("Found obj: " + f)
                    filename, extension = os.path.splitext(f)
                    polyfile = ix.cmds.CreateObject(filename,
                                                    "GeometryPolyfile",
                                                    "Global",
                                                    str(plant_root_ctx))
                    ix.cmds.SetValue(
                        str(polyfile) + ".filename",
                        [os.path.normpath(os.path.join(variation_dir, f))])
                    # Megascans .obj files are saved in cm, Clarisse imports them as meters.
                    polyfile.attrs.scale_offset[0] = .01
                    polyfile.attrs.scale_offset[1] = .01
                    polyfile.attrs.scale_offset[2] = .01
                    geo = polyfile.get_module()
                    for i in range(geo.get_shading_group_count()):
                        if filename.endswith('3'):
                            geo.assign_material(billboard_mtl.get_module(), i)
                            if clip_opacity and billboard_surface.get(
                                    'opacity'):
                                geo.assign_clip_map(
                                    (billboard_surface.get('opacity')
                                     ).get_module(), i)
                        else:
                            geo.assign_material(atlas_mtl.get_module(), i)
                            if clip_opacity and atlas_surface.get('opacity'):
                                geo.assign_clip_map(
                                    atlas_surface.get('opacity').get_module(),
                                    i)
                            lod_level_match = re.sub('.*?([0-9]*)$', r'\1',
                                                     filename)
                            if int(
                                    lod_level_match
                            ) in ATLAS_LOD_DISPLACEMENT_LEVELS and use_displacement:
                                geo.assign_displacement(
                                    atlas_surface.get(
                                        'displacement_map').get_module(), i)
                elif extension.lower() == ".abc":
                    logging.debug("Found abc: " + f)
                    abc_reference = ix.cmds.CreateFileReference(
                        str(plant_root_ctx),
                        [os.path.normpath(os.path.join(variation_dir, f))])
                    for item in get_items(abc_reference,
                                          kind=('GeometryAbcMesh', 'AbcXform'),
                                          ix=ix):
                        if not item.attrs.parent[0]:
                            item.attrs.scale_offset[0] = .01
                            item.attrs.scale_offset[1] = .01
                            item.attrs.scale_offset[2] = .01

    shading_layer = ix.cmds.CreateObject(asset_name + SHADING_LAYER_SUFFIX,
                                         "ShadingLayer", "Global",
                                         str(plant_root_ctx))
    logging.debug("Creating shading layers and groups...")
    for i in range(0, 4):
        ix.cmds.AddShadingLayerRule(str(shading_layer), i,
                                    ["filter", "", "is_visible", "1"])
        ix.cmds.SetShadingLayerRulesProperty(str(shading_layer), [i], "filter",
                                             ["./*LOD" + str(i) + "*"])
        ix.cmds.SetShadingLayerRulesProperty(str(shading_layer), [i],
                                             "material", [str(atlas_mtl)])
        if atlas_surface.get('opacity') and clip_opacity:
            ix.cmds.SetShadingLayerRulesProperty(
                str(shading_layer), [i], "clip_map",
                [str(atlas_surface.get('opacity'))])
        if atlas_surface.get(
                'displacement'
        ) and i in ATLAS_LOD_DISPLACEMENT_LEVELS and use_displacement:
            ix.cmds.SetShadingLayerRulesProperty(
                str(shading_layer), [i], "displacement",
                [str(atlas_surface.get('displacement_map'))])

        group = ix.cmds.CreateObject(
            asset_name + "_LOD" + str(i) + GROUP_SUFFIX, "Group", "Global",
            str(plant_root_ctx))
        group.attrs.inclusion_rule = "./*LOD" + str(i) + "*"
        ix.cmds.AddValues([group.get_full_name() + ".filter"],
                          ["GeometryAbcMesh"])
        ix.cmds.AddValues([group.get_full_name() + ".filter"],
                          ["GeometryPolyfile"])
        ix.cmds.RemoveValue([group.get_full_name() + ".filter"], [2, 0, 1])

    logging.debug("...done setting up shading rules, groups and 3d plant")
    logging.debug("*****************************************************")