Skip to content
On this page

Geometry data caster

The Geometry data caster is used to cast arbitrary geometry fields like the original texcoords to imagedata, allowing things like indirect texturing or manual runtime material casting.

This example shows how to use the geometry data caster.

cpp
// Copyright (c) Microsoft Corporation. 
// Licensed under the MIT License. 

#include <string>
#include <stdlib.h>
#include <filesystem>
#include <future>
#include "SimplygonLoader.h"


Simplygon::spScene LoadScene(Simplygon::ISimplygon* sg, const char* path)
{
	// Create scene importer 
	Simplygon::spSceneImporter sgSceneImporter = sg->CreateSceneImporter();
	sgSceneImporter->SetImportFilePath(path);
	
	// Run scene importer. 
	auto importResult = sgSceneImporter->Run();
	if (Simplygon::Failed(importResult))
	{
		throw std::exception("Failed to load scene.");
	}
	Simplygon::spScene sgScene = sgSceneImporter->GetScene();
	return sgScene;
}

void SaveScene(Simplygon::ISimplygon* sg, Simplygon::spScene sgScene, const char* path)
{
	// Create scene exporter. 
	Simplygon::spSceneExporter sgSceneExporter = sg->CreateSceneExporter();
	std::string outputScenePath = std::string("output\\") + std::string("GeometryDataCasting") + std::string("_") + std::string(path);
	sgSceneExporter->SetExportFilePath(outputScenePath.c_str());
	sgSceneExporter->SetScene(sgScene);
	
	// Run scene exporter. 
	auto exportResult = sgSceneExporter->Run();
	if (Simplygon::Failed(exportResult))
	{
		throw std::exception("Failed to save scene.");
	}
}

void CheckLog(Simplygon::ISimplygon* sg)
{
	// Check if any errors occurred. 
	bool hasErrors = sg->ErrorOccurred();
	if (hasErrors)
	{
		Simplygon::spStringArray errors = sg->CreateStringArray();
		sg->GetErrorMessages(errors);
		auto errorCount = errors->GetItemCount();
		if (errorCount > 0)
		{
			printf("%s\n", "CheckLog: Errors:");
			for (auto errorIndex = 0U; errorIndex < errorCount; ++errorIndex)
			{
				Simplygon::spString errorString = errors->GetItem((int)errorIndex);
				printf("%s\n", errorString.c_str());
			}
			sg->ClearErrorMessages();
		}
	}
	else
	{
		printf("%s\n", "CheckLog: No errors.");
	}
	
	// Check if any warnings occurred. 
	bool hasWarnings = sg->WarningOccurred();
	if (hasWarnings)
	{
		Simplygon::spStringArray warnings = sg->CreateStringArray();
		sg->GetWarningMessages(warnings);
		auto warningCount = warnings->GetItemCount();
		if (warningCount > 0)
		{
			printf("%s\n", "CheckLog: Warnings:");
			for (auto warningIndex = 0U; warningIndex < warningCount; ++warningIndex)
			{
				Simplygon::spString warningString = warnings->GetItem((int)warningIndex);
				printf("%s\n", warningString.c_str());
			}
			sg->ClearWarningMessages();
		}
	}
	else
	{
		printf("%s\n", "CheckLog: No warnings.");
	}
	
	// Error out if Simplygon has errors. 
	if (hasErrors)
	{
		throw std::exception("Processing failed with an error");
	}
}

