Example #1
0
    def __init__(self, parentEntity):
        super(Cube, self).__init__()

        # build the cube
        side = 15
        self.cubeEntity = Qt3DCore.QEntity(parentEntity)

        # init params of the 6 planes
        planeTranslations = [[0, -side / 2, 0], [0, +side / 2, 0],
                             [-side / 2, 0, 0], [+side / 2, 0, 0],
                             [0, 0, -side / 2], [0, 0, +side / 2]]
        planeRotations = [[0, 0, 180], [0, 0, 0], [0, 0, 90], [0, 0, 270],
                          [270, 0, 0], [90, 0, 0]]

        # allocate planes
        self.planeEntities = [None for i in range(6)]
        self.planeMeshes = [None for i in range(6)]
        self.planeTransforms = [None for i in range(6)]
        self.materials = [None for i in range(6)]

        # build the planes
        for i in range(0, 6):
            self.planeMeshes[i] = Qt3DExtras.QPlaneMesh()
            self.planeMeshes[i].setWidth(side)
            self.planeMeshes[i].setHeight(side)

            self.planeTransforms[i] = Qt3DCore.QTransform()
            self.planeTransforms[i].setRotationX(planeRotations[i][0])
            self.planeTransforms[i].setRotationY(planeRotations[i][1])
            self.planeTransforms[i].setRotationZ(planeRotations[i][2])
            self.planeTransforms[i].setTranslation(
                QVector3D(planeTranslations[i][0], planeTranslations[i][1],
                          planeTranslations[i][2]))

            self.materials[i] = Qt3DExtras.QPhongMaterial(self.cubeEntity)
            self.materials[i].setAmbient(
                QColor(random.randint(0, 255), random.randint(0, 255),
                       random.randint(0, 255)))

            self.planeEntities[i] = Qt3DCore.QEntity(self.cubeEntity)
            self.planeEntities[i].addComponent(self.planeMeshes[i])
            self.planeEntities[i].addComponent(self.planeTransforms[i])
            self.planeEntities[i].addComponent(self.materials[i])

        #initial rotation
        self.yaw = -15
        self.pitch = 15
        self.yawSpeed = 0
        self.pitchSpeed = 0
        self.cubeTransform = Qt3DCore.QTransform()
        self.cubeEntity.addComponent(self.cubeTransform)
        self.rotate(
            0, 0
        )  #trigger the computation of the rotation matrix for the initial rotation
Example #2
0
    def showAll(self):

        self.rootEntity = Qt3DCore.QEntity()
        self.materialSquare = Qt3DExtras.QPhongMaterial(self.rootEntity)
        self.materialSphere = Qt3DExtras.QPhongMaterial(self.rootEntity)
        # self.material = Qt3DExtras.QPhongMaterial(self.rootEntity)
        with open('local2.csv', 'r') as file:
            reader = csv.reader(file)
            for row in reader:
                if row[0] == 's':

                    self.sphereEntity = Qt3DCore.QEntity(self.rootEntity)
                    self.sphereMesh = Qt3DExtras.QSphereMesh()
                    self.name = row[1]
                    self.materialSphere.setAmbient(
                        QColor(int(row[2]), int(row[3]), int(row[4]),
                               int(row[5])))
                    self.sphereMesh.setRadius(int(row[6]))
                    self.QTransformSphere = Qt3DCore.QTransform()
                    self.sphereEntity.addComponent(self.sphereMesh)
                    self.sphereEntity.addComponent(self.materialSphere)
                    self.sphereEntity.addComponent(self.QTransformSphere)
                    sphereVector3D = QVector3D()
                    sphereVector3D.setX(int(row[7]))
                    sphereVector3D.setY(int(row[8]))
                    sphereVector3D.setZ(int(row[9]))
                    self.QTransformSphere.setTranslation(sphereVector3D)

                else:

                    self.squareEntity = Qt3DCore.QEntity(self.rootEntity)
                    self.squareMesh = Qt3DExtras.QCuboidMesh()
                    self.name = row[1]
                    self.materialSquare.setAmbient(
                        QColor(int(row[2]), int(row[3]), int(row[4]),
                               int(row[5])))
                    self.squareMesh.setXExtent(int(row[6]))
                    self.squareMesh.setYExtent(int(row[7]))
                    self.squareMesh.setZExtent(int(row[8]))
                    self.QTransformSquare = Qt3DCore.QTransform()
                    self.squareEntity.addComponent(self.squareMesh)
                    self.squareEntity.addComponent(self.materialSquare)
                    self.squareEntity.addComponent(self.QTransformSquare)

                    squareVector3D = QVector3D()
                    squareVector3D.setX(int(row[9]))
                    squareVector3D.setY(int(row[10]))
                    squareVector3D.setZ(int(row[11]))
                    self.QTransformSquare.setTranslation(squareVector3D)
                    self.QTransformSquare.setRotationX(int(row[12]))
                    self.QTransformSquare.setRotationY(int(row[13]))
                    self.QTransformSquare.setRotationZ(int(row[14]))
Example #3
0
    def __init__(self, root_entity, main_camera):
        """
        A class that houses the Qt3D items (entities, transformations, etc) related to the gnomon (or axis indicator).
        The gnomon/axis indicator is an object that appears in the bottom right-hand corner of the instrument view that
        shows the direction of the x, y, and z axes.
        :param root_entity: The root entity for the gnomon.
        :param main_camera: The main component view camera.
        """

        self.gnomon_root_entity = root_entity
        self.gnomon_cylinder_length = 4
        self.main_camera = main_camera
        self.gnomon_camera = self.create_gnomon_camera(main_camera)

        self.x_text_transformation = Qt3DCore.QTransform()
        self.y_text_transformation = Qt3DCore.QTransform()
        self.z_text_transformation = Qt3DCore.QTransform()

        # Set the text translation value to be the length of the cylinder plus some extra space so that it doesn't
        # overlap with the cylinder or the cones.
        text_translation = self.gnomon_cylinder_length * 1.3

        # The text translation value calculated above is used in addition to some "extra" values in order to make the
        # text placement look good and appear centered next to the cone point. This extra values were found via trial
        # and error and will likely have to be figured out again if you decide to change the font/size/height/etc of
        # the text.
        self.x_text_vector = QVector3D(text_translation, -0.5, 0)
        self.y_text_vector = QVector3D(-0.4, text_translation, 0)
        self.z_text_vector = QVector3D(-0.5, -0.5, text_translation)

        diffuse_color = QColor("grey")

        self.x_material = create_material(AxisColors.X.value,
                                          diffuse_color,
                                          root_entity,
                                          remove_shininess=True)
        self.y_material = create_material(AxisColors.Y.value,
                                          diffuse_color,
                                          root_entity,
                                          remove_shininess=True)
        self.z_material = create_material(AxisColors.Z.value,
                                          diffuse_color,
                                          root_entity,
                                          remove_shininess=True)

        self.num_neutrons = 9

        self.neutron_animation_length = self.gnomon_cylinder_length * 1.5
