use of org.twak.utils.collections.MultiMap in project chordatlas by twak.
the class Tube method cap.
private static void cap(MeshBuilder out, Collection<LinearForm3D> after, Vector3d along, List<Point3d> profilePts, boolean reverse) {
MultiMap<LinearForm3D, Point3d> faces = new MultiMap<>();
for (Point3d p : profilePts) {
List<LinearForm3D> hit = new ArrayList<>();
Point3d c = clip(p, along, after, hit);
for (LinearForm3D h : hit) faces.put(h, c);
}
for (Map.Entry<LinearForm3D, List<Point3d>> e : faces.map.entrySet()) out.add(new Loop<Point3d>(e.getValue()).singleton(), null, reverse);
}
use of org.twak.utils.collections.MultiMap in project chordatlas by twak.
the class GreebleEdge method roowWallGreeble.
public static void roowWallGreeble(Output output, MeshBuilder roof, MeshBuilder wall) {
MultiMap<Point3d, SharedEdge> boundary = new MultiMap<>();
Set<SharedEdge> roofWallBoundary = new HashSet<>();
for (Face f1 : output.faces.values()) for (Loop<SharedEdge> sl : f1.edges) for (Loopable<SharedEdge> se : sl.loopableIterator()) {
Face f2 = se.get().getOther(f1);
if (isWall(f1) ^ isWall(f2)) {
boundary.put(se.get().getStart(f1), se.get());
roofWallBoundary.add(se.get());
}
}
for (SharedEdge se : roofWallBoundary) {
if (se.start.z < 1 || se.end.z < 1)
// something strange here...
continue;
Face f1 = se.left, f2 = se.right;
if (f1 == null || f2 == null)
continue;
EdgePoint bs = findAdjacent(se.start, se.end, boundary), be = findAdjacent(se.end, se.start, boundary);
if (bs != null && be != null) {
LinearForm3D cutS, cutE;
if (isOverhang(bs.se))
// between two angles
cutS = cut(bs.pt, se.start, se.end);
else
// flat at end
cutS = new LinearForm3D(LinearForm3D.linePerp(toXZ(se.end), toXZ(se.start)));
if (isOverhang(be.se))
cutE = cut(se.start, se.end, be.pt);
else
// flat at end
cutE = new LinearForm3D(LinearForm3D.linePerp(toXZ(se.start), toXZ(se.end)));
LinearForm3D right = new LinearForm3D(toXZ(f1.edge.getPlaneNormal()), toXZ(f1.edge.start)), left = new LinearForm3D(toXZ(f2.edge.getPlaneNormal()), toXZ(f2.edge.start));
Tube.tube(roof, Collections.singleton(cutS), Collections.singleton(cutE), new Line3d(toXZ(se.start), toXZ(se.end)), left, right, isOverhang(se) ? new OverhangCross() : new LipCross());
}
}
}
use of org.twak.utils.collections.MultiMap 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.utils.collections.MultiMap in project chordatlas by twak.
the class SkelFootprint method debugFindCleanProfiles.
public static void debugFindCleanProfiles(List<Line> footprint, SkelGen skelGen, ProgressMonitor m, Tweed tweed) {
MultiMap<SuperLine, List<Prof>> profSets = new MultiMap<>();
for (Line l : footprint) profileRuns((SuperLine) l, profSets);
List<List<Prof>> ordered = new ArrayList<>();
Map<List<Prof>, SuperLine> pairs = new LinkedHashMap<>();
for (SuperLine l : profSets.keySet()) for (List<Prof> lp : profSets.get(l)) {
pairs.put(lp, l);
ordered.add(lp);
}
JSlider bunch = new JSlider(0, ordered.size() - 1);
JButton button = new JButton("go");
Plot plot = new Plot(bunch, button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
PaintThing.debug.clear();
plot.toPaint.clear();
List<Prof> ps = ordered.get(bunch.getValue());
SuperLine sl = pairs.get(ps);
if (sl != null && ps != null) {
PaintThing.debug(new Color(0, 0, 0, 50), 1, ps);
Prof clean = Prof.parameterize(ps);
Prof c2 = new Prof(clean);
for (Point2d p : c2) p.x += 10;
// plot.toPaint.add( clean ) );
PaintThing.debug(new Color(0, 170, 255), 3f, c2);
Prof mid = ps.get(ps.size() / 2);
tweed.enqueue(new Runnable() {
@Override
public void run() {
Jme3z.removeAllChildren(tweed.debug);
for (Prof p : ps) {
// p = p.moveToX0();
p.render(tweed, tweed.debug, ColorRGBA.Blue, (float) TweedSettings.settings.profileHSampleDist);
}
Point3d pt = mid.to3d(mid.get(0));
pt.y = 0;
Geometry geom = new Geometry("material_", clean.renderStrip(1, null));
Material mat = new Material(tweed.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
mat.setColor("Diffuse", ColorRGBA.Blue);
mat.setColor("Ambient", ColorRGBA.Red);
geom.setMaterial(mat);
// tweed.debug.attachChild( geom );
tweed.debug.updateGeometricState();
tweed.debug.updateModelBound();
tweed.gainFocus();
}
});
}
plot.repaint();
}
});
bunch.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
button.doClick();
}
});
}
use of org.twak.utils.collections.MultiMap in project chordatlas by twak.
the class SkelFootprint method findProfiles.
private void findProfiles(List<Line> footprint, List<Prof> globalProfs) {
MultiMap<SuperLine, List<Prof>> profSets = new MultiMap<>();
System.out.println("clustering " + globalProfs.size() + " profiles over sweep edges...");
for (Line l : footprint) profileRuns((SuperLine) l, profSets);
Prof example = null;
System.out.println("cleaning " + profSets.values().stream().flatMap(c -> c.stream()).count() + " profiles...");
for (SuperLine sl : profSets.keySet()) for (List<Prof> lp : profSets.get(sl)) {
if (example == null)
example = lp.get(0);
Prof p = Prof.parameterize(lp);
if (p != null && p.size() > 1)
globalProfs.add(SkelGen.moveToX0(p));
}
Iterator<Prof> git = globalProfs.iterator();
int c = 0;
// remove trivial
while (git.hasNext()) {
Prof p = git.next();
if (p.size() < 2)
git.remove();
else if (p.size() == 2) {
if (p.get(0).x == p.get(1).x) {
git.remove();
c++;
}
} else if (p.size() == 3) {
if (p.get(0).x == p.get(1).x && p.get(2).y == p.get(1).y)
git.remove();
}
}
System.out.println("found " + globalProfs.size() + " interesting profiles" + " from " + profSets.size() + " runs");
removeSimilarB(globalProfs, TweedSettings.settings.profilePrune);
System.out.println("after remove similar " + globalProfs.size());
// insert single vertical profile
{
Prof vertical = defaultProf(example);
globalProfs.add(0, vertical);
}
}
Aggregations