Beispiel #1
0
def cdtFromPSLG(pslg, onlyInner = False):
    """cdtFromPSLG(pslg, onlyInner) -> GeoMap

    Return a CDT for the given planar straight line graph.  `pslg`
    should be a GeoMap whose node positions are simple input points
    and edges define constraint segments.

    FIXME: ATM, this function may crash if the input contains
    duplicate points (e.g. within the same edge).  This is due to a
    limitation of the triangle module, i.e. J. Shewchuck's code.
    """
#     return constrainedDelaunayMap(
#         list(pslg.edgeIter()), pslg.imageSize(),
#         [node.position() for node in pslg.nodeIter() if node.isIsolated()],
#         onlyInner = False)

    points = []
    segments = []
    holes = []

    nodes = [None] * pslg.maxNodeLabel()
    for node in pslg.nodeIter():
        nodes[node.label()] = len(points)
        points.append(node.position())

    for edge in pslg.edgeIter():
        l = len(points)
        edgeSegments = [(l+i-1, l+i) for i in range(len(edge)-1)]
        edgeSegments[0] = (nodes[edge.startNodeLabel()], edgeSegments[0][1])
        edgeSegments[-1] = (edgeSegments[-1][0], nodes[edge.endNodeLabel()])
        points.extend(edge[1:-1])
#         for i in range(1, len(edge)-1):
#             assert edge[i] not in points, "%s[%d] = ..%s,%s,%s,.. is already present!" % (
#                 edge, i, edge[i-1], edge[i], edge[i+1])
#             points.append(edge[i])
        segments.extend(edgeSegments)

    for face in pslg.faceIter(skipInfinite = True):
        if face.flag(OUTER_FACE):
            # FIXME: re-use available scanlines for face:
            holes.append(_pointInHole(contourPoly(face.contour())))

    print "- performing Constrained Delaunay Triangulation..."
    print "  (%d points, %s segments, %d holes)" % (
        len(points), len(segments), len(holes))
    nodePositions, edgeData = triangle.constrainedDelaunay(
        points, segments, onlyInner, holes)

    print "- storing result in a GeoMap..."
    result = _delaunayMapFromData(nodePositions, edgeData, pslg.imageSize())

    for edge in result.edgeIter():
        if edgeData[edge.label()][2]:
            edge.setFlag(CONTOUR_SEGMENT)

    result.face(0).setFlag(OUTER_FACE)
    for holePoint in holes:
        result.faceAt(holePoint).setFlag(OUTER_FACE)

    return result
Beispiel #2
0
def cdtFromPSLG(pslg, onlyInner = False):
    """cdtFromPSLG(pslg, onlyInner) -> GeoMap

    Return a CDT for the given planar straight line graph.  `pslg`
    should be a GeoMap whose node positions are simple input points
    and edges define constraint segments.

    FIXME: ATM, this function may crash if the input contains
    duplicate points (e.g. within the same edge).  This is due to a
    limitation of the triangle module, i.e. J. Shewchuck's code.
    """
#     return constrainedDelaunayMap(
#         list(pslg.edgeIter()), pslg.imageSize(),
#         [node.position() for node in pslg.nodeIter() if node.isIsolated()],
#         onlyInner = False)

    points = []
    segments = []
    holes = []

    nodes = [None] * pslg.maxNodeLabel()
    for node in pslg.nodeIter():
        nodes[node.label()] = len(points)
        points.append(node.position())

    for edge in pslg.edgeIter():
        l = len(points)
        edgeSegments = [(l+i-1, l+i) for i in range(len(edge)-1)]
        edgeSegments[0] = (nodes[edge.startNodeLabel()], edgeSegments[0][1])
        edgeSegments[-1] = (edgeSegments[-1][0], nodes[edge.endNodeLabel()])
        points.extend(edge[1:-1])
#         for i in range(1, len(edge)-1):
#             assert edge[i] not in points, "%s[%d] = ..%s,%s,%s,.. is already present!" % (
#                 edge, i, edge[i-1], edge[i], edge[i+1])
#             points.append(edge[i])
        segments.extend(edgeSegments)

    for face in pslg.faceIter(skipInfinite = True):
        if face.flag(OUTER_FACE):
            # FIXME: re-use available scanlines for face:
            holes.append(_pointInHole(contourPoly(face.contour())))

    print "- performing Constrained Delaunay Triangulation..."
    print "  (%d points, %s segments, %d holes)" % (
        len(points), len(segments), len(holes))
    nodePositions, edgeData = triangle.constrainedDelaunay(
        points, segments, onlyInner, holes)

    print "- storing result in a GeoMap..."
    result = _delaunayMapFromData(nodePositions, edgeData, pslg.imageSize())

    for edge in result.edgeIter():
        if edgeData[edge.label()][2]:
            edge.setFlag(CONTOUR_SEGMENT)

    result.face(0).setFlag(OUTER_FACE)
    for holePoint in holes:
        result.faceAt(holePoint).setFlag(OUTER_FACE)

    return result
