VTK resliceCursorWidget compatibility with QT - qt

I am working on the medical GUI development with QT and VTK. I have made MPR (MultiPlanar reformation) in VTK alone, but it does not display when I show it in QT (basically I add the renderwindow and renderer to QVTKWidget). I also tried QVTKOpenGLNativeWidget as an option, but it does not work as well. I knew it needs vtkGenericOpenGLRenderWindow where for display.
coding environment:
QT5.9 VS2017 VTK8.2.0
alone:
in QT:
here is my code
void BorderWidgetQt::openMPRwindow(QVTKWidget* qvtkwidget) {
QVTKInteractor* iren = qvtkwidget->GetInteractor();
vtkRenderWindow* renWin = qvtkwidget->GetRenderWindow();
vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
reader->SetDirectoryName("C:\\Users\\u\\source\\repos\\myrobotapp\\DICOM");
reader->Update();
vtkSmartPointer<vtkRenderer> ren; //vtksmartpointer
//vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
renWin->SetMultiSamples(0);
ren = vtkSmartPointer<vtkRenderer>::New();
renWin->AddRenderer(ren);
//vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
//renWin->SetInteractor(iren);
vtkSmartPointer<vtkProperty> ipwProp = vtkSmartPointer<vtkProperty>::New();
int imageDims[3];
reader->GetOutput()->GetDimensions(imageDims);
for (int i = 0; i < 3; i++) {
std::cout << "imagesize L X W X H: " << imageDims[i] << std::endl;
}
vtkSmartPointer< vtkResliceCursor > resliceCursor = vtkSmartPointer< vtkResliceCursor >::New();
resliceCursor->SetCenter(reader->GetOutput()->GetCenter());
resliceCursor->SetThickMode(1);// mode 1 or more and thickness can be viewed
//set image that are resliced
resliceCursor->SetImage(reader->GetOutput());
vtkSmartPointer< vtkResliceCursorWidget > resliceCursorWidget;
vtkSmartPointer< vtkResliceCursorLineRepresentation > resliceCursorRep;
//camera viewup
double viewUp[3][3] = { { 1, 0, -1 }, { 0, 0, 1 }, { 0, 1, 0 } };
/************************/
resliceCursorWidget = vtkSmartPointer< vtkResliceCursorWidget >::New();
resliceCursorWidget->SetInteractor(iren);
resliceCursorRep = vtkSmartPointer< vtkResliceCursorLineRepresentation >::New();
resliceCursorWidget->SetRepresentation(resliceCursorRep);
resliceCursorRep->GetResliceCursorActor()->GetCursorAlgorithm()->SetResliceCursor(resliceCursor);
//thickness text is ediable and can turn off
//resliceCursorRep->DisplayTextOff();
resliceCursorRep->GetResliceCursorActor()->GetCursorAlgorithm()->SetReslicePlaneNormal(0);
cout << "number of input port: " << resliceCursorRep->GetResliceCursorActor()->GetCursorAlgorithm() << endl;
const double minVal = reader->GetOutput()->GetScalarRange()[0];
std::cout << "minVal: " << minVal << " maxVal: " << reader->GetOutput()->GetScalarRange()[1] << endl; //0~1059
if (vtkImageReslice *reslice = vtkImageReslice::SafeDownCast(resliceCursorRep->GetReslice()))
{
reslice->SetBackgroundColor(minVal, minVal, minVal, minVal);
}
resliceCursorWidget->SetDefaultRenderer(ren);
resliceCursorWidget->SetEnabled(1);
ren->GetActiveCamera()->SetFocalPoint(0, 0, 0);
double camPos[3] = { 1, 0, 0 };
ren->GetActiveCamera()->SetPosition(camPos);
ren->GetActiveCamera()->ParallelProjectionOn();
ren->GetActiveCamera()->SetViewUp(viewUp[0][0], viewUp[0][1], viewUp[0][2]);
ren->ResetCamera();
double range[2];
reader->GetOutput()->GetScalarRange(range);
std::cout << "range[0]: " << range[0] << " range[1]: " << range[1] << endl; // 0~1059
//cover full range of window
resliceCursorRep->SetWindowLevel(range[1] - range[0], (range[0] + range[1]) / 2.0);
//resliceCursorRep->SetLookupTable(resliceCursorRep->GetLookupTable());
//reslice cursor center
vtkResliceCursor *rc = resliceCursorRep->GetResliceCursorActor()->GetCursorAlgorithm()->GetResliceCursor();
double *center = rc->GetCenter();
std::cout << "cursor center: " << " [x]: "
<< center[0] << " [y]: " << center[1] << " [z]: " << center[2] << endl;
/************************/
//background of window
ren->SetBackground(0.3, 0.1, 0.1);
//whether it is a hole in the center of two cross hair
resliceCursor->SetHole(0);
resliceCursor->SetThickness(2, 2, 2);
cout << "thickness is : " << resliceCursor->GetThickness()[0] << endl;
vtkSmartPointer< vtkInteractorStyleImage > style = vtkSmartPointer< vtkInteractorStyleImage >::New();
iren->SetInteractorStyle(style);
renWin->Render();
//iren->Initialize();
//iren->Start();
}

