Search in sources :

Example 1 with HalfMesh2

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

the class SuperMeshPainter method paint.

@Override
public void paint(Object oa, Graphics2D g2, PanMouseAdaptor ma) {
    HalfMesh2 o = (HalfMesh2) oa;
    double scatterRadius = 0.0;
    if (o.faces.isEmpty())
        return;
    double maxHeight = o.faces.stream().mapToDouble(x -> ((SuperFace) x).height).max().getAsDouble();
    // (int) ( Math.random() * 100 );
    int fc = 0;
    for (HalfFace f : o.faces) {
        fc++;
        Polygon pwt = new Polygon();
        try {
            for (HalfEdge e : f.edges()) {
                pwt.addPoint(ma.toX(e.start.x + Math.random() * scatterRadius), ma.toY(e.start.y + Math.random() * scatterRadius));
            // PaintThing.paint(e.start, g2, ma);
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }
        SuperFace sf = (SuperFace) f;
        Color c;
        if (false) {
            int h = (int) Mathz.clamp(((SuperFace) f).height * 5, 0, 255);
            if (((SuperFace) f).height == -Double.MAX_VALUE)
                c = Color.green;
            else if (((SuperFace) f).height < 0)
                c = Color.red;
            else
                c = new Color(h, h, h);
        } else if (sf.height == -Double.MAX_VALUE) {
            c = Color.yellow;
        } else if (sf.classification == -1 || sf.height < 0) {
            c = Color.red;
        } else {
            // c = Color.white;
            c = Rainbow.getColour(sf.classification + 1);
        // c = Rainbow.getColour( fc++ + 1 );
        }
        // c = Color.white;
        // new Color( c.getRed(), c.getGreen(), c.getBlue(), 50 ) );
        g2.setColor(c);
        g2.fill(pwt);
    // Loop<Point2d> pts = new Loop<>();
    // for ( HalfEdge e : f.edges() )
    // pts.append(e.end);
    // 
    // if ( ( Loopz.area( pts ) ) < 0.1 ) {
    // g2.setColor(Color.red);
    // g2.setStroke( new BasicStroke( 4f ) );
    // g2.draw( pwt );
    // }
    }
    for (HalfFace f : o.faces) {
        g2.setColor(Color.black);
        try {
            for (HalfEdge e : f) {
                SuperEdge se = (SuperEdge) e;
                g2.setColor(Color.black);
                if (se.proceduralFacade != null) {
                    g2.setStroke(new BasicStroke(3f));
                } else {
                    g2.setStroke(new BasicStroke(1f));
                }
            // if ( se.profLine != null || ( se.over != null && ((SuperEdge)se.over).profLine != null ) ) {
            // g2.setStroke( new BasicStroke( 2f ) );
            // g2.setColor( new Color (255, 0, 0 ) );
            // }
            // else
            // {
            // g2.setStroke( new BasicStroke( 1f ) );
            // g2.setColor( Color.black );
            // }
            // g2.setColor( ((SuperEdge)e).profLine == null? Color.green : Color.magenta);
            // PaintThing.paint ( e.line(), g2, ma );
            // }
            }
        } catch (Throwable th) {
            th.printStackTrace();
        }
        g2.setStroke(new BasicStroke(3));
        if (false)
            for (HalfEdge e : f.edges()) {
                SuperEdge se = (SuperEdge) e;
                if (se.profLine != null) {
                    // g2.setColor( Color.BLACK );
                    // new Line (new Point2d (e.start), new Point2d (e.end));
                    Line l = se.line();
                    // PaintThing.drawArrow( g2, ma, l, 5 );
                    g2.drawLine(ma.toX(l.start.x), ma.toY(l.start.y), ma.toX(l.end.x), ma.toY(l.end.y));
                }
            // if (e.over != null)
            // {
            // l.moveLeft( ma.fromZoom( 2 ) );
            // 
            // double delta = Math.abs (  ((SuperEdge)e).localHeight - ((SuperEdge)e.over).localHeight );
            // 
            // int h =  (int) Math.min(255, delta * 10 ) ;
            // g2.setColor ( new Color (0,h,h) );
            // g2.setStroke (new BasicStroke( 3f ));
            // 
            // }
            // if ( ( (SuperEdge) e ).debug ) {
            // if ( e.over == null || ((SuperFace)e.over.face).classification != ((SuperFace)f).classification ) {
            // g2.setColor( Color.black );
            // g2.setStroke( new BasicStroke( 2 ) );
            // PaintThing.paint( e.line(), g2, ma );
            // }
            }
    }
    fc = 0;
    if (false)
        for (HalfFace f : o.faces) {
            for (HalfEdge e : f.edges()) {
                // Point2d pt = new Point2d(e.start);
                // pt.add( off );
                // Point2d pt2 = new Point2d(e.end);
                // pt2.add( off );
                // 
                // PaintThing.paint( new Line (pt, pt2) , g2, ma );
                g2.setColor(new Color(255, 0, 0, 20));
                if (e.line().absAngle(e.next.line()) > Math.PI - 0.001) {
                    g2.setColor(new Color(0, 255, 0, 255));
                }
                PaintThing.paint(new Line(e.start, e.end), g2, ma);
                PaintThing.paint(new Line(e.next.start, e.next.end), g2, ma);
            }
        // for ( HalfEdge e : f.edges() ) {
        // PaintThing.drawArrow( g2, ma, e.line(), 5 );
        // }
        }
    if (false)
        for (HalfFace f : o.faces) for (HalfEdge e : f.edges()) {
            if (e.face != f || (e.over != null && (e.over.over != e || !o.faces.contains(e.over.face))) || e.face == null || e.start == null || e.end == null || e.next == null) {
                g2.setColor(Color.red);
                g2.setStroke(new BasicStroke(4));
                PaintThing.paint(e.line(), g2, ma);
            }
        }
}
Also used : BasicStroke(java.awt.BasicStroke) Line(org.twak.utils.Line) Color(java.awt.Color) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace) Polygon(java.awt.Polygon) SuperFace(org.twak.tweed.gen.SuperFace) SuperEdge(org.twak.tweed.gen.SuperEdge) HalfMesh2(org.twak.utils.geom.HalfMesh2)

