from math import fabs, sqrt
from mathutils import Vector
from numpy import interp
from . imageSpot import ImageSpot
[docs]
class SpaceProfile:
def __init__(self, *, radius=None, value=None):
self._radius = radius
self._value = value
self._maxRadius = max(radius)
[docs]
def getValue(self, *, radius=None):
return interp(radius, self._radius, self._value, left=0, right=0)
@property
def maxRadius(self):
return self._maxRadius
[docs]
class LaserBeam:
def __init__(self, *, laserSpot=None, laserBeam=None, point=None, axis=None):
self._point = point
self._axis = axis
if self._point is None:
self._point = Vector((laserBeam.point[0],
laserBeam.point[1],
laserBeam.point[2]))
if self._axis is None:
self._axis = Vector((laserBeam.axis[0],
laserBeam.axis[1],
laserBeam.axis[2]))
self._axis.normalize()
self._considerFaceNormal = laserSpot.consider_face_normal
self._isSquare = False
self._squareDir = Vector((laserBeam.spot_axis[0],
laserBeam.spot_axis[1],
laserBeam.spot_axis[2]))
self._pureSquareRadius = 0.0
if laserSpot.shape == 'image':
self._spaceProfile = ImageSpot(laserSpot=laserSpot)
self._isSquare = True
else:
radius = []
value = []
for profile in laserSpot.profile:
radius.append(profile.radius)
value.append(profile.value)
self._spaceProfile = SpaceProfile(radius=radius, value=value)
if laserSpot.shape == 'square':
self._isSquare = True
self._pureSquareRadius = laserSpot.pure_square_radius
if self._isSquare:
self._pureSquareRadius = self._pureSquareRadius
self._C = []
self._C.append(Vector((self._pureSquareRadius,
self._pureSquareRadius, 0.0)))
self._C.append(Vector((-self._pureSquareRadius,
self._pureSquareRadius, 0.0)))
self._C.append(Vector((self._pureSquareRadius,
-self._pureSquareRadius, 0.0)))
self._C.append(Vector((-self._pureSquareRadius,
-self._pureSquareRadius, 0.0)))
self._e1 = self._axis.dot(self._squareDir)
self._e1 = self._e1 * self._axis
self._e1 = self._squareDir - self._e1
self._e1.normalize()
self._e2 = self._axis.cross(self._e1)
self._e2.normalize()
[docs]
def inBeam(self, *, coords=None):
d = coords - self._point
maxDist = 0
if self._isSquare:
d1 = self._e1.dot(d)
d2 = self._e2.dot(d)
maxDist = max(fabs(d1), fabs(d2))
else:
magD = fabs(d.dot(self._axis))
maxDist = d.dot(d) - magD * magD
try:
maxDist = sqrt(maxDist)
except Exception:
maxDist = 0.0
if maxDist < self._spaceProfile.maxRadius:
return True
else:
return False
[docs]
def getValue(self, *, coords=None, normal=None):
d = coords - self._point
eff = 1.0
if self._considerFaceNormal:
eff = -normal.dot(self._axis)
if eff < 0.0:
eff = 0.0
if isinstance(self._spaceProfile, ImageSpot):
d1 = self._e1.dot(d)
d2 = self._e2.dot(d)
value = self._spaceProfile.getValue(x=d1, y=d2)
else:
if self._isSquare:
d1 = self._e1.dot(d)
d2 = self._e2.dot(d)
maxDist = max(fabs(d1), fabs(d2))
if maxDist > self._pureSquareRadius:
V = Vector((d1, d2, 0.0))
for i in range(0, 4):
R = V - self._C[i]
if R.x * self._C[i].x >= 0.0:
if R.y * self._C[i].y >= 0.0:
maxDist = self._pureSquareRadius + R.length
else:
magD = fabs(d.dot(self._axis))
try:
maxDist = sqrt((d.dot(d) - magD * magD))
except Exception:
maxDist = 0.0
value = self._spaceProfile.getValue(radius=maxDist)
return eff * value
@property
def point(self):
return self._point
@property
def axis(self):
return self._axis
@property
def spaceProfil(self):
return self._spaceProfile