How to use CGAL::read_ply_points() to read binary ply files? - io

A new user of CGAL here.
I am currently trying out the example "registration_with_OpenGR.cpp"
https://cgal.geometryfactory.com/CGAL/doc/master/Point_set_processing_3/Point_set_processing_3_2registration_with_OpenGR_8cpp-example.html
It seems that the function CGAL::read_ply_points() that is used to read ply files does not work on binary format, but it works when a ASCII ply file is given. Is there any extra flag that I need to set when reading binary ply files?
here is my current code for reading ply files.
#include <CGAL/property_map.h>
#include <fstream>
#include <iostream>
#include <utility>
#include <vector>
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point_3;
typedef K::Vector_3 Vector_3;
typedef std::pair<Point_3, Vector_3> Pwn;
typedef CGAL::First_of_pair_property_map<Pwn> Point_map;
typedef CGAL::Second_of_pair_property_map<Pwn> Normal_map;
namespace params = CGAL::parameters;
int main(int argc, const char** argv) {
const char* fname1 = "data/reference.ply";
const char* fname2 = "data/1.ply";
std::vector<Pwn> pwns1, pwns2;
std::ifstream input(fname1);
if (!input ||
!CGAL::read_ply_points(input, std::back_inserter(pwns1),
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<Pwn>()).
normal_map(Normal_map())))
{
std::cerr << "Error: cannot read file " << fname1 << std::endl;
return EXIT_FAILURE;
}
input.close();
input.open(fname2);
if (!input ||
!CGAL::read_ply_points(input, std::back_inserter(pwns2),
CGAL::parameters::point_map(Point_map()).
normal_map(Normal_map())))
{
std::cerr << "Error: cannot read file " << fname2 << std::endl;
return EXIT_FAILURE;
}
input.close();
std::cerr << "SUCCESS" << std::endl;
return EXIT_SUCCESS;
}

You need to give std::ios_base::binary to your stream constructor:
std::ifstream input(fname1,std::ios_base::binary);

Related

Pthreads and QT

I have a issue, where I need the GUI from QT Designer to give values to a separate program running from terminal where the values from the GUI are "printed" onto the terminal interface (Linux with GCC compiler)
I have researched pthreads, but their application examples are limited to In-Application uses. The code in my main file is as follows:
#include "main_window.h"
#include <QApplication>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
void *thr_func(void *thread_id)
{
int tid = thread_id;
pthread_mutex_lock(&lock_x);
cout << "thread" << tid << end1;
cout << xValue << end1;
cout << yValue << end1;
cout << zValue << end1;
pthread_mutex_unlock(&lock_x);
}
int main(int argc, char *argv[])
{
pthread_create(thread_1, NULL, thr_func, NULL)
while(true)
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
pthread_exit(NULL);
}
**Note that xValue, yValue, and zValue already stream to a textfile from the QT application. I am adapting the application for terminal running and control.

Using CLOCK_MONOTONIC type in the 'condition variable' wait_for() notify() mechanism

I am using code that runs on ARM (not Intel processor). Running c++11 code example (CODE A) from: http://www.cplusplus.com/reference/condition_variable/condition_variable/wait_for/ to test the wait_for() mechanism. This is not working right - looks like the wait_for() does not wait. In Intel works fine. After some research and using pthread library directly and setting MONOTONIC_CLOCK definition, solves the issue (CODE B).
(Running on ARM is not the issue)
My problem is :
How can I force the C++11 API wait_for() to work with MONOTONIC_CLOCK?
Actually I would like to stay with 'CODE A' but with the support or setting of MONOTONIC_CLOCK.
Thanks
CODE A
// condition_variable::wait_for example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::chrono::seconds
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status
std::condition_variable cv;
int value;
void read_value() {
std::cin >> value;
cv.notify_one();
}
int main ()
{
std::cout << "Please, enter an integer (I'll be printing dots): \n";
std::thread th (read_value);
std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
while
(cv.wait_for(lck,std::chrono::seconds(1))==std::cv_status::timeout)
{
std::cout << '.' << std::endl;
}
std::cout << "You entered: " << value << '\n';
th.join();
return 0;
}
CODE B
#include <sys/time.h>
#include <unistd.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::chrono::seconds
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status
const size_t NUMTHREADS = 1;
pthread_mutex_t mutex;
pthread_cond_t cond;
int value;
bool done = false;
void* read_value( void* id )
{
const int myid = (long)id; // force the pointer to be a 64bit integer
std::cin >> value;
done = true;
printf( "[thread %d] done is now %d. Signalling cond.\n", myid, done
);
pthread_cond_signal( &cond );
}
int main ()
{
struct timeval now;
pthread_mutexattr_t Attr;
pthread_mutexattr_init(&Attr);
pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex, &Attr);
pthread_condattr_t CaAttr;
pthread_condattr_init(&CaAttr);
pthread_condattr_setclock(&CaAttr, CLOCK_MONOTONIC);
pthread_cond_init(&cond, &CaAttr);
std::cout << "Please, enter an integer:\n";
pthread_t threads[NUMTHREADS];
int t = 0;
pthread_create( &threads[t], NULL, read_value, (void*)(long)t );
struct timespec ts;
pthread_mutex_lock( &mutex );
int rt = 0;
while( !done )
{
clock_gettime(CLOCK_MONOTONIC, &ts);
ts.tv_sec += 1;
rt = pthread_cond_timedwait( & cond, & mutex, &ts );
std::cout << "..." << std::endl;
}
pthread_mutex_unlock( & mutex );
std::cout << "You entered: " << value << '\n';
return 0;
}
The documentation for std::condition_variable::wait_for says:
A steady clock is used to measure the duration.
std::chrono::steady_clock:
Class std::chrono::steady_clock represents a monotonic clock. The time points of this clock cannot decrease as physical time moves forward.
Unfortunately, this is gcc Bug 41861 (DR887) - (DR 887)(C++0x) does not use monotonic_clock that it uses system_clock instead of steady_clock for condition variables.
One solution is to use wait_until (be sure to read Notes section) function that allows to specify durations relative to a specific clock. E.g.:
cv.wait_until(lck, std::chrono::steady_clock::now() + std::chrono::seconds(1))

