Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions bladex/blade.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,83 @@ def rotate(self, deg_angle=None, rad_angle=None, axis='x'):
elif id == 3:
self.root_face = face

def mirror(self, *args, **kwargs):
"""
3D mirroring of the blade with respect to a plane.
The plane can be defined either by three points or by a point and its normal direction.
Which option to be used depends on the inputs taken by the funtion.

args: -three entries means three points
-two entries means one point and one normal vector
kwargs: -only accepted arguments: point1, point2, point3, normal
"""
if len(self.blade_coordinates_up) == 0:
raise ValueError('You must apply transformations before rotation.')

if len(args) + len(kwargs) not in [2, 3]:
raise ValueError("Wrong number of arguments")

admissible_kwargs = ['point1', 'point2', 'point3', 'point', 'normal']
if any(key not in admissible_kwargs for key in kwargs.keys()):
raise ValueError('Wrong argument. Admissible arguments are only {}'.format(admissible_kwargs))

from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_Transform
from OCC.Core.gp import gp_Pnt
from OCC.Core.gp import gp_Vec
from OCC.Core.gp import gp_Dir
from OCC.Core.gp import gp_Ax2
from OCC.Core.gp import gp_Trsf

if len(args) == 3:
# Case where the three points are passed
point1 = gp_Pnt(*args[0])
point2 = gp_Pnt(*args[1])
point3 = gp_Pnt(*args[2])
# Two vectors defining the directions of the plane
vector1 = gp_Vec(point1, point2)
vector2 = gp_Vec(point2, point3)
# Normal versor to the plane passing through the three points
normal = gp_Dir(vector1.Crossed(vector2))
elif list(kwargs.keys()) == ['point1', 'point2', 'point3']:
# Case where the three points are passed
point1 = gp_Pnt(*kwargs['point1'])
point2 = gp_Pnt(*kwargs['point2'])
point3 = gp_Pnt(*kwargs['point3'])
# Two vectors defining the directions of the plane
vector1 = gp_Vec(point1, point2)
vector2 = gp_Vec(point2, point3)
# Normal versor to the plane passing through the three points
normal = gp_Dir(vector1.Crossed(vector2))
elif len(args) == 2:
# Case where one point and the normal are passed
point1 = gp_Pnt(*args[0])
normal = gp_Dir(*args[1])
elif sorted(kwargs.keys()) == sorted(['point', 'normal']):
point1 = gp_Pnt(*kwargs['point'])
normal = gp_Dir(*kwargs['normal'])
else:
raise ValueError('Wrong arguments passed')

# Ax2 object identifying the plane
ax2 = gp_Ax2(point1, normal)

# Mirroring wrt plane transformation
trsf = gp_Trsf()
trsf.SetMirror(ax2)

for id, face in enumerate([self.upper_face, self.lower_face,
self.tip_face, self.root_face]):
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.
Expand Down
2 changes: 1 addition & 1 deletion bladex/deform.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ def compute_deformed_parameters(self, param, tol=1e-3):
if index.shape[0] > 1:
# In case more neighbors are found, then take first value only.
index = index[0]
self.deformed_parameters[param][i] = self.spline[param][index, 1]
self.deformed_parameters[param][i] = self.spline[param][index, 1].item()

def compute_all(self,
rbf_points=1000,
Expand Down
12 changes: 12 additions & 0 deletions tests/test_blade.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,18 @@ def test_rotate_rad(self):
np.testing.assert_almost_equal(blade.blade_coordinates_down[1][2],
rotated_coordinates)

def test_blade_mirror_exceptions(self):
blade = create_sample_blade_NACA()
blade.apply_transformations()
with self.assertRaises(ValueError):
blade.mirror(wrong_argument=[0., 0., 0.], point2=[0., 1., 0.], point3=[0., 1., 1.])

def test_blade_mirror_exceptions_2(self):
blade = create_sample_blade_NACA()
blade.apply_transformations()
with self.assertRaises(ValueError):
blade.mirror([0., 1., 1.])

def test_plot_view_elev_init(self):
blade = create_sample_blade_NACA()
blade.apply_transformations()
Expand Down
Loading