Esempio n. 1
0
        def __call__(self, skelcontext, name):
            skelobj = skelcontext.getObject()

            (seg_set, direction_set)=skelobj.getInterfaceSegments(
                skelcontext, self.interface)

            if self.direction==director.Director('Non-sequenceable'):
                skelcontext.createNonsequenceableEdgeBoundary(name, seg_set, direction_set)
            else:
                (startnode, seg_list) = _segset2seglist(seg_set, self.direction, skelobj)
                # At this point, we have a correctly-sequenced list of segments.
                # Actually create the boundary.  The context will create it in
                # the underlying object.
                skelcontext.createEdgeBoundary(name, seg_list, startnode)
Esempio n. 2
0
def _segset2seglist(seg_set, direction, skel):

    if len(seg_set) == 0:
        raise ooferror.ErrUserError("Attempt to sequence null segment set.")

    (seg_list, node_list,
     winding_number) = skeletonsegment.segSequence(seg_set)

    # At this point, seg_list is an ordered list of adjacent
    # segments, and "node_list" is the corresponding set of nodes.
    # The path is a loop if node_list[0]==node_list[-1], otherwise
    # it's a simple path.

    # We may want to reverse this list, depending on the
    # setting of "direction".
    firstnode = node_list[0]
    lastnode = node_list[-1]

    startnode = firstnode
    # The winding number is used to handle the cases where the line
    # crosses a periodic boundary.
    if (firstnode != lastnode and firstnode not in lastnode.getPartners()) \
       or winding_number != [0,0]:
        # In case the first node and last node are partners, we set them
        # equal so that we can compare positions properly.
        if lastnode in firstnode.getPartners():
            lastnode = firstnode
        if direction == director.Director('Left to right'):
            if (firstnode.position().x > lastnode.position().x +
                    winding_number[0] * skel.MS.size()[0]):
                seg_list.reverse()
                startnode = lastnode
        elif direction == director.Director('Right to left'):
            if (firstnode.position().x < lastnode.position().x +
                    winding_number[0] * skel.MS.size()[0]):
                seg_list.reverse()
                startnode = lastnode
        elif direction == director.Director('Top to bottom'):
            if (firstnode.position().y < lastnode.position().y +
                    winding_number[1] * skel.MS.size()[1]):
                seg_list.reverse()
                startnode = lastnode
        elif direction == director.Director('Bottom to top'):
            if (firstnode.position().y > lastnode.position().y +
                    winding_number[1] * skel.MS.size()[1]):
                seg_list.reverse()
                startnode = lastnode
        else:
            # User specified clockwise or counterclockwise for a
            # non-loop segment set.  This is an error.
            raise ooferror.ErrUserError(
                "Clockwise or counterclockwise is for closed loops.")

    else:  # firstnode==lastnode, loop case.
        # Use the total area swept out by vectors from the origin to the
        # nodes along the path as we traverse the path in order to
        # determine if the existing sequence traces a clockwise or
        # counterclockwise path.  If two consecutive nodes in the
        # node_list are not the endpoints of a segment, we are crossing a
        # periodic boundary.  In this case, use the positions not to find
        # the area swept out, but to increment the position_adjustment
        # needed to unwrap the periodic boundary conditions.
        startnode = None
        area = 0.0
        p0 = node_list[0].position()
        position_adjustment = primitives.Point(0, 0)
        for i in range(1, len(node_list)):
            p1 = node_list[i].position() + position_adjustment
            if skel.findSegment(node_list[i], node_list[i - 1]) is not None:
                area += p0.x * p1.y - p1.x * p0.y
                p0 = p1
            else:
                position_adjustment += p0 - p1
                # setting p0 = p1 here will be redundant as we
                # must now adjust positions by p0 - p1

        if direction == director.Director('Clockwise'):
            if area > 0.0:
                seg_list.reverse()
        elif direction == director.Director('Counterclockwise'):
            if area < 0.0:
                seg_list.reverse()
        else:
            # User specified an endpoint orientation on a loop.
            raise ooferror.ErrUserError(
                "Closed loops need clockwise or counterclockwise direction.")

    return (startnode, seg_list)
Esempio n. 3
0
        seg_set = skelcontext.segments_from_seg_aggregate(self.group)

        if config.dimension() == 2:
            (startnode, seg_list) = _segset2seglist(seg_set, self.direction,
                                                    skelobj)
            # At this point, we have a correctly-sequenced list of segments.
            # Actually create the boundary.  The context will create it in
            # the underlying object.
            skelcontext.createEdgeBoundary(name, seg_list, startnode)
        else:  # 3D
            segmentsequence = _segset2seglist3D(seg_set, self.direction)
            skelcontext.createEdgeBoundary3D(name, segmentsequence)


if config.dimension() == 2:
    director0 = director.Director('Left to right')
else:
    director0 = director.Director('-X to +X')

registeredclass.Registration(
    "Edge boundary from segments",
    BoundaryConstructor,
    EdgeFromSegments,
    ordering=_edgeBdyConstructor + _edgeBdySource,
    params=[
        skeletongroupparams.SegmentAggregateParameter(
            'group', tip="Construct the boundary from these segments"),
        director.DirectorParameter('direction',
                                   director0,
                                   tip="Direction of the boundary.")
    ],
Esempio n. 4
0
        # At this point, we have a correctly-sequenced list of segments.
        # Actually create the boundary.  The context will create it in
        # the underlying object.
        skelcontext.createEdgeBoundary(name, seg_list, startnode)
    


registeredclass.Registration(
    "Edge boundary from segments",
    BoundaryConstructor,
    EdgeFromSegments,
    ordering=100,
    params = [skeletongroupparams.SegmentAggregateParameter('group',
                              tip="Construct the boundary from these segments"),
              director.DirectorParameter('direction',
                                         director.Director('Clockwise'),
                                         tip="Direction of the boundary.")],
    tip="Construct an edge boundary from a set of segments.",
    discussion=xmlmenudump.loadFile('DISCUSSIONS/engine/reg/edge_from_segments.xml'))


    
# ## ### #### ##### ###### ####### ######## ####### ##### #### ### ## #

  
# Finds the perimeter of an elementgroup.  Requires that the element
# group have a topologically simple (non-self-intersecting,
# non-disjoint) boundary.

# Utility function for extracting a segment list from elements.
# Also used by the DirectorWidget.