Trouble with garbage chars in visual c++ file reading

I am trying to read a text file using the following code:
void function readfile(char *inputfile) {
istream is;
int filesize = 0;
is.open(inputfile);
if (!is.is_open()) {
return;
}
is.seekg(0, ios::end);
filesize = (int)is.tellg();
is.seekg(0, ios::beg);
char *buf = new char[filesize];
is.read(buf, filesize);
is.close();
cout << buf << endl;
delete[] buf;
return;
}
While in g++ (mac / macports) it works correctly (getting all contents into a dynamic allocated char* array), in Visual Studio C++ 2010, I get constant errors of this type: Debug assertion failed: (unsigned)(c+1) <= 256, file isctype.c.
The problem is that it opens the file but can't find a termination delimeter so when it reaches the eof it starts reading somewhere else (garbage characters). Using the cout << buf; I can see that the file is being read correctly in mac but in visual c++ it types more garbage chars. What is the problem here?
Make your buffer one larger and add the terminating nul yourself.
Let C++ standard library do the work for you:
void readfile(const char *inputfile) {
std::ifstream is(inputfile);
std::string buf(std::istreambuf_iterator<char>(is), {});
std::cout << buf << std::endl;
}
See, it's now also
exception safe
handles embedded NUL characters correctly
Note, of course you can use vector instead of string if you prefer (just change that one word)
Full demo: see it live on Coliru
#include <fstream>
#include <iostream>
#include <iterator>
void readfile(const char *inputfile) {
std::ifstream is(inputfile);
std::string buf(std::istreambuf_iterator<char>(is), {});
std::cout << buf << std::endl;
}
int main()
{
readfile("main.cpp");
}
Update For C++11 challenged compilers (and showing how to use a vector):
Also Live on Coliru
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
void readfile(const char *inputfile) {
std::ifstream is(inputfile);
std::istreambuf_iterator<char> f(is), l;
std::vector<char> buf(f, l);
std::cout.write(buf.data(), buf.size());
}
int main()
{
readfile("main.cpp");
}

How to use boost.spirit.qi parse string value to attrubute with attribute has default value

I have a question for boost.spirit.qi string parser. When I want parse string value to std::string attribute, like bellow:
#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
template <typename P, typename T>
void test_phrase_parser_attr(
char const* input, P const& p, T& attr, bool full_match = true)
{
using boost::spirit::qi::phrase_parse;
using boost::spirit::qi::ascii::space;
char const* f(input);
char const* l(f + strlen(f));
if (phrase_parse(f, l, p, space, attr) && (!full_match || (f == l)))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
int main()
{
std::string str("abc");
test_phrase_parser_attr("cba", string("cba"), str);
std::cout << str << std::endl;
return 0;
}
The output:abccba
But I want the program output "cba", How can I do?
Note that your str was initialized with "abc". Parser does not clear the string, just appends its output.
Pass in an empty string and you will get back what you want.

The function avformat_open_input from ffmpeg lib cann't open file

I'm tried open file from my code with ffmpeg lib. And avformat_open_input always receive an error "No such file or directory". I tried different files and directories but results are the same.
I use VS 2010 on Win7 and compiled lib and dll from http://ffmpeg.zeranoe.com/builds/
A bit of my code.
int decode_sound(const char * infile, const char * outfile)
{
AVFormatContext *pFormatCtx = 0;
if((err = avformat_open_input(&pFormatCtx, infile, NULL, 0)) != 0)
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
avcodec_register_all();
cout << decode_sound("D:\\DELTA.MPG", "D:\\wav.wav") << endl;
char errbuf[128];
const char *errbuf_ptr = errbuf;
if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
strerror_s(errbuf, AVUNERROR(err));
cout << err << endl << errbuf_ptr << endl;
system("pause");
return 0;
}
I realize this is a kind of old question, but this
int _tmain(int argc, _TCHAR* argv[])
is your problem. Windows is passing in a wide charachter string and you are casting it to a char string so ffmpeg is only seeing the first byte of it. Changing that to
int main(int argc, char* argv[])
Will fix it

Resources