Example #1
0
    def getPeriodicTransPtHelper(self, transptlistCandidates, c1, c2, v1, v2,
                                 node0, node1):
        n0pt = node0.position()
        n1pt = node1.position()
        key = skeletonnode.canonical_order(node0, node1)
        partners = node0.getPartnerPair(node1)
        partnerKey = skeletonnode.canonical_order(partners[0], partners[1])

        #Get transpt closest to the endpoints
        transpt0 = transptlistCandidates[0]
        transpt1 = transptlistCandidates[0]  #?
        transptlist = []
        transptnodelist = []
        #Squaring would not be necessary if we order
        #the operands correctly.
        min0 = (transpt0[c2] - n0pt[c2])**2
        min1 = (transpt1[c2] - n1pt[c2])**2
        for transpt in transptlistCandidates:
            mintmp = (transpt[c2] - n0pt[c2])**2
            if mintmp < min0:
                min0 = mintmp
                transpt0 = transpt
            mintmp = (transpt[c2] - n1pt[c2])**2
            if mintmp < min1:
                min1 = mintmp
                transpt1 = transpt
        transptlist.append(transpt0)
        if transpt0 != transpt1 and \
               (transpt0[c2]-transpt1[c2])**2>self.maxdelta2:
            transptlist.append(transpt1)
        #Fix the horizontal coordinates to match the location
        #of the edge when creating nodes.
        transptnodelistPartner = []
        for transpt in transptlist:
            #For current edge
            transpt[c1] = v1
            transptnode = self.newSkeleton.newNodeFromPoint(transpt)
            transptnodelist.append(transptnode)
            #For partner
            transpt[c1] = v2
            transptnodePartner = self.newSkeleton.newNodeFromPoint(transpt)
            transptnode.addPartner(transptnodePartner)
            transptnodelistPartner.append(transptnodePartner)
        self.newEdgeNodes[key] = transptnodelist
        #transptnodelistPartner.reverse()
        self.newEdgeNodes[partnerKey] = transptnodelistPartner
        return transptnodelist
Example #2
0
    def getPeriodicTransPtHelper(self, transptlistCandidates, c1, c2, v1, v2, node0, node1):
        n0pt=node0.position()
        n1pt=node1.position()
        key=skeletonnode.canonical_order(node0,node1)
        partners=node0.getPartnerPair(node1)
        partnerKey = skeletonnode.canonical_order(partners[0], partners[1])

        #Get transpt closest to the endpoints
        transpt0=transptlistCandidates[0]
        transpt1=transptlistCandidates[0] #?
        transptlist = []
        transptnodelist = []
        #Squaring would not be necessary if we order
        #the operands correctly.
        min0=(transpt0[c2]-n0pt[c2])**2
        min1=(transpt1[c2]-n1pt[c2])**2
        for transpt in transptlistCandidates:
            mintmp=(transpt[c2]-n0pt[c2])**2
            if mintmp<min0:
                min0=mintmp
                transpt0=transpt
            mintmp=(transpt[c2]-n1pt[c2])**2
            if mintmp<min1:
                min1=mintmp
                transpt1=transpt
        transptlist.append(transpt0)
        if transpt0 != transpt1 and \
               (transpt0[c2]-transpt1[c2])**2>self.maxdelta2:
            transptlist.append(transpt1)
        #Fix the horizontal coordinates to match the location
        #of the edge when creating nodes.
        transptnodelistPartner=[]
        for transpt in transptlist:
            #For current edge
            transpt[c1]=v1
            transptnode = self.newSkeleton.newNodeFromPoint(transpt)
            transptnodelist.append(transptnode)
            #For partner
            transpt[c1]=v2
            transptnodePartner = self.newSkeleton.newNodeFromPoint(transpt)
            transptnode.addPartner(transptnodePartner)
            transptnodelistPartner.append(transptnodePartner)
        self.newEdgeNodes[key] = transptnodelist
        #transptnodelistPartner.reverse()
        self.newEdgeNodes[partnerKey] = transptnodelistPartner
        return transptnodelist
