Esempio n. 1
0
def triTriSplit(skel, anchor, itchy, scratchy, tri1, tri2):
    #
    #
    # scratchy /|\               |\
    #         / | \              | \
    #        /  |  \           C | A\   If tri1.dominantPixel is different
    #       /tri|tri\T0    ===>  |___\  from tri2.dominantPixel ...
    # anchor\ 1 | 2 /            |   /
    #        \  |  /           D | B/
    #         \ | /              | /
    #   itchy  \|/               |/
    #
    #
    #          /|\              / \
    #         / | \            /   \
    #        /  |  \          /     \   If tri1.dominantPixel is the same as
    #       /tri|tri\   ===> /_______\  from tri2.dominantPixel ...
    #       \ 1 | 2 /        \       /
    #        \  |  /          \     /
    #         \ | /            \   /
    #          \|/              \ /
    #

    # If itchy and scratchy are pinned, the process should be aborted
    if itchy.pinned() and scratchy.pinned():
        return []

    # Find the midpoint of the segment, and its periodic partner, if
    # it exists.
    midpoint, midpoint2 = _midpoints(skel, itchy, scratchy)
    periodic = midpoint2 is not None

    # Find the nodes of tri2 that correspond to itchy and scratchy.
    # If the border between tri and quad is a periodic boundary, these
    # nodes aren't the same as itchy and scratchy!
    if periodic:
        partners = itchy.getPartnerPair(scratchy)
        itchy2, scratchy2 = partners
    else:
        itchy2, scratchy2 = itchy, scratchy

    tri2nodes = tri2.nodes
    t0 = tri2nodes[(tri2nodes.index(itchy2) + 1) % 3]
    parents = tri2.getParents()
    changes = []

    if anchor.movable_x() and anchor.movable_y() and not anchor.getPartners():
        if not periodic:
            change0 = skeleton.ProvisionalChanges(skel)
            change0.moveNode(anchor, midpoint)
            change0.removeElements(tri1, tri2)
            change0.insertElements(
                ProvisionalTriangle([anchor, t0, scratchy], parents=parents),
                ProvisionalTriangle([anchor, itchy, t0], parents=parents))
        else:  # periodic
            change0 = skeleton.ProvisionalInsertion(skel)
            newanchor = skel.newNode(midpoint.x, midpoint.y)
            anchor2 = skel.newNode(midpoint2.x, midpoint2.y)
            newanchor.addPartner(anchor2)
            elsubs = [(el, el.provisionalReplacement(anchor, newanchor))
                      for el in anchor.aperiodicNeighborElements(skel)
                      if el is not tri1]
            change0.removeElements(tri1, tri2)
            for oldel, newel in elsubs:
                change0.substituteElement(oldel, newel)
            change0.insertElements(
                ProvisionalTriangle([anchor2, t0, scratchy2], parents=parents),
                ProvisionalTriangle([anchor2, itchy2, t0], parents=parents))
            change0.addNode(newanchor)
            change0.addNode(anchor2)
        changes.append(change0)

    if not periodic:
        change1 = skeleton.ProvisionalChanges(skel)
        change1.removeElements(tri1, tri2)
        parents = tri1.getParents() + tri2.getParents()
        change1.insertElements(
            ProvisionalTriangle([anchor, t0, scratchy], parents=parents),
            ProvisionalTriangle([anchor, itchy, t0], parents=parents))
        changes.append(change1)

    return changes