Example 2 with HalfMesh2

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

the class GurobiSkelSolver method findNear.

public static List<HalfEdge> findNear(Line l, Point2d start, HalfMesh2 mesh2) {
    double tol = 4;
    l = new Line(l);
    l.moveLeft(tol);
    List<HalfEdge> out = new ArrayList<>();
    for (HalfFace f : mesh2) try {
        for (HalfEdge e : f) {
            if (e.end.distanceSquared(start) < tol * tol && l.isOnLeft(e.start) && l.isOnLeft(e.end) && Mathz.inRangeTol(e.line().absAngle(e.next.line()), Mathz.PI2, 1)) {
                double angle = l.absAngle(e.line());
                if (// regular T-jn on edge or left corner
                (e.next.over == null && Mathz.inRangeTol(angle, Mathz.PI2, 1)) || // right corner
                (e.over == null && e.next.over == null && angle < 1))
                    out.add(e);
            }
        }
    } catch (Throwable th) {
        th.printStackTrace();
    }
    return out;
}
Also used : Line(org.twak.utils.Line) ArrayList(java.util.ArrayList) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace)

Example 3 with HalfMesh2

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

the class GurobiSkelSolver method buildMini.

private void buildMini() throws GRBException {
    Cache<HalfEdge, GRBLinExpr> isMiniExpr = new Cach<HalfMesh2.HalfEdge, GRBLinExpr>(he -> new GRBLinExpr());
    if (minis == null)
        return;
    for (MegaFeatures mf : minis.keySet()) {
        List<MiniPtCluster> clusterVars = new ArrayList<>();
        mega2clusters.put(mf, clusterVars);
        double mLen = mf.megafacade.length();
        DumbCluster1D<MFPoint> clusters = clusterMinis(mf, minis);
        for (DumbCluster1D.Cluster<MFPoint> d : clusters) {
            // for each cluster, we pick a single MFPoint as the boundary
            MiniPtCluster miniPtVar = new MiniPtCluster();
            Cache<HalfEdge, GRBLinExpr> isEdgeBind = new Cach<HalfMesh2.HalfEdge, GRBLinExpr>(he -> new GRBLinExpr());
            GRBLinExpr selectHE = new GRBLinExpr();
            boolean one = false;
            for (MFPoint pt : d.things) {
                MiniSelectEdge miniSelectEdge = new MiniSelectEdge();
                miniPtVar.put(pt, miniSelectEdge);
                List<HalfEdge> nearCorners = findNear(mf.megafacade, pt, mesh);
                try {
                    for (HalfEdge he : nearCorners) {
                        GRBVar heVar = model.addVar(0.0, 1.0, 0, GRB.BINARY, MINI_TO_EDGE);
                        miniSelectEdge.edge.put(he, heVar);
                        selectHE.addTerm(1, heVar);
                        double cost = he.end.distance(pt);
                        if (he.over != null) {
                            if (pt.right != null)
                                cost += Math.abs(pt.right.height - ((SuperFace) he.face).height);
                            if (pt.left != null)
                                cost += Math.abs(pt.left.height - ((SuperFace) he.over.face).height);
                            isEdgeBind.get(he).addTerm(1, heVar);
                        } else
                            // bonus for being on a corner;
                            cost -= totalEdgeLength * 0.1;
                        target.addTerm(cost, heVar);
                        isMiniExpr.get(he).addTerm(1, heVar);
                        one = true;
                    }
                } catch (Throwable th) {
                    th.printStackTrace();
                }
            }
            if (one) {
                clusterVars.add(miniPtVar);
                model.addConstr(selectHE, GRB.EQUAL, 1, "pick one near " + d.things.iterator().next());
            } else
                print("warning skipping minifacade loction " + d.things.size());
            for (HalfEdge he : isEdgeBind.cache.keySet()) model.addConstr(isEdgeBind.get(he), GRB.EQUAL, edgeInfo.get(he).isEdge, "minifacade boundary must terminate on edge " + he);
            miniPtVar.mean = mf.megafacade.fromPPram(d.mean / mLen);
        }
    }
    double penalty = totalEdgeLength * 0.1;
    for (HalfEdge he : edges) {
        if (he.over != null && he.next.over == null) {
            // edge comes to boundary without minifacade --> penalty
            OptionalDouble miniDist = minis.keySet().stream().map(mf -> mf.megafacade).mapToDouble(line -> line.distance(he.end, true)).min();
            if (!miniDist.isPresent() || miniDist.getAsDouble() > 4)
                continue;
            EdgeVars ei = edgeInfo.get(he);
            ei.edgeNoMini = model.addVar(0.0, 1.0, 0, GRB.BINARY, EDGE_NO_MINI);
            if (isMiniExpr.cache.containsKey(he)) {
                ei.isMini = model.addVar(0.0, 1.0, 0, GRB.BINARY, IS_MINI);
                GRBLinExpr is = isMiniExpr.get(he);
                /* ei.isMini might take 0 or positive integer... assume it's below 10 (0.1 = 1/10) */
                model.addConstr(ei.isMini, GRB.LESS_EQUAL, is, "is minifacade on edge " + he);
                model.addConstr(scale(0.1, is), GRB.LESS_EQUAL, ei.isMini, "is minifacade on edge " + he);
                GRBLinExpr expr = new GRBLinExpr();
                expr.addTerm(1, ei.isEdge);
                expr.addTerm(1, ei.isMini);
                model.addConstr(ei.edgeNoMini, GRB.LESS_EQUAL, expr, null);
                expr = new GRBLinExpr();
                expr.addTerm(1, ei.edgeNoMini);
                expr.addTerm(1, ei.isMini);
                model.addConstr(expr, GRB.LESS_EQUAL, 1, null);
                expr = new GRBLinExpr();
                expr.addTerm(1, ei.isEdge);
                expr.addTerm(-1, ei.isMini);
                model.addConstr(ei.edgeNoMini, GRB.GREATER_EQUAL, expr, null);
            } else {
                // no mini, but easier debug
                model.addConstr(ei.edgeNoMini, GRB.EQUAL, ei.isEdge, null);
            }
            target.addTerm(penalty, ei.edgeNoMini);
        }
    }
}
Also used : Color(java.awt.Color) GRBQuadExpr(gurobi.GRBQuadExpr) DumbCluster1D(org.twak.utils.DumbCluster1D) GRBException(gurobi.GRBException) Cache2(org.twak.utils.Cache2) StringAttr(gurobi.GRB.StringAttr) OptionalDouble(java.util.OptionalDouble) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace) HashMap(java.util.HashMap) Random(java.util.Random) Cach(org.twak.utils.Cach) Tweed(org.twak.tweed.Tweed) ArrayList(java.util.ArrayList) TweedSettings(org.twak.tweed.TweedSettings) HashSet(java.util.HashSet) GRBModel(gurobi.GRBModel) Map(java.util.Map) Cache(org.twak.utils.Cache) Mathz(org.twak.utils.Mathz) PaintThing(org.twak.utils.PaintThing) ProgressMonitor(javax.swing.ProgressMonitor) GRBVar(gurobi.GRBVar) Iterator(java.util.Iterator) ImageFeatures(org.twak.tweed.gen.FeatureCache.ImageFeatures) GRBLinExpr(gurobi.GRBLinExpr) MultiMap(org.twak.utils.collections.MultiMap) Line(org.twak.utils.Line) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) Set(java.util.Set) HalfMesh2(org.twak.utils.geom.HalfMesh2) DoubleAttr(gurobi.GRB.DoubleAttr) MegaFeatures(org.twak.tweed.gen.FeatureCache.MegaFeatures) LinearForm(org.twak.utils.geom.LinearForm) Collectors(java.util.stream.Collectors) File(java.io.File) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint) Point2d(javax.vecmath.Point2d) List(java.util.List) Collections(java.util.Collections) GRBEnv(gurobi.GRBEnv) GRB(gurobi.GRB) GRBLinExpr(gurobi.GRBLinExpr) MegaFeatures(org.twak.tweed.gen.FeatureCache.MegaFeatures) ArrayList(java.util.ArrayList) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) DumbCluster1D(org.twak.utils.DumbCluster1D) OptionalDouble(java.util.OptionalDouble) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint) GRBVar(gurobi.GRBVar) Cach(org.twak.utils.Cach) HalfMesh2(org.twak.utils.geom.HalfMesh2)

