def compose(self, scale: Vector = None, shear: Vector = None, angles: Vector = None, translate: Vector = None, perspective: Vector = None, mirror: Vector = None) -> None: M = numpy.identity(4) if perspective is not None: P = numpy.identity(4) P[3, :] = perspective.getData()[:4] M = numpy.dot(M, P) if translate is not None: T = numpy.identity(4) T[:3, 3] = translate.getData()[:3] M = numpy.dot(M, T) if angles is not None: R = Matrix() R.setByEuler(angles.x, angles.y, angles.z, "sxyz") M = numpy.dot(M, R.getData()) if shear is not None: Z = numpy.identity(4) Z[1, 2] = shear.x Z[0, 2] = shear.y Z[0, 1] = shear.z M = numpy.dot(M, Z) if scale is not None: S = numpy.identity(4) S[0, 0] = scale.x S[1, 1] = scale.y S[2, 2] = scale.z M = numpy.dot(M, S) if mirror is not None: mir = numpy.identity(4) mir[0, 0] *= mirror.x mir[1, 1] *= mirror.y mir[2, 2] *= mirror.z M = numpy.dot(M, mir) M /= M[3, 3] self._data = M
def test_subtract(self): vector = Vector(2, 2, 2) vector2 = Vector(1, 1, 1) assert vector - vector2 == Vector(1, 1, 1) assert vector - vector2.getData() == Vector(1, 1, 1) assert vector2 - vector == Vector(-1, -1, -1) assert vector2 - vector.getData() == Vector(-1, -1, -1) vector -= vector2 assert vector == Vector(1, 1, 1)
def compose(self, scale: Vector = None, shear: Vector = None, angles: Vector = None, translate: Vector = None, perspective: Vector = None, mirror: Vector = None) -> None: """Return transformation matrix from sequence of transformations. This is the inverse of the decompose_matrix function. :param scale : vector of 3 scaling factors :param shear : list of shear factors for x-y, x-z, y-z axes :param angles : list of Euler angles about static x, y, z axes :param translate : translation vector along x, y, z axes :param perspective : perspective partition of matrix :param mirror: vector with mirror factors (1 if that axis is not mirrored, -1 if it is) """ M = numpy.identity(4) if perspective is not None: P = numpy.identity(4) P[3, :] = perspective.getData()[:4] M = numpy.dot(M, P) if translate is not None: T = numpy.identity(4) T[:3, 3] = translate.getData()[:3] M = numpy.dot(M, T) if angles is not None: R = Matrix() R.setByEuler(angles.x, angles.y, angles.z, "sxyz") M = numpy.dot(M, R.getData()) if shear is not None: Z = numpy.identity(4) Z[1, 2] = shear.x Z[0, 2] = shear.y Z[0, 1] = shear.z M = numpy.dot(M, Z) if scale is not None: S = numpy.identity(4) S[0, 0] = scale.x S[1, 1] = scale.y S[2, 2] = scale.z M = numpy.dot(M, S) if mirror is not None: mir = numpy.identity(4) mir[0, 0] *= mirror.x mir[1, 1] *= mirror.y mir[2, 2] *= mirror.z M = numpy.dot(M, mir) M /= M[3, 3] self._data = M
def test_add(self): vector = Vector(0, 1, 0) vector2 = Vector(1, 0, 1) assert vector + vector2 == Vector(1, 1, 1) assert vector + vector2.getData() == Vector(1, 1, 1) vector += vector2 assert vector == Vector(1, 1, 1)
def test_setValues(self): x = 10 y = 10 z = 10 temp_vector = Vector(x, y, z) numpy.testing.assert_array_almost_equal(temp_vector.getData(), numpy.array([x, y, z]))
def findFirstAngleNormal(): for i in range(1, ns - 1): spt = spine[i] z = (spine[i + 1] - spt).cross(spine[i - 1] - spt) if z.length() > EPSILON: return z # All the spines are collinear. Fallback to the rotated source # XZ plane. # TODO: handle the situation where the first two spine points match if len(spine) < 2: return Vector(0, 0, 1) v = spine[1] - spine[0] orig_y = Vector(0, 1, 0) orig_z = Vector(0, 0, 1) if v.cross(orig_y).length() > EPSILON: # Spine at angle with global y - rotate the z accordingly a = v.cross(orig_y) # Axis of rotation to get to the Z (x, y, z) = a.normalized().getData() s = a.length()/v.length() c = sqrt(1-s*s) t = 1-c m = numpy.array(( (x * x * t + c, x * y * t + z*s, x * z * t - y * s), (x * y * t - z*s, y * y * t + c, y * z * t + x * s), (x * z * t + y * s, y * z * t - x * s, z * z * t + c))) orig_z = Vector(*m.dot(orig_z.getData())) return orig_z
def setByRotationAxis(self, angle: float, direction: Vector, point: Optional[List[float]] = None) -> None: """Set the matrix based on rotation axis. This overwrites any existing data. :param angle: The angle by which matrix needs to be rotated in radians. :param direction: Axis by which the matrix needs to be rotated about. :param point: Point where from where the rotation happens. If None, origin is used. """ sina = math.sin(angle) cosa = math.cos(angle) direction_data = cast(numpy.ndarray, self._unitVector(direction.getData())) # rotation matrix around unit vector R = numpy.diag([cosa, cosa, cosa]) R += numpy.outer(direction_data, direction_data) * (1.0 - cosa) direction_data *= sina R += numpy.array([[0.0, -direction_data[2], direction_data[1]], [direction_data[2], 0.0, -direction_data[0]], [-direction_data[1], direction_data[0], 0.0]], dtype=numpy.float64) M = numpy.identity(4) M[:3, :3] = R if point is not None: # rotation not around origin point2 = numpy.array(point[:3], dtype=numpy.float64, copy=False) M[:3, 3] = point2 - numpy.dot(R, point2) self._data = M
def findFirstAngleNormal(): for i in range(1, ns - 1): spt = spine[i] z = (spine[i + 1] - spt).cross(spine[i - 1] - spt) if z.length() > EPSILON: return z # All the spines are collinear. Fallback to the rotated source # XZ plane. # TODO: handle the situation where the first two spine points match if len(spine) < 2: return Vector(0, 0, 1) v = spine[1] - spine[0] orig_y = Vector(0, 1, 0) orig_z = Vector(0, 0, 1) if v.cross(orig_y).length() > EPSILON: # Spine at angle with global y - rotate the z accordingly a = v.cross(orig_y) # Axis of rotation to get to the Z (x, y, z) = a.normalized().getData() s = a.length() / v.length() c = sqrt(1 - s * s) t = 1 - c m = numpy.array( ((x * x * t + c, x * y * t + z * s, x * z * t - y * s), (x * y * t - z * s, y * y * t + c, y * z * t + x * s), (x * z * t + y * s, y * z * t - x * s, z * z * t + c))) orig_z = Vector(*m.dot(orig_z.getData())) return orig_z
def setByTranslation(self, direction: Vector) -> None: """Set the matrix by translation vector. This overwrites any existing data. :param direction: The vector by which the (unit) matrix needs to be translated. """ M = numpy.identity(4, dtype=numpy.float64) M[:3, 3] = direction.getData()[:3] self._data = M
def test_setValues(self): x = 10 y = 10 z = 10 temp_vector = Vector(x,y,z) numpy.testing.assert_array_almost_equal(temp_vector.getData(), numpy.array([x,y,z])) temp_vector2 = temp_vector.set(1, 2, 3) numpy.testing.assert_array_almost_equal(temp_vector2.getData(), numpy.array([1, 2, 3]))
class TestVector(unittest.TestCase): def setUp(self): # Called before the first testfunction is executed self._vector = Vector(1, 0, 0) pass def tearDown(self): # Called after the last testfunction was executed pass def test_getData(self): numpy.testing.assert_array_almost_equal(self._vector.getData(), numpy.array([1, 0, 0])) pass def test_angleBetweenVectors(self): second_vector = Vector(1, 0, 0) third_vector = Vector(0, 1, 0) fourth_vector = Vector(0, 0, 1) # Check if angle with itself is 0 self.assertEqual(self._vector.angleToVector(second_vector), 0) # Check if angle between the two vectors that are rotated in equal angle but different direction are the same self.assertEqual(self._vector.angleToVector(third_vector), self._vector.angleToVector(fourth_vector)) def test_normalize(self): vector = Vector(10, 10, 10) assert vector.normalized().length() == 1 def test_setValues(self): x = 10 y = 10 z = 10 temp_vector = Vector(x, y, z) numpy.testing.assert_array_almost_equal(temp_vector.getData(), numpy.array([x, y, z])) temp_vector2 = temp_vector.set(1, 2, 3) numpy.testing.assert_array_almost_equal(temp_vector2.getData(), numpy.array([1, 2, 3])) def test_negPos(self): v = Vector(0, 1, 0) self.assertEqual(Vector(0, -1, 0), -v) self.assertEqual(Vector(0, 1, 0), v) # - should have no side effects
def setByRotationAxis(self, angle: float, direction: Vector, point: Optional[List[float]] = None) -> None: sina = math.sin(angle) cosa = math.cos(angle) direction_data = self._unitVector(direction.getData()) # rotation matrix around unit vector R = numpy.diag([cosa, cosa, cosa]) R += numpy.outer(direction_data, direction_data) * (1.0 - cosa) direction_data *= sina R += numpy.array([[ 0.0, -direction_data[2], direction_data[1]], [ direction_data[2], 0.0, -direction_data[0]], [-direction_data[1], direction_data[0], 0.0]], dtype = numpy.float64) M = numpy.identity(4) M[:3, :3] = R if point is not None: # rotation not around origin point = numpy.array(point[:3], dtype = numpy.float64, copy=False) M[:3, 3] = point - numpy.dot(R, point) self._data = M
class TestVector(unittest.TestCase): def setUp(self): # Called before the first testfunction is executed self._vector = Vector(1, 0, 0) pass def tearDown(self): # Called after the last testfunction was executed pass def test_getData(self): numpy.testing.assert_array_almost_equal(self._vector.getData(), numpy.array([1, 0, 0])) pass def test_angleBetweenVectors(self): second_vector = Vector(1, 0, 0) third_vector = Vector(0, 1, 0) fourth_vector = Vector(0, 0, 1) # Check if angle with itself is 0 self.assertEqual(self._vector.angleToVector(second_vector), 0) # Check if angle between the two vectors that are rotated in equal angle but different direction are the same self.assertEqual(self._vector.angleToVector(third_vector), self._vector.angleToVector(fourth_vector)) def test_normalize(self): pass def test_setValues(self): x = 10 y = 10 z = 10 temp_vector = Vector(x, y, z) numpy.testing.assert_array_almost_equal(temp_vector.getData(), numpy.array([x, y, z])) def test_negPos(self): v = Vector(0, 1, 0) self.assertEqual(Vector(0, -1, 0), -v) self.assertEqual(Vector(0, 1, 0), v) # - should have no side effects
def setTranslation(self, translation: Vector) -> None: self._data[:3, 3] = translation.getData()
class TestVector(unittest.TestCase): def setUp(self): # Called before the first testfunction is executed self._vector = Vector(1,0,0) pass def tearDown(self): # Called after the last testfunction was executed pass def test_getData(self): numpy.testing.assert_array_almost_equal(self._vector.getData(), numpy.array([1,0,0])) def test_angleBetweenVectors(self): second_vector = Vector(1,0,0) third_vector = Vector(0,1,0) fourth_vector = Vector(0,0,1) # Check if angle with itself is 0 self.assertEqual(self._vector.angleToVector(second_vector), 0) # Check if angle between the two vectors that are rotated in equal angle but different direction are the same self.assertEqual(self._vector.angleToVector(third_vector), self._vector.angleToVector(fourth_vector)) def test_normalize(self): vector = Vector(10, 10, 10) assert vector.normalized().length() == pytest.approx(1) def test_setValues(self): x = 10 y = 10 z = 10 temp_vector = Vector(x,y,z) numpy.testing.assert_array_almost_equal(temp_vector.getData(), numpy.array([x,y,z])) temp_vector2 = temp_vector.set(1, 2, 3) numpy.testing.assert_array_almost_equal(temp_vector2.getData(), numpy.array([1, 2, 3])) def test_negPos(self): v = Vector(0, 1, 0) self.assertEqual(Vector(0, -1, 0), -v) self.assertEqual(Vector(0, 1, 0), v) # - should have no side effects def test_compare(self): short_vector = Vector(0, 1, 0) long_vector = Vector(200, 300, 500) assert short_vector < long_vector assert long_vector > short_vector assert not long_vector == None def test_add(self): vector = Vector(0, 1, 0) vector2 = Vector(1, 0, 1) assert vector + vector2 == Vector(1, 1, 1) assert vector + vector2.getData() == Vector(1, 1, 1) vector += vector2 assert vector == Vector(1, 1, 1) def test_subtract(self): vector = Vector(2, 2, 2) vector2 = Vector(1, 1, 1) assert vector - vector2 == Vector(1, 1, 1) assert vector - vector2.getData() == Vector(1, 1, 1) assert vector2 - vector == Vector(-1, -1, -1) assert vector2 - vector.getData() == Vector(-1, -1, -1) vector -= vector2 assert vector == Vector(1, 1, 1) def test_multiply(self): vector = Vector(2, 2, 2) vector2 = Vector(2, 2, 2) assert vector * vector2 == Vector(4, 4, 4) assert vector * 2 == Vector(4, 4, 4) assert vector.scale(vector2) == Vector(4, 4, 4) vector *= vector2 assert vector == Vector(4, 4, 4)
def setByTranslation(self, direction: Vector) -> None: M = numpy.identity(4, dtype=numpy.float64) M[:3, 3] = direction.getData()[:3] self._data = M
def loadStep(self, step): selected_node = Selection.getSelectedObject(0) for bc in step.boundary_conditions: selected_face = self._interactive_mesh.face_from_ids(bc.face) face = AnchorFace(str(bc.name)) face.selection = (selected_node, bc.face[0]) if len(selected_face.triangles) > 0: face.surface_type = self._guessSurfaceTypeFromTriangles( selected_face) axis = None if face.surface_type == HighlightFace.SurfaceType.Flat: axis = selected_face.planar_axis() elif face.surface_type != face.SurfaceType.Unknown: axis = selected_face.rotation_axis() face.setMeshDataFromPywimTriangles(selected_face, axis) face.disableTools() self.addFace(face) for bc in step.loads: selected_face = self._interactive_mesh.face_from_ids(bc.face) face = LoadFace(str(bc.name)) face.selection = (selected_node, bc.face[0]) load_prime = Vector(bc.force[0], bc.force[1], bc.force[2]) origin_prime = Vector(bc.origin[0], bc.origin[1], bc.origin[2]) print_to_cura = Matrix() print_to_cura._data[1, 1] = 0 print_to_cura._data[1, 2] = 1 print_to_cura._data[2, 1] = -1 print_to_cura._data[2, 2] = 0 _, rotation, _, _ = print_to_cura.decompose() load = numpy.dot(rotation.getData(), load_prime.getData()) origin = numpy.dot(rotation.getData(), origin_prime.getData()) rotated_load = pywim.geom.Vector(load[0], load[1], load[2]) rotated_load.origin = pywim.geom.Vertex(origin[0], origin[1], origin[2]) if len(selected_face.triangles) > 0: face.surface_type = self._guessSurfaceTypeFromTriangles( selected_face) axis = None if face.surface_type == HighlightFace.SurfaceType.Flat: axis = selected_face.planar_axis() elif face.surface_type != face.SurfaceType.Unknown: axis = selected_face.rotation_axis() face.force.setFromVectorAndAxis(rotated_load, axis) # Need to reverse the load direction for concave / convex surface if face.surface_type == HighlightFace.SurfaceType.Concave or face.surface_type == HighlightFace.SurfaceType.Convex: if face.force.direction_type == Force.DirectionType.Normal: face.force.direction_type = Force.DirectionType.Parallel else: face.force.direction_type = Force.DirectionType.Normal face.setMeshDataFromPywimTriangles(selected_face, axis) face.setArrow(Vector(load[0], load[1], load[2])) self.addFace(face) face.disableTools()
def setByTranslation(self, direction: Vector) -> None: M = numpy.identity(4, dtype = numpy.float64) M[:3, 3] = direction.getData()[:3] self._data = M
class TestVector(unittest.TestCase): def setUp(self): # Called before the first testfunction is executed self._vector = Vector(1,0,0) pass def tearDown(self): # Called after the last testfunction was executed pass def test_getData(self): numpy.testing.assert_array_almost_equal(self._vector.getData(), numpy.array([1,0,0])) def test_angleBetweenVectors(self): second_vector = Vector(1,0,0) third_vector = Vector(0,1,0) fourth_vector = Vector(0,0,1) # Check if angle with itself is 0 self.assertEqual(self._vector.angleToVector(second_vector), 0) # Check if angle between the two vectors that are rotated in equal angle but different direction are the same self.assertEqual(self._vector.angleToVector(third_vector), self._vector.angleToVector(fourth_vector)) def test_normalize(self): vector = Vector(10, 10, 10) assert vector.normalized().length() == 1 def test_setValues(self): x = 10 y = 10 z = 10 temp_vector = Vector(x,y,z) numpy.testing.assert_array_almost_equal(temp_vector.getData(), numpy.array([x,y,z])) temp_vector2 = temp_vector.set(1, 2, 3) numpy.testing.assert_array_almost_equal(temp_vector2.getData(), numpy.array([1, 2, 3])) def test_negPos(self): v = Vector(0, 1, 0) self.assertEqual(Vector(0, -1, 0), -v) self.assertEqual(Vector(0, 1, 0), v) # - should have no side effects def test_compare(self): short_vector = Vector(0, 1, 0) long_vector = Vector(200, 300, 500) assert short_vector < long_vector assert long_vector > short_vector assert not long_vector == None def test_add(self): vector = Vector(0, 1, 0) vector2 = Vector(1, 0, 1) assert vector + vector2 == Vector(1, 1, 1) assert vector + vector2.getData() == Vector(1, 1, 1) vector += vector2 assert vector == Vector(1, 1, 1) def test_subtract(self): vector = Vector(2, 2, 2) vector2 = Vector(1, 1, 1) assert vector - vector2 == Vector(1, 1, 1) assert vector - vector2.getData() == Vector(1, 1, 1) assert vector2 - vector == Vector(-1, -1, -1) assert vector2 - vector.getData() == Vector(-1, -1, -1) vector -= vector2 assert vector == Vector(1, 1, 1) def test_multiply(self): vector = Vector(2, 2, 2) vector2 = Vector(2, 2, 2) assert vector * vector2 == Vector(4, 4, 4) assert vector * 2 == Vector(4, 4, 4) assert vector.scale(vector2) == Vector(4, 4, 4) vector *= vector2 assert vector == Vector(4, 4, 4)