def test_GIVEN_geometry_WHEN_creating_off_mesh_THEN_geometry_contains_original_geometry(
):
    off_output = OFFGeometryNoNexus(
        vertices=[QVector3D(0, 0, 0),
                  QVector3D(0, 1, 0),
                  QVector3D(1, 1, 0)],
        faces=[[0, 1, 2]],
    )

    off_mesh = OffMesh(off_output, None)

    assert off_mesh.geometry().vertex_count == VERTICES_IN_TRIANGLE
def test_remove_from_beginning_2(nexus_wrapper):
    component1 = add_component_to_file(nexus_wrapper, "field", 42,
                                       "component1")
    rot1 = component1.add_rotation(QVector3D(1.0, 0.0, 0.0), 90.0)
    rot2 = component1.add_rotation(QVector3D(1.0, 0.0, 0.0), 90.0)
    component1.depends_on = rot1
    rot1.depends_on = rot2
    assert len(rot2.get_dependents()) == 1
    rot1.remove_from_dependee_chain()
    assert len(rot2.get_dependents()) == 1
    assert rot2.get_dependents()[0] == component1
    assert component1.depends_on == rot2
Example #3
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 #4
0
def test_has_link_2(nexus_wrapper):
    component1 = add_component_to_file(nexus_wrapper, "field", 42,
                                       "component1")
    rot1 = component1.add_rotation(QVector3D(1.0, 0.0, 0.0), 90.0)
    component1.depends_on = rot1
    component2 = add_component_to_file(nexus_wrapper, "field", 42,
                                       "component2")
    rot2 = component2.add_rotation(QVector3D(1.0, 0.0, 0.0), 90.0)
    component2.depends_on = rot2
    rot1.depends_on = rot2

    new_component = Component(component1.file, component1.group)
    assert new_component.transforms.has_link
Example #5
0
    def calculateModel(self):
        translation = QMatrix4x4()
        translation.translate(self.translationVec)

        scale = QMatrix4x4()
        scale.scale(self.scaleVec)

        rotation = QMatrix4x4()
        rotation.rotate(self.rotationVec.y(), QVector3D(0, 1, 0))
        rotation.rotate(self.rotationVec.x(), QVector3D(1, 0, 0))
        rotation.rotate(self.rotationVec.z(), QVector3D(0, 0, 1))

        return translation * rotation * scale
Example #6
0
    def __init__(self):
        self.__modelMatrix = QMatrix4x4()
        self.__vertices = vertices
        self.__indices = indices
        self.__shader = None
        self.__vertexArray = None
        self.__indexBuffer = None
        self.__vertexBuffer = None

        self.__translate = QVector3D()
        self.__scale = QVector3D(1.0, 0.0, 1.0)

        self.initObject()
def test_GIVEN_a_square_WHEN_creating_vertex_buffer_THEN_length_is_correct():
    vertices = [
        QVector3D(0, 0, 0),
        QVector3D(1, 0, 0),
        QVector3D(0, 1, 0),
        QVector3D(1, 1, 0),
    ]
    faces = [[0, 1, 2, 3]]

    vertex_buffer = create_vertex_buffer(vertices, faces)

    assert (len(list(vertex_buffer)) == TRIANGLES_IN_SQUARE *
            VERTICES_IN_TRIANGLE * POINTS_IN_VERTEX)
Example #8
0
def test_GIVEN_cylinder_with_height_of_zero_WHEN_getting_axis_direction_THEN_default_value_is_returned(
    component, nexus_wrapper
):

    axis_x = 1.0
    axis_y = 0.0
    axis_z = 0.0
    axis = QVector3D(axis_x, axis_y, axis_z)
    height = 0
    radius = 37.0

    component.set_cylinder_shape(axis, height, radius)
    assert component.shape[0].axis_direction == QVector3D(0, 0, 1)