it was solved when I just claim the following in head file and make corresponding change in cpp:
private:
vtkSmartPointer< vtkResliceCursorWidget > resliceCursorWidget;
I don't know the depth of the solution. Maybe the QT cannot read the source file if it is not claimed, and also it needs timely render the source.

Related

Rcpp: Calculation in loop stops with error "Not a matrix"

in an R script I source a cpp file to make some calculations. In that R script, a function defined in the cpp file is called and a matrix and an integer is provided. After a few rounds through the loop it gives the error "Not a matrix" (in line of code resid = (x(_,j) - x(_,i))*(x(_,j) - x(_,i));), even though for the rounds before it worked.
R script:
## all together
# rm(list=ls())
library(RcppArmadillo)
library(Rcpp)
sourceCpp("~/test.cpp",verbose = FALSE)
cat("start loop")
for(n in c(45:46)){
cat("\n", n, "\n")
p_m <- matrix(data=rnorm(n^2,1,1),nrow = n, ncol=n)
print(class(p_m))
print(some_function(p_m,nosamples=10))
}
cat("finished")
I start this R script via the command line. R version R-4.1.0. In R-Studio it crashes with a fatal error.
The cpp file:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector some_function(NumericMatrix x,int nosamples) {
int ncol = x.ncol();
NumericVector out2(nosamples);
int loops;
int loops2;
double result=0;
NumericVector::iterator it;
double acc = 0;
NumericVector resid(ncol);
NumericVector out(ncol*(ncol-1)/2);
loops2=0;
std::cout << nosamples << std::endl;
std::cout << (ncol-1) << std::endl;
std::cout << ncol*(ncol-1)/2 << std::endl;
while(loops2 < (nosamples)){
std::cout << "loops2:" << std::endl;
std::cout << loops2 << std::endl;
loops=0;
int i;
int j;
for(j=0;j<(ncol-1);++j){
std::cout << " j: " << j << std::endl;
for (i = (j+1); i < (ncol); ++i) {
std::cout << " i: " << i << std::endl;
resid = (x(_,j) - x(_,i))*(x(_,j) - x(_,i)); //here it stops
std::cout << " i: " << i << std::endl;
for(int ii=0; ii<ncol;++ii){
acc += resid[i];
}
result=sqrt(acc);
loops += 1;
out[loops] = result;
std::cout << " i: " << i << std::endl;
}
}
std::cout << "loops:" << std::endl;
std::cout << loops << std::endl;
out = out[out > 0];
it = std::min_element(out.begin(), out.end());
out= *it;
std::cout << out << std::endl;
loops2 += 1;
out2[loops2]=out[0];
}
std::cout << "cpp finished" << std::endl;
return(out2);
}
Can someone explain what the problem is about?
Thanks and kind regards
Edit
I adapted some things in the cpp file (shown below) and the error disappeared. First I thought, everything is fine. But when I increase the number of loops, another problem occurs: the function breaks, but no error is shown. It breaks after loop number 543 ("loop2: 543"). At least it does the same in each round of the while loop with the same data.
I adapted the R-script and the ccp file to make this problem (at least on my machine) reproducible.
I know this code seems to be somehow meaningless, but it is part of a bigger program and I wanted to give here a minimum example.
The R script:
## all together
# rm(list=ls())
library(RcppArmadillo)
library(Rcpp)
sourceCpp("~/test.cpp",verbose = FALSE)
cat("start loop")
for(n in c(100:101)){
cat("\n", n, "\n")
p_m <- matrix(data=rnorm(n^2,1,1),nrow = n, ncol=n)
print(class(p_m))
print(some_function(p_m,nosamples=800))
}
cat("finished")
The cpp file:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppEigen)]]
#include <RcppArmadillo.h>
#include <RcppEigen.h>
using namespace Rcpp;
using Eigen::Map;
using Eigen::VectorXd;
typedef Map<VectorXd> MapVecd;
// [[Rcpp::export]]
NumericVector some_function(NumericMatrix x,int nosamples) {
int ncol = x.ncol();
NumericVector out(ncol*(ncol-1)/2);
NumericVector out2(nosamples);
NumericVector out3(ncol*(ncol-1)/2);
NumericVector resid(ncol);
int loops;
int loops2;
double result=0;
double acc = 0;
int show_cout=0;
loops2=0;
std::cout << nosamples << std::endl;
std::cout << (ncol-1) << std::endl;
std::cout << ncol*(ncol-1)/2 << std::endl;
while(loops2 < (nosamples)){
std::cout << "loops2:" << loops2 << std::endl;
loops=0;
int i;
int j;
for(j=0;j<(ncol-1);++j){
// std::cout << " j: " << j << std::endl;
for (i = (j+1); i < (ncol); ++i) {
if(show_cout==1){
std::cout << " i: " << i << std::endl;
}
resid = (x(_,j) - x(_,i))*(x(_,j) - x(_,i));
if(show_cout==1){
std::cout << " i: " << i << std::endl;
}
for(int ii=0; ii<ncol;++ii){
acc += resid[ii];
}
result=sqrt(acc);
loops += 1;
out[loops] = result;
if(show_cout==1){
std::cout << " i: " << i << std::endl;
}
}
}
// std::cout << "loops:" << loops << std::endl;
//
out = out[out > 0];
const MapVecd xy(as<MapVecd>(out));
out3=xy.minCoeff();
out2[loops2]=out3[0];
loops2 += 1;
}
std::cout << "cpp finished" << std::endl;
return(out2);
}
Two things here:
Use out[loops++] = result; instead of loops += 1; out[loops] = result; because you were starting at 1, and probably accessing the last element outside of the range of this vector.
Use
for(int ii=0; ii<ncol;++ii){ double eps = x(ii, j) - x(ii, i); acc += eps * eps; }
instead of relying on this resid vector.

