Search in sources :

Example 1 with SuperLine

use of org.twak.viewTrace.SuperLine in project chordatlas by twak.

the class ProfileGen method processMegaFaces.

private void processMegaFaces() {
    addOnJmeThread.clear();
    if (faces == null || faces.isEmpty()) {
        JOptionPane.showMessageDialog(tweed.frame(), "Failed to cluster facades");
        return;
    }
    Node mfNode = new Node();
    // Node cProfileNode = new Node();
    Random randy = new Random(2);
    dbgProfileLookup.clear();
    final boolean DBG = true;
    computeProfiles(faces);
    int i = 0;
    for (MegaFacade mf : faces) {
        // if (i == 4)
        {
            System.out.println("building profiles over megafacade " + i + "/" + faces.size());
            ColorRGBA dispCol = new ColorRGBA(color.getRed() * randy.nextFloat() / 255f, color.getGreen() * randy.nextFloat() / 255f, color.getBlue() * randy.nextFloat() / 255f, 1);
            if (DBG) {
                List<Line3d> dbg = new ArrayList();
                for (int d : mf.keySet()) {
                    for (Line l2 : mf.get(d)) {
                        Line3d oLine = new Line3d(l2.start.x, getHeight(d), l2.start.y, l2.end.x, getHeight(d), l2.end.y);
                        dbg.add(oLine);
                    }
                }
                mfNode.attachChild(Jme3z.lines(tweed.getAssetManager(), dbg, dispCol, 0.1f, true));
                Line l2 = mf.origin.line;
                Line3d oLine = new Line3d(l2.start.x, getHeight(mf.origin.height), l2.start.y, l2.end.x, getHeight(mf.origin.height), l2.end.y);
            // mfNode.attachChild( Jme3z.lines( tweed.getAssetManager(), Collections.singletonList( oLine ), dispCol, 0.5f, true ) );
            }
            {
                Line l3 = mf.origin.line;
                // if ( mf.profiles.values().stream().mapToDouble( p -> p.get( 0 ).y ).min().getAsDouble() > 8 )
                // continue;
                totalPlanLineLength += l3.length();
                Line3d oLine = new Line3d(l3.start.x, getHeight(mf.origin.height), l3.start.y, l3.end.x, getHeight(mf.origin.height), l3.end.y);
                List<SuperLine> pLines = Prof.findProfileLines(mf.profiles.values(), oLine);
                for (int pi = 0; pi < pLines.size(); pi++) {
                    SuperLine profileLine = pLines.get(pi);
                    // if ( distance ( gis, profileLine.start ) > 2 || distance ( gis, profileLine.end ) > 2 )
                    // continue;
                    Node profileNode = new Node();
                    // dispCol = new ColorRGBA( randy.nextFloat(), randy.nextFloat(), randy.nextFloat(), 1 );
                    MegaFacade pMF = mf.moveTo(profileLine);
                    if (pi >= 1) {
                        Line newOrigin = null;
                        double bestDist = Double.MAX_VALUE;
                        Point3d plCen = Pointz.to3(profileLine.fromPPram(0.5), getHeight(mf.hExtentMin));
                        for (int li = mf.hExtentMin; li <= mf.hExtentMax; li++) for (Line l : mf.get(li)) {
                            double dist = Pointz.to3(l.fromPPram(0.5), getHeight(li)).distance(plCen);
                            if (dist < bestDist) {
                                newOrigin = l;
                                bestDist = dist;
                            }
                        }
                        if (newOrigin != null) {
                            pMF.setOrigin(new LineAtHeight(pMF.hExtentMin, newOrigin));
                            pMF.computeProfiles(ProfileGen.this);
                        }
                    }
                    profileLine.setMega(pMF);
                    footprint.add(profileLine);
                    dbgProfileLookup.put(i++, pMF);
                    if (DBG) {
                        profileNode.attachChild(Jme3z.lines(tweed.getAssetManager(), Collections.singletonList(new Line3d(profileLine.start.x, 0, profileLine.start.y, profileLine.end.x, 0, profileLine.end.y)), dispCol, 0.3f, true));
                        render(new ArrayList<>(pMF.profiles.values()), tweed, dispCol, profileNode);
                        // List<Prof> cleans = new ArrayList<>();
                        // for ( Prof p : pMF.profiles.values() ) {
                        // p.render( tweed, profileNode, dispCol, 1f );
                        // cleans.add( new Prof( p ).parameterize() );
                        // .render( tweed, cProfileNode, dispCol.add( ColorRGBA.Gray ), 1f );
                        // 
                        // }
                        // render ( cleans, tweed, cProfileNode );
                        profileNode.attachChild(Jme3z.lines(tweed.getAssetManager(), Collections.singletonList(oLine), dispCol, 0.3f, true));
                        profileNode.setUserData(ProfileGen.class.getSimpleName(), i);
                        addOnJmeThread.add(profileNode);
                    }
                }
            }
        }
    }
    if (DBG)
        tweed.frame.addGen(new JmeGen("horizontal lines", tweed, mfNode), false);
    // tweed.frame.addGen( new JmeGen( "clean profiles", tweed, cProfileNode ), false );
    calculateOnJmeThread();
}
Also used : Node(com.jme3.scene.Node) ArrayList(java.util.ArrayList) CullHint(com.jme3.scene.Spatial.CullHint) Line3d(org.twak.utils.geom.Line3d) Line(org.twak.utils.Line) SuperLine(org.twak.viewTrace.SuperLine) Random(java.util.Random) ColorRGBA(com.jme3.math.ColorRGBA) Point3d(javax.vecmath.Point3d) SuperLine(org.twak.viewTrace.SuperLine) List(java.util.List) ArrayList(java.util.ArrayList)

