public static void toWireframe(TFloatList positions, TIntList indices, boolean deTriangulation) {
        int indicesSize = indices.size();
        int positionsSize = positions.size();
        // Remove duplicate vertices
        for (int i = 0; i < positionsSize; i += 3) {
            final float x = positions.get(i);
            final float y = positions.get(i + 1);
            final float z = positions.get(i + 2);
            // Search for a duplicate
            for (int ii = i + 3; ii < positionsSize; ii += 3) {
                final float ox = positions.get(ii);
                final float oy = positions.get(ii + 1);
                final float oz = positions.get(ii + 2);
                if (x == ox && y == oy && z == oz) {
                    // If one is removed, we need to fix the indices
                    for (int iii = 0; iii < indicesSize; iii++) {
                        final int index = indices.get(iii);
                        if (index == ii / 3) {
                            // Any index referring to it is replaced by the original
                            indices.replace(iii, i / 3);
                        } else if (index > ii / 3) {
                            // Any index above is decremented
                            indices.replace(iii, index - 1);
                        }
                    }
                    // Then we can remove it properly
                    positions.remove(ii, 3);
                    positionsSize -= 3;
                    ii -= 3;
                }
            }
        }
        // Next we remove duplicate edges using a hash set
        final Set<Vector2i> edges = new HashSet<>();
        final Set<Vector2i> cancelled = new HashSet<>();
        for (int i = 0; i < indicesSize; i += 3) {
            final int i0 = indices.get(i);
            final int i1 = indices.get(i + 1);
            final int i2 = indices.get(i + 2);
            // If we need to remove unnecessary edges
            if (deTriangulation) {
                // Get the points of the triangle
                final Vector3f p00 = new Vector3f(positions.get(i0 * 3), positions.get(i0 * 3 + 1), positions.get(i0 * 3 + 2));
                final Vector3f p01 = new Vector3f(positions.get(i1 * 3), positions.get(i1 * 3 + 1), positions.get(i1 * 3 + 2));
                final Vector3f p02 = new Vector3f(positions.get(i2 * 3), positions.get(i2 * 3 + 1), positions.get(i2 * 3 + 2));
                // Test with all the other triangles
                for (int ii = i + 3; ii < indicesSize; ii += 3) {
                    // Get the indices of the other triangle
                    final int ii0 = indices.get(ii);
                    final int ii1 = indices.get(ii + 1);
                    final int ii2 = indices.get(ii + 2);
                    // Get the vertices of the other triangle
                    final Vector3f p10 = new Vector3f(positions.get(ii0 * 3), positions.get(ii0 * 3 + 1), positions.get(ii0 * 3 + 2));
                    final Vector3f p11 = new Vector3f(positions.get(ii1 * 3), positions.get(ii1 * 3 + 1), positions.get(ii1 * 3 + 2));
                    final Vector3f p12 = new Vector3f(positions.get(ii2 * 3), positions.get(ii2 * 3 + 1), positions.get(ii2 * 3 + 2));
                    // Test for a common edge
                    final Vector2i edge = getCommonEdge(p00, p01, p02, p10, p11, p12);
                    if (edge != null) {
                        // If we have one, add it to the cancelled list to be removed later since we can't do that now
                        final int c00 = indices.get(i + edge.getX());
                        final int c01 = indices.get(i + (edge.getX() + 1) % 3);
                        final int c10 = indices.get(ii + edge.getY());
                        final int c11 = indices.get(ii + (edge.getY() + 1) % 3);
                        cancelled.add(new Vector2i(Math.min(c00, c01), Math.max(c00, c01)));
                        cancelled.add(new Vector2i(Math.min(c10, c11), Math.max(c10, c11)));
                    }
                }
            }
            // Sorting the indices for the edges ensure the equalities will work correctly
            edges.add(new Vector2i(Math.min(i0, i1), Math.max(i0, i1)));
            edges.add(new Vector2i(Math.min(i1, i2), Math.max(i1, i2)));
            edges.add(new Vector2i(Math.min(i2, i0), Math.max(i2, i0)));
        }
        // Removed any edge that was flagged as unnecessary by the de-triangulation
        edges.removeAll(cancelled);
        // Finally, clear the indices and re-add them from the now unique edges
        indices.clear();
        for (Vector2i edge : edges) {
            indices.add(edge.getX());
            indices.add(edge.getY());
        }
    }
public static void toWireframe ( TFloatList positions , TIntList indices , boolean deTriangulation ) { int indicesSize = indices . size ( ) ; int positionsSize = positions . size ( ) ; for ( int i = 0 ; i < positionsSize ; i += 3 ) { final float x = positions . get ( i ) ; final float y = positions . get ( i + 1 ) ; final float z = positions . get ( i + 2 ) ; for ( int ii = i + 3 ; ii < positionsSize ; ii += 3 ) { final float ox = positions . get ( ii ) ; final float oy = positions . get ( ii + 1 ) ; final float oz = positions . get ( ii + 2 ) ; if ( x == ox && y == oy && z == oz ) { for ( int iii = 0 ; iii < indicesSize ; iii ++ ) { final int index = indices . get ( iii ) ; if ( index == ii / 3 ) { indices . replace ( iii , i / 3 ) ; } else if ( index > ii / 3 ) { indices . replace ( iii , index - 1 ) ; } } positions . remove ( ii , 3 ) ; positionsSize -= 3 ; ii -= 3 ; } } } final Set < Vector2i > edges = new HashSet < > ( ) ; final Set < Vector2i > cancelled = new HashSet < > ( ) ; for ( int i = 0 ; i < indicesSize ; i += 3 ) { final int i0 = indices . get ( i ) ; final int i1 = indices . get ( i + 1 ) ; final int i2 = indices . get ( i + 2 ) ; if ( deTriangulation ) { final Vector3f p00 = new Vector3f ( positions . get ( i0 * 3 ) , positions . get ( i0 * 3 + 1 ) , positions . get ( i0 * 3 + 2 ) ) ; final Vector3f p01 = new Vector3f ( positions . get ( i1 * 3 ) , positions . get ( i1 * 3 + 1 ) , positions . get ( i1 * 3 + 2 ) ) ; final Vector3f p02 = new Vector3f ( positions . get ( i2 * 3 ) , positions . get ( i2 * 3 + 1 ) , positions . get ( i2 * 3 + 2 ) ) ; for ( int ii = i + 3 ; ii < indicesSize ; ii += 3 ) { final int ii0 = indices . get ( ii ) ; final int ii1 = indices . get ( ii + 1 ) ; final int ii2 = indices . get ( ii + 2 ) ; final Vector3f p10 = new Vector3f ( positions . get ( ii0 * 3 ) , positions . get ( ii0 * 3 + 1 ) , positions . get ( ii0 * 3 + 2 ) ) ; final Vector3f p11 = new Vector3f ( positions . get ( ii1 * 3 ) , positions . get ( ii1 * 3 + 1 ) , positions . get ( ii1 * 3 + 2 ) ) ; final Vector3f p12 = new Vector3f ( positions . get ( ii2 * 3 ) , positions . get ( ii2 * 3 + 1 ) , positions . get ( ii2 * 3 + 2 ) ) ; final Vector2i edge = getCommonEdge ( p00 , p01 , p02 , p10 , p11 , p12 ) ; if ( edge != null ) { final int c00 = indices . get ( i + edge . getX ( ) ) ; final int c01 = indices . get ( i + ( edge . getX ( ) + 1 ) % 3 ) ; final int c10 = indices . get ( ii + edge . getY ( ) ) ; final int c11 = indices . get ( ii + ( edge . getY ( ) + 1 ) % 3 ) ; cancelled . add ( new Vector2i ( Math . min ( c00 , c01 ) , Math . max ( c00 , c01 ) ) ) ; cancelled . add ( new Vector2i ( Math . min ( c10 , c11 ) , Math . max ( c10 , c11 ) ) ) ; } } } edges . add ( new Vector2i ( Math . min ( i0 , i1 ) , Math . max ( i0 , i1 ) ) ) ; edges . add ( new Vector2i ( Math . min ( i1 , i2 ) , Math . max ( i1 , i2 ) ) ) ; edges . add ( new Vector2i ( Math . min ( i2 , i0 ) , Math . max ( i2 , i0 ) ) ) ; } edges . removeAll ( cancelled ) ; indices . clear ( ) ; for ( Vector2i edge : edges ) { indices . add ( edge . getX ( ) ) ; indices . add ( edge . getY ( ) ) ; } }
Converts a standard triangle model to a wireframe model, with the option to perform de-triangulation (convert faces of triangles back to a polygon). This assumes that the positions have 3
components, in the x, y, z order. No excess data is kept. The final model will have no duplicate vertices or edges.

@param positions The position list
@param indices The indices
@param deTriangulation Merge triangles into faces when possible