void RunGeometryDataDasting(Simplygon::ISimplygon* sg)
{
	// Load scene to process. 
	Simplygon::spScene sgScene = LoadScene(sg, "../../../Assets/SimplygonMan/SimplygonMan.obj");
	
	// Create the remeshing processor. 
	Simplygon::spRemeshingProcessor sgRemeshingProcessor = sg->CreateRemeshingProcessor();
	sgRemeshingProcessor->SetScene( sgScene );
	Simplygon::spRemeshingSettings sgRemeshingSettings = sgRemeshingProcessor->GetRemeshingSettings();
	Simplygon::spMappingImageSettings sgMappingImageSettings = sgRemeshingProcessor->GetMappingImageSettings();
	
	// Set on-screen size target for remeshing. 
	sgRemeshingSettings->SetOnScreenSize( 300 );
	
	// Generates a mapping image which is used after the remeshing to cast new materials to the new 
	// remeshed object. 
	sgMappingImageSettings->SetGenerateMappingImage( true );
	sgMappingImageSettings->SetGenerateTexCoords( true );
	sgMappingImageSettings->SetApplyNewMaterialIds( true );
	sgMappingImageSettings->SetGenerateTangents( true );
	sgMappingImageSettings->SetUseFullRetexturing( true );
	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 remeshing process. 	
	printf("%s\n", "Start the remeshing process.");
	sgRemeshingProcessor->RunProcessing();
	
	// Setup and run the geometry data caster casting Coords to a texture. 	
	printf("%s\n", "Setup and run the geometry data caster casting Coords to a texture.");
	Simplygon::spGeometryDataCaster sgGeometryData_CoordsCaster = sg->CreateGeometryDataCaster();
	sgGeometryData_CoordsCaster->SetMappingImage( sgRemeshingProcessor->GetMappingImage() );
	sgGeometryData_CoordsCaster->SetSourceMaterials( sgScene->GetMaterialTable() );
	sgGeometryData_CoordsCaster->SetSourceTextures( sgScene->GetTextureTable() );
	sgGeometryData_CoordsCaster->SetOutputFilePath( "GeometryData_CoordsTexture" );

	Simplygon::spGeometryDataCasterSettings sgGeometryData_CoordsCasterSettings = sgGeometryData_CoordsCaster->GetGeometryDataCasterSettings();
	sgGeometryData_CoordsCasterSettings->SetMaterialChannel( "GeometryData_Coords" );
	sgGeometryData_CoordsCasterSettings->SetOutputImageFileFormat( Simplygon::EImageOutputFormat::PNG );
	sgGeometryData_CoordsCasterSettings->SetOutputPixelFormat( Simplygon::EPixelFormat::R16G16B16 );
	sgGeometryData_CoordsCasterSettings->SetFillMode( Simplygon::EAtlasFillMode::NoFill );
	sgGeometryData_CoordsCasterSettings->SetGeometryDataFieldType( Simplygon::EGeometryDataFieldType::Coords );
	sgGeometryData_CoordsCasterSettings->SetGeometryDataFieldIndex( 0 );

	sgGeometryData_CoordsCaster->RunProcessing();
	std::string geometrydata_coordsTextureFilePath = sgGeometryData_CoordsCaster->GetOutputFilePath().c_str();
	
	// Setup and run the geometry data caster casting Normals to a texture. 	
	printf("%s\n", "Setup and run the geometry data caster casting Normals to a texture.");
	Simplygon::spGeometryDataCaster sgGeometryData_NormalsCaster = sg->CreateGeometryDataCaster();
	sgGeometryData_NormalsCaster->SetMappingImage( sgRemeshingProcessor->GetMappingImage() );
	sgGeometryData_NormalsCaster->SetSourceMaterials( sgScene->GetMaterialTable() );
	sgGeometryData_NormalsCaster->SetSourceTextures( sgScene->GetTextureTable() );
	sgGeometryData_NormalsCaster->SetOutputFilePath( "GeometryData_NormalsTexture" );

	Simplygon::spGeometryDataCasterSettings sgGeometryData_NormalsCasterSettings = sgGeometryData_NormalsCaster->GetGeometryDataCasterSettings();
	sgGeometryData_NormalsCasterSettings->SetMaterialChannel( "GeometryData_Normals" );
	sgGeometryData_NormalsCasterSettings->SetOutputImageFileFormat( Simplygon::EImageOutputFormat::PNG );
	sgGeometryData_NormalsCasterSettings->SetOutputPixelFormat( Simplygon::EPixelFormat::R16G16B16 );
	sgGeometryData_NormalsCasterSettings->SetFillMode( Simplygon::EAtlasFillMode::NoFill );
	sgGeometryData_NormalsCasterSettings->SetGeometryDataFieldType( Simplygon::EGeometryDataFieldType::Normals );
	sgGeometryData_NormalsCasterSettings->SetGeometryDataFieldIndex( 0 );

	sgGeometryData_NormalsCaster->RunProcessing();
	std::string geometrydata_normalsTextureFilePath = sgGeometryData_NormalsCaster->GetOutputFilePath().c_str();
	
	// Setup and run the geometry data caster casting MaterialIds to a texture. 	
	printf("%s\n", "Setup and run the geometry data caster casting MaterialIds to a texture.");
	Simplygon::spGeometryDataCaster sgGeometryData_MaterialIdsCaster = sg->CreateGeometryDataCaster();
	sgGeometryData_MaterialIdsCaster->SetMappingImage( sgRemeshingProcessor->GetMappingImage() );
	sgGeometryData_MaterialIdsCaster->SetSourceMaterials( sgScene->GetMaterialTable() );
	sgGeometryData_MaterialIdsCaster->SetSourceTextures( sgScene->GetTextureTable() );
	sgGeometryData_MaterialIdsCaster->SetOutputFilePath( "GeometryData_MaterialIdsTexture" );

	Simplygon::spGeometryDataCasterSettings sgGeometryData_MaterialIdsCasterSettings = sgGeometryData_MaterialIdsCaster->GetGeometryDataCasterSettings();
	sgGeometryData_MaterialIdsCasterSettings->SetMaterialChannel( "GeometryData_MaterialIds" );
	sgGeometryData_MaterialIdsCasterSettings->SetOutputImageFileFormat( Simplygon::EImageOutputFormat::PNG );
	sgGeometryData_MaterialIdsCasterSettings->SetOutputPixelFormat( Simplygon::EPixelFormat::R8 );
	sgGeometryData_MaterialIdsCasterSettings->SetFillMode( Simplygon::EAtlasFillMode::NoFill );
	sgGeometryData_MaterialIdsCasterSettings->SetGeometryDataFieldType( Simplygon::EGeometryDataFieldType::MaterialIds );
	sgGeometryData_MaterialIdsCasterSettings->SetGeometryDataFieldIndex( 0 );

	sgGeometryData_MaterialIdsCaster->RunProcessing();
	std::string geometrydata_materialidsTextureFilePath = sgGeometryData_MaterialIdsCaster->GetOutputFilePath().c_str();
	
	// Update scene with new casted textures. 
	Simplygon::spMaterialTable sgMaterialTable = sg->CreateMaterialTable();
	Simplygon::spTextureTable sgTextureTable = sg->CreateTextureTable();
	Simplygon::spMaterial sgMaterial = sg->CreateMaterial();
	sgMaterial->SetName("OutputMaterial");
	Simplygon::spTexture sgGeometryData_CoordsTexture = sg->CreateTexture();
	sgGeometryData_CoordsTexture->SetName( "GeometryData_Coords" );
	sgGeometryData_CoordsTexture->SetFilePath( geometrydata_coordsTextureFilePath.c_str() );
	sgTextureTable->AddTexture( sgGeometryData_CoordsTexture );

	Simplygon::spShadingTextureNode sgGeometryData_CoordsTextureShadingNode = sg->CreateShadingTextureNode();
	sgGeometryData_CoordsTextureShadingNode->SetTexCoordLevel( 0 );
	sgGeometryData_CoordsTextureShadingNode->SetTextureName( "GeometryData_Coords" );

	sgMaterial->AddMaterialChannel( "GeometryData_Coords" );
	sgMaterial->SetShadingNetwork( "GeometryData_Coords", sgGeometryData_CoordsTextureShadingNode );
	Simplygon::spTexture sgGeometryData_NormalsTexture = sg->CreateTexture();
	sgGeometryData_NormalsTexture->SetName( "GeometryData_Normals" );
	sgGeometryData_NormalsTexture->SetFilePath( geometrydata_normalsTextureFilePath.c_str() );
	sgTextureTable->AddTexture( sgGeometryData_NormalsTexture );

	Simplygon::spShadingTextureNode sgGeometryData_NormalsTextureShadingNode = sg->CreateShadingTextureNode();
	sgGeometryData_NormalsTextureShadingNode->SetTexCoordLevel( 0 );
	sgGeometryData_NormalsTextureShadingNode->SetTextureName( "GeometryData_Normals" );

	sgMaterial->AddMaterialChannel( "GeometryData_Normals" );
	sgMaterial->SetShadingNetwork( "GeometryData_Normals", sgGeometryData_NormalsTextureShadingNode );
	Simplygon::spTexture sgGeometryData_MaterialIdsTexture = sg->CreateTexture();
	sgGeometryData_MaterialIdsTexture->SetName( "GeometryData_MaterialIds" );
	sgGeometryData_MaterialIdsTexture->SetFilePath( geometrydata_materialidsTextureFilePath.c_str() );
	sgTextureTable->AddTexture( sgGeometryData_MaterialIdsTexture );

	Simplygon::spShadingTextureNode sgGeometryData_MaterialIdsTextureShadingNode = sg->CreateShadingTextureNode();
	sgGeometryData_MaterialIdsTextureShadingNode->SetTexCoordLevel( 0 );
	sgGeometryData_MaterialIdsTextureShadingNode->SetTextureName( "GeometryData_MaterialIds" );

	sgMaterial->AddMaterialChannel( "GeometryData_MaterialIds" );
	sgMaterial->SetShadingNetwork( "GeometryData_MaterialIds", sgGeometryData_MaterialIdsTextureShadingNode );

	sgMaterialTable->AddMaterial( sgMaterial );

	sgScene->GetTextureTable()->Clear();
	sgScene->GetMaterialTable()->Clear();
	sgScene->GetTextureTable()->Copy(sgTextureTable);
	sgScene->GetMaterialTable()->Copy(sgMaterialTable);
	
	// Save processed scene. 	
	printf("%s\n", "Save processed scene.");
	SaveScene(sg, sgScene, "Output.fbx");
	
	// Check log for any warnings or errors. 	
	printf("%s\n", "Check log for any warnings or errors.");
	CheckLog(sg);
}

