use of org.twak.camp.Output.Face in project chordatlas by twak.
the class Campz method findChains.
public static List<List<Face>> findChains(Output output) {
Set<Face> remaining = new LinkedHashSet<>(output.faces.values());
MultiMap<Face, Face> parent2children = new MultiMap<>();
while (!remaining.isEmpty()) {
Set<Face> above = new LinkedHashSet<>();
Face f = remaining.iterator().next();
do {
remaining.remove(f);
above.add(f);
if (f.parent != null)
f = f.parent;
} while (f.parent != null);
above.add(f);
parent2children.putAll(f, above, true);
}
return parent2children.keySet().stream().map(f -> parent2children.get(f)).collect(Collectors.toList());
}
use of org.twak.camp.Output.Face in project chordatlas by twak.
the class GreebleSkel method createMesh.
public void createMesh(Output output) {
float[] roofColor = new float[] { 0.3f, 0.3f, 0.3f, 1 }, wallColor = new float[] { 228 / 255f, 223 / 255f, 206 / 255f, 1.0f };
if (output.faces == null)
return;
double bestWallArea = 0, bestRoofArea = 0;
for (Face f : output.faces.values()) {
double area = Loopz.area3(f.getLoopL());
Tag t = getTag(f.profile, RoofTag.class);
if (t != null && area > bestRoofArea && ((RoofTag) t).color != null) {
roofColor = ((RoofTag) t).color;
bestRoofArea = area;
}
t = getTag(f.profile, WallTag.class);
if (t != null && area > bestWallArea && ((WallTag) t).color != null) {
wallColor = ((WallTag) t).color;
bestWallArea = area;
}
}
greebleGrid = new GreebleGrid(tweed, mbs = new MMeshBuilderCache());
output.addNonSkeletonSharedEdges(new RoofTag(roofColor));
edges(output, roofColor);
for (List<Face> chain : Campz.findChains(output)) {
// for ( Face f : output.faces.values() )
// mbs.get(roofColor).add3d( Loopz.insertInnerEdges( f.getLoopL() ), zToYup );
Optional<Tag> opt = chain.stream().flatMap(f -> f.profile.stream()).filter(tag -> tag instanceof WallTag).findAny();
WallTag wt = null;
Set<QuadF> features = new HashSet<>();
MiniFacade mf = null;
if (opt.isPresent() && (wt = (WallTag) opt.get()).miniFacade != null) {
MiniFacade mf2 = new MiniFacade(wt.miniFacade);
Line facadeLine;
{
Edge e = chain.get(0).edge;
// we might rotate the facade to apply a set of features to a different side of the building.
facadeLine = new Line(e.end.x, e.end.y, e.start.x, e.start.y);
}
if (TweedSettings.settings.snapFacadeWidth) {
// move/scale mf horizontally from mean-image-location to mesh-facade-location
double[] meshSE = findSE(wt.miniFacade, facadeLine, chain);
mf2.scaleX(meshSE[0], meshSE[1]);
}
// find window locations in 3 space
mf2.rects.values().stream().flatMap(f -> f.stream()).map(r -> new QuadF(r, facadeLine)).forEach(q -> features.add(q));
mf = mf2;
}
for (Face f : chain) {
face(f, mf, features, roofColor, wallColor);
}
for (QuadF w : features) if ((w.original.f == Feature.WINDOW || w.original.f == Feature.SHOP) && w.foundAll()) {
greebleGrid.createDormerWindow(w, mbs.WOOD, mbs.GLASS, (float) wt.sillDepth, (float) wt.sillHeight, (float) wt.corniceHeight, 0.6, 0.9);
}
// for ( String mName : mbs.cache.keySet() )
// for (float[] mCol : mbs.cache.get( mName ).keySet() )
// node.attachChild( mb2Geom( output, chain, mName, mCol ) );
greebleGrid.attachAll(node, chain, output, new ClickMe() {
@Override
public void clicked(Object data) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
selected(output, node, findSuperEdge(output, chain));
}
});
} catch (Throwable th) {
th.printStackTrace();
}
}
});
}
}
Aggregations