Example #3
0
    def mark(self, node0, node1, ndivs):
        # arguments are the nodes defining the edge, and the number of
        # new nodes to add to that edge.
        key = skeletonnode.canonical_order(node0, node1)
        try:
            # Only mark an edge if it's not already marked for more
            # divisions.
            if self.markings[key] < ndivs:
                self.markings[key] = ndivs
        except KeyError:
            self.markings[key] = ndivs

        # mark the partner segment, if it exists
        partners = node0.getPartnerPair(node1)
        if partners is not None:
            partnerKey = skeletonnode.canonical_order(partners[0], partners[1])
            try:
                # Only mark an edge if it's not already marked for more
                # divisions.
                if self.markings[partnerKey] < ndivs:
                    self.markings[partnerKey] = ndivs
            except KeyError:
                self.markings[partnerKey] = ndivs
Example #4
0
    def mark(self, node0, node1, ndivs):
        # arguments are the nodes defining the edge, and the number of
        # new nodes to add to that edge.
        key = skeletonnode.canonical_order(node0, node1)
        try:
            # Only mark an edge if it's not already marked for more
            # divisions.
            if self.markings[key] < ndivs:
                self.markings[key] = ndivs
        except KeyError:
            self.markings[key] = ndivs

        # mark the partner segment, if it exists
        partners = node0.getPartnerPair(node1)
        if partners is not None:
            partnerKey = skeletonnode.canonical_order(partners[0], partners[1])
            try:
                # Only mark an edge if it's not already marked for more
                # divisions.
                if self.markings[partnerKey] < ndivs:
                    self.markings[partnerKey] = ndivs
            except KeyError:
                self.markings[partnerKey] = ndivs
Example #5
0
    def getNewEdgeNodes(self, node0, node1, ndivs, newSkeleton, oldSkeleton):
        # Create ndivs new nodes between node0 and node1 in the
        # skeleton.  node0 and node1 are from the old skeleton
        if ndivs < 1:
            return []
        key = skeletonnode.canonical_order(node0, node1)
        try:
            #Unlike in snaprefine.py, we don't make a list copy.
            nodes = self.newEdgeNodes[key]
            if config.dimension() == 2:
                # Since this is the second time we're using this list
                # of nodes, we must be looking at them from the other
                # side, and the nodes should be in the opposite order.
                # Reversing them in place like this would be wrong if
                # the list weren't being used immediately, as it is in
                # Refine.apply()
                # don't do this in 3D because for now
                # we are only doing bisection, and because order
                # doesn't have the same meaning in 3d.
                nodes.reverse()
        except KeyError:
            nodes = [None] * ndivs
            p0 = node0.position()
            p1 = node1.position()
            delta = (p1 - p0) / (ndivs + 1)
            for i in range(ndivs):
                pt = p0 + (i + 1) * delta
                nodes[i] = newSkeleton.newNodeFromPoint(pt)
            self.newEdgeNodes[key] = nodes

            ## Begin Periodic Skeleton Node Construction ###################
            partners = node0.getPartnerPair(node1)
            # It can happen that partners contains the same two nodes
            # (node1,node0), if the Skeleton is only one element wide!
            if partners and node0 != partners[1]:
                partnerKey = skeletonnode.canonical_order(
                    partners[0], partners[1])
                # Make new edge nodes for the partner-edge.  ndivs for
                # the current edge and the partner-edge must be the
                # same.
                nodespartner = [None] * ndivs
                s = newSkeleton.MS.size()
                n0pt = node0.position()
                n1pt = node1.position()
                # in 2D only one of the first four cases can be met,
                # but in 3D a combination of two of the following six
                # cases can be met and we must test that the
                # appropriate periodicity is in the skeleton
                partnerdict = {}
                # Case 1: boundary at left edge or face
                if n0pt.x == 0 and n1pt.x == 0 and newSkeleton.left_right_periodicity:
                    partnerdict[0] = s[0]
                # Case 2: boundary at right edge or face
                elif n0pt.x == s[0] and n1pt.x == s[
                        0] and newSkeleton.left_right_periodicity:
                    partnerdict[0] = 0
                # Case 3: boundary at bottom edge or face
                if n0pt.y == 0 and n1pt.y == 0 and newSkeleton.top_bottom_periodicity:
                    partnerdict[1] = s[1]
                # Case 4: boundary at top edge or face
                elif n0pt.y == s[1] and n1pt.y == s[
                        1] and newSkeleton.top_bottom_periodicity:
                    partnerdict[1] = 0
                if config.dimension() == 3:
                    # Case 5: boundary at back edge or face
                    if n0pt.z == 0 and n1pt.z == 0 and newSkeleton.front_back_periodicity:
                        partnerdict[2] = s[2]
                    # Case 6: boundary at front edge or face
                    elif n0pt.z == s[2] and n1pt.z == s[
                            2] and newSkeleton.top_bottom_periodicity:
                        partnerdict[2] = 0

                for i in range(ndivs):
                    pt = nodes[i].position()
                    for c, v in partnerdict.iteritems():
                        pt[c] = v
                    newnodepartner = newSkeleton.newNodeFromPoint(pt)
                    nodes[i].addPartner(newnodepartner)
                    nodespartner[i] = newnodepartner
                self.newEdgeNodes[partnerKey] = nodespartner
                ## End Periodic Skeleton Node Construction ###################

        return nodes