Esempio n. 2
0
    def quadquadSwap(skel, n0, n1, quad0, quad1):
        #           n1
        #          /|\
        #         / | \
        #        /  |  \          [n0, n4, n2, n3] & [n4, n5, n1, n2]
        #     n2|   |   |n5       [n0, n4, n5, n3] & [n5, n1, n2, n3]
        #       |q0 |q1 |     ==>
        #     n3|   |   |n4
        #        \  |  /
        #         \ | /
        #          \|/
        #           n0

        #           n1
        #          /|\
        #         / | \
        #        /  |  \
        #     n2|  /n6  |n5
        #       | /   \ |     ==> [n0, n4, n6, n3] & [n3, n6, n1, n2] &
        #     n3|/     \|n4       [n6, n4, n5, n1]
        #        \     /           n6 = (n3+n4+n1)/3.
        #         \   /
        #          \ /
        #           n0

        #           n1
        #          / \
        #         /   \
        #        /     \
        #     n2|\     /|n5
        #       | \   / |     ==> [n7, n5, n1, n2] & [n3, n0, n7, n2] &
        #     n3|  \n7  |n4       [n0, n4, n5, n7]
        #        \  |  /          n7 = (n2+n0+n5)/3.
        #         \ | /
        #          \|/
        #           n0

        if (n0.pinned() and n1.pinned()) and \
           (quad0.dominantPixel(skel.MS) != quad1.dominantPixel(skel.MS)):
            return []

        i = quad0.nodes.index(n1)
        n2 = quad0.nodes[(i + 1) % 4]
        n3 = quad0.nodes[(i + 2) % 4]
        i = quad1.nodes.index(n0)
        n4 = quad1.nodes[(i + 1) % 4]
        n5 = quad1.nodes[(i + 2) % 4]

        parents = quad0.getParents() + quad1.getParents()

        A = ProvisionalQuad([n0, n4, n2, n3], parents=parents)
        B = ProvisionalQuad([n4, n5, n1, n2], parents=parents)
        change0 = skeleton.ProvisionalChanges(skel)
        change0.insertElements(A, B)
        change0.removeElements(quad0, quad1)

        C = ProvisionalQuad([n0, n4, n5, n3], parents=parents)
        D = ProvisionalQuad([n5, n1, n2, n3], parents=parents)
        change1 = skeleton.ProvisionalChanges(skel)
        change1.insertElements(C, D)
        change1.removeElements(quad0, quad1)

        pos = (n3.position() + n4.position() + n1.position()) / 3.0
        n6 = skel.newNode(pos.x, pos.y)
        E = ProvisionalQuad([n0, n4, n6, n3], parents=parents)
        F = ProvisionalQuad([n3, n6, n1, n2], parents=quad0.getParents())
        G = ProvisionalQuad([n6, n4, n5, n1], parents=quad1.getParents())
        change2 = skeleton.ProvisionalInsertion(skel)
        change2.addNode(n6)
        change2.insertElements(E, F, G)
        change2.removeElements(quad0, quad1)

        pos = (n2.position() + n0.position() + n5.position()) / 3.0
        n7 = skel.newNode(pos.x, pos.y)
        H = ProvisionalQuad([n7, n5, n1, n2], parents=parents)
        I = ProvisionalQuad([n3, n0, n7, n2], parents=quad0.getParents())
        J = ProvisionalQuad([n0, n4, n5, n7], parents=quad1.getParents())
        change3 = skeleton.ProvisionalInsertion(skel)
        change3.addNode(n7)
        change3.insertElements(H, I, J)
        change3.removeElements(quad0, quad1)

        # If source elements are 100 % homogeneous with the same dominant pixel,
        # resulting elements will be so.
        if quad0.homogeneity(skel.MS)==1. and quad1.homogeneity(skel.MS)==1. and \
           quad0.dominantPixel(skel.MS)==quad1.dominantPixel(skel.MS):
            A.copyHomogeneity(quad0)
            B.copyHomogeneity(quad0)
            C.copyHomogeneity(quad0)
            D.copyHomogeneity(quad0)
            E.copyHomogeneity(quad0)
            F.copyHomogeneity(quad0)
            G.copyHomogeneity(quad0)
            H.copyHomogeneity(quad0)
            I.copyHomogeneity(quad0)
            J.copyHomogeneity(quad0)

        return [change0, change1, change2, change3]
