Search in sources :

Example 1 with Face

use of org.twak.camp.Output.Face in project chordatlas by twak.

the class GreebleSkel method findSE.

private static double[] findSE(MiniFacade mf, Line l, List<Face> chain) {
    double mlen = l.length();
    double lowest = Double.MAX_VALUE;
    Face bestFace = null;
    for (Face f : chain) {
        double[] bounds = Loopz.minMax(f.getLoopL());
        if (bounds[5] - bounds[4] > 1 && bounds[4] < lowest) {
            bestFace = f;
            lowest = bounds[4];
        }
    }
    if (bestFace == null)
        // !
        return new double[] { mf.left, mf.left + mf.width };
    List<Double> params = bestFace.getLoopL().streamE().map(p3 -> l.findPPram(new Point2d(p3.x, p3.y))).collect(Collectors.toList());
    double[] out = new double[] { params.stream().mapToDouble(x -> x).min().getAsDouble() * mlen, params.stream().mapToDouble(x -> x).max().getAsDouble() * mlen };
    // if good, stretch whole minifacade to mesh
    if (Mathz.inRange((out[1] - out[0]) / (mf.width), 0.66, 1.4))
        return out;
    // else snap to the closest of start/end
    if (l.fromPPram(out[0] / mlen).distance(l.fromPPram(mf.left / mlen)) > l.fromPPram(out[1] / mlen).distance(l.fromPPram((mf.left + mf.width) / mlen)))
        return new double[] { out[1] - mf.width, out[1] };
    else
        return new double[] { out[0], out[0] + mf.width };
}
Also used : LinearForm3D(org.twak.utils.geom.LinearForm3D) PlanSkeleton(org.twak.siteplan.campskeleton.PlanSkeleton) Matrix4d(javax.vecmath.Matrix4d) ClickMe(org.twak.tweed.ClickMe) Tag(org.twak.camp.Tag) Vector3d(javax.vecmath.Vector3d) Bar(org.twak.camp.ui.Bar) Tweed(org.twak.tweed.Tweed) ArrayList(java.util.ArrayList) TweedSettings(org.twak.tweed.TweedSettings) HashSet(java.util.HashSet) SETag(org.twak.tweed.gen.skel.SETag) Loop(org.twak.utils.collections.Loop) Node(com.jme3.scene.Node) SwingUtilities(javax.swing.SwingUtilities) Pointz(org.twak.tweed.gen.Pointz) Mathz(org.twak.utils.Mathz) SuperEdge(org.twak.tweed.gen.SuperEdge) Point3d(javax.vecmath.Point3d) ColumnProperties(org.twak.siteplan.campskeleton.PlanSkeleton.ColumnProperties) LoopL(org.twak.utils.collections.LoopL) Iterator(java.util.Iterator) Output(org.twak.camp.Output) Edge(org.twak.camp.Edge) Line(org.twak.utils.Line) Set(java.util.Set) MeshBuilder(org.twak.siteplan.jme.MeshBuilder) LinearForm(org.twak.utils.geom.LinearForm) Collectors(java.util.stream.Collectors) LPoint2d(org.twak.viewTrace.facades.GreebleHelper.LPoint2d) Loopz(org.twak.utils.collections.Loopz) Point2d(javax.vecmath.Point2d) LPoint3d(org.twak.viewTrace.facades.GreebleHelper.LPoint3d) List(java.util.List) Loopable(org.twak.utils.collections.Loopable) DRectangle(org.twak.utils.geom.DRectangle) Optional(java.util.Optional) Face(org.twak.camp.Output.Face) Feature(org.twak.viewTrace.facades.MiniFacade.Feature) LPoint2d(org.twak.viewTrace.facades.GreebleHelper.LPoint2d) Point2d(javax.vecmath.Point2d) Face(org.twak.camp.Output.Face)

Example 2 with Face

use of org.twak.camp.Output.Face in project chordatlas by twak.

the class GreebleEdge method roowWallGreeble.

