How to define a C++ function in VTK - c++

I'm new with C++ and VTK. I'm trying to get cells ID into a rectilinearGrid basic example. I'm using this code, but the compiler say that is wrong with the error that I wrote in comment
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkFloatArray.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRectilinearGrid.h>
#include <vtkRectilinearGridGeometryFilter.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <array>
int main()
{
vtkNew<vtkNamedColors> colors;
std::array<int, 16> x = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
std::array<int, 16> y = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
std::array<int, 16> z = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
// Create a rectilinear grid by defining three arrays specifying the
// coordinates in the x-y-z directions.
vtkNew<vtkFloatArray> xCoords;
for (auto&& i : x)
{
xCoords->InsertNextValue(i);
}
vtkNew<vtkFloatArray> yCoords;
for (auto&& i : y)
{
yCoords->InsertNextValue(i);
}
vtkNew<vtkFloatArray> zCoords;
for (auto&& i : z)
{
zCoords->InsertNextValue(i);
}
// The coordinates are assigned to the rectilinear grid. Make sure that
// the number of values in each of the XCoordinates, YCoordinates,
// and ZCoordinates is equal to what is defined in SetDimensions().
//
vtkNew<vtkRectilinearGrid> rgrid;
rgrid->SetDimensions(int(x.size()), int(y.size()), int(z.size()));
rgrid->SetXCoordinates(xCoords);
rgrid->SetYCoordinates(yCoords);
rgrid->SetZCoordinates(zCoords);
vtkCell* GetCell(vtkRectilinearGrid * rgrid, int i, int j, int k) //I SHOULD INSERT IN HERE ";" FOR
{ //CLOSING THE STATEMENT. BUT IN
int dims[3]; //THIS WAY THE FUNCTION PARAMETER
rgrid->GetDimensions(dims); // BEHIND WOULDN'T BE CONNECTED.
if (i < 0 || i > dims[0] - 1 ||
j < 0 || j > dims[1] - 1 ||
k < 0 || k > dims[2] - 1)
{
return NULL; // out of bounds!
}
int pos[3];
pos[0] = i;
pos[1] = j;
pos[2] = k;
vtkIdType id;
id = vtkStructuredData::ComputeCellId(dims, pos);
return rgrid->GetCell(id);
};
// Extract a plane from the grid to see what we've got.
vtkNew<vtkRectilinearGridGeometryFilter> plane;
plane->SetInputData(rgrid);
plane->SetExtent(0, 46, 16, 16, 0, 43);
vtkNew<vtkPolyDataMapper> rgridMapper;
rgridMapper->SetInputConnection(plane->GetOutputPort());
vtkNew<vtkActor> wireActor;
wireActor->SetMapper(rgridMapper);
wireActor->GetProperty()->SetRepresentationToWireframe();
wireActor->GetProperty()->SetColor(colors->GetColor3d("Black").GetData());
// Create the usual rendering stuff.
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
renderer->AddActor(wireActor);
renderer->SetBackground(1, 1, 1);
renderer->ResetCamera();
renderer->GetActiveCamera()->Elevation(30.0);
renderer->GetActiveCamera()->Azimuth(15.0);
renderer->GetActiveCamera()->Zoom(1.0);
renderer->SetBackground(colors->GetColor3d("Beige").GetData());
renWin->SetSize(600, 600);
// interact with data
renWin->Render();
iren->Start();
return EXIT_SUCCESS;
}
How could be fixed?
UPDATE 1: I have inserted an image of the compiling error. Should be inserted ";" for closing the statement before {}
UPDATE 2: the exact error is
Errore (attivo) E0065 expected ';' RGrid C:\vtk\VTK-8.2.0\Examples\DataManipulation\Cxx\RGrid.cxx 73
I'm using Visual Studio. I have tried to drop the last ";" but nothing change
UPDATE 3: I have uploaded all the code

You have defined your GetCell function inside the body of the main function, which is not allowed in C++. Only a declaration would be allowed inside the body, hence the compiler expects a semicolon after the function header.
Move the whole GetCell function block outside the main function. If that leads to problems you cannot solve ask another question about them.

Related

Solving a C2039 error and a C3861 error using std::minmax_element

