MultiMaterialCastingExample.cpp

<< Click to Display Table of Contents >>

Navigation:  Simplygon 7.1 examples >

MultiMaterialCastingExample.cpp

///////////////////////////////////////////////////////////////////////////
//
//  System:    Simplygon
//  File:      MultiMaterialCastingExample.cpp
//  Language:  C++
//
//  Copyright (c) 2015 Donya Labs AB. All rights reserved.
//
//  This is private property, and it is illegal to copy or distribute in
//  any form, without written authorization by the copyright owner(s).
//
///////////////////////////////////////////////////////////////////////////
//
//  #Description#
//
//  A scene is loaded from a WaveFront file. The scene contains 3 materials.
//
//  Two of the materials are grouped together to become a single new material,
//  and the third original material is baked into its own new material.
//  So the three input materials are cast to two output materials/textures.
//
//  The textures and optimized objects are saved to file.
//
///////////////////////////////////////////////////////////////////////////
#include "../Common/Example.h"
#include "BMPheader.h"
void RunExampleCasting(const std::string& readFrom, const std::string& writeTo);
int main( int argc , char* argv[] )
    {
    InitExample();
    // Set global variable. Using Orthonormal method for calculating tangentspace.
    sg->SetGlobalSetting( "DefaultTBNType" , SG_TANGENTSPACEMETHOD_ORTHONORMAL );
    std::string assetPath = GetAssetPath();
    // Run the example code
    RunExampleCasting( assetPath + "MaterialTestMesh/materialTestMesh.obj", "ObjectTextured" );
    DeinitExample();
    return 0;
    }
