Moving triangles to a new column with triangle strip - c++

I'm having problems moving triangles to another column. I'm able to successfully add them to right direction (in the picture), but when I want to move them into a new column it takes points from old points (furthest on the right) and I would like to have them connected to the upper triangles as I elevate the mesh, the strip will make the mesh rise.
// triangles without a new column
std::vector<triangle_vertices_t> vertices = {
{ {0, 0, 0}, {1, 0, 0}, {0, 0, 1} },
{ {1, 0, 0}, {0, 0, 1}, {1, 0, 1} },
{ {0, 0, 0 + 1}, {1, 0, 0 + 1}, {0, 0, 1 + 1} },
{ {1, 0, 0 + 1}, {0, 0, 1 + 1}, {1, 0, 1 + 1} }
};
// vertices with a new column
std::vector<triangle_vertices_t> vertices = {
{ {0, 0, 0}, {1, 0, 0}, {0, 0, 1} },
{ {1, 0, 0}, {0, 0, 1}, {1, 0, 1} },
{ {0, 0, 0 + 1}, {1, 0, 0 + 1}, {0, 0, 1 + 1} },
{ {1, 0, 0 + 1}, {0, 0, 1 + 1}, {1, 0, 1 + 1} },
{ {1 - 1, 0, 0}, {1 - 1, 0, 1}, {0 - 1, 0, 1} },
{ {-1, 0, 0}, {1 - 1, 0, 0}, {-1, 0, 1} },
};
//drawing the triangles
glBindVertexArray(m_vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3 * amount_of_triangles);
glBindVertexArray(0);
So my question is, how can I add a column while connecting to the upper triangles?

On possibility is to use Primitive Restart inidces.
Another simple trick is to add the last vertex and the first vertex of a strip twice:
A C E G
+---- +-----+-----+
| / | / | / |
| / | / | / |
B +-----+-----+-----+
| / | D F H
| / |
+-----+
I J
Triangle strip:
A - B - C - D - E - F - G - H - H - B - B - I - D - J
This works because with a triangular primitive with 2 identical points nothing at all is rasterized. Hence the "triangles" G - H - H, H - H - B, H - B - B and B - B - I do not generate any fragments.

Related

WMesh face shading artifacts in OpenCV

I'm using OpenCV v4.4.0 with gcc v10.1 on Ubuntu 18.04.5. This code snippet:
using namespace std;
using namespace cv;
using namespace cv::viz;
......
vector<Vec3f> points{{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}, {2, 0, 0}, {2, 1, 0}};
vector<int> faces{4, 0, 1, 2, 0, 4, 0, 2, 3, 0, 5, 1, 4, 5, 2, 1};
Viz3d window("Mesh");
WMesh mesh(points, faces);
window.setBackgroundColor(Color::gray());
mesh.setColor(Color::indigo());
mesh.setRenderingProperty(OPACITY, 0.4);
mesh.setRenderingProperty(SHADING, SHADING_FLAT);
mesh.setRenderingProperty(REPRESENTATION, REPRESENTATION_SURFACE);
window.showWidget("mesh", mesh);
window.spin();
creates and displays this planar mesh:
The square on the left is defined as 2 triangles and is shaded uniformly, but the square on the right, which is defined as a single quadrilateral face is not shaded uniformly. Again, the mesh is planar. Why the non-uniformity?
It becomes even more non-uniform when I change shading from SHADING_FLAT to SHADING_GOURAUD:
Can someone explain what is going on here? I know that quadrilateral faces are converted to triangles, but why the shading is non-uniform?
EDIT
As noted by Матвей Вислоух in his answer below, I intended to use:
vector<int> faces{3, 0, 1, 2, 3, 0, 2, 3, 4, 1, 4, 5, 2};
which properly defines two triangular and one quadrilateral face. This solves the problem of artifacts in the left half, but they still remain in the right half:
vector<int> faces{3, 0, 1, 2, 3, 0, 2, 3, 4, 1, 4, 2, 5};
There is a specific rule how opencv unpacks indices from polygon.
if there is a polygon : (5, 1, 4, 5, 2, 0) it consists of 3 triangles: (1,4,5) , (4, 5, 2), (5, 2, 0)
OLD:
vector faces{4, 0, 1, 2, 0, 4, 0, 2, 3, 0, 5, 1, 4, 5, 2, 1};
This means you draw 3 polygons: 2 quads and 1 pentagon.
But by indices I guess that you want to draw 2 triangles, and one quad, so try this:
vector faces{3, 0, 1, 2, 3, 0, 2, 3, 4, 1, 4, 5, 2};

Accessing Lua global tables with C++