int main()
{
	Simplygon::ISimplygon* sg = NULL;
	Simplygon::EErrorCodes initval = Simplygon::Initialize( &sg );
	if( initval != Simplygon::EErrorCodes::NoError )
	{
		printf( "Failed to initialize Simplygon: ErrorCode(%d)", (int)initval );
		return int(initval);
	}

	RunGeometryDataDasting(sg);

	Simplygon::Deinitialize(sg);

	return 0;
}
csharp
// Copyright (c) Microsoft Corporation. 
// Licensed under the MIT License. 

using System;
using System.IO;
using System.Threading.Tasks;

public class Program
{
    static Simplygon.spScene LoadScene(Simplygon.ISimplygon sg, string path)
    {
        // Create scene importer 
        using Simplygon.spSceneImporter sgSceneImporter = sg.CreateSceneImporter();
        sgSceneImporter.SetImportFilePath(path);
        
        // Run scene importer. 
        var importResult = sgSceneImporter.Run();
        if (Simplygon.Simplygon.Failed(importResult))
        {
            throw new System.Exception("Failed to load scene.");
        }
        Simplygon.spScene sgScene = sgSceneImporter.GetScene();
        return sgScene;
    }

    static void SaveScene(Simplygon.ISimplygon sg, Simplygon.spScene sgScene, string path)
    {
        // Create scene exporter. 
        using Simplygon.spSceneExporter sgSceneExporter = sg.CreateSceneExporter();
        string outputScenePath = string.Join("", new string[] { "output\\", "GeometryDataCasting", "_", path });
        sgSceneExporter.SetExportFilePath(outputScenePath);
        sgSceneExporter.SetScene(sgScene);
        
        // Run scene exporter. 
        var exportResult = sgSceneExporter.Run();
        if (Simplygon.Simplygon.Failed(exportResult))
        {
            throw new System.Exception("Failed to save scene.");
        }
    }

