Simultaneous CGAL calculations in multiple threads - c++

I'm trying to run multiple geometric calculations with CGAL simultaneously in multiple threads. All threads are 100% "isolated" from each other. Nevertheless the app crashes with an access violation:
http://s8.postimg.org/52u9qphdx/error.png
I've build a small example app to reproduce the error:
main.cpp
#include <fstream>
#include "windows.h"
#include "cTestClass.h"
int main ( int argc, char *argv[] ){
cTestClass *eval0 = new cTestClass("d://.partion_2.stl", 0);
cTestClass *eval1 = new cTestClass("d://.partion_2.stl", 1);
eval0->start_eval();
eval1->start_eval();
while (!eval0->eval_finished())
{
Sleep(200);
}
while (!eval1->eval_finished())
{
Sleep(200);
}
return EXIT_SUCCESS;
}
cTestClass.h
#ifndef CTEST_CLASS_H
#define CTEST_CLASS_H
#include <atomic>
#include <thread>
class cTestClass
{
private:
std::atomic<bool> flag_eval_finished;
std::thread eval_thread;
std::string stl_file_name;
unsigned int thread_index;
cTestClass(){ }
void evaluate_partition();
public:
cTestClass(std::string argStlFile, unsigned int argThread_index);
void start_eval();
bool eval_finished();
};
#endif
cTestClass.cpp
#include "cTestClass.h"
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/polygon_soup_to_polyhedron_3.h>
#include <CGAL/IO/Polyhedron_builder_from_STL.h>
#include <iostream>
#include <fstream>
//typedef CGAL::Cartesian<double> Kernel;
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron_3;
typedef CGAL::Nef_polyhedron_3<Kernel> Nef_polyhedron_3;
typedef CGAL::Point_3<Kernel> Point_3;
//typedef Polyhedron::Point_iterator Point_iterator;
typedef Polyhedron_3::Vertex_iterator Vertex_iterator;
typedef Polyhedron_3::Facet_iterator Facet_iterator;
typedef Polyhedron_3::Halfedge_around_facet_circulator Halfedge_facet_circulator;
typedef Nef_polyhedron_3::Volume_const_iterator Volume_const_iterator;
typedef Kernel::Iso_cuboid_3 Iso_cuboid;
//constructor
cTestClass::cTestClass(std::string argStlFile, unsigned int argThread_index)
{
thread_index = argThread_index;
stl_file_name = argStlFile;
flag_eval_finished = false;
}
//===========================================================================================
// public member functions
void cTestClass::start_eval()
{
std::cout << "Thread " << thread_index << ": start" << std::endl;
eval_thread = std::thread(&cTestClass::evaluate_partition, this);
}
bool cTestClass::eval_finished()
{
return flag_eval_finished;
}
//===========================================================================================
//private member functions
void cTestClass::evaluate_partition()
{
//read stl file and create cgal polyhedron
Polyhedron_3 poly_Partition;
std::ifstream stl_file(stl_file_name.c_str(), std::ifstream::in);
std::vector<CGAL::cpp11::array<double, 3> > points;
std::vector<CGAL::cpp11::array<int, 3> > triangles;
CGAL::read_STL(stl_file, points, triangles);
stl_file.close();
//create polyhedron
CGAL::polygon_soup_to_polyhedron_3(poly_Partition, points, triangles);
//convert polyhedron to nef_poly representation
std::cout << "Thread " << thread_index << ": " <<"Converting partition polyhedron to Nef representation" << std::endl;
Nef_polyhedron_3 nefpoly_Partition(poly_Partition);
flag_eval_finished = true;
}
Anyone got an idea what causes this crash?
Best regards
Monchi

Related

How to convert 4 dimensional matrix to NHWC format in OpenCV

