Search in sources :

Example 1 with Feature

use of org.twak.viewTrace.facades.MiniFacade.Feature in project chordatlas by twak.

the class Regularizer method goDebug.

public List<MiniFacade> goDebug(List<MiniFacade> in, double debugFrac, MegaFeatures megaFeatures) {
    miniFacadesUsed += in.size();
    regularised++;
    for (MiniFacade mf : in) if (mf.imageFeatures != null)
        seenImages.add(mf.imageFeatures.ortho);
    if (in.isEmpty())
        return Collections.singletonList(gridMini());
    System.out.println("starting to regularize " + in.size() + " facades...");
    in = augmentWithTween(in, megaFeatures);
    System.out.println(" adding tween for " + in.size() + " facades");
    double alpha = 0.2;
    List<MiniFacade> out;
    if (true)
        out = newFromWindows(in);
    else
        out = in.stream().map(mf -> new MiniFacade(mf)).collect(Collectors.toList());
    System.out.println(" included grids for " + out.size() + " facades...");
    if (debugFrac < 0) {
        out.add(0, new MiniFacade());
        return out;
    }
    alignMFs(out);
    if (debugFrac == 0) {
        out.add(0, new MiniFacade());
        return out;
    }
    for (MiniFacade mf : out) {
        assignFeaturesToWindows(mf.getRects(Feature.WINDOW, Feature.SHOP).stream().collect(Collectors.toList()), mf.rects);
        mf.rects.get(Feature.CORNICE).clear();
        mf.rects.get(Feature.BALCONY).clear();
        mf.rects.get(Feature.SILL).clear();
        mf.rects.get(Feature.GRID).clear();
    }
    for (MiniFacade mf : out) {
        mergeRemoveSmall(mf);
        mergeRemoveSimilar(mf);
    }
    for (Feature f : Feature.values()) for (MiniFacade mf : out) mf.rects.get(f).stream().forEach(r -> r.f = f);
    for (int i = 0; i < 50 * debugFrac; i++) {
        for (MiniFacade mf : out) for (Feature f : toReg) cluster1(mf.getRects(f), 1, alpha, Bounds.XMIN, Bounds.XMAX, Bounds.YMIN, Bounds.YMAX);
        // for (MiniFacade mf : out)
        // cluster1 ( mf.getRects(toReg), 1,  alpha, Bounds.XMIN, Bounds.XMAX, Bounds.YMIN, Bounds.YMAX);
        List<FRect> allRects = new ArrayList<>();
        for (MiniFacade mf : out) for (Feature f : toReg) allRects.addAll(mf.rects.get(f));
        for (Feature f : toReg) {
            List<FRect> allF = out.stream().flatMap(mf -> mf.rects.get(f).stream()).collect(Collectors.toList());
            cluster1(allF, 0.5, alpha, Bounds.WIDTH, Bounds.HEIGHT);
        }
        cluster1(allRects, 0.3, alpha, Bounds.XMIN, Bounds.XMAX, Bounds.YMIN, Bounds.YMAX);
        if (i % 5 == 0)
            for (MiniFacade mf : out) findNeighbours(mf.getRects(Feature.WINDOW));
        for (Dir dir : Dir.values()) clusterDeltas(allRects, 0.2, alpha, dir);
        for (MiniFacade mf : out) {
            for (FRect d : mf.rects.get(Feature.DOOR)) constrainDoor(mf, d, alpha);
            for (FRect m : mf.rects.get(Feature.MOULDING)) constrainMoulding(mf, m, alpha);
        }
        for (MiniFacade mf : out) {
            for (Feature f : toReg) {
                Iterator<FRect> rit = mf.rects.get(f).iterator();
                while (rit.hasNext()) {
                    FRect r = rit.next();
                    if (r.width <= 0.4 || r.height <= 0.4)
                        rit.remove();
                    else
                        for (FRect n : r.adjacent) if (n != null && similar(n, r)) {
                            n.attached.putAll(r.attached);
                            rit.remove();
                            break;
                        }
                }
            }
        }
    }
    if (debugFrac < 1) {
        out.add(0, new MiniFacade());
        return out;
    }
    for (MiniFacade mf : out) {
        findOuters(mf);
        mergeRemoveSmall(mf);
    }
    ids = 0;
    for (// find ids...starting with the biggest
    Feature f : // find ids...starting with the biggest
    toReg) {
        List<Pair<MiniFacade, FRect>> allRects = new ArrayList<>();
        for (MiniFacade mf : out) for (FRect r : mf.rects.get(f)) allRects.add(new Pair<>(mf, r));
        Collections.sort(allRects, new Comparator<Pair<MiniFacade, FRect>>() {

            @Override
            public int compare(Pair<MiniFacade, FRect> a_, Pair<MiniFacade, FRect> b_) {
                FRect a = a_.second(), b = b_.second();
                if (a.gridCoords != null && b.gridCoords == null)
                    return -1;
                if (b.gridCoords != null && a.gridCoords == null)
                    return 1;
                if (a.gridCoords != null && b.gridCoords != null) {
                    int out = -Integer.compare(countCoords(a.gridCoords), countCoords(b.gridCoords));
                    if (out != 0)
                        return out;
                }
                return Double.compare(a.area(), b.area());
            }

            private int countCoords(int[] gridCoords) {
                int out = 0;
                for (int i : gridCoords) if (i != -Integer.MAX_VALUE)
                    out++;
                return out;
            }
        });
        for (Pair<MiniFacade, FRect> pair : allRects) {
            FRect w = pair.second();
            if (w.id == -1)
                findId(w, f, out, pair.first(), ids++);
        }
    }
    out.add(0, combine(out));
    totalFeature += out.get(0).getRects(Feature.values()).size();
    System.out.println("done");
    return out;
}
Also used : DumbCluster1D(org.twak.utils.DumbCluster1D) Cache2(org.twak.utils.Cache2) OptionalDouble(java.util.OptionalDouble) HashMap(java.util.HashMap) CountThings(org.twak.utils.collections.CountThings) Pair(org.twak.utils.Pair) TreeSet(java.util.TreeSet) MapMapList(org.twak.utils.collections.MapMapList) ArrayList(java.util.ArrayList) Arrayz(org.twak.utils.collections.Arrayz) HashSet(java.util.HashSet) Map(java.util.Map) Mathz(org.twak.utils.Mathz) Streamz(org.twak.utils.collections.Streamz) LinkedHashSet(java.util.LinkedHashSet) InAxDouble(org.twak.utils.streams.InAxDouble) Iterator(java.util.Iterator) ImageFeatures(org.twak.tweed.gen.FeatureCache.ImageFeatures) MultiMap(org.twak.utils.collections.MultiMap) Set(java.util.Set) Vector2d(javax.vecmath.Vector2d) MegaFeatures(org.twak.tweed.gen.FeatureCache.MegaFeatures) Collectors(java.util.stream.Collectors) File(java.io.File) Cluster(org.twak.utils.DumbCluster1D.Cluster) Point2d(javax.vecmath.Point2d) List(java.util.List) DumbCluster1DImpl(org.twak.utils.DumbCluster1DImpl) Bounds(org.twak.utils.geom.DRectangle.Bounds) DRectangle(org.twak.utils.geom.DRectangle) Comparator(java.util.Comparator) Collections(java.util.Collections) Feature(org.twak.viewTrace.facades.MiniFacade.Feature) ArrayList(java.util.ArrayList) Feature(org.twak.viewTrace.facades.MiniFacade.Feature) Pair(org.twak.utils.Pair)

