235 lines
7.1 KiB
C++
235 lines
7.1 KiB
C++
#include "MeshPrimitives.h"
|
|
|
|
#include "MeshBuilder.h"
|
|
|
|
#include <math.h>
|
|
|
|
#include <iostream>
|
|
|
|
std::unique_ptr<TriMesh> MeshPrimitives::buildRectangleAsTriMesh()
|
|
{
|
|
VecPoints locations = {
|
|
{0, 0},
|
|
{1, 0},
|
|
{1, 1},
|
|
{0, 1}
|
|
};
|
|
|
|
EdgeIds edge_ids = {
|
|
{0, 1},
|
|
{1, 2},
|
|
{2, 0},
|
|
{2, 3},
|
|
{3, 0}
|
|
};
|
|
|
|
FaceIds face_ids = {
|
|
{0, 1, 2},
|
|
{2, 3, 4}
|
|
};
|
|
|
|
return MeshBuilder::buildTriMesh(locations, edge_ids, face_ids);
|
|
}
|
|
|
|
std::unique_ptr<TriMesh> MeshPrimitives::buildRoundedRectangleAsTriMesh(double radius, double aspect_ratio, unsigned num_segments)
|
|
{
|
|
unsigned num_fans = 4;
|
|
unsigned num_nodes_per_fan = num_segments + 2;
|
|
VecPoints locations(num_fans * num_nodes_per_fan);
|
|
|
|
double rect_start_x = radius;
|
|
double rect_end_x = 1.0 - radius;
|
|
double rect_end_y = 1.0 - radius;
|
|
|
|
double delta_theta = (M_PI/4.0) / double (num_segments);
|
|
double running_theta = 0;
|
|
|
|
locations[0] = {rect_end_x, radius};
|
|
unsigned offset = 1;
|
|
for (unsigned idx=0; idx<=num_segments; idx++)
|
|
{
|
|
locations[offset + idx] = {rect_end_x + radius*sin(running_theta), radius*(1.0 - cos(running_theta))};
|
|
running_theta += delta_theta;
|
|
}
|
|
offset += num_segments;
|
|
|
|
locations[offset] = {rect_end_x, rect_end_y};
|
|
offset++;
|
|
running_theta = 0;
|
|
for (unsigned idx=0; idx<=num_segments;idx++)
|
|
{
|
|
locations[offset + idx] = {rect_end_x + radius*cos(running_theta), rect_end_y + radius*sin(running_theta)};
|
|
running_theta += delta_theta;
|
|
}
|
|
offset += num_segments;
|
|
|
|
locations[offset] = {rect_start_x, rect_end_y};
|
|
offset ++;
|
|
running_theta = 0;
|
|
for (unsigned idx=0; idx<=num_segments;idx++)
|
|
{
|
|
locations[offset + idx] = {rect_start_x - radius*sin(running_theta), rect_end_y + radius*cos(running_theta)};
|
|
running_theta += delta_theta;
|
|
}
|
|
offset += num_segments;
|
|
|
|
locations[offset] = {rect_start_x, radius};
|
|
offset++;
|
|
running_theta = 0;
|
|
for (unsigned idx=0; idx<=num_segments;idx++)
|
|
{
|
|
locations[offset + idx] = {rect_start_x - radius*cos(running_theta), radius *(1 - sin(running_theta))};
|
|
running_theta += delta_theta;
|
|
}
|
|
|
|
unsigned num_edges_per_fan = 2*num_segments + 1;
|
|
unsigned num_inner_rect_edges = 3*num_fans;
|
|
EdgeIds edge_ids(num_edges_per_fan*num_fans + num_inner_rect_edges + 1);
|
|
|
|
// Fan edges
|
|
for (unsigned jdx=0; jdx< num_fans; jdx++)
|
|
{
|
|
unsigned node_offset = jdx*num_nodes_per_fan;
|
|
unsigned edge_offset = jdx*num_edges_per_fan;
|
|
|
|
// Inner edges
|
|
for(unsigned idx=0; idx<=num_segments; idx++)
|
|
{
|
|
edge_ids[edge_offset + idx] = {node_offset, node_offset + idx + 1};
|
|
}
|
|
|
|
// Outer edges
|
|
for(unsigned idx=0; idx<num_segments; idx++)
|
|
{
|
|
edge_ids[edge_offset + num_segments + 1 + idx] = {node_offset + idx + 1, node_offset + idx + 2};
|
|
}
|
|
}
|
|
|
|
// Inner rect edges
|
|
unsigned edge_offset = num_edges_per_fan*num_fans;
|
|
return nullptr;
|
|
}
|
|
|
|
std::unique_ptr<LineMesh> MeshPrimitives::buildRectangleAsLineMesh()
|
|
{
|
|
VecPoints locations = {
|
|
{0, 0},
|
|
{1, 0},
|
|
{1, 1},
|
|
{0, 1}
|
|
};
|
|
|
|
EdgeIds edge_ids = {
|
|
{0, 1},
|
|
{1, 2},
|
|
{2, 3},
|
|
{3, 0}
|
|
};
|
|
|
|
return MeshBuilder::buildLineMesh(locations, edge_ids);
|
|
}
|
|
|
|
std::unique_ptr<TriMesh> MeshPrimitives::buildExplodedGridAsTriMesh(unsigned numX, unsigned numY)
|
|
{
|
|
double delta_x = 1.0/double(numX);
|
|
double delta_y = 1.0/double(numY);
|
|
|
|
VecPoints locations (4 * numX * numY);
|
|
double offset_x = delta_x/2.0;
|
|
double offset_y = delta_y/2.0;
|
|
for (unsigned idx=0; idx<numY; idx++)
|
|
{
|
|
for(unsigned jdx=0; jdx<numX; jdx++)
|
|
{
|
|
auto locX0 = offset_x - delta_x/2.0;
|
|
auto locX1 = offset_x + delta_x/2.0;
|
|
auto locY0 = offset_y - delta_y/2.0;
|
|
auto locY1 = offset_y + delta_y/2.0;
|
|
|
|
auto id_offset = 4* (jdx + numX*idx);
|
|
locations[id_offset] = Point(locX0, locY0);
|
|
locations[id_offset + 1] = Point(locX1, locY0);
|
|
locations[id_offset + 2] = Point(locX1, locY1);
|
|
locations[id_offset + 3] = Point(locX0, locY1);
|
|
|
|
offset_x += delta_x;
|
|
}
|
|
offset_x = delta_x/2.0;
|
|
offset_y += delta_y;
|
|
}
|
|
|
|
EdgeIds edge_ids(5 * numX * numY);
|
|
for (unsigned idx=0; idx<numY; idx++)
|
|
{
|
|
for(unsigned jdx=0; jdx<numX; jdx++)
|
|
{
|
|
unsigned node_offset = 4 * (jdx + numX * idx);
|
|
auto id_offset = 5* (jdx + numX*idx);
|
|
edge_ids[id_offset] = {node_offset, node_offset + 1};
|
|
edge_ids[id_offset + 1] = {node_offset + 1, node_offset + 2};
|
|
edge_ids[id_offset + 2] = {node_offset + 2, node_offset + 3};
|
|
edge_ids[id_offset + 3] = {node_offset + 3, node_offset};
|
|
edge_ids[id_offset + 4] = {node_offset + 2, node_offset};
|
|
}
|
|
}
|
|
|
|
FaceIds face_ids(2 *numX * numY);
|
|
for (unsigned idx=0; idx<numY; idx++)
|
|
{
|
|
for(unsigned jdx=0; jdx<numX; jdx++)
|
|
{
|
|
unsigned edge_offset = 5 * (jdx + numX * idx);
|
|
unsigned face_offset = 2 * (jdx + numX * idx);
|
|
face_ids[face_offset] = {edge_offset, edge_offset + 1, edge_offset + 4};
|
|
face_ids[face_offset + 1] = {edge_offset + 4, edge_offset + 2, edge_offset + 3};
|
|
}
|
|
}
|
|
|
|
return MeshBuilder::buildTriMesh(locations, edge_ids, face_ids);
|
|
}
|
|
|
|
std::unique_ptr<LineMesh> MeshPrimitives::buildExplodedGridAsLineMesh(unsigned numX, unsigned numY)
|
|
{
|
|
double delta_x = 1.0/double(numX);
|
|
double delta_y = 1.0/double(numY);
|
|
|
|
VecPoints locations (4 * numX * numY);
|
|
double offset_x = delta_x/2.0;
|
|
double offset_y = delta_y/2.0;
|
|
for (unsigned idx=0; idx<numY; idx++)
|
|
{
|
|
for(unsigned jdx=0; jdx<numX; jdx++)
|
|
{
|
|
auto locX0 = offset_x - delta_x/2.0;
|
|
auto locX1 = offset_x + delta_x/2.0;
|
|
auto locY0 = offset_y - delta_y/2.0;
|
|
auto locY1 = offset_y + delta_y/2.0;
|
|
|
|
auto id_offset = 4* (jdx + numX*idx);
|
|
locations[id_offset] = Point(locX0, locY0);
|
|
locations[id_offset + 1] = Point(locX1, locY0);
|
|
locations[id_offset + 2] = Point(locX1, locY1);
|
|
locations[id_offset + 3] = Point(locX0, locY1);
|
|
|
|
offset_x += delta_x;
|
|
}
|
|
offset_x = delta_x/2.0;
|
|
offset_y += delta_y;
|
|
}
|
|
|
|
EdgeIds edge_ids(4 * numX * numY);
|
|
for (unsigned idx=0; idx<numY; idx++)
|
|
{
|
|
for(unsigned jdx=0; jdx<numX; jdx++)
|
|
{
|
|
unsigned node_offset = 4 * (jdx + numX * idx);
|
|
auto id_offset = 4* (jdx + numX*idx);
|
|
edge_ids[id_offset] = {node_offset, node_offset + 1};
|
|
edge_ids[id_offset + 1] = {node_offset + 1, node_offset + 2};
|
|
edge_ids[id_offset + 2] = {node_offset + 2, node_offset + 3};
|
|
edge_ids[id_offset + 3] = {node_offset + 3, node_offset};
|
|
}
|
|
}
|
|
|
|
return MeshBuilder::buildLineMesh(locations, edge_ids);
|
|
}
|