| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 
 | def clip_segment_v3_plane_n(p1, p2, planes):"""
 - p1, p2: pair of 3d vectors defining a line segment.
 - planes: a sequence of (4 floats): `(x, y, z, d)`.
 
 Returns 2 vector triplets (the clipped segment)
 or (None, None) then segment is entirely outside.
 """
 dp = sub_v3v3(p2, p1)
 
 p1_fac = 0.0
 p2_fac = 1.0
 
 for p in planes:
 div = dot_v3v3(p, dp)
 if div != 0.0:
 t = -plane_point_side_v3(p, p1)
 if div > 0.0:  # clip p1 lower bounds
 if t >= div:
 return None, None
 if t > 0.0:
 fac = (t / div)
 if fac > p1_fac:
 p1_fac = fac
 if p1_fac > p2_fac:
 return None, None
 elif div < 0.0:  # clip p2 upper bounds
 if t > 0.0:
 return None, None
 if t > div:
 fac = (t / div)
 if fac < p2_fac:
 p2_fac = fac
 if p1_fac > p2_fac:
 return None, None
 
 p1_clip = add_v3v3(p1, mul_v3_fl(dp, p1_fac))
 p2_clip = add_v3v3(p1, mul_v3_fl(dp, p2_fac))
 
 return p1_clip, p2_clip
 
 
 # inline math library
 def add_v3v3(v0, v1):
 return (
 v0[0] + v1[0],
 v0[1] + v1[1],
 v0[2] + v1[2],
 )
 
 def sub_v3v3(v0, v1):
 return (
 v0[0] - v1[0],
 v0[1] - v1[1],
 v0[2] - v1[2],
 )
 
 def dot_v3v3(v0, v1):
 return (
 (v0[0] * v1[0]) +
 (v0[1] * v1[1]) +
 (v0[2] * v1[2])
 )
 
 def mul_v3_fl(v0, f):
 return (
 v0[0] * f,
 v0[1] * f,
 v0[2] * f,
 )
 
 def plane_point_side_v3(p, v):
 return dot_v3v3(p, v) + p[3]
 |