<< 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();
}