Example #4
0
    def setup_neutrons(self):
        """
        Sets up the neutrons and their animations by preparing their meshes and then giving offset and
        distance parameters to an animation controller.
        """

        # Create lists of x, y, and time offsets for the neutron animations
        x_offsets = [0, 0, 0, 2, -2, 1.4, 1.4, -1.4, -1.4]
        y_offsets = [0, 2, -2, 0, 0, 1.4, -1.4, 1.4, -1.4]
        time_span_offsets = [0, -5, -7, 5, 7, 19, -19, 23, -23]

        neutron_radius = 1.5

        for i in range(self.num_neutrons):
            mesh = Qt3DExtras.QSphereMesh(self.gnomon_root_entity)
            self.set_sphere_mesh_radius(mesh, neutron_radius)

            transform = Qt3DCore.QTransform(self.gnomon_root_entity)
            neutron_animation_controller = NeutronAnimationController(
                x_offsets[i] * 0.5, y_offsets[i] * 0.5, transform)
            neutron_animation_controller.set_target(transform)

            neutron_animation = QPropertyAnimation(transform)
            self.set_neutron_animation_properties(
                neutron_animation,
                neutron_animation_controller,
                self.neutron_animation_length,
                time_span_offsets[i],
            )

            neutron_material = create_material(QColor("black"), QColor("grey"),
                                               self.gnomon_root_entity)

            create_qentity([mesh, neutron_material, transform],
                           self.gnomon_root_entity)
Example #5
0
 def add_transformation(self, transformation: Qt3DCore.QComponent):
     matrix = transformation.matrix()
     for index, entity in enumerate(self.entities):
         if index:
             transformation = Qt3DCore.QTransform(self.root_entity)
         self._redo_transformation(matrix, transformation, entity[1])
         entity[0].addComponent(transformation)
Example #6
0
    def createScene(self):
        # Root entity
        self.rootEntity = Qt3DCore.QEntity()

        # Material
        self.material = Qt3DExtras.QPhongMaterial(self.rootEntity)

        # Torus
        self.torusEntity = Qt3DCore.QEntity(self.rootEntity)
        self.torusMesh = Qt3DExtras.QTorusMesh()
        self.torusMesh.setRadius(5)
        self.torusMesh.setMinorRadius(1)
        self.torusMesh.setRings(100)
        self.torusMesh.setSlices(20)

        self.torusTransform = Qt3DCore.QTransform()
        self.torusTransform.setScale3D(QVector3D(1.5, 1, 0.5))
        self.torusTransform.setRotation(
            QQuaternion.fromAxisAndAngle(QVector3D(1, 0, 0), 45))

        self.torusEntity.addComponent(self.torusMesh)
        self.torusEntity.addComponent(self.torusTransform)
        self.torusEntity.addComponent(self.material)

        # Sphere
        self.sphereEntity = Qt3DCore.QEntity(self.rootEntity)
        self.sphereMesh = Qt3DExtras.QSphereMesh()
        self.sphereMesh.setRadius(3)

        self.sphereTransform = Qt3DCore.QTransform()
        self.controller = OrbitTransformController(self.sphereTransform)
        self.controller.setTarget(self.sphereTransform)
        self.controller.setRadius(20)

        self.sphereRotateTransformAnimation = QPropertyAnimation(
            self.sphereTransform)
        self.sphereRotateTransformAnimation.setTargetObject(self.controller)
        self.sphereRotateTransformAnimation.setPropertyName("angle")
        self.sphereRotateTransformAnimation.setStartValue(0)
        self.sphereRotateTransformAnimation.setEndValue(360)
        self.sphereRotateTransformAnimation.setDuration(10000)
        self.sphereRotateTransformAnimation.setLoopCount(-1)
        self.sphereRotateTransformAnimation.start()

        self.sphereEntity.addComponent(self.sphereMesh)
        self.sphereEntity.addComponent(self.sphereTransform)
        self.sphereEntity.addComponent(self.material)
Example #7
0
    def __init__(self, view: Qt3DExtras.Qt3DWindow) -> None:
        """
        Initialize a new instance.
        Args:
            view: where to render the planetary sphere.
        """
        self.root_entity = Qt3DCore.QEntity()

        ce = self.camera_entity = view.camera()
        ce.lens().setPerspectiveProjection(45.0, 1.0, 0.1, 1000.0)
        ce.setPosition(V3(0, 8, 8))
        ce.setUpVector(V3(0, 1, 0))
        ce.setViewCenter(V3(0, 0, 0))

        self.light = Qt3DCore.QEntity(self.root_entity)
        self.point_light = Qt3DRender.QPointLight(self.light)
        self.point_light.setColor("white")
        self.point_light.setIntensity(1.0)
        self.light.addComponent(self.point_light)
        # Move the light to the camera's position - on-camera 'flash'!
        t = self.light_transform = Qt3DCore.QTransform(self.light)
        t.setTranslation(ce.position())
        self.light.addComponent(t)

        self.mesh = Qt3DExtras.QSphereMesh()
        self.mesh.setRings(30)
        self.mesh.setSlices(30)
        self.mesh.setRadius(2)

        t = self.transform = Qt3DCore.QTransform()
        t.setScale(1.3)
        t.setTranslation(V3(0.0, 0.0, 0.0))

        m = self.material = Qt3DExtras.QDiffuseSpecularMaterial()
        m.setAmbient(QColor(200, 200, 255))
        m.setShininess(20.0)

        self.entity = Qt3DCore.QEntity(self.root_entity)
        self.entity.addComponent(self.mesh)
        self.entity.addComponent(self.material)
        self.entity.addComponent(self.transform)

        view.setRootEntity(self.root_entity)
        self.entity.setEnabled(True)
 def transform(self) -> Qt3DCore.QTransform:
     """
     Get a QTransform describing the position and orientation of the component
     """
     transform_matrix = QMatrix4x4()
     for transform in self.transforms_full_chain:
         transform_matrix *= transform.qmatrix
     transformation = Qt3DCore.QTransform()
     transformation.setMatrix(transform_matrix)
     return transformation
    def add_acq_sphere(self, df, label):
        pos = df.loc[label, ["x", "y", "z"]].values*1000  # m to mm
        if label not in self.acq_coordinate_entities:
            self.acq_coordinate_meshes[label] = Qt3DExtras.QSphereMesh(rings=20, slices=20, radius=3)
            self.acq_coordinate_entities[label] = Qt3DCore.QEntity(self.root_entity)
            self.acq_coordinate_transforms[label] = Qt3DCore.QTransform(self.acq_coordinate_meshes[label])

            self.acq_coordinate_entities[label].addComponent(self.acq_coordinate_meshes[label])
            self.acq_coordinate_entities[label].addComponent(self.acq_coordinate_transforms[label])
            self.acq_coordinate_entities[label].addComponent(self.acq_material)

        self.acq_coordinate_transforms[label].setTranslation(QtGui.QVector3D(*pos))
