MaterialPartRemoverExample.cpp

<< Click to Display Table of Contents >>

Navigation:  Simplygon 7.1 examples >

MaterialPartRemoverExample.cpp

///////////////////////////////////////////////////////////////////////////
//
//  System:    Simplygon
//  File:      MaterialPartRemoverExample.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#
//
//  A scene containing multiple objects of different sizes and materials are loaded.
// 
//  A threshold is set per-material. If an object is smaller than the threshold
//  corresponding with its material ID, it will be removed by the PartRemover.
//
//  The threshold is expressed in percent of the entire scene diameter. So if
//  Material 0 has threshold 10% and an object with material ID 0 is smaller than
//  10% of the scene, it will be removed.
//
//  This is useful for removing decal quads of certain sizes from the generated LOD.
// 
///////////////////////////////////////////////////////////////////////////
#include "../Common/Example.h"
void RunExampleMaterialPartRemover(const std::string& readFrom, const std::string& writeTo);
int main( int argc , char* argv[] )
    {
    InitExample();
    // Set global variable. Using Orthonormal method for calculating
    // tangentspace.
    sg->SetGlobalSetting( "DefaultTBNType" , SG_TANGENTSPACEMETHOD_ORTHONORMAL );
    std::string assetPath = GetAssetPath();
    // Run the example code
    RunExampleMaterialPartRemover( assetPath + "PartRemoverAssets/partRemoverScene.obj", "partRemoverScene_out" );
    DeinitExample();
    return 0;
    }
void RunExampleMaterialPartRemover(const std::string& readFrom, const std::string& writeTo)
    {
    std::string output_geometry_filename = GetExecutablePath() + writeTo + ".obj";
    // Load from file
    spWavefrontImporter objReader = sg->CreateWavefrontImporter();
    objReader->SetExtractGroups( false ); //Makes unified geometry data
    objReader->SetImportFilePath( readFrom.c_str() );
    if( !objReader->RunImport() )
        return;
    // Make a copy of all the scene geometries as a a single combined geometry
    // The triangles that belong to each individual geometry (or part-geometry)
    // will have a GroupID to know where it belongs to.
    spScene scene = objReader->GetScene();
    spGeometryData combinedGeomCopy = scene->GetCombinedGeometry(-1);
    spMaterialTable materials = scene->GetMaterialTable();
    // Calculate the extents to get a scene scale value
    combinedGeomCopy->CalculateExtents(false);
    real inf[3], sup[3], diag[3];
    combinedGeomCopy->GetInf(inf);
    combinedGeomCopy->GetSup(sup);
    for(uint i = 0; i < 3; ++i)
        diag[i] = sup[i] - inf[i];
    real diam = sqrtf(diag[0] * diag[0] + diag[1] * diag[1] + diag[2] * diag[2]);
    // Create the part remover tool
    spPartRemover partRem = sg->CreatePartRemover();
    partRem->SetGeometry( combinedGeomCopy );
    // Set settings
    // partRem->SetSizeThreshold( 0.2f*diam ); //This sets the global threshold, which will be ignored if the flag below is true
    partRem->SetUsePerMaterialSizeThresholds( true ); // This will make the part remover use the per-material threshold array
    // Setup the PerMaterialSizeThresholds array
    spRealArray perMaterialSizeThresholds = partRem->GetPerMaterialSizeThresholds();
    unsigned int matCount = materials->GetItemsCount();
    perMaterialSizeThresholds->SetItemCount( matCount );
    // If parts made up of material 1 have a diameter smaller than 10% of the scene's entire diameter,
    // then remove the part. Material 2 parts get removed at 20%.
    // The threshold for Material 0 is zero, meaning we never remove parts using it.
    if( matCount >= 2 )
        {
        perMaterialSizeThresholds->SetItem( 0, 0.0f );
        perMaterialSizeThresholds->SetItem( 1, 0.1f*diam);
        perMaterialSizeThresholds->SetItem( 2, 0.2f*diam);
        }
    // For all remaining materials
    for(uint i = 3; i < matCount; ++i)
        {
        perMaterialSizeThresholds->SetItem( i, 0.f ); //Do not remove parts consisting of these materials
        }
    // Run the processing
    partRem->RunPartRemoval();
    // Input the combined geometry with the parts removed into a new empty scene
    spScene processedScene = sg->CreateScene();
    processedScene->GetRootNode()->CreateChildMesh(combinedGeomCopy);
    processedScene->GetMaterialTable()->Copy(scene->GetMaterialTable());
    // Store to file
    spWavefrontExporter objexp = sg->CreateWavefrontExporter();
    objexp->SetExportFilePath( output_geometry_filename.c_str() );
    objexp->SetScene(processedScene);
    objexp->RunExport();
    }