use of org.twak.utils.geom.HalfMesh2 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 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 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;
}
}
use of org.twak.utils.geom.HalfMesh2 in project chordatlas by twak.
the class SkelFootprint method buildFootprint.
public SolverState buildFootprint(List<Line> footprint, ProgressMonitor m, FeatureCache features, BlockGen blockGen) {
MultiMap<MegaFeatures, MFPoint> minis = features == null ? null : features.createMinis(blockGen);
Map<SuperEdge, double[]> profFit = new HashMap();
HalfMesh2 mesh = boundMesh(footprint);
globalProfs = null;
Collections.sort(footprint, megaAreaComparator);
for (Line l : footprint) {
MegaFacade mf = ((SuperLine) l).getMega();
if (mf.area < megaFacadeAreaThreshold)
break;
insert(mesh, l, 2, true, true);
if (m.isCanceled())
return null;
}
if (features != null)
fractureOnFeatures(minis, footprint, mesh);
m.setProgress(2);
if (!TweedSettings.settings.useGreedyProfiles) {
globalProfs = new ArrayList();
findProfiles(footprint, globalProfs);
calcProfFit(mesh, globalProfs, profFit, m);
}
if (FALSE && profMergeTol > 0)
mergeOnProfiles(mesh, footprint);
if (exitA)
return new SolverState(mesh, minis, globalProfs, profFit, footprint);
System.out.println("sampling...");
for (HalfFace f : mesh) meanModeHeightColor(Loopz.from(f), (SuperFace) f, blockGen);
pushHeightsToSmallFaces(mesh);
for (HalfFace f : new ArrayList<>(mesh.faces)) {
SuperFace sf = (SuperFace) f;
if (sf.height < heightCutoff)
sf.remove(mesh);
}
removeExposedFaces(mesh);
return new SolverState(mesh, minis, globalProfs, profFit, footprint);
}
use of org.twak.utils.geom.HalfMesh2 in project chordatlas by twak.
the class SkelFootprint method fractureOnFeatures.
private void fractureOnFeatures(MultiMap<MegaFeatures, MFPoint> minis, List<Line> footprint, HalfMesh2 mesh) {
for (MegaFeatures mf : minis.keySet()) pt: for (MFPoint pt : minis.get(mf)) {
if (!Mathz.inRange(mf.megafacade.findPPram(pt), 0, 1))
continue;
Vector2d dir = pt.mega.megafacade.dir();
dir.set(dir.y, -dir.x);
Point2d probe = new Point2d(dir);
probe.scale(2 / dir.length());
probe.add(pt);
for (// don't fracture near minifacade boundaries...we can't distinguish nice block bondaries
Point2d avoid : // don't fracture near minifacade boundaries...we can't distinguish nice block bondaries
pt.mega.megafacade.points()) if (avoid.distanceSquared(pt) < 4)
continue pt;
double bestDist = Double.MAX_VALUE;
for (HalfFace f : mesh.faces) for (HalfEdge e : f) if (e.line().dir().angle(dir) < 0.4) {
double dist = e.line().distance(probe);
if (dist < bestDist)
bestDist = dist;
}
if (bestDist > 0.3) {
Vector2d end = new Vector2d(dir);
end.scale(3 / end.length());
end.add(probe);
Vector2d start = new Vector2d(dir);
start.scale(0.5 / start.length());
start.add(pt);
Line extra = new Line(new Point2d(start), new Point2d(end));
SkelFootprint.insert(mesh, extra, 2, false, false);
}
}
}
Aggregations