Example #10
0
    def _create_source(self):
        cylinder_mesh = Qt3DExtras.QCylinderMesh(self.root_entity)
        cone_transform = Qt3DCore.QTransform(self.root_entity)
        self._set_cylinder_dimension(cylinder_mesh, self._source_radius,
                                     self._source_length)
        cone_transform.setMatrix(self._get_cylinder_transformation_matrix())

        self.entities.append((
            create_qentity(
                [cylinder_mesh, self.default_material, cone_transform],
                self.root_entity,
            ),
            self._get_cylinder_transformation_matrix(),
        ))
Example #11
0
 def qmatrix(self) -> QMatrix4x4:
     """
     Get a Qt3DCore.QTransform describing the transformation
     """
     transform = Qt3DCore.QTransform()
     if self.type == TransformationType.ROTATION:
         quaternion = transform.fromAxisAndAngle(self.vector, self.ui_value)
         transform.setRotation(quaternion)
     elif self.type == TransformationType.TRANSLATION:
         transform.setTranslation(self.vector.normalized() * self.ui_value)
     else:
         raise (RuntimeError('Unknown transformation of type "{}".'.format(
             self.type)))
     return transform.matrix()
Example #12
0
    def createScene(self):
        # Root entity
        self.rootEntity = Qt3DCore.QEntity()

        # Material
        self.material = Qt3DExtras.QPhongMaterial(self.rootEntity)

        # Torus
        self.torusEntity = Qt3DCore.QEntity(self.rootEntity)
        self.torusMesh = Qt3DExtras.QTorusMesh()
        self.torusMesh.setRadius(5)
        self.torusMesh.setMinorRadius(1)
        self.torusMesh.setRings(100)
        self.torusMesh.setSlices(20)

        self.torusTransform = Qt3DCore.QTransform()
        self.torusTransform.setScale3D(QVector3D(1.5, 1, 0.5))
        self.torusTransform.setRotation(
            QQuaternion.fromAxisAndAngle(QVector3D(1, 0, 0), 45))

        self.torusEntity.addComponent(self.torusMesh)
        self.torusEntity.addComponent(self.torusTransform)
        self.torusEntity.addComponent(self.material)

        # Sphere
        self.sphereEntity = Qt3DCore.QEntity(self.rootEntity)
        self.sphereMesh = Qt3DExtras.QSphereMesh()
        self.sphereMesh.setRadius(3)

        self.sphereTransform = Qt3DCore.QTransform()
        self.controller = OrbitTransformController(self.sphereTransform)
        self.controller.setTarget(self.sphereTransform)
        self.controller.setRadius(20)

        self.sphereEntity.addComponent(self.sphereMesh)
        self.sphereEntity.addComponent(self.sphereTransform)
        self.sphereEntity.addComponent(self.material)
Example #13
0
    def qtransform(self) -> QTransform:
        """
        Creates a QTransform based on the full chain of transforms this component points to.
        Where T_1 depends on T_2 which depends on T_3:
        the final transformation T_f = T_3*T_2*T_1

        :return: QTransform of final transformation
        """
        transform_matrix = QMatrix4x4()  # Identity matrix
        for transform in self.transforms_full_chain:
            # Left multiply each new matrix
            transform_matrix = transform.qmatrix * transform_matrix
        transformation = Qt3DCore.QTransform()
        transformation.setMatrix(transform_matrix)
        return transformation
Example #14
0
 def setup_beam_cylinder(self):
     """
     Sets up the beam cylinder by giving the cylinder entity a mesh, a material, and a transformation.
     """
     # Initialise beam objects
     cylinder_mesh = Qt3DExtras.QCylinderMesh(self.gnomon_root_entity)
     cylinder_transform = Qt3DCore.QTransform(self.gnomon_root_entity)
     self.set_cylinder_mesh_dimensions(cylinder_mesh, 1.5,
                                       self.neutron_animation_length, 2)
     self.set_beam_transform(cylinder_transform,
                             self.neutron_animation_length)
     beam_material = create_material(QColor("blue"),
                                     QColor("lightblue"),
                                     self.gnomon_root_entity,
                                     alpha=0.5)
     create_qentity([cylinder_mesh, beam_material, cylinder_transform],
                    self.gnomon_root_entity)
Example #15
0
class ScannerWindow(Qt3DExtras.Qt3DWindow):
    qw = 0.5
    qx = 0.5
    qy = -0.5
    qz = 0.5
    scannerTransform = Qt3DCore.QTransform()

    def __init__(self):
        super(ScannerWindow, self).__init__()

        # camera
        self.camera().lens().setPerspectiveProjection(50, 16 / 9, 0.1, 1000)
        self.camera().setPosition(QVector3D(0, 0, 30))
        self.camera().setViewCenter(QVector3D(0, 0, 0))

        # create scene from obj file
        self.createScene()
        self.setRootEntity(self.rootEntity)

    def updateAngle(self, qw, qx, qy, qz):
        self.qw = qw
        self.qx = qx
        self.qy = qy
        self.qz = qz
        self.addTransform()

    def addTransform(self):
        # correct orientation
        self.scannerTransform.setScale3D(QVector3D(100, 100, 100))
        self.orientation = QQuaternion(self.qw, self.qx, self.qy, self.qz)
        self.axisCorrection = QQuaternion.fromEulerAngles(0, 180, 90)
        self.modelCorrection = QQuaternion.fromEulerAngles(-90, 0, 90)
        self.modelRotation = self.orientation * self.axisCorrection
        self.correctedOrientation = self.modelCorrection * self.modelRotation
        self.scannerTransform.setRotation(self.correctedOrientation)
        self.scannerEntity.addComponent(self.scannerTransform)

    def createScene(self):
        self.rootEntity = Qt3DCore.QEntity()
        self.scannerEntity = Qt3DCore.QEntity(self.rootEntity)
        # QSceneLoader loads materials from scanner.mtl referenced in scanner.obj
        self.scanner = Qt3DRender.QSceneLoader(self.scannerEntity)
        self.scanner.setSource(QUrl.fromLocalFile("scanner.obj"))
        self.scannerEntity.addComponent(self.scanner)
        self.addTransform()
