<commit_before>from panda3d.core import *
from odvm.edges import edge, edges
from odvm.grid import square, grid, intersect, same_corners


class Quad:
   def __init__(self,v0,v1,v2,v3,colour):
      self.diag12 = (v1,v2)
      self.diag03 = (v0,v3)
      self.colour = colour

   def match(self,v1,v2): return same_corners(self.diag12[0],self.diag12[1],v1,v2)

   def attach(self,geom):
      self.geom = geom

      x0,y0,z0 = self.diag12[0]
      x1,y1,z1 = self.diag12[1]
      if   y0 == y1: self.normal = Vec3(0.0,(1.0 if (x0-x1)*(z1-z0) >= 0.0 else -1.0),0.0) # == -ux*vz, u=(x1-x0,0,z1-z0), v=(0,0,z1-z0)
      elif x0 == x1: self.normal = Vec3((1.0 if (z0-z1)*(y1-y0) >= 0.0 else -1.0),0.0,0.0) # == -uz*vy, u=(0,y1-y0,z1-z0), v=(0,y1-y0,0)
      else         : self.normal = Vec3(0.0,0.0,(1.0 if (x1-x0)*(y1-y0) >= 0.0 else -1.0)) # ==  ux*vy, u=(x1-x0,y1-y0,0), v=(0,y1-y0,0)
      self.edges     = ( [], [], [], [] )
      self.points    = ( [], [], [], [] )
      self.vertices  = []
      self.triangles = []
      self.desc = ( [self.diag03[0],self.diag12[0],self.geom.add_edge(self.diag03[0],self.diag12[0],self)],  # v0 -> v1 : left
                    [self.diag12[0],self.diag03[1],self.geom.add_edge(self.diag12[0],self.diag03[1],self)],  # v1 -> v3 : bottom
                    [self.diag03[1],self.diag12[1],self.geom.add_edge(self.diag03[1],self.diag12[1],self)],  # v3 -> v2 : right
                    [self.diag12[1],self.diag03[0],self.geom.add_edge(self.diag12[1],self.diag03[0],self)] ) # v2 -> v0 : top
      self.geom.update_q.add(self)

   def detach(self):
      if hasattr(self,'vertices'):
         self.geom.unused_v.extend(self.vertices )
         self.geom.unused_t.extend(self.triangles)
         del self.vertices
         del self.triangles
         for d in self.desc: self.geom.sub_edge(d[0],d[1],d[2],self)
         del self.edges
         del self.points
         del self.desc
         del self.normal
      self.geom.update_q.discard(self)

   def change_edge(self,f,t):
      for d in self.desc:
         if d[2] is f: d[2] = t

   def query_edges(self):
      build_rqrd = False
      for i,d in enumerate(self.desc):
         if   d[0][0] != d[1][0]: ps = d[2].query_points(d[0][0],d[1][0])
         elif d[0][1] != d[1][1]: ps = d[2].query_points(d[0][1],d[1][1])
         else                   : ps = d[2].query_points(d[0][2],d[1][2])

         if not self.edges[i] or self.points[i] != ps:
            self.points[i][:] = ps
            build_rqrd = True

            del self.edges[i][:]
            self.edges[i].append(d[0])
            if   d[0][0] != d[1][0]:
               pp = d[0][0]
               for p in ps:
                  if p == pp: continue
                  self.edges[i].append(Vec3(p,d[0][1],d[0][2]))
                  pp = p
            elif d[0][1] != d[1][1]:
               pp = d[0][1]
               for p in ps:
                  if p == pp: continue
                  self.edges[i].append(Vec3(d[0][0],p,d[0][2]))
                  pp = p
            else:
               pp = d[0][2]
               for p in ps:
                  if p == pp: continue
                  self.edges[i].append(Vec3(d[0][0],d[0][1],p))
                  pp = p
            self.edges[i].append(d[1])
      return build_rqrd

   def add_triangle(self,e0,k0,e1,k1,e2,k2,dk):
      i0 = self.imap[e0][k0]
      if i0 < 0:
         i0 = self.geom.add_vertex(self.edges[e0][k0],self.normal,self.colour)
         self.imap[e0][k0] = i0
      i1 = self.imap[e1][k1]
      if i1 < 0:
         i1 = self.geom.add_vertex(self.edges[e1][k1],self.normal,self.colour)
         self.imap[e1][k1] = i1
      i2 = self.imap[e2][k2]
      if i2 < 0:
         i2 = self.geom.add_vertex(self.edges[e2][k2],self.normal,self.colour)
         self.imap[e2][k2] = i2
      if dk > 0: self.geom.add_triangle(i0,i1,i2)
      else     : self.geom.add_triangle(i1,i0,i2)

   def build(self):
      if not self.query_edges(): return

      assert( not self.geom.used_v )
      assert( not self.geom.used_t )

      self.geom.unused_v.extend(self.vertices )
      self.geom.unused_t.extend(self.triangles)

      lsts      = ( len(self.edges[0])-1, len(self.edges[1])-1, len(self.edges[2])-1, len(self.edges[3])-1 )
      idxs      = ( [ 0, lsts[0], 0x7f ], [ 0, lsts[1], 0x7f ], [ 0, lsts[2], 0x7f ], [ 0, lsts[3], 0x7f ] )
      attach    = ( -1, 0, 0, 1, -1, -1, 1 )
      self.imap = ( [-1]*len(self.edges[0]), [-2]*len(self.edges[1]), [-3]*len(self.edges[2]), [-4]*len(self.edges[3]) )
      self.imap[0][ 0] = self.imap[3][-1] = self.geom.add_vertex(self.edges[0][0],self.normal,self.colour)
      self.imap[0][-1] = self.imap[1][ 0] = self.geom.add_vertex(self.edges[1][0],self.normal,self.colour)
      self.imap[2][-1] = self.imap[3][ 0] = self.geom.add_vertex(self.edges[3][0],self.normal,self.colour)
      self.imap[1][-1] = self.imap[2][ 0] = self.geom.add_vertex(self.edges[2][0],self.normal,self.colour)

      while True:
         sel = ( 1e9, )
         for e0 in range(4):
            if idxs[e0][2] and idxs[e0][0] != idxs[e0][1]:
               for e in (3,1,2,6):
                  if idxs[e0][2]&(1<<e) != 0:
                     j2 = attach[e]
                     j0 = j2^1
                     k0 = idxs[e0][j0]
                     e2 = (e0+e)&3
                     k2 = idxs[e2][j2]
                     dk = 1-(j0<<1) # +1 or -1
                     if self.imap[e0][k0] == self.imap[e2][k2]: # corner
                        if k2 == idxs[e2][j0]: continue
                        k2 -= dk
                     d  = max( (self.edges[e2][k2]-self.edges[e0][k0]).length_squared(), (self.edges[e2][k2]-self.edges[e0][k0+dk]).length_squared() )
                     if d < sel[0]: sel = (d,e0,j0,k0,e2,j2,k2,dk,e)
         if len(sel) == 1:
            for e0 in range(4):
               if idxs[e0][0] == idxs[e0][1] and 0 < idxs[e0][0] < lsts[e0] and idxs[e0][2]&((1<<1)|(1<<3)) == ((1<<1)|(1<<3)):
                  e1 = (e0+1)&3
                  e2 = (e0+3)&3
                  if idxs[e1][0] == idxs[e1][1] and idxs[e2][0] == idxs[e2][1]: break
            else: break
            idxs[e0][2] = 0
            self.add_triangle(e0,idxs[e0][0],e1,idxs[e1][0],e2,idxs[e2][0],1)
            continue
         d,e0,j0,k0,e2,j2,k2,dk,e = sel
         k1 = k0+dk
         self.add_triangle(e0,k0,e0,k1,e2,k2,dk)
         idxs[e0][j0] = k1
         idxs[e2][j2] = k2
         if e&3 == 2: # opposite
            if j0 == 0:
               idxs[(e0+1)&3][2] &= ~((1<<2)|(1<<6))
               idxs[ e0     ][2] &= ~(1<<3)
               idxs[(e0+3)&3][2]  = 0
               idxs[ e2     ][2] &= ~(1<<1)
            else:
               idxs[(e0+3)&3][2] &= ~((1<<2)|(1<<6))
               idxs[ e0     ][2] &= ~(1<<1)
               idxs[(e0+1)&3][2]  = 0
               idxs[ e2     ][2] &= ~(1<<3)

      del self.imap
      self.vertices    = self.geom.used_v
      self.triangles   = self.geom.used_t
      self.geom.used_v = []
      self.geom.used_t = []

   def change_triangles(self,imap):<commit_msg>Fixed missing triangles in some rare cases<commit_after>from panda3d.core import *
