in h3_h3Index.c [1115:1188]
H3Error H3_EXPORT(getIcosahedronFaces)(H3Index h3, int *out) {
int res = H3_GET_RESOLUTION(h3);
int isPent = H3_EXPORT(isPentagon)(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 (isPent && !isResolutionClassIII(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);
return H3_EXPORT(getIcosahedronFaces)(childPentagon, out);
}
// convert to FaceIJK
FaceIJK fijk;
H3Error err = _h3ToFaceIjk(h3, &fijk);
if (err) {
return err;
}
// 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 (isPent) {
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;
H3Error maxFaceCountError = H3_EXPORT(maxFaceCount)(h3, &faceCount);
if (NEVER(maxFaceCountError != E_SUCCESS)) {
return maxFaceCountError;
}
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 (isPent) {
_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++;
if (pos >= faceCount) {
// Mismatch between the heuristic used in maxFaceCount and
// calculation here - indicates an invalid index.
return E_FAILED;
}
}
out[pos] = face;
}
return E_SUCCESS;
}