    static void CheckLog(Simplygon.ISimplygon sg)
    {
        // Check if any errors occurred. 
        bool hasErrors = sg.ErrorOccurred();
        if (hasErrors)
        {
            Simplygon.spStringArray errors = sg.CreateStringArray();
            sg.GetErrorMessages(errors);
            var errorCount = errors.GetItemCount();
            if (errorCount > 0)
            {
                Console.WriteLine("CheckLog: Errors:");
                for (uint errorIndex = 0; errorIndex < errorCount; ++errorIndex)
                {
                    string errorString = errors.GetItem((int)errorIndex);
                    Console.WriteLine(errorString);
                }
                sg.ClearErrorMessages();
            }
        }
        else
        {
            Console.WriteLine("CheckLog: No errors.");
        }
        
        // Check if any warnings occurred. 
        bool hasWarnings = sg.WarningOccurred();
        if (hasWarnings)
        {
            Simplygon.spStringArray warnings = sg.CreateStringArray();
            sg.GetWarningMessages(warnings);
            var warningCount = warnings.GetItemCount();
            if (warningCount > 0)
            {
                Console.WriteLine("CheckLog: Warnings:");
                for (uint warningIndex = 0; warningIndex < warningCount; ++warningIndex)
                {
                    string warningString = warnings.GetItem((int)warningIndex);
                    Console.WriteLine(warningString);
                }
                sg.ClearWarningMessages();
            }
        }
        else
        {
            Console.WriteLine("CheckLog: No warnings.");
        }
        
        // Error out if Simplygon has errors. 
        if (hasErrors)
        {
            throw new System.Exception("Processing failed with an error");
        }
    }

