# Repair settings
Welding consists of merging vertices that are closer than a certain distance from each other. This is often used as a pre-processing step to make sure that the geometry is properly connected. Geometry information imported from file formats that do not use vertex indexing have to be welded or gaps between the triangles would be introduced when simplifying it. T-junction removal is also performed by the reducer processor as a pre-processing step. A T-junction is when a vertex is very close to an edge causing a small gap between the triangles. This is solved by splitting the edge at the projection of the vertex onto the edge and then then merging the two vertices.
T-Junction processing before and after.
# Supported processors
- Reduction processor
# Example
This example shows how to use the Reduction processor with repair settings.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include <string>
#include <stdlib.h>
#include <filesystem>
#include <future>
#include "SimplygonLoader.h"
void RunReduction(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::spRepairSettings sgRepairSettings = sgReductionProcessor->GetRepairSettings();
// Set reduction target to triangle ratio with a ratio of 50%.
sgReductionSettings->SetReductionTargets( Simplygon::EStopCondition::All, true, false, false, false );
sgReductionSettings->SetReductionTargetTriangleRatio( 0.5f );
// The number of repair passes. Higher value is slower but give better quality.
sgRepairSettings->SetProgressivePasses( 3 );
// Enable vertex welding.
sgRepairSettings->SetUseWelding( true );
sgRepairSettings->SetWeldDist( 0.0f );
// Remove T-junktions.
sgRepairSettings->SetUseTJunctionRemover( true );
sgRepairSettings->SetTJuncDist( 0.0f );
// No restriction to the weld process.
sgRepairSettings->SetWeldOnlyBetweenSceneNodes( false );
sgRepairSettings->SetWeldOnlyBorderVertices( false );
sgRepairSettings->SetWeldOnlyWithinMaterial( false );
sgRepairSettings->SetWeldOnlyWithinSceneNode( false );
// Start the reduction process.
sgReductionProcessor->RunProcessing();
Simplygon::spSceneExporter sgSceneExporter = sg->CreateSceneExporter();
sgSceneExporter->SetScene(sgScene);
sgSceneExporter->SetExportFilePath( "ReductionOutput.fbx" );
if(!sgSceneExporter->RunExport())
throw std::exception("Failed to save ReductionOutput.fbx.");
}
int main()
{
Simplygon::ISimplygon* sg = NULL;
Simplygon::EErrorCodes initval = Simplygon::Initialize( &sg );
if( initval != Simplygon::EErrorCodes::NoError )
{
return int(initval);
}
RunReduction(sg);
Simplygon::Deinitialize(sg);
return 0;
}
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using System;
using System.IO;
using System.Threading.Tasks;
public class Program
{
static void RunReduction(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.spRepairSettings sgRepairSettings = sgReductionProcessor.GetRepairSettings())
{
// Set reduction target to triangle ratio with a ratio of 50%.
sgReductionSettings.SetReductionTargets( Simplygon.EStopCondition.All, true, false, false, false );
sgReductionSettings.SetReductionTargetTriangleRatio( 0.5f );
// The number of repair passes. Higher value is slower but give better quality.
sgRepairSettings.SetProgressivePasses( 3 );
// Enable vertex welding.
sgRepairSettings.SetUseWelding( true );
sgRepairSettings.SetWeldDist( 0.0f );
// Remove T-junktions.
sgRepairSettings.SetUseTJunctionRemover( true );
sgRepairSettings.SetTJuncDist( 0.0f );
// No restriction to the weld process.
sgRepairSettings.SetWeldOnlyBetweenSceneNodes( false );
sgRepairSettings.SetWeldOnlyBorderVertices( false );
sgRepairSettings.SetWeldOnlyWithinMaterial( false );
sgRepairSettings.SetWeldOnlyWithinSceneNode( false );
}
// Start the reduction process.
sgReductionProcessor.RunProcessing();
}
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 int Main(string[] args)
{
using (var sg = Simplygon.Loader.InitSimplygon(out var errorCode, out var errorMessage))
{
if (errorCode != Simplygon.EErrorCodes.NoError)
return (int)errorCode;
RunReduction(sg);
}
return 0;
}
}
# 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 RunReduction(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()
sgRepairSettings = sgReductionProcessor.GetRepairSettings()
# Set reduction target to triangle ratio with a ratio of 50%.
sgReductionSettings.SetReductionTargets( Simplygon.EStopCondition_All, True, False, False, False )
sgReductionSettings.SetReductionTargetTriangleRatio( 0.5 )
# The number of repair passes. Higher value is slower but give better quality.
sgRepairSettings.SetProgressivePasses( 3 )
# Enable vertex welding.
sgRepairSettings.SetUseWelding( True )
sgRepairSettings.SetWeldDist( 0.0 )
# Remove T-junktions.
sgRepairSettings.SetUseTJunctionRemover( True )
sgRepairSettings.SetTJuncDist( 0.0 )
# No restriction to the weld process.
sgRepairSettings.SetWeldOnlyBetweenSceneNodes( False )
sgRepairSettings.SetWeldOnlyBorderVertices( False )
sgRepairSettings.SetWeldOnlyWithinMaterial( False )
sgRepairSettings.SetWeldOnlyWithinSceneNode( False )
# Start the reduction process.
sgReductionProcessor.RunProcessing()
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 None:
exit(Simplygon.GetLastInitializationError())
RunReduction(sg)
sg = None
gc.collect()