public static void roowWallGreeble(Output output, MeshBuilder roof, MeshBuilder wall) {
    MultiMap<Point3d, SharedEdge> boundary = new MultiMap<>();
    Set<SharedEdge> roofWallBoundary = new HashSet<>();
    for (Face f1 : output.faces.values()) for (Loop<SharedEdge> sl : f1.edges) for (Loopable<SharedEdge> se : sl.loopableIterator()) {
        Face f2 = se.get().getOther(f1);
        if (isWall(f1) ^ isWall(f2)) {
            boundary.put(se.get().getStart(f1), se.get());
            roofWallBoundary.add(se.get());
        }
    }
    for (SharedEdge se : roofWallBoundary) {
        if (se.start.z < 1 || se.end.z < 1)
            // something strange here...
            continue;
        Face f1 = se.left, f2 = se.right;
        if (f1 == null || f2 == null)
            continue;
        EdgePoint bs = findAdjacent(se.start, se.end, boundary), be = findAdjacent(se.end, se.start, boundary);
        if (bs != null && be != null) {
            LinearForm3D cutS, cutE;
            if (isOverhang(bs.se))
                // between two angles
                cutS = cut(bs.pt, se.start, se.end);
            else
                // flat at end
                cutS = new LinearForm3D(LinearForm3D.linePerp(toXZ(se.end), toXZ(se.start)));
            if (isOverhang(be.se))
                cutE = cut(se.start, se.end, be.pt);
            else
                // flat at end
                cutE = new LinearForm3D(LinearForm3D.linePerp(toXZ(se.start), toXZ(se.end)));
            LinearForm3D right = new LinearForm3D(toXZ(f1.edge.getPlaneNormal()), toXZ(f1.edge.start)), left = new LinearForm3D(toXZ(f2.edge.getPlaneNormal()), toXZ(f2.edge.start));
            Tube.tube(roof, Collections.singleton(cutS), Collections.singleton(cutE), new Line3d(toXZ(se.start), toXZ(se.end)), left, right, isOverhang(se) ? new OverhangCross() : new LipCross());
        }
    }
}
Also used : Loop(org.twak.utils.collections.Loop) LinearForm3D(org.twak.utils.geom.LinearForm3D) Line3d(org.twak.utils.geom.Line3d) MultiMap(org.twak.utils.collections.MultiMap) SharedEdge(org.twak.camp.Output.SharedEdge) Point3d(javax.vecmath.Point3d) Face(org.twak.camp.Output.Face) HashSet(java.util.HashSet)

Example 3 with Face

use of org.twak.camp.Output.Face in project chordatlas by twak.

the class GreebleEdge method isOverhang.

private static boolean isOverhang(SharedEdge se) {
    Face f1 = se.left, f2 = se.right;
    if (f1 == null || f2 == null)
        return false;
    double angle = f1.edge.getPlaneNormal().angle(f2.edge.getPlaneNormal());
    return angle < Math.PI * 0.4;
}
Also used : Face(org.twak.camp.Output.Face)

Example 4 with Face

use of org.twak.camp.Output.Face in project chordatlas by twak.

the class GreebleEdge method roofGreeble.