    static void RunGeometryDataDasting(Simplygon.ISimplygon sg)
    {
        // Load scene to process. 
        Simplygon.spScene sgScene = LoadScene(sg, "../../../Assets/SimplygonMan/SimplygonMan.obj");
        
        // Create the remeshing processor. 
        using Simplygon.spRemeshingProcessor sgRemeshingProcessor = sg.CreateRemeshingProcessor();
        sgRemeshingProcessor.SetScene( sgScene );
        using Simplygon.spRemeshingSettings sgRemeshingSettings = sgRemeshingProcessor.GetRemeshingSettings();
        using Simplygon.spMappingImageSettings sgMappingImageSettings = sgRemeshingProcessor.GetMappingImageSettings();
        
        // Set on-screen size target for remeshing. 
        sgRemeshingSettings.SetOnScreenSize( 300 );
        
        // Generates a mapping image which is used after the remeshing to cast new materials to the new 
        // remeshed object. 
        sgMappingImageSettings.SetGenerateMappingImage( true );
        sgMappingImageSettings.SetGenerateTexCoords( true );
        sgMappingImageSettings.SetApplyNewMaterialIds( true );
        sgMappingImageSettings.SetGenerateTangents( true );
        sgMappingImageSettings.SetUseFullRetexturing( true );
        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 remeshing process.         
        Console.WriteLine("Start the remeshing process.");
        sgRemeshingProcessor.RunProcessing();
        
        // Setup and run the geometry data caster casting Coords to a texture.         
        Console.WriteLine("Setup and run the geometry data caster casting Coords to a texture.");
        string geometrydata_coordsTextureFilePath;
        using Simplygon.spGeometryDataCaster sgGeometryData_CoordsCaster = sg.CreateGeometryDataCaster();
        sgGeometryData_CoordsCaster.SetMappingImage( sgRemeshingProcessor.GetMappingImage() );
        sgGeometryData_CoordsCaster.SetSourceMaterials( sgScene.GetMaterialTable() );
        sgGeometryData_CoordsCaster.SetSourceTextures( sgScene.GetTextureTable() );
        sgGeometryData_CoordsCaster.SetOutputFilePath( "GeometryData_CoordsTexture" );

        using Simplygon.spGeometryDataCasterSettings sgGeometryData_CoordsCasterSettings = sgGeometryData_CoordsCaster.GetGeometryDataCasterSettings();
        sgGeometryData_CoordsCasterSettings.SetMaterialChannel( "GeometryData_Coords" );
        sgGeometryData_CoordsCasterSettings.SetOutputImageFileFormat( Simplygon.EImageOutputFormat.PNG );
        sgGeometryData_CoordsCasterSettings.SetOutputPixelFormat( Simplygon.EPixelFormat.R16G16B16 );
        sgGeometryData_CoordsCasterSettings.SetFillMode( Simplygon.EAtlasFillMode.NoFill );
        sgGeometryData_CoordsCasterSettings.SetGeometryDataFieldType( Simplygon.EGeometryDataFieldType.Coords );
        sgGeometryData_CoordsCasterSettings.SetGeometryDataFieldIndex( 0 );

        sgGeometryData_CoordsCaster.RunProcessing();
        geometrydata_coordsTextureFilePath = sgGeometryData_CoordsCaster.GetOutputFilePath();
        
        // Setup and run the geometry data caster casting Normals to a texture.         
        Console.WriteLine("Setup and run the geometry data caster casting Normals to a texture.");
        string geometrydata_normalsTextureFilePath;
        using Simplygon.spGeometryDataCaster sgGeometryData_NormalsCaster = sg.CreateGeometryDataCaster();
        sgGeometryData_NormalsCaster.SetMappingImage( sgRemeshingProcessor.GetMappingImage() );
        sgGeometryData_NormalsCaster.SetSourceMaterials( sgScene.GetMaterialTable() );
        sgGeometryData_NormalsCaster.SetSourceTextures( sgScene.GetTextureTable() );
        sgGeometryData_NormalsCaster.SetOutputFilePath( "GeometryData_NormalsTexture" );

        using Simplygon.spGeometryDataCasterSettings sgGeometryData_NormalsCasterSettings = sgGeometryData_NormalsCaster.GetGeometryDataCasterSettings();
        sgGeometryData_NormalsCasterSettings.SetMaterialChannel( "GeometryData_Normals" );
        sgGeometryData_NormalsCasterSettings.SetOutputImageFileFormat( Simplygon.EImageOutputFormat.PNG );
        sgGeometryData_NormalsCasterSettings.SetOutputPixelFormat( Simplygon.EPixelFormat.R16G16B16 );
        sgGeometryData_NormalsCasterSettings.SetFillMode( Simplygon.EAtlasFillMode.NoFill );
        sgGeometryData_NormalsCasterSettings.SetGeometryDataFieldType( Simplygon.EGeometryDataFieldType.Normals );
        sgGeometryData_NormalsCasterSettings.SetGeometryDataFieldIndex( 0 );

        sgGeometryData_NormalsCaster.RunProcessing();
        geometrydata_normalsTextureFilePath = sgGeometryData_NormalsCaster.GetOutputFilePath();
        
        // Setup and run the geometry data caster casting MaterialIds to a texture.         
        Console.WriteLine("Setup and run the geometry data caster casting MaterialIds to a texture.");
        string geometrydata_materialidsTextureFilePath;
        using Simplygon.spGeometryDataCaster sgGeometryData_MaterialIdsCaster = sg.CreateGeometryDataCaster();
        sgGeometryData_MaterialIdsCaster.SetMappingImage( sgRemeshingProcessor.GetMappingImage() );
        sgGeometryData_MaterialIdsCaster.SetSourceMaterials( sgScene.GetMaterialTable() );
        sgGeometryData_MaterialIdsCaster.SetSourceTextures( sgScene.GetTextureTable() );
        sgGeometryData_MaterialIdsCaster.SetOutputFilePath( "GeometryData_MaterialIdsTexture" );

        using Simplygon.spGeometryDataCasterSettings sgGeometryData_MaterialIdsCasterSettings = sgGeometryData_MaterialIdsCaster.GetGeometryDataCasterSettings();
        sgGeometryData_MaterialIdsCasterSettings.SetMaterialChannel( "GeometryData_MaterialIds" );
        sgGeometryData_MaterialIdsCasterSettings.SetOutputImageFileFormat( Simplygon.EImageOutputFormat.PNG );
        sgGeometryData_MaterialIdsCasterSettings.SetOutputPixelFormat( Simplygon.EPixelFormat.R8 );
        sgGeometryData_MaterialIdsCasterSettings.SetFillMode( Simplygon.EAtlasFillMode.NoFill );
        sgGeometryData_MaterialIdsCasterSettings.SetGeometryDataFieldType( Simplygon.EGeometryDataFieldType.MaterialIds );
        sgGeometryData_MaterialIdsCasterSettings.SetGeometryDataFieldIndex( 0 );

        sgGeometryData_MaterialIdsCaster.RunProcessing();
        geometrydata_materialidsTextureFilePath = sgGeometryData_MaterialIdsCaster.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();
        sgMaterial.SetName("OutputMaterial");
        using Simplygon.spTexture sgGeometryData_CoordsTexture = sg.CreateTexture();
        sgGeometryData_CoordsTexture.SetName( "GeometryData_Coords" );
        sgGeometryData_CoordsTexture.SetFilePath( geometrydata_coordsTextureFilePath );
        sgTextureTable.AddTexture( sgGeometryData_CoordsTexture );

        using Simplygon.spShadingTextureNode sgGeometryData_CoordsTextureShadingNode = sg.CreateShadingTextureNode();
        sgGeometryData_CoordsTextureShadingNode.SetTexCoordLevel( 0 );
        sgGeometryData_CoordsTextureShadingNode.SetTextureName( "GeometryData_Coords" );

        sgMaterial.AddMaterialChannel( "GeometryData_Coords" );
        sgMaterial.SetShadingNetwork( "GeometryData_Coords", sgGeometryData_CoordsTextureShadingNode );
        using Simplygon.spTexture sgGeometryData_NormalsTexture = sg.CreateTexture();
        sgGeometryData_NormalsTexture.SetName( "GeometryData_Normals" );
        sgGeometryData_NormalsTexture.SetFilePath( geometrydata_normalsTextureFilePath );
        sgTextureTable.AddTexture( sgGeometryData_NormalsTexture );

        using Simplygon.spShadingTextureNode sgGeometryData_NormalsTextureShadingNode = sg.CreateShadingTextureNode();
        sgGeometryData_NormalsTextureShadingNode.SetTexCoordLevel( 0 );
        sgGeometryData_NormalsTextureShadingNode.SetTextureName( "GeometryData_Normals" );

        sgMaterial.AddMaterialChannel( "GeometryData_Normals" );
        sgMaterial.SetShadingNetwork( "GeometryData_Normals", sgGeometryData_NormalsTextureShadingNode );
        using Simplygon.spTexture sgGeometryData_MaterialIdsTexture = sg.CreateTexture();
        sgGeometryData_MaterialIdsTexture.SetName( "GeometryData_MaterialIds" );
        sgGeometryData_MaterialIdsTexture.SetFilePath( geometrydata_materialidsTextureFilePath );
        sgTextureTable.AddTexture( sgGeometryData_MaterialIdsTexture );

        using Simplygon.spShadingTextureNode sgGeometryData_MaterialIdsTextureShadingNode = sg.CreateShadingTextureNode();
        sgGeometryData_MaterialIdsTextureShadingNode.SetTexCoordLevel( 0 );
        sgGeometryData_MaterialIdsTextureShadingNode.SetTextureName( "GeometryData_MaterialIds" );

        sgMaterial.AddMaterialChannel( "GeometryData_MaterialIds" );
        sgMaterial.SetShadingNetwork( "GeometryData_MaterialIds", sgGeometryData_MaterialIdsTextureShadingNode );

        sgMaterialTable.AddMaterial( sgMaterial );

        sgScene.GetTextureTable().Clear();
        sgScene.GetMaterialTable().Clear();
        sgScene.GetTextureTable().Copy(sgTextureTable);
        sgScene.GetMaterialTable().Copy(sgMaterialTable);
        
        // Save processed scene.         
        Console.WriteLine("Save processed scene.");
        SaveScene(sg, sgScene, "Output.fbx");
        
        // Check log for any warnings or errors.         
        Console.WriteLine("Check log for any warnings or errors.");
        CheckLog(sg);
    }