So I'm in the middle of implementing SIFT and the thing is that I don't know how to deal with channel in OpenCV. Here is what I've done so far.
#ifndef QUANTIZATION_DATABASE_DATA_READ_H
#define QUANTIZATION_DATABASE_DATA_READ_H
// C HEADERS
#include <stdlib.h>
#include <fcntl.h>
// C++ HEADERS
#include <iostream>
#include <string>
// OPENCV HEADERS
#include <opencv2/opencv.hpp>
namespace cv
{
class DataReader
{
public:
explicit DataReader(int _flags) : flags(_flags)
{
}
void read(std::string filename, const char *key, Mat &res)
{
try
{
FileStorage fs(filename, FileStorage::Mode::FORMAT_XML | FileStorage::Mode::READ);
fs[key] >> res;
fs.release();
}
catch (Exception e)
{
std::cerr << e.msg << std::endl;
}
}
private:
int flags;
};
}
The algorithm that I want to implement is as follow.
Read the 4 dimensional matrix(NHWC) from a xml file.
Store it in a matrix
Convert it into NHWC
The thing is that I don't have to do step 3 when I do some stuffs using Tensorflow. It just automatically knows the last dimension is channel. So, what should I do?
It seems like there is no way whatsoever to make 4 dimensional buffer to a batch of images. So I decided to change the format of the xml file and it worked like a charm.
Below is temporarily workaround for this problem.
#ifndef QUANTIZATION_DATABASE_DATA_READ_H
#define QUANTIZATION_DATABASE_DATA_READ_H
// C HEADERS
#include <stdlib.h>
#include <fcntl.h>
// C++ HEADERS
#include <iostream>
#include <string>
// OPENCV HEADERS
#include <opencv2/opencv.hpp>
namespace cv
{
class DataReader
{
public:
explicit DataReader(int _flags) : flags(_flags)
{
}
void read(std::string filename, Mat &res)
{
try
{
float length = 0;
FileStorage fs(filename, FileStorage::Mode::FORMAT_XML | FileStorage::Mode::READ);
fs["size"] >> length;
for (int i = 0; i < (int)length; ++i) {
std::string key("image");
std::string index = std::to_string(i);
Mat image;
key = key + index;
fs[key.c_str()] >> image;
std::cout << image.channels() << std::endl;
res.push_back(image);
}
fs.release();
}
catch (Exception e)
{
std::cerr << e.msg << std::endl;
}
}
private:
int flags;
};
}

Boost deadline_timer is not generating event when i am using expire_at?