Beispiel #3
0
def constrainedDelaunayMap(polygons, imageSize, extraPoints = [],
                           onlyInner = True):
    """constrainedDelaunayMap(polygons, imageSize, extraPoints, onlyInner) -> GeoMap

    Returns a new `GeoMap` containing a Constrained Delaunay
    Triangulation of all points of the polygons plus the extraPoints
    if given.  The segments of the polygons will be constrained
    segments of the CDT.

    If the optional `onlyInner` parameter is True (default), then all
    edge segments in the 'outside' will be removed.  (This assumes
    that all closed polygons with a negative partialArea() are
    holes.)

    **NOTE**: You probably want to use `cdtFromPSLG` or `faceCDTMap`
    instead, both of which have a much simpler API."""

    assert triangle, """For correct CDT, you need to compile the
    triangle module (vigra/experiments/triangle).  You might want to
    try the home-made fakedConstrainedDelaunayMap instead, which will
    give a correct result if possible, but may just throw an exception
    if it has to give up or even go into an infinite loop."""

    points = list(extraPoints)
    segments = []
    holes = []
    for polygon in polygons:
        l = len(points)
        partPoints = list(polygon)
        partSegments = [(l+i, l+i+1) for i in range(len(partPoints)-1)]
        if polygon[-1] == polygon[0]:
            del partPoints[-1]
            if partPoints[0] in points:
                for i, (s, e) in enumerate(partSegments):
                    partSegments[i] = (s-1, e-1) # partPoints[0] will be deleted
                partSegments[0] = (points.index(partPoints[0]), partSegments[0][1])
                del partPoints[0]
            partSegments[-1] = (partSegments[-1][0], partSegments[0][0])
            if onlyInner and polygon.partialArea() < 0:
                holes.append(_pointInHole(polygon))
        else:
            if partPoints[-1] in points:
                partSegments[-1] = (partSegments[-1][0], points.index(partPoints[-1]))
                del partPoints[-1]
            if partPoints[0] in points:
                for i, (s, e) in enumerate(partSegments):
                    partSegments[i] = (s-1, e-1) # partPoints[0] will be deleted
                partSegments[0] = (points.index(partPoints[0]), partSegments[0][1])
                del partPoints[0]
        points.extend(partPoints)
        segments.extend(partSegments)

    print "- performing Constrained Delaunay Triangulation..."
    print "  (%d points, %s segments, %d holes)" % (
        len(points), len(segments), len(holes))
    nodePositions, edgeData = triangle.constrainedDelaunay(
        points, segments, onlyInner, holes)

    print "- storing result in a GeoMap..."
    result = _delaunayMapFromData(nodePositions, edgeData, imageSize)

    for edge in result.edgeIter():
        if edgeData[edge.label()][2]:
            edge.setFlag(CONTOUR_SEGMENT)

    result.face(0).setFlag(OUTER_FACE)
    for holePoint in holes:
        result.faceAt(holePoint).setFlag(OUTER_FACE)

    return result
Beispiel #4
0
def constrainedDelaunayMap(polygons, imageSize, extraPoints = [],
                           onlyInner = True):
    """constrainedDelaunayMap(polygons, imageSize, extraPoints, onlyInner) -> GeoMap

    Returns a new `GeoMap` containing a Constrained Delaunay
    Triangulation of all points of the polygons plus the extraPoints
    if given.  The segments of the polygons will be constrained
    segments of the CDT.

    If the optional `onlyInner` parameter is True (default), then all
    edge segments in the 'outside' will be removed.  (This assumes
    that all closed polygons with a negative partialArea() are
    holes.)

    **NOTE**: You probably want to use `cdtFromPSLG` or `faceCDTMap`
    instead, both of which have a much simpler API."""

    assert triangle, """For correct CDT, you need to compile the
    triangle module (vigra/experiments/triangle).  You might want to
    try the home-made fakedConstrainedDelaunayMap instead, which will
    give a correct result if possible, but may just throw an exception
    if it has to give up or even go into an infinite loop."""

    points = list(extraPoints)
    segments = []
    holes = []
    for polygon in polygons:
        l = len(points)
        partPoints = list(polygon)
        partSegments = [(l+i, l+i+1) for i in range(len(partPoints)-1)]
        if polygon[-1] == polygon[0]:
            del partPoints[-1]
            if partPoints[0] in points:
                for i, (s, e) in enumerate(partSegments):
                    partSegments[i] = (s-1, e-1) # partPoints[0] will be deleted
                partSegments[0] = (points.index(partPoints[0]), partSegments[0][1])
                del partPoints[0]
            partSegments[-1] = (partSegments[-1][0], partSegments[0][0])
            if onlyInner and polygon.partialArea() < 0:
                holes.append(_pointInHole(polygon))
        else:
            if partPoints[-1] in points:
                partSegments[-1] = (partSegments[-1][0], points.index(partPoints[-1]))
                del partPoints[-1]
            if partPoints[0] in points:
                for i, (s, e) in enumerate(partSegments):
                    partSegments[i] = (s-1, e-1) # partPoints[0] will be deleted
                partSegments[0] = (points.index(partPoints[0]), partSegments[0][1])
                del partPoints[0]
        points.extend(partPoints)
        segments.extend(partSegments)

    print "- performing Constrained Delaunay Triangulation..."
    print "  (%d points, %s segments, %d holes)" % (
        len(points), len(segments), len(holes))
    nodePositions, edgeData = triangle.constrainedDelaunay(
        points, segments, onlyInner, holes)

    print "- storing result in a GeoMap..."
    result = _delaunayMapFromData(nodePositions, edgeData, imageSize)

    for edge in result.edgeIter():
        if edgeData[edge.label()][2]:
            edge.setFlag(CONTOUR_SEGMENT)

    result.face(0).setFlag(OUTER_FACE)
    for holePoint in holes:
        result.faceAt(holePoint).setFlag(OUTER_FACE)

    return result