Example #6
0
 def getMark(self, node0, node1):
     key = skeletonnode.canonical_order(node0, node1)
     try:
         return self.markings[key]
     except KeyError:
         return 0
Example #7
0
    def realelement_shares(self, skeleton, mesh, index, fe_node,
                    curnodeindex, elemdict, materialfunc):        
        # Be safe with indices.
        if self.meshindex is None: # Zero is nontrivial index.
            self.meshindex = index
        else:
            if index != self.meshindex:
                raise ooferror2.ErrPyProgrammingError(
                    "Index mismatch in element construction.")
                
        nnewnodes = 0
        ncn = len(self.nodes) # Corner nodes.

        # elemdict is a dictionary of MasterElements, keyed by number
        # of sides.
        elementtype = elemdict[self.nnodes()]
        nodes = []                      # real nodes for this element

        for i in range(len(self.nodes)):  # i.e. for each edge...
            c0 = self.nodes[i]
            nodes.append(fe_node[c0])     # Corner nodes already exist.
            c1 = self.nodes[(i+1)%ncn]
            cset = skeletonnode.canonical_order(c0, c1)

            # Look up this edge in the dictionary.  If it's there,
            # then nodes have been created on the edge already, and we
            # should reuse them.

            try:
                xtranodes = mesh.getEdgeNodes(cset)
                # The nodes were created by the neighboring element.
                # Since elements traverse their edges counterclockwise
                # when creating nodes, the preexisting nodes are in
                # the wrong order for the current element.
                xtranodes.reverse()
            except KeyError:
                newindexinc=0
                newindex=0
                protocount=0
                protodiclength=len(elementtype.protodic[i])
                if c0.index<c1.index:
                    newindexinc=1
                    newindex=skeleton.maxnnodes+100*c0.index
                else:
                    # Do this to distinguish the protonode on either
                    # side of a corner node that has a smaller index
                    # than either corner nodes of the collinear
                    # segments extending from that corner node.
                    newindexinc=-1
                    newindex=skeleton.maxnnodes+100*c1.index+50+protodiclength-1

                # The edge wasn't in the dictionary.  It's a new edge.
                xtranodes  = []
                # Loop over all protonodes on the current
                # edge of the new element
                for newproto in elementtype.protodic[i]:
                    masterxy = primitives.Point(newproto.mastercoord()[0],
                                           newproto.mastercoord()[1])
                    realxy = self.frommaster(masterxy, 0)
                    newnode = _makenewnode_shares(
                        mesh, newproto,
                        coord.Coord(realxy.x, realxy.y),
                        c0,c1,newindex,protocount,
                        protodiclength,skeleton.maxnnodes)
                    newindex+=newindexinc
                    protocount+=1
                    nnewnodes = nnewnodes + 1
                    xtranodes.append(newnode)
                mesh.addEdgeNodes(cset, xtranodes)
            #Should this be 'join'ed instead, for speed?
            nodes = nodes + xtranodes

        # Interior nodes at the end.
        for newproto in elementtype.protodic['interior']:
            masterxy = primitives.Point(newproto.mastercoord()[0],
                                        newproto.mastercoord()[1])
            realxy = self.frommaster(masterxy, 0)
            newnode = _makenewnode(mesh, newproto,
                                   coord.Coord(realxy.x, realxy.y))
            nnewnodes = nnewnodes + 1
            nodes.append(newnode)
            mesh.addInternalNodes(self, newnode)

        # Having constructed the list of nodes, call the real
        # element's constructor.
        realel = elementtype.build(self, materialfunc(self, skeleton), nodes)
        # Long-lost cousin of Kal-El and Jor-El.
        
        mesh.addElement(realel)               # Add to mesh.
        # Tell the element about its exterior edges.
        for edge in self.exterior_edges:
            realel.set_exterior(fe_node[edge[0]], fe_node[edge[1]])

        return nnewnodes
