# Mapping image settings
Simplygon can generate one or more mapping images, which can be used to cast material data from the original geometry onto the reduced geometry after the processing has completed.
A Mapping image is basically a texture on the reduced geometry where each pixel contains information of which triangle and barycentric coordinate on the original geometry that the pixel corresponds to.
The settings contains basic things like the desired texture dimensions of the mapping image to create, and there is also a setting for whether new texcoords shall be generated and how these texcoords shall be generated on the processed mesh. Texcoords can either be created from scratch when using the Parameterizer, purely based on LOD geometry, or be created from the original texcoords when using the ChartAggregator.
Some settings has a prefix which means they are only relevant when the corresponding GeneratorType is used. Multiple mapping image generation currently only works with the Reduction processor.
# Supported processors
- Reduction processor
- Remeshing processor
- Impostor processor
- Aggregation processor
- Foliage processor
# Example
This example shows how to use the Reduction processor with material casting.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include <string>
#include <stdlib.h>
#include <filesystem>
#include <future>
#include "SimplygonLoader.h"
void RunReductionWithMaterialCasting(Simplygon::ISimplygon* sg)
{
Simplygon::spSceneImporter sgSceneImporter = sg->CreateSceneImporter();
sgSceneImporter->SetImportFilePath( "../Assets/SimplygonMan/SimplygonMan.obj" );
if(!sgSceneImporter->RunImport())
throw std::exception("Failed to load SimplygonMan/SimplygonMan.obj.");
Simplygon::spScene sgScene = sgSceneImporter->GetScene();
// Create the reduction processor.
Simplygon::spReductionProcessor sgReductionProcessor = sg->CreateReductionProcessor();
sgReductionProcessor->SetScene( sgScene );
Simplygon::spReductionSettings sgReductionSettings = sgReductionProcessor->GetReductionSettings();
Simplygon::spMappingImageSettings sgMappingImageSettings = sgReductionProcessor->GetMappingImageSettings();
// Set reduction target to triangle ratio with a ratio of 50%.
sgReductionSettings->SetReductionTargets( Simplygon::EStopCondition::All, true, false, false, false );
sgReductionSettings->SetReductionTargetTriangleRatio( 0.5f );
// Generates a mapping image which is used after the reduction to cast new materials to the new
// reduced object.
sgMappingImageSettings->SetGenerateMappingImage( true );
sgMappingImageSettings->SetApplyNewMaterialIds( true );
sgMappingImageSettings->SetGenerateTangents( true );
sgMappingImageSettings->SetUseFullRetexturing( true );
sgMappingImageSettings->SetTexCoordGeneratorType( Simplygon::ETexcoordGeneratorType::ChartAggregator );
Simplygon::spChartAggregatorSettings sgChartAggregatorSettings = sgMappingImageSettings->GetChartAggregatorSettings();
// Enable the chart aggregator and reuse UV space.
sgChartAggregatorSettings->SetChartAggregatorMode( Simplygon::EChartAggregatorMode::SurfaceArea );
sgChartAggregatorSettings->SetSeparateOverlappingCharts( false );
Simplygon::spMappingImageOutputMaterialSettings sgOutputMaterialSettings = sgMappingImageSettings->GetOutputMaterialSettings(0);
// Setting the size of the output material for the mapping image. This will be the output size of the
// textures when we do material casting in a later stage.
sgOutputMaterialSettings->SetTextureWidth( 2048 );
sgOutputMaterialSettings->SetTextureHeight( 2048 );
// Start the reduction process.
sgReductionProcessor->RunProcessing();
// Setup and run the diffuse material casting.
Simplygon::spColorCaster sgDiffuseCaster = sg->CreateColorCaster();
sgDiffuseCaster->SetMappingImage( sgReductionProcessor->GetMappingImage() );
sgDiffuseCaster->SetSourceMaterials( sgScene->GetMaterialTable() );
sgDiffuseCaster->SetSourceTextures( sgScene->GetTextureTable() );
sgDiffuseCaster->SetOutputFilePath( "DiffuseTexture" );
Simplygon::spColorCasterSettings sgDiffuseCasterSettings = sgDiffuseCaster->GetColorCasterSettings();
sgDiffuseCasterSettings->SetMaterialChannel( "Diffuse" );
sgDiffuseCasterSettings->SetOutputImageFileFormat( Simplygon::EImageOutputFormat::PNG );
sgDiffuseCaster->RunProcessing();
std::string diffuseTextureFilePath = sgDiffuseCaster->GetOutputFilePath();
// Setup and run the normals material casting.
Simplygon::spNormalCaster sgNormalsCaster = sg->CreateNormalCaster();
sgNormalsCaster->SetMappingImage( sgReductionProcessor->GetMappingImage() );
sgNormalsCaster->SetSourceMaterials( sgScene->GetMaterialTable() );
sgNormalsCaster->SetSourceTextures( sgScene->GetTextureTable() );
sgNormalsCaster->SetOutputFilePath( "NormalsTexture" );
Simplygon::spNormalCasterSettings sgNormalsCasterSettings = sgNormalsCaster->GetNormalCasterSettings();
sgNormalsCasterSettings->SetMaterialChannel( "Normals" );
sgNormalsCasterSettings->SetGenerateTangentSpaceNormals( true );
sgNormalsCasterSettings->SetOutputImageFileFormat( Simplygon::EImageOutputFormat::PNG );
sgNormalsCaster->RunProcessing();
std::string normalsTextureFilePath = sgNormalsCaster->GetOutputFilePath();
// Update scene with new casted textures.
Simplygon::spMaterialTable sgMaterialTable = sg->CreateMaterialTable();
Simplygon::spTextureTable sgTextureTable = sg->CreateTextureTable();
Simplygon::spMaterial sgMaterial = sg->CreateMaterial();
Simplygon::spTexture sgDiffuseTexture = sg->CreateTexture();
sgDiffuseTexture->SetName( "Diffuse" );
sgDiffuseTexture->SetFilePath( diffuseTextureFilePath.c_str() );
sgTextureTable->AddTexture( sgDiffuseTexture );
Simplygon::spShadingTextureNode sgDiffuseTextureShadingNode = sg->CreateShadingTextureNode();
sgDiffuseTextureShadingNode->SetTexCoordLevel( 0 );
sgDiffuseTextureShadingNode->SetTextureName( "Diffuse" );
sgMaterial->AddMaterialChannel( "Diffuse" );
sgMaterial->SetShadingNetwork( "Diffuse", sgDiffuseTextureShadingNode );
Simplygon::spTexture sgNormalsTexture = sg->CreateTexture();
sgNormalsTexture->SetName( "Normals" );
sgNormalsTexture->SetFilePath( normalsTextureFilePath.c_str() );
sgTextureTable->AddTexture( sgNormalsTexture );
Simplygon::spShadingTextureNode sgNormalsTextureShadingNode = sg->CreateShadingTextureNode();
sgNormalsTextureShadingNode->SetTexCoordLevel( 0 );
sgNormalsTextureShadingNode->SetTextureName( "Normals" );
sgMaterial->AddMaterialChannel( "Normals" );
sgMaterial->SetShadingNetwork( "Normals", sgNormalsTextureShadingNode );
sgMaterialTable->AddMaterial( sgMaterial );
sgScene->GetTextureTable()->Clear();
sgScene->GetMaterialTable()->Clear();
sgScene->GetTextureTable()->Copy(sgTextureTable);
sgScene->GetMaterialTable()->Copy(sgMaterialTable);
Simplygon::spSceneExporter sgSceneExporter = sg->CreateSceneExporter();
sgSceneExporter->SetScene(sgScene);
sgSceneExporter->SetExportFilePath( "ReductionOutput.fbx" );
if(!sgSceneExporter->RunExport())
throw std::exception("Failed to save ReductionOutput.fbx.");
}
void main()
{
Simplygon::ISimplygon* sg = NULL;
Simplygon::EErrorCodes initval = Simplygon::Initialize( &sg );
if( initval != Simplygon::EErrorCodes::NoError )
{
return;
}
RunReductionWithMaterialCasting(sg);
Simplygon::Deinitialize(sg);
}
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.IO;
using System.Threading.Tasks;
public class Program
{
static void RunReductionWithMaterialCasting(Simplygon.ISimplygon sg)
{
using (Simplygon.spSceneImporter sgSceneImporter = sg.CreateSceneImporter())
{
sgSceneImporter.SetImportFilePath( "../Assets/SimplygonMan/SimplygonMan.obj" );
if(!sgSceneImporter.RunImport())
throw new System.Exception("Failed to load SimplygonMan/SimplygonMan.obj.");
Simplygon.spScene sgScene = sgSceneImporter.GetScene();
// Create the reduction processor.
using (Simplygon.spReductionProcessor sgReductionProcessor = sg.CreateReductionProcessor())
{
sgReductionProcessor.SetScene( sgScene );
using (Simplygon.spReductionSettings sgReductionSettings = sgReductionProcessor.GetReductionSettings())
using (Simplygon.spMappingImageSettings sgMappingImageSettings = sgReductionProcessor.GetMappingImageSettings())
{
// Set reduction target to triangle ratio with a ratio of 50%.
sgReductionSettings.SetReductionTargets( Simplygon.EStopCondition.All, true, false, false, false );
sgReductionSettings.SetReductionTargetTriangleRatio( 0.5f );
// Generates a mapping image which is used after the reduction to cast new materials to the new
// reduced object.
sgMappingImageSettings.SetGenerateMappingImage( true );
sgMappingImageSettings.SetApplyNewMaterialIds( true );
sgMappingImageSettings.SetGenerateTangents( true );
sgMappingImageSettings.SetUseFullRetexturing( true );
sgMappingImageSettings.SetTexCoordGeneratorType( Simplygon.ETexcoordGeneratorType.ChartAggregator );
using (Simplygon.spChartAggregatorSettings sgChartAggregatorSettings = sgMappingImageSettings.GetChartAggregatorSettings())
{
// Enable the chart aggregator and reuse UV space.
sgChartAggregatorSettings.SetChartAggregatorMode( Simplygon.EChartAggregatorMode.SurfaceArea );
sgChartAggregatorSettings.SetSeparateOverlappingCharts( false );
}
using (Simplygon.spMappingImageOutputMaterialSettings sgOutputMaterialSettings = sgMappingImageSettings.GetOutputMaterialSettings(0))
{
// Setting the size of the output material for the mapping image. This will be the output size of the
// textures when we do material casting in a later stage.
sgOutputMaterialSettings.SetTextureWidth( 2048 );
sgOutputMaterialSettings.SetTextureHeight( 2048 );
}
}
// Start the reduction process.
sgReductionProcessor.RunProcessing();
// Setup and run the diffuse material casting.
string diffuseTextureFilePath;
using (Simplygon.spColorCaster sgDiffuseCaster = sg.CreateColorCaster())
{
sgDiffuseCaster.SetMappingImage( sgReductionProcessor.GetMappingImage() );
sgDiffuseCaster.SetSourceMaterials( sgScene.GetMaterialTable() );
sgDiffuseCaster.SetSourceTextures( sgScene.GetTextureTable() );
sgDiffuseCaster.SetOutputFilePath( "DiffuseTexture" );
using (Simplygon.spColorCasterSettings sgDiffuseCasterSettings = sgDiffuseCaster.GetColorCasterSettings())
{
sgDiffuseCasterSettings.SetMaterialChannel( "Diffuse" );
sgDiffuseCasterSettings.SetOutputImageFileFormat( Simplygon.EImageOutputFormat.PNG );
}
sgDiffuseCaster.RunProcessing();
diffuseTextureFilePath = sgDiffuseCaster.GetOutputFilePath();
}
// Setup and run the normals material casting.
string normalsTextureFilePath;
using (Simplygon.spNormalCaster sgNormalsCaster = sg.CreateNormalCaster())
{
sgNormalsCaster.SetMappingImage( sgReductionProcessor.GetMappingImage() );
sgNormalsCaster.SetSourceMaterials( sgScene.GetMaterialTable() );
sgNormalsCaster.SetSourceTextures( sgScene.GetTextureTable() );
sgNormalsCaster.SetOutputFilePath( "NormalsTexture" );
using (Simplygon.spNormalCasterSettings sgNormalsCasterSettings = sgNormalsCaster.GetNormalCasterSettings())
{
sgNormalsCasterSettings.SetMaterialChannel( "Normals" );
sgNormalsCasterSettings.SetGenerateTangentSpaceNormals( true );
sgNormalsCasterSettings.SetOutputImageFileFormat( Simplygon.EImageOutputFormat.PNG );
}
sgNormalsCaster.RunProcessing();
normalsTextureFilePath = sgNormalsCaster.GetOutputFilePath();
}
// Update scene with new casted textures.
using (Simplygon.spMaterialTable sgMaterialTable = sg.CreateMaterialTable())
using (Simplygon.spTextureTable sgTextureTable = sg.CreateTextureTable())
using (Simplygon.spMaterial sgMaterial = sg.CreateMaterial())
{
using(Simplygon.spTexture sgDiffuseTexture = sg.CreateTexture())
{
sgDiffuseTexture.SetName( "Diffuse" );
sgDiffuseTexture.SetFilePath( diffuseTextureFilePath );
sgTextureTable.AddTexture( sgDiffuseTexture );
}
using(Simplygon.spShadingTextureNode sgDiffuseTextureShadingNode = sg.CreateShadingTextureNode())
{
sgDiffuseTextureShadingNode.SetTexCoordLevel( 0 );
sgDiffuseTextureShadingNode.SetTextureName( "Diffuse" );
sgMaterial.AddMaterialChannel( "Diffuse" );
sgMaterial.SetShadingNetwork( "Diffuse", sgDiffuseTextureShadingNode );
}
using(Simplygon.spTexture sgNormalsTexture = sg.CreateTexture())
{
sgNormalsTexture.SetName( "Normals" );
sgNormalsTexture.SetFilePath( normalsTextureFilePath );
sgTextureTable.AddTexture( sgNormalsTexture );
}
using(Simplygon.spShadingTextureNode sgNormalsTextureShadingNode = sg.CreateShadingTextureNode())
{
sgNormalsTextureShadingNode.SetTexCoordLevel( 0 );
sgNormalsTextureShadingNode.SetTextureName( "Normals" );
sgMaterial.AddMaterialChannel( "Normals" );
sgMaterial.SetShadingNetwork( "Normals", sgNormalsTextureShadingNode );
}
sgMaterialTable.AddMaterial( sgMaterial );
sgScene.GetTextureTable().Clear();
sgScene.GetMaterialTable().Clear();
sgScene.GetTextureTable().Copy(sgTextureTable);
sgScene.GetMaterialTable().Copy(sgMaterialTable);
}
}
using (Simplygon.spSceneExporter sgSceneExporter = sg.CreateSceneExporter())
{
sgSceneExporter.SetScene(sgScene);
sgSceneExporter.SetExportFilePath( "ReductionOutput.fbx" );
if(!sgSceneExporter.RunExport())
throw new System.Exception("Failed to save ReductionOutput.fbx.");
}
}
}
static void Main(string[] args)
{
using (var sg = Simplygon.Loader.InitSimplygon(out var errorCode, out var errorMessage))
{
if (errorCode != Simplygon.EErrorCodes.NoError)
return;
RunReductionWithMaterialCasting(sg);
}
}
}
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
import math
import os
import sys
import glob
import gc
import threading
from pathlib import Path
from simplygon import simplygon_loader
from simplygon import Simplygon
def RunReductionWithMaterialCasting(sg: Simplygon.ISimplygon):
sgSceneImporter = sg.CreateSceneImporter()
sgSceneImporter.SetImportFilePath( '../Assets/SimplygonMan/SimplygonMan.obj' )
if not sgSceneImporter.RunImport():
raise Exception('Failed to load SimplygonMan/SimplygonMan.obj.')
sgScene = sgSceneImporter.GetScene()
# Create the reduction processor.
sgReductionProcessor = sg.CreateReductionProcessor()
sgReductionProcessor.SetScene( sgScene )
sgReductionSettings = sgReductionProcessor.GetReductionSettings()
sgMappingImageSettings = sgReductionProcessor.GetMappingImageSettings()
# Set reduction target to triangle ratio with a ratio of 50%.
sgReductionSettings.SetReductionTargets( Simplygon.EStopCondition_All, True, False, False, False )
sgReductionSettings.SetReductionTargetTriangleRatio( 0.5 )
# Generates a mapping image which is used after the reduction to cast new materials to the new
# reduced object.
sgMappingImageSettings.SetGenerateMappingImage( True )
sgMappingImageSettings.SetApplyNewMaterialIds( True )
sgMappingImageSettings.SetGenerateTangents( True )
sgMappingImageSettings.SetUseFullRetexturing( True )
sgMappingImageSettings.SetTexCoordGeneratorType( Simplygon.ETexcoordGeneratorType_ChartAggregator )
sgChartAggregatorSettings = sgMappingImageSettings.GetChartAggregatorSettings()
# Enable the chart aggregator and reuse UV space.
sgChartAggregatorSettings.SetChartAggregatorMode( Simplygon.EChartAggregatorMode_SurfaceArea )
sgChartAggregatorSettings.SetSeparateOverlappingCharts( False )
sgOutputMaterialSettings = sgMappingImageSettings.GetOutputMaterialSettings(0)
# Setting the size of the output material for the mapping image. This will be the output size of the
# textures when we do material casting in a later stage.
sgOutputMaterialSettings.SetTextureWidth( 2048 )
sgOutputMaterialSettings.SetTextureHeight( 2048 )
# Start the reduction process.
sgReductionProcessor.RunProcessing()
# Setup and run the diffuse material casting.
sgDiffuseCaster = sg.CreateColorCaster()
sgDiffuseCaster.SetMappingImage( sgReductionProcessor.GetMappingImage() )
sgDiffuseCaster.SetSourceMaterials( sgScene.GetMaterialTable() )
sgDiffuseCaster.SetSourceTextures( sgScene.GetTextureTable() )
sgDiffuseCaster.SetOutputFilePath( 'DiffuseTexture' )
sgDiffuseCasterSettings = sgDiffuseCaster.GetColorCasterSettings()
sgDiffuseCasterSettings.SetMaterialChannel( 'Diffuse' )
sgDiffuseCasterSettings.SetOutputImageFileFormat( Simplygon.EImageOutputFormat_PNG )
sgDiffuseCaster.RunProcessing()
diffuseTextureFilePath = sgDiffuseCaster.GetOutputFilePath()
# Setup and run the normals material casting.
sgNormalsCaster = sg.CreateNormalCaster()
sgNormalsCaster.SetMappingImage( sgReductionProcessor.GetMappingImage() )
sgNormalsCaster.SetSourceMaterials( sgScene.GetMaterialTable() )
sgNormalsCaster.SetSourceTextures( sgScene.GetTextureTable() )
sgNormalsCaster.SetOutputFilePath( 'NormalsTexture' )
sgNormalsCasterSettings = sgNormalsCaster.GetNormalCasterSettings()
sgNormalsCasterSettings.SetMaterialChannel( 'Normals' )
sgNormalsCasterSettings.SetGenerateTangentSpaceNormals( True )
sgNormalsCasterSettings.SetOutputImageFileFormat( Simplygon.EImageOutputFormat_PNG )
sgNormalsCaster.RunProcessing()
normalsTextureFilePath = sgNormalsCaster.GetOutputFilePath()
# Update scene with new casted textures.
sgMaterialTable = sg.CreateMaterialTable()
sgTextureTable = sg.CreateTextureTable()
sgMaterial = sg.CreateMaterial()
sgDiffuseTexture = sg.CreateTexture()
sgDiffuseTexture.SetName( 'Diffuse' )
sgDiffuseTexture.SetFilePath( diffuseTextureFilePath )
sgTextureTable.AddTexture( sgDiffuseTexture )
sgDiffuseTextureShadingNode = sg.CreateShadingTextureNode()
sgDiffuseTextureShadingNode.SetTexCoordLevel( 0 )
sgDiffuseTextureShadingNode.SetTextureName( 'Diffuse' )
sgMaterial.AddMaterialChannel( 'Diffuse' )
sgMaterial.SetShadingNetwork( 'Diffuse', sgDiffuseTextureShadingNode )
sgNormalsTexture = sg.CreateTexture()
sgNormalsTexture.SetName( 'Normals' )
sgNormalsTexture.SetFilePath( normalsTextureFilePath )
sgTextureTable.AddTexture( sgNormalsTexture )
sgNormalsTextureShadingNode = sg.CreateShadingTextureNode()
sgNormalsTextureShadingNode.SetTexCoordLevel( 0 )
sgNormalsTextureShadingNode.SetTextureName( 'Normals' )
sgMaterial.AddMaterialChannel( 'Normals' )
sgMaterial.SetShadingNetwork( 'Normals', sgNormalsTextureShadingNode )
sgMaterialTable.AddMaterial( sgMaterial )
sgScene.GetTextureTable().Clear()
sgScene.GetMaterialTable().Clear()
sgScene.GetTextureTable().Copy(sgTextureTable)
sgScene.GetMaterialTable().Copy(sgMaterialTable)
sgSceneExporter = sg.CreateSceneExporter()
sgSceneExporter.SetScene(sgScene)
sgSceneExporter.SetExportFilePath( 'ReductionOutput.fbx' )
if not sgSceneExporter.RunExport():
raise Exception('Failed to save ReductionOutput.fbx.')
if __name__ == '__main__':
sg = simplygon_loader.init_simplygon()
if sg is not None:
RunReductionWithMaterialCasting(sg)
sg = None
gc.collect()