use of org.twak.utils.Line in project chordatlas by twak.
the class LineSoup method partition.
public List<Set<Line>> partition(double d) {
List<Set<Line>> out = new ArrayList();
for (Line l : all) {
Set<Set<Line>> closeSets = new HashSet<>();
part: for (Set<Line> part : out) for (Line pl : part) if (pl.distance(l) < d) {
closeSets.add(part);
continue part;
}
Set<Line> best = null;
if (closeSets.isEmpty()) {
best = new HashSet<>();
out.add(best);
} else {
Iterator<Set<Line>> wtf = closeSets.iterator();
best = wtf.next();
while (wtf.hasNext()) {
Set<Line> togo = wtf.next();
best.addAll(togo);
out.remove(togo);
}
}
best.add(l);
}
return out;
}
use of org.twak.utils.Line in project chordatlas by twak.
the class SkelGen method findRange.
private static double[] findRange(SuperEdge se, Point2d s, Point2d e, Line backup) {
Line mf;
if (se.mini.isEmpty() || se.mini.get(0).imageFeatures == null) {
if (backup == null)
return null;
else
mf = backup;
} else
// todo: bad place for this method.
mf = se.mini.get(0).imageFeatures.mega.megafacade;
double mfL = mf.length();
return new double[] { mf.findPPram(s) * mfL, mf.findPPram(e) * mfL };
}
use of org.twak.utils.Line 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();
}
}
});
}
}
use of org.twak.utils.Line in project chordatlas by twak.
the class GreebleSkel method setToHeight.
private static PtInChain setToHeight(List<Point2d> chain, boolean left, double x2, double y2) {
double bestX = chain.get(0).x;
for (int i = 1; i < chain.size(); i++) {
Point2d p = chain.get(i - 1), n = chain.get(i);
bestX = left ? Math.max(p.x, bestX) : Math.min(p.x, bestX);
PtInChain first = new PtInChain(new Point2d(n), i, 0);
first.x = bestX;
if (Math.abs(n.y - y2) < 0.001) {
first.x = left ? Math.max(n.x, first.x) : Math.min(n.x, first.x);
return first;
}
Line pn = new Line(p, n);
if (n.y > y2) {
Point2d sec = new LinearForm(pn).intersect(new LinearForm(0, 1, y2));
if (sec == null)
return first;
sec.x = left ? Math.max(bestX, sec.x) : Math.min(bestX, sec.x);
return new PtInChain(sec, i - 1, pn.findPPram(sec));
}
}
return null;
}
use of org.twak.utils.Line 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"));
}
Aggregations