Example #8
0
    def realelement(self, skeletoncontext, mesh, index,
                    fe_node, seg_dict,
                    elemdict, materialfunc):
        # Create a real element corresponding to this skeleton
        # element. The elemdict argument is a dictionary (keyed by the
        # number of sides of the element) of MasterElement objects,
        # which contain the information needed to construct the real
        # elements.  "index" is the SkeletonElement's position in the
        # Skeleton's list, and "fe_node" is a dictionary of real nodes
        # in the FEMesh, indexed by their corresponding SkeletonNode
        # objects.  The lists give the nodes in the order in which
        # they were added to the element.
        
        # Be safe with indices.
        if self.meshindex is None: # Zero is nontrivial index.
            self.meshindex = index
        else:
            if index != self.meshindex:
                raise ooferror2.ErrPyProgrammingError(
                    "Index mismatch in element construction.")
                
        nnewnodes = 0
        ncn = len(self.nodes) # Corner nodes.

        # elemdict is a dictionary of MasterElements, keyed by number
        # of sides.
        elementtype = elemdict[self.nnodes()]
        nodes = []                      # real nodes for this element

        for i in range(len(self.nodes)):  # i.e. for each edge...
            c0 = self.nodes[i]
            nodes.append(fe_node[c0])     # Corner nodes already exist.
            c1 = self.nodes[(i+1)%ncn]
            cset = skeletonnode.canonical_order(c0, c1)


            # Look up this edge in the dictionary.  If it's there,
            # then nodes have been created on the edge already, and we
            # should reuse them.

            try:
                xtranodes = mesh.getEdgeNodes(cset)
                # The nodes were created by the neighboring element.
                # Since elements traverse their edges counterclockwise
                # when creating nodes, the preexisting nodes are in
                # the wrong order for the current element.
                xtranodes.reverse()
            except KeyError:
                # The edge wasn't in the dictionary.  It's a new edge.
                xtranodes  = []
                # Loop over all protonodes on the current
                # edge of the new element
                for newproto in elementtype.protodic[i]:
                    masterxy = primitives.Point(newproto.mastercoord()[0],
                                           newproto.mastercoord()[1])
                    realxy = self.frommaster(masterxy, 0)
                    newnode = _makenewnode(mesh, newproto,
                                           coord.Coord(realxy.x, realxy.y))
                    nnewnodes = nnewnodes + 1
                    xtranodes.append(newnode)
                #Interface branch
                try:
                    #If the segment represented by cset is a member of an
                    #interface, then new edge nodes (xtranodes) will
                    #not be shared by another element.
                    test=seg_dict[cset]
                except KeyError:
                    mesh.addEdgeNodes(cset, xtranodes)
            nodes = nodes + xtranodes

        # Interior nodes at the end.
        for newproto in elementtype.protodic['interior']:
            masterxy = primitives.Point(newproto.mastercoord()[0],
                                        newproto.mastercoord()[1])
            realxy = self.frommaster(masterxy, 0)
            newnode = _makenewnode(mesh, newproto,
                                   coord.Coord(realxy.x, realxy.y))
            nnewnodes = nnewnodes + 1
            nodes.append(newnode)
            mesh.addInternalNodes(self, newnode)

        # Having constructed the list of nodes, call the real
        # element's constructor.  materialfunc returns the element's
        # material.  In normal operation, materialfunc is
        # SkeletonElement.realmaterial.
        realel = elementtype.build(self, materialfunc(self, skeletoncontext),
                                   nodes)
        
        mesh.addElement(realel)               # Add to mesh.
        # Tell the element about its exterior edges.
        for edge in self.exterior_edges:
            realel.set_exterior(fe_node[edge[0]], fe_node[edge[1]])

        return nnewnodes
Example #9
0
 def new_child(self, index):
     n0 = self._nodes[0].getChildren()[-1]
     n1 = self._nodes[1].getChildren()[-1]
     new = SkeletonSegment(skeletonnode.canonical_order(n0, n1), index)
     new._elements = [ x.getChildren()[-1] for x in self._elements ]
     return new