Example 2 with SuperLine

use of org.twak.viewTrace.SuperLine in project chordatlas by twak.

the class Prof method findProfileLines.

/**
 * We find an initial base offset. Then we cluster the start point of all
 * (clean) profiles. If any are a good distance from the initial base, we
 * add those as their own profile lines.
 *
 * The original line is offset by the remaiing data.
 */
public static List<SuperLine> findProfileLines(Collection<Prof> profiles, Line3d line) {
    List<SuperLine> out = new ArrayList();
    // PaintThing.debug.clear();
    SuperLine superLine = new SuperLine(line.start.x, line.start.z, line.end.x, line.end.z);
    double outLen = superLine.length();
    double min = Double.MAX_VALUE, max = -Double.MAX_VALUE;
    Cache<Prof, Double> vLength = new Cache<Prof, Double>() {

        @Override
        public Double create(Prof i) {
            return i.verticalLength(0.5);
        }
    };
    double vLen = profiles.stream().mapToDouble(p -> vLength.get(p)).sum();
    boolean useVertical = vLen / profiles.size() > 1;
    class Wrapper implements Clusterable {

        double[] pt;

        public Wrapper(Point2d pt) {
            this.pt = new double[] { pt.x, pt.y };
        }

        @Override
        public double[] getPoint() {
            return pt;
        }
    }
    List<Wrapper> toCluster = new ArrayList();
    List<Double> baseLineOffset = new ArrayList();
    for (Prof p : profiles) {
        if (// vLen / (5*profiles.size()))
        useVertical && vLength.get(p) < 1)
            continue;
        Prof clean = p.parameterize();
        Point2d pt = clean.get(0);
        Point3d pt3 = clean.to3d(pt);
        double ppram = superLine.findPPram(new Point2d(pt3.x, pt3.z));
        baseLineOffset.add(pt.x);
        toCluster.add(new Wrapper(new Point2d(pt.x, ppram * outLen)));
        min = Math.min(min, ppram);
        max = Math.max(max, ppram);
    }
    if (min == max || toCluster.isEmpty())
        return out;
    if (true) {
        baseLineOffset.sort(Double::compareTo);
        double modeBaselineOffset = baseLineOffset.get(baseLineOffset.size() / 2);
        DBSCANClusterer<Wrapper> cr = new DBSCANClusterer<>(1.5, 0);
        List<Cluster<Wrapper>> results = cr.cluster(toCluster);
        Iterator<Cluster<Wrapper>> cit = results.iterator();
        while (cit.hasNext()) {
            Cluster<Wrapper> cw = cit.next();
            if (cw.getPoints().size() < 2 / TweedSettings.settings.profileHSampleDist) {
                cit.remove();
                double cMeanY = cw.getPoints().stream().mapToDouble(x -> x.pt[1]).average().getAsDouble();
                double bestDist = Double.MAX_VALUE;
                Cluster<Wrapper> bestWrapper = null;
                for (Cluster<Wrapper> near : results) {
                    double meanY = near.getPoints().stream().mapToDouble(x -> x.pt[1]).average().getAsDouble();
                    double dist = Math.abs(meanY - cMeanY);
                    if (dist < bestDist) {
                        bestDist = dist;
                        bestWrapper = near;
                    }
                }
                if (bestWrapper != null)
                    bestWrapper.getPoints().addAll(cw.getPoints());
            }
        }
        {
            baseLineOffset.clear();
            int c = 0;
            for (Cluster<Wrapper> cw : results) {
                double[] minMax = cw.getPoints().stream().map(p -> new double[] { p.pt[1] }).collect(new InAxDoubleArray());
                double[] offsetA = cw.getPoints().stream().mapToDouble(p -> p.pt[0]).sorted().toArray();
                double offset = offsetA[offsetA.length / 2];
                if (offset - modeBaselineOffset < 1) {
                    for (Wrapper w : cw.getPoints()) baseLineOffset.add(w.pt[0]);
                    continue;
                }
                SuperLine sl = new SuperLine(superLine.fromPPram(minMax[0] / outLen), superLine.fromPPram(minMax[1] / outLen));
                sl.moveLeft(offset);
                out.add(sl);
                List<Point2d> pts = cw.getPoints().stream().map(w -> new Point2d(w.pt[0], w.pt[1])).collect(Collectors.toList());
                PaintThing.debug(Rainbow.getColour(c++), 1, pts);
            }
        }
    }
    Point2d nStart = superLine.fromPPram(min), nEnd = superLine.fromPPram(max);
    superLine.start = nStart;
    superLine.end = nEnd;
    baseLineOffset.sort(Double::compare);
    if (!baseLineOffset.isEmpty())
        superLine.moveLeft(baseLineOffset.get(baseLineOffset.size() / 2));
    out.add(0, superLine);
    return out;
}
Also used : ConsecutivePairs(org.twak.utils.collections.ConsecutivePairs) Matrix4d(javax.vecmath.Matrix4d) ConsecutiveItPairs(org.twak.utils.collections.ConsecutiveItPairs) SliceParameters(org.twak.viewTrace.SliceParameters) Arrayz(org.twak.utils.collections.Arrayz) Node(com.jme3.scene.Node) ObjRead(org.twak.utils.geom.ObjRead) Map(java.util.Map) Cache(org.twak.utils.Cache) Material(com.jme3.material.Material) Point3d(javax.vecmath.Point3d) VertexBuffer(com.jme3.scene.VertexBuffer) IdentityHashMap(java.util.IdentityHashMap) Collection(java.util.Collection) Line(org.twak.utils.Line) FindLines(org.twak.viewTrace.FindLines) Set(java.util.Set) Vector2d(javax.vecmath.Vector2d) LinearForm(org.twak.utils.geom.LinearForm) Collectors(java.util.stream.Collectors) List(java.util.List) Rainbow(org.twak.utils.ui.Rainbow) Line3d(org.twak.utils.geom.Line3d) Mesh(com.jme3.scene.Mesh) Geometry(com.jme3.scene.Geometry) DBSCANClusterer(org.apache.commons.math3.ml.clustering.DBSCANClusterer) LinearForm3D(org.twak.utils.geom.LinearForm3D) Bin(org.twak.viewTrace.Bin) Pair(org.twak.utils.Pair) Vector3d(javax.vecmath.Vector3d) Clusterable(org.apache.commons.math3.ml.clustering.Clusterable) Tweed(org.twak.tweed.Tweed) ArrayList(java.util.ArrayList) TweedSettings(org.twak.tweed.TweedSettings) HashSet(java.util.HashSet) PanMouseAdaptor(org.twak.utils.PanMouseAdaptor) Graphics2D(java.awt.Graphics2D) ICanPaintU(org.twak.utils.PaintThing.ICanPaintU) Mathz(org.twak.utils.Mathz) PaintThing(org.twak.utils.PaintThing) Iterator(java.util.Iterator) Point2d(javax.vecmath.Point2d) SuperLine(org.twak.viewTrace.SuperLine) Cluster(org.apache.commons.math3.ml.clustering.Cluster) ColorRGBA(com.jme3.math.ColorRGBA) Comparator(java.util.Comparator) InAxDoubleArray(org.twak.utils.streams.InAxDoubleArray) Collections(java.util.Collections) ObjSlice(org.twak.viewTrace.ObjSlice) ArrayList(java.util.ArrayList) Cluster(org.apache.commons.math3.ml.clustering.Cluster) Clusterable(org.apache.commons.math3.ml.clustering.Clusterable) InAxDoubleArray(org.twak.utils.streams.InAxDoubleArray) Point2d(javax.vecmath.Point2d) Point3d(javax.vecmath.Point3d) SuperLine(org.twak.viewTrace.SuperLine) List(java.util.List) ArrayList(java.util.ArrayList) DBSCANClusterer(org.apache.commons.math3.ml.clustering.DBSCANClusterer) Cache(org.twak.utils.Cache)