Example 4 with HalfMesh2

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

the class HouseTool method clickedOn.

@Override
public void clickedOn(Spatial target, Vector3f loc, Vector2f cursorPosition) {
    // (Line) new XStream().fromXML( new File( "/home/twak/data/regent/March_30/congo/1/line.xml" ) ));
    MegaFeatures mf = new MegaFeatures(new Line(0, 0, 10, 0));
    // FeatureCache.readFeatures( new File( "/home/twak/data/regent/March_30/congo/1/0" ), mf );
    ImageFeatures imf = new ImageFeatures();
    imf.mega = mf;
    double[] minMax = new double[] { 0, 15, 0, 25 };
    HalfMesh2.Builder builder = new HalfMesh2.Builder(SuperEdge.class, SuperFace.class);
    builder.newPoint(new Point2d(minMax[0] + loc.x, minMax[3] + loc.z));
    builder.newPoint(new Point2d(minMax[1] + loc.x, minMax[3] + loc.z));
    builder.newPoint(new Point2d(minMax[1] + loc.x, minMax[2] + loc.z));
    builder.newPoint(new Point2d(minMax[0] + loc.x, minMax[2] + loc.z));
    builder.newFace();
    HalfMesh2 mesh = builder.done();
    Prof p = new Prof();
    p.add(new Point2d(0, 0));
    p.add(new Point2d(0, 20));
    p.add(new Point2d(-5, 25));
    boolean first = true;
    for (HalfFace f : mesh) {
        for (HalfEdge e : f) {
            SuperEdge se = (SuperEdge) e;
            se.prof = p;
            MiniFacade mini = newMini(imf, se.length());
            if (true) {
                se.addMini(mini);
                se.proceduralFacade = mf;
                se.toEdit = mini;
                if (first)
                    se.addMini(mini);
            }
            first = false;
        }
        SuperFace sf = (SuperFace) f;
        sf.maxProfHeights = new ArrayList();
        sf.maxProfHeights.add(Double.valueOf(100));
        sf.height = 100;
    }
    SkelGen sg = new SkelGen(mesh, tweed, null);
    tweed.frame.addGen(sg, true);
}
Also used : MiniFacade(org.twak.viewTrace.facades.MiniFacade) ImageFeatures(org.twak.tweed.gen.FeatureCache.ImageFeatures) MegaFeatures(org.twak.tweed.gen.FeatureCache.MegaFeatures) ArrayList(java.util.ArrayList) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace) SuperEdge(org.twak.tweed.gen.SuperEdge) SuperFace(org.twak.tweed.gen.SuperFace) SkelGen(org.twak.tweed.gen.skel.SkelGen) Line(org.twak.utils.Line) Point2d(javax.vecmath.Point2d) HalfMesh2(org.twak.utils.geom.HalfMesh2) Prof(org.twak.tweed.gen.Prof)

Example 5 with HalfMesh2

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

the class SkelFootprint method killDoubleEdges.

public static void killDoubleEdges(HalfMesh2 mesh) {
    for (HalfFace f : mesh) {
        boolean iDidSomething;
        do {
            iDidSomething = false;
            for (HalfEdge e : f) {
                if (e.next.over == e) {
                    e.dissolve(mesh);
                    iDidSomething = true;
                }
            }
        } while (iDidSomething);
    }
}
Also used : HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace)

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