How can I access a global table that already exists in Lua using C++ ?
Below are code which I tried. I tried creating a global variable and try modifying a that local to the local in Lua but things dont seem to work
lua_State *lua_state = luaL_newstate();
luaL_openlibs(lua_state);
// lua_createtable(lua_state, 0, 81);
// for (int i = 1; i <= 81; i++)
// {
// lua_pushnumber(lua_state, i);
// lua_pushnumber(lua_state, grid_[i - 1]);
// lua_settable(lua_state, -3);
// }
//
// lua_setglobal(lua_state, "arg");
// lua_createtable(lua_state, 81, 1);
//
// for (int i = 1; i <= 81; i++)
// {
// lua_pushnumber(lua_state, i);
// lua_pushnumber(lua_state, grid_[i - 1]);
// lua_settable(lua_state, -3);
// }
// lua_setglobal(lua_state, "arg");
luaL_loadfile(lua_state, "main.lua");
lua_call(lua_state, 0, 0);
int t = 2;
/* table is in the stack at index 't' */
lua_pushnil(lua_state); /* first key */
while (lua_next(lua_state, t) != 0) {
/* uses 'key' (at index -2) and 'value' (at index -1) */
printf("%s - %s\n",
lua_typename(lua_state, lua_type(lua_state, -2)),
lua_typename(lua_state, lua_type(lua_state, -1)));
/* removes 'value'; keeps 'key' for next iteration */
lua_pop(lua_state, 1);
}
Lua
problem =
{
{9, 0, 0, 1, 0, 0, 0, 0, 5},
{0, 0, 5, 0, 9, 0, 2, 0, 1},
{8, 0, 0, 0, 4, 0, 0, 0, 0},
{0, 0, 0, 0, 8, 0, 0, 0, 0},
{0, 0, 0, 7, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 2, 6, 0, 0, 9},
{2, 0, 0, 3, 0, 0, 0, 0, 6},
{0, 0, 0, 2, 0, 0, 9, 0, 0},
{0, 0, 1, 9, 0, 4, 5, 7, 0},
}
Update 1
int main()
{
lua_State *lua_state = luaL_newstate();
luaL_openlibs(lua_state);
luaL_loadfile(lua_state, "main.lua");
lua_getglobal(lua_state, "problem");
//lua_pushglobaltable(lua_state); // Get global table
lua_pushnil(lua_state); // put a nil key on stack
while (lua_next(lua_state, -2) != 0) { // key(-1) is replaced by the next key(-1) in table(-2)
std::string name = lua_tostring(lua_state, -2); // Get key(-2) name
std::cout << name << std::endl;
lua_pop(lua_state, 1); // remove value(-1), now key on top at(-1)
}
lua_pop(lua_state, 1); // remove global table(-1)
lua_call(lua_state, 0, 0);
return 0;
}
Lua
problem =
{
{9, 0, 0, 1, 0, 0, 0, 0, 5},
{0, 0, 5, 0, 9, 0, 2, 0, 1},
{8, 0, 0, 0, 4, 0, 0, 0, 0},
{0, 0, 0, 0, 8, 0, 0, 0, 0},
{0, 0, 0, 7, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 2, 6, 0, 0, 9},
{2, 0, 0, 3, 0, 0, 0, 0, 6},
{0, 0, 0, 2, 0, 0, 9, 0, 0},
{0, 0, 1, 9, 0, 4, 5, 7, 0},
}
print("Lua Works")
user_input = io.read();
You don't have any values to iterate on Lua stack.
That int t=2; doesn't reflect anything, and your script doesn't return values to be left on stack.
See PIL book: 25.1 – Table Manipulation for examples on accessing global table.

How to get a coefficient matrix in Eigen?