Example #10
0
    def getSnapMarks(self, element):
        #print "in getSnapMarks"
        numinitmarks = 0
        marks = []
        cats = []
        transpts = []
        nnodes = element.nnodes()
        for node0, node1 in element.segment_node_iterator():
            n0pt = node0.position()
            n1pt = node1.position()
            key = skeletonnode.canonical_order(node0, node1)
            initmark = 0
            try:
                initmark = self.markings[key]
                # If the edges are marked then the element should be
                # refined, even if we find no transition points.
                numinitmarks += initmark
            except KeyError:
                pass
            if initmark > 0:
                #print "initmark>0"
                #Marked for bisection or trisection, find or retrieve new edge nodes.
                try:
                    #See if we already created new edge nodes for this edge.
                    transptnodelist = self.newEdgeNodes[
                        key][:]  # Make a list copy
                    if config.dimension() == 2:
                        transptnodelist.reverse()
                except KeyError:
                    #print "not already in edge nodes"
                    partners = node0.getPartnerPair(node1)
                    #It can happen that partners contains the same two nodes (node1,node0)!
                    if partners and node0 != partners[1]:
                        ############## Begin Periodic Skeleton Node Construction ###################
                        partnerKey = skeletonnode.canonical_order(
                            partners[0], partners[1])
                        #If the edge nodes have periodic partners, then find the transition
                        #points on the current edge and the partner edge. Get the pair of
                        #transition points that is closest to the endpoints (imagine joining
                        #together the two opposite edges).
                        n0pt_partner = partners[0].position()
                        n1pt_partner = partners[1].position()
                        transptlistCandidates=self.getTransitionPoints(n0pt,n1pt)+\
                                         self.getTransitionPoints(n0pt_partner,n1pt_partner)
                        size = self.newSkelMS.size()
                        if len(transptlistCandidates) > 0:
                            #Case 1: boundary at left edge or face
                            if n0pt.x == 0 and n1pt.x == 0:
                                transptnodelist = self.getPeriodicTransPtHelper(
                                    transptlistCandidates, 0, 1, 0, size[0],
                                    node0, node1)
                            #Case 2: boundary at right edge or face
                            elif n0pt.x == size[0] and n1pt.x == size[0]:
                                transptnodelist = self.getPeriodicTransPtHelper(
                                    transptlistCandidates, 0, 1, size[0], 0,
                                    node0, node1)
                            #Case 3: boundary at bottom edge or face
                            elif n0pt.y == 0 and n1pt.y == 0:
                                transptnodelist = self.getPeriodicTransPtHelper(
                                    transptlistCandidates, 1, 0, 0, size[1],
                                    node0, node1)
                            #Case 4: boundary at top edge or face
                            elif n0pt.y == size[1] and n1pt.y == size[1]:
                                transptnodelist = self.getPeriodicTransPtHelper(
                                    transptlistCandidates, 1, 0, size[1], 0,
                                    node0, node1)

                        else:
                            self.newEdgeNodes[key] = []
                            self.newEdgeNodes[partnerKey] = []
                            transptnodelist = []

    ############## End Periodic Skeleton Node Construction ###################
                    else:
                        ## getTransitionPoints returns 0, 1, or 2
                        ## points.  If there are more than 2, it
                        ## ignores the ones in the middle.
                        tpts = self.getTransitionPoints(n0pt, n1pt)
                        # debug.fmsg("n0pt=", n0pt, "n1pt=", n1pt)
                        # debug.fmsg("tpts=", tpts)
                        transptnodelist = [
                            self.newSkeleton.newNodeFromPoint(p) for p in tpts
                        ]
                        self.newEdgeNodes[key] = transptnodelist

                if len(transptnodelist) == 2:
                    transpt0 = transptnodelist[0].position()
                    transpt1 = transptnodelist[1].position()
                    # Order of the arguments to edgeHomogeneityCat is
                    # significant.  If the edge n0pt-n1pt is
                    # horizontal or vertical and lies at a pixel
                    # boundary, then we want the function to use the
                    # pixels lying within the element in its
                    # calculations.
                    homog0, cat0 = self.newSkelMS.edgeHomogeneityCat(
                        n0pt, transpt0)
                    homog1, cat1 = self.newSkelMS.edgeHomogeneityCat(
                        transpt0, transpt1)
                    homog2, cat2 = self.newSkelMS.edgeHomogeneityCat(
                        transpt1, n1pt)
                    marks.append(2)
                    cats.append((cat0, cat1, cat2))
                    transpts.append(transptnodelist)
                elif len(transptnodelist) == 1:
                    transpt = transptnodelist[0].position()
                    homog0, cat0 = self.newSkelMS.edgeHomogeneityCat(
                        n0pt, transpt)
                    homog1, cat1 = self.newSkelMS.edgeHomogeneityCat(
                        transpt, n1pt)
                    marks.append(1)
                    cats.append((cat0, cat1))
                    transpts.append(transptnodelist)
                else:
                    marks.append(0)
                    homogedge, catedge = self.newSkelMS.edgeHomogeneityCat(
                        n0pt, n1pt)
                    cats.append((catedge, ))
                    transpts.append([])
            else:
                marks.append(0)
                homogedge, catedge = self.newSkelMS.edgeHomogeneityCat(
                    n0pt, n1pt)
                cats.append((catedge, ))
                transpts.append([])

        #print "end of getSnapMarks"
        return (numinitmarks, marks, cats, transpts)