I'm newer to C++.
I've written the following line in a test function inside a standard VS2019 test project:
auto minAndMaxYards = std::minmax_element(simResults.begin(), simResults.end());
It yields both C2039 and C3861 errors for the minmax_element function even though intellisense recognizes it as a member of std, and I can peek its definition. I can't figure out what I'm missing. I've included the algorithm file as well at the top of the test project.
Is there a project setting that I don't have right?
Full error text:
C2039 'minmax_element': is not a member of 'std'
C3861 'minmax_element': identifier not found
Edit, including code in case it helps
#include <algorithm>
#include "pch.h"
#include "CppUnitTest.h"
#include "Playbook.h"
#include "PlaySim.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
std::string output;
using std::vector;
namespace FootballDynastyV20UnitTest
{
TEST_CLASS(PlaybookIO)
{
public:
TEST_METHOD(setAndGetPlayblookName)
{
Playbook testPlays;
string testName = "testPlays";
testPlays.setName(testName);
string name = testPlays.getName();
Assert::IsTrue(name == testName);
}
TEST_METHOD(addPlayIncrementsPlayNum)
{
Playbook testPlays;
string playName = "Play1";
int numDLine = 4;
int numLB = 3;
vector<int> playerPos = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 19 };
vector<int> playerStance = { 2, 1, 0, 0, 1, 2, 2, 3, 2, 3, 3 };
vector<int> playerBlitzGaps = { 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0 };
testPlays.setName("testPlays");
testPlays.addPlay(playName, numDLine, numLB, playerPos, playerStance, playerBlitzGaps);
Assert::IsTrue(testPlays.getNumPlays() == 1);
}
TEST_METHOD(saveAndLoadPlayblook)
{
Playbook testPlays;
Playbook testPlaysLoad;
string playName = "Play1";
int numDLine = 4;
int numLB = 3;
vector<int> playerPos = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 19 };
vector<int> playerStance = { 2, 1, 0, 0, 1, 2, 2, 3, 2, 3, 3 };
vector<int> playerBlitzGaps = { 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0 };
testPlays.setName("testPlays");
testPlays.addPlay(playName, numDLine, numLB, playerPos, playerStance, playerBlitzGaps);
testPlays.save();
testPlaysLoad.load(testPlays.getName());
Assert::IsTrue(testPlays == testPlaysLoad);
}
};
TEST_CLASS(PlaySimTesting)
{
public:
TEST_METHOD(playSimReturnsYdsGainedBetweenNegative10And40)
{
PlaySim newPlay;
int numSims = 2000;
int lwrBound = -10;
int uprBound = 40;
vector<int> simResults;
for (int i = 0; i < numSims; i++)
{
newPlay.Run();
simResults.push_back(newPlay.GetYds());
}
auto minAndMaxYards = std::minmax_element(simResults.begin(), simResults.end());
int actualMin = *minAndMaxYards.first;
int actualMax = *minAndMaxYards.second;
int yds = newPlay.GetYds();
Assert::IsTrue((actualMin >= lwrBound) && (actualMax <= uprBound));
}
};
}
Move #include "pch.h" to the top of the file. When using precompiled headers, the compiler ignores everything above this line. In your example, that would be #include <algorithm>, that's why std::minmax_element is not found.

How to reset two-dimensional array to its original form after sorting?