Ok so I want to do this operation in Eigen:
float StartMatrix[7][7] = { { 1, 4, 6, 9, 3, 5, 8 }, { 2, 5, 3, 7, 4, 8, 2 }, { 3, 6, 6, 7, 0, 2, 4 },
{ 2, 4, 3, 7, 4, 8, 2 }, { 2, 3, 3, 11, 4, 8, 1 }, { 2, 12, 3, 7, 0, 8, 2 },
{ 2, 2, 3, 4, 4, 11, 2 } };
float TotalMatrix[7] = { 22, 15, 13, 26, 27, 33, 19 };
float CoMatrix[7][7] = { { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0 } };
for (int row = 0; row < 7; row++) {
for (int col = 0; col < 7; col++) {
CoMatrix[row][col] = StartMatrix[row][col] / TotalMatrix[col];
}
}
Divide each row by just the column in the TotalMatrix. And then I want to subtract the Identity matrix from the CoMatrix in Eigen and get the inverse on that (just to get an idea why I want to do this).
Problem is, how do I either perform this operation with Eigen, or somehow get the CoMatrix array into a matrix in Eigen so I can do stuff with it (like getting inverse etc).
Thanks!
Your code in Eigen would look something like this (after importing the Eigen namespace, using namespace Eigen;):
MatrixXd StartMatrix(7, 7);
StartMatrix <<
1, 4, 6, 9, 3, 5, 8, 2, 5, 3, 7, 4, 8, 2, 3, 6, 6, 7, 0, 2, 4,
2, 4, 3, 7, 4, 8, 2, 2, 3, 3, 11, 4, 8, 1, 2, 12, 3, 7, 0, 8, 2,
2, 2, 3, 4, 4, 11, 2;
VectorXd TotalMatrix(7);
TotalMatrix << 22, 15, 13, 26, 27, 33, 19;
MatrixXd CoMatrix = MatrixXd::Zero(StartMatrix.rows(), StartMatrix.cols());
CoMatrix = StartMatrix.array() / (TotalMatrix.replicate(1,StartMatrix.cols())).array();
You can continue subtracting the identity matrix with
CoMatrix -= MatrixXd::Identity(CoMatrix.rows(), CoMatrix.cols());
or combine it with the previous expression as:
CoMatrix = (StartMatrix.array() / (TotalMatrix.replicate(1, StartMatrix.cols())).array()).matrix()
- MatrixXd::Identity(CoMatrix.rows(), CoMatrix.cols());

Assigning to an array from an initializer list [duplicate]

This question already has answers here:
Error: Assigning to an array from an initializer list
(2 answers)
Closed 9 years ago.
I've checked on SO already for a simple way to fix this error. I didn't get this when compiling on another computer but suddenly now it's not compiling on my PC. Here's the error I'm getting:
Error: Assigning to an array from an initializer list
And here's the code:
int maze[12][12];
void print(bool playing);
int main()
{
printMaze(false);
playGame();
return 0;
}
void print(bool playing)
{
if (!playing) maze = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1},
{2, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1},
{1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 3},
{1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
}
It might also be worth mentioning that I get a warning on the same line:
Warning: Extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
I know that clearly means I have to use one of these two to use extended initializer lists, but have no idea what to do to resolve the matter.
Edit:
Having g++ follow the C++11 ISO C++ language standard in the settings removes the warning, but not the error.
What do your compilations steps look like? The warning is fairly clear: you are trying to use a feature that requires -std=c++11 or -std=gnu++11, and although that is apparently enabled by default, it is possible that you have overridden it (i.e. explicitly turned it off) somehow. You should examine your compilation process closer and make sure you aren't preventing that feature from being allowed.
A workaround is to use the old-style C function memcpy. This will work with older compilers.
int maze[12][12];
void printMaze(bool playing);
int main()
{
printMaze(false);
playGame();
return 0;
}
void printMaze(bool playing)
{
static int maze1[12][12] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1},
{2, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1},
{1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 3},
{1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
if (!playing) memcpy(maze, maze1, 12*12*sizeof(int));
}

Adding two arrays?

In the Arduino IDE, I'd like to add the contents of two existing arrays like this:
#define L0 { {0, 0, 0, 0}, {0, 0, 0, 1}, {0, 0, 0, 0} }
#define L1 { {0, 0, 0, 1}, {0, 0, 0, 0}, {0, 0, 0, 0} }
should become
int myarray[3][4] = { {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 0} }
How would I go about this?
Thanks!
Thy this;
const int a[3][4] = { {0, 0, 0, 0}, {0, 0, 0, 1}, {0, 0, 0, 0} };
const int b[3][4] = { {0, 0, 0, 1}, {0, 0, 0, 0}, {0, 0, 0, 0} };
int c[3][4];
const int* pa = &a[0][0];
const int* pb = &b[0][0];
int* pc = &c[0][0];
for(int i = 0; i < 3 * 4; ++i)
{
*(pc + i) = *(pa + i) + *(pb + i);
}
I think you are confused about how to go access the arrays L0 and L1 since they are defined as macros. Just assign them to arrays since the preprocessor will simply replace them:
int l[][4]=L0;
int m[][4]=L1;
Preprocessor will replace L0 and L1 with their values and compiler will only see them as:
int l[][4]={ {0, 0, 0, 0}, {0, 0, 0, 1}, {0, 2, 0, 0} };
int m[][4]={ {0, 0, 0, 5}, {0, 0, 0, 6}, {0, 0, 7, 0} };
Now, you can use l & m to access the elements of array. Should easy enough from here to add two arrays :)