Skip to content

Commit 618cdf0

Browse files
committed
fix contour algorithm for special case when a boundary node has 4 neighbors
1 parent 4a47664 commit 618cdf0

File tree

1 file changed

+45
-9
lines changed

1 file changed

+45
-9
lines changed

tripyview/sub_mesh.py

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,7 @@ def compute_lsmask(self):
13641364
bnde = njit_compute_boundary_edges(self.e_i)
13651365
bnde_nodes = np.unique(bnde.ravel())
13661366
nbnde_nodes = bnde_nodes.size
1367+
self.n_ibnde=bnde_nodes
13671368

13681369
# compute mapping global --> local
13691370
mapping = -np.ones(self.n2dn, dtype=np.int32)
@@ -3483,7 +3484,10 @@ def njit_lsmask_build_adjacency(bnde, bnde_mapping, bnde_nodes):
34833484
RETURNS:
34843485
adj : (nb_nodes, 2) with neighbor indices
34853486
"""
3486-
adj = -np.ones((bnde_nodes, 2), dtype=np.int32)
3487+
3488+
# An edge node can have under certain circumstance have more than just 2 neighboring
3489+
# boundary nodes. under certain conditions it can be 4 thats why (bnde_nodes, 4)
3490+
adj = -np.ones((bnde_nodes, 4), dtype=np.int32)
34873491
count = np.zeros(bnde_nodes , dtype=np.int32)
34883492

34893493
for ii in range(bnde.shape[0]):
@@ -3502,6 +3506,8 @@ def njit_lsmask_build_adjacency(bnde, bnde_mapping, bnde_nodes):
35023506
kb = count[idxb]
35033507
adj[idxb, kb] = idxa
35043508
count[idxb] = kb + 1
3509+
#if count[idxa]>2 or count[idxb]>2: print('--> Careful found boundary edge node with more than 2 neighbors')
3510+
35053511
#___________________________________________________________________________
35063512
return adj
35073513

@@ -3521,14 +3527,18 @@ def njit_lsmask_trace_loops(adj):
35213527
loops : list of compressed index lists
35223528
"""
35233529
nbnde_nodes = adj.shape[0]
3524-
visited = np.zeros(nbnde_nodes, dtype=np.int8)
3525-
loops = []
3530+
visited = np.zeros((nbnde_nodes), dtype=np.int8)
3531+
canreturn = np.zeros((nbnde_nodes), dtype=np.int8)
3532+
isreturn = np.zeros((nbnde_nodes), dtype=np.int8)
3533+
loops = []
35263534

35273535
# loop over all the boundary edge nodes
3536+
cnt=0
35283537
for start in range(nbnde_nodes):
35293538

35303539
# check if point has already been checked out
3531-
if visited[start]: continue
3540+
# if np.all(visited[start,:]): continue
3541+
if visited[start] and canreturn[start]==0: continue
35323542

35333543
# set start index as current index to check out
35343544
cur = start
@@ -3537,27 +3547,53 @@ def njit_lsmask_trace_loops(adj):
35373547

35383548
# walk step by step through neighbor connectivity
35393549
while True:
3550+
35403551
# add point to contour loop list
3541-
loop.append(cur)
3552+
if visited[cur]==0 or canreturn[cur]==1:
3553+
loop.append(cur)
3554+
else:
3555+
break
35423556

35433557
# set current neighbor node as visited
35443558
visited[cur] = 1
35453559

3546-
# check out whos is the next node in neighborhood
3547-
a = adj[cur, 0]
3548-
b = adj[cur, 1]
3549-
nxt = a if a != prev else b
3560+
# check out whos is the next node in neighborhood. usually there are 2
3561+
# neighboring nodes (a and b) but under certain conditions there can be also
3562+
# 4 neighboring boudnary nodes
3563+
if canreturn[0]==0 and isreturn[cur]==0:
3564+
a = adj[cur, 0]
3565+
b = adj[cur, 1]
3566+
if a!=prev: nxt = a
3567+
elif b!=prev: nxt = b
3568+
if (adj[cur,2]>=0 and adj[cur,3]>=0) and isreturn[cur]==0: canreturn[cur]=1
3569+
3570+
# This case when there are more than to neighbouring boundary nodes
3571+
else:
3572+
c = adj[cur, 2]
3573+
d = adj[cur, 3]
3574+
if c!=prev and visited[c] == 0: nxt = c
3575+
elif d!=prev and visited[d] == 0: nxt = d
3576+
isreturn[cur]=1
3577+
canreturn[cur]=0
35503578

35513579
prev = cur
35523580
cur = nxt
35533581

35543582
# if starting point is reached again contour loop is closed again
35553583
# finish while loop. start with next accumaulation of closed coastline
35563584
# loop
3585+
#print(start, cur, prev, nxt, adj[cur,2]<0 and adj[cur,3]>=0)
35573586
if cur == start: break
35583587

3588+
# failsafe not to be drapped in infinite loop
3589+
if cnt > 10*nbnde_nodes:
3590+
print(' -WARNING-> the contour algorithm did not converge properly!')
3591+
break
3592+
cnt+=1
3593+
35593594
# only if loop is large enough add it ti the contour list
35603595
if len(loop) > 4: loops.append(loop)
3596+
35613597
#___________________________________________________________________________
35623598
return loops
35633599

0 commit comments

Comments
 (0)