ChartAggregatorExample.cpp

<< Click to Display Table of Contents >>

Navigation:  Simplygon 7.1 examples >

ChartAggregatorExample.cpp

///////////////////////////////////////////////////////////////////////////
//
//  System:    Simplygon
//  File:      ChartAggregatorExample.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#
// 
//  Sets up a scene from an OBJ file and creates an aggregate
//  UV layout for all mesh parts, while preserving original charts.
//  Four different layouts are produced, where charts are scaled differently:
//  - Equal scaling
//  - Scaling weighted based on the charts' corresponding area in 3D space
//  - Scaling weighted based on the corresponding material texture sizes
//  - Scaling charts to perfectly reproduce the pixel density of the input textures
//
//  To view the results, load the outputted scenes and view the texture coords.
//
//  No new materials are baked in this example, only new UVs are computed.
//  Check out AggregationProcessorExample for aggregating scenes and baking
//  the materials.
//
///////////////////////////////////////////////////////////////////////////
#include "../Common/Example.h"
void RunChartAggregation(const std::string& readFrom,
                         const std::string& writeToUnWeighted,
                         const std::string& writeToAreaWeighted,
                         const std::string& writeToOriginalTextureWeighted,
                         const std::string& writeToAreaAndTexture);
int main( int argc , char* argv[] )
    {
    InitExample();
    std::string assetPath = GetAssetPath();
    // Run the example code
    //
    RunChartAggregation(assetPath + "TexturedPlanes/texturedplanes.obj", "result_unweighted", "result_areaWeighted", "result_originalTextureWeighted", "result_areaAndTexture");
    DeinitExample();
    return 0;
    }
void RunChartAggregation(const std::string& readFrom,
                         const std::string& writeToUnWeighted,
                         const std::string& writeToAreaWeighted,
                         const std::string& writeToOriginalTextureWeighted,
                         const std::string& writeToAreaAndTexture
                         )
    {
    std::string exePath = GetExecutablePath();
    // Import geometries from a file and optimize them.
    //
    std::string output_unweighted_filename = exePath + writeToUnWeighted + ".obj";
    std::string output_areaweighted_filename = exePath + writeToAreaWeighted + ".obj";
    std::string output_textureweighted_filename = exePath + writeToOriginalTextureWeighted + ".obj";
    std::string output_preservedpixeldensity_filename = exePath + writeToAreaAndTexture + ".obj";
    // Load object from file.
    // Have the importer combine all groups into one geometry.
    //
    spWavefrontImporter objReader = sg->CreateWavefrontImporter();
    objReader->SetExtractGroups(false);
    objReader->SetImportFilePath( readFrom.c_str() );
    if( !objReader->RunImport() )
        {
        return;
        }
    spScene scene = objReader->GetScene();
    spSceneMesh sceneMesh = SafeCast<ISceneMesh>(scene->GetRootNode()->GetChild(0));
    spGeometryData originalGeometry = sceneMesh->GetGeometry();
    // The working geometry have multiple overlapping UV charts, since
    // several meshes were combined into one geometry.
    // Now, create new chart-disjoint UV layouts by running the
    // chart aggregator.
    //
    spChartAggregator chartAggregator = sg->CreateChartAggregator();
    // If multiple parts of the mesh have the same texcoords, you can either select to
    // only generate one instance of the repeating texture or one instance for each
    // time it is used. This is controlled with the SeparateOverlappingCharts flag.
    // If charts are overlapping in the original texture coords, they will be separated if
    // SeparateOverlappingCharts is set to true.
    //
    chartAggregator->SetSeparateOverlappingCharts(true);
    chartAggregator->SetMaterialTable(scene->GetMaterialTable());
    chartAggregator->SetTexCoordLevel( 0 );
    chartAggregator->SetTextureWidth( 1024 );
    chartAggregator->SetTextureHeight( 1024 );
    chartAggregator->SetGutterSpace( 4 );
    spWavefrontExporter objExporter = sg->CreateWavefrontExporter();
    // Unweighted layout (i.e. all charts are scaled with the same factor, so sizes correspond to the proportions defined by their old UVs)
    //
    spGeometryData workingGeometry = originalGeometry->NewCopy(true);
    chartAggregator->SetChartAggregatorMode( SG_CHARTAGGREGATORMODE_UVSIZEPROPORTIONS );
    chartAggregator->Parameterize( workingGeometry, workingGeometry->GetTexCoords(0) );
    sceneMesh->SetGeometry(workingGeometry);
    objExporter->SetExportFilePath( output_unweighted_filename.c_str() );
    objExporter->SetScene( scene );
    objExporter->RunExport();
    // Chart size based on corresponding geometry area in 3D-space, i.e. pixel density per area will be consistent across the mesh
    //
    workingGeometry = originalGeometry->NewCopy(true);
    chartAggregator->SetChartAggregatorMode( SG_CHARTAGGREGATORMODE_SURFACEAREA );
    chartAggregator->Parameterize( workingGeometry, workingGeometry->GetTexCoords(0) );
    sceneMesh->SetGeometry(workingGeometry);
    objExporter = sg->CreateWavefrontExporter();
    objExporter->SetExportFilePath( output_areaweighted_filename.c_str() );
    objExporter->SetScene( scene );
    objExporter->RunExport();
    // Chart size based on the original texture sizes. Here we want the output chart proportions to be determined by the original textures proportions
    //
    workingGeometry = originalGeometry->NewCopy(true);
    chartAggregator->SetChartAggregatorMode( SG_CHARTAGGREGATORMODE_TEXTURESIZEPROPORTIONS );
    // We can decide which texture channel decides which proportions to keep, diffuse if default
    //chartAggregator->SetOriginalChartProportionsChannel(SG_MATERIAL_CHANNEL_DIFFUSE);
    chartAggregator->Parameterize( workingGeometry, workingGeometry->GetTexCoords(0) );
    sceneMesh->SetGeometry(workingGeometry);
    objExporter = sg->CreateWavefrontExporter();
    objExporter->SetExportFilePath( output_textureweighted_filename.c_str() );
    objExporter->SetScene( scene );
    objExporter->RunExport();
    // Chart size based on the original texture sizes, while perfectly maintaining the pixel density of the original textures. Will override manually set output texture sizes.
    //
    workingGeometry = originalGeometry->NewCopy(true);
    chartAggregator->SetChartAggregatorMode( SG_CHARTAGGREGATORMODE_ORIGINALPIXELDENSITY );
    // We can decide which texture channel decides which proportions to keep, diffuse if default
    //chartAggregator->SetOriginalChartProportionsChannel(SG_MATERIAL_CHANNEL_DIFFUSE);
    chartAggregator->Parameterize( workingGeometry, workingGeometry->GetTexCoords(0) );
    sceneMesh->SetGeometry(workingGeometry);
    objExporter = sg->CreateWavefrontExporter();
    objExporter->SetExportFilePath( output_preservedpixeldensity_filename.c_str() );
    objExporter->SetScene( scene );
    objExporter->RunExport();
    }