use of org.twak.utils.geom.UnionWalker in project chordatlas by twak.
the class Concarnie method tidy.
private void tidy(Graph2D graph) {
UnionWalker uw = new UnionWalker();
for (Point2d a : graph.map.keySet()) {
for (Line l : graph.get(a)) {
uw.addEdge(l.start, l.end);
// PaintThing.debug.put("flibble", l);
}
}
out = uw.findAll();
// if (false)
for (Loop<Point2d> loop : out) {
for (Loopable<Point2d> pt : loop.loopableIterator()) {
Line prev = findSupporting(pt, 1), next = findSupporting(pt, -1);
if (prev != null && next != null) {
Point2d bestFit = prev.intersects(next, false);
if (bestFit != null && pt.get().distance(bestFit) < P.CON_TOL && // if nearer other ends of lines, don't use
bestFit.distanceSquared(prev.start) < bestFit.distanceSquared(prev.end) && bestFit.distanceSquared(next.end) < bestFit.distanceSquared(next.start)) {
pt.get().set(bestFit);
}
}
}
}
Iterator<Loop<Point2d>> lit = out.iterator();
// if (false)
while (lit.hasNext()) {
Loop<Point2d> loop = lit.next();
Loopable<Point2d> start = loop.start, current = start;
int size = loop.count();
boolean again;
do {
again = false;
Point2d a = current.getPrev().get(), b = current.get(), c = current.getNext().get();
Line ab = new Line(a, b), bc = new Line(b, c);
double angle = Anglez.dist(ab.aTan2(), bc.aTan2());
if (// corner filter moves corners to same point!
a.distanceSquared(b) < 0.0001 || b.distanceSquared(c) < 0.0001 || // nearly parallel, but small area removed
angle < 0.2 && Math.abs(Mathz.area(a, b, c)) < 50 * P.CON_TOL * P.CON_TOL) // ab.length() + bc.length() > TOL/2 &&
// angle > Math.PI - 0.1 ) // pointy corner
// a.distanceSquared(c) < 0.0001 )
{
current.getPrev().setNext(current.getNext());
current.getNext().setPrev(current.getPrev());
size--;
if (start == current)
loop.start = start = current.getPrev();
again = true;
current = current.getPrev();
} else
current = current.getNext();
} while ((again || current != start) && size > 2);
if (size <= 2)
lit.remove();
}
}
use of org.twak.utils.geom.UnionWalker in project chordatlas by twak.
the class GMLReader method main1.
public static void main1(String[] args) {
Graph2D g2 = readGMLToGraph(new File("/home/twak/data/langham/langham.gml"));
g2.removeInnerEdges();
Point2d offset = new Point2d();
int count = 0;
for (Point2d p : g2.map.keySet()) for (Line l : g2.get(p)) {
count++;
offset.add(l.start);
System.out.println(l);
}
offset.scale(1. / count);
System.out.println("offset is " + offset);
AffineTransform at = AffineTransform.getScaleInstance(-1, 1);
at.concatenate(AffineTransform.getTranslateInstance(-offset.x, -offset.y));
g2 = g2.apply(at);
UnionWalker uw = new UnionWalker();
for (Point2d a : g2.map.keySet()) {
for (Line l : g2.get(a)) {
uw.addEdge(l.start, l.end);
}
}
LoopL<Point2d> out = uw.findAll();
ObjDump obj = new ObjDump();
for (Loop<Point2d> loop : out) {
List<Point3d> pts = new ArrayList();
for (Point2d pt : loop) pts.add(new Point3d(pt.x, 0, pt.y));
obj.addFace(pts);
}
obj.dump(new File(Tweed.SCRATCH + "langham.obj"));
}
use of org.twak.utils.geom.UnionWalker in project chordatlas by twak.
the class GISGen method importMesh.
private void importMesh(int index) {
LoopL<Point3d> polies = blocks.get(index);
List<Vector2D> verts = polies.stream().flatMap(ll -> ll.streamAble()).map(x -> {
Line3d l = new Line3d(x.get(), x.getNext().get());
l.move(perp(l.dir(), EXPAND_MESH));
return new Vector2D(l.start.x, l.start.z);
}).collect(Collectors.toList());
double tol = 0.0001;
ConvexHull2D chull = null;
while (tol < 10) {
try {
chull = new MonotoneChain(false, tol).generate(verts);
tol = 1000;
} catch (ConvergenceException e) {
tol *= 10;
}
}
if (chull == null) {
System.out.println("unable to find hull");
return;
}
Loop<Point3d> hull = new Loop<Point3d>((Arrays.stream(chull.getLineSegments()).map(x -> new Point3d(x.getStart().getX(), 0, x.getStart().getY())).collect(Collectors.toList())));
File root = new File(Tweed.SCRATCH + "meshes" + File.separator);
int i = 0;
File l;
while ((l = new File(root, "" + i)).exists()) i++;
l.mkdirs();
File croppedFile = new File(l, CROPPED_OBJ);
boolean found = false;
for (Gen gen : tweed.frame.gens(MiniGen.class)) {
// minigen == optimised obj
((MiniGen) gen).clip(hull, croppedFile);
found = true;
}
if (!found)
for (Gen gen : tweed.frame.gens(MeshGen.class)) {
// obj == just import whole obj
ObjGen objg = (ObjGen) gen;
try {
Files.asByteSource(objg.getFile()).copyTo(Files.asByteSink(croppedFile));
objg.setVisible(false);
found = true;
} catch (IOException e) {
e.printStackTrace();
}
}
if (found) {
Graph2D g2 = new Graph2D();
polies.stream().flatMap(ll -> ll.streamAble()).forEach(x -> g2.add(new Point2d(x.get().x, x.get().z), new Point2d(x.getNext().get().x, x.getNext().get().z)));
g2.removeInnerEdges();
// new Plot (true, g2 );
UnionWalker uw = new UnionWalker();
for (Point2d p : g2.map.keySet()) for (Line line : g2.map.get(p)) uw.addEdge(line.end, line.start);
// new Plot (true, new ArrayList( uw.map.keySet()) );
Loopz.writeXZObj(uw.findAll(), new File(l, "gis.obj"), true);
Loopz.writeXZObj(Loopz.to2dLoop(polies, 1, null), new File(l, "gis_footprints.obj"), false);
BlockGen bg = new BlockGen(l, tweed, polies);
lastMesh.put(index, bg);
tweed.frame.addGen(bg, true);
tweed.frame.setSelected(bg);
} else
JOptionPane.showMessageDialog(tweed.frame(), "Failed to find mesh from minimesh or gml layers");
}
Aggregations