use of org.twak.tweed.gen.ProfileGen.MegaFacade in project chordatlas by twak.
the class SkelFootprint method assignGreedyProfiles.
private static void assignGreedyProfiles(SolverState SS) {
Prof defaultProf = defaultProf(null);
for (HalfFace f : SS.mesh) for (List<HalfEdge> le : f.parallelFaces(0.1)) {
List<Prof> profs = new ArrayList();
for (HalfEdge he : le) {
SuperLine sl = ((SuperEdge) he).profLine;
if (sl != null) {
MegaFacade mf = sl.getMega();
if (mf != null)
profs.addAll(mf.getTween(he.start, he.end, 0));
}
}
Prof p = null;
if (!profs.isEmpty())
p = Prof.parameterize(profs);
else
p = defaultProf;
for (HalfEdge he : le) ((SuperEdge) he).prof = p;
}
}
use of org.twak.tweed.gen.ProfileGen.MegaFacade in project chordatlas by twak.
the class SkelFootprint method mergeOnProfiles.
private void mergeOnProfiles(HalfMesh2 mesh, List<Line> footprint) {
System.out.println("merging over profiles...");
TreeSet<HalfFace> togo = new TreeSet<>((HalfFace o1, HalfFace o2) -> Double.compare(o1.area(), o2.area()));
togo.addAll(mesh.faces);
int count = 0;
while (!togo.isEmpty()) {
HalfFace f = togo.pollFirst();
Cache<HalfEdge, MutableDouble> crossedBy = new Cach<>(e -> new MutableDouble(0));
for (HalfEdge e : f) {
SuperEdge se = (SuperEdge) e;
if (se.profLine != null) {
MegaFacade mf = ((SuperLine) se.profLine).mega;
if (mf != null)
for (Prof p : mf.getTween(se.start, se.end, 0)) {
Line proj = new Line(Pointz.to2(p.to3d(p.get(0))), Pointz.to2(p.to3d(p.get(p.size() - 1))));
for (HalfEdge e2 : f) {
SuperEdge se2 = (SuperEdge) e2;
if (se2.profLine == null && (se2.over == null || ((SuperEdge) se2.over).profLine == null) && e2.over != null && e2.line().intersects(proj) != null && Mathz.inRange(e2.line().absAngle(proj), 0.25 * Math.PI, 0.75 * Math.PI)) {
crossedBy.get(e2).d += TweedSettings.settings.profileHSampleDist;
}
}
}
}
}
count += crossedBy.cache.size();
Optional<Map.Entry<HalfEdge, MutableDouble>> longestO = crossedBy.cache.entrySet().stream().filter(//
e1 -> ((SuperEdge) e1.getKey()).profLine == null && e1.getValue().d > 0).max((e1, e2) -> Double.compare(e1.getValue().d, e2.getValue().d));
if (longestO.isPresent()) {
Map.Entry<HalfEdge, MutableDouble> longest = longestO.get();
if (longest.getValue().d > 0.6 * longest.getKey().length()) {
HalfFace tgf = longest.getKey().over.face;
togo.remove(tgf);
longest.getKey().face.merge(mesh, tgf);
((SuperFace) longest.getKey().face).mergeFrom((SuperFace) tgf);
togo.add(f);
}
}
}
System.out.println("found crossings " + count);
killDoubleEdges(mesh);
}
use of org.twak.tweed.gen.ProfileGen.MegaFacade in project chordatlas by twak.
the class VizSkelGen method toHalf.
private SuperFace toHalf(Loop<Point3d> loop) {
Cache<Point3d, Point2d> look = new Cach<>(x -> Pointz.to2(x));
HalfEdge last = null, first = null;
SuperFace out = new SuperFace();
for (Loopable<Point3d> edge : loop.loopableIterator()) {
SuperEdge e = new SuperEdge(look.get(edge.get()), look.get(edge.getNext().get()), null);
if (first == null)
first = e;
if (last != null)
last.next = e;
e.face = out;
// !
e.prof = null;
e.mini = Collections.EMPTY_LIST;
if (mode == Mode.Profiles)
for (Line l : footprint) {
if (l.absAngle(e.line()) < 0.1 && l.distance(e.start, true) < 1.5 && l.distance(e.end, true) < 1.5) {
SuperLine sl = (SuperLine) l;
MegaFacade mf = sl.getMega();
e.prof = findProf(e.start, e.end, sl, mf);
}
}
last = e;
}
last.next = first;
out.e = first;
SkelFootprint.meanModeHeightColor(Loopz.toXZLoop(loop), out, blockGen);
if (mode == Mode.CE) {
for (HalfEdge ee : out) {
SuperEdge e = (SuperEdge) ee;
Matrix4d m = new Matrix4d();
m.setIdentity();
e.prof = new Prof(m, new Vector3d());
e.prof.add(new Point2d(0, 0));
e.prof.add(new Point2d(0, out.height));
e.prof.add(new Point2d(-1, out.height + 1));
}
}
return out;
}
use of org.twak.tweed.gen.ProfileGen.MegaFacade in project chordatlas by twak.
the class SkelFootprint method profileRuns.
private static void profileRuns(SuperLine sl, MultiMap<SuperLine, List<Prof>> profSets) {
MegaFacade mf = sl.getMega();
Cache<Integer, Double> distance2Next = new Cache<Integer, Double>() {
@Override
public Double create(Integer i) {
Prof pc = mf.profiles.get(i), pn = mf.profiles.get(i + 1);
if (pc == null || pn == null)
return 1e6;
return pc.distance(pn, true, false, false);
}
};
// i -> mf.profiles.get( i ).distance( mf.profiles.get(i+1), true ));
int start = mf.hExtentMin;
for (int i = mf.hExtentMin; i < mf.hExtentMax; i++) {
if (distance2Next.get(i) > 4 || i == mf.hExtentMax - 1) {
// if ( (Math.random() > 0.95 || i == mf.hExtentMax - 1) ){//0.5 / ProfileGen.HORIZ_SAMPLE_DIST) {
if (i - start > 0.5 / TweedSettings.settings.profileHSampleDist) {
List<Prof> lp = IntStream.range(start, i + 1).mapToObj(p -> mf.profiles.get(p)).filter(p -> p != null).collect(Collectors.toList());
if (lp != null && !lp.isEmpty())
profSets.put(sl, lp);
}
start = i + 1;
// i++;
// }
}
}
// System.out.println( (mf.hExtentMax - mf.hExtentMin)+ " mm " + min+ " / " + max +" found " + profSets.size() );
}
use of org.twak.tweed.gen.ProfileGen.MegaFacade 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);
}
Aggregations