Tutorial_Generation_rebuild.cpp

Tutorial_Generation_rebuild.cpp
/*
* Copyright 2015 Autodesk, Inc. All rights reserved.
* Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
* or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
*/
#include "common/basesystemenv.h"
#include "common/GeneratorEnvInit.h"
//RUN_THIS_FILE
namespace
{
// This tutorial explains how to rebuild selected sectors, and how to use
// the generatorInputOutput class to setup an iterative rebuild across different processes.
// The process starts with a classic producer using two modes.
// The sectorB geometry can be altered with a flag.
class TutorialProducer_Rebuild : public Kaim::GeneratorInputProducer
{
public:
TutorialProducer_Rebuild() : m_alterSectorB(false) {}
virtual KyResult Produce(const Kaim::GeneratorSector& sector, Kaim::ClientInputConsumer& inputConsumer)
{
Kaim::String sectorName(sector.GetName());
Kaim::String sector_A_Name("Sector_A");
Kaim::String sector_B_Name("Sector_B");
// Both name and GUID can be used to identify which sector the InputConsumer is requesting.
if (sectorName == sector_A_Name)
{
// When the current sector has been identified, feed the relevant data (geometry, seedpoints, tagVolumes)
// for this sector by calling the functions provided by the InputConsumer.
// In this case, add a basic triangle with a custom NavData value of "42".
Kaim::Vec3f aTriangle[3] = { Kaim::Vec3f(0.0f, 0.0f, 0.0f), Kaim::Vec3f(25.0f, 25.0f, 0.0f), Kaim::Vec3f(25.0f, 0.0f, 0.0f) };
Kaim::DynamicNavTag aNavTag;
aNavTag.m_blindDataArray.PushBack(42);
inputConsumer.ConsumeTriangle(aTriangle[0], aTriangle[1], aTriangle[2], aNavTag);
}
else if (sector.GetGuid() == Kaim::KyGuid("BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB"))
{
// In this case, add a basic triangle with a custom NavData value of "13".
Kaim::Vec3f bTriangle[3] = { Kaim::Vec3f(25.0f, 0.0f, 0.0f), Kaim::Vec3f(25.0f, 25.0f, 0.0f), Kaim::Vec3f(50.0f, 0.0f, 0.0f) };
if (m_alterSectorB)
{
bTriangle[0].y = -10.0f;
}
Kaim::DynamicNavTag bNavTag;
bNavTag.m_blindDataArray.PushBack(13);
inputConsumer.ConsumeTriangle(bTriangle[0], bTriangle[1], bTriangle[2], bNavTag);
}
return KY_SUCCESS;
}
void AlterSectorB() { m_alterSectorB = !m_alterSectorB; }
bool m_alterSectorB;
};
class Tutorial_Generation_Rebuild : public BaseSystemEnv
{
public:
// This is used to set up the Alloc instance for the generation,
// and the log for the Tutorial.
typedef GeneratorEnvInit InitClass;
public:
bool Generate_And_Rebuild_SameInstance()
{
// Create the producer using the class coded above.
Kaim::Ptr<TutorialProducer_Rebuild> producer = *KY_NEW TutorialProducer_Rebuild;
// Setup a generator using the Producer and no Glue;
// parallel processing will be disabled.
Kaim::Generator generator(producer);
// Set the Directory where the navdata and clientInput files will be saved.
generator.SetOutputDirectory(RootDir().c_str(), RelativeOutputDir().c_str());
// Add sectors A and B.
Kaim::GeneratorInputOutput generatorInputOutput;
Kaim::Ptr<Kaim::GeneratorSector> sectorA = *KY_NEW Kaim::GeneratorSector(Kaim::KyGuid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA"), "Sector_A_sameInstance");
Kaim::Ptr<Kaim::GeneratorSector> sectorB = *KY_NEW Kaim::GeneratorSector(Kaim::KyGuid("BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB"), "Sector_B_sameInstance");
generatorInputOutput.AddSector(sectorA);
generatorInputOutput.AddSector(sectorB);
// This stage is complete, the generator can run using the configuration established above.
if (generator.Generate(generatorInputOutput) == KY_ERROR)
return false;
// Now, slightly modify the geometry of sector B and instruct the generator
// to only generate sector B in the next generation cycle.
// Sector A geometry will be loaded from ClientInput rather than from the producer.
producer->AlterSectorB();
// Use the Ptr returned by AddNewSector to update some of the build flags.
sectorA->m_sectorChange = Kaim::GenFlags::SECTOR_CHANGED; // Optional, same as default
sectorA->m_inputSource = Kaim::GenFlags::INPUTSOURCE_PRODUCER; /*Optional, same as default*/
// Run the generation cycle a second time to update sector B without re-generating sector A.
// Sector A will be loaded from client Input but will not be generated and Sector_A.navdata will not change.
// Sector B will be loaded from the producer; Sector_B.navdata will be regenerated and will include the
// latest version of the sector A and B overlap.
if (Kaim::Result::Fail(generator.Generate(generatorInputOutput)))
{
return false;
}
return true;
}
// To rebuild a specific sector on a different generator or a different process,
// it can be achieved by dropping a generatorConfigBlob and reloading it later as illustrated in
// the example below.
bool Generate_And_Rebuild_SeparateInstances()
{
// Create the producer using the class coded above.
Kaim::Ptr<TutorialProducer_Rebuild> producer = *KY_NEW TutorialProducer_Rebuild;;
// Set up a first generator using the Producer and no Glue;
// parallel processing will be disabled.
Kaim::Generator generator_1(producer);
// Set the Directory where the navdata and clientInput files
// will be saved.
generator_1.SetOutputDirectory(RootDir().c_str(), RelativeOutputDir().c_str());
// Prepare a config to be used by both instances of the Genenerator.
Kaim::GeneratorInputOutput generatorInputOutput_1;
// Set the custom Generation parameters.
generatorInputOutput_1.m_params.m_entityRadius = 0.5f;
generatorInputOutput_1.m_params.m_rasterPrecision = 0.5f;
// ...
// Add sectors A and B to the config.
Kaim::Ptr<Kaim::GeneratorSector> sectorA = *KY_NEW Kaim::GeneratorSector(Kaim::KyGuid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA"), "Sector_A_separatedInstance");
Kaim::Ptr<Kaim::GeneratorSector> sectorB = *KY_NEW Kaim::GeneratorSector(Kaim::KyGuid("BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB"), "Sector_B_separatedInstance");
generatorInputOutput_1.AddSector(sectorA);
generatorInputOutput_1.AddSector(sectorB);
// This stage is complete, the generator can run using the configuration established above for both sectors.
if (Kaim::Result::Fail(generator_1.Generate(generatorInputOutput_1)))
{
return false;
}
// Save the config. Unless you change the associated runOption, this is done
// automatically during the Generation, and a file named [generatorName].genIO
// is saved in the Root directory.
// It can also be saved explicitly as follows:
if (Kaim::Result::Fail(generatorInputOutput_1.Save("MyGenIO.GenIO")))
return false;
// Create a second generator using the same producer.
Kaim::Generator generator_2(producer);
// Set the Directory where the navdata and clientInput files will be saved.
generator_2.SetOutputDirectory(RootDir().c_str(), RelativeOutputDir().c_str());
// Now, slightly modify the geometry of sector B and instruct the generator
// to only generate sector B in the next generation cycle.
// Sector A geometry will be loaded from ClientInput rather than from the producer.
producer->AlterSectorB();
// Load the previous configuration.
Kaim::GeneratorInputOutput generatorInputOutput_2;
if (generatorInputOutput_2.Load("MyGenIO.GenIO") == KY_ERROR)
return false;
Kaim::Ptr<Kaim::GeneratorSector> sectorA_2 = generatorInputOutput_2.GetSectorWithName("Sector_A_separatedInstance");
Kaim::Ptr<Kaim::GeneratorSector> sectorB_2 = generatorInputOutput_2.GetSectorWithName("Sector_B_separatedInstance");
if (sectorA == KY_NULL || sectorB == KY_NULL)
return false;
// Change the build flags for both sectors.
sectorB->m_sectorChange = Kaim::GenFlags::SECTOR_CHANGED; // Optional, same as default
sectorB->m_inputSource = Kaim::GenFlags::INPUTSOURCE_PRODUCER; // Optional, same as default
// Run the generation cycle a second time to update sector B without re-generating sector A.
// Sector A will be loaded from client Input but will not be generated and Sector_A.navdata will not change.
// Sector B will be loaded from the producer; Sector_B.navdata will be regenerated and will include the
// latest version of the sector A and B overlap.
if (generator_2.Generate(generatorInputOutput_2) == KY_ERROR)
return false;
return true;
}
};
#define TEST_ENV_CLASS Tutorial_Generation_Rebuild
TEST_ENV {}
//TUTORIAL { CHECK(env.Generate_And_Rebuild_SameInstance()) }
//TUTORIAL { CHECK(env.Generate_And_Rebuild_SeparateInstances()) }
}