public static boolean roofGreeble(Face f, MeshBuilder roof) {
    boolean isWall = isWall(f);
    for (Loop<SharedEdge> sl : f.edges) {
        for (Loopable<SharedEdge> sel : sl.loopableIterator()) {
            SharedEdge se = sel.get();
            boolean otherIsWall = isWall(se.getOther(f));
            if (!isWall && !otherIsWall) {
                Face oF = se.getOther(f);
                if (oF == null || order(f, oF) || f.edge.getPlaneNormal().angle(oF.edge.getPlaneNormal()) < 0.4)
                    continue;
                List<LinearForm3D> start = new ArrayList(), end = new ArrayList<>();
                {
                    SharedEdge fPrev = se.getAdjEdge(f, false), fNext = se.getAdjEdge(f, true), ofPrev = se.getAdjEdge(oF, false), ofNext = se.getAdjEdge(oF, true);
                    if (fNext == null || fPrev == null || ofNext == null || ofPrev == null)
                        continue;
                    double overHang = -0.03;
                    if (isWall(fNext.getOther(f)))
                        end.add(toLF(fNext.getOther(f), overHang));
                    else
                        end.add(roofTween(fNext, se, f));
                    if (isWall(ofPrev.getOther(oF)))
                        end.add(toLF(ofPrev.getOther(oF), overHang));
                    else
                        end.add(roofTween(se, ofPrev, oF));
                    if (isWall(fPrev.getOther(f)))
                        start.add(toLF(fPrev.getOther(f), overHang));
                    else
                        start.add(roofTween(se, fPrev, f));
                    if (isWall(ofNext.getOther(oF)))
                        start.add(toLF(ofNext.getOther(oF), overHang));
                    else
                        start.add(roofTween(ofNext, se, oF));
                }
                Point3d s = se.getStart(f), e = se.getEnd(f);
                if (end.contains(null) || start.contains(null))
                    continue;
                Tube.tube(roof, end, start, new Line3d(new Point3d(s.x, s.z, s.y), new Point3d(e.x, e.z, e.y)), toLF(f, 0), toLF(oF, 0), new CrossGen() {

                    @Override
                    public List<Point2d> gen(Vector2d left, Vector2d right) {
                        Vector2d l = new Vector2d(left);
                        l.normalize();
                        Vector2d lP = new Vector2d(l.y, -l.x);
                        Vector2d r = new Vector2d(right);
                        r.normalize();
                        Vector2d rP = new Vector2d(-r.y, r.x);
                        List<Point2d> out = new ArrayList();
                        double width = 0.15, height = 0.03;
                        Vector2d rn = new Vector2d(r);
                        rn.negate();
                        // height / Math.sin ( ( Math.PI - l.angle( rn ) ) /2 );
                        double cenOffset = 0.02;
                        Vector2d cen = new Vector2d(lP);
                        cen.add(rP);
                        cen.normalize();
                        for (double[] coords : new double[][] { { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, -width }, { 0, 0, 0, height, -width }, { 0, 0, cenOffset, 0, 0 }, { -width, height, 0, 0, 0 }, { -width, 0, 0, 0, 0 } }) {
                            Point2d tmp = new Point2d(l), tmp2;
                            tmp.scale(coords[0]);
                            tmp2 = new Point2d(lP);
                            tmp2.scale(coords[1]);
                            tmp.add(tmp2);
                            tmp2 = new Point2d(cen);
                            tmp2.scale(coords[2]);
                            tmp.add(tmp2);
                            tmp2 = new Point2d(rP);
                            tmp2.scale(coords[3]);
                            tmp.add(tmp2);
                            tmp2 = new Point2d(r);
                            tmp2.scale(coords[4]);
                            tmp.add(tmp2);
                            out.add(tmp);
                        }
                        return out;
                    }
                });
            }
        }
    }
    return true;
}
Also used : ArrayList(java.util.ArrayList) LinearForm3D(org.twak.utils.geom.LinearForm3D) Line3d(org.twak.utils.geom.Line3d) SharedEdge(org.twak.camp.Output.SharedEdge) Vector2d(javax.vecmath.Vector2d) Point2d(javax.vecmath.Point2d) Point3d(javax.vecmath.Point3d) CrossGen(org.twak.viewTrace.facades.Tube.CrossGen) ArrayList(java.util.ArrayList) List(java.util.List) Face(org.twak.camp.Output.Face)

Example 5 with Face

use of org.twak.camp.Output.Face in project chordatlas by twak.

the class GreebleHelper method findPerimeter.

public static LoopL<LPoint3d> findPerimeter(Face f) {
    LoopL<LPoint3d> out = new LoopL<>();
    for (Loop<SharedEdge> loop : f.edges) {
        Loop<LPoint3d> lout = new Loop<>();
        out.add(lout);
        for (SharedEdge se : loop) {
            String label;
            Face other = se.getOther(f);
            if (other == null || se.start.z < 0.1 && se.end.z < 0.1)
                label = FLOOR_EDGE;
            else if (GreebleEdge.isWall(other))
                label = WALL_EDGE;
            else
                label = ROOF_EDGE;
            Point3d pt = se.getStart(f);
            if (pt != null)
                lout.append(new LPoint3d(pt, label));
        }
    }
    return out;
}
Also used : Loop(org.twak.utils.collections.Loop) SharedEdge(org.twak.camp.Output.SharedEdge) Point3d(javax.vecmath.Point3d) LoopL(org.twak.utils.collections.LoopL) Face(org.twak.camp.Output.Face)

Aggregations

Face (org.twak.camp.Output.Face)7 Point3d (javax.vecmath.Point3d)5 List (java.util.List)4 Loop (org.twak.utils.collections.Loop)4 LinearForm3D (org.twak.utils.geom.LinearForm3D)4 ArrayList (java.util.ArrayList)3 HashSet (java.util.HashSet)3 Set (java.util.Set)3 Collectors (java.util.stream.Collectors)3 Point2d (javax.vecmath.Point2d)3 Output (org.twak.camp.Output)3 SharedEdge (org.twak.camp.Output.SharedEdge)3 LoopL (org.twak.utils.collections.LoopL)3 Node (com.jme3.scene.Node)2 Iterator (java.util.Iterator)2 Optional (java.util.Optional)2 SwingUtilities (javax.swing.SwingUtilities)2 Matrix4d (javax.vecmath.Matrix4d)2 Vector3d (javax.vecmath.Vector3d)2 Edge (org.twak.camp.Edge)2