use of org.twak.utils.geom.HalfMesh2.HalfEdge 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.HalfEdge 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.HalfEdge in project chordatlas by twak.
the class SkelFootprint method dbgCountProfileEdges.
private void dbgCountProfileEdges(SolverState SS) {
Set<SuperLine> used = new HashSet<>();
for (HalfFace f : SS.mesh) for (HalfEdge e : f) {
used.add(((SuperEdge) e).profLine);
}
used.remove(null);
System.out.println("Input sweep edges: " + used.size());
}
use of org.twak.utils.geom.HalfMesh2.HalfEdge in project chordatlas by twak.
the class SkelFootprint method meanModeHeightColor.
public static void meanModeHeightColor(Loop<Point2d> pts, SuperFace sf, BlockGen blockgen) {
double[] minMax = Loopz.minMax2d(pts);
double sample = 2;
double missCost = 30;
if (sf.colors != null)
sf.colors.clear();
sf.heights.clear();
int insideGIS = 0, outsideGIS = 0;
LoopL<Point2d> gis = blockgen.profileGen.gis;
gis = Loopz.removeInnerEdges(gis);
gis = Loopz.removeNegativeArea(gis, -1);
gis = Loopz.mergeAdjacentEdges(gis, 1, 0.05);
for (double x = minMax[0]; x < minMax[1]; x += sample) for (double y = minMax[2]; y < minMax[3]; y += sample) {
x += Math.random() * sample - sample / 2;
y += Math.random() * sample - sample / 2;
Point2d p2d = new Point2d(x, y);
if (Loopz.inside(p2d, pts)) {
CollisionResults results = new CollisionResults();
blockgen.gNode.collideWith(new Ray(Jme3z.toJmeV(x, 0, y), UP), results);
CollisionResult cr = results.getFarthestCollision();
double height;
if (cr != null) {
height = cr.getDistance();
sf.heights.add(height);
if (sf != null && sf.colors != null) {
ColorRGBA col = getColor(cr.getGeometry(), cr.getContactPoint(), cr.getTriangleIndex(), blockgen.tweed);
sf.colors.add(new float[] { col.r, col.g, col.b });
}
}
if (Loopz.inside(p2d, gis)) {
insideGIS++;
// PaintThing.debug( Color.yellow, 1, p2d);
} else {
outsideGIS++;
// PaintThing.debug( Color.green, 1, p2d);
}
}
}
if (sf.heights.size() < 2)
sf.height = -Double.MAX_VALUE;
else if (TweedSettings.settings.useGis && insideGIS < gisInterior * outsideGIS)
sf.height = -missCost;
else {
sf.updateHeight();
}
sf.maxProfHeights = new ArrayList();
for (HalfEdge e : sf) {
SuperEdge se = ((SuperEdge) e);
if (se.profLine != null)
for (Prof p : ((SuperLine) se.profLine).getMega().getTween(e.start, e.end, 0.3)) sf.maxProfHeights.add(p.get(p.size() - 1).y);
}
}
use of org.twak.utils.geom.HalfMesh2.HalfEdge 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