Search in sources :

Example 11 with HalfMesh2

use of org.twak.utils.geom.HalfMesh2 in project chordatlas by twak.

the class SkelFootprint method removeExposedFaces.

public static void removeExposedFaces(HalfMesh2 mesh) {
    System.out.println("removing exposed faces....");
    Set<HalfFace> togo = new HashSet<>(mesh.faces);
    while (!togo.isEmpty()) {
        // for ( HalfFace hf : new ArrayList<HalfFace>( mesh.faces ) ) {
        HalfFace hf = togo.iterator().next();
        togo.remove(hf);
        double exposed = 0, safe = 0;
        for (HalfEdge e : hf.edges()) {
            if (e.over == null && ((SuperEdge) e).profLine == null)
                exposed += e.length();
            else
                safe += e.length();
        }
        if (exposed > exposedFaceFrac * safe) {
            togo.addAll(hf.getNeighbours());
            hf.remove(mesh);
        }
    }
}
Also used : HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 12 with HalfMesh2

use of org.twak.utils.geom.HalfMesh2 in project chordatlas by twak.

the class SkelFootprint method boundMesh.

public static HalfMesh2 boundMesh(List<Line> footprint) {
    double[] minMax = minMax(10, footprint);
    HalfMesh2.Builder builder = new HalfMesh2.Builder(SuperEdge.class, SuperFace.class);
    builder.newPoint(new Point2d(minMax[0], minMax[3]));
    builder.newPoint(new Point2d(minMax[1], minMax[3]));
    builder.newPoint(new Point2d(minMax[1], minMax[2]));
    builder.newPoint(new Point2d(minMax[0], minMax[2]));
    builder.newFace();
    HalfMesh2 mesh = builder.done();
    return mesh;
}
Also used : Point2d(javax.vecmath.Point2d) MeshBuilder(org.twak.siteplan.jme.MeshBuilder) HalfMesh2(org.twak.utils.geom.HalfMesh2)

Example 13 with HalfMesh2

use of org.twak.utils.geom.HalfMesh2 in project chordatlas by twak.

the class SkelFootprint method calcProfFit.

// private static Prof boringProf( double h ) {
// Prof prof = Prof.buildProfile( new Line3d( new Point3d( 0, 0, 0 ), new Point3d( 1, 0, 0 ) ), new Point3d( 0, 0, 0 ) );
// prof.add(new Point2d (0,0));
// prof.add(new Point2d (0,h));
// return prof;
// }
private void calcProfFit(HalfMesh2 mesh, List<Prof> globalProfs, Map<SuperEdge, double[]> out, ProgressMonitor m) {
    System.out.println("Building F...");
    boolean[] used = new boolean[globalProfs.size()];
    Map<SuperEdge, double[]> tmp = new HashMap();
    double[] noData = new double[globalProfs.size()];
    Arrays.fill(noData, 0);
    noData[0] = -1;
    used[0] = true;
    for (int i = 0; i < mesh.faces.size(); i++) {
        // System.out.println( "calculating profile fit for face " + i + "/" + mesh.faces.size() );
        HalfFace f = mesh.faces.get(i);
        for (HalfEdge e : f) {
            double[] fits = new double[globalProfs.size()];
            for (int g = 0; g < fits.length; g++) {
                Double d = meanDistance(globalProfs.get(g), (SuperEdge) e);
                if (d == null || Double.isNaN(d)) {
                    fits = noData;
                    break;
                } else
                    fits[g] = d;
            }
            tmp.put((SuperEdge) e, fits);
            used[Arrayz.min(fits)] = true;
        }
        if (m.isCanceled())
            return;
    }
    Arrays.fill(used, true);
    int count = 0;
    for (boolean u : used) if (u)
        count++;
    for (Map.Entry<SuperEdge, double[]> e : tmp.entrySet()) {
        double[] fits = new double[count];
        int c = 0;
        for (int i = 0; i < e.getValue().length; i++) if (used[i])
            fits[c++] = e.getValue()[i];
        out.put(e.getKey(), fits);
    }
    for (int g = globalProfs.size() - 1; g >= 0; g--) if (!used[g])
        globalProfs.remove(g);
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace) MutableDouble(org.twak.utils.MutableDouble) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) MultiMap(org.twak.utils.collections.MultiMap) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint)

Example 14 with HalfMesh2

use of org.twak.utils.geom.HalfMesh2 in project chordatlas by twak.

the class SkelFootprint method dbgShowProfiles.

