Show / Hide Table of Contents
    ///////////////////////////////////////////////////////////////////////////
    //
    //  System:    Simplygon
    //  File:      VertexColorBakingExample.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# 
    //
    //  Utilizes the VertexColorBaker to bake all a specific channel of the 
    //  materials into a vertex color field.
    //
    //
    ///////////////////////////////////////////////////////////////////////////
    
    #include "../Common/Example.h"
    
    void RunBakingTesting( const std::string& readFrom, const std::string& writeToBaked );
    
    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
            //
            RunBakingTesting(assetPath + "SimplygonMan/SimplygonMan.obj", "SimplygonMan_bakedDiffuse");
    
            DeinitExample();
        }
        catch (const std::exception& ex)
        {
            std::cerr << ex.what() << std::endl;
            return -1;
        }
    
        return 0;
        }
    
    void RunBakingTesting( const std::string& readFrom, const std::string& writeToBaked )
        {
        // Import geometries from a file and optimize them. Generate a mapping image
        // from the LOD to the original that will be used to sample the materials and
        // populate the vertex color field.
    
        // Generate the output filenames
        //
        std::string output_geometry_baked_filename = writeToBaked + ".sgscene";
    
        // Load object from file
        //
        spWavefrontImporter objReader = sg->CreateWavefrontImporter();
        objReader->SetImportFilePath( readFrom.c_str() );
        if( !objReader->RunImport() )
            throw std::exception("Failed to load input file!");
    
        spScene scene = objReader->GetScene();
    
        // Reducer
        //
        spReductionProcessor reducer = sg->CreateReductionProcessor();
        reducer->SetScene( scene );
    
        // Set the Repair Settings.
        //
        spRepairSettings repairSettings = reducer->GetRepairSettings();
        repairSettings->SetWeldDist( 0.0f );
        repairSettings->SetTjuncDist( 0.0f );
    
        // Set the Reduction Settings.
        //
        spReductionSettings reductionSettings = reducer->GetReductionSettings();
        reductionSettings->SetTriangleRatio( 0.5 );
    
        // Set the Image Mapping Settings.
        //
        spMappingImageSettings mappingSettings = reducer->GetMappingImageSettings();
    
        // Without this we cannot fetch data from the original geometry, and thus not
        // populate the vertex color field
        //
        mappingSettings->SetGenerateMappingImage( true );
    
        // The higher the number, the fewer texture-borders.
        //
        mappingSettings->SetParameterizerMaxStretch( 0.5f );
        mappingSettings->SetGutterSpace( 1 );
    
        // When only using the mapping image to bake to vert colors, the resolution and super-sampling
        // effectively decides how many samples will be used for each vertex. Higher sizes means better quality.
        //
        mappingSettings->SetWidth( 1024 );
        mappingSettings->SetHeight( 1024 );
        mappingSettings->SetMultisamplingLevel( 1 );
    
        // If the asset does not already have unique UVs per vertex, i.e. many textures or mirrored UVs,
        // a new unique UV set will need to be generated for the mapping image.
        //
        mappingSettings->SetGenerateTexCoords( true );
        mappingSettings->SetTexCoordLevel( (SG_NUM_SUPPORTED_TEXTURE_CHANNELS - 1) );
    
        reducer->RunProcessing();
    
        // Mapping image has now been generated
        //
        spMappingImage mappingImage = reducer->GetMappingImage();
    
        // Now, finally, bake the entire diffuse channel into color field 0
        //
        spVertexColorBaker baker = sg->CreateVertexColorBaker();
        baker->SetScene( scene ); // The geometry in which you want to create the new vertex color field
        baker->SetMappingImage( mappingImage ); // The mapping image mapping the original geometry to the geometry set above
        baker->SetSourceMaterials( scene->GetMaterialTable() ); // The material table from which the sampling will be done
        baker->SetSourceTextures( scene->GetTextureTable() );
        baker->SetChannelName( SG_MATERIAL_CHANNEL_DIFFUSE ); // The channel that will be cast to the color field
        baker->SetOutputColorLevelName( "0" ); // The output color level
        baker->SetColorSpaceEdgeThreshold( 3.0 ); // This will determine how many "hard borders" will exist in the color field
        // It is essentially a RGBA color space difference threshold, where smaller distances are merged.
        // This means that the largest distance is sqrt(4) = 2, so 3.0 will produce all smooth borders.
    
        baker->Bake();
    
        // Since .obj does not support colors, we export the result as a scene binary.
        //
        scene->SaveToFile( output_geometry_baked_filename.c_str() );
    
    
        ///////////////////////////////////
        //Output a map of the vertex colors
        spScene sceneWithVertexColors = sg->CreateScene();
        sceneWithVertexColors->LoadFromFile(output_geometry_baked_filename.c_str());
        spGeometryData geom = sceneWithVertexColors->NewCombinedGeometry();
        spRealArray colors = geom->GetColors(0);
    
        sceneWithVertexColors->GetTextureTable()->Clear();
        sceneWithVertexColors->GetMaterialTable()->Clear();
    
        spShadingVertexColorNode exitNode = sg->CreateShadingVertexColorNode();
        exitNode->SetVertexColorIndex(0);
    
        spMaterial mat = sg->CreateMaterial();
        mat->SetShadingNetwork(SG_MATERIAL_CHANNEL_DIFFUSE, exitNode);
        sceneWithVertexColors->GetMaterialTable()->AddMaterial(mat);
    
        //Use the reduction processor to generate the mapping image needed for outputting the vertex color map
        spReductionProcessor red = sg->CreateReductionProcessor();
        red->SetScene(sceneWithVertexColors);
        red->GetMappingImageSettings()->SetGenerateMappingImage(true);
        red->GetMappingImageSettings()->SetUseFullRetexturing(true);
        red->RunProcessing();
    
        int id = sceneWithVertexColors->SelectNodes("ISceneMesh");
        spSelectionSet set = sceneWithVertexColors->GetSelectionSetTable()->GetSelectionSet(id);
        for (uint i = 0; i < set->GetItemCount(); ++i)
            {
            spGeometryData geomWithVertexColors = SafeCast<ISceneMesh>(sceneWithVertexColors->GetNodeByGUID(set->GetItem(i)))->GetGeometry();
    
            for (uint m = 0; m < geomWithVertexColors->GetMaterialIds()->GetItemCount(); ++m)
                {
                geomWithVertexColors->GetMaterialIds()->SetItem(m, 0);
                }
            }
    
        //Use a colorcaster to output the vertex colors
        spColorCaster caster = sg->CreateColorCaster();
        caster->SetSourceMaterials(sceneWithVertexColors->GetMaterialTable());
        caster->SetMappingImage(red->GetMappingImage());
        caster->SetColorType(SG_MATERIAL_CHANNEL_DIFFUSE);
        caster->SetOutputFilePath("vertexcolors.png");
        caster->RunProcessing();
    
    
    
        }
    
    Back to top Terms of Use | Privacy and cookies | Trademarks | Copyright © 2019 Microsoft