Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information:

Commit 795b4856 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Cleaned up CampcomMhdReceiver

parent 4c214bf8
......@@ -29,3 +29,4 @@ FILE(GLOB ThisModHeaders RELATIVE ${ModulesDir}
SET(ThisModDependencies vis)
......@@ -77,10 +77,13 @@ namespace campvis {
void CampcomMhdReceiver::process(DataContainer& data) {
// Get the last received MHD file:
// Use atomic fetch and store because at the same time CAMPCom may receive another file!
campcom::MHDImageData* mid = _incomingMhd.fetch_and_store(0);
if (mid == 0)
// Transform campcom::MHDImageData to campvis::ImageData
int numChannels = 1;
size_t dimensionality = mid->NDims;
tgt::svec3 size(1);
......@@ -119,40 +122,49 @@ namespace campvis {
ImageRepresentationLocal::create(image, wtp);
image->setMappingInformation(ImageMappingInformation(size, imageOffset + p_imageOffset.getValue(), voxelSize * p_voxelSize.getValue()));
data.addData(p_targetImageID.getValue(), image);
void CampcomMhdReceiver::onBtnConnectClicked() {
// CAMPComClient does not support dis-/reconnect. So we have to delete it and recreate it.
if (_ccclient) {
delete _ccclient;
_ccclient = 0;
// create CAMPComClient and subscribe.
_ccclient = new campcom::CAMPComClient("Campvis", campcom::Device_TestDevice, p_address.getValue());
if (_ccclient->isConnected()) {
campcom::DataCallback dc;
dc = boost::bind(&CampcomMhdReceiver::ccReceiveImage, this, _1);
campcom::SuccessCallback sc = std::bind1st(std::mem_fun(&CampcomMhdReceiver::ccSuccessCalback), this);
// use ugly boost magic to connect to member function (unfortunately CAMPCom only supports free functions...)
campcom::DataCallback dc = boost::bind(&CampcomMhdReceiver::ccReceiveImage, this, _1);
campcom::SuccessCallback sc = std::bind1st(std::mem_fun(&CampcomMhdReceiver::ccSuccessCallback), this);
_ccclient->subscribe(campcom::Type_Image, dc, sc);
else {
LWARNING("Could not connect to CAMPCom server.");
// delete _ccclient;
delete _ccclient;
_ccclient = 0;
void CampcomMhdReceiver::ccReceiveImage(std::vector<campcom::Byte>& msg) {
// Deserialize payload
campcom::MHDImageData return_payload;
campcom::Header header;
campcom::TypeHandler<campcom::MHDImageData>::deserializePayload(&msg[0], msg.size(), return_payload);
if (campcom::MHDImageData::isValid(return_payload)) {
LINFO("New valid MHDImageData received! Pushing it to the DataContainer...");
// putting the image into the DataContainer has to be done asynchroneously, because we
// don't know the DataContainer here... :/
// So copy the image one more time, but it into _incomingMhd and invalidate the processor.
// Use atomic fetch and store because at the same time we may convert the last received image!
campcom::MHDImageData* copy = new campcom::MHDImageData(return_payload);
// delete old image not yet converted (if present)
campcom::MHDImageData* toDelete = _incomingMhd.fetch_and_store(copy);
delete toDelete;
......@@ -164,7 +176,7 @@ namespace campvis {
void CampcomMhdReceiver::ccSuccessCalback(bool b) {
void CampcomMhdReceiver::ccSuccessCallback(bool b) {
LINFO("CAMPCom subscribe callback: " << b);
......@@ -45,9 +45,8 @@
namespace campvis {
* Reads a MHD image file into the pipeline.
* \note Full format specification at
* Experimental demo implementation how to receive MHD files via CAMPCom, convert it to
* CAMPVis ImageData and store it into the DataContainer.
class CampcomMhdReceiver : public AbstractProcessor {
......@@ -67,19 +66,20 @@ namespace campvis {
virtual void deinit();
* Reads the MHD file into an ImageRepresentationDisk representation
* \param data DataContainer to work on
* Transforms the last received MHD image (found in _incomingMhd) into CAMPVis ImageData
* and stores it in \a data.
* \param data DataContainer to work on
virtual void process(DataContainer& data);
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "CampcomMhdReceiver"; };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Reads an MHD image into the pipeline."; };
virtual const std::string getDescription() const { return "Experimental demo implementation how to receive MHD files via CAMPCom."; };
/// \see AbstractProcessor::getAuthor()
virtual const std::string getAuthor() const { return "Christian Schulte zu Berge <>"; };
/// \see AbstractProcessor::getProcessorState()
virtual const ProcessorState getProcessorState() const { return AbstractProcessor::TESTING; };
virtual ProcessorState getProcessorState() const { return AbstractProcessor::EXPERIMENTAL; };
StringProperty p_address; ///< URL for file to read
ButtonProperty p_connect; ///<
......@@ -89,15 +89,23 @@ namespace campvis {
Vec3Property p_voxelSize; ///< Voxel Size in mm
/// Callback slot for connect button
void onBtnConnectClicked();
* Callback for CAMPCom when receiving an image.
* \param msg Received CAMPCom message
void ccReceiveImage(std::vector<campcom::Byte>& msg);
void ccSuccessCalback(bool b);
* Callback for CAMPCom when connection/subscribtion was successful.
* \param b Flag whether subscription was successful.
void ccSuccessCallback(bool b);
campcom::CAMPComClient* _ccclient;
tbb::atomic<campcom::MHDImageData*> _incomingMhd;
campcom::CAMPComClient* _ccclient; ///< Pointer to CAMPComClient (!=0 when connected)
tbb::atomic<campcom::MHDImageData*> _incomingMhd; ///< Pointer to last received MHD file
static const std::string loggerCat_;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment