2D lineart - culling hidden lines for SVG output / Plotting

This is possible in Processing with PGS shape boolean operations.

The approach is: for each shape, subtract the union of shapes visually above it.

l will include the algorithm given below as a method in the next version of the library (which has been WIP for some time now!).

Example

Input

[left] Circles shaded by layer (lighter = visually on top). [right] Translucent fill to reveal overlap.

Line culling

Note that some edges duplicated/overlap where shapes have been cut away from each other.

Line culling + dissolve remaining lines

Having removed any overlapping edges, we get pure linework for svg/plotting.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import micycle.pgs.PGS_Conversion;
import micycle.pgs.PGS_ShapeBoolean;
import org.locationtech.jts.dissolve.LineDissolver;

PShape cullLines(PShape shape) {
	var layers = PGS_Conversion.getChildren(shape); // visual top last
	Collections.reverse(layers); // visual top first
	PShape union = layers.get(0); // cascading union

	List<PShape> layersOut = new ArrayList<>();
	layersOut.add(layers.get(0));
	for (int i = 1; i < layers.size(); i++) {
		// for each shape, subtract the union of shapes visually above it
		var layer = PGS_ShapeBoolean.subtract(layers.get(i), union);
		layersOut.add(layer);
		union = PGS_ShapeBoolean.union(union, layers.get(i));
	}

	var culled = PGS_Conversion.fromChildren(layersOut);
	var dissolved = toPShape(LineDissolver.dissolve(fromPShape(culled)));
	
	return dissolved;
	}
1 Like