Example #11
0
 def new_child(self, index):
     n0 = self._nodes[0].getChildren()[-1]
     n1 = self._nodes[1].getChildren()[-1]
     new = SkeletonSegment(skeletonnode.canonical_order(n0, n1), index)
     new._elements = [x.getChildren()[-1] for x in self._elements]
     return new
Example #12
0
    def getSnapMarks(self, element):
        #print "in getSnapMarks"
        numinitmarks=0
        marks=[]
        cats=[]
        transpts=[]
        nnodes = element.nnodes()
        for node0, node1 in element.segment_node_iterator():
            n0pt=node0.position()
            n1pt=node1.position()
            key=skeletonnode.canonical_order(node0,node1)
            initmark=0
            try:
                initmark=self.markings[key]
                # If the edges are marked then the element should be
                # refined, even if we find no transition points.
                numinitmarks+=initmark
            except KeyError:
                pass
            if initmark>0:
                #print "initmark>0"
                #Marked for bisection or trisection, find or retrieve new edge nodes.
                try:
                    #See if we already created new edge nodes for this edge.
                    transptnodelist = self.newEdgeNodes[key][:] # Make a list copy
                    if config.dimension() == 2:
                        transptnodelist.reverse()
                except KeyError:
                    #print "not already in edge nodes"
                    partners=node0.getPartnerPair(node1)
                    #It can happen that partners contains the same two nodes (node1,node0)!
                    if partners and node0!=partners[1]:
                        ############## Begin Periodic Skeleton Node Construction ###################
                        partnerKey = skeletonnode.canonical_order(partners[0], partners[1])
                        #If the edge nodes have periodic partners, then find the transition
                        #points on the current edge and the partner edge. Get the pair of
                        #transition points that is closest to the endpoints (imagine joining
                        #together the two opposite edges).
                        n0pt_partner=partners[0].position()
                        n1pt_partner=partners[1].position()
                        transptlistCandidates=self.getTransitionPoints(n0pt,n1pt)+\
                                         self.getTransitionPoints(n0pt_partner,n1pt_partner)
                        size = self.newSkelMS.size()
                        if len(transptlistCandidates)>0:
                            #Case 1: boundary at left edge or face
                            if n0pt.x==0 and n1pt.x==0:
                                transptnodelist = self.getPeriodicTransPtHelper(transptlistCandidates, 0, 1, 0, size[0], node0, node1)
                            #Case 2: boundary at right edge or face
                            elif n0pt.x==size[0] and n1pt.x==size[0]: 
                                transptnodelist = self.getPeriodicTransPtHelper(transptlistCandidates, 0, 1, size[0], 0, node0, node1)
                            #Case 3: boundary at bottom edge or face
                            elif n0pt.y==0 and n1pt.y==0:
                                transptnodelist = self.getPeriodicTransPtHelper(transptlistCandidates, 1, 0, 0, size[1], node0, node1)
                            #Case 4: boundary at top edge or face
                            elif n0pt.y==size[1] and n1pt.y==size[1]:
                                transptnodelist = self.getPeriodicTransPtHelper(transptlistCandidates, 1, 0, size[1], 0, node0, node1)

                        else:
                            self.newEdgeNodes[key]=[]
                            self.newEdgeNodes[partnerKey]=[]
                            transptnodelist = []
                        ############## End Periodic Skeleton Node Construction ###################
                    else:
                        #print "non periodic case"
                        transptnodelist = [self.newSkeleton.newNodeFromPoint(pt)
                                           for pt in self.getTransitionPoints(n0pt, n1pt)]
                        self.newEdgeNodes[key] = transptnodelist

                if len(transptnodelist)==2:
                    transpt0 = transptnodelist[0].position()
                    transpt1 = transptnodelist[1].position()
                    #Order of the arguments to edgeHomogeneityCat are significant.
                    #If the edge n0pt-n1pt is horizontal or vertical and lies at
                    #a pixel boundary, then we want the function to use the pixels
                    #lying within the element in its calculations.
                    homog0, cat0 = self.newSkelMS.edgeHomogeneityCat(n0pt,transpt0)
                    homog1, cat1 = self.newSkelMS.edgeHomogeneityCat(transpt0,transpt1)
                    homog2, cat2 = self.newSkelMS.edgeHomogeneityCat(transpt1,n1pt)
                    marks.append(2)
                    cats.append((cat0,cat1,cat2))
                    transpts.append(transptnodelist)
                elif len(transptnodelist)==1:
                    transpt = transptnodelist[0].position()
                    homog0, cat0 = self.newSkelMS.edgeHomogeneityCat(n0pt,transpt)
                    homog1, cat1 = self.newSkelMS.edgeHomogeneityCat(transpt,n1pt)
                    marks.append(1)
                    cats.append((cat0,cat1))
                    transpts.append(transptnodelist)
                else:
                    marks.append(0)
                    homogedge,catedge=self.newSkelMS.edgeHomogeneityCat(n0pt,n1pt)
                    cats.append((catedge,))
                    transpts.append([])
            else:
                marks.append(0)
                homogedge,catedge=self.newSkelMS.edgeHomogeneityCat(n0pt,n1pt)
                cats.append((catedge,))
                transpts.append([])

        #print "end of getSnapMarks"
        return (numinitmarks, marks, cats, transpts)