    static int Main(string[] args)
    {
        using var sg = Simplygon.Loader.InitSimplygon(out var errorCode, out var errorMessage);
        if (errorCode != Simplygon.EErrorCodes.NoError)
        {
            Console.WriteLine( $"Failed to initialize Simplygon: ErrorCode({(int)errorCode}) {errorMessage}" );
            return (int)errorCode;
        }
        RunGeometryDataDasting(sg);

        return 0;
    }

}
python
# 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 simplygon10 import simplygon_loader
from simplygon10 import Simplygon


def LoadScene(sg: Simplygon.ISimplygon, path: str):
    # Create scene importer 
    sgSceneImporter = sg.CreateSceneImporter()
    sgSceneImporter.SetImportFilePath(path)
    
    # Run scene importer. 
    importResult = sgSceneImporter.Run()
    if Simplygon.Failed(importResult):
        raise Exception('Failed to load scene.')
    sgScene = sgSceneImporter.GetScene()
    return sgScene

def SaveScene(sg: Simplygon.ISimplygon, sgScene: Simplygon.spScene, path: str):
    # Create scene exporter. 
    sgSceneExporter = sg.CreateSceneExporter()
    outputScenePath = ''.join(['output\\', 'GeometryDataCasting', '_', path])
    sgSceneExporter.SetExportFilePath(outputScenePath)
    sgSceneExporter.SetScene(sgScene)
    
    # Run scene exporter. 
    exportResult = sgSceneExporter.Run()
    if Simplygon.Failed(exportResult):
        raise Exception('Failed to save scene.')

def CheckLog(sg: Simplygon.ISimplygon):
    # Check if any errors occurred. 
    hasErrors = sg.ErrorOccurred()
    if hasErrors:
        errors = sg.CreateStringArray()
        sg.GetErrorMessages(errors)
        errorCount = errors.GetItemCount()
        if errorCount > 0:
            print('CheckLog: Errors:')
            for errorIndex in range(errorCount):
                errorString = errors.GetItem(errorIndex)
                print(errorString)
            sg.ClearErrorMessages()
    else:
        print('CheckLog: No errors.')
    
    # Check if any warnings occurred. 
    hasWarnings = sg.WarningOccurred()
    if hasWarnings:
        warnings = sg.CreateStringArray()
        sg.GetWarningMessages(warnings)
        warningCount = warnings.GetItemCount()
        if warningCount > 0:
            print('CheckLog: Warnings:')
            for warningIndex in range(warningCount):
                warningString = warnings.GetItem(warningIndex)
                print(warningString)
            sg.ClearWarningMessages()
    else:
        print('CheckLog: No warnings.')
    
    # Error out if Simplygon has errors. 
    if hasErrors:
        raise Exception('Processing failed with an error')