Example 3 with SuperLine

use of org.twak.viewTrace.SuperLine in project chordatlas by twak.

the class SkelFootprint method debugFindCleanProfiles.

public static void debugFindCleanProfiles(List<Line> footprint, SkelGen skelGen, ProgressMonitor m, Tweed tweed) {
    MultiMap<SuperLine, List<Prof>> profSets = new MultiMap<>();
    for (Line l : footprint) profileRuns((SuperLine) l, profSets);
    List<List<Prof>> ordered = new ArrayList<>();
    Map<List<Prof>, SuperLine> pairs = new LinkedHashMap<>();
    for (SuperLine l : profSets.keySet()) for (List<Prof> lp : profSets.get(l)) {
        pairs.put(lp, l);
        ordered.add(lp);
    }
    JSlider bunch = new JSlider(0, ordered.size() - 1);
    JButton button = new JButton("go");
    Plot plot = new Plot(bunch, button);
    button.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            PaintThing.debug.clear();
            plot.toPaint.clear();
            List<Prof> ps = ordered.get(bunch.getValue());
            SuperLine sl = pairs.get(ps);
            if (sl != null && ps != null) {
                PaintThing.debug(new Color(0, 0, 0, 50), 1, ps);
                Prof clean = Prof.parameterize(ps);
                Prof c2 = new Prof(clean);
                for (Point2d p : c2) p.x += 10;
                // plot.toPaint.add( clean ) );
                PaintThing.debug(new Color(0, 170, 255), 3f, c2);
                Prof mid = ps.get(ps.size() / 2);
                tweed.enqueue(new Runnable() {

                    @Override
                    public void run() {
                        Jme3z.removeAllChildren(tweed.debug);
                        for (Prof p : ps) {
                            // p = p.moveToX0();
                            p.render(tweed, tweed.debug, ColorRGBA.Blue, (float) TweedSettings.settings.profileHSampleDist);
                        }
                        Point3d pt = mid.to3d(mid.get(0));
                        pt.y = 0;
                        Geometry geom = new Geometry("material_", clean.renderStrip(1, null));
                        Material mat = new Material(tweed.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
                        mat.setColor("Diffuse", ColorRGBA.Blue);
                        mat.setColor("Ambient", ColorRGBA.Red);
                        geom.setMaterial(mat);
                        // tweed.debug.attachChild( geom );
                        tweed.debug.updateGeometricState();
                        tweed.debug.updateModelBound();
                        tweed.gainFocus();
                    }
                });
            }
            plot.repaint();
        }
    });
    bunch.addChangeListener(new ChangeListener() {

        @Override
        public void stateChanged(ChangeEvent e) {
            button.doClick();
        }
    });
}
Also used : ActionEvent(java.awt.event.ActionEvent) Plot(org.twak.utils.ui.Plot) Color(java.awt.Color) ArrayList(java.util.ArrayList) JButton(javax.swing.JButton) Material(com.jme3.material.Material) LinkedHashMap(java.util.LinkedHashMap) Line(org.twak.utils.Line) SuperLine(org.twak.viewTrace.SuperLine) Geometry(com.jme3.scene.Geometry) MultiMap(org.twak.utils.collections.MultiMap) ActionListener(java.awt.event.ActionListener) ChangeEvent(javax.swing.event.ChangeEvent) Point2d(javax.vecmath.Point2d) Point3d(javax.vecmath.Point3d) SuperLine(org.twak.viewTrace.SuperLine) JSlider(javax.swing.JSlider) List(java.util.List) ArrayList(java.util.ArrayList) ChangeListener(javax.swing.event.ChangeListener)

