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
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
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
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
def getMark(self, node0, node1): key = skeletonnode.canonical_order(node0, node1) try: return self.markings[key] except KeyError: return 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
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
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
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)
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
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)
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
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