Passing map by reference in C++ and mutating its value

I am passing map by reference in the canSum function where i am mutating its value and adding pairs but at the end when I iterate over the map I find the value of map has not been updated.
canSum function is a recursive function which takes a number (targetSum) and an array and finds if it is possible to form targetSum by any combinations of number in the array (numbers can be repeated).
#include<iostream>
#include<vector>
#include<map>
using namespace std;
bool canSum(int targetSum,vector<int> a,map<int, bool> &m){
if(!(m.find(targetSum) == m.end()))
return m[targetSum];
if (targetSum == 0)
return true;
if(targetSum<0)
return false;
for (int num : a)
{
if (canSum(targetSum - num, a,m)==true)
{
// m[targetSum] = true;
m.insert(pair<int, bool>(targetSum, true));
return m[targetSum];
}
}
m[targetSum] = false;
return m[targetSum];
}
int main(){
int targetSum, t;
vector<int> a;
map<int, bool> m;
m[0] = true;
cout << "enter target" << endl;
cin >> targetSum;
cout << "enter array, press esc to stop entering"<<endl;
while(cin>>t){
a.push_back(t);
}
for (int j = 0; j < a.size(); j++)
{
cout << a[j]<<" ";
}
cout << endl;
for (auto itr = m.begin(); itr != m.end(); ++itr) {
cout << '\t' << itr->first
<< '\t' << itr->second << '\n';
}
if(canSum(targetSum, a,m)){
cout << endl << "true" << endl;
}
else cout << endl << "false" << endl;
return 0;
}
Please help me. Thank you.
The for loop to print the map should be after the function call like.
if(canSum(targetSum, a,m)){
cout << endl << "true" << endl;
}
else cout << endl << "false" << endl;
for (auto itr = m.begin(); itr != m.end(); ++itr) {
cout << '\t' << itr->first
<< '\t' << itr->second << '\n';
}
Instead of
for (auto itr = m.begin(); itr != m.end(); ++itr) {
cout << '\t' << itr->first
<< '\t' << itr->second << '\n';
}
if(canSum(targetSum, a,m)){
cout << endl << "true" << endl;
}
else cout << endl << "false" << endl;
To see mutations in the map due to the function