Example 4 with SuperLine

use of org.twak.viewTrace.SuperLine 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;
    }
}
Also used : ArrayList(java.util.ArrayList) SuperLine(org.twak.viewTrace.SuperLine) MegaFacade(org.twak.tweed.gen.ProfileGen.MegaFacade) List(java.util.List) ArrayList(java.util.ArrayList) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace)

Example 5 with SuperLine

use of org.twak.viewTrace.SuperLine in project chordatlas by twak.

the class SkelFootprint method findProfiles.

private void findProfiles(List<Line> footprint, List<Prof> globalProfs) {
    MultiMap<SuperLine, List<Prof>> profSets = new MultiMap<>();
    System.out.println("clustering " + globalProfs.size() + " profiles over sweep edges...");
    for (Line l : footprint) profileRuns((SuperLine) l, profSets);
    Prof example = null;
    System.out.println("cleaning " + profSets.values().stream().flatMap(c -> c.stream()).count() + " profiles...");
    for (SuperLine sl : profSets.keySet()) for (List<Prof> lp : profSets.get(sl)) {
        if (example == null)
            example = lp.get(0);
        Prof p = Prof.parameterize(lp);
        if (p != null && p.size() > 1)
            globalProfs.add(SkelGen.moveToX0(p));
    }
    Iterator<Prof> git = globalProfs.iterator();
    int c = 0;
    // remove trivial
    while (git.hasNext()) {
        Prof p = git.next();
        if (p.size() < 2)
            git.remove();
        else if (p.size() == 2) {
            if (p.get(0).x == p.get(1).x) {
                git.remove();
                c++;
            }
        } else if (p.size() == 3) {
            if (p.get(0).x == p.get(1).x && p.get(2).y == p.get(1).y)
                git.remove();
        }
    }
    System.out.println("found " + globalProfs.size() + " interesting profiles" + " from " + profSets.size() + " runs");
    removeSimilarB(globalProfs, TweedSettings.settings.profilePrune);
    System.out.println("after remove similar " + globalProfs.size());
    // insert single vertical profile
    {
        Prof vertical = defaultProf(example);
        globalProfs.add(0, vertical);
    }
}
Also used : Line(org.twak.utils.Line) SuperLine(org.twak.viewTrace.SuperLine) MultiMap(org.twak.utils.collections.MultiMap) SuperLine(org.twak.viewTrace.SuperLine) List(java.util.List) ArrayList(java.util.ArrayList) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint)

Aggregations

SuperLine (org.twak.viewTrace.SuperLine)14 ArrayList (java.util.ArrayList)9 Point2d (javax.vecmath.Point2d)8 Line (org.twak.utils.Line)8 List (java.util.List)6 Point3d (javax.vecmath.Point3d)6 MFPoint (org.twak.tweed.gen.FeatureCache.MFPoint)6 MegaFacade (org.twak.tweed.gen.ProfileGen.MegaFacade)6 HalfEdge (org.twak.utils.geom.HalfMesh2.HalfEdge)6 ColorRGBA (com.jme3.math.ColorRGBA)5 Material (com.jme3.material.Material)4 Geometry (com.jme3.scene.Geometry)4 Node (com.jme3.scene.Node)4 HashSet (java.util.HashSet)4 LinkedHashMap (java.util.LinkedHashMap)4 Vector2d (javax.vecmath.Vector2d)4 HalfFace (org.twak.utils.geom.HalfMesh2.HalfFace)4 Mesh (com.jme3.scene.Mesh)3 VertexBuffer (com.jme3.scene.VertexBuffer)3 Color (java.awt.Color)3