Example #13
0
    def apply(self, oldskeleton, context):
        prog = progress.getProgress("SnapNodes", progress.DEFINITE)
        prog.setMessage("examining elements...")
        skel = oldskeleton.deputyCopy()
        skel.activate()

        # Examine elements and create NodeSnapper objects
        movedict = {}                   # dict of all moves, keyed by element
        movelists = {}         # dict of lists of all moves, keyed by priority
        elements = self.targets(context)

        # Big try-finally block to ensure that
        # self.targets.cleanSelection() gets called if something goes
        # wrong.
        try:
            stored_tps = {}  # keyed by node pair
            nel = len(elements)
            for i, element in enumerate(elements):
                if element.homogeneity(skel.MS) == 1.0:
                    continue  # no need to even look at it!
                if element.active(oldskeleton):
                    #nnodes = element.nnodes()
                    # Common segments will be looked at only once.
                    # With a small Skeleton, this takes more time due to
                    # additional book-keeping stuff.
                    transitionpts = []
                    for n, nodes in zip(range(element.getNumberOfEdges()), 
                                              element.segment_node_iterator()):
                        #for n in range(nnodes):
                        #key = skeletonnode.canonical_order(
                        #    element.nodes[n], element.nodes[(n+1)%nnodes])
                        key = skeletonnode.canonical_order(nodes[0], nodes[1])
                        try:
                            transitionpts.append(stored_tps[key])
                        except KeyError:
                            tp = element.transitionPoint(skel, n)
                            stored_tps[key] = tp
                            transitionpts.append(tp)
                    nodemotion = getNodeSnapper(element, transitionpts)
                    if nodemotion is not None:
                        movedict[element] = nodemotion
                        try:
                            movelists[nodemotion.priority].append(nodemotion)
                        except KeyError:
                            movelists[nodemotion.priority] = [nodemotion]
                if prog.stopped() :
                    return None
                prog.setFraction(1.0*(i+1)/nel)
                prog.setMessage("examined %d/%d elements" % (i+1, nel))

            # Perform node motions in random order within their
            # priority classes
            priorities = movelists.keys()
            priorities.sort()
            # A set to keep track of moved nodes & use them to assist
            # movers that are associated with these nodes.
            movednodes = set()
            for p in priorities:
                movelist = movelists[p]
                random.shuffle(movelist)
                nmv = len(movelist)
                for i in range(nmv):
                    move = movelist[i]
                    move.perform(skel, self.criterion, movedict, movednodes)
                    if prog.stopped():
                        return None
                    prog.setFraction(1.0*(i+1)/nmv)
                    prog.setMessage("Type %d: %d/%d" % (p, i+1, nmv))
            nmoved = len(movednodes)
        finally:  
            self.targets.cleanSelection()
            prog.finish()

        # Only need to clean up the skeleton if we're going to return it.
        skel.cleanUp()
        reporter.report("Snapped %d node%s." % (nmoved, "s"*(nmoved != 1)))
        return skel
