Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues/108 #116

Merged
merged 32 commits into from
Jun 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
56153ad
fixing crucial error with .odt formatting
LemurPwned May 12, 2018
0969188
now time is displayed in Canvas if plot file has time data
LemurPwned May 12, 2018
b858655
screenshots are now saved from all widgets
LemurPwned May 12, 2018
a935aa3
merge
LemurPwned May 15, 2018
faf8ec2
merge with master
LemurPwned May 15, 2018
6d660ab
plots are now synchronized 1-1 to animation
LemurPwned May 15, 2018
ef582b3
simplifying widget choosing
LemurPwned May 15, 2018
eb9d102
optional matplotlib toolbar
LemurPwned May 15, 2018
5444c44
update
LemurPwned May 15, 2018
a71d7ca
missing files on this branch
LemurPwned May 15, 2018
db95c61
merging master
LemurPwned May 15, 2018
4173a78
working toolbar
LemurPwned May 17, 2018
a88e4fd
working toolbar
LemurPwned May 17, 2018
355c210
fixing prototype toolbar for matplotlib
LemurPwned May 17, 2018
a87a6ec
small camera fix
LemurPwned May 17, 2018
7edbe51
heading towards proper screenshots
LemurPwned May 21, 2018
82aa055
used existing decorator, problem was that decorator was overwritten
LemurPwned May 21, 2018
91ba4a4
iterating in matplotlib canvas fixed
LemurPwned May 21, 2018
3887c7f
adding new files
LemurPwned May 23, 2018
3d6baf3
merging
LemurPwned Jun 12, 2018
972b5da
updated .gitignore
LemurPwned Jun 12, 2018
1ad94db
update for Windows stuff
LemurPwned Jun 12, 2018
0afacea
resolving conflicts after merge update
LemurPwned Jun 14, 2018
707b165
old branch update
LemurPwned Jun 14, 2018
78ec501
merge update
LemurPwned Jun 14, 2018
2aa71ba
merge update
LemurPwned Jun 14, 2018
5be45ee
another merge resolve
LemurPwned Jun 14, 2018
2634ce5
now object snaps to mouse
LemurPwned Jun 14, 2018
7238ace
fixes #105 with a completely new camera
LemurPwned Jun 17, 2018
711e598
adding additional field to columns
LemurPwned Jun 17, 2018
5c66f5e
fixes #110 adding super high contrast
LemurPwned Jun 17, 2018
690196f
adding Windows automatic installation
LemurPwned Jun 18, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ Screenshots/
test_folder/
*.so
*.o
*.c
cython_modules/*.so
cython_modules/*.c

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
4 changes: 3 additions & 1 deletion AnimatedWidget.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class AnimatedWidget():
WIDGET_ID = 0
def shareData(self, **kwargs):
"""
@param **kwargs are the arguments to be passed to the main widget
Expand All @@ -18,7 +19,7 @@ def handleOptionalData(self):
def loop_guard(self):
self.i %= self.iterations

def set_i(self, value, trigger=False):
def set_i(self, value, trigger=False, record=False):
"""
This is iterating setter. Function set_i should provide
a neat way to change the current data of Widget and then
Expand All @@ -35,3 +36,4 @@ def receivedOptions(self):
self.vector_set = self.options[4]
self.decimate = int(self.options[5])
self.disableDot = self.options[6]
self.hyperContrast = self.options[7]
21 changes: 19 additions & 2 deletions ColorPolicy.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ def standard_procedure(outline, color, iterations, averaging, xc, yc, zc,
picked_layer='all',
vector_set=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
decimate=1,
disableDot=True):
disableDot=True,
hyperContrast=False):
"""
this function should be called whenever one of the following is needed:
- sampling
Expand All @@ -157,6 +158,7 @@ def standard_procedure(outline, color, iterations, averaging, xc, yc, zc,
color = np.array(color)
outline = np.array(outline)
outline = ColorPolicy.pad_4f_vertices(color[0], outline)

if type(picked_layer) == int:
# if single layer is picked modify memory data
zc = 1
Expand All @@ -165,6 +167,21 @@ def standard_procedure(outline, color, iterations, averaging, xc, yc, zc,
color = color[:, picked_layer:picked_layer+layer_thickness, :]
outline = outline[picked_layer:picked_layer+layer_thickness]
# input is in form (iterations, zc*yc*xc, 3) and vectors are normalized
if hyperContrast:
for iteration in range(len(color)):
"""
this is hyper contrast option, enabled via options
"""
for i in range(zc):
mnR = np.mean(color[iteration, i*xc*yc:(i+1)*xc*yc, 0])
mnG = np.mean(color[iteration, i*xc*yc:(i+1)*xc*yc, 1])
mnB = np.mean(color[iteration, i*xc*yc:(i+1)*xc*yc, 2])
color[iteration, i*xc*yc:(i+1)*xc*yc, 0] -= mnR
color[iteration, i*xc*yc:(i+1)*xc*yc, 1] -= mnG
color[iteration, i*xc*yc:(i+1)*xc*yc, 2] -= mnB
color[iteration, i*xc*yc:(i+1)*xc*yc, 0] *= 10e7
color[iteration, i*xc*yc:(i+1)*xc*yc, 1] *= 10e7
color[iteration, i*xc*yc:(i+1)*xc*yc, 2] *= 10e7
if decimate != 1:
color = color[:,::decimate,:]
outline = outline[::decimate, :]
Expand Down Expand Up @@ -195,4 +212,4 @@ def standard_procedure(outline, color, iterations, averaging, xc, yc, zc,
if not decimate:
assert dotted_color.shape == (iterations, zc*yc*xc, 3)
assert outline.shape == (zc*yc*xc, 4)
return dotted_color, outline, decimate, color
return dotted_color, outline, decimate
11 changes: 10 additions & 1 deletion WidgetHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,14 @@ def addWidget(self, widget):
except:
raise ValueError("Layout is not proper or argument is not a widget")

def addToolBar(self, toolbar):
self._toolbar = toolbar
if self._groupBox == None:
raise ValueError("GroupBox must be initialized")
# try:
self._widget.addToolBar(self._toolbar)
# except:
# raise ValueError("Argument is not a toolbar")

def setDisabled(self, value):
self._button.setDisabled(value)
self._button.setDisabled(value)
97 changes: 49 additions & 48 deletions Widgets/openGL_widgets/AbstractGLContext.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ class AbstractGLContext(QOpenGLWidget, AnimatedWidget):
def __init__(self, parent=None):
super(AbstractGLContext, self).__init__(parent)
AbstractGLContext.ANY_GL_WIDGET_IN_VIEW += 1

self.subdir = "GL" + str(AnimatedWidget.WIDGET_ID)
AnimatedWidget.WIDGET_ID += 1
self.lastPos = QPoint()
self.setFocusPolicy(Qt.StrongFocus) # needed if keyboard to be active

Expand Down Expand Up @@ -80,7 +81,7 @@ def prerendering_calculation(self):
yc = int(self.file_header['ynodes'])
zc = int(self.file_header['znodes'])
# change drawing function
self.color_vectors, self.vectors_list, decimate, self.color = \
self.color_vectors, self.vectors_list, decimate = \
ColorPolicy.standard_procedure(self.vectors_list,
self.color_vectors,
self.iterations,
Expand All @@ -89,7 +90,8 @@ def prerendering_calculation(self):
self.layer,
self.vector_set,
self.decimate,
disableDot=self.disableDot)
disableDot=self.disableDot,
hyperContrast=self.hyperContrast)
if decimate is not None:
# this is arbitrary
self.spacer *= decimate*3
Expand All @@ -108,30 +110,29 @@ def auto_center(self):
"""
auto centers the structure in widget screen
"""
x_fix = (self.file_header['xnodes'] * self.file_header['xbase'] * 1e9) / 2
y_fix = (self.file_header['ynodes'] * self.file_header['ybase'] * 1e9) / 2
z_fix = (self.file_header['znodes'] * self.file_header['zbase'] * 1e9) / 2
self.x_fix = (self.file_header['xnodes'] * self.file_header['xbase'] * 1e9) / 2
self.y_fix = (self.file_header['ynodes'] * self.file_header['ybase'] * 1e9) / 2
self.z_fix = (self.file_header['znodes'] * self.file_header['zbase'] * 1e9) / 2
for vec in self.vectors_list:
vec[0] -= x_fix
vec[1] -= y_fix
vec[2] -= z_fix
vec[0] -= self.x_fix
vec[1] -= self.y_fix
vec[2] -= self.z_fix

def initial_transformation(self):
"""
resets the view to the initial one
:return:
"""
self.rotation = [0, 0, 0] # xyz degrees in xyz axis
self.position = [0, 0 , -50] # xyz initial
self.position = [0, 0 , -150] # xyz initial

def transformate(self):
"""
applies rotation and transformation
"""
gl.glRotatef(self.rotation[0], 0, 1, 0) # rotate around y axis
gl.glRotatef(self.rotation[1], 1, 0, 0) # rotate around x axis
gl.glRotatef(self.rotation[0], 0, 1, 0) # rotate around y axis
gl.glRotatef(self.rotation[2], 0, 0, 1) # rotate around z axis
gl.glTranslatef(self.position[0], self.position[1], self.position[2])

def initializeGL(self):
"""
Expand Down Expand Up @@ -163,6 +164,7 @@ def paintGL(self):
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
# Push Matrix onto stack
gl.glPushMatrix()
gl.glTranslatef(*self.position)
self.transformate()
self.drawing_function()
self.text_functionalities()
Expand All @@ -181,12 +183,13 @@ def text_functionalities(self):
self.text_render(AbstractGLContext.TEXT,
AbstractGLContext.SELECTED_POS)

def set_i(self, value, trigger=False):
def set_i(self, value, trigger=False, record=False):
if trigger:
self.i += 1
else:
self.i = value
self.i %= self.iterations
self.record = record

def keyPressEvent(self, event):
"""
Expand Down Expand Up @@ -224,38 +227,21 @@ def keyPressEvent(self, event):
self.display_frames = True

def zoomIn(self):
self.steps = 1
# SMART SCROLL BETA
self.position[0] -= mt.sin(self.rotation[0] * mt.pi / 180) * \
mt.cos(self.rotation[1] * mt.pi / 180) * self.steps
self.position[1] += mt.cos(self.rotation[0] * mt.pi / 180) * \
mt.sin(self.rotation[1] * mt.pi / 180) * self.steps
self.position[2] += mt.cos(self.rotation[0] * mt.pi / 180) * \
mt.cos(self.rotation[1] * mt.pi / 180) * self.steps
self.position[2] += 16 / 8

def zoomOut(self):
self.steps = -1

self.position[0] -= mt.sin(self.rotation[0] * mt.pi / 180) * \
mt.cos(self.rotation[1] * mt.pi / 180) * self.steps
self.position[1] += mt.cos(self.rotation[0] * mt.pi / 180) * \
mt.sin(self.rotation[1] * mt.pi / 180) * self.steps
self.position[2] += mt.cos(self.rotation[0] * mt.pi / 180) * \
mt.cos(self.rotation[1] * mt.pi / 180) * self.steps
self.position[2] -= 16 / 8

def wheelEvent(self, event):
"""
Handles basic mouse scroll
"""
degs = event.angleDelta().y() / 8
self.steps = degs / 15
# SMART SCROLL BETA
self.position[0] -= mt.sin(self.rotation[0] * mt.pi / 180) * \
mt.cos(self.rotation[1] * mt.pi / 180) * self.steps
self.position[1] += mt.cos(self.rotation[0] * mt.pi / 180) * \
mt.sin(self.rotation[1] * mt.pi / 180) * self.steps
self.position[2] += mt.cos(self.rotation[0] * mt.pi / 180) * \
mt.cos(self.rotation[1] * mt.pi / 180) * self.steps
degsx = event.angleDelta().x() / 8
degsy = event.angleDelta().y() / 8
if (abs(degsx) > abs(degsy)):
self.position[0] += event.angleDelta().x() / 8 / 2
else:
self.position[2] += event.angleDelta().y() / 8 / 2

self.update()

Expand All @@ -277,24 +263,33 @@ def mouseMoveEvent(self, event):
self.lastPos = event.pos()
if event.buttons() & Qt.LeftButton:
rotation_speed = 0.5
self.rotation[0] += dx * rotation_speed
xpos = self.position[0] * mt.cos(dx * rotation_speed * mt.pi / 180) \
- self.position[2] * mt.sin(dx * rotation_speed * mt.pi / 180)
zpos = self.position[0] * mt.sin(dx * rotation_speed * mt.pi / 180) \
+ self.position[2] * mt.cos(dx * rotation_speed * mt.pi / 180)

self.position[0] = xpos
self.position[2] = zpos
if abs(dx) > abs(dy):
ang = self.normalize_angle(dx * rotation_speed)
self.rotation[0] += ang
else:
ang = self.normalize_angle(dy * rotation_speed)
self.rotation[1] += ang

elif event.buttons() & Qt.RightButton:
if abs(self.rotation[0])%360 < 90:
self.position[0] += dx * 0.2
else:
self.position[0] -= dx * 0.2

self.position[1] -= dy * 0.2

self.update()

def mouseReleaseEvent(self, event):
if event.buttons() & Qt.RightButton:
self.lastPos = event.pos()

def normalize_angle(self, angle):
while angle < 0:
angle += 360 * 16
while angle > 360 * 16:
angle -= 360 * 16
return angle

def fps_counter(self, initialize=False):
if initialize:
self.TIME_PASSED = time.time()
Expand Down Expand Up @@ -341,17 +336,23 @@ def screenshot_manager(self):
"""
# fetch dimensions for highest resolution
_, _, width, height = gl.glGetIntegerv(gl.GL_VIEWPORT)
if width == 0 or height == 0:
width = self.geom[0]
height = self.geom[1]
color = gl.glReadPixels(0, 0,
width, height,
gl.GL_RGB, gl.GL_UNSIGNED_BYTE)
image = Image.frombytes(mode='RGB', size=(width, height),
data=color)
image = image.transpose(Image.FLIP_TOP_BOTTOM)
try:
if os.path.basename(self.screenshot_dir) != self.subdir:
self.screenshot_dir = os.path.join(self.screenshot_dir,
self.subdir)
image.save(os.path.join(self.screenshot_dir,
str(self.i).zfill(4) + ".png"))
except FileNotFoundError:
# if basic dir not found, create it and save there
os.mkdir(self.screenshot_dir)
os.makedirs(self.screenshot_dir)
image.save(os.path.join(self.screenshot_dir,
str(self.i).zfill(4) + ".png"))
14 changes: 3 additions & 11 deletions Widgets/openGL_widgets/CubicGLContext.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import OpenGL.GLU as glu
import OpenGL.GL as gl
import numpy as np

from PyQt5.QtWidgets import QWidget
from PyQt5.Qt import Qt

from cython_modules.cython_parse import getLayerOutline, genCubes

from Widgets.openGL_widgets.AbstractGLContext import AbstractGLContext
from pattern_types.Patterns import AbstractGLContextDecorators

from ColorPolicy import ColorPolicy
from multiprocessing import Pool


class CubicGLContext(AbstractGLContext, QWidget):
def __init__(self, data_dict, parent):
Expand All @@ -21,6 +19,8 @@ def __init__(self, data_dict, parent):
self.vertices = 0
self.buffers = None
self.buffer_len = 0
self.scale = 5

self.prerendering_calculation()
self.drawing_function = self.vbo_cubic_draw

Expand All @@ -33,21 +33,13 @@ def prerendering_calculation(self):
self.drawing_function = self.vbo_cubic_draw
self.buffers = None
# if vbo drawing is selected, do additional processing

xc = int(self.file_header['xnodes'])
yc = int(self.file_header['ynodes'])
zc = int(self.file_header['znodes'])
self.vectors_list, self.vertices = genCubes(self.vectors_list,
self.spacer)
self.color_vectors = ColorPolicy.apply_vbo_format(self.color_vectors)

print(np.array(self.vectors_list).shape, self.vertices)
print(np.array(self.color_vectors).shape)

# TODO: temporary fix, dont know why x4, should not be multiplied
# at all!
self.buffer_len = len(self.color_vectors[0])*4
print("BUFFER LEN" , self.buffer_len)
elif self.function_select == 'slow':
self.drawing_function = self.slower_cubic_draw

Expand Down
Loading