def RunGeometryDataDasting(sg: Simplygon.ISimplygon):
    # Load scene to process. 
    sgScene = LoadScene(sg, '../../../Assets/SimplygonMan/SimplygonMan.obj')
    
    # Create the remeshing processor. 
    sgRemeshingProcessor = sg.CreateRemeshingProcessor()
    sgRemeshingProcessor.SetScene( sgScene )
    sgRemeshingSettings = sgRemeshingProcessor.GetRemeshingSettings()
    sgMappingImageSettings = sgRemeshingProcessor.GetMappingImageSettings()
    
    # Set on-screen size target for remeshing. 
    sgRemeshingSettings.SetOnScreenSize( 300 )
    
    # Generates a mapping image which is used after the remeshing to cast new materials to the new 
    # remeshed object. 
    sgMappingImageSettings.SetGenerateMappingImage( True )
    sgMappingImageSettings.SetGenerateTexCoords( True )
    sgMappingImageSettings.SetApplyNewMaterialIds( True )
    sgMappingImageSettings.SetGenerateTangents( True )
    sgMappingImageSettings.SetUseFullRetexturing( True )
    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 remeshing process.     
    print("Start the remeshing process.")
    sgRemeshingProcessor.RunProcessing()
    
    # Setup and run the geometry data caster casting Coords to a texture.     
    print("Setup and run the geometry data caster casting Coords to a texture.")
    sgGeometryData_CoordsCaster = sg.CreateGeometryDataCaster()
    sgGeometryData_CoordsCaster.SetMappingImage( sgRemeshingProcessor.GetMappingImage() )
    sgGeometryData_CoordsCaster.SetSourceMaterials( sgScene.GetMaterialTable() )
    sgGeometryData_CoordsCaster.SetSourceTextures( sgScene.GetTextureTable() )
    sgGeometryData_CoordsCaster.SetOutputFilePath( 'GeometryData_CoordsTexture' )

    sgGeometryData_CoordsCasterSettings = sgGeometryData_CoordsCaster.GetGeometryDataCasterSettings()
    sgGeometryData_CoordsCasterSettings.SetMaterialChannel( 'GeometryData_Coords' )
    sgGeometryData_CoordsCasterSettings.SetOutputImageFileFormat( Simplygon.EImageOutputFormat_PNG )
    sgGeometryData_CoordsCasterSettings.SetOutputPixelFormat( Simplygon.EPixelFormat_R16G16B16 )
    sgGeometryData_CoordsCasterSettings.SetFillMode( Simplygon.EAtlasFillMode_NoFill )
    sgGeometryData_CoordsCasterSettings.SetGeometryDataFieldType( Simplygon.EGeometryDataFieldType_Coords )
    sgGeometryData_CoordsCasterSettings.SetGeometryDataFieldIndex( 0 )

    sgGeometryData_CoordsCaster.RunProcessing()
    geometrydata_coordsTextureFilePath = sgGeometryData_CoordsCaster.GetOutputFilePath()
    
    # Setup and run the geometry data caster casting Normals to a texture.     
    print("Setup and run the geometry data caster casting Normals to a texture.")
    sgGeometryData_NormalsCaster = sg.CreateGeometryDataCaster()
    sgGeometryData_NormalsCaster.SetMappingImage( sgRemeshingProcessor.GetMappingImage() )
    sgGeometryData_NormalsCaster.SetSourceMaterials( sgScene.GetMaterialTable() )
    sgGeometryData_NormalsCaster.SetSourceTextures( sgScene.GetTextureTable() )
    sgGeometryData_NormalsCaster.SetOutputFilePath( 'GeometryData_NormalsTexture' )

    sgGeometryData_NormalsCasterSettings = sgGeometryData_NormalsCaster.GetGeometryDataCasterSettings()
    sgGeometryData_NormalsCasterSettings.SetMaterialChannel( 'GeometryData_Normals' )
    sgGeometryData_NormalsCasterSettings.SetOutputImageFileFormat( Simplygon.EImageOutputFormat_PNG )
    sgGeometryData_NormalsCasterSettings.SetOutputPixelFormat( Simplygon.EPixelFormat_R16G16B16 )
    sgGeometryData_NormalsCasterSettings.SetFillMode( Simplygon.EAtlasFillMode_NoFill )
    sgGeometryData_NormalsCasterSettings.SetGeometryDataFieldType( Simplygon.EGeometryDataFieldType_Normals )
    sgGeometryData_NormalsCasterSettings.SetGeometryDataFieldIndex( 0 )

    sgGeometryData_NormalsCaster.RunProcessing()
    geometrydata_normalsTextureFilePath = sgGeometryData_NormalsCaster.GetOutputFilePath()
    
    # Setup and run the geometry data caster casting MaterialIds to a texture.     
    print("Setup and run the geometry data caster casting MaterialIds to a texture.")
    sgGeometryData_MaterialIdsCaster = sg.CreateGeometryDataCaster()
    sgGeometryData_MaterialIdsCaster.SetMappingImage( sgRemeshingProcessor.GetMappingImage() )
    sgGeometryData_MaterialIdsCaster.SetSourceMaterials( sgScene.GetMaterialTable() )
    sgGeometryData_MaterialIdsCaster.SetSourceTextures( sgScene.GetTextureTable() )
    sgGeometryData_MaterialIdsCaster.SetOutputFilePath( 'GeometryData_MaterialIdsTexture' )

    sgGeometryData_MaterialIdsCasterSettings = sgGeometryData_MaterialIdsCaster.GetGeometryDataCasterSettings()
    sgGeometryData_MaterialIdsCasterSettings.SetMaterialChannel( 'GeometryData_MaterialIds' )
    sgGeometryData_MaterialIdsCasterSettings.SetOutputImageFileFormat( Simplygon.EImageOutputFormat_PNG )
    sgGeometryData_MaterialIdsCasterSettings.SetOutputPixelFormat( Simplygon.EPixelFormat_R8 )
    sgGeometryData_MaterialIdsCasterSettings.SetFillMode( Simplygon.EAtlasFillMode_NoFill )
    sgGeometryData_MaterialIdsCasterSettings.SetGeometryDataFieldType( Simplygon.EGeometryDataFieldType_MaterialIds )
    sgGeometryData_MaterialIdsCasterSettings.SetGeometryDataFieldIndex( 0 )

    sgGeometryData_MaterialIdsCaster.RunProcessing()
    geometrydata_materialidsTextureFilePath = sgGeometryData_MaterialIdsCaster.GetOutputFilePath()
    
    # Update scene with new casted textures. 
    sgMaterialTable = sg.CreateMaterialTable()
    sgTextureTable = sg.CreateTextureTable()
    sgMaterial = sg.CreateMaterial()
    sgMaterial.SetName("OutputMaterial")
    sgGeometryData_CoordsTexture = sg.CreateTexture()
    sgGeometryData_CoordsTexture.SetName( 'GeometryData_Coords' )
    sgGeometryData_CoordsTexture.SetFilePath( geometrydata_coordsTextureFilePath )
    sgTextureTable.AddTexture( sgGeometryData_CoordsTexture )

    sgGeometryData_CoordsTextureShadingNode = sg.CreateShadingTextureNode()
    sgGeometryData_CoordsTextureShadingNode.SetTexCoordLevel( 0 )
    sgGeometryData_CoordsTextureShadingNode.SetTextureName( 'GeometryData_Coords' )

    sgMaterial.AddMaterialChannel( 'GeometryData_Coords' )
    sgMaterial.SetShadingNetwork( 'GeometryData_Coords', sgGeometryData_CoordsTextureShadingNode )
    sgGeometryData_NormalsTexture = sg.CreateTexture()
    sgGeometryData_NormalsTexture.SetName( 'GeometryData_Normals' )
    sgGeometryData_NormalsTexture.SetFilePath( geometrydata_normalsTextureFilePath )
    sgTextureTable.AddTexture( sgGeometryData_NormalsTexture )

    sgGeometryData_NormalsTextureShadingNode = sg.CreateShadingTextureNode()
    sgGeometryData_NormalsTextureShadingNode.SetTexCoordLevel( 0 )
    sgGeometryData_NormalsTextureShadingNode.SetTextureName( 'GeometryData_Normals' )

    sgMaterial.AddMaterialChannel( 'GeometryData_Normals' )
    sgMaterial.SetShadingNetwork( 'GeometryData_Normals', sgGeometryData_NormalsTextureShadingNode )
    sgGeometryData_MaterialIdsTexture = sg.CreateTexture()
    sgGeometryData_MaterialIdsTexture.SetName( 'GeometryData_MaterialIds' )
    sgGeometryData_MaterialIdsTexture.SetFilePath( geometrydata_materialidsTextureFilePath )
    sgTextureTable.AddTexture( sgGeometryData_MaterialIdsTexture )

    sgGeometryData_MaterialIdsTextureShadingNode = sg.CreateShadingTextureNode()
    sgGeometryData_MaterialIdsTextureShadingNode.SetTexCoordLevel( 0 )
    sgGeometryData_MaterialIdsTextureShadingNode.SetTextureName( 'GeometryData_MaterialIds' )

    sgMaterial.AddMaterialChannel( 'GeometryData_MaterialIds' )
    sgMaterial.SetShadingNetwork( 'GeometryData_MaterialIds', sgGeometryData_MaterialIdsTextureShadingNode )

    sgMaterialTable.AddMaterial( sgMaterial )

    sgScene.GetTextureTable().Clear()
    sgScene.GetMaterialTable().Clear()
    sgScene.GetTextureTable().Copy(sgTextureTable)
    sgScene.GetMaterialTable().Copy(sgMaterialTable)
    
    # Save processed scene.     
    print("Save processed scene.")
    SaveScene(sg, sgScene, 'Output.fbx')
    
    # Check log for any warnings or errors.     
    print("Check log for any warnings or errors.")
    CheckLog(sg)

if __name__ == '__main__':
        sg = simplygon_loader.init_simplygon()
        if sg is None:
            exit(Simplygon.GetLastInitializationError())

        RunGeometryDataDasting(sg)

        sg = None
        gc.collect()