Example #14
0
    def getNewEdgeNodes(self, node0, node1, ndivs, newSkeleton, oldSkeleton):
        # Create ndivs new nodes between node0 and node1 in the
        # skeleton.  node0 and node1 are from the old skeleton
        if ndivs < 1:
            return []
        key = skeletonnode.canonical_order(node0, node1)
        try:
            # Unlike in snaprefine.py, we don't make a list copy.
            nodes = self.newEdgeNodes[key]
            if config.dimension() == 2:
                # Since this is the second time we're using this list
                # of nodes, we must be looking at them from the other
                # side, and the nodes should be in the opposite order.
                # Reversing them in place like this would be wrong if
                # the list weren't being used immediately, as it is in
                # Refine.apply()
                # don't do this in 3D because for now
                # we are only doing bisection, and because order
                # doesn't have the same meaning in 3d.
                nodes.reverse()
        except KeyError:
            nodes = [None] * ndivs
            p0 = node0.position()
            p1 = node1.position()
            delta = (p1 - p0) / (ndivs + 1)
            for i in range(ndivs):
                pt = p0 + (i + 1) * delta
                nodes[i] = newSkeleton.newNodeFromPoint(pt)
            self.newEdgeNodes[key] = nodes

            ## Begin Periodic Skeleton Node Construction ###################
            partners = node0.getPartnerPair(node1)
            # It can happen that partners contains the same two nodes
            # (node1,node0), if the Skeleton is only one element wide!
            if partners and node0 != partners[1]:
                partnerKey = skeletonnode.canonical_order(partners[0], partners[1])
                # Make new edge nodes for the partner-edge.  ndivs for
                # the current edge and the partner-edge must be the
                # same.
                nodespartner = [None] * ndivs
                s = newSkeleton.MS.size()
                n0pt = node0.position()
                n1pt = node1.position()
                # in 2D only one of the first four cases can be met,
                # but in 3D a combination of two of the following six
                # cases can be met and we must test that the
                # appropriate periodicity is in the skeleton
                partnerdict = {}
                # Case 1: boundary at left edge or face
                if n0pt.x == 0 and n1pt.x == 0 and newSkeleton.left_right_periodicity:
                    partnerdict[0] = s[0]
                # Case 2: boundary at right edge or face
                elif n0pt.x == s[0] and n1pt.x == s[0] and newSkeleton.left_right_periodicity:
                    partnerdict[0] = 0
                # Case 3: boundary at bottom edge or face
                if n0pt.y == 0 and n1pt.y == 0 and newSkeleton.top_bottom_periodicity:
                    partnerdict[1] = s[1]
                # Case 4: boundary at top edge or face
                elif n0pt.y == s[1] and n1pt.y == s[1] and newSkeleton.top_bottom_periodicity:
                    partnerdict[1] = 0
                if config.dimension() == 3:
                    # Case 5: boundary at back edge or face
                    if n0pt.z == 0 and n1pt.z == 0 and newSkeleton.front_back_periodicity:
                        partnerdict[2] = s[2]
                    # Case 6: boundary at front edge or face
                    elif n0pt.z == s[2] and n1pt.z == s[2] and newSkeleton.top_bottom_periodicity:
                        partnerdict[2] = 0

                for i in range(ndivs):
                    pt = nodes[i].position()
                    for c, v in partnerdict.iteritems():
                        pt[c] = v
                    newnodepartner = newSkeleton.newNodeFromPoint(pt)
                    nodes[i].addPartner(newnodepartner)
                    nodespartner[i] = newnodepartner
                self.newEdgeNodes[partnerKey] = nodespartner
                ## End Periodic Skeleton Node Construction ###################

        return nodes
Example #15
0
 def getMark(self, node0, node1):
     key = skeletonnode.canonical_order(node0, node1)
     try:
         return self.markings[key]
     except KeyError:
         return 0