use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class GurobiSkelSolver method buildBadGeom.
private void buildBadGeom(boolean isContraint) throws GRBException {
countBadCorners = countBadEdges = 0;
for (HalfEdge e1 : edges) {
if (e1.over != null && e1.next.over != null)
if (e1.line().absAngle(e1.next.line()) > Math.PI - TweedSettings.settings.badGeomAngle) {
notBoth(e1, e1.next, isContraint, totalEdgeLength * 0.5);
countBadCorners++;
}
}
// if over both h
for (HalfFace f : mesh) {
Set<HalfEdge> togo = new HashSet<>();
for (HalfEdge e : f) togo.add(e);
while (!togo.isEmpty()) {
HalfEdge start = togo.iterator().next();
togo.remove(start);
// if (start.over == null)
// continue;
boolean parallelHasOverProfile = start.over == null ? false : ((SuperEdge) start.over).profLine != null, oppositeHasOverProfile = false;
Line sl = start.line();
LinearForm slf = new LinearForm(sl);
Map<HalfFace, HalfEdge> parallel = new HashMap<>();
parallel.put(start.over == null ? null : start.over.face, start);
Iterator<HalfEdge> tig = togo.iterator();
while (tig.hasNext()) {
HalfEdge e2 = tig.next();
HalfFace f2 = e2.over == null ? null : e2.over.face;
if (sl.absAngle(e2.line()) < 0.05) {
// one from each non-f face
parallel.put(f2, e2);
tig.remove();
parallelHasOverProfile |= (e2.over != null && ((SuperEdge) e2.over).profLine != null);
}
}
Map<HalfFace, HalfEdge> opposite = new HashMap();
tig = togo.iterator();
while (tig.hasNext()) {
HalfEdge e2 = tig.next();
HalfFace f2 = e2.over == null ? null : e2.over.face;
if (// e2l.lengthSquared() > 1 &&
sl.absAngle(e2.line()) > Math.PI - 0.3 && (slf.distance(e2.start) < 0.3 || slf.distance(e2.end) < 0.3)) {
opposite.put(f2, e2);
tig.remove();
oppositeHasOverProfile |= (e2.over != null && ((SuperEdge) e2.over).profLine != null);
}
}
if (parallelHasOverProfile && oppositeHasOverProfile)
continue;
for (HalfEdge e1 : parallel.values()) for (HalfEdge e2 : opposite.values()) {
notBoth(e1, e2, isContraint, totalEdgeLength * 0.5);
countBadEdges++;
}
}
}
print(countBadCorners + " " + countBadEdges);
}
use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class ResultsGen method readMesh.
private MeshFile readMesh(File f, boolean plot) {
System.out.println("reading solution " + f.getParentFile().getName());
try {
SolverState SS = (SolverState) new XStream().fromXML(f);
for (HalfFace hf : SS.mesh) plansIn.incrementAndGet();
SkelFootprint.postProcesss(SS);
for (HalfFace hf : SS.mesh) {
plansOut.incrementAndGet();
for (HalfEdge e : hf) {
SuperEdge se = (SuperEdge) e;
if (se.proceduralFacade != null) {
meshFacades.getAndIncrement();
}
}
}
if (plot)
SS.debugSolverResult();
return new MeshFile(SS.mesh, f);
} catch (Throwable t) {
t.printStackTrace();
return null;
}
}
use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class SkelFootprint method insert.
public static void insert(HalfMesh2 mesh, Line line, double softDist, boolean backwardsToo, boolean setLine) {
Vector2d dir = line.dir(), nDir = new Vector2d(dir);
nDir.negate();
double remaining = line.length();
for (HalfFace f : mesh.faces) {
if (f.contains(line.start)) {
HalfEdge n = f.fracture(line.start, nDir), p = f.fracture(line.start, dir);
if (n == null || p == null) {
System.err.println("geometry failure");
return;
}
HalfEdge next = p.next.over, prev = n.next.over;
HalfEdge dividing = f.split(mesh, n, p);
dividing.split(line.start);
((SuperEdge) dividing.next).profLine = setLine ? (SuperLine) line : null;
double l = dividing.next.length();
if (remaining < l) {
Point2d softStart = new Point2d(dir);
softStart.scale(remaining / dir.length());
softStart.add(line.start);
dividing.next.split(softStart);
((SuperEdge) dividing.next.next).profLine = null;
((SuperEdge) dividing.next.next.over).profLine = null;
double remSoftDist = softDist - dividing.next.next.line().length();
if (remSoftDist > 0)
fracture(mesh, next, dir, 0, remSoftDist, null, setLine);
} else if (next != null)
fracture(mesh, next, dir, remaining - l, softDist, line, setLine);
double softDistN = softDist - dividing.start.distance(line.start);
if (backwardsToo && softDistN > 0 && prev != null) {
fracture(mesh, prev, nDir, 0, softDistN, null, setLine);
}
return;
}
}
}
use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class SkelFootprint method findOcclusions.
private static void findOcclusions(HalfMesh2 mesh) {
int count = 0;
for (HalfFace hf : mesh.faces) for (HalfEdge e1 : hf.edges()) {
Line el1 = e1.line();
for (HalfFace hf2 : mesh.faces) {
for (HalfEdge e2 : hf2.edges()) if (e1 != e2) {
Line e2l = e2.line();
if (el1.distance(e2l) < 1 && e2l.absAngle(el1) > Math.PI * 0.7) // !el1.isOnLeft( e2l.fromPPram( 0.5 ) )
{
((SuperEdge) e1).occlusions.add(new LineHeight(el1.project(e2l.start, true), el1.project(e2l.end, true), 0, ((SuperFace) hf2).height));
count++;
}
}
}
}
System.out.println("found " + count + " occluding surfaces");
}
use of org.twak.utils.geom.HalfMesh2.HalfFace in project chordatlas by twak.
the class SkelFootprint method findRoofColor.
private static void findRoofColor(HalfMesh2 mesh) {
class Wrapper implements Clusterable {
double[] col;
public Wrapper(float[] col) {
this.col = new double[] { col[0], col[1], col[2] };
}
@Override
public double[] getPoint() {
return col;
}
}
for (HalfFace hf : mesh.faces) {
List<Wrapper> toCluster = new ArrayList();
SuperFace sf = (SuperFace) hf;
if (sf.colors == null || sf.colors.isEmpty()) {
float grey = (float) (Math.random() * 0.3 + 0.2);
sf.roofColor = new float[] { grey, grey, grey };
continue;
}
for (float[] v : sf.colors) toCluster.add(new Wrapper(v));
sf.colors = null;
DBSCANClusterer<Wrapper> cr = new DBSCANClusterer<>(0.2, 5);
List<Cluster<Wrapper>> results = cr.cluster(toCluster);
float[] col = new float[] { 0.3f, 0.3f, 0.3f };
try {
Cluster<Wrapper> biggest = results.stream().max((a, b) -> Double.compare(a.getPoints().size(), b.getPoints().size())).get();
col = new float[3];
for (Wrapper w : biggest.getPoints()) for (int i = 0; i < 3; i++) col[i] += (float) w.col[i];
int size = biggest.getPoints().size();
for (int i = 0; i < 3; i++) col[i] /= size;
} catch (NoSuchElementException e) {
}
sf.roofColor = col;
}
}
Aggregations