# How-To: Using SC::Store::Utils::TriangulateFace

TriangulateFace takes several arguments (cf. HOOPS Communicator documentation — HOOPS Communicator documentation ) to triangulate a supplied polygonal face. While most arguments are straightforward, the `face_list` is a little more complicated.

The first number in the face list array indicates the number of indices defining a face. This is followed by those indices (in the points array). This pattern repeats for subsequent faces. If you have two triangles, the face list array might be as follows;

``````{ 3, 0, 1, 2,
3, 2, 3, 0 }
``````

## Instructions

### Simple Example

Lets assume we have a single polygon with 300 points (`nb_circle_steps`). This is all in one “face”. So, the correct code for this would be

``````	std::vector<int> face_list;
face_list.push_back(nb_circle_steps);
for (uint32_t i = 0; i < nb_circle_steps; i++)
face_list.push_back(i);

std::vector<SC::Store::Point> out_points;
bool triStatus = SC::Store::Utils::TriangulateFace(mesh_points.data(), face_list.data(), face_list.size(), SC::Store::Point(0, 0, 1), out_points);
if (triStatus)
std::cout << "TriangulateFace : out_points count = " << out_points.size() << std::endl;
else
std::cout << "TriangulateFace : failed" << std::endl;
``````

Notice `face_list.size()` is used as an argument to `TriagulateFace` rather than `nb_circle_steps`.

### Concave Faces

This is the only triangulation function available in Communicator and it handles concave polygons. Consider this simple test.

``````	int point_count = 5;
std::vector<int> face_list;
face_list.push_back(point_count);
for (uint32_t i = 0; i < point_count; i++)
face_list.push_back(i);

std::vector<SC::Store::Point> poly_points;
poly_points.resize(point_count);
poly_points[0].x = 0;
poly_points[0].y = 0;
poly_points[0].z = 0;
poly_points[1].x = 1;
poly_points[1].y = 1;
poly_points[1].z = 0;
poly_points[2].x = 2;
poly_points[2].y = 0;
poly_points[2].z = 0;
poly_points[3].x = 1;
poly_points[3].y = 2;
poly_points[3].z = 0;
poly_points[4].x = 0;
poly_points[4].y = 0;
poly_points[4].z = 0;

std::vector<SC::Store::Point> out_points;
bool triStatus = SC::Store::Utils::TriangulateFace(poly_points.data(), face_list.data(), face_list.size(), SC::Store::Point(0, 0, 1), out_points);
``````

The result was

``````+		[0]	{x=1.00000000 y=2.00000000 z=0.00000000 }	SC::Store::Point
+		[1]	{x=0.00000000 y=0.00000000 z=0.00000000 }	SC::Store::Point
+		[2]	{x=1.00000000 y=1.00000000 z=0.00000000 }	SC::Store::Point
+		[3]	{x=1.00000000 y=2.00000000 z=0.00000000 }	SC::Store::Point
+		[4]	{x=1.00000000 y=1.00000000 z=0.00000000 }	SC::Store::Point
+		[5]	{x=2.00000000 y=0.00000000 z=0.00000000 }	SC::Store::Point
``````

### Faces with Holes

This method supports holes as well. It expects more than one face passed in where one face represents the perimeter and subsequent faces represent holes. Simply negate the first parameter in the face list for a face which represents a hole.

``````	int perim_count = 4;
int hole_count = 4;
int point_count = perim_count + hole_count;
std::vector<int> face_list;
for (uint32_t i = 0; i < point_count; i++)
{
if (i == 0)
face_list.push_back(perim_count);
else if (i == 4)
face_list.push_back(-hole_count); // negated parameter indicates this face is a hole

face_list.push_back(i);
}

std::vector<SC::Store::Point> poly_points;
poly_points.push_back(SC::Store::Point(0, 0, 0)); // perimeter
poly_points.push_back(SC::Store::Point(3, 0, 0));
poly_points.push_back(SC::Store::Point(3, 3, 0));
poly_points.push_back(SC::Store::Point(0, 3, 0));
poly_points.push_back(SC::Store::Point(1, 1, 0)); // hole
poly_points.push_back(SC::Store::Point(2, 1, 0));
poly_points.push_back(SC::Store::Point(2, 2, 0));
poly_points.push_back(SC::Store::Point(1, 2, 0));

std::vector<SC::Store::Point> out_points;
bool triStatus = SC::Store::Utils::TriangulateFace(poly_points.data(), face_list.data(), face_list.size(), SC::Store::Point(0, 0, 1), out_points);
if (triStatus)
std::cout << "TriangulateFace : out_points count = " << out_points.size() << std::endl;
else
std::cout << "TriangulateFace : failed" << std::endl;
``````