Skip to content

Commit

Permalink
Actors{} are now proper actor trees!
Browse files Browse the repository at this point in the history
Actors now have a "transform" property that premultiplies all children Actor of Actors insances
  • Loading branch information
maxlem committed Mar 27, 2022
1 parent 5efdf5d commit 33e3d39
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 18 deletions.
24 changes: 13 additions & 11 deletions QtQmlViewport/Actors.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from QtQmlViewport.Transforms import Transform
from QtQmlViewport.utils import to_numpy, tf_to_numpy

from PyQt5.QtGui import QVector3D
from PyQt5.QtGui import QMatrix4x4
from PyQt5.QtCore import pyqtProperty as Property, pyqtSignal as Signal, pyqtSlot as Slot, QObject, Q_CLASSINFO
from PyQt5.QtQml import QQmlListProperty

Expand Down Expand Up @@ -92,6 +92,7 @@ def renderables(self):
return QQmlListProperty(Renderable, self, self._renderables)

Product.InputProperty(vars(), QObject, 'instantiator', None)
Product.InputProperty(vars(), Transform, 'transform', None)

@Slot(Renderable, result = Renderable)
def addActor(self, actor):
Expand Down Expand Up @@ -126,7 +127,7 @@ def actor_to_id(self, id_to_actors = None):
id_to_actors = self.get_visible_actors()

actor_to_id_ = {}
for i, a in enumerate(id_to_actors):
for i, (a, _) in enumerate(id_to_actors):
n = a.objectName()
if not n:
n = "anonymous"
Expand All @@ -150,14 +151,15 @@ def merged_bvhs(self):


id_to_actors = self.get_visible_actors()
for i, a in enumerate(id_to_actors):
for i, (a, parentTransform) in enumerate(id_to_actors):
a.geometry.update()
if a.transform:
a.transform.update()
bvh = a.geometry.goc_bvh(True)
bvhs.append(bvh if bvh is None else bvh.bvh)

matrices.append(tf_to_numpy(a.transform) if a.transform else np.eye(4, dtype = 'f4'))
p = tf_to_numpy(a.transform) if parentTransform else np.eye(4, dtype = 'f4')
m = tf_to_numpy(a.transform) if a.transform else np.eye(4, dtype = 'f4')
matrices.append(np.matmul(p, m))

uniforms = {}
for k,v, in a.effect.shader0.uniforms.items():
Expand Down Expand Up @@ -187,8 +189,6 @@ def merged_bvhs(self):

def is_any_visible_actor_dirty(self):

is_dirty = False

def recursive_check(a):
if issubclass(type(a), Actor):
if a.visible:
Expand All @@ -215,15 +215,17 @@ def recursive_check(a):

return False

def get_visible_actors(self):
actors = set()
def get_visible_actors(self, parentTransform = QMatrix4x4()):
actors = []

tf = parentTransform * (self.transform.worldTransform(True) if self.transform else QMatrix4x4())

def add_actor(a):
if issubclass(type(a), Actor):
if a.visible:
actors.add(a)
actors.append((a, tf))
elif issubclass(type(a), Actors):
actors.update(a.get_visible_actors()) #union of sets
actors.extend(a.get_visible_actors(tf)) #union of sets

for r in self._renderables:
add_actor(r)
Expand Down
7 changes: 3 additions & 4 deletions QtQmlViewport/InFboRenderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,10 @@ def synchronize(self, viewport):
if viewport.actors is None :
return

sorted_actors = sorted(list(viewport.actors.get_visible_actors()), key=attrgetter('renderRank'))
sorted_actors = sorted(list(viewport.actors.get_visible_actors()), key=lambda a_tf:a_tf[0].renderRank)
sorted_actors.extend(viewport._debug_actors.get_visible_actors())

for actor in sorted_actors:
for actor, parent_tf in sorted_actors:
if not actor.update() :
if not hasattr(actor, "__error_reported___") or not actor.__error_reported___:
LoggingManager.instance().warning("Not rendering actor " + str(actor) + ". It is has error " + str(actor._error )+ ".")
Expand All @@ -202,7 +202,6 @@ def synchronize(self, viewport):
indices = actor.geometry.indices
attribs = actor.geometry.attribs.get_attributes()


bo_actor = {"attribs": {}
, "textures": {}
, "out_textures": {}
Expand All @@ -211,7 +210,7 @@ def synchronize(self, viewport):
, "program": actor.effect.shader0._program
, "point_size": actor.effect.pointSize
, "line_width": actor.effect.lineWidth
, "transform" : actor.transform.worldTransform() if actor.transform else QMatrix4x4()
, "transform" : parent_tf * (actor.transform.worldTransform() if actor.transform else QMatrix4x4())
, "primitiveType": actor.geometry.primitiveType
, "actor_not_thread_safe": actor}
except Exception as e:
Expand Down
8 changes: 7 additions & 1 deletion QtQmlViewport/Transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,16 @@ def before_write_local_transform(self, matrix4x4):
matrix4x4 = QMatrix4x4()
return matrix4x4

Product.InputProperty(vars(), Product.Product, 'localTransform', QMatrix4x4(), None, before_write_local_transform)
Product.InputProperty(vars(), QMatrix4x4, 'localTransform', QMatrix4x4(), None, before_write_local_transform)

Product.InputProperty(vars(), Product.Product, 'parentTransform', None)

@Slot(result = QMatrix4x4)
def earliestParent(self, update = False):
tf = self.parentTransform
while tf is not None:
tf = tf.parentTransform
return tf

@Slot(result = QMatrix4x4)
def worldTransform(self, update = False):
Expand Down
2 changes: 1 addition & 1 deletion QtQmlViewport/Viewport.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def __init__( self, parent=None ):

Product.RWProperty(vars(), Camera, 'camera', Camera())

Product.RWProperty(vars(), 'QVariant', 'backgroundColor', QColor(qRgba(1,1,1,1)))
Product.RWProperty(vars(), QColor, 'backgroundColor', QColor(qRgba(1,1,1,1)))

Product.RWProperty(vars(), Actors, 'actors', None)

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def build_extension(self, ext):

kwargs = dict(
name='QtQmlViewport',
version='0.2.0',
version='0.2.1',
author='Maxime Lemonnier',
description='Python QtQml 3D viewer toolkit',
long_description='',
Expand Down

0 comments on commit 33e3d39

Please sign in to comment.