public static void silhouette(
      ExpandingPolytopeEntry entry, int i, Vector3d w, ExpandingPolytopeEdgeList edgeList) {
    if ((entry != null) && !entry.isObsolete()) {
      // Facet entry is visited for the first time.

      Vector3d closestPointToOrigin = entry.getClosestPointToOrigin();
      if (isNotVisibleFromW(closestPointToOrigin, w)) {
        // Facet entry is not visible from w.
        edgeList.addEdge(entry, i);
      } else {
        // Mark entry visible, and search its neighbors.
        entry.setObsolete();
        int iPlusOne = (i + 1) % 3;
        int iPlusTwo = (i + 2) % 3;
        silhouette(
            entry.getAdjacentTriangle(iPlusOne),
            entry.getAdjacentTriangleEdgeIndex(iPlusOne),
            w,
            edgeList);
        silhouette(
            entry.getAdjacentTriangle(iPlusTwo),
            entry.getAdjacentTriangleEdgeIndex(iPlusTwo),
            w,
            edgeList);
      }
    }
  }