use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class SolverState method miniPainter.
public ICanPaint miniPainter() {
return new ICanPaint() {
@Override
public void paint(Graphics2D g, PanMouseAdaptor ma) {
// for ( MegaFeatures f : SS.minis.keySet() ) {
//
// for ( MFPoint mfp : SS.minis.get( f ) ) {
// Line l = mfp.image.mega.megafacade;
//
// spreadImages( g, ma, l, mfp, Listz.from( mfp.left, mfp.right ) );
//
// }
// }
// if (SS.minis == null)
int brake = 100;
for (HalfFace f : mesh) {
for (HalfEdge e : f) {
if (e.over != null)
continue;
if (brake-- < 0)
break;
SuperEdge se = (SuperEdge) e;
if (se.mini == null)
continue;
List<MiniFacade> mfs = new ArrayList(se.mini);
// while (mfs .size() < 2)
// mfs.add(null);
spreadImages(g, ma, se.line(), se.line().fromPPram(0.5), mfs);
}
}
int i = 0;
if (minis != null)
for (MegaFeatures f : minis.keySet()) {
// PaintThing.paint (f.megafacade, g, ma);
DumbCluster1D<MFPoint> res = GurobiSkelSolver.clusterMinis(f, minis);
Vector2d dir = f.megafacade.dir();
Vector2d out = new Vector2d(dir);
out.set(-out.y, out.x);
out.scale(ma.toZoom(2) / out.length());
for (Cluster<MFPoint> c : res) {
g.setColor(Rainbow.getColour(i++));
for (MFPoint mfp : c.things) {
Point2d pt = new Point2d(mfp);
pt.add(out);
g.setStroke(new BasicStroke(0.2f));
PaintThing.paint(pt, g, ma);
g.setStroke(new BasicStroke(0.2f));
for (HalfEdge e : GurobiSkelSolver.findNear(f.megafacade, mfp, mesh)) g.drawLine(ma.toX(pt.x), ma.toY(pt.y), ma.toX(e.end.x), ma.toY(e.end.y));
if (mfp.selectedEdge != null) {
g.setStroke(new BasicStroke(2f));
g.drawLine(ma.toX(pt.x), ma.toY(pt.y), ma.toX(mfp.selectedEdge.end.x), ma.toY(mfp.selectedEdge.end.y));
}
}
}
}
g.setStroke(new BasicStroke(1));
}
private void spreadImages(Graphics2D g, PanMouseAdaptor ma, Line sel, Point2d cen, List<MiniFacade> mfs) {
Vector2d perp = sel.dir();
perp.set(-perp.y, perp.x);
perp.normalize();
for (int i = 0; i < mfs.size(); i++) {
MiniFacade mf = mfs.get(i);
Vector2d p2 = new Vector2d(perp);
p2.scale((i + 1) * 10);
p2.add(cen);
if (mf == null) {
g.setColor(Color.black);
g.fillRect(ma.toX(p2.x - 1), ma.toY(p2.y - 3), ma.toZoom(2), ma.toZoom(6));
continue;
}
double w = mf.width * 0.1;
double h = mf.height * 0.1;
mf.paintImage(g, ma, p2.x - w, p2.y - h, p2.x + w, p2.y + h);
}
}
};
}
use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class SkelFootprint method killDoubleEdges.
public static void killDoubleEdges(HalfMesh2 mesh) {
for (HalfFace f : mesh) {
boolean iDidSomething;
do {
iDidSomething = false;
for (HalfEdge e : f) {
if (e.next.over == e) {
e.dissolve(mesh);
iDidSomething = true;
}
}
} while (iDidSomething);
}
}
use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class SkelFootprint method pushHeightsToSmallFaces.
private static void pushHeightsToSmallFaces(HalfMesh2 mesh) {
for (HalfFace f : mesh.faces) {
SuperFace sf = (SuperFace) f;
if (sf.height == -Double.MAX_VALUE) {
// || sf.area() < 1 ) {
double bestLength = -Double.MAX_VALUE;
SuperFace bestFace = null;
overProfile: for (boolean overProfiles : new boolean[] { false, true }) {
for (HalfEdge e2 : f.edges()) {
double len = e2.length();
if (len > bestLength && e2.over != null)
if (overProfiles || ((SuperEdge) e2).profLine == null && ((SuperEdge) e2.over).profLine == null) {
SuperFace sf2 = (SuperFace) e2.over.face;
if (sf2.height != -Double.MAX_VALUE) {
bestFace = sf2;
bestLength = len;
}
}
}
if (bestFace != null) {
sf.height = bestFace.height;
break overProfile;
}
}
}
}
}
use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class SkelFootprint method mergeSameClassification.
public static void mergeSameClassification(HalfMesh2 mesh) {
// goal is to encode a polygon with holes as a single perimeter loop that backtracks along itself....
Set<HalfEdge> edges = new LinkedHashSet();
for (HalfFace hf : mesh.faces) for (HalfEdge e2 : hf.edges()) if (e2.over != null && ((SuperFace) e2.face).classification == ((SuperFace) e2.over.face).classification)
edges.add(e2);
edges: while (!edges.isEmpty()) {
HalfEdge e = edges.iterator().next();
if (e.over == null) {
// debug condition
edges.remove(e);
continue;
}
HalfFace a = e.face, b = e.over.face;
if (a == b) {
edges.remove(e);
continue;
}
{
HalfEdge start = null;
while (// set a's edge to be one that we won't fuck with
a.e.over != null && a.e.over.face == b) {
if (a.e == start) {
for (HalfEdge f : a.edges()) {
edges.remove(f);
edges.remove(f.over);
if (f.next.over.next.over != f) {
HalfEdge beforeBreak = f.over.findBefore();
beforeBreak.next = f.next.over.next;
b.e = beforeBreak;
}
}
((SuperFace) b).mergeFrom((SuperFace) a);
mesh.faces.remove(a);
continue edges;
}
if (start == null)
start = a.e;
a.e = a.e.next;
}
}
for (HalfEdge oeb : a.edges()) {
HalfEdge oe = oeb.next;
edges.remove(oe);
if ((oeb.over == null || oeb.over.face != b) && oe.over != null && oe.over.face == b) {
edges.remove(oe.over);
HalfEdge le = oe;
while (le.next.over != null && le.next.over.face == b && le.next.over.next == le.over) {
le = le.next;
edges.remove(le);
edges.remove(le.over);
}
le.over.findBefore().next = le.next;
oeb.next = oe.over.next;
((SuperFace) a).mergeFrom((SuperFace) b);
mesh.faces.remove(b);
for (HalfEdge e2 : a.edges()) {
if (e2.over != null && e2.over.face == b) {
edges.remove(e2);
edges.remove(e2.over);
}
e2.face = a;
}
// only remove the first boundary between a and b
break;
}
}
}
}
use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class SkelFootprint method updateHeights.
private static void updateHeights(HalfMesh2 mesh) {
for (HalfFace hf : mesh) {
SuperFace sf = (SuperFace) hf;
sf.height = sf.heights.stream().sorted().collect(new ModeCollector(0.5));
if (Double.isNaN(sf.height))
sf.height = 0;
}
}
Aggregations