private void dbgShowProfiles(HalfMesh2 mesh, List<Prof> globalProfs, Map<SuperEdge, double[]> profFit, String name) {
    Node n = new Node();
    Jme3z.removeAllChildren(n);
    int colI = 0;
    for (HalfFace f : mesh) {
        ColorRGBA col = Jme3z.toJme(Rainbow.getColour(colI++));
        colI = colI % 6;
        Material mat = new Material(tweed.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
        mat.setColor("Diffuse", col);
        mat.setColor("Ambient", col);
        mat.setBoolean("UseMaterialColors", true);
        if (true) {
            Loop<Point3d> loop = new Loop<>();
            for (HalfEdge e : f) loop.append(new Point3d(e.start.x, 0, e.start.y));
            MeshBuilder mb = new MeshBuilder();
            mb.add(loop.singleton(), null, false);
            Geometry g = new Geometry("floorplan", mb.getMesh());
            g.setMaterial(mat);
            n.attachChild(g);
        }
        for (HalfEdge e : f) {
            SuperEdge se = (SuperEdge) e;
            Prof bestProf = null;
            if (globalProfs == null)
                bestProf = se.prof;
            else {
                // if (se.profLine != null) {
                // 
                // SuperLine sl = ((SuperLine)se.profLine);
                // MegaFacade mf = (MegaFacade) sl.properties.get( MegaFacade.class.getName() );
                // 
                // List<Prof> pfs = mf.getTween( se.start, se.end, 0.3 );
                // 
                // if (!pfs.isEmpty())
                // bestProf = Prof.parameterize( sl, pfs );
                // else {
                // bestProf = clean.get( 0 );
                // double bestScore = Double.MAX_VALUE;
                // 
                // for ( Prof c : clean ) {
                // 
                // double score = 0;
                // boolean good = false;
                // for ( Prof r : mf.getTween( se.start, se.end, 0.3 ) ) {
                // score += c.distance( r, true, false, true );
                // good = true;
                // }
                // if ( good && score < bestScore ) {
                // bestScore = score;
                // bestProf = c;
                // }
                // 
                // }
                // }
                // 
                // 
                // }
                // if (bestProf)
                // ((SuperLine))
                // 
                double[] fitV = profFit.get(se);
                if (fitV == null)
                    continue;
                double bestScore = Double.MAX_VALUE;
                for (int ii = 0; ii < fitV.length; ii++) {
                    double d = fitV[ii];
                    if (d < bestScore) {
                        bestScore = d;
                        bestProf = globalProfs.get(ii);
                    }
                }
            // 
            // double bestScore = Double.MAX_VALUE;
            // 
            // for ( int ii = 0; ii < fitV.length; ii++ ) {
            // double d = fitV[ ii ];
            // if ( d < bestScore ) {
            // bestScore = d;
            // bestProf = globalProfs.get( ii );
            // }
            // }
            // if (false)
            // se.prof = bestProf;
            }
            if (bestProf != null) {
                Geometry g = new Geometry();
                Point3d cen = Pointz.to3(se.line().fromPPram(0.5));
                Prof goodOrientation = Prof.buildProfile(Pointz.to3(se.line()), cen);
                for (Point2d p : bestProf) goodOrientation.add(p);
                g.setMesh(goodOrientation.renderStrip(1.5, cen));
                g.setMaterial(mat);
                n.attachChild(g);
                g.updateGeometricState();
                g.updateModelBound();
            }
        }
    }
    skelGen.tweed.frame.addGen(new JmeGen(name, tweed, n), false);
}
Also used : Loop(org.twak.utils.collections.Loop) Node(com.jme3.scene.Node) Material(com.jme3.material.Material) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint) Geometry(com.jme3.scene.Geometry) ColorRGBA(com.jme3.math.ColorRGBA) Point2d(javax.vecmath.Point2d) Point3d(javax.vecmath.Point3d) MeshBuilder(org.twak.siteplan.jme.MeshBuilder)

Example 15 with HalfMesh2

use of org.twak.utils.geom.HalfMesh2 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

HalfEdge (org.twak.utils.geom.HalfMesh2.HalfEdge)18 HalfFace (org.twak.utils.geom.HalfMesh2.HalfFace)18 Point2d (javax.vecmath.Point2d)10 MFPoint (org.twak.tweed.gen.FeatureCache.MFPoint)10 Line (org.twak.utils.Line)10 HalfMesh2 (org.twak.utils.geom.HalfMesh2)9 ArrayList (java.util.ArrayList)7 MegaFeatures (org.twak.tweed.gen.FeatureCache.MegaFeatures)7 HashMap (java.util.HashMap)6 SuperLine (org.twak.viewTrace.SuperLine)6 Color (java.awt.Color)5 LinkedHashMap (java.util.LinkedHashMap)5 Material (com.jme3.material.Material)4 ColorRGBA (com.jme3.math.ColorRGBA)4 Geometry (com.jme3.scene.Geometry)4 Node (com.jme3.scene.Node)4 File (java.io.File)4 HashSet (java.util.HashSet)4 LinkedHashSet (java.util.LinkedHashSet)4 Map (java.util.Map)4