from odvm.edges import edge, edges
from odvm.grid import square, grid, intersect, same_corners


class Quad:
   def __init__(self,v0,v1,v2,v3,colour):
      self.diag12 = (v1,v2)
      self.diag03 = (v0,v3)
      self.colour = colour

   def match(self,v1,v2): return same_corners(self.diag12[0],self.diag12[1],v1,v2)

   def attach(self,geom):
      self.geom = geom

      x0,y0,z0 = self.diag12[0]
      x1,y1,z1 = self.diag12[1]
      if   y0 == y1: self.normal = Vec3(0.0,(1.0 if (x0-x1)*(z1-z0) >= 0.0 else -1.0),0.0) # == -ux*vz, u=(x1-x0,0,z1-z0), v=(0,0,z1-z0)
      elif x0 == x1: self.normal = Vec3((1.0 if (z0-z1)*(y1-y0) >= 0.0 else -1.0),0.0,0.0) # == -uz*vy, u=(0,y1-y0,z1-z0), v=(0,y1-y0,0)
      else         : self.normal = Vec3(0.0,0.0,(1.0 if (x1-x0)*(y1-y0) >= 0.0 else -1.0)) # ==  ux*vy, u=(x1-x0,y1-y0,0), v=(0,y1-y0,0)
      self.edges     = ( [], [], [], [] )
      self.points    = ( [], [], [], [] )
      self.vertices  = []
      self.triangles = []
      self.desc = ( [self.diag03[0],self.diag12[0],self.geom.add_edge(self.diag03[0],self.diag12[0],self)],  # v0 -> v1 : left
                    [self.diag12[0],self.diag03[1],self.geom.add_edge(self.diag12[0],self.diag03[1],self)],  # v1 -> v3 : bottom
                    [self.diag03[1],self.diag12[1],self.geom.add_edge(self.diag03[1],self.diag12[1],self)],  # v3 -> v2 : right
                    [self.diag12[1],self.diag03[0],self.geom.add_edge(self.diag12[1],self.diag03[0],self)] ) # v2 -> v0 : top
      self.geom.update_q.add(self)

   def detach(self):
      if hasattr(self,'vertices'):
         self.geom.unused_v.extend(self.vertices )
         self.geom.unused_t.extend(self.triangles)
         del self.vertices
         del self.triangles
         for d in self.desc: self.geom.sub_edge(d[0],d[1],d[2],self)
         del self.edges
         del self.points
         del self.desc
         del self.normal
      self.geom.update_q.discard(self)

   def change_edge(self,f,t):
      for d in self.desc:
         if d[2] is f: d[2] = t

   def query_edges(self):
      build_rqrd = False
      for i,d in enumerate(self.desc):
         if   d[0][0] != d[1][0]: ps = d[2].query_points(d[0][0],d[1][0])
         elif d[0][1] != d[1][1]: ps = d[2].query_points(d[0][1],d[1][1])
         else                   : ps = d[2].query_points(d[0][2],d[1][2])

         if not self.edges[i] or self.points[i] != ps:
            self.points[i][:] = ps
            build_rqrd = True

            del self.edges[i][:]
            self.edges[i].append(d[0])
            if   d[0][0] != d[1][0]:
               pp = d[0][0]
               for p in ps:
                  if p == pp: continue
                  self.edges[i].append(Vec3(p,d[0][1],d[0][2]))
                  pp = p
            elif d[0][1] != d[1][1]:
               pp = d[0][1]
               for p in ps:
                  if p == pp: continue
                  self.edges[i].append(Vec3(d[0][0],p,d[0][2]))
                  pp = p
            else:
               pp = d[0][2]
               for p in ps:
                  if p == pp: continue
                  self.edges[i].append(Vec3(d[0][0],d[0][1],p))
                  pp = p
            self.edges[i].append(d[1])
      return build_rqrd

   def add_triangle(self,e0,k0,e1,k1,e2,k2,dk):
      i0 = self.imap[e0][k0]
      if i0 < 0:
         i0 = self.geom.add_vertex(self.edges[e0][k0],self.normal,self.colour)
         self.imap[e0][k0] = i0
      i1 = self.imap[e1][k1]
      if i1 < 0:
         i1 = self.geom.add_vertex(self.edges[e1][k1],self.normal,self.colour)
         self.imap[e1][k1] = i1
      i2 = self.imap[e2][k2]
      if i2 < 0:
         i2 = self.geom.add_vertex(self.edges[e2][k2],self.normal,self.colour)
         self.imap[e2][k2] = i2
      if dk > 0: self.geom.add_triangle(i0,i1,i2)
      else     : self.geom.add_triangle(i1,i0,i2)

   def build(self):
      if not self.query_edges(): return

      assert( not self.geom.used_v )
      assert( not self.geom.used_t )

      self.geom.unused_v.extend(self.vertices )
      self.geom.unused_t.extend(self.triangles)

      lsts      = ( len(self.edges[0])-1, len(self.edges[1])-1, len(self.edges[2])-1, len(self.edges[3])-1 )
      idxs      = ( [ 0, lsts[0], 0x7f ], [ 0, lsts[1], 0x7f ], [ 0, lsts[2], 0x7f ], [ 0, lsts[3], 0x7f ] )
      attach    = ( -1, 0, 0, 1, -1, -1, 1 )
      self.imap = ( [-1]*len(self.edges[0]), [-2]*len(self.edges[1]), [-3]*len(self.edges[2]), [-4]*len(self.edges[3]) )
      self.imap[0][ 0] = self.imap[3][-1] = self.geom.add_vertex(self.edges[0][0],self.normal,self.colour)
      self.imap[0][-1] = self.imap[1][ 0] = self.geom.add_vertex(self.edges[1][0],self.normal,self.colour)
      self.imap[2][-1] = self.imap[3][ 0] = self.geom.add_vertex(self.edges[3][0],self.normal,self.colour)
      self.imap[1][-1] = self.imap[2][ 0] = self.geom.add_vertex(self.edges[2][0],self.normal,self.colour)

      while True:
         sel = ( 1e9, )
         for e0 in range(4):
            if idxs[e0][2] and idxs[e0][0] != idxs[e0][1]:
               for e in (3,1,2,6):
                  if idxs[e0][2]&(1<<e) != 0:
                     if e&3 == 2: # opposite
                        e2 = (e0+(3 if e == 6 else 1))&3
                        if idxs[e2][0] == idxs[e2][1] and 0 < idxs[e2][0] < lsts[e2] and idxs[e2][2]&((1<<1)|(1<<3)) == ((1<<1)|(1<<3)): continue
                     j2 = attach[e]
                     j0 = j2^1
                     k0 = idxs[e0][j0]
                     e2 = (e0+e)&3
                     k2 = idxs[e2][j2]
                     dk = 1-(j0<<1) # +1 or -1
                     if self.imap[e0][k0] == self.imap[e2][k2]: # corner
                        if k2 == idxs[e2][j0]: continue
                        k2 -= dk
                     d  = max( (self.edges[e2][k2]-self.edges[e0][k0]).length_squared(), (self.edges[e2][k2]-self.edges[e0][k0+dk]).length_squared() )
                     if d < sel[0]: sel = (d,e0,j0,k0,e2,j2,k2,dk,e)
         if len(sel) == 1:
            for e0 in range(4):
               if idxs[e0][0] == idxs[e0][1] and 0 < idxs[e0][0] < lsts[e0] and idxs[e0][2]&((1<<1)|(1<<3)) == ((1<<1)|(1<<3)):
                  e1 = (e0+1)&3
                  e2 = (e0+3)&3
                  if idxs[e1][0] == idxs[e1][1] and idxs[e2][0] == idxs[e2][1]: break
            else: break
            idxs[e0][2] = 0
            self.add_triangle(e0,idxs[e0][0],e1,idxs[e1][0],e2,idxs[e2][0],1)
            continue
         d,e0,j0,k0,e2,j2,k2,dk,e = sel
         k1 = k0+dk
         self.add_triangle(e0,k0,e0,k1,e2,k2,dk)
         idxs[e0][j0] = k1
         idxs[e2][j2] = k2
         if   e == 6: # from left to opposite left
            idxs[(e0+1)&3][2] &= ~((1<<2)|(1<<6))        # right   : disable opposite
            idxs[ e0     ][2] &= ~(1<<3)                 # current : disable left
            idxs[(e0+3)&3][2] &= ~((1<<2)|(1<<6)|(1<<1)) # left    : disable opposite and right
            idxs[ e2     ][2] &= ~(1<<1)                 # opposite: disable right
         elif e == 2: # from right to opposite right
            idxs[(e0+3)&3][2] &= ~((1<<2)|(1<<6))        # left    : disable opposite
            idxs[ e0     ][2] &= ~(1<<1)                 # current : disable right
            idxs[(e0+1)&3][2] &= ~((1<<2)|(1<<6)|(1<<3)) # right   : disable opposite and left
            idxs[ e2     ][2] &= ~(1<<3)                 # opposite: disable left

      del self.imap
      self.vertices    = self.geom.used_v
      self.triangles   = self.geom.used_t
      self.geom.used_v = []
      self.geom.used_t = []

   def change_triangles(self,imap):
{'fraction_non_alphanumeric': 0.19981054198524933, 'fraction_numerical': 0.07131740983828405, 'mean_word_length': 1.8335889570552146, 'pattern_counts': {'":': 0, '<': 93, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5645168', 'n_tokens_mistral': 6383, 'n_tokens_neox': 6110, 'n_words': 963}