Example #16
0
    def importerLoaded(self, status):
        if status != Kuesa.GLTF2Importer.Status.Ready:
            return

        # First let's take the components that we are going to use to create our clones
        parent = self.rootEntity.entity("KuesaEntity_0")

        parent.setObjectName("KuesaEntity_0")
        orig_entity = self.rootEntity.entity("KuesaEntity_2").childNodes()[1]
        orig_geometry = orig_entity.childNodes()[0]
        orig_material = orig_entity.childNodes()[1]

        row = 10
        col = 10
        distance = 200
        r = 500
        # Then create clones by giving them a custom transform, and the same components than before
        for i in range(0, col):
            for j in range(0, row):
                new_entity = Qt3DCore.QEntity(parent)

                # Note : there is an inconsistency in the Python bindings -
                # In C++ it is not necessary to assign a parent to the transform.
                new_transform = Qt3DCore.QTransform(new_entity)

                new_material = self.cloneMaterial(orig_material, new_entity)
                new_material.setEffect(orig_material.effect())
                new_props = new_material.metallicRoughnessProperties()

                new_props.setMetallicFactor(i / col)
                new_props.setRoughnessFactor(j / row)

                dt = QVector3D(i * distance, j * distance, 0)
                new_transform.setTranslation(dt)

                # Add the custom transform to the entity
                new_entity.addComponent(new_transform)

                # Add the material we created
                new_entity.addComponent(new_material)

                # These two components will be shared across all the ducks.
                new_entity.addComponent(orig_geometry)
Example #17
0
    def _setup_neutrons(self):
        neutron_radius = 0.1
        for i in range(self._num_neutrons):
            mesh = Qt3DExtras.QSphereMesh(self.root_entity)
            mesh.setRadius(neutron_radius)

            transform = Qt3DCore.QTransform(self.root_entity)
            transform.setMatrix(
                self._get_sphere_transformation_matrix(
                    self._neutron_offsets[i]))
            neutron_material = create_material(QColor("black"), QColor("grey"),
                                               self.root_entity)
            entity = create_qentity([mesh, neutron_material, transform],
                                    self.root_entity)
            self.entities.append((
                entity,
                self._get_sphere_transformation_matrix(
                    self._neutron_offsets[i]),
            ))
Example #18
0
    def create_gnomon_cones(self):
        """
        Prepares the gnomon cones by configuring the meshes and then placing them at the ends of the cylinders.
        """
        x_cone_matrix, y_cone_matrix, z_cone_matrix = self.create_cone_matrices(
            self.gnomon_cylinder_length)

        for matrix, material in [
            (x_cone_matrix, self.x_material),
            (y_cone_matrix, self.y_material),
            (z_cone_matrix, self.z_material),
        ]:
            cone_mesh = Qt3DExtras.QConeMesh(self.gnomon_root_entity)

            self.configure_gnomon_cone(cone_mesh, self.gnomon_cylinder_length)

            cone_transformation = Qt3DCore.QTransform(self.gnomon_root_entity)
            cone_transformation.setMatrix(matrix)

            create_qentity([cone_mesh, cone_transformation, material],
                           self.gnomon_root_entity)
Example #19
0
    def create_gnomon_cylinders(self):
        """
        Configures three cylinder meshes and translates them in order to create a basic gnomon shape.
        """
        x_axis_matrix, y_axis_matrix, z_axis_matrix = self.create_cylinder_matrices(
            self.gnomon_cylinder_length)
        for matrix, material in [
            (x_axis_matrix, self.x_material),
            (y_axis_matrix, self.y_material),
            (z_axis_matrix, self.z_material),
        ]:
            axis_mesh = Qt3DExtras.QCylinderMesh(self.gnomon_root_entity)

            self.configure_gnomon_cylinder(axis_mesh,
                                           self.gnomon_cylinder_length)

            axis_transformation = Qt3DCore.QTransform(self.gnomon_root_entity)
            axis_transformation.setMatrix(matrix)

            create_qentity([axis_mesh, axis_transformation, material],
                           self.gnomon_root_entity)
Example #20
0
    def add_sphere(self, radius, x, y, z, rings=10, slices=10):

        sphereEntity = Qt3DCore.QEntity(self.rootEntity)

        # Mesh
        sphereMesh = Qt3DExtras.QSphereMesh()
        sphereMesh.setRadius(radius)
        sphereMesh.setRings(rings)
        sphereMesh.setSlices(slices)

        # Transforms
        sphereTransform = Qt3DCore.QTransform()
        sphereTransform.setTranslation(QVector3D(x, y, z))

        sphereEntity.addComponent(sphereMesh)
        sphereEntity.addComponent(self.material)
        sphereEntity.addComponent(sphereTransform)

        self.spheres.append(sphereEntity)
        self.meshes.append(sphereMesh)
        self.transforms.append(sphereTransform)
 def qmatrix(self) -> QMatrix4x4:
     """
     Get a Qt3DCore.QTransform describing the transformation
     for use in the 3D view
     """
     transform = Qt3DCore.QTransform()
     transform.matrix()
     if self.transform_type == TransformationType.ROTATION:
         quaternion = transform.fromAxisAndAngle(
             self.vector, self.ui_value * self._ui_scale_factor
         )
         transform.setRotation(quaternion)
     elif self.transform_type == TransformationType.TRANSLATION:
         transform.setTranslation(
             self.vector.normalized() * self.ui_value * self._ui_scale_factor
         )
     else:
         raise (
             RuntimeError(f'Unknown transformation of type "{self.transform_type}".')
         )
     return transform.matrix()
Example #22
0
    def importerLoaded(self, status):
        if status != Kuesa.GLTF2Importer.Status.Ready:
            return

        # First let's take the components that we are going to use to create our clones
        parent = self.rootEntity.entity("KuesaEntity_0")

        parent.setObjectName("KuesaEntity_0")
        orig_entity = self.rootEntity.entity("KuesaEntity_2").childNodes()[1]
        orig_geometry = orig_entity.childNodes()[0]
        orig_material = orig_entity.childNodes()[1]

        self.ducks = 1000
        r = 500
        # Then create clones by giving them a custom transform, and the same components than before
        for i in range(0, self.ducks):
            new_entity = Qt3DCore.QEntity(parent)

            # Note : there is an inconsistency in the Python bindings -
            # In C++ it is not necessary to assign a parent to the transform.
            new_transform = Qt3DCore.QTransform(new_entity)

            new_transform.setScale(0.2)

            dt = QVector3D(random.randint(-r, r), random.randint(-r, r),
                           random.randint(-r, r))
            new_transform.setTranslation(dt)

            new_transform.setRotationX(random.randint(0, 360))
            new_transform.setRotationY(random.randint(0, 360))
            new_transform.setRotationZ(random.randint(0, 360))

            # Add the custom transform, plus the original components, to the entity
            new_entity.addComponent(new_transform)

            # These two components will be shared across all the ducks.
            new_entity.addComponent(orig_geometry)
            new_entity.addComponent(orig_material)
