Search in sources :

Example 1 with Cache2

use of org.twak.utils.Cache2 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)

Example 2 with Cache2

use of org.twak.utils.Cache2 in project chordatlas by twak.

the class GurobiSkelSolver method buildProfiles.

private void buildProfiles() throws GRBException {
    for (HalfEdge e : edges) {
        if (// when a profile ends, we assume it can't start again...
        ((SuperEdge) e).profLine == null)
            continue;
        EdgeVars ev = edgeInfo.get(e);
        ev.profile = new GRBVar[globalProfs.size()];
        for (int p = 0; p < globalProfs.size(); p++) {
            ev.profile[p] = model.addVar(0.0, 1.0, 0, GRB.BINARY, PROFILE_SELECT);
            set(ev.profile[p], p == 0 ? 1 : 0);
        }
    }
    Cache2<HalfEdge, HalfEdge, GRBVar> isProfileDifferent = new Cache2<HalfMesh2.HalfEdge, HalfMesh2.HalfEdge, GRBVar>() {

        @Override
        public GRBVar create(HalfEdge e1, HalfEdge e2) {
            try {
                GRBVar s = model.addVar(0.0, 1.0, 0.0, GRB.BINARY, PROFILE_DIFFERENT);
                buildIsDifferentColor(s, edgeInfo.get(e1).profile, edgeInfo.get(e2).profile, "profile");
                s.set(DoubleAttr.Start, 0);
                return s;
            } catch (GRBException e) {
                e.printStackTrace();
            }
            return null;
        }
    };
    for (HalfEdge e1 : edges) {
        // if (e1.over != null)
        // continue;
        EdgeVars ev = edgeInfo.get(e1);
        if (ev.profile == null)
            continue;
        double[] fit = profFit.get(e1);
        GRBLinExpr pickOneProfile = new GRBLinExpr();
        for (int p = 0; p < globalProfs.size(); p++) {
            GRBVar a = ev.profile[p];
            pickOneProfile.addTerm(1, a);
            target.addTerm(.001 * fit[p] * e1.length(), a);
        }
        model.addConstr(pickOneProfile, GRB.EQUAL, 1, /*ev.isEdge*/
        "pick only one profile for " + e1);
        List<HalfEdge> atEnd = e1.collectAroundEnd();
        for (HalfEdge e2 : atEnd) {
            if (e1 != e2 && edgeInfo.get(e2).profile != null && // only constrain if ~parallel
            e1.line().absAngle(e2.line()) < 0.1) {
                GRBVar s = isProfileDifferent.get(e1, e2);
                // ev.debug = s;
                // Point2d dbg = new Point2d(e1.end);
                // dbg.add(new Point2d(Math.random() * 0.1, Math.random() * 0.1));
                GRBLinExpr perpIsEdge = new GRBLinExpr();
                for (HalfEdge e3 : atEnd) {
                    if (e3 == e1 || e3 == e2 || e3 == e1.over || e3 == e2.over || (e3.over != null && (e3.over == e1.over || e3.over == e2.over)))
                        continue;
                    if (!e1.line().isOnLeft(e1.end.distanceSquared(e3.start) > e1.end.distanceSquared(e3.end) ? e3.start : e3.end))
                        continue;
                    perpIsEdge.addTerm(1, edgeInfo.get(e3).isEdge);
                // PaintThing.debug.put(e2, dbg);
                // Point2d d2 = new Point2d(e3.line().dir());
                // d2.scale (0.1/new Vector2d(d2).length());
                // d2.add(dbg);
                // PaintThing.debug.put(e2, new Line (dbg, d2));
                // model.addConstr( s, GRB.LESS_EQUAL, edgeInfo.get(e3).isEdge, "only change profile if no adjacent edge "+e1 );
                }
                model.addConstr(s, GRB.LESS_EQUAL, perpIsEdge, "dont' change profile over " + e1);
            // PaintThing.debug.put(e2, dbg);
            // Point2d d2 = new Point2d(e2.line().dir());
            // d2.scale (0.2/new Vector2d(d2).length());
            // d2.add(dbg);
            // PaintThing.debug.put(e2, new Line (dbg, d2));
            }
        }
    }
    countNearbyProfiles = 0;
    if (false)
        for (int i = 0; i < edges.size(); i++) {
            HalfEdge e1 = edges.get(i);
            if (edgeInfo.get(e1).profile == null)
                continue;
            print("building edge locality term " + i + " / " + edges.size());
            for (HalfEdge e2 : edges) if (lt(e1, e2) && edgeInfo.get(e2).profile != null) {
                if (e1.line().distance(e2.line()) < 2) {
                    GRBVar s = isProfileDifferent.get(e1, e2);
                    target.addTerm(0.1 * (e1.length() + e2.length()), s);
                    countNearbyProfiles++;
                }
            }
        }
}
Also used : GRBLinExpr(gurobi.GRBLinExpr) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) GRBVar(gurobi.GRBVar) Cache2(org.twak.utils.Cache2) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint) HalfMesh2(org.twak.utils.geom.HalfMesh2) GRBException(gurobi.GRBException)

Aggregations

Cache2 (org.twak.utils.Cache2)2 GRBException (gurobi.GRBException)1 GRBLinExpr (gurobi.GRBLinExpr)1 GRBVar (gurobi.GRBVar)1 File (java.io.File)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 Comparator (java.util.Comparator)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 LinkedHashSet (java.util.LinkedHashSet)1 List (java.util.List)1 Map (java.util.Map)1 OptionalDouble (java.util.OptionalDouble)1 Set (java.util.Set)1 TreeSet (java.util.TreeSet)1 Collectors (java.util.stream.Collectors)1 Point2d (javax.vecmath.Point2d)1 Vector2d (javax.vecmath.Vector2d)1