Sending Floats from server to client through socket (UDP)

So I am trying to send floats back and forth between clients and a server. I am able to send floats to the server and the server reads them perfectly. But unfortunately I can't seem to get the server sending the floats back to the other clients. Our current code that doesn't work looks like this.
Send function on server side
int Server::Send(float dt) {
{
char message[BUFLEN];
std::string msg = std::to_string(x2) + "#" + std::to_string(z2);
strcpy(message, (char*)msg.c_str());
if (sendto(server_socket, message, sizeof(message), 0, ptr->ai_addr, ptr->ai_addrlen) == SOCKET_ERROR)
{
std::cout << "Sendto() failed..." << std::endl;
}
else
{
std::cout << "Sent: " << message << "\n" << std::endl;
}
Receiving on Client side
int Client::Recieve(float dt) {
char buf[BUFLEN];
struct sockaddr_in fromAddr;
int fromlen;
fromlen = sizeof(fromAddr);
memset(buf, 0, BUFLEN);
int bytes_recieved = -1;
int sError = -1;
bytes_recieved = recvfrom(client_socket, buf, BUFLEN, 0, (struct sockaddr*) &fromAddr, &fromlen);
sError = WSAGetLastError();
if (sError != WSAEWOULDBLOCK && bytes_recieved > 0)
{
std::cout << "Recieved: " << buf << std::endl;
std::string tmp = buf;
std::size_t pos = tmp.find("#");
tmp = tmp.substr(0, pos - 1);
x2 = std::stof(tmp, NULL);
tmp = buf;
tmp = tmp.substr(pos + 1);
z2 = std::stof(tmp, NULL);
std::cout << "tx: " << x2 << " ty: " << z2 << std::endl;
}
else
std::cout << "Not Receiving" << std::endl;
Any help would be awesome!

I have created a dice betting game. I cannot get the loop to run correctly could someone help me with finding the issue?

Okay so I need help with getting the bank to NOT reset to 100 after each time the loop runs. I have tried many ways but can't seem to get it to work. Could you please help me with a few explanations and examples?
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <ctime>
using namespace std;
int displaystats(int gamesplayed, int wins, int losses, int bank);
int main()
{
int bank = 100;//intital bank value
int bet = 0;//desired wager
int wins = 0;//games won
int losses = 0;//games lost
int gamesplayed = 0;//how many rounds you played
int compdice1 = 0;//first rolled dice for computer
int compdice2 = 0;//second rolled dice for computer
int playdice1 = 0;//first rolled dice for player
int playdice2 = 0;//seconds rolled dice for player
int newdice = 0;//the dice to risk your wager
int comproll = 0;//the sum of the computers roll
int playroll = 0;//the sum of the players roll
do
{
if (bank < 0)
{
cout << "You have " << bank << " coins in your bank." << endl;
cout << "I am sorry you are out of money." << endl;
displaystats(gamesplayed, wins, losses, bank);
break;
}
else if (bank > 0)
{
cout << "You have " << bank << " coins in your bank." << endl;
cout << "How many coins would you like to bet? ";
cin >> bet;
compdice1 = (rand() + time(0)) % 6 + 1;//computer dice
compdice2 = (rand() + time(0)) % 6 + 1;//computer second dice
playdice1 = (rand() + time(0)) % 6 + 1;//player dice
playdice2 = (rand() + time(0)) % 6 + 1;//player second dice
comproll = compdice1 + compdice2;//computer sum
playroll = playdice1 + playdice2;//player sume
cout << "Your roll was " << playdice1 << " and " << playdice2 << " with a sume of " << playroll << endl;
if (playroll < comproll)
{
char option;//option to roll another dice
cout << "You win!" << endl;
cout << "Would you like to roll a third dice to earn 1.5 times your bet, yes or no? ";
cin >> option;
if (option == 'yes')
{
int newroll;//the new sum of the three dice
int newdice;//the extra roll
newdice = (rand() + time(0)) % 6 + 1;
newroll = playroll + newdice;//the value of players roll
if (newroll > comproll)
{
cout << "The computer rolled " << comproll << endl;
cout << "You now rolled higher than the computer therefore, I am sorry you lose this round." << endl;
cout << "Your bank now equals " << bank - bet << endl;
losses++;
gamesplayed++;
}
else if (newroll < comproll)
{
cout << "You win!" << endl;
cout << "Your bank now equals " << bank + (1.5 * bet) << endl;
wins++;
gamesplayed++;
}
}
else if (option == 'no')
{
cout << "Your bank now equals " << bank + bet << endl;
wins++;
gamesplayed++;
}
}
else if (playroll > comproll)
{
cout << "The computer rolled " << comproll << endl;
cout << "You rolled higher than the computer therefore, I am sorry you lose this round." << endl;
cout << "Your bank now equals " << bank - bet << endl;
losses++;
gamesplayed++;
}
else if (playroll = comproll)
{
cout << "The computer also rolled " << comproll << endl;
cout << "I am sorry you now lose double your bet!" << endl;
cout << "Your bank now equals " << bank - (2 * bet) << endl;
losses++;
gamesplayed++;
}
}
} while (bank > 0);
int stats = displaystats(gamesplayed, wins, losses, bank);
cout << "Your stats are " << stats << endl;
return 0;
}
int displaystats(int gamesplayed, int wins, int losses, int bank)
{
cout << "Games Played: " << gamesplayed << endl;
cout << "Wins: " << wins << endl;
cout << "Losses: " << losses << endl;
cout << "Bank Total: " << bank << endl;
return (gamesplayed, wins, losses, bank);
}
Your problem with the bank "resetting" constantly was you never actually subtracted the bet from the bank. See the following code, I hope this helps.
cout << "You have " << bank << " coins in your bank." << endl;
cout << "How many coins would you like to bet? ";
cin >> bet;
//This is the line that you forgot.
bank = bank - bet
If you then win, then you may want to later on add some money back into the bank. (But this is up to you.) I hope this helps.
EDIT:
Here is a paste-bin for the full code as requested: http://pastebin.com/HzvRxjXL
Also, if this solves your problem, I would appreciate it if you would mark it as the answer so others don't spend time answering a problem that has been solved.
EDIT 2:
This has a (As far as I can tell) fixed and commentated version of the code. I hope this helps: http://pastebin.com/miQjy4B5

Why is my program looping infinitely?

My program skips past the option for the user to enter the squareSide and keeps looping.
Code is as follows:
do
{
//Displays menu
cout << "Please select a geometric shape." << endl << endl;
cout << "s:" << setw(10) << "Square" << endl;
cout << "c:" << setw(10) << "Circle" << endl;
cout << "d:" << setw(10) << "Diamond" << endl;
cout << "t:" << setw(10) << "Triangle" << endl;
cout << "e:" << setw(10) << "Exit" << endl << endl;
cin >> letter;
cout << "You selected " << letter << endl;
if (letter != EXIT || letter == EXIT1)
{
if (letter == SQUARE || letter == SQUARE1)
{
int squareSide;
int character;
cout <<"\nPlease enter the ASCII character you would like to use to print your square" << endl;
cin >> character;
cout << "\nPlease enter the length of one side of your square"
<< endl;
cin >> squareSide;
for (int x=0; x < squareSide; x++)
{
for (int y = 0; y < squareSide; y++)
{
cout << character;
}
cout << endl;
}
}
}
} while (letter != EXIT && letter != EXIT1);
return 0;
}
All menu selections have to be char.

Resources