Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'render_povray/voxel_lib.py')
-rw-r--r--render_povray/voxel_lib.py389
1 files changed, 389 insertions, 0 deletions
diff --git a/render_povray/voxel_lib.py b/render_povray/voxel_lib.py
new file mode 100644
index 00000000..02497595
--- /dev/null
+++ b/render_povray/voxel_lib.py
@@ -0,0 +1,389 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright 2005 Mike Kost <contact@povray.tashcorp.net>
+
+################################################################################
+#
+# df3.py
+#
+# -----------------------------------------------------------------------------
+#
+# Creation functions
+# __init__(x=1, y=1, z=1) : default constructor
+# clone(indf3) : make this df3 look like indf3
+#
+# Info functions
+# sizeX(): returns X dimension
+# sizeY(): returns Y dimension
+# sizeZ(): returns Z dimension
+#
+# Scalar functions
+# mult():
+# add():
+# max(): returns highest voxel value in df3
+# min(): returns lowest voxel value in df3
+#
+# Vector functions
+#
+# Import/Export functions
+# exportDF3():
+# importDF3():
+#
+# -----------------------------------------------------------------------------
+
+import struct
+import os
+import stat
+import array
+
+# -+-+-+- Start df3 Class -+-+-+-
+
+
+class df3:
+ __version__ = '0.2'
+
+ __arraytype__ = 'f'
+
+ __struct4byte__ = '>I'
+ __struct2byte__ = '>H'
+ __struct2byte3__ = '>HHH'
+ __struct1byte__ = '>B'
+ __array4byte__ = 'I'
+ __array2byte__ = 'H'
+ __array1byte__ = 'B'
+
+ def __init__(self, x=1, y=1, z=1):
+ self.maxX = x
+ self.maxY = y
+ self.maxZ = z
+ self.voxel = self.__create__(x, y, z)
+
+ def clone(self, indf3):
+ self.voxel = array.array(self.__arraytype__)
+ for i in range(indf3.sizeX() * indf3.sizeY() * indf3.sizeZ()):
+ self.voxel[i] = indf3.voxel[i]
+ return self
+
+ # --- Info Functions
+
+ def sizeX(self):
+ return self.maxX
+
+ def sizeY(self):
+ return self.maxY
+
+ def sizeZ(self):
+ return self.maxZ
+
+ def size(self):
+ tmp = [self.sizeX()]
+ tmp.append(self.sizeY())
+ tmp.append(self.sizeZ())
+ return tmp
+
+ # --- Voxel Access Functions
+
+ def get(self, x, y, z):
+ return self.voxel[self.__voxa__(x, y, z)]
+
+ def getB(self, x, y, z):
+ if x > self.sizeX() or x < 0:
+ return 0
+ if y > self.sizeX() or y < 0:
+ return 0
+ if z > self.sizeX() or z < 0:
+ return 0
+
+ return self.voxel[self.__voxa__(x, y, z)]
+
+ def set(self, x, y, z, val):
+ self.voxel[self.__voxa__(x, y, z)] = val
+
+ def setB(self, x, y, z, val):
+ if x > self.sizeX() or x < 0:
+ return
+ if y > self.sizeX() or y < 0:
+ return
+ if z > self.sizeX() or z < 0:
+ return
+
+ self.voxel[self.__voxa__(x, y, z)] = val
+
+ # --- Scalar Functions
+
+ def mult(self, val):
+ for i in range(self.sizeX() * self.sizeY() * self.sizeZ()):
+ self.voxel[i] = self.voxel[i] * val
+
+ return self
+
+ def add(self, val):
+ for i in range(self.sizeX() * self.sizeY() * self.sizeZ()):
+ self.voxel[i] = self.voxel[i] + val
+
+ return self
+
+ def max(self):
+ tmp = self.voxel[0]
+
+ for i in range(self.sizeX() * self.sizeY() * self.sizeZ()):
+ if self.voxel[i] > tmp:
+ tmp = self.voxel[i]
+
+ return tmp
+
+ def min(self):
+ tmp = self.voxel[0]
+
+ for i in range(self.sizeX() * self.sizeY() * self.sizeZ()):
+ if self.voxel[i] < tmp:
+ tmp = self.voxel[i]
+
+ return tmp
+
+ # --- Vector Functions
+
+ def compare(self, indf3):
+ if self.__samesize__(indf3) == 0:
+ return 0
+
+ if self.voxel == indf3.voxel:
+ return 1
+
+ return 0
+
+ def multV(self, indf3):
+ if self.__samesize__(indf3) == 0:
+ print("Cannot multiply voxels - not same size")
+ return
+
+ for i in range(self.sizeX() * self.sizeY() * self.sizeZ()):
+ self.voxel[i] = self.voxel[i] * indf3.voxel[i]
+
+ return self
+
+ def addV(self, indf3):
+ if self.__samesize__(indf3) == 0:
+ print("Cannot add voxels - not same size")
+ return
+
+ for i in range(self.sizeX() * self.sizeY() * self.sizeZ()):
+ self.voxel[i] = self.voxel[i] + indf3.voxel[i]
+
+ return self
+
+ def convolveV(self, filt):
+ fx = filt.sizeX()
+ fy = filt.sizeY()
+ fz = filt.sizeZ()
+ if fx % 2 != 1:
+ print("Incompatible filter - must be odd number of X")
+ return self
+ if fy % 2 != 1:
+ print("Incompatible filter - must be odd number of Y")
+ return self
+ if fz % 2 != 1:
+ print("Incompatible filter - must be odd number of Z")
+ return self
+
+ fdx = (fx - 1) / 2
+ fdy = (fy - 1) / 2
+ fdz = (fz - 1) / 2
+ flen = fx * fy * fz
+
+ newV = self.__create__(self.sizeX(), self.sizeY(), self.sizeZ())
+
+ for x in range(self.sizeX()):
+ for y in range(self.sizeY()):
+ for z in range(self.sizeZ()):
+ rip = self.__rip__(x - fdx, x + fdx, y - fdy, y + fdy, z - fdz, z + fdz)
+ tmp = 0.0
+ for i in range(flen):
+ tmp += rip[i] * filt.voxel[i]
+ newV[self.__voxa__(x, y, z)] = tmp
+
+ self.voxel = newV
+
+ return self
+
+ # --- Import/Export Functions
+
+ def exportDF3(self, file, depth=8, rescale=1):
+ x = self.sizeX()
+ y = self.sizeY()
+ z = self.sizeZ()
+
+ try:
+ f = open(file, 'wb')
+ except BaseException as e:
+ print(e.__doc__)
+ print('An exception occurred: {}'.format(e))
+ print("Could not open " + file + " for write")
+ return
+
+ f.write(struct.pack(self.__struct2byte3__, x, y, z))
+
+ tmp = self.__toInteger__(pow(2, depth) - 1, rescale)
+
+ if depth > 16: # 32-bit
+ for i in range(x * y * z):
+ f.write(struct.pack(self.__struct4byte__, tmp[i]))
+ elif depth > 8: # 16-bit
+ for i in range(x * y * z):
+ f.write(struct.pack(self.__struct2byte__, tmp[i]))
+ else:
+ for i in range(x * y * z):
+ f.write(struct.pack(self.__struct1byte__, tmp[i]))
+
+ def importDF3(self, file, scale=1):
+ try:
+ f = open(file, 'rb')
+ size = os.stat(file)[stat.ST_SIZE]
+
+ except BaseException as e:
+ print(e.__doc__)
+ print('An exception occurred: {}'.format(e))
+ print("Could not open " + file + " for read")
+ return []
+
+ (x, y, z) = struct.unpack(self.__struct2byte3__, f.read(6))
+
+ self.voxel = self.__create__(x, y, z)
+ self.maxX = x
+ self.maxY = y
+ self.maxZ = z
+
+ size = size - 6
+ if size == x * y * z:
+ format = 8
+ elif size == 2 * x * y * z:
+ format = 16
+ elif size == 4 * x * y * z:
+ format = 32
+
+ for i in range(x * y * z):
+ if format == 32:
+ self.voxel[i] = float(struct.unpack(self.__struct4byte__, f.read(4))[0])
+ elif format == 16:
+ self.voxel[i] = float(struct.unpack(self.__struct2byte__, f.read(2))[0])
+ elif format == 8:
+ self.voxel[i] = float(struct.unpack(self.__struct1byte__, f.read(1))[0])
+
+ return self
+
+ # --- Local classes not intended for user use
+
+ def __rip__(self, minX, maxX, minY, maxY, minZ, maxZ):
+ sizeX = maxX - minX + 1
+ sizeY = maxY - minY + 1
+ sizeZ = maxZ - minZ + 1
+
+ tmpV = self.__create__(sizeX, sizeY, sizeZ)
+
+ for x in range(sizeX):
+ for y in range(sizeY):
+ for z in range(sizeZ):
+ # Check X
+ if (minX + x) < 0:
+ tmpV[(z * sizeZ + y) * sizeY + x] = 0.0
+ elif (minX + x) > self.sizeX() - 1:
+ tmpV[(z * sizeZ + y) * sizeY + x] = 0.0
+ # Check Y
+ elif (minY + y) < 0:
+ tmpV[(z * sizeZ + y) * sizeY + x] = 0.0
+ elif (minY + y) > self.sizeY() - 1:
+ tmpV[(z * sizeZ + y) * sizeY + x] = 0.0
+ # Check Z
+ elif (minZ + z) < 0:
+ tmpV[(z * sizeZ + y) * sizeY + x] = 0.0
+ elif (minZ + z) > self.sizeZ() - 1:
+ tmpV[(z * sizeZ + y) * sizeY + x] = 0.0
+ else:
+ tmpV[(z * sizeZ + y) * sizeY + x] = self.get(minX + x, minY + y, minZ + z)
+
+ return tmpV
+
+ def __samesize__(self, indf3):
+ if self.sizeX() != indf3.sizeX():
+ return 0
+ if self.sizeY() != indf3.sizeY():
+ return 0
+ if self.sizeZ() != indf3.sizeZ():
+ return 0
+ return 1
+
+ def __voxa__(self, x, y, z):
+ return (z * self.sizeY() + y) * self.sizeX() + x
+
+ def __create__(self, x, y, z, atype='0', init=1):
+ if atype == '0':
+ tmp = self.__arraytype__
+ else:
+ tmp = atype
+
+ if init == 1:
+ if tmp in ('f', 'd'):
+ voxel = array.array(tmp, [0.0 for i in range(x * y * z)])
+ else:
+ voxel = array.array(tmp, [0 for i in range(x * y * z)])
+ else:
+ voxel = array.array(tmp)
+
+ return voxel
+
+ def __toInteger__(self, scale, rescale=1):
+ if scale < pow(2, 8): # 8-bit
+ tmp = self.__create__(self.sizeX(), self.sizeY(), self.sizeZ(), self.__array1byte__)
+ elif scale < pow(2, 16): # 16-bit
+ tmp = self.__create__(self.sizeX(), self.sizeY(), self.sizeZ(), self.__array2byte__)
+ else: # 32-bit
+ tmp = self.__create__(self.sizeX(), self.sizeY(), self.sizeZ(), self.__array4byte__)
+
+ maxVal = self.max()
+
+ print(scale)
+
+ for i in range(self.sizeX() * self.sizeY() * self.sizeZ()):
+ if rescale == 1:
+ tmp[i] = max(0, int(round(scale * self.voxel[i] / maxVal)))
+ else:
+ tmp[i] = max(0, min(scale, int(round(self.voxel[i]))))
+
+ return tmp
+
+
+# -=-=-=- End df3 Class -=-=-=-
+# --------DEFAULT EXAMPLES
+# if __name__ == '__main__':
+# localX = 80
+# localY = 90
+# localZ = 100
+# -- Generate an output
+# temp = df3(localX, localY, localZ)
+
+# for i in range(localX):
+# for j in range(localY):
+# for k in range(localZ):
+# if (i >= (localX/2)):
+# temp.set(i, j, k, 1.0)
+
+# temp.exportDF3('temp.df3', 16)
+# -----------------------------------------------------------------------------
+# -- Import
+# temp2 = df3().importDF3('temp.df3')
+# temp2.mult(1/temp2.max())
+
+# -- Compare
+# print(temp2.size())
+
+# if (temp.compare(temp2) == 0): print("DF3's Do Not Match")
+
+# -----------------------------------------------------------------------------
+# ChangeLog
+# ---------
+# 08/09/05: 0.20 released
+# + Change internal representation to floating point
+# + Rewrite import/export for speed
+# + Convert from 3-d list structure to Array class for data storage
+# + Add element access, scalar, and vector functions
+# 07/13/05: 0.10 released
+# -----------------------------------------------------------------------------