class header file
//dividandconquer.h
#ifndef DIVIDANDCONQUER_H
#define DIVIDANDCONQUER_H
#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/date.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
using namespace boost::posix_time;
using namespace boost::gregorian;
class dividandconquer
{
public:
dividandconquer(boost::asio::io_service& io);
int lb =0;
int ub =1000;
int mb =0;
ptime t1;
ptime finaltimer;
void reset(int);
void print();
private:
boost::asio::deadline_timer timer_;
int count_;
};
#endif // DIVIDANDCONQUER_H
inside constructor i am trying to trigger timer at specific time(using expire_at) but its not working. But if i am using expires_from_now it works fine.
File name :dividandconquer.cpp
#include "dividandconquer.h"
dividandconquer::dividandconquer(boost::asio::io_service& io)
: timer_(io),
count_(0)
{
t1=ptime( (boost::gregorian::day_clock::local_day()), hours(15)+minutes(12));
timer_.expires_at(t1);
timer_.async_wait(boost::bind(&dividandconquer::print, this));
}
void dividandconquer::reset(int upordown)// 0 means lowebound 1 means uperbound
{
if (mb>0)
{
if (0==upordown)
{ mb=(lb+ub)/2;
ub=mb;
}
else
{
mb=(ub-lb)/2;
lb=mb;
}
}
}
void dividandconquer::print()
{
if (count_ < 5)
{
std::cout << count_ << "\n";
++count_;
//timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(1));
// timer_.async_wait(boost::bind(&printer::print, this));
}
}
main file
#include <QApplication>
#include "dividandconquer.h"
#include <boost/asio.hpp>
int main(int argc, char *argv[])
{
boost::asio::io_service io;
dividandconquer d1(io);
io.run();
return 0;
}
The main problem is that asio::deadline_timer expects absolute timepoints in UTC but gregorian::day_clock::local_day() returns the local date without any time component; I believe this is a working (and reduced) version of what you're looking for:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/deadline_timer.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/system/error_code.hpp>
using namespace boost::posix_time;
using boost::system::error_code;
struct dividandconquer {
explicit dividandconquer(boost::asio::io_service& io) : timer_(io) {
timer_.expires_at(microsec_clock::universal_time() + milliseconds(500));
timer_.async_wait([this](error_code const&){ print(); });
}
void print() {
if (count_ < 5) {
std::cout
<< microsec_clock::universal_time().time_of_day().ticks()
<< " :: " << count_++ << '\n';
timer_.expires_at(timer_.expires_at() + milliseconds(500));
timer_.async_wait([this](error_code const&){ print(); });
}
}
private:
boost::asio::deadline_timer timer_;
int count_{};
};
int main() {
boost::asio::io_service io;
dividandconquer d1{io};
io.run();
}
Online Demo
(Or see here if you really want to stick with bind over using a lambda.)
Since you're using C++11, it's best to avoid involving Boost.Date_Time in any way and just use the standard library instead:
#include <chrono>
#include <boost/asio/steady_timer.hpp>
using namespace std::chrono;
struct dividandconquer {
explicit dividandconquer(boost::asio::io_service& io) : timer_(io) {
timer_.expires_at(steady_clock::now() + milliseconds(500));
timer_.async_wait([this](error_code const&){ print(); });
}
void print() {
if (count_ < 5) {
std::cout
<< steady_clock::now().time_since_epoch().count()
<< " :: " << count_++ << '\n';
timer_.expires_at(timer_.expires_at() + milliseconds(500));
timer_.async_wait([this](error_code const&){ print(); });
}
}
private:
boost::asio::steady_timer timer_;
int count_{};
};
Online Demo

boost geometry precision loss

#include <iostream>
#include <vector>
#include <boost/geometry.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <boost/foreach.hpp>
int main(int argc, char *argv[])
{
typedef boost::geometry::model::d2::point_xy<double> point;
typedef boost::geometry::model::polygon<point> polygon;
std::stringstream ss;
std::string sstring;
char *poly1 =
"POLYGON((45.4602851 9.1146293,45.4602851 9.1196293,45.4652851 9.1196293,45.4652851 9.1146293,45.4602851 9.1146293))";
char *buffer = NULL;
int poly1StrLen;
double tmp;
polygon poly, newPoly;
point p1;
boost::geometry::read_wkt(poly1, poly);
boost::geometry::correct(poly);
BOOST_FOREACH(point const & p, boost::geometry::exterior_ring(poly))
{
// ss << boost::geometry::wkt(p);
// p1.x(p.y());
// p1.y(p.x());
boost::geometry::append(boost::geometry::exterior_ring(newPoly), p);
}
ss << boost::geometry::wkt(newPoly);
sstring = ss.str();
buffer = (char *)malloc(sstring.length());
buffer = strcpy(buffer, sstring.c_str());
printf("%s\n", buffer);
free(buffer);
}
Result is :
POLYGON((45.4603 9.11463,45.4603 9.11963,45.4653 9.11963,45.4653 9.11463,45.4603 9.11463))
Is loosing too much precision for geo-coordinates, what I have to do to leave the same precision?
Just set the output precision on the stream, e.g.
std::cout << std::setprecision(12) << boost::geometry::wkt(newPoly);
This is a lot simpler. You don't have to do the whole buffer dance either!
Live On Coliru
#include <iostream>
#include <vector>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <boost/foreach.hpp>
int main() {
typedef boost::geometry::model::d2::point_xy<double> point;
typedef boost::geometry::model::polygon<point> polygon;
char const *poly1 = "POLYGON((45.4602851 9.1146293,45.4602851 9.1196293,45.4652851 9.1196293,45.4652851 9.1146293,45.4602851 9.1146293))";
polygon poly, newPoly;
boost::geometry::read_wkt(poly1, poly);
boost::geometry::correct(poly);
BOOST_FOREACH(point const & p, boost::geometry::exterior_ring(poly)) {
boost::geometry::append(boost::geometry::exterior_ring(newPoly), p);
}
std::cout << std::setprecision(12) << boost::geometry::wkt(newPoly);
}
Prints
POLYGON((45.4602851 9.1146293,45.4602851 9.1196293,45.4652851 9.1196293,45.4652851 9.1146293,45.4602851 9.1146293))