Esempio n. 3
0
def triQuadSplit(skel, anchor, itchy, scratchy, tri, quad):

    # If tri.dominantPixel is different from quad.dominantPixel ...
    # Pick the best of three configurations.
    #            ___________        ______      ______      ______
    # scratchy /|          Q1       |   /|      |   /|      |    |
    #         / |          |        |C / |      |B / |      |    |
    #        /  |          |        | /  |      | /  |      |  B |
    #       /tri|  quad    |  ===>  |/   |      |/   |      |    |
    # anchor\   |          |        |\ B |      |    |      |\   |
    #        \  |          |        | \  |      | A  |      | \  |
    #         \ |          |        |A \ |      |    |      |A \ |
    #   itchy  \|__________Q0       |___\|      |____|      |___\|
    #

    # If tri & quad have same dominantPixel and aren't separated by a
    # periodic boundary, consider this geometry as well:
    #            ___________            _________
    #          /|          |           /      . |
    #         / |          |          / C  .    |
    #        /  |          |         /  .       |
    #       /tri|  quad    |  ===>  /.     B    | Three different cases
    #       \   |          |        \   .       | as in the above
    #        \  |          |         \     .    |
    #         \ |          |          \  A    . |
    #          \|__________|           \________|
    #

    # If itchy and scratchy are pinned, the process should be aborted
    if itchy.pinned() and scratchy.pinned():
        return []

    # Find the midpoint of the segment, and its periodic partner, if
    # it exists.
    midpoint, midpointQ = _midpoints(skel, itchy, scratchy)
    periodic = midpointQ is not None

    # Find the nodes of the quad that correspond to itchy and
    # scratchy.  If the border between tri and quad is a periodic
    # boundary, these nodes aren't the same as itchy and scratchy!
    if periodic:
        partners = itchy.getPartnerPair(scratchy)
        itchyQ, scratchyQ = partners
    else:
        itchyQ, scratchyQ = itchy, scratchy

    # Find nodes Q0 and Q1
    quadnodes = quad.nodes
    itchyindex = quadnodes.index(itchyQ)
    q0 = quadnodes[(itchyindex + 1) % 4]
    q1 = quadnodes[(itchyindex + 2) % 4]

    parents = quad.getParents()
    changes = []

    # Cases that move the anchor point.  Don't do these at all if the
    # anchor is a periodic node or not otherwise movable:
    if anchor.movable_x() and anchor.movable_y() and not anchor.getPartners():
        # Divide the quad into three triangles.  The periodic case is
        # complicated because it has to replace the aperiodic anchor
        # Node with a periodic one, and that requires replacing all of
        # the elements connected to the anchor point.  We do the
        # periodic and aperiodic cases completely separately here.
        if not periodic:
            change0 = skeleton.ProvisionalChanges(skel)
            change0.moveNode(anchor, midpoint)
            change0.removeElements(tri, quad)
            change0.insertElements(
                ProvisionalTriangle([anchor, itchy, q0], parents=parents),
                ProvisionalTriangle([anchor, q0, q1], parents=parents),
                ProvisionalTriangle([anchor, q1, scratchy], parents=parents))

            change1 = skeleton.ProvisionalChanges(skel)
            change1.moveNode(anchor, midpoint)
            change1.removeElements(tri, quad)
            parents = quad.getParents()
            change1.insertElements(
                ProvisionalQuad([anchor, itchy, q0, q1], parents=parents),
                ProvisionalTriangle([anchor, q1, scratchy], parents=parents))

            change2 = skeleton.ProvisionalChanges(skel)
            change2.moveNode(anchor, midpoint)
            change2.removeElements(tri, quad)
            parents = quad.getParents()
            change2.insertElements(
                ProvisionalTriangle([anchor, itchy, q0], parents=parents),
                ProvisionalQuad([anchor, q0, q1, scratchy], parents=parents))
        else:
            # Three ways of moving the anchor point to the *periodic*
            # boundary and dividing the quad.
            newanchor, anchorQ, elsubs = triquadhelper(skel, tri, anchor,
                                                       midpoint, midpointQ)
            change0 = skeleton.ProvisionalInsertion(skel)
            change0.removeElements(quad, tri)
            change0.addNode(newanchor)
            change0.addNode(anchorQ)
            for oldel, newel in elsubs:
                change0.substituteElement(oldel, newel)
            change0.insertElements(
                ProvisionalTriangle([anchorQ, itchyQ, q0], parents=parents),
                ProvisionalTriangle([anchorQ, q0, q1], parents=parents),
                ProvisionalTriangle([anchorQ, q1, scratchyQ], parents=parents))

            newanchor, anchorQ, elsubs = triquadhelper(skel, tri, anchor,
                                                       midpoint, midpointQ)
            change1 = skeleton.ProvisionalInsertion(skel)
            change1.removeElements(quad, tri)
            change1.addNode(newanchor)
            change1.addNode(anchorQ)
            for oldel, newel in elsubs:
                change1.substituteElement(oldel, newel)
            change1.insertElements(
                ProvisionalQuad([anchorQ, itchyQ, q0, q1], parents=parents),
                ProvisionalTriangle([anchorQ, q1, scratchyQ], parents=parents))

            newanchor, anchorQ, elsubs = triquadhelper(skel, tri, anchor,
                                                       midpoint, midpointQ)
            change2 = skeleton.ProvisionalInsertion(skel)
            change2.removeElements(quad, tri)
            change2.addNode(newanchor)
            change2.addNode(anchorQ)
            for oldel, newel in elsubs:
                change2.substituteElement(oldel, newel)
            change2.insertElements(
                ProvisionalTriangle([anchorQ, itchyQ, q0], parents=parents),
                ProvisionalQuad([anchorQ, q0, q1, scratchyQ], parents=parents))

        changes.extend([change0, change1, change2])

    # Cases for lazy (immobile) anchor.  These can only be done if tri
    # and quad don't span a periodic boundary.
    if not periodic:
        change3 = skeleton.ProvisionalChanges(skel)
        change3.removeElements(tri, quad)
        parents = quad.getParents() + tri.getParents()
        change3.insertElements(
            ProvisionalTriangle([anchor, itchy, q0], parents=parents),
            ProvisionalTriangle([anchor, q0, q1], parents=parents),
            ProvisionalTriangle([anchor, q1, scratchy], parents=parents))

        change4 = skeleton.ProvisionalChanges(skel)
        change4.removeElements(tri, quad)
        parents = quad.getParents()
        change4.insertElements(
            ProvisionalQuad([anchor, itchy, q0, q1], parents=parents),
            ProvisionalTriangle([anchor, q1, scratchy], parents=parents))

        change5 = skeleton.ProvisionalChanges(skel)
        change5.removeElements(tri, quad)
        parents = quad.getParents()
        change5.insertElements(
            ProvisionalTriangle([anchor, itchy, q0], parents=parents),
            ProvisionalQuad([anchor, q0, q1, scratchy], parents=parents))

        changes.extend([change3, change4, change5])

    return changes