Example #9
0
    def set_beam_transform(cylinder_transform, neutron_animation_distance):
        """
        Configures the transform for the beam cylinder by giving it a matrix. The matrix will turn the cylinder sideways
        and then move it "backwards" in the z-direction by 20 units so that it ends at the location of the sample.
        :param cylinder_transform: A QTransform object.
        :param neutron_animation_distance: The distance that the neutron travels during its animation.
        """
        cylinder_matrix = QMatrix4x4()
        cylinder_matrix.rotate(90, QVector3D(1, 0, 0))
        cylinder_matrix.translate(
            QVector3D(0, neutron_animation_distance * 0.5, 0))

        cylinder_transform.setMatrix(cylinder_matrix)
Example #10
0
 def set_parameters_from_dict(self, parameters):
     self.set_unit_of_measurement(parameters['unit_of_measurements'])
     position = QVector3D(parameters['position'][0],
                          parameters['position'][1],
                          parameters['position'][2])
     self.set_position(position)
     rotation = QVector3D(parameters['rotation'][0],
                          parameters['rotation'][1],
                          parameters['rotation'][2])
     self.set_rotation(rotation)
     scale = QVector3D(parameters['scale'][0], parameters['scale'][1],
                       parameters['scale'][2])
     self.set_scale(scale)
Example #11
0
def load_text_stl(filename, swap_yz=False, test=True):
    fp = open(filename, 'r')
    number_of_triangles = 0
    normals_list = []
    vertices_list = []
    is_bbox_defined = False
    bbox_min = None
    bbox_max = None
    try:
        for line in fp.readlines():
            words = line.split()
            if len(words) > 0:
                if words[0] == 'facet':
                    number_of_triangles += 1
                    v = [float(words[2]), float(words[3]), float(words[4])]
                    if swap_yz:
                        v = [-v[0], v[2], v[1]]
                    normals_list.append(v)
                    normals_list.append(v)
                    normals_list.append(v)
                if words[0] == 'vertex':
                    v = [float(words[1]), float(words[2]), float(words[3])]
                    if swap_yz:
                        v = [-v[0], v[2], v[1]]
                    vertices_list.append(v)
                    q_v = QVector3D(v[0], v[1], v[2])
                    if is_bbox_defined:
                        min_temp = np.minimum(bbox_min.toTuple(), v)
                        max_temp = np.maximum(bbox_max.toTuple(), v)
                        bbox_min = QVector3D(min_temp[0], min_temp[1],
                                             min_temp[2])
                        bbox_max = QVector3D(max_temp[0], max_temp[1],
                                             max_temp[2])
                    else:
                        bbox_max = q_v
                        bbox_min = q_v
                        is_bbox_defined = True
    except Exception as e:
        fp.close()
        return False, vertices_list, normals_list, bbox_min, bbox_max
    fp.close()
    # bbox recentering around origin
    bbox_center = 0.5 * (bbox_min + bbox_max)
    for idx in range(len(vertices_list)):
        vertices_list[idx] = vertices_list[idx] - np.array(
            bbox_center.toTuple())
    bbox_min = bbox_min - bbox_center
    bbox_max = bbox_max - bbox_center
    vertices_list = np.array(vertices_list, dtype=np.float32).ravel()
    normals_list = np.array(normals_list, dtype=np.float32).ravel()
    return True, vertices_list, normals_list, bbox_min, bbox_max
