ImFusion SDK 4.3
StreamAlgorithmFactory.cpp
#include <ImFusion/Base/Algorithm.h>
#include <ImFusion/Base/AlgorithmControllerFactory.h>
#include <ImFusion/Base/AlgorithmFactory.h>
#include <ImFusion/Stream/ImageStream.h>
#include <ImFusion/Stream/CreateStreamAlgorithm.h>
#include <ImFusion/Stream/CreateStreamIoAlgorithm.h>
#include <ImFusion/Stream/FakeImageStream.h>
#include <ImFusion/Stream/Stream.h>
#include <ImFusion/Stream/StreamControllerBase.h>
#include <ImFusion/Stream/StreamData.h>
#include <iostream>
#include <memory>
#include <vector>
using namespace ImFusion;
namespace CreateStreamAlgorithmFactoryUsage
{
class MyAlgorithmFactory : public ImFusion::AlgorithmFactory
{
public:
MyAlgorithmFactory();
};
class MyControllerFactory : public ImFusion::AlgorithmControllerFactory
{
public:
MyControllerFactory();
AlgorithmController* create(Algorithm* a) const override;
};
// clang-format off
// A custom processing stream that processes images from an input ImageStream
class DemoProcessingStream : public ImFusion::ImageStream, public ImFusion::SignalReceiver
{
public:
static bool isCompatible(const DataList& inputData)
{
// Check if the input data contains an ImageStream
return inputData.getFirst<ImageStream>() != nullptr;
}
explicit DemoProcessingStream(const DataList& inputData) : ImageStream("processed images")
{
m_inputStream = inputData.getFirst<ImageStream>();
if (!m_inputStream) throw std::runtime_error("DemoProcessingStream requires an ImageStream as input data");
m_inputStream->signalStreamData.connect(this, &DemoProcessingStream::processImage);
}
~DemoProcessingStream() override
{
disconnectAll(); // Ensure our signal connections are cleaned up
}
void processImage(std::shared_ptr<const StreamData> inputData)
{
const auto imageData = std::dynamic_pointer_cast<const ImageStreamData>(inputData);
// Here you would process the input image data and emit the processed image.
// For demonstration, we just print a message and emit the same images.
std::cout << "Processing image from input stream: " << m_inputStream->name() << std::endl;
// Emit a new ImageStreamData with processed data
auto outputData = std::make_shared<ImageStreamData>(this);
outputData->setImages(imageData->images2()); // Just passing through the input image(s) for now
signalStreamData.emitSignal(outputData);
}
std::optional<WorkContinuation> doWork() override { return {}; };
bool openImpl() override { return true; };
bool closeImpl() override { return true; };
bool startImpl() override { return true; };
bool stopImpl() override { return true; }
std::string uuid() override { return "DemoProcessingStream"; }
private:
const ImageStream* m_inputStream;
};
// Register the DemoProcessingStream in the AlgorithmFactory and ControllerFactory
// Create a type alias, to not have to repeat the template arguments
MyAlgorithmFactory::MyAlgorithmFactory() : AlgorithmFactory("MyPlugin", false)
{
// register the DemoProcessingAlgorithm, which creates a DemoProcessingStream with the Algorithm inputs
registerAlgorithm<DemoProcessingAlgorithm>("DemoProcessingAlgorithm", "Demo;Demo Processing Stream");
}
MyControllerFactory::MyControllerFactory() : AlgorithmControllerFactory("MyPlugin", false) { }
AlgorithmController* MyControllerFactory::create(Algorithm* a) const
{
// use the StreamControllerBase for the DemoProcessingAlgorithm
if (auto alg = dynamic_cast<DemoProcessingAlgorithm*>(a))
return new StreamControllerBase(alg);
return nullptr;
}
// clang-format on
}
namespace CreateStreamIoAlgorithmFactoryUsage
{
class DemoInputStream : public ImFusion::FakeImageStream
{
};
class MyAlgorithmFactory : public ImFusion::AlgorithmFactory
{
public:
MyAlgorithmFactory();
};
class MyControllerFactory : public ImFusion::AlgorithmControllerFactory
{
public:
MyControllerFactory();
AlgorithmController* create(Algorithm* a) const override;
};
// clang-format off
// class DemoInputStream : public ImFusion::Stream...
// Create a type alias, to not have to repeat the template arguments
using DemoInputIoAlgorithm = ImFusion::CreateStreamIoAlgorithm<DemoInputStream, true, true>;
MyAlgorithmFactory::MyAlgorithmFactory() : AlgorithmFactory("MyPlugin", false)
{
// register the DemoInputIoAlgorithm, which creates a DemoInputStream
registerAlgorithm<DemoInputIoAlgorithm>("DemoInputIoAlgorithm", "Demo;Demo Input Stream");
}
MyControllerFactory::MyControllerFactory() : AlgorithmControllerFactory("MyPlugin", false) { }
AlgorithmController* MyControllerFactory::create(Algorithm* a) const
{
// use the StreamControllerBase for the DemoInputIoAlgorithm
if (auto alg = dynamic_cast<DemoInputIoAlgorithm*>(a))
return new StreamControllerBase(alg);
return nullptr;
}
// clang-format on
}
Interface for algorithm controller factories.
Definition AlgorithmControllerFactory.h:29
Specialization of the Controller interface to be used with Algorithm instances.
Definition AlgorithmController.h:38
Interface for algorithm factories.
Definition AlgorithmFactory.h:51
Interface for describing algorithms that can be made available in the ImFusion Suite through Algorith...
Definition Algorithm.h:41
Algorithm template to create streams.
Definition CreateStreamAlgorithm.h:54
Container for any number of Data instances such as image or meshes.
Definition DataList.h:30
Data * getFirst(Data::Kind kind=Data::UNKNOWN) const
Return the first Data instance of the given kind.
Small tool class to create an image stream.
Definition FakeImageStream.h:20
Specialization of Stream for streams producing 2D or 3D images.
Definition ImageStream.h:21
Base class for classes that can contain slots (i.e.
Definition Signal.h:28
Base AlgorithmController for creating controllers of streaming algorithms, but it can also be used di...
Definition StreamControllerBase.h:29
T endl(T... args)
T make_shared(T... args)
Namespace of the ImFusion SDK.
Definition Assert.h:7
T dynamic_pointer_cast(T... args)
Search Tab / S to search, Esc to close