in src/h3lib/lib/h3Index.c [877:936]
void H3_EXPORT(h3GetFaces)(H3Index h3, int* out) {
int res = H3_GET_RESOLUTION(h3);
int isPentagon = H3_EXPORT(h3IsPentagon)(h3);
// We can't use the vertex-based approach here for class II pentagons,
// because all their vertices are on the icosahedron edges. Their
// direct child pentagons cross the same faces, so use those instead.
if (isPentagon && !isResClassIII(res)) {
// Note that this would not work for res 15, but this is only run on
// Class II pentagons, it should never be invoked for a res 15 index.
H3Index childPentagon = makeDirectChild(h3, 0);
H3_EXPORT(h3GetFaces)(childPentagon, out);
return;
}
// convert to FaceIJK
FaceIJK fijk;
_h3ToFaceIjk(h3, &fijk);
// Get all vertices as FaceIJK addresses. For simplicity, always
// initialize the array with 6 verts, ignoring the last one for pentagons
FaceIJK fijkVerts[NUM_HEX_VERTS];
int vertexCount;
if (isPentagon) {
vertexCount = NUM_PENT_VERTS;
_faceIjkPentToVerts(&fijk, &res, fijkVerts);
} else {
vertexCount = NUM_HEX_VERTS;
_faceIjkToVerts(&fijk, &res, fijkVerts);
}
// We may not use all of the slots in the output array,
// so fill with invalid values to indicate unused slots
int faceCount = H3_EXPORT(maxFaceCount)(h3);
for (int i = 0; i < faceCount; i++) {
out[i] = INVALID_FACE;
}
// add each vertex face, using the output array as a hash set
for (int i = 0; i < vertexCount; i++) {
FaceIJK* vert = &fijkVerts[i];
// Adjust overage, determining whether this vertex is
// on another face
if (isPentagon) {
_adjustPentVertOverage(vert, res);
} else {
_adjustOverageClassII(vert, res, 0, 1);
}
// Save the face to the output array
int face = vert->face;
int pos = 0;
// Find the first empty output position, or the first position
// matching the current face
while (out[pos] != INVALID_FACE && out[pos] != face) pos++;
out[pos] = face;
}
}