Example #12
0
    def __init__(self):
        super(Window, self).__init__()

        # Default set-up
        self.rootEntity = Kuesa.SceneEntity()
        self.rootEntity.addComponent(DefaultEnvMap(self.rootEntity))

        self.camera().setPosition(QVector3D(5, 1.5, 5))
        self.camera().setViewCenter(QVector3D(0, 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)

        # Load a glTF model
        self.gltfImporter = Kuesa.GLTF2Importer(self.rootEntity)
        self.gltfImporter.setSceneEntity(self.rootEntity)
        self.gltfImporter.setSource(assetsUrl() + "/models/duck/Duck.glb")
        self.gltfImporter.statusChanged.connect(self.importerLoaded)

        # Skybox creation
        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")

        # Creation of a few post-processing effects
        self.blurFx = Kuesa.GaussianBlurEffect()
        self.blurFx.setBlurPassCount(8)

        self.dofFx = Kuesa.DepthOfFieldEffect()
        self.dofFx.setFocusRange(3.1)
        self.dofFx.setRadius(21.)
        self.dofFx.setFocusDistance(6.6)

        self.threshFx = Kuesa.ThresholdEffect()
        self.threshFx.setThreshold(.1)

        # self.fg.addPostProcessingEffect(self.blurFx)
        # self.fg.addPostProcessingEffect(self.dofFx)
        self.fg.addPostProcessingEffect(self.threshFx)

        self.setRootEntity(self.rootEntity)
Example #13
0
def test_deleting_a_transformation_which_the_component_indirectly_depends_on_is_not_allowed(
    nexus_wrapper,
):
    component = add_component_to_file(nexus_wrapper, "some_field", 42, "component_name")
    first_transform = component.add_rotation(QVector3D(1.0, 0.0, 0.0), 90.0)
    second_transform = component.add_translation(
        QVector3D(1.0, 0.0, 0.0), depends_on=first_transform
    )
    component.depends_on = second_transform

    with pytest.raises(DependencyError):
        assert component.remove_transformation(
            first_transform
        ), "Expected not to be allowed to delete the transform as the component indirectly depends on it"
Example #14
0
def test_GIVEN_off_geometry_WHEN_calling_off_geometry_on_offGeometry_THEN_original_geometry_is_returned():
    vertices = [
        QVector3D(0, 0, 1),
        QVector3D(0, 1, 0),
        QVector3D(0, 0, 0),
        QVector3D(0, 1, 1),
    ]

    faces = [[0, 1, 2, 3]]
    geom = OFFGeometryNoNexus(vertices, faces)

    assert geom.faces == faces
    assert geom.vertices == vertices
    assert geom.off_geometry == geom
Example #15
0
 def make_rotation_matrix(cls, axis: str, angle: float):
     "make rotation matrix with given axis"
     ax = axis.lower()
     mat = QMatrix4x4()
     mat.setToIdentity()
     if ax == "x":
         mat.rotate(angle, QVector3D(1.0, 0.0, 0.0))
     elif ax == "y":
         mat.rotate(angle, QVector3D(0.0, 1.0, 0.0))
     elif ax == "z":
         mat.rotate(angle, QVector3D(0.0, 0.0, 1.0))
     else:
         raise ValueError("Unknown axis: " + axis + ". x, y, z available")
     return mat
def test_does_not_link_back_4(nexus_wrapper):
    component1 = add_component_to_file(nexus_wrapper, "field", 42,
                                       "component1")
    rot2 = component1.add_rotation(QVector3D(1.0, 0.0, 0.0), 90.0)
    component1.depends_on = rot2
    component2 = add_component_to_file(nexus_wrapper, "field", 42,
                                       "component2")
    component3 = add_component_to_file(nexus_wrapper, "field", 42,
                                       "component3")
    rot1 = component3.add_rotation(QVector3D(1.0, 0.0, 0.0), 90.0)
    component3.depends_on = rot1
    component2.transforms.link.linked_component = component3

    assert not links_back_to_component(component1, component2)
Example #17
0
def test_GIVEN_faces_WHEN_calling_winding_order_on_OFF_THEN_order_is_correct():
    vertices = [
        QVector3D(0, 0, 1),
        QVector3D(0, 1, 0),
        QVector3D(0, 0, 0),
        QVector3D(0, 1, 1),
    ]

    faces = [[0, 1, 2, 3]]

    geom = OFFGeometryNoNexus(vertices, faces)
    expected = [point for face in faces for point in face]

    assert expected == geom.winding_order
Example #18
0
    def extrude(self, x1, y1, x2, y2):
        n = QVector3D.normal(QVector3D(0, 0, -0.1),
                             QVector3D(x2 - x1, y2 - y1, 0))

        self.add(QVector3D(x1, y1, 0.05), n)
        self.add(QVector3D(x1, y1, -0.05), n)
        self.add(QVector3D(x2, y2, 0.05), n)

        self.add(QVector3D(x2, y2, -0.05), n)
        self.add(QVector3D(x2, y2, 0.05), n)
        self.add(QVector3D(x1, y1, -0.05), n)
Example #19
0
def test_can_override_existing_shape(nexus_wrapper):
    component = add_component_to_file(nexus_wrapper, "some_field", 42, "component_name")

    component.set_cylinder_shape()
    cylinder, _ = component.shape
    assert isinstance(
        cylinder, CylindricalGeometry
    ), "Expect shape to initially be a cylinder"

    vertices = [QVector3D(-0.5, -0.5, 0), QVector3D(0, 0.5, 0), QVector3D(0.5, -0.5, 0)]
    faces = [[0, 1, 2]]
    input_mesh = OFFGeometryNoNexus(vertices, faces)
    component.set_off_shape(input_mesh)
    output_mesh, _ = component.shape
    assert isinstance(output_mesh, OFFGeometryNexus), "Expect shape to now be a mesh"
Example #20
0
 def update_vectors(self):
     "override base class"
     yawRadian = math.radians(self.yaw)
     yawCos = math.cos(yawRadian)
     pitchRadian = math.radians(self.pitch)
     pitchCos = math.cos(pitchRadian)
     frontX = yawCos * pitchCos
     frontY = math.sin(pitchRadian)
     frontZ = math.sin(yawRadian) * pitchCos
     self.front = QVector3D(frontX, frontY, frontZ)
     self.front.normalize()
     self.right = QVector3D.crossProduct(self.front, self.worldUp)
     self.right.normalize()
     self.up = QVector3D.crossProduct(self.right, self.front)
     self.up.normalize()
Example #21
0
    def __init__(self):
        ""
        super().__init__()
        # Camera attributes
        self.front = QVector3D(0.0, 0.0, -0.5)
        self.worldUp = QVector3D(0.0, 1.0, 0.0)

        # Euler Angles for rotation
        self.yaw = -90.0
        self.pitch = 0.0

        # camera options
        self.movementSpeed = 2.5
        self.movementSensitivity = 0.00001
        self.zoom = 45.0
Example #22
0
 def updateCameraVectors(self):
     "Update the camera vectors and compute a new front"
     yawRadian = np.radians(self.yaw)
     yawCos = np.cos(yawRadian)
     pitchRadian = np.radians(self.pitch)
     pitchCos = np.cos(pitchRadian)
     frontX = yawCos * pitchCos
     frontY = np.sin(pitchRadian)
     frontZ = np.sin(yawRadian) * pitchCos
     self.front = QVector3D(frontX, frontY, frontZ)
     self.front.normalize()
     self.right = QVector3D.crossProduct(self.front, self.worldUp)
     self.right.normalize()
     self.up = QVector3D.crossProduct(self.right, self.front)
     self.up.normalize()
def test_remove_from_beginning_3(nexus_wrapper):
    component1 = add_component_to_file(nexus_wrapper, "field", 42, "component1")
    component2 = add_component_to_file(nexus_wrapper, "field", 42, "component2")
    rot1 = component1.add_rotation(QVector3D(1.0, 0.0, 0.0), 90.0)
    rot2 = component2.add_rotation(QVector3D(1.0, 0.0, 0.0), 90.0)
    component1.depends_on = rot1
    component2.depends_on = rot2
    rot1.depends_on = rot2
    assert len(rot2.dependents) == 2
    rot1.remove_from_dependee_chain()
    assert len(rot2.dependents) == 2
    assert component2 in rot2.dependents
    assert component1 in rot2.dependents
    assert component1.depends_on == rot2
    assert component1.transforms.link.linked_component == component2
Example #24
0
def test_GIVEN_faces_WHEN_calling_winding_order_indices_on_OFF_THEN_order_is_correct():
    vertices = [
        QVector3D(0, 0, 1),
        QVector3D(0, 1, 0),
        QVector3D(0, 0, 0),
        QVector3D(0, 1, 1),
    ]

    faces = [[0, 1, 2, 3]]

    geom = OFFGeometryNoNexus(vertices, faces)

    expected = [0]  # only one face

    assert expected == geom.winding_order_indices
Example #25
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
def test_GIVEN_off_shape_json_WHEN_reading_shape_THEN_geometry_object_has_expected_properties(
    off_shape_reader, off_shape_json, mock_component
):
    children = off_shape_json[CommonKeys.CHILDREN]

    name = off_shape_json[CommonKeys.NAME]
    vertices_dataset = off_shape_reader._get_shape_dataset_from_list(
        CommonAttrs.VERTICES, children
    )
    vertices = list(
        map(
            lambda vertex: QVector3D(*vertex),
            vertices_dataset[NodeType.CONFIG][CommonKeys.VALUES],
        )
    )
    faces = off_shape_reader._get_shape_dataset_from_list("faces", children)[
        NodeType.CONFIG
    ][CommonKeys.VALUES]
    units = _find_attribute_from_list_or_dict(
        CommonAttrs.UNITS, vertices_dataset[CommonKeys.ATTRIBUTES]
    )
    winding_order = off_shape_reader._get_shape_dataset_from_list(
        "winding_order", children
    )[NodeType.CONFIG][CommonKeys.VALUES]

    off_shape_reader.add_shape_to_component()

    shape = mock_component[SHAPE_GROUP_NAME]
    assert isinstance(shape, OFFGeometryNexus)
    assert shape.nx_class == OFF_GEOMETRY_NX_CLASS
    assert shape.name == name
    assert shape.units == units
    assert shape.get_field_value("faces") == faces
    assert shape.vertices == vertices
    assert shape.winding_order == winding_order
def test_GIVEN_all_information_present_in_json_with_stream_WHEN_attempting_to_create_translation_THEN_create_transform_is_called(
        transformation_reader, transformation_with_stream_json):
    transform_json = transformation_with_stream_json["children"][0]
    transform_json["config"]["name"] = name = "TranslationName"
    transform_json["attributes"][0][
        "values"] = transformation_type = "translation"
    transform_json["attributes"][1]["values"] = units = "mm"
    transform_json["attributes"][2]["values"] = vector = [
        1.0,
        2.0,
        3.0,
    ]
    depends_on = None
    values = _create_transformation_datastream_group(transform_json, name)
    transformation_reader._create_transformations(
        transformation_with_stream_json["children"])

    transformation_reader.parent_component._create_and_add_transform.assert_called_once_with(
        name=name,
        transformation_type=TRANSFORMATION_MAP[transformation_type],
        angle_or_magnitude=0.0,
        units=units,
        vector=QVector3D(*vector),
        depends_on=depends_on,
        values=values,
    )
Example #28
0
 def _create_transformation_vectors_for_pixel_offsets(
     self, ) -> Optional[List[QVector3D]]:
     """
     Construct a transformation (as a QVector3D) for each pixel offset
     """
     try:
         units = self.get_field_attribute(X_PIXEL_OFFSET, CommonAttrs.UNITS)
         unit_conversion_factor = calculate_unit_conversion_factor(
             units, METRES)
         x_offsets = self.get_field_value(
             X_PIXEL_OFFSET) * unit_conversion_factor
         y_offsets = self.get_field_value(
             Y_PIXEL_OFFSET) * unit_conversion_factor
     except AttributeError:
         logging.info(
             "In pixel_shape_component expected to find x_pixel_offset and y_pixel_offset datasets"
         )
         return None
     try:
         z_offsets = self.get_field_value(Z_PIXEL_OFFSET)
     except AttributeError:
         z_offsets = np.zeros_like(x_offsets)
     if not isinstance(x_offsets, list):
         x_offsets = x_offsets.flatten()
     if not isinstance(y_offsets, list):
         y_offsets = y_offsets.flatten()
     if not isinstance(z_offsets, list):
         z_offsets = z_offsets.flatten()
     # offsets datasets can be 2D to match dimensionality of detector, so flatten to 1D
     return [
         QVector3D(x, y, z)
         for x, y, z in zip(x_offsets, y_offsets, z_offsets)
     ]
Example #29
0
    def set_cylinder_shape(
        self,
        axis_direction: QVector3D = QVector3D(0.0, 0.0, 1.0),
        height: float = 1.0,
        radius: float = 1.0,
        units: Union[str, bytes] = "m",
        pixel_data=None,
    ) -> Optional[CylindricalGeometry]:
        if validate_nonzero_qvector(axis_direction):
            return None
        self.remove_shape()
        shape_group = _get_shape_group_for_pixel_data(pixel_data)
        geometry = CylindricalGeometry(shape_group)
        geometry.nx_class = CYLINDRICAL_GEOMETRY_NX_CLASS

        vertices = CylindricalGeometry.calculate_vertices(
            axis_direction, height, radius)
        geometry.set_field_value(CommonAttrs.VERTICES, vertices,
                                 ValueTypes.FLOAT)

        # # Specify 0th vertex is base centre, 1st is base edge, 2nd is top centre
        geometry.set_field_value(CYLINDERS, np.array([0, 1, 2]),
                                 ValueTypes.INT)
        geometry[CommonAttrs.VERTICES].attributes.set_attribute_value(
            CommonAttrs.UNITS, units)

        if isinstance(pixel_data, PixelMapping):
            geometry.detector_number = get_detector_number_from_pixel_mapping(
                pixel_data)
        self[shape_group] = geometry
        return geometry
def _load_stl_geometry(
    file: StringIO,
    mult_factor: float,
    geometry: OFFGeometry = OFFGeometryNoNexus()
) -> OFFGeometry:
    """
    Loads geometry from an STL file into an OFFGeometry instance.

    :param file: The file containing an STL geometry.
    :param mult_factor: The multiplication factor for unit conversion.
    :param geometry: The optional OFFGeometry to load the STL data into. If not provided, a new instance will be
    returned.
    :return: An OFFGeometry instance containing that file's geometry.
    """
    mesh_data = mesh.Mesh.from_file("", fh=file, calculate_normals=False)
    # numpy-stl loads numbers as python decimals, not floats, which aren't valid in json
    geometry.vertices = [
        QVector3D(
            float(corner[0]) * mult_factor,
            float(corner[1]) * mult_factor,
            float(corner[2]) * mult_factor,
        ) for triangle in mesh_data.vectors for corner in triangle
    ]
    geometry.faces = [[i * 3, (i * 3) + 1, (i * 3) + 2]
                      for i in range(len(mesh_data.vectors))]
    logging.info("STL loaded")
    return geometry
Example #31
0
    def extrude(self, x1, y1, x2, y2):
        n = QVector3D.normal(QVector3D(0, 0, -0.1), QVector3D(x2 - x1, y2 - y1, 0))

        self.add(QVector3D(x1, y1, 0.05), n)
        self.add(QVector3D(x1, y1, -0.05), n)
        self.add(QVector3D(x2, y2, 0.05), n)

        self.add(QVector3D(x2, y2, -0.05), n)
        self.add(QVector3D(x2, y2, 0.05), n)
        self.add(QVector3D(x1, y1, -0.05), n)
Example #32
0
    def quad(self, x1, y1, x2, y2, x3, y3, x4, y4):
        n = QVector3D.normal(QVector3D(x4 - x1, y4 - y1, 0), QVector3D(x2 - x1, y2 - y1, 0))

        self.add(QVector3D(x1, y1, -0.05), n)
        self.add(QVector3D(x4, y4, -0.05), n)
        self.add(QVector3D(x2, y2, -0.05), n)

        self.add(QVector3D(x3, y3, -0.05), n)
        self.add(QVector3D(x2, y2, -0.05), n)
        self.add(QVector3D(x4, y4, -0.05), n)

        n = QVector3D.normal(QVector3D(x1 - x4, y1 - y4, 0), QVector3D(x2 - x4, y2 - y4, 0))

        self.add(QVector3D(x4, y4, 0.05), n)
        self.add(QVector3D(x1, y1, 0.05), n)
        self.add(QVector3D(x2, y2, 0.05), n)

        self.add(QVector3D(x2, y2, 0.05), n)
        self.add(QVector3D(x3, y3, 0.05), n)
        self.add(QVector3D(x4, y4, 0.05), n)