I am trying to reset 2D array to its original form after it's been sorted with a bubble sort. I need to reset it back to what it was before sorting. How do I do it? In case you have a question why an array is global. It's a school assignment and that's how our professor wants us to do it.
Here is my program:
#include<iostream>
using namespace std;
const int NUM_COLS=4;
const int NUM_ROWS=5;
int array[NUM_ROWS][NUM_COLS]={{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
it sorts an array with bubbleSort
void bubbleSort(int row, int col){}
it is display array function header
void displayArray(){}
and here is main function
int main(){
cout<<"original array"<<endl;
displayArray();
bubbleSort(NUM_ROWS-1, NUM_COLS);
cout<<"\nbubble sort"<<endl;
displayArray();
reset();
displayArray();
return 0;
}
Now I need to reset an array back to original. I did this but it doesn't work.
void reset(){
int array[NUM_ROWS][NUM_COLS]={{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
}
Your reset is declaring a new array (and doing nothing with it). You can't assign (=) C style arrays, so you will need something that looks different. If you can use std::array instead, you could assign in reset.
#include <array>
const int NUM_COLS=4;
const int NUM_ROWS=5;
std::array<std::array<int, NUM_ROWS>, NUM_COLS> values = {
{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
// Other code probably remains unchanged
void reset() {
values = {
{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
}
At which point you notice that you've got your bounds the wrong way round, and it should either be
const int NUM_COLS=5;
const int NUM_ROWS=4;
or a differently shaped array initialiser.
void reset(){
static int original[NUM_ROWS][NUM_COLS]={{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
for (int i = 0; i < NUM_ROWS; i++)
memcpy(array[i], original[i], NUM_COLS * sizeof(int));
}
Not the prettiest thing, but this should work. Since that's how your professor wants you to do it, go for it ¯\_(ツ)_/¯
As I said in a comment, the easiest way to assign arrays is to wrap them in a structure. Voilà, suddenly C++ develops abilities it didn't even know it had inherited from C and copies arrays!1 Even nested, multi-dimensional arrays!
#include <iostream>
#include <iomanip>
#include <algorithm>
using namespace std;
const int NUM_COLS=4;
const int NUM_ROWS=5;
// Define a struct (i.e., a class with all public members)
// which has just a single member, the array. Note that this is
// only a *type* declaration, no object is created yet.
struct arrT
{
int array [NUM_ROWS][NUM_COLS];
};
// object creation.
arrT workArr;
void reset()
{
// The initialization value is hidden inside the function.
// static variables are initialized only once, for constant
// data at compile time.
static const arrT oriArr
{
{ {5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}
}
};
workArr = oriArr; // simple default assignment of structs
}
// The parameters are redundant.
void stdSort(int /*row*/, int /*col*/)
{
// Sort the 2D array as a one-dimensional sequence
// (which the elements are in memory).
// The algorithm expects iterators to the first and
// one-after-the-last elements in the sequence. Pointers
// to the elements in an array are perfectly good iterators.
std::sort(&workArr.array[0][0], &workArr.array[NUM_ROWS-1][NUM_COLS]);
}
void displayArray()
{
// The top-level elements of a 2D array are the rows...
for(auto &row: workArr.array)
{
// ... and the elements of the rows are ints.
// Note how the
// dimensions are known from the class declaration.
for(auto &el: row)
{
cout << setw(4) << el;
}
cout << "\n";
}
}
int main(){
cout << "Work array before initialization:\n";
displayArray();
reset(); // before, the values of the global array are 0.
cout<<"\nWork array after init:\n";
displayArray();
stdSort(NUM_ROWS, NUM_COLS);
cout<<"\nWork array after std sort"<<endl;
displayArray();
reset();
cout << "\nWork array after reset\n";
displayArray();
return 0;
}
1 Arrays are the only example I know of off the cuff where the memberwise assignment of the generated default assignment operator can assign a type which does not have a standalone assignment operator (which is the exact reason we jump through this hoop). Are there others?

GEOS OverlayOp intersection operation

I am using GEOS 3.6.2 to compute an intersection between two polygons. I was able to construct my polygons, but when I try to compute the intersection it won't work.
Compiling my program in Debug mode, I get the error message:
The inferior stopped because it received a signal from the operating
system.
Signal name : SIGSEG
Signal meaning : Segmentation fault
Any idea where I'm wrong?
Here is my code:
#include <geos/geom/Polygon.h>
#include <geos/geom/LinearRing.h>
#include <geos/geom/CoordinateSequenceFactory.h>
#include <geos/geom/GeometryFactory.h>
#include <geos/geom/Geometry.h>
#include <geos/operation/overlay/OverlayOp.h>
#include <iostream>
#include <array>
////////////////////////////////////////////////////////////////////////////////
geos::geom::Polygon* MakePoly(std::vector<std::vector<int>> const& polyCoords)
{
geos::geom::GeometryFactory* factory = geos::geom::GeometryFactory::create().get();
geos::geom::CoordinateSequence* temp = factory->getCoordinateSequenceFactory()->create((std::size_t) 0, 0);
std::vector<std::vector<int>>::const_iterator it_x = polyCoords.begin();
int size = it_x->size();
for (int i=0; i<size; i++)
{
temp->add(geos::geom::Coordinate(polyCoords[0][i], polyCoords[1][i]));
}
geos::geom::LinearRing *shell=factory->createLinearRing(temp);
//NULL in this case could instead be a collection of one or more holes
//in the interior of the polygon
return factory->createPolygon(shell,NULL);
}
////////////////////////////////////////////////////////////////////////////////
int main()
{
// Create geometry.
std::vector<std::vector<int>> polyCoords1 = {
{1, 1, 2, 2, 1, 1, 4, 5, 4, 1},
{1, 2, 2, 4, 4, 5, 5, 3, 1, 1}
};
geos::geom::Polygon* poly1 = MakePoly(polyCoords1);
std::vector<std::vector<int>> polyCoords2 = {
{4, 4, 6, 6, 4},
{1, 5, 5, 1, 1}
};
geos::geom::Polygon* poly2 = MakePoly(polyCoords2);
// Actually perform the operation.
geos::operation::overlay::OverlayOp intersection(poly1, poly2);
// Extracting the geometry of the intersection (position of the error).
geos::geom::Geometry* intersectionGeo = intersection.getResultGeometry( geos::operation::overlay::OverlayOp::OpCode::opINTERSECTION );
std::cout<<intersectionGeo->getArea()<<std::endl;
}
The problem in your code is getting the GeometryFactory pointer.
geos::geom::GeometryFactory::create() returns a smart pointer (std::unique_ptr) so after this line:
geos::geom::GeometryFactory* factory = geos::geom::GeometryFactory::create().get();
The unique_ptr returned by create is disposed.
Change that line with:
geos::geom::GeometryFactory::Ptr factory = geos::geom::GeometryFactory::create();
And the code works.

Running error of SSE2 code in VS2013

I have the following SIMD code trying to run in vs2013. It can be well compiled but cannot run. Anyone knows why?
#include <cstdio>
#include <xmmintrin.h>
int main()
{
const size_t num = 7;
float a[num] = { 1, 2, 3, 4, 5, 6, 7 };
float b[num] = { 1, -1, -2, 1, -3, -2, 5 };
float c[num];
__m128 A, B, C;
A = _mm_load_ps(&a[0]); // <== crash here.
B = _mm_load_ps(&b[0]);
C = _mm_add_ps(A, B);
_mm_store_ps(&c[0], C);
return 0;
}
The address being loaded from or stored to using these intrinsics needs to be 16 byte aligned (divisible by 16). See
https://msdn.microsoft.com/en-us/library/zzd50xxt(v=vs.90).aspx
You should declare the variables a,b and c like this:
__declspec(align(16)) float a[num] = { 1, 2, 3, 4, 5, 6, 7 };

Not declared in this scope - Arduino

I'm having a problem when I try this code I've made:
int ledStart = 30;
boolean commonHigh = true;
void setup() {
Serial.begin(115200);
SetTimer(0, 0, 10); // 10 seconds
StartTimer();
for (int i =0;i<9;++i) {
pinMode (i, OUTPUT);
}
pinMode(9, INPUT);
}
int counter = 0;
bool go_by_switch = true;
int last_input_value = LOW;
void loop() {
// put your main code here, to run repeatedly:
number++;
delay(1000);
if(number>9)
number=0; // If number is bigger than 9, then number is 0
}
// 0 6
// pins A B C D E F G
int ledpins[] = {12, 10, 7, 4, 2, 13, 8};
int pincnt = 7;
int number = 0;
int sevenseg[10][7] = {
// A, B, C, D, E, F, G
{1, 1, 1, 1, 1, 1, 0}, // A-F shall light. G shall not light.
{0, 1, 1, 0, 0, 0, 0}, // A shall not light. B and C shall light.
/*0*/
/*1*/
/*2*/
/*3*/
/*4*/
/*5*/
/*6*/
/*7*/
/*8*/
{1, 1, 1, 1, 1, 1, 1, 1}
if(go_by_switch) {
int switch_input_value = digitalRead(9);
if(last_input_value == LOW && switch_input_value == HIGH) {
counter = (counter + 1) % 10;
}
last_input_value = switch_input_value;
}
else {
delay(500);
counter = (counter + 1) % 10;
}
writeNumber(counter);
}
for (int p=0; p<pincnt; p++) {
pinMode (ledpins[P], OUTPUT);
//It will count from 0 to smaller than 7. {12, 10, 7, 4, 2, 13, 8}; It will count from 0 to smaller than 7.
// 0 1 2 3 4 5 6
digitalWrite(ledpins[P], LOW);
}
for (int x=0; x<pincnt; x++); { //x is smaller than 7. The point is to bring out one of the patterns that will show on the display
if (sevenseg[number][x]) // sevenseg = 7-segment display
digitalWrite (ledpins[x], HIGH); // If it is 1, then there will be light.
else
digitalWrite (ledpins[x], LOW); // If it is 0, then there will not be light.
// A
//F B
// G
//E C
// D
The error message I get is:
_28.10.2015.ino: In function 'void setup()':
_28.10.2015.ino:7:20: error: 'SetTimer' was not declared in this scope
_28.10.2015.ino:8:14: error: 'StartTimer' was not declared in this scope
_28.10.2015.ino: In function 'void loop()':
_28.10.2015.ino:22:1: error: 'number' was not declared in this scope
_28.10.2015.ino: At global scope:
_28.10.2015.ino:52:1: error: expected '}' before 'if'
_28.10.2015.ino:52:1: error: too many initializers for 'int [7]'
_28.10.2015.ino:52:1: error: expected ',' or ';' before 'if'
Feil ved kompilering.
(Feil ved kompilering=Errors at compile(Norwegian)
The problem is that you are not declaring these functions that you are getting errors, neither the "number" variable.
You need to declare them, like:
int number;
void StartTimer( )
{
// function code;
}
Or include a ".h" that contain these functions, like #Neil Locketz said.
There are quite a few issues with this code.
One of the first things that I notice is that you close out your loop() function with }, then you proceed to write more code that doesn't belong to any function at all.
Also, as #Raul points out, you define an array sevenseg[][], but you do not end the statement with a semicolon.
Your last for() loop is missing its closing brace, }.
Your last for() loop has a semicolon before the opening brace. It shouldn't be there.
You use the variable number in your loop() function, but you define what number is after you use it. You have to define a variable before you use it.
You call SetTimer() and StartTimer() in your setup() function, but those functions are not defined. That's because either 1, you have not included the library where those functions are defined or 2, you did not define those functions yourself. If your issue is 1, then I assume you intended to use #include <SimpleTimer.h>. Note that you also have to install that library. The instructions on how to download it and add it to your Arduino libraries are here. Finally, you have to create a timer object like this: SimpleTimer timer; and then you can call the function like this, timer.SetTimer(your-parameters-here);.
There are probably other things that I have missed, but that should give you a starting point. It looks like you have created a lot of code without testing to see if any of it worked. I would recommend taking this a step at a time... code one logical block and see if it works before you move on to coding your next idea. It may seem like it takes more time but, in the end, it is usually a much faster way to program.
Another suggestion that I would make is to define variables within the function in which you use them. Making all of your variables "global" like you have done is not a good way to write code. For example:
void loop()
{
static int number = 0;
number++;
delay(1000);
if (number > 9)
{
number = 0;
}
}
Note the use of the keyword static. This will ensure that the value stored in number will not go away when the function ends. In other words, the value will still be there the next time the loop() function is called.
Finally, if I had to guess at what you were trying to accomplish, I would think your code should look a little more like this. It appears as though you were trying out different things so I left a number of code snippets in there from your original code that don't actually do anything:
void setup() {
Serial.begin(115200);
for (int i = 0; i < 9; ++i)
{
pinMode (i, OUTPUT);
}
pinMode(9, INPUT);
}
void loop() {
static int counter = 0;
static int last_input_value = LOW;
static bool go_by_switch = true;
if(go_by_switch)
{
int switch_input_value = digitalRead(9);
if(last_input_value == LOW && switch_input_value == HIGH)
{
counter = (counter + 1) % 10;
}
last_input_value = switch_input_value;
}
else
{
delay(500);
counter = (counter + 1) % 10;
}
writeNumber(counter);
}
void writeNumber (int count)
{
#define PIN_COUNT 7
#define NUM_OF_SEGMENTS 7
#define NUM_OF_NUMBERS 10
// 0 6
// pins A B C D E F G
static const int ledpins[PIN_COUNT] = {12, 10, 7, 4, 2, 13, 8};
static const int sevenseg[NUM_OF_NUMBERS][NUM_OF_SEGMENTS] =
{
// A B C D E F G
{1, 1, 1, 1, 1, 1, 0}, //0
{0, 1, 1, 0, 0, 0, 0}, //1
{1, 1, 0, 1, 1, 0, 1}, //2
{1, 1, 1, 1, 0, 0, 1}, //3
{0, 1, 1, 0, 0, 1, 1}, //4
{1, 0, 1, 1, 0, 1, 1}, //5
{1, 0, 1, 1, 1, 1, 1}, //6
{1, 1, 1, 0, 0, 0, 0}, //7
{1, 1, 1, 1, 1, 1, 1}, //8
{1, 1, 1, 1, 0, 1, 1}, //9
};
static int number = 0;
int i;
number++;
delay(1000);
if(number >= NUM_OF_NUMBERS)
{
number = 0;
}
/* Clear all segments of the 7-segment display. */
for (i = 0; i < PIN_COUNT; i++)
{
pinMode (ledpins[i], OUTPUT);
digitalWrite(ledpins[i], LOW);
}
/* Set the 7-segment display with the current number. */
for (i = 0; i < PIN_COUNT; i++)
{
if (sevenseg[number][i]) // sevenseg = 7-segment display
digitalWrite (ledpins[i], HIGH); // If it is 1, then there will be light.
else
digitalWrite (ledpins[i], LOW); // If it is 0, then there will not be light.
}
}