use of org.twak.utils.collections.Loop in project chordatlas by twak.
the class GreebleSkel method toPoly.
private static Loop<Point2d> toPoly(List<Point2d> left, PtInChain xyL) {
Loop<Point2d> lef = new Loop<>();
for (int i = 0; i <= xyL.prevPt; i++) lef.append(left.get(i));
if (xyL.frac > 0 && xyL.prevPt < left.size() - 1)
lef.append(new Line(left.get(xyL.prevPt), left.get(xyL.prevPt + 1)).fromPPram(xyL.frac));
lef.append(new Point2d(xyL.x, xyL.y));
lef.append(new Point2d(xyL.x, 0));
return lef;
}
use of org.twak.utils.collections.Loop in project chordatlas by twak.
the class GMLReader method readGML3d.
public static LoopL<Point3d> readGML3d(File in, DefaultGeocentricCRS targetCS, CoordinateReferenceSystem sourceCS) {
LoopL<Point3d> out = new LoopL();
try {
InputSource input = new InputSource(new FileInputStream(in));
new GMLReader(input, targetCS, sourceCS) {
Loop<Point3d> parent, poly;
public void newPoly(String name) {
parent = poly = new SuperLoop<Point3d>(name);
out.add(poly);
}
@Override
public void hole(int n) {
poly = new Loop<Point3d>();
parent.holes.add(poly);
}
public void addLine(double[] s, double[] e) {
poly.append(new Point3d(s[0], s[1], s[2]));
}
};
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("found " + out.size() + " polygons ");
return out;
}
use of org.twak.utils.collections.Loop 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.Loop in project chordatlas by twak.
the class GreebleHelper method findPerimeter.
public static LoopL<LPoint3d> findPerimeter(Face f) {
LoopL<LPoint3d> out = new LoopL<>();
for (Loop<SharedEdge> loop : f.edges) {
Loop<LPoint3d> lout = new Loop<>();
out.add(lout);
for (SharedEdge se : loop) {
String label;
Face other = se.getOther(f);
if (other == null || se.start.z < 0.1 && se.end.z < 0.1)
label = FLOOR_EDGE;
else if (GreebleEdge.isWall(other))
label = WALL_EDGE;
else
label = ROOF_EDGE;
Point3d pt = se.getStart(f);
if (pt != null)
lout.append(new LPoint3d(pt, label));
}
}
return out;
}
use of org.twak.utils.collections.Loop in project chordatlas by twak.
the class GreebleCGA method cga.
protected double cga(Loop<Point2d> rect, Matrix4d to3d, WallTag wallTag, MeshBuilder normalWall, MeshBuilder ground, Cache<float[], MeshBuilder> mbs, List<DRectangle> occlusions) {
double[] bounds = Loopz.minMax2d(rect);
GreebleGrid gg = new GreebleGrid(tweed, new MMeshBuilderCache());
DRectangle all = new DRectangle(bounds[0], bounds[2], bounds[1] - bounds[0], bounds[3] - bounds[2]);
// for (DRectangle d : occlusions)
// mbs.get( new float[] {1,1,0,1} ).add( d, to3d );
float[] windowColor = new float[] { 0.8f, .8f, 0.8f, 1 }, glassColor = new float[] { 0.3f, 0.3f, 1, 1 }, mouldingColor = new float[] { 0.7f, .7f, 0.7f, 1 };
double groundFloorHeight = 0;
List<DRectangle> floors = all.splitY(r -> splitFloors(r, 3, 2.5, 2));
for (int f = 0; f < floors.size(); f++) {
boolean isGround = f == 0 && wallTag.isGroundFloor;
DRectangle floor = floors.get(f);
MeshBuilder wall = isGround ? ground : normalWall;
List<DRectangle> edges = floor.splitX(r -> split3(r, 1, 1));
if (isGround)
groundFloorHeight = floor.height;
if (edges.size() != 3) {
wall.add(floor, to3d);
} else {
wall.add(edges.get(0), to3d);
wall.add(edges.get(edges.size() - 1), to3d);
DRectangle cen = edges.get(1);
if (cen.height < 1.8)
wall.add(cen, to3d);
else {
if (f == 0 && wallTag.isGroundFloor) {
List<DRectangle> groundPanel = cen.splitX(r -> split1(r, 0.9));
if (groundPanel.get(0).width < 0.7)
wall.add(groundPanel.get(0), to3d);
else if (wallTag.makeDoor) {
List<DRectangle> doorHeight = groundPanel.get(0).splitY(r -> split1(r, 2.2));
if (visible(doorHeight.get(0), occlusions))
greebleGrid.createDoor(doorHeight.get(0), to3d, wall, mbs.get(windowColor), wallTag.doorDepth);
else
wall.add(doorHeight.get(0), to3d);
if (doorHeight.size() > 1)
wall.add(doorHeight.get(1), to3d);
if (groundPanel.size() > 1) {
List<DRectangle> gWindowPanelH = groundPanel.get(1).splitX(r -> split3(r, 0.5, 0.0));
if (gWindowPanelH.size() > 2) {
wall.add(gWindowPanelH.get(0), to3d);
wall.add(gWindowPanelH.get(2), to3d);
List<DRectangle> gWindowPanelV = gWindowPanelH.get(1).splitY(r -> split3(r, 0.5, 0.5));
if (gWindowPanelV.size() > 2) {
wall.add(gWindowPanelV.get(0), to3d);
wall.add(gWindowPanelV.get(2), to3d);
if (visible(gWindowPanelV.get(1), occlusions))
greebleGrid.createWindow(gWindowPanelV.get(1), to3d, wall, mbs.get(windowColor), mbs.get(glassColor), wallTag.windowDepth, -1, -1, -1, 0.6, 0.9);
else
wall.add(gWindowPanelV.get(1), to3d);
} else
for (DRectangle d : gWindowPanelV) wall.add(d, to3d);
} else
for (DRectangle d : gWindowPanelH) wall.add(d, to3d);
}
} else
windowStrip(to3d, wallTag, mbs.get(windowColor), mbs.get(glassColor), wall, cen, false, occlusions, greebleGrid);
} else {
windowStrip(to3d, wallTag, mbs.get(windowColor), mbs.get(glassColor), wall, cen, f > 0 && f < floors.size() - 1 && wallTag.makeBalcony, occlusions, greebleGrid);
if (f == 1 && wallTag.isGroundFloor)
greebleGrid.moulding(to3d, new DRectangle(floor.x, floor.y, floor.width, 0.5), mbs.get(mouldingColor));
}
}
}
}
return groundFloorHeight;
}
Aggregations