use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class SkelFootprint method calcProfFit.
// private static Prof boringProf( double h ) {
// Prof prof = Prof.buildProfile( new Line3d( new Point3d( 0, 0, 0 ), new Point3d( 1, 0, 0 ) ), new Point3d( 0, 0, 0 ) );
// prof.add(new Point2d (0,0));
// prof.add(new Point2d (0,h));
// return prof;
// }
private void calcProfFit(HalfMesh2 mesh, List<Prof> globalProfs, Map<SuperEdge, double[]> out, ProgressMonitor m) {
System.out.println("Building F...");
boolean[] used = new boolean[globalProfs.size()];
Map<SuperEdge, double[]> tmp = new HashMap();
double[] noData = new double[globalProfs.size()];
Arrays.fill(noData, 0);
noData[0] = -1;
used[0] = true;
for (int i = 0; i < mesh.faces.size(); i++) {
// System.out.println( "calculating profile fit for face " + i + "/" + mesh.faces.size() );
HalfFace f = mesh.faces.get(i);
for (HalfEdge e : f) {
double[] fits = new double[globalProfs.size()];
for (int g = 0; g < fits.length; g++) {
Double d = meanDistance(globalProfs.get(g), (SuperEdge) e);
if (d == null || Double.isNaN(d)) {
fits = noData;
break;
} else
fits[g] = d;
}
tmp.put((SuperEdge) e, fits);
used[Arrayz.min(fits)] = true;
}
if (m.isCanceled())
return;
}
Arrays.fill(used, true);
int count = 0;
for (boolean u : used) if (u)
count++;
for (Map.Entry<SuperEdge, double[]> e : tmp.entrySet()) {
double[] fits = new double[count];
int c = 0;
for (int i = 0; i < e.getValue().length; i++) if (used[i])
fits[c++] = e.getValue()[i];
out.put(e.getKey(), fits);
}
for (int g = globalProfs.size() - 1; g >= 0; g--) if (!used[g])
globalProfs.remove(g);
}
use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class SkelFootprint method dbgShowProfiles.
private void dbgShowProfiles(HalfMesh2 mesh, List<Prof> globalProfs, Map<SuperEdge, double[]> profFit, String name) {
Node n = new Node();
Jme3z.removeAllChildren(n);
int colI = 0;
for (HalfFace f : mesh) {
ColorRGBA col = Jme3z.toJme(Rainbow.getColour(colI++));
colI = colI % 6;
Material mat = new Material(tweed.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
mat.setColor("Diffuse", col);
mat.setColor("Ambient", col);
mat.setBoolean("UseMaterialColors", true);
if (true) {
Loop<Point3d> loop = new Loop<>();
for (HalfEdge e : f) loop.append(new Point3d(e.start.x, 0, e.start.y));
MeshBuilder mb = new MeshBuilder();
mb.add(loop.singleton(), null, false);
Geometry g = new Geometry("floorplan", mb.getMesh());
g.setMaterial(mat);
n.attachChild(g);
}
for (HalfEdge e : f) {
SuperEdge se = (SuperEdge) e;
Prof bestProf = null;
if (globalProfs == null)
bestProf = se.prof;
else {
// if (se.profLine != null) {
//
// SuperLine sl = ((SuperLine)se.profLine);
// MegaFacade mf = (MegaFacade) sl.properties.get( MegaFacade.class.getName() );
//
// List<Prof> pfs = mf.getTween( se.start, se.end, 0.3 );
//
// if (!pfs.isEmpty())
// bestProf = Prof.parameterize( sl, pfs );
// else {
// bestProf = clean.get( 0 );
// double bestScore = Double.MAX_VALUE;
//
// for ( Prof c : clean ) {
//
// double score = 0;
// boolean good = false;
// for ( Prof r : mf.getTween( se.start, se.end, 0.3 ) ) {
// score += c.distance( r, true, false, true );
// good = true;
// }
// if ( good && score < bestScore ) {
// bestScore = score;
// bestProf = c;
// }
//
// }
// }
//
//
// }
// if (bestProf)
// ((SuperLine))
//
double[] fitV = profFit.get(se);
if (fitV == null)
continue;
double bestScore = Double.MAX_VALUE;
for (int ii = 0; ii < fitV.length; ii++) {
double d = fitV[ii];
if (d < bestScore) {
bestScore = d;
bestProf = globalProfs.get(ii);
}
}
//
// double bestScore = Double.MAX_VALUE;
//
// for ( int ii = 0; ii < fitV.length; ii++ ) {
// double d = fitV[ ii ];
// if ( d < bestScore ) {
// bestScore = d;
// bestProf = globalProfs.get( ii );
// }
// }
// if (false)
// se.prof = bestProf;
}
if (bestProf != null) {
Geometry g = new Geometry();
Point3d cen = Pointz.to3(se.line().fromPPram(0.5));
Prof goodOrientation = Prof.buildProfile(Pointz.to3(se.line()), cen);
for (Point2d p : bestProf) goodOrientation.add(p);
g.setMesh(goodOrientation.renderStrip(1.5, cen));
g.setMaterial(mat);
n.attachChild(g);
g.updateGeometricState();
g.updateModelBound();
}
}
}
skelGen.tweed.frame.addGen(new JmeGen(name, tweed, n), false);
}
use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class SolverState method debugSolverResult.
public void debugSolverResult() {
new Plot(mesh).add(miniPainter()).add(new ICanPaint() {
@Override
public void paint(Graphics2D g, PanMouseAdaptor ma) {
Set<HalfEdge> seen = new HashSet<>();
Color tWhite = new Color(255, 255, 255, 150);
if (!seen.isEmpty())
for (HalfFace f : mesh) {
for (HalfEdge e : f) {
int i = ((SuperEdge) e).profI;
// if (i == -1)
// continue;
Point2d loc = e.line().fromPPram(0.5);
String s = "" + i;
int offset = e.start.x < e.end.x ? -10 : 10;
seen.add(e);
Rectangle2D b = g.getFontMetrics().getStringBounds(s, g);
b = new Rectangle2D.Double(0, 0, b.getWidth() + 4, b.getHeight());
g.setColor(tWhite);
g.fillRect(ma.toX(loc.x) - (int) (b.getWidth() / 2), offset + ma.toY(loc.y) - (int) (b.getHeight() / 2), (int) (b.getWidth()), (int) (b.getHeight()));
g.setColor(Color.gray);
g.drawString(s, ma.toX(loc.x) - (int) (b.getWidth() / 2) + 2, offset + ma.toY(loc.y) + (int) (b.getHeight() / 2) - 3);
}
}
}
});
}
use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class SolverState method save.
public void save(File location, boolean clean) {
try {
if (clean)
for (HalfFace f : mesh) {
for (HalfEdge e : f) {
SuperEdge se = (SuperEdge) e;
if (se.profLine != null)
((SuperLine) se.profLine).mega = null;
}
}
System.out.print("writing state to " + location + " ...");
location.getAbsoluteFile().getParentFile().mkdirs();
new XStream().toXML(this, new FileOutputStream(location));
System.out.println("done!");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class GurobiSkelSolver method solve.
public void solve() {
try {
for (HalfFace f : mesh.faces) for (HalfEdge e : f.edges()) {
edges.add(e);
totalEdgeLength += e.length();
}
print("total edge length " + totalEdgeLength);
progress.setProgress((int) (Math.random() * 90));
buildProblem();
model.getEnv().set(GRB.DoubleParam.TimeLimit, GRB.INFINITY);
long time = System.currentTimeMillis();
new Thread(() -> {
while (!gurobiDone) {
try {
Thread.sleep(300);
if ((System.currentTimeMillis() - time) / 1000 > maxTimeSecs) {
print("time's up");
model.terminate();
progress.close();
return;
}
} catch (InterruptedException e1) {
}
progress.setProgress((int) (Math.random() * 90));
if (progress.isCanceled()) {
print("user cancelled");
model.terminate();
}
}
progress.setProgress(100);
}).start();
try {
String file = Tweed.SCRATCH + "problem_" + System.currentTimeMillis() + ".mps";
new File(file).getParentFile().mkdirs();
model.write(file);
model.optimize();
} finally {
gurobiDone = true;
progress.setProgress(100);
}
print("time " + (System.currentTimeMillis() - time) / 1000. + " seconds");
if (model.get(GRB.IntAttr.Status) == GRB.Status.INFEASIBLE) {
print("Can't solve; won't solve");
return;
}
for (HalfFace f : mesh.faces) ((SuperFace) f).classification = index(faceInfo.get(f).color);
if (minis != null)
for (MegaFeatures mf : minis.keySet()) {
if (mega2clusters.containsKey(mf))
for (MiniPtCluster pt : mega2clusters.get(mf)) {
for (Map.Entry<MFPoint, MiniSelectEdge> selectPt : pt.entrySet()) {
for (Map.Entry<HalfEdge, GRBVar> selectEdge : selectPt.getValue().edge.entrySet()) {
if (selectEdge.getValue().get(GRB.DoubleAttr.X) > 0.5) {
HalfEdge e = selectEdge.getKey();
selectPt.getKey().selectedEdge = e;
selectPt.getKey().sameCluster = pt.keySet();
if (e.over != null && e.next.over == null) {
for (MFPoint p : pt.keySet()) ((SuperEdge) e.next).addMini(p.right);
for (MFPoint p : pt.keySet()) ((SuperEdge) e.over.findBefore()).addMini(p.left);
}
if (e.over == null && e.next.over == null) {
Line parallel = selectPt.getKey().mega.megafacade;
if (parallel.absAngle(e.line()) < parallel.absAngle(e.next.line()))
for (MFPoint p : pt.keySet()) ((SuperEdge) e).addMini(p.left);
else
for (MFPoint p : pt.keySet()) ((SuperEdge) e.next).addMini(p.right);
}
}
}
}
}
}
if (false)
for (HalfEdge he : edges) {
if (he.over != null && he.next.over == null) {
// face comes to boundary
boolean viz = false;
EdgeVars ei = edgeInfo.get(he);
if (ei.edgeNoMini != null) {
viz = true;
}
if (viz)
PaintThing.debug.put("dd", new Point2d(he.end));
}
}
if (globalProfs != null)
for (HalfEdge e : edges) {
EdgeVars ei = edgeInfo.get(e);
GRBVar plot = ei.debug;
if (plot != null) {
// && plot.get(GRB.DoubleAttr.X) > 0.5 ) {
Point2d o = new Point2d(e.end);
PaintThing.debug.put(1, o);
}
int p = index(ei.profile);
((SuperEdge) e).profI = p;
((SuperEdge) e).prof = p < 0 ? null : globalProfs.get(p);
}
dumpModelStats(edges);
model.getEnv().dispose();
model.dispose();
} catch (GRBException e) {
print("Error code: " + e.getErrorCode() + ". " + e.getMessage());
e.printStackTrace();
}
}
Aggregations