diff --git a/bladex/blade.py b/bladex/blade.py index a71dd86..ed5b476 100644 --- a/bladex/blade.py +++ b/bladex/blade.py @@ -404,6 +404,7 @@ def rotate(self, deg_angle=None, rad_angle=None, axis='x'): elif deg_angle is not None: cosine = np.cos(np.radians(deg_angle)) sine = np.sin(np.radians(deg_angle)) + rad_angle = deg_angle * np.pi / 180 else: raise ValueError( 'You have to pass either the angle in radians or in degrees.') @@ -429,6 +430,39 @@ def rotate(self, deg_angle=None, rad_angle=None, axis='x'): self.blade_coordinates_down = np.einsum('ij, kjl->kil', rot_matrix, self.blade_coordinates_down) + # TODO: working but ugly + for id, face in enumerate([self.upper_face, self.lower_face, + self.tip_face, self.root_face]): + from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_Transform + from OCC.Core.gp import gp_Pnt + from OCC.Core.gp import gp_Dir + from OCC.Core.gp import gp_Ax1 + from OCC.Core.gp import gp_Trsf + + origin = gp_Pnt(0, 0, 0) + if axis == 'y': + direction = gp_Dir(0, 1, 0) + elif axis == 'z': + direction = gp_Dir(0, 0, 1) + elif axis == 'x': + direction = gp_Dir(1, 0, 0) + else: + raise ValueError('Axis must be either x, y, or z.') + ax1 = gp_Ax1(origin, direction) + trsf = gp_Trsf() + trsf.SetRotation(ax1, rad_angle) + + brep_tr = BRepBuilderAPI_Transform(face, trsf, True, True) + face = brep_tr.Shape() + if id == 0: + self.upper_face = face + elif id == 1: + self.lower_face = face + elif id == 2: + self.tip_face = face + elif id == 3: + self.root_face = face + def scale(self, factor): """ Scale the blade coordinates by a specified factor. @@ -438,11 +472,29 @@ def scale(self, factor): from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_Transform self.blade_coordinates_up *= factor self.blade_coordinates_down *= factor - # for face in [self.upper_face, self.lower_face, self.tip_face, self.root_face]: - # brepgp_Trsf = BRepBuilderAPI_Transform() - # brepgp_Trsf.SetScale(gp_Pnt(0, 0, 0), factor) - # brepgp_Trsf.Perform(face, True) - # face = brepgp_Trsf.Shape() + + for id, face in enumerate([self.upper_face, self.lower_face, + self.tip_face, self.root_face]): + from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_Transform + from OCC.Core.gp import gp_Pnt + from OCC.Core.gp import gp_Dir + from OCC.Core.gp import gp_Ax1 + from OCC.Core.gp import gp_Trsf + + origin = gp_Pnt(0, 0, 0) + trsf = gp_Trsf() + trsf.SetScale(origin, factor) + + brep_tr = BRepBuilderAPI_Transform(face, trsf, True, True) + face = brep_tr.Shape() + if id == 0: + self.upper_face = face + elif id == 1: + self.lower_face = face + elif id == 2: + self.tip_face = face + elif id == 3: + self.root_face = face def plot(self, elev=None, azim=None, ax=None, outfile=None): """ @@ -944,3 +996,15 @@ def __str__(self): string += '\nInduced rake from skew (in unit length)'\ ' for the sections = {}'.format(self.induced_rake) return string + + def display(self): + """ + Display the propeller with shaft. + """ + from OCC.Display.SimpleGui import init_display + display, start_display = init_display()[:2] + display.DisplayShape(self.upper_face, update=True) + display.DisplayShape(self.lower_face, update=True) + display.DisplayShape(self.root_face, update=True) + display.DisplayShape(self.tip_face, update=True) + start_display() \ No newline at end of file diff --git a/bladex/propeller.py b/bladex/propeller.py index 309687e..868c737 100644 --- a/bladex/propeller.py +++ b/bladex/propeller.py @@ -27,6 +27,14 @@ def __init__(self, shaft, blade, n_blades): self.shaft_solid = shaft.generate_solid() blade.build(reflect=True) + import copy + + self.blades = [copy.deepcopy(blade) for _ in range(n_blades)] + [ + blade.rotate(rad_angle=i * 2.0 * np.pi / float(n_blades)) + for i, blade in enumerate(self.blades) + ] + blade_solid = blade.generate_solid() blades = [] blades.append(blade_solid) @@ -34,10 +42,12 @@ def __init__(self, shaft, blade, n_blades): blade.rotate(rad_angle=1.0 * 2.0 * np.pi / float(n_blades)) blade_solid = blade.generate_solid() blades.append(blade_solid) - blades_combined = blades[0] + + blade_solids = [blade_.generate_solid() for blade_ in self.blades] + blades_combined = blade_solids[0] for i in range(len(blades) - 1): print(i) - boolean_union = BRepAlgoAPI_Fuse(blades_combined, blades[i + 1]) + boolean_union = BRepAlgoAPI_Fuse(blades_combined, blade_solids[i + 1]) boolean_union.Build() if not boolean_union.IsDone(): raise RuntimeError("Unsuccessful assembling of blade") @@ -245,4 +255,4 @@ def display(self): """ display, start_display = init_display()[:2] display.DisplayShape(self.sewed_full_body, update=True) - start_display() + start_display() \ No newline at end of file diff --git a/tests/test_blade.py b/tests/test_blade.py index f9c6d76..c09f75c 100644 --- a/tests/test_blade.py +++ b/tests/test_blade.py @@ -338,7 +338,7 @@ def test_blade_rotate_exceptions_no_transformation(self): def test_rotate_deg_section_0(self): blade = create_sample_blade_NACA_10() - blade.apply_transformations() + blade.build() blade.rotate(deg_angle=90) rotated_coordinates = np.array([ 0.2969784, 0.2653103, 0.2146533, 0.1597801, 0.1024542, @@ -361,9 +361,9 @@ def test_rotate_deg_section_0(self): np.testing.assert_almost_equal(blade.blade_coordinates_up[0][2], rotated_coordinates) - def test_rotate_rad_section_1_xdown(self): + def test_rotate_rad(self): blade = create_sample_blade_NACA_10() - blade.apply_transformations() + blade.build() blade.rotate(rad_angle=np.pi / 2.0) rotated_coordinates = np.array([ 0.23913475, 0.17512439, 0.12479053, 0.07749333, 0.03196268, @@ -372,10 +372,6 @@ def test_rotate_rad_section_1_xdown(self): np.testing.assert_almost_equal(blade.blade_coordinates_down[1][0], rotated_coordinates) - def test_rotate_rad_section_1_ydown(self): - blade = create_sample_blade_NACA_10() - blade.apply_transformations() - blade.rotate(rad_angle=np.pi / 2.0) rotated_coordinates = np.array([ -0.3488408, -0.3576312, -0.3719492, -0.3844258, -0.3936846, -0.3989522, -0.3997457, -0.3957593, -0.3867917, -0.3726862 @@ -383,10 +379,6 @@ def test_rotate_rad_section_1_ydown(self): np.testing.assert_almost_equal(blade.blade_coordinates_down[1][1], rotated_coordinates) - def test_rotate_rad_section_1_zdown(self): - blade = create_sample_blade_NACA_10() - blade.apply_transformations() - blade.rotate(rad_angle=np.pi / 2.0) rotated_coordinates = np.array([ 0.19572966, 0.17916459, 0.14715217, 0.11052969, 0.07079877, 0.02893379, -0.01426232, -0.05809137, -0.10194212, -0.14527558