void RunExampleCasting(const std::string& readFrom, const std::string& writeTo)
    {
    // Import a scene from a file and optimize it. Generate image mapping from
    // the original geometries and use it to cast diffuse, specular, normal and a
    // custom map to the reduced geometry.
    std::string exePath = GetExecutablePath();
    std::string outputGeometryFilename = exePath + writeTo + ".obj";
    std::string outputDiffuse1Filename = exePath + writeTo + "_diffuse1.png";
    std::string outputDiffuse2Filename = exePath + writeTo + "_diffuse2.png";
    //Load object from file
    spWavefrontImporter objReader = sg->CreateWavefrontImporter();
    objReader->SetImportFilePath( readFrom.c_str() );
    if( !objReader->RunImport() )
        return;
    // Get the scene
    spScene scene = objReader->GetScene();
    spMaterialTable originalMaterials = scene->GetMaterialTable();
    //Reducer
    spReductionProcessor red = sg->CreateReductionProcessor();
    red->SetScene(scene);
    // Set the Repair Settings.
    spRepairSettings repairSettings = red->GetRepairSettings();
    // Will take care of holes that are of size 0.2 or less, so small gaps etc are removed.
    repairSettings->SetWeldDist( 0.2f );
    repairSettings->SetTjuncDist( 0.2f );
    // Set the Reduction Settings.
    spReductionSettings reductionSettings = red->GetReductionSettings();
    reductionSettings->SetTriangleRatio(1.0f);
    // Set the Normal Calculation Settings.
    spNormalCalculationSettings normalSettings = red->GetNormalCalculationSettings();
    normalSettings->SetReplaceNormals( true );
    normalSettings->SetHardEdgeAngleInRadians( 3.14159f * 90.f / 180.0f );
    // Set the Image Mapping Settings.
    spMappingImageSettings mappingSettings = red->GetMappingImageSettings();
    mappingSettings->SetGenerateMappingImage( true );
    mappingSettings->SetGenerateTexCoords( true ); // Set to generate new texture coordinates.
    mappingSettings->SetParameterizerMaxStretch( 0.5f ); // The higher the number, the fewer texture-borders.
    // We set the number of input materials and the number of output materials.
    mappingSettings->SetInputMaterialCount(originalMaterials->GetMaterialsCount());
    // We want to bake into two materials
    mappingSettings->SetOutputMaterialCount(2);
    // We set which output material each of the original materials should be baked to
    mappingSettings->SetInputOutputMaterialMapping(0, 0); //The first and second original materials are baked to the same output material
    mappingSettings->SetInputOutputMaterialMapping(1, 0);
    mappingSettings->SetInputOutputMaterialMapping(2, 1); //The third material is baked alone to the second output material
    // Set the properties for the first mapping image
    mappingSettings->SetGutterSpace(0, 4 );
    mappingSettings->SetWidth(0, 512 );
    mappingSettings->SetHeight(0, 512 );
    mappingSettings->SetMultisamplingLevel(0, 2 );
    // Set the properties for the second mapping image
    mappingSettings->SetGutterSpace(1, 4 );
    mappingSettings->SetWidth( 1, 1024 );
    mappingSettings->SetHeight( 1, 1024 );
    mappingSettings->SetMultisamplingLevel( 1, 2 );
    red->RunProcessing();
    // Mapping image is needed later on for texture casting.
    spMappingImage mappingImage0 = red->GetMappingImage(0);
    spMappingImage mappingImage1 = red->GetMappingImage(1);
    // Create new material table.
    spMaterialTable outputMaterials = sg->CreateMaterialTable();
    //  Create new material for the table.
    spMaterial outputMaterial0 = sg->CreateMaterial();
    outputMaterial0->SetName( "output_material1" );
    //Add the new material to the table
    outputMaterials->AddMaterial( outputMaterial0 );
    //  Create new material for the table.
    spMaterial outputMaterial1 = sg->CreateMaterial();
    outputMaterial1->SetName( "output_material2" );
    //Add the new material to the table
    outputMaterials->AddMaterial( outputMaterial1 );
    // Cast the first material
    if(true)
        {
        // Cast the data using a color caster
        spColorCaster cast = sg->CreateColorCaster();
        cast->SetColorType( SG_MATERIAL_CHANNEL_DIFFUSE ); //Select the diffuse channel from the original material
        cast->SetSourceMaterials( originalMaterials );
        cast->SetMappingImage( mappingImage0 ); // The mapping image we got from the reduction process.
        cast->SetOutputChannels( 3 ); // RGB, 3 channels! (1 would be for grey scale, and 4 would be for RGBA.)
        cast->SetOutputChannelBitDepth( 8 ); // 8 bits per channel. So in this case we will have 24bit colors RGB.
        cast->SetDilation( 10 ); // To avoid mip-map artifacts, the empty pixels on the map needs to be filled to a degree as well.
        cast->SetOutputFilePath( outputDiffuse1Filename.c_str() ); // Where the texture map will be saved to file.
        cast->CastMaterials(); // Fetch!
        // set the material properties
        // Set the diffuse multiplier for the texture. 1 means it will not differ from original texture
        outputMaterial0->SetColor(SG_MATERIAL_CHANNEL_DIFFUSE, 1.0,1.0,1.0,1.0);
        // Set material to point to created texture filename.
        outputMaterial0->SetTexture( SG_MATERIAL_CHANNEL_DIFFUSE , outputDiffuse1Filename.c_str() );
        }   
    // Cast the second material
    if(true)
        {
        // Cast the data using a color caster
        spColorCaster cast = sg->CreateColorCaster();
        cast->SetColorType( SG_MATERIAL_CHANNEL_DIFFUSE ); //Select the diffuse channel from the original material
        cast->SetSourceMaterials( originalMaterials );
        cast->SetMappingImage( mappingImage1 ); // The mapping image we got from the reduction process.
        cast->SetOutputChannels( 3 ); // RGB, 3 channels! (1 would be for grey scale, and 4 would be for RGBA.)
        cast->SetOutputChannelBitDepth( 8 ); // 8 bits per channel. So in this case we will have 24bit colors RGB.
        cast->SetDilation( 10 ); // To avoid mip-map artifacts, the empty pixels on the map needs to be filled to a degree as well.
        cast->SetOutputFilePath( outputDiffuse2Filename.c_str() ); // Where the texture map will be saved to file.
        cast->CastMaterials(); // Fetch!
        // set the material properties
        // Set the diffuse multiplier for the texture. 1 means it will not differ from original texture
        outputMaterial1->SetColor(SG_MATERIAL_CHANNEL_DIFFUSE, 1.0,1.0,1.0,1.0);
        // Set material to point to created texture filename.
        outputMaterial1->SetTexture( SG_MATERIAL_CHANNEL_DIFFUSE , outputDiffuse2Filename.c_str() );
        }   
    scene->GetMaterialTable()->Copy(outputMaterials);
    spWavefrontExporter objExporter = sg->CreateWavefrontExporter();
    objExporter->SetExportFilePath( outputGeometryFilename.c_str() );
    objExporter->SetScene(scene);
    objExporter->RunExport();
    }