use of org.twak.camp.Output 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 in project chordatlas by twak.
the class SkelGen method selected.
private void selected(PlanSkeleton skel, Node house, SuperFace sf, SuperEdge se) {
JPanel ui = new JPanel();
ui.setLayout(new ListDownLayout());
JButton fac = new JButton("edit facade");
fac.addActionListener(e -> editFacade(skel, sf, se, false));
ui.add(fac);
// JButton tex = new JButton( "texture facade" );
// tex.addActionListener( e -> editFacade( skel, sf, se, true ) );
// ui.add( tex );
JButton proc = new JButton("procedural facade");
proc.addActionListener(e -> cgaFacade(skel, sf, se));
ui.add(proc);
JButton camp = new JButton("procedural extrusions");
camp.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
closeSitePlan();
siteplan = new Siteplan(skel.plan, false) {
SuperFace workon = sf;
public void show(Output output, Skeleton threadKey) {
super.show(output, threadKey);
Plot.closeLast();
tweed.enqueue(new Runnable() {
@Override
public void run() {
removeGeometryFor(workon);
// current selection is invalid
tweed.frame.setGenUI(null);
setSkel((PlanSkeleton) threadKey, output, workon);
}
});
}
};
siteplan.setVisible(true);
siteplan.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
});
ui.add(camp);
JButton mini = new JButton("street-view");
mini.addActionListener(e -> new MiniViewer(se));
if (sf != null)
ui.add(mini);
JButton prof = new JButton("profiles");
prof.addActionListener(e -> new ProfileAssignmentViewer(sf, skelFootprint == null ? null : skelFootprint.globalProfs));
ui.add(prof);
ui.add(new JLabel("height " + sf.heights.size()));
JButton plan = new JButton("plan");
plan.addActionListener(e -> new Plot(toRender, footprint));
ui.add(plan);
JButton remove = new JButton("remove");
remove.addActionListener(e -> {
visible = false;
calculateOnJmeThread();
tweed.frame.removeGen(SkelGen.this);
});
ui.add(plan);
JButton b = new JButton("view clean profiles");
b.addActionListener(e -> SkelFootprint.debugFindCleanProfiles(footprint, this, new ProgressMonitor(null, "", "", 0, 100), tweed));
ui.add(b);
JButton c = new JButton("compare profiles");
c.addActionListener(e -> skelFootprint.debugCompareProfs(skelFootprint.globalProfs));
ui.add(c);
tweed.frame.setGenUI(ui);
}
use of org.twak.camp.Output in project chordatlas by twak.
the class SkelGen method setSkel.
public synchronized void setSkel(PlanSkeleton skel, Output output, SuperFace sf) {
removeGeometryFor(sf);
Node house;
OnClick onclick = new OnClick() {
@Override
public void selected(Output output, Node house2, SuperEdge se) {
SkelGen.this.selected(skel, house2, sf, se);
}
};
GreebleSkel greeble = new GreebleSkel(tweed);
house = greeble.showSkeleton(output, onclick);
gNode.attachChild(house);
geometry.put(sf, house);
tweed.getRootNode().updateGeometricState();
tweed.getRootNode().updateModelBound();
tweed.gainFocus();
}
use of org.twak.camp.Output 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