C++ error LNK2001: unresolved external symbol [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 years ago.
I have a compiling problem in my project. I have read tons of post with this error on the title but I couldn't fix it.
I am receiving this error:
Error 4 error LNK2019: unresolved external symbol "public: class vtkUnstructuredGrid * __thiscall volumerendering::volume(class itk::SmartPointer<class itk::Image<unsigned short,3> >,class itk::SmartPointer<class itk::Image<int,3> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?volume#volumerendering##QAEPAVvtkUnstructuredGrid##V?$SmartPointer#V?$Image#G$02#itk###itk##V?$SmartPointer#V?$Image#H$02#itk###4#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) referenced in function __catch$_main$0 a.obj
Error 5 fatal error LNK1120: 1 unresolved externals C:\Users\SERAP\Desktop\programlar\vnewb\Debug\DICOM.exe
The code is the following:
a.cpp
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif
#include "volumerendering.h"
#include "itkImage.h"
#include "itkImageSeriesReader.h"
#include "itkImageFileWriter.h"
#include "itkNumericSeriesFileNames.h"
#include "itkPNGImageIO.h"
#include "itkTIFFImageIO.h"
#include <vtkXMLUnstructuredGridWriter.h>
// Software Guide : EndCodeSnippet
#include <list>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include<itkRGBPixel.h>
#include "itkThresholdImageFilter.h"
#include "itkGDCMSeriesFileNames.h"
#include "itkGDCMImageIO.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkImageActor.h"
#include "vtkInteractorStyleImage.h"
#include "vtkRenderer.h"
#include"vtkImageViewer2.h"
#include <vtkSliderWidget.h>
#include <vtkSliderRepresentation2D.h>
#include <vtkSTLWriter.h>
// Software Guide : EndCodeSnippet
int main( int argc, char ** argv )
{
// Verify the number of parameters in the command line
if( argc < 6 )
{
std::cerr << "Usage: " << std::endl;
std::cerr << argv[0] << " firstSliceValue lastSliceValue outputImageFile OrjinalDicomDirectory Alanhesabı(txt)DosyasıAdı" << std::endl;
return EXIT_FAILURE;
}
typedef unsigned short PixelType;
const unsigned int Dimension = 3;
typedef itk::Image< PixelType, Dimension > ImageType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The image type is used as a template parameter to instantiate
// the reader and writer.
//
// \index{itk::ImageSeriesReader!Instantiation}
// \index{itk::ImageFileWriter!Instantiation}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef itk::ImageSeriesReader< ImageType > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
const unsigned int first = atoi( argv[1] );
const unsigned int last = atoi( argv[2] );
typedef itk::NumericSeriesFileNames NameGeneratorType;
NameGeneratorType::Pointer nameGenerator = NameGeneratorType::New();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The filenames generator requires us to provide a pattern of text for the
// filenames, and numbers for the initial value, last value and increment to be
// used for generating the names of the files.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
nameGenerator->SetSeriesFormat( "trabekuler%03d.tiff" );
nameGenerator->SetStartIndex( first );
nameGenerator->SetEndIndex( last );
nameGenerator->SetIncrementIndex( 1 );
reader->SetImageIO( itk::TIFFImageIO::New() );
//reader->SetImageIO( itk::PNGImageIO::New() );
reader->SetFileNames( nameGenerator->GetFileNames() );
reader->Update();
typedef int PixelType1;
const unsigned int Dimension1 = 3;
typedef itk::Image< PixelType1, Dimension1 > ImageType1;
typedef itk::ImageSeriesReader< ImageType1 > ReaderType1;
typedef itk::GDCMImageIO ImageIOType;
typedef itk::GDCMSeriesFileNames NamesGeneratorType;
ImageIOType::Pointer gdcmIO = ImageIOType::New();
NamesGeneratorType::Pointer namesGenerator1 = NamesGeneratorType::New();
namesGenerator1->SetInputDirectory( argv[4] );
const ReaderType1::FileNamesContainer & filenames1 =
namesGenerator1->GetInputFileNames();
unsigned int numberOfFilenames1 = filenames1.size();
std::cout << numberOfFilenames1 << std::endl;
for(unsigned int fni1 = 0; fni1<numberOfFilenames1; fni1++)
{
std::cout << "filename # " << fni1 << " = ";
std::cout << filenames1[fni1] << std::endl;
}
ReaderType1::Pointer reader1 = ReaderType1::New();
reader1->SetImageIO( gdcmIO );
reader1->SetFileNames( filenames1 );
try
{
// Software Guide : BeginCodeSnippet
reader1->Update();
// Software Guide : EndCodeSnippet
}
catch (itk::ExceptionObject &excp)
{
std::cerr << "Exception thrown while writing the image" << std::endl;
std::cerr << excp << std::endl;
return EXIT_FAILURE;
}
ImageType1::Pointer image=reader1->GetOutput();
typedef itk::MetaDataDictionary DictionaryType;
const DictionaryType & dictionary = gdcmIO->GetMetaDataDictionary();
typedef itk::MetaDataObject< std::string > MetaDataStringType;
std::string entryId = "0010|0010";
DictionaryType::ConstIterator end = dictionary.End();
DictionaryType::ConstIterator tagItr = dictionary.Find( entryId );
if( tagItr == end )
{
std::cerr << "Tag " << entryId;
std::cerr << " not found in the DICOM header" << std::endl;
return EXIT_FAILURE;
}
MetaDataStringType::ConstPointer entryvalue =
dynamic_cast<const MetaDataStringType *>( tagItr->second.GetPointer() );
std::string filename2 = argv[5];
if( entryvalue )
{
std::string tagvalue = entryvalue->GetMetaDataObjectValue();
std::cout << "Patient's Name (" << entryId << ") ";
std::cout << " is: " << tagvalue << std::endl;
std::ofstream myfile;
myfile.open(filename2.c_str(),std::ios::app);
myfile<< "Patient's Name: "<<tagvalue<<std::endl;
myfile .close();
}
else
{
std::cerr << "Entry was not of string type" << std::endl;
return EXIT_FAILURE;
}
//hacim ve alan hesabi
ImageType::SizeType si;
si=reader->GetOutput()->GetLargestPossibleRegion().GetSize();
ImageType::IndexType pixelIndex;
ImageType1::SpacingType sp;
sp=image->GetSpacing();
std::ofstream myfile;
myfile.open(filename2.c_str(),std::ios::app);
myfile<< "\n"<<std::endl;
myfile<< "Areas: "<<std::endl;
myfile<< "\n"<<std::endl;
double alann=sp[1]*sp[0];
for(int k=si[2]-1;k>-1;k--)
{
int sayii=0;
for(int i=0;i<si[0];i++)
{
for(int j=0;j<si[1];j++)
{
pixelIndex[0] = i; // x position
pixelIndex[1] =j ; // y position
pixelIndex[2]= k;
if(reader->GetOutput()->GetPixel(pixelIndex)==255)
{
sayii=sayii+1;
}
}
}
myfile<< "filename: "<<filenames1[k]<<" "<<"Area : "<<alann*sayii<<" mm_2"<<std::endl;
}
myfile .close();
// end hacim
volumerendering * vol = new volumerendering;
std::string filename = argv[3];
vtkSmartPointer<vtkXMLUnstructuredGridWriter> writer =
vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
writer->SetFileName(filename.c_str());
writer->SetInput( vol->volume(reader->GetOutput(),image,filename2));
writer->Write();
return EXIT_SUCCESS;
}
volumerendering.cpp
#ifndef _volumerendering_cpp
#define _volumerendering_cpp
#include"volumerendering.h"
#include <vtkSmartPointer.h>
#include <vtkDataSetMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPoints.h>
#include <vtkVoxel.h>
#include <vtkUnstructuredGrid.h>
#include <vtkParticleReader.h>
#include <vtkProperty.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkPointSource.h>
#include <vtkPointData.h>
#include <vtkSTLWriter.h>
#include <vtkVertexGlyphFilter.h>
#include<vtkPolyDataWriter.h>
vtkUnstructuredGrid* volumerendering::volume(itk::Image<unsigned short,3>::Pointer image,itk::Image<int,3>::Pointer image1,std::string outt )
{
vtkUnstructuredGrid *ug = vtkUnstructuredGrid::New();
vtkSmartPointer<vtkPoints> points =vtkSmartPointer<vtkPoints>::New();
typedef itk::Image< unsigned short, 3 > ImageType;
typedef itk::Image< int, 3 > ImageType1;
ImageType::SizeType si;
si=image->GetLargestPossibleRegion().GetSize();
ImageType::IndexType pixelIndex;
ImageType1::SpacingType sp;
sp=image1->GetSpacing();
// hacim vee alan hesapları
double hacim=sp[1]*sp[0]*sp[2];
//hacim ve alan hesabi son
int fr=0;
int hacimsayii=0;
for(int i=0;i<si[0];i++)
{
for(int j=0;j<si[1];j++)
{
for(int k=0;k<si[2];k++)
{
pixelIndex[0] = i; // x position
pixelIndex[1] =j ; // y position
pixelIndex[2]= k;
if(image->GetPixel(pixelIndex)==255)
{hacimsayii=hacimsayii+1;
float a1[]={i*sp[0],j*sp[1],k*sp[2]};
float a2[]={(i+1)*sp[0],j*sp[1],k*sp[2]};
float a3[]={i*sp[0],(j+1)*sp[1],k*sp[2]};
float a4[]={(i+1)*sp[0],(j+1)*sp[1],k*sp[2]};
float a5[]={i*sp[0],j*sp[1],(k+1)*sp[2]};
float a6[]={(i+1)*sp[0],j*sp[1],(k+1)*sp[2]};
float a7[]={i*sp[0],(j+1)*sp[1],(k+1)*sp[2]};
float a8[]={(i+1)*sp[0],(j+1)*sp[1],(k+1)*sp[2]};
points->InsertPoint(fr,a1);
points->InsertPoint(fr+1,a2);
points->InsertPoint(fr+2,a3);
points->InsertPoint(fr+3,a4);
points->InsertPoint(fr+4,a5);
points->InsertPoint(fr+5,a6);
points->InsertPoint(fr+6,a7);
points->InsertPoint(fr+7,a8);
fr=fr+8;
}
}
}
}
std::ofstream myfile;
myfile.open(outt.c_str(),std::ios::app);
myfile<< "\n"<<std::endl;
myfile<< "Volume "<<std::endl;
myfile<< "\n"<<std::endl;
myfile<< "Total Volume= "<<hacim*hacimsayii<<" mm_3"<<std::endl;
myfile .close();
static int ptr[8];
int tt=0;
int cti=points->GetNumberOfPoints();
for (int i=0;i<cti/8 ;i++)
{
for (int iy=0;iy<1;iy++)
{
ptr[0]=iy+tt; ptr[1]=iy+tt+1; ptr[2]=iy+tt+2; ptr[3]=iy+tt+3;
ptr[4]=iy+tt+4; ptr[5]=iy+tt+5; ptr[6]=iy+tt+6; ptr[7]=iy+tt+7;
ug->InsertNextCell(VTK_VOXEL,8,ptr);
tt=tt+8;
}
}
ug->SetPoints(points);
/* vtkSmartPointer<vtkDataSetMapper> mapper =
vtkSmartPointer<vtkDataSetMapper>::New();
mapper->SetInput(ug);
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderWindow->AddRenderer(renderer);
renderer->AddActor(actor);
renderer->ResetCamera();
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindow->Render();
renderWindowInteractor->Start();*/
return ug;
}
#endif
volumerendering.h
#ifndef __volumerendering_h
#define __volumerendering_h
#include"vtkUnstructuredGrid.h"
#include"itkImage.h"
#include "itkImageSeriesReader.h"
class volumerendering
{
public:
vtkUnstructuredGrid* volume(itk::Image<unsigned short,3>::Pointer image,itk::Image<int,3>::Pointer image1,std::string outt );
};
#endif
thanks
volumerendering.cpp has to be compiled with the project.
But I do not see anything that prevent volumerendering::volume from being defined, so it may be a project configuration problem ?
Make sure that volumerendering.cpp is compiled at the same time than a.cpp.

How to use Boost.Interprocess to stream data to other applications?

The main application needs to update the shared memory at a fast frequency.
And several consuming applications need to read from the shared memory to update the streamed data.
main and consuming applications are different processes.
How to implement this with Boost.Interprocess ?
producer:
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/thread.hpp>
#include <iostream>
struct shared_data_t {
boost::uint32_t data;
boost::interprocess::interprocess_mutex mutex;
};
/***************************************************************************/
/* producer */
int main(int argc, char** argv) {
const char* shname = "_unique_object_name_";
boost::shared_ptr<const char> remover(
shname,
boost::interprocess::shared_memory_object::remove
);
try {
boost::interprocess::shared_memory_object shared_object(
boost::interprocess::create_only,
shname,
boost::interprocess::read_write
);
shared_object.truncate(sizeof(shared_data_t));
boost::interprocess::mapped_region region(
shared_object,
boost::interprocess::read_write
);
shared_data_t* data = new(region.get_address())shared_data_t;
assert(data);
const boost::uint32_t count = 0x1000;
for ( boost::uint32_t idx = 0; idx < count; ++idx ) {
{ boost::interprocess::scoped_lock<
boost::interprocess::interprocess_mutex
> lock(data->mutex);
data->data = idx;
}
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
} catch(boost::interprocess::interprocess_exception &e){
std::cout << e.what() << std::endl;
return 1;
}
return 0;
}
consumer:
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/thread.hpp>
struct shared_data_t {
boost::uint32_t data;
boost::interprocess::interprocess_mutex mutex;
};
/***************************************************************************/
/* consumer */
int main(int argc, char** argv) {
try {
boost::interprocess::shared_memory_object shared_object(
boost::interprocess::open_only,
"_unique_object_name_",
boost::interprocess::read_only
);
shared_object.truncate(sizeof(shared_data_t));
boost::interprocess::mapped_region region(
shared_object,
boost::interprocess::read_only
);
shared_data_t* data = new(region.get_address())shared_data_t;
assert(data);
while ( true ) {
{ boost::interprocess::scoped_lock<
boost::interprocess::interprocess_mutex
> lock(data->mutex);
std::cout << "ping: " << data->data << std::endl;
}
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
}
} catch(boost::interprocess::interprocess_exception &e){
std::cout << e.what() << std::endl;
return 1;
}
return 0;
}
man:
http://www.boost.org/doc/libs/1_43_0/doc/html/interprocess/synchronization_mechanisms.html