Show / Hide Table of Contents
    ///////////////////////////////////////////////////////////////////////////
    //
    //  System:    Simplygon
    //  File:      MultiMaterialCastingExample.cpp
    //  Language:  C++
    //
    //  Copyright (c) 2019 Microsoft. 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[] )
        {
        try
        {
            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();
        }
        catch (const std::exception& ex)
        {
            std::cerr << ex.what() << std::endl;
            return -1;
        }
    
        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() )
            throw std::exception("Failed to load input file!");
    
        // Get the scene
        spScene scene = objReader->GetScene();
        spMaterialTable originalMaterials = scene->GetMaterialTable();
        spTextureTable originalTextures = scene->GetTextureTable();
    
        //Setup lod scene
        spScene lodScene = sg->CreateScene();
        lodScene->DeepCopy( scene );
        spMaterialTable lodMatTable = lodScene->GetMaterialTable();
        lodMatTable->Clear();
        spTextureTable lodTexTable = lodScene->GetTextureTable();
        lodTexTable->Clear();
    
        //Reducer
        spReductionProcessor red = sg->CreateReductionProcessor();
        red->SetScene( lodScene );
    
        // 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
        spMaterial outputMaterial0 = sg->CreateMaterial();
        outputMaterial0->SetName( "output_material1" );
    
        //Add the new material
        lodMatTable->AddMaterial( outputMaterial0 );
    
        //  Create new material for the table.
        spMaterial outputMaterial1 = sg->CreateMaterial();
        outputMaterial1->SetName( "output_material2" );
    
        //Add the new material to the table
        lodMatTable->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->SetSourceTextures( originalTextures );
            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->RunProcessing(); // Fetch!
    
            //Setup new texture in LOD scene
            {
            spTexture newTex = sg->CreateTexture();
            newTex->SetFilePath( outputDiffuse1Filename.c_str() );
            newTex->SetName( "mat0Diff" );
            lodTexTable->AddTexture( newTex );
            spShadingTextureNode texNode = sg->CreateShadingTextureNode();
            texNode->SetTextureName( "mat0Diff" );
            outputMaterial0->SetShadingNetwork( SG_MATERIAL_CHANNEL_DIFFUSE, texNode );
            }
            }
    
        // 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->SetSourceTextures( originalTextures );
            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->RunProcessing(); // Fetch!
    
            //Setup new texture in LOD scene
            {
            spTexture newTex = sg->CreateTexture();
            newTex->SetFilePath( outputDiffuse2Filename.c_str() );
            newTex->SetName( "mat1Diff" );
            lodTexTable->AddTexture( newTex );
            spShadingTextureNode texNode = sg->CreateShadingTextureNode();
            texNode->SetTextureName( "mat1Diff" );
            outputMaterial1->SetShadingNetwork( SG_MATERIAL_CHANNEL_DIFFUSE, texNode );
            }
            }
    
        spWavefrontExporter objExporter = sg->CreateWavefrontExporter();
        objExporter->SetExportFilePath( outputGeometryFilename.c_str() );
        objExporter->SetScene( lodScene );
        objExporter->RunExport();
        }
    
    Back to top Terms of Use | Privacy and cookies | Trademarks | Copyright © 2019 Microsoft