Example 2 with Feature

use of org.twak.viewTrace.facades.MiniFacade.Feature in project chordatlas by twak.

the class Regularizer method findOuters.

private void findOuters(MiniFacade mf) {
    mf.outers.clear();
    for (Feature f : Feature.values()) {
        if (f != Feature.WINDOW)
            continue;
        Set<FRect> togo = new LinkedHashSet(mf.rects.get(f));
        while (!togo.isEmpty()) {
            AOuter outer = new AOuter(f);
            FRect first = findBest(togo);
            Set<FRect> neighbours = new TreeSet<>(FRect.comparatorArea(false));
            neighbours.add(first);
            while (!neighbours.isEmpty()) {
                FRect n = neighbours.iterator().next();
                if (!togo.contains(n)) {
                    neighbours.remove(n);
                    continue;
                }
                if (outer.easyAdd(n)) {
                    neighbours.remove(n);
                    add(togo, neighbours, n);
                } else {
                    n = findBest(neighbours);
                    neighbours.remove(n);
                    if (outer.extend(n))
                        add(togo, neighbours, n);
                }
            }
            if (outer.building.findPositions().values().size() >= 2) {
                outer.done();
                mf.outers.add(outer);
                // re-ground the grid coordinate system
                CountThings<Integer> xes = new CountThings<>(), yes = new CountThings<>();
                for (int x = 0; x < outer.elements.length; x++) for (int y = 0; y < outer.elements[0].length; y++) if (outer.elements[x][y] != null) {
                    xes.count(x);
                    yes.count(y);
                }
                double halfAvgX = 0.5 * xes.getSize() / xes.counts.cache.keySet().size(), halfAvgY = 0.5 * yes.getSize() / yes.counts.cache.keySet().size();
                List<Integer> rows = new ArrayList(xes.counts.cache.keySet());
                Collections.sort(rows);
                int xMin = rows.stream().filter(row -> xes.total(row) > halfAvgX).findFirst().get();
                Collections.reverse(rows);
                int xMax = rows.stream().filter(row -> xes.total(row) > halfAvgX).findFirst().get();
                List<Integer> cols = new ArrayList(yes.counts.cache.keySet());
                int yMin = cols.stream().filter(col -> yes.total(col) > halfAvgY).findFirst().get();
                Collections.reverse(cols);
                int yMax = cols.stream().filter(col -> yes.total(col) > halfAvgY).findFirst().get();
                for (int x = 0; x < outer.elements.length; x++) for (int y = 0; y < outer.elements[0].length; y++) {
                    FRect w = outer.elements[x][y];
                    if (w == null)
                        continue;
                    w.gridCoords = new int[] { w.xi - xMin, xMax - w.xi, w.yi - yMin, yMax - w.yi };
                    if (mf.softLeft)
                        w.gridCoords[0] = -Integer.MAX_VALUE;
                    if (mf.softRight)
                        w.gridCoords[1] = -Integer.MAX_VALUE;
                }
            }
        }
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ArrayList(java.util.ArrayList) Feature(org.twak.viewTrace.facades.MiniFacade.Feature) TreeSet(java.util.TreeSet) CountThings(org.twak.utils.collections.CountThings)

Example 3 with Feature

use of org.twak.viewTrace.facades.MiniFacade.Feature in project chordatlas by twak.

the class Regularizer method assignFeaturesToWindows.

private void assignFeaturesToWindows(List<FRect> windows, MultiMap<Feature, FRect> rects) {
    int count = 0;
    for (Feature f : new Feature[] { Feature.CORNICE, Feature.SILL, Feature.BALCONY }) {
        for (FRect r : rects.get(f)) {
            for (FRect w : windows) {
                DRectangle bounds = new DRectangle(w);
                bounds.height = bounds.height * 0.5;
                switch(f) {
                    case SILL:
                        bounds.y = bounds.x - bounds.height;
                        break;
                    case BALCONY:
                        bounds.y = bounds.x;
                        break;
                    case CORNICE:
                        bounds.y = bounds.getMaxY();
                        break;
                    default:
                        break;
                }
                if (r.intersects(w)) {
                    w.attached.put(f, r);
                    count++;
                }
            }
            FRect win = nearest(windows, r, 2);
            if (win != null)
                win.attached.put(f, r);
        }
    }
// System.out.println("atatched " + count +" cornicesesese");
}
Also used : DRectangle(org.twak.utils.geom.DRectangle) Feature(org.twak.viewTrace.facades.MiniFacade.Feature)

Example 4 with Feature

use of org.twak.viewTrace.facades.MiniFacade.Feature in project chordatlas by twak.

the class Regularizer method combine.

private MiniFacade combine(List<MiniFacade> in) {
    MiniFacade out = new MiniFacade();
    out.left = lp;
    out.width = rp - lp;
    out.imageFeatures = in.get(0).imageFeatures;
    out.color = new double[] { 0, 0, 0, 1 };
    out.groundColor = new double[] { 0, 0, 0, 1 };
    int gcc = 0;
    for (MiniFacade mf : in) for (int i = 0; i < 3; i++) {
        out.color[i] += mf.color[i];
        if (mf.groundColor != null) {
            out.groundColor[i] += mf.groundColor[i];
            gcc++;
        }
    }
    for (int i = 0; i < 3; i++) {
        out.color[i] /= in.size();
        if (gcc > 0)
            out.groundColor[i] /= gcc;
    }
    Cache2<Outer, Integer, List<FRect>> corniceX = new ArrayCache2();
    Cache2<Outer, Integer, List<FRect>> sillX = new ArrayCache2();
    Cache2<Outer, Integer, List<FRect>> balX = new ArrayCache2();
    out.height = in.stream().mapToDouble(mf -> mf.height).average().getAsDouble();
    out.groundFloorHeight = in.stream().mapToDouble(mf -> mf.groundFloorHeight).average().getAsDouble();
    for (int i = 0; i < ids; i++) {
        int yay = 0, nay = 0;
        int ii = i;
        List<FRect> found = in.stream().map(mf -> m2i2r.get(mf, ii)).filter(x -> x != null).flatMap(l -> l.stream()).collect(Collectors.toList());
        Point2d avg = found.stream().map(r -> r.getCenter()).collect(new Point2DMeanCollector());
        for (MiniFacade mf : in) {
            List<FRect> r = m2i2r.get(mf, i);
            if (mf.contains(avg)) {
                if (r.isEmpty()) {
                    if (mf.left + 3 < avg.x && mf.left + mf.width - 3 > avg.x)
                        nay++;
                } else
                    yay++;
            }
        }
        if (yay >= nay) {
            // if we believe it exists add it as average of observed sizes
            FRect o;
            if (dimensionSpread(found) > 1.4) {
                // scattered -> union (typically shop windows)
                o = new FRect(found.get(0));
                for (FRect n : found) o.setFrom(o.union(n));
            } else
                // about same size: average position: windows on a grid
                o = new FRect(average(found.toArray(new FRect[found.size()])));
            {
                FRect t = found.get(0);
                o.f = t.f;
                o.id = i;
                o.outer = null;
                o.attachedHeight.get(Feature.SILL).d = averageAttached(o, Feature.SILL, found);
                o.attachedHeight.get(Feature.CORNICE).d = averageAttached(o, Feature.CORNICE, found);
                o.attachedHeight.get(Feature.BALCONY).d = averageAttached(o, Feature.BALCONY, found);
                if (t.f == Feature.WINDOW || t.f == Feature.SHOP) {
                    for (FRect r : found) {
                        corniceX.get(r.outer, r.yi).add(o);
                        sillX.get(r.outer, r.yi).add(o);
                        balX.get(r.outer, r.yi).add(o);
                    }
                }
            }
            out.rects.put(o.f, o);
        }
    }
    spreadAttachedOverGrid(Feature.SILL, sillX);
    spreadAttachedOverGrid(Feature.CORNICE, corniceX);
    spreadAttachedOverGrid(Feature.BALCONY, balX);
    fixOverlaps(out);
    mergeRemoveSmall(out);
    DRectangle mr = out.getAsRect();
    // ensure everything is comfortably within the bounds
    mr.width -= 0.2;
    mr.x += 0.1;
    for (Feature f : Feature.values()) {
        // clip to all
        Iterator<FRect> rit = out.rects.get(f).iterator();
        while (rit.hasNext()) {
            FRect r = rit.next();
            DRectangle section = r.intersect(mr);
            if (section == null || section.area() < 0.5)
                rit.remove();
            else
                r.setFrom(section);
        }
    }
    {
        // door height
        Double hf = Double.valueOf(0);
        while (out.groundFloorHeight < 6 && ((hf = horizontalEmpty(out, out.groundFloorHeight)) != null)) out.groundFloorHeight = hf + 0.3;
        if (out.groundFloorHeight >= 6)
            // no ground floor!
            out.groundFloorHeight = 0;
    }
    return out;
}
Also used : DumbCluster1D(org.twak.utils.DumbCluster1D) Cache2(org.twak.utils.Cache2) OptionalDouble(java.util.OptionalDouble) HashMap(java.util.HashMap) CountThings(org.twak.utils.collections.CountThings) Pair(org.twak.utils.Pair) TreeSet(java.util.TreeSet) MapMapList(org.twak.utils.collections.MapMapList) ArrayList(java.util.ArrayList) Arrayz(org.twak.utils.collections.Arrayz) HashSet(java.util.HashSet) Map(java.util.Map) Mathz(org.twak.utils.Mathz) Streamz(org.twak.utils.collections.Streamz) LinkedHashSet(java.util.LinkedHashSet) InAxDouble(org.twak.utils.streams.InAxDouble) Iterator(java.util.Iterator) ImageFeatures(org.twak.tweed.gen.FeatureCache.ImageFeatures) MultiMap(org.twak.utils.collections.MultiMap) Set(java.util.Set) Vector2d(javax.vecmath.Vector2d) MegaFeatures(org.twak.tweed.gen.FeatureCache.MegaFeatures) Collectors(java.util.stream.Collectors) File(java.io.File) Cluster(org.twak.utils.DumbCluster1D.Cluster) Point2d(javax.vecmath.Point2d) List(java.util.List) DumbCluster1DImpl(org.twak.utils.DumbCluster1DImpl) Bounds(org.twak.utils.geom.DRectangle.Bounds) DRectangle(org.twak.utils.geom.DRectangle) Comparator(java.util.Comparator) Collections(java.util.Collections) Feature(org.twak.viewTrace.facades.MiniFacade.Feature) DRectangle(org.twak.utils.geom.DRectangle) Feature(org.twak.viewTrace.facades.MiniFacade.Feature) OptionalDouble(java.util.OptionalDouble) InAxDouble(org.twak.utils.streams.InAxDouble) Point2d(javax.vecmath.Point2d) MapMapList(org.twak.utils.collections.MapMapList) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

Feature (org.twak.viewTrace.facades.MiniFacade.Feature)4 ArrayList (java.util.ArrayList)3 LinkedHashSet (java.util.LinkedHashSet)3 TreeSet (java.util.TreeSet)3 CountThings (org.twak.utils.collections.CountThings)3 DRectangle (org.twak.utils.geom.DRectangle)3 File (java.io.File)2 Collections (java.util.Collections)2 Comparator (java.util.Comparator)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 Iterator (java.util.Iterator)2 List (java.util.List)2 Map (java.util.Map)2 OptionalDouble (java.util.OptionalDouble)2 Set (java.util.Set)2 Collectors (java.util.stream.Collectors)2 Point2d (javax.vecmath.Point2d)2 Vector2d (javax.vecmath.Vector2d)2 ImageFeatures (org.twak.tweed.gen.FeatureCache.ImageFeatures)2