Example #23
0
    def __init__(self, args, parent=None):
        super().__init__(parent)
        ##############################################################################
        # UI初期化処理
        self.ui = MainWindowUi.loader(os.path.join(os.getcwd(), 'ui/main.ui'))
        self.setWindowTitle('self.viewer test')
        self.setCentralWidget(self.ui.widgets)

        self.view = Qt3DExtras.Qt3DWindow()
        self.view.defaultFrameGraph().setClearColor(QtGui.QColor(0, 0, 0))
        self.container = QWidget.createWindowContainer(self.view)

        screen_size = self.view.screen().size()
        self.ui.viewer.addWidget(self.container)
        self.container.setMinimumSize(QtCore.QSize(400, 600))
        self.container.setMaximumSize(screen_size)

        # QSize screenSize = self.view -> screen() -> size();
        # container -> setMinimumSize(QSize(200, 100));
        # container -> setMaximumSize(screenSize);

        # vLayout -> setAlignment(Qt: : AlignTop);
        # hLayout -> addWidget(container, 1);
        # hLayout -> addLayout(vLayout);

        # input_aspect = Qt3DInput.QInputAspect()
        # self.view.registerAspect(input_aspect)

        # root entity
        self.root_entity: Qt3DCore.QEntity = Qt3DCore.QEntity()

        # draw grid and axis
        """
        self.x_axis: Qt3DRender.QGeometry = Qt3DRender.QGeometry(self.root_entity)
        x_axis_pos: QtCore.QByteArray = QtCore.QByteArray()
        x_axis_pos.append(0)
        x_axis_pos.append(0)
        x_axis_pos.append(0)
        x_axis_pos.append(10)
        x_axis_pos.append(0)
        x_axis_pos.append(0)
        x_axis_buf: Qt3DRender.QBuffer = Qt3DRender.QBuffer(self.x_axis)
        x_axis_buf.setData(x_axis_pos)

        x_axis_attr: Qt3DRender.QAttribute = Qt3DRender.QAttribute(self.x_axis)
        x_axis_attr.setVertexBaseType(Qt3DRender.QAttribute.Float)
        x_axis_attr.setVertexSize(3)
        x_axis_attr.setAttributeType(Qt3DRender.QAttribute.VertexAttribute)
        x_axis_attr.setBuffer(x_axis_buf)
        x_axis_attr.setByteStride(3)
        x_axis_attr.setCount(2)
        self.x_axis.addAttribute(x_axis_attr)
        """

        test_mtl = Qt3DExtras.QTextureMaterial(self.root_entity)

        self.test = Qt3DCore.QEntity(self.root_entity)
        self.test_mesh: Qt3DExtras.QTorusMesh = Qt3DExtras.QTorusMesh()
        self.test_mesh.setRadius(5)
        self.test_mesh.setMinorRadius(1)
        self.test_mesh.setRings(100)
        self.test_mesh.setSlices(20)
        self.test_tr = Qt3DCore.QTransform()
        self.test_tr.setTranslation(QtGui.QVector3D(0, 0, 0))
        # test_tr.setScale3D()
        self.test.addComponent(self.test_mesh)
        self.test.addComponent(self.test_tr)
        self.test.addComponent(self.test_mtl)

        # camera entity
        camera_entity: Qt3DRender.QCamera = self.view.camera()

        camera_entity.lens().setPerspectiveProjection(45.0, 16.0 / 9.0, 0.1, 1000.0)
        camera_entity.setPosition(QtGui.QVector3D(0, 0, 20.0))
        camera_entity.setUpVector(QtGui.QVector3D(0, 1, 0))
        camera_entity.setViewCenter(QtGui.QVector3D(0, 0, 0))

        light_entity = Qt3DCore.QEntity(self.root_entity)
        light = Qt3DRender.QPointLight(light_entity)
        light.setColor("white")
        light.setIntensity(1)
        light_entity.addComponent(light)

        light_transform = Qt3DCore.QTransform(light_entity)
        light_transform.setTranslation(camera_entity.position())
        light_entity.addComponent(light_transform)

        # for camera controls
        cam_controller = Qt3DExtras.QFirstPersonCameraController(self.root_entity)
        cam_controller.setCamera(camera_entity)

        # set root object of the scene
        self.view.setRootEntity(self.root_entity)
Example #24
0
    def __init__(self, parent=None):
        super().__init__(parent)
        self.rnd_lat = random.randrange(5200,5300)  / 100.0
        self.rnd_hdg = random.randrange(-300,300)  / 100.0
        self.rnd_dec = random.randrange(-50,50) / 10.0

        print(self.rnd_lat, self.rnd_hdg, self.rnd_dec)

        self.view = Qt3DExtras.Qt3DWindow()
        self.view.defaultFrameGraph().setClearColor(QtGui.QColor("#4d4d4f"))
        self.container = QtWidgets.QWidget.createWindowContainer(self.view)
        self.vLayout = QtWidgets.QVBoxLayout(self)
        self.vLayout.addWidget(self.container, 1)

        self.input_aspect = Qt3DInput.QInputAspect()
        self.view.registerAspect(self.input_aspect)

        self.rootEntity = Qt3DCore.QEntity()
        self.view.setRootEntity(self.rootEntity)

        ###

        cameraEntity = self.view.camera()
        cameraEntity.lens().setPerspectiveProjection(5.0, 16.0 / 9.0, 10, 100000.0)
        cameraEntity.setPosition(QtGui.QVector3D(0, 1000, 50000))
        cameraEntity.setUpVector(QtGui.QVector3D(0, 1, 0))
        cameraEntity.setViewCenter(QtGui.QVector3D(0, 1000, 0))

        self.camController = Qt3DExtras.QOrbitCameraController(self.rootEntity)
        self.camController.setCamera(cameraEntity)

        ###

        self.lightEntity = Qt3DCore.QEntity(self.rootEntity)
        self.light = Qt3DRender.QPointLight(self.lightEntity)
        self.light.setColor("white")
        self.light.setIntensity(1)

        self.lightTransform = Qt3DCore.QTransform(self.lightEntity)
        self.lightTransform.setTranslation(cameraEntity.position())

        self.lightEntity.addComponent(self.light)
        self.lightEntity.addComponent(self.lightTransform)

        ### sky
        # self.skyMesh = Qt3DExtras.QSphereMesh(radius=5000, rings=94, slices=48)
        # self.skyMaterial = Qt3DExtras.QPhongMaterial(diffuse=QtGui.QColor("#ff0000"))

        # self.skyEntity = Qt3DCore.QEntity(self.rootEntity)
        # self.skyEntity.addComponent(self.skyMesh)
        # self.skyEntity.addComponent(self.skyMaterial)

        ### hdg, x right, y up

        # Cylinder cog = (0,0,0) long direction = y
        self.hdgMesh = Qt3DExtras.QCylinderMesh(length=1200.0, radius=100.0, rings=100, slices=20)
        rotation = QtGui.QQuaternion.fromAxisAndAngle(QtGui.QVector3D(0.0, 0.0, 1.0), 15.0)
        translation = QtGui.QVector3D(0.0, 600.0, 0.0)
        self.hdgTransform = Qt3DCore.QTransform(translation=translation, rotation=rotation)
        self.hdgMaterial = Qt3DExtras.QPhongMaterial(diffuse=QtGui.QColor("#ff0000"))
        self.hdgEntity = Qt3DCore.QEntity(self.rootEntity)
        self.hdgEntity.addComponent(self.hdgMesh)
        self.hdgEntity.addComponent(self.hdgMaterial)
        self.hdgEntity.addComponent(self.hdgTransform)

        ### lat x up, y left
        self.latMesh = Qt3DExtras.QCylinderMesh(length=200.0, radius=100.0, rings=100, slices=20)
        rotation = QtGui.QQuaternion.fromAxisAndAngle(QtGui.QVector3D(0.0, 0.0, 1.0), 90.0)
        translation = QtGui.QVector3D(0.0, 700.0, 0.0)
        self.latTransform = Qt3DCore.QTransform(rotation=rotation, translation=translation)
        self.latMaterial = Qt3DExtras.QPhongMaterial(diffuse=QtGui.QColor("#00ff00"))
        self.latEntity = Qt3DCore.QEntity(self.hdgEntity)
        self.latEntity.addComponent(self.latMesh)
        self.latEntity.addComponent(self.latMaterial)
        self.latEntity.addComponent(self.latTransform)

        ### ra x up, y left

        self.raMesh = Qt3DExtras.QCylinderMesh(length=500.0, radius=100.0, rings=100, slices=20)
        rotation1 = QtGui.QQuaternion.fromAxisAndAngle(QtGui.QVector3D(0.0, 0.0, -1.0), 90)
        rotation2 = QtGui.QQuaternion.fromAxisAndAngle(QtGui.QVector3D(-1.0, 0.0, 0.0), 90)
        rotation = rotation1 * rotation2
        translation = QtGui.QVector3D(200.0, 0.0, 0.0)
        self.raTransform = Qt3DCore.QTransform(rotation=rotation, translation=translation)
        self.raMaterial = Qt3DExtras.QPhongMaterial(diffuse=QtGui.QColor("#beb32b"))
        self.raEntity = Qt3DCore.QEntity(self.latEntity)
        self.raEntity.addComponent(self.raMesh)
        self.raEntity.addComponent(self.raMaterial)
        self.raEntity.addComponent(self.raTransform)

        ### dec

        self.decMesh = Qt3DExtras.QCylinderMesh(length=500.0, radius=100.0, rings=100, slices=20)
        rotation = QtGui.QQuaternion.fromAxisAndAngle(QtGui.QVector3D(1.0, 0.0, 0.0), 90.0)
        translation = QtGui.QVector3D(0.0, 350.0, 0.0)
        self.decTransform = Qt3DCore.QTransform(rotation=rotation, translation=translation)
        self.decMaterial = Qt3DExtras.QPhongMaterial(diffuse=QtGui.QColor("#0000ff"))
        self.decEntity = Qt3DCore.QEntity(self.raEntity)
        self.decEntity.addComponent(self.decMesh)
        self.decEntity.addComponent(self.decMaterial)
        self.decEntity.addComponent(self.decTransform)

        ### tube

        self.tubeMesh = Qt3DExtras.QCylinderMesh(length=1200.0, radius=100.0, rings=100, slices=20)

        rotation = QtGui.QQuaternion.fromAxisAndAngle(QtGui.QVector3D(-1.0, 0.0, 0.0), 90.0)
        translation = QtGui.QVector3D(0.0, 350.0, 100.0)
        self.tubeTransform = Qt3DCore.QTransform(rotation=rotation, translation=translation)
        self.tubeMaterial = Qt3DExtras.QPhongMaterial(diffuse=QtGui.QColor("#ffffff"))
        self.tubeEntity = Qt3DCore.QEntity(self.decEntity)
        self.tubeEntity.addComponent(self.tubeMesh)
        self.tubeEntity.addComponent(self.tubeMaterial)
        self.tubeEntity.addComponent(self.tubeTransform)

        self.ocuMesh = Qt3DExtras.QCylinderMesh(length=100.0, radius=50.0, rings=100, slices=20)
        translation = QtGui.QVector3D(0.0, -650.0, 0.0)
        self.ocuTransform = Qt3DCore.QTransform(translation=translation)
        self.ocuMaterial = Qt3DExtras.QPhongMaterial(diffuse=QtGui.QColor("#ffffff"))
        self.ocuEntity = Qt3DCore.QEntity(self.tubeEntity)
        self.ocuEntity.addComponent(self.ocuMesh)
        self.ocuEntity.addComponent(self.ocuMaterial)
        self.ocuEntity.addComponent(self.ocuTransform)

        self.fakeMesh = Qt3DExtras.QCuboidMesh(xExtent=500, yExtent=500, zExtent=500)
        translation = QtGui.QVector3D(-1000.0, 0, 0.0)
        self.fakeTransform = Qt3DCore.QTransform(translation=translation)
        self.fakeMaterial = Qt3DExtras.QPhongMaterial(diffuse=QtGui.QColor("#ffffff"))
        self.fakeEntity = Qt3DCore.QEntity(self.rootEntity)
        self.fakeEntity.addComponent(self.fakeMesh)
        self.fakeEntity.addComponent(self.fakeMaterial)
        self.fakeEntity.addComponent(self.fakeTransform)

        self._heading = 0
        self._latitude = 45
        self._ra = 0
        self._dec = 90
Example #25
0
 def __init__(self):
     super(Transform, self).__init__()
     self._type = ComponentType.Transform
     self._component = Qt3DCore.QTransform()
Example #26
0
    def __init__(self):
        super(Window, self).__init__()

        # Default set-up - by now you know the drill :-)
        self.rootEntity = Kuesa.SceneEntity()
        self.rootEntity.addComponent(DefaultEnvMap(self.rootEntity))

        self.gltfImporter = Kuesa.GLTF2Importer(self.rootEntity)
        self.gltfImporter.setSceneEntity(self.rootEntity)
        self.gltfImporter.setSource(assetsUrl() + "/models/duck/Duck.glb")

        self.camera().setPosition(QVector3D(10, 1.5, 10))
        self.camera().setViewCenter(QVector3D(0, .5, 0))
        self.camera().setUpVector(QVector3D(0, 1, 0))
        self.camera().setAspectRatio(16. / 9.)

        self.camController = Qt3DExtras.QOrbitCameraController(self.rootEntity)
        self.camController.setCamera(self.camera())

        self.fg = Kuesa.ForwardRenderer()
        self.fg.setCamera(self.camera())
        self.fg.setClearColor("white")
        self.setActiveFrameGraph(self.fg)

        envmap_root = assetsUrl() + "/envmaps/pink_sunrise"
        envmap_name = "pink_sunrise" + ("_16f" if platform.system() == "Darwin"
                                        else "") + "_radiance"
        self.skybox = Kuesa.Skybox(self.rootEntity)
        self.skybox.setBaseName(envmap_root + "/" + envmap_name)
        self.skybox.setExtension(".dds")

        # Now we create some lights.
        # All lights have an intensity and a color.
        # Specific light types have relevant additional properties.
        # Point light
        self.pointLightEntity = Qt3DCore.QEntity(self.rootEntity)
        self.pointLightTransform = Qt3DCore.QTransform(self.pointLightEntity)
        self.pointLightTransform.setTranslation(QVector3D(20, -10, -10))

        self.pointLight = Kuesa.PointLight(self.pointLightEntity)
        self.pointLight.setIntensity(1000.0)
        self.pointLight.setColor("red")

        self.pointLightEntity.addComponent(self.pointLightTransform)
        self.pointLightEntity.addComponent(self.pointLight)

        # Spot light
        self.spotLightEntity = Qt3DCore.QEntity(self.rootEntity)
        self.spotLightTransform = Qt3DCore.QTransform(self.spotLightEntity)
        self.spotLightTransform.setTranslation(QVector3D(-10, 10, 10))

        self.spotLight = Kuesa.SpotLight(self.spotLightEntity)
        self.spotLight.setIntensity(1000.0)
        self.spotLight.setColor("green")
        self.spotLight.setInnerConeAngle(50)
        self.spotLight.setOuterConeAngle(100)
        self.spotLight.setRange(1000)

        self.spotLightEntity.addComponent(self.spotLightTransform)
        self.spotLightEntity.addComponent(self.spotLight)

        # Directional light
        self.directionalLightEntity = Qt3DCore.QEntity(self.rootEntity)
        self.directionalLightTransform = Qt3DCore.QTransform(
            self.directionalLightEntity)

        self.directionalLight = Kuesa.DirectionalLight(
            self.directionalLightEntity)
        self.directionalLight.setIntensity(100.0)
        self.directionalLight.setColor("blue")
        self.directionalLight.setDirection(QVector3D(10, 10, -10))

        self.directionalLightEntity.addComponent(
            self.directionalLightTransform)
        self.directionalLightEntity.addComponent(self.directionalLight)

        self.setRootEntity(self.rootEntity)
    def __init__(self, parent, fs_subject="sample"):
        super(MeshDisplayWidget, self).__init__(parent)

        self.config = parent.config
        self.fs_subject = fs_subject

        self.view = Qt3DExtras.Qt3DWindow()
        self.view.defaultFrameGraph().setClearColor(QtGui.QColor("#4d4d4f"))
        self.container = QtWidgets.QWidget.createWindowContainer(self.view, self)
        screen_size = self.view.screen().size()
        self.container.setMinimumSize(QtCore.QSize(600, 100))
        self.container.setMaximumSize(screen_size)

        #h_layout = QtWidgets.QHBoxLayout(self)
        #h_layout.addWidget(self.container)
        self.addWidget(self.container)

        self.tableView = QtWidgets.QTableView(self)
        self.tableView.setObjectName("tableView")

        v_layout = QtWidgets.QVBoxLayout()
        v_layout.addWidget(self.tableView)

        self.overlay_btn = QtWidgets.QPushButton("Update and overlay digitized points")
        self.overlay_btn.clicked.connect(self.update_acquisition_overlay)
        v_layout.addWidget(self.overlay_btn)

        subject_name_layout = QtWidgets.QHBoxLayout()
        subject_name_layout.addWidget(QtWidgets.QLabel("Subject name:"))
        self.subject_name_wgt = QtWidgets.QComboBox()
        subject_name_layout.addWidget(self.subject_name_wgt)
        self.new_subject_wgt = QtWidgets.QPushButton("New subject")
        self.new_subject_wgt.clicked.connect(self.new_subject)
        subject_name_layout.addWidget(self.new_subject_wgt)

        self.mute_sound_wgt = QtWidgets.QCheckBox("Mute sound")
        subject_name_layout.addWidget(self.mute_sound_wgt)

        v_layout.addLayout(subject_name_layout)

        if "subject_dir" not in self.config["DEFAULT"]:
            self.config["DEFAULT"]["subject_dir"] = str(Path(__file__).parent.absolute() / "subjects_data")

        subject_dir_layout = QtWidgets.QHBoxLayout()
        subject_dir_layout.addWidget(QtWidgets.QLabel("Subject dir:"))
        self.subject_dir_wgt = QtWidgets.QLineEdit(self.config["DEFAULT"]["subject_dir"])
        self.subject_dir_wgt.setReadOnly(False)
        subject_dir_layout.addWidget(self.subject_dir_wgt)
        select_subject_dir_btn = QtWidgets.QPushButton("...")
        subject_dir_layout.addWidget(select_subject_dir_btn)
        select_subject_dir_btn.clicked.connect(self.open_subject_dir_dlg)

        v_layout.addLayout(subject_dir_layout)
        self.subject_dir_wgt.textChanged.connect(self.set_subject_dir)

        if not Path(self.config["DEFAULT"]["subject_dir"]).exists():
            msgBox = QtWidgets.QMessageBox()
            msgBox.setIcon(QtWidgets.QMessageBox.Information)
            msgBox.setText(f"The chosen subject directory (i.e. {self.config['DEFAULT']['subject_dir']}) does not "
                           "exist. Do you want to create it or to select a new directory?")
            msgBox.setWindowTitle("Non-existent subject directory")

            button_create = msgBox.addButton("Create it!", QtWidgets.QMessageBox.YesRole);
            msgBox.addButton("Select a different directory", QtWidgets.QMessageBox.NoRole)
            msgBox.exec_()
            if msgBox.clickedButton() == button_create:
                Path(self.config["DEFAULT"]["subject_dir"]).mkdir(exist_ok=True, parents=True)
            else:
                self.open_subject_dir_dlg()

        #h_layout.addLayout(v_layout)
        v_layout_widget = QtWidgets.QWidget(self)
        v_layout_widget.setLayout(v_layout)
        self.addWidget(v_layout_widget)

        self.data = QtCore.QUrl.fromLocalFile(str(Path(__file__).parent.absolute() / f"{self.fs_subject}_head.obj"))

        self.root_entity = Qt3DCore.QEntity()

        self.material = Qt3DExtras.QPhongMaterial()
        self.material.setDiffuse(QtGui.QColor(254, 254, 254))

        self.camera = self.view.camera()
        self.camera.lens().setPerspectiveProjection(400.0, 16.0/9.0, 100, 1200.0)
        self.camera.setPosition(QtGui.QVector3D(0, 500, 0))
        self.camera.setUpVector(QtGui.QVector3D(0, 0, 1))

        self.lightEntities = {}
        self.lights = {}
        self.lightTransforms = {}
        for trans_x in [200, -200]:
            for trans_y in [200, -200]:
                self.lightEntities[(trans_x, trans_y)] = Qt3DCore.QEntity(self.root_entity)
                self.lights[(trans_x, trans_y)] = Qt3DRender.QPointLight(self.lightEntities[(trans_x, trans_y)])
                self.lights[(trans_x, trans_y)].setColor("white")
                self.lights[(trans_x, trans_y)].setIntensity(0.4)
                self.lightEntities[(trans_x, trans_y)].addComponent(self.lights[(trans_x, trans_y)])
        
                self.lightTransforms[(trans_x, trans_y)] = Qt3DCore.QTransform(self.lightEntities[(trans_x, trans_y)])
                self.lightTransforms[(trans_x, trans_y)].setTranslation(QtGui.QVector3D(trans_x, trans_y, 100.0))
                self.lightEntities[(trans_x, trans_y)].addComponent(self.lightTransforms[(trans_x, trans_y)])

        # Get co-registered head, fiducials and electrodes
        data_path = Path(mne.datasets.sample.data_path())
        fs_subjects_dir = data_path / 'subjects'
        trans_fname = data_path / 'MEG' / 'sample' / 'sample_audvis_raw-trans.fif'
        trans = mne.read_trans(trans_fname)

        montage = mne.channels.make_standard_montage('GSN-HydroCel-129')
        info = mne.create_info(montage.ch_names, 100, ch_types='eeg')
        raw = mne.io.RawArray(np.zeros((len(montage.ch_names), 100)), info)
        raw.set_montage(montage)

        eeg, fid, surf = get_aligned_artifacts(raw.info, subject=self.fs_subject, trans=trans,
                                               subjects_dir=fs_subjects_dir, coord_frame='mri')
        self.head_surf = surf

        path_out = Path(str(Path(__file__).parent.absolute() / f"{self.fs_subject}_head.obj"))
        if True: #not path_out.exists():
            mesh = trimesh.Trimesh(surf["rr"] * 1000, surf["tris"])
            open3d_mesh = open3d.geometry.TriangleMesh(vertices=open3d.utility.Vector3dVector(mesh.vertices),
                                                       triangles=open3d.utility.Vector3iVector(mesh.faces))
            mesh = open3d_mesh.simplify_quadric_decimation(int(20000))
            mesh = trimesh.Trimesh(np.asarray(mesh.vertices), np.asarray(mesh.triangles))

            with path_out.open('w') as file_obj:
                file_obj.write(trimesh.exchange.obj.export_obj(mesh))

        # Head
        self.data = QtCore.QUrl.fromLocalFile(str(path_out))

        self.head_entity = Qt3DCore.QEntity(self.root_entity)
        self.head_mesh = Qt3DRender.QMesh()
        self.head_mesh.setMeshName(str(path_out))
        self.head_mesh.setSource(self.data)

        self.head_entity.addComponent(self.head_mesh)
        self.head_entity.addComponent(self.material)

        self.camController = Qt3DExtras.QOrbitCameraController(self.head_mesh)
        self.camController.setCamera(self.camera)
        self.camController.setLinearSpeed(self.camController.linearSpeed()*100)
        self.mesh_center_of_mass = np.median(surf['rr'], 0)*1000
        self.camera.setViewCenter(QtGui.QVector3D(*(self.mesh_center_of_mass)))

        self.camera.viewCenterChanged.connect(self.cam_view_center_changed)

        ## EEG electrodes and Fiducials
        self.electrode_material = Qt3DExtras.QPhongMaterial(diffuse=QtGui.QColor("#665423"))
        self.fid_material = Qt3DExtras.QPhongMaterial(diffuse=QtGui.QColor("#0000FF"))
        self.selected_material = Qt3DExtras.QPhongMaterial(diffuse=QtGui.QColor("#FF0000"))
        self.edited_material = Qt3DExtras.QPhongMaterial(diffuse=QtGui.QColor("#FFFF00"))
        self.acq_material = Qt3DExtras.QPhongMaterial(diffuse=QtGui.QColor("#00FF00"))
        self.selected_item = None

        self.coordinate_meshes = {}
        self.coordinate_entities = {}
        self.coordinate_transforms = {}
        self.coordinate_materials = {}

        for kind, var in zip(["fid", "elec"], [fid, eeg]):
            for label, pos in var.iterrows():
                pos = pos.values*1000
                self.coordinate_meshes[label] = Qt3DExtras.QSphereMesh(rings=20, slices=20, radius=3)
                self.coordinate_entities[label] = Qt3DCore.QEntity(self.root_entity)
                self.coordinate_transforms[label] = Qt3DCore.QTransform(self.coordinate_meshes[label])
                self.coordinate_transforms[label].setTranslation(QtGui.QVector3D(*pos))

                self.coordinate_entities[label].addComponent(self.coordinate_meshes[label])
                self.coordinate_entities[label].addComponent(self.coordinate_transforms[label])

        self.acq_coordinate_meshes = {}
        self.acq_coordinate_entities = {}
        self.acq_coordinate_transforms = {}

        self.df_montage = pd.concat([fid, eeg])
        self.df_montage.columns = ["x", "y", "z"]
        self.df_acq = pd.concat([self.df_montage.copy().rename(columns={"x": f"x{i+1}", "y": f"y{i+1}", "z": f"z{i+1}"})
                                 for i in range(4)], axis=1)
        model = DataFrameModel(self.df_acq)
        self.tableView.setModel(model)
        self.df_acq.loc[:, :] = np.nan

        self.set_table_view_selection(0)
        self.view.setRootEntity(self.root_entity)

        self.subject_name_wgt.currentTextChanged.connect(self.load_subject)
        self.update_subject_lst()