Search in sources :

Example 56 with Line

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

the class SkelFootprint method minMax.

private static double[] minMax(double expand, List<Line> footprint) {
    double[] out = new double[] { Double.MAX_VALUE, -Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE };
    for (Line l : footprint) {
        out[0] = Math.min(l.start.x, out[0]);
        out[1] = Math.max(l.start.x, out[1]);
        out[2] = Math.min(l.start.y, out[2]);
        out[3] = Math.max(l.start.y, out[3]);
    }
    out[0] -= expand;
    out[1] += expand;
    out[2] -= expand;
    out[3] += expand;
    return out;
}
Also used : Line(org.twak.utils.Line) SuperLine(org.twak.viewTrace.SuperLine)

Example 57 with Line

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

the class SkelFootprint method fractureOnFeatures.

private void fractureOnFeatures(MultiMap<MegaFeatures, MFPoint> minis, List<Line> footprint, HalfMesh2 mesh) {
    for (MegaFeatures mf : minis.keySet()) pt: for (MFPoint pt : minis.get(mf)) {
        if (!Mathz.inRange(mf.megafacade.findPPram(pt), 0, 1))
            continue;
        Vector2d dir = pt.mega.megafacade.dir();
        dir.set(dir.y, -dir.x);
        Point2d probe = new Point2d(dir);
        probe.scale(2 / dir.length());
        probe.add(pt);
        for (// don't fracture near minifacade boundaries...we can't distinguish nice block bondaries
        Point2d avoid : // don't fracture near minifacade boundaries...we can't distinguish nice block bondaries
        pt.mega.megafacade.points()) if (avoid.distanceSquared(pt) < 4)
            continue pt;
        double bestDist = Double.MAX_VALUE;
        for (HalfFace f : mesh.faces) for (HalfEdge e : f) if (e.line().dir().angle(dir) < 0.4) {
            double dist = e.line().distance(probe);
            if (dist < bestDist)
                bestDist = dist;
        }
        if (bestDist > 0.3) {
            Vector2d end = new Vector2d(dir);
            end.scale(3 / end.length());
            end.add(probe);
            Vector2d start = new Vector2d(dir);
            start.scale(0.5 / start.length());
            start.add(pt);
            Line extra = new Line(new Point2d(start), new Point2d(end));
            SkelFootprint.insert(mesh, extra, 2, false, false);
        }
    }
}
Also used : Line(org.twak.utils.Line) SuperLine(org.twak.viewTrace.SuperLine) MegaFeatures(org.twak.tweed.gen.FeatureCache.MegaFeatures) Vector2d(javax.vecmath.Vector2d) Point2d(javax.vecmath.Point2d) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace)

Example 58 with Line

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

the class LineGen method calculate.

@Override
public void calculate() {
    for (Spatial s : gNode.getChildren()) s.removeFromParent();
    Mesh m = new Mesh();
    m.setMode(Mesh.Mode.Lines);
    List<Float> coords = new ArrayList();
    List<Integer> inds = new ArrayList();
    for (Line l : getLines()) {
        inds.add(inds.size());
        inds.add(inds.size());
        coords.add((float) l.start.x);
        coords.add(0f);
        coords.add((float) l.start.y);
        coords.add((float) l.end.x);
        coords.add(0f);
        coords.add((float) l.end.y);
    }
    m.setBuffer(VertexBuffer.Type.Position, 3, Arrayz.toFloatArray(coords));
    m.setBuffer(VertexBuffer.Type.Index, 2, Arrayz.toIntArray(inds));
    geom = new Geometry(filename, m);
    Material lineMaterial = new Material(tweed.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
    lineMaterial.setColor("Color", new ColorRGBA(color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, 1f));
    geom.setMaterial(lineMaterial);
    for (Spatial s : gNode.getChildren()) s.removeFromParent();
    geom.setLocalTranslation(0, height * 30, 0);
    gNode.attachChild(geom);
    geom.updateModelBound();
    super.calculate();
}
Also used : Line(org.twak.utils.Line) Geometry(com.jme3.scene.Geometry) ColorRGBA(com.jme3.math.ColorRGBA) Spatial(com.jme3.scene.Spatial) ArrayList(java.util.ArrayList) Mesh(com.jme3.scene.Mesh) Material(com.jme3.material.Material)

Example 59 with Line

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

the class ProfileGen method findMegaFaces.

private List<MegaFacade> findMegaFaces(double delta) {
    SliceParameters P = new SliceParameters(SLICE_SCALE);
    List<LineAtHeight> lines = new ArrayList();
    Map<Integer, LineSoup> slices = new HashMap<>();
    for (int hi = 0; getHeight(hi) < extent[3]; hi++) {
        int _i = hi;
        boolean error;
        int count = 0;
        do {
            error = false;
            try {
                LineSoup soup = new LineSoup(ObjSlice.sliceTri(blockGen.getCroppedMesh(), getHeight(hi), majorAxis));
                FindLines foundLines = new FindLines(soup, TweedSettings.settings.useGis ? gisBias : null, -1, null, P);
                foundLines.result.all.stream().forEach(x -> lines.add(new LineAtHeight(_i, delta, x, foundLines.result.all)));
                slices.put(hi, foundLines.result);
            } catch (Throwable th) {
                th.printStackTrace();
                error = true;
            }
        } while (error && count++ < 10);
    }
    Collections.sort(lines, new LAHComparator());
    // new Plot(lines.stream().map (lah -> lah.line).collect(Collectors.toList() ), gis);
    faces = new ArrayList<>();
    while (!lines.isEmpty()) {
        System.out.println("clustering megafacdes " + lines.size());
        // longest line
        LineAtHeight start = lines.get(0);
        lines.remove(start);
        MegaFacade face = new MegaFacade(start);
        Set<LineAtHeight> toProcess = new HashSet<>();
        toProcess.add(start);
        while (!toProcess.isEmpty()) {
            LineAtHeight lah = toProcess.iterator().next();
            toProcess.remove(lah);
            for (int _pmDelta : new int[] { -2, -1, 1, 2 }) {
                int hi = lah.height + _pmDelta;
                LineSoup ls = slices.get(hi);
                if (ls != null) {
                    for (Line l : ls.all) {
                        double lps = start.line.findPPram(l.start), lpe = start.line.findPPram(l.end);
                        double overlap = 0;
                        if (lpe < lps)
                            overlap = 0;
                        else if (lps > face.minP && lpe < face.maxP || lps < face.minP && lpe > face.maxP)
                            overlap = 1;
                        else if (lps < face.minP && lpe > face.minP)
                            overlap = (lpe - face.minP) / (lpe - lps);
                        else if (lps < face.maxP && lpe > face.maxP)
                            overlap = (face.maxP - lps) / (lpe - lps);
                        double angle = l.absAngle(start.line);
                        if (overlap > 0.8 && angle < 0.3 || overlap > 0.5 && /* 0.1 for aggressive clustering */
                        angle < 0.1) {
                            // if (overlap > 0.1 && angle < 0.5 ) {
                            if (l.distance(lah.line) < delta * TweedSettings.settings.megafacacadeClusterGradient) {
                                LineAtHeight toProc = new LineAtHeight(hi, l);
                                if (lines.contains(toProc)) {
                                    toProcess.add(toProc);
                                    face.put(hi, l);
                                    lines.remove(toProc);
                                    // bit strange: depends on the processing order of the set
                                    face.minP = Mathz.min(face.minP, lps);
                                    face.maxP = Mathz.max(face.maxP, lpe);
                                }
                            }
                        }
                    }
                }
            }
        }
        if (face.values().stream().flatMap(x -> x.stream()).count() > 5)
            faces.add(face);
        else
            System.out.println("skipping small megafacade");
    }
    Collections.sort(faces);
    processMegaFaces();
    return faces;
}
Also used : FindLines(org.twak.viewTrace.FindLines) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) CullHint(com.jme3.scene.Spatial.CullHint) Line(org.twak.utils.Line) SuperLine(org.twak.viewTrace.SuperLine) SliceParameters(org.twak.viewTrace.SliceParameters) LineSoup(org.twak.viewTrace.LineSoup) HashSet(java.util.HashSet)

Aggregations

Line (org.twak.utils.Line)59 Point2d (javax.vecmath.Point2d)38 ArrayList (java.util.ArrayList)25 SuperLine (org.twak.viewTrace.SuperLine)22 List (java.util.List)16 Point3d (javax.vecmath.Point3d)14 HashSet (java.util.HashSet)13 LinearForm (org.twak.utils.geom.LinearForm)13 HashMap (java.util.HashMap)12 Map (java.util.Map)11 Set (java.util.Set)11 HalfEdge (org.twak.utils.geom.HalfMesh2.HalfEdge)11 HalfFace (org.twak.utils.geom.HalfMesh2.HalfFace)11 Collectors (java.util.stream.Collectors)10 Vector2d (javax.vecmath.Vector2d)10 Iterator (java.util.Iterator)9 Vector3d (javax.vecmath.Vector3d)9 Tweed (org.twak.tweed.Tweed)8 TweedSettings (org.twak.tweed.TweedSettings)8 MFPoint (org.twak.tweed.gen.FeatureCache.MFPoint)8