From 1a5aacdff376be3c6359fd3ee2738ba876a9d468 Mon Sep 17 00:00:00 2001 From: Davide Oberto Date: Fri, 6 Mar 2026 09:29:39 +0100 Subject: [PATCH 1/2] Moved some repeated code to the base class and implemented check for empty intersection between blade and cutting cylinder --- .../reversepropeller/basereversepropeller.py | 39 +++++++++ bladex/reversepropeller/reversepropeller.py | 63 +++++++------- .../reversepropellerbladex.py | 84 +++++++++++++------ 3 files changed, 128 insertions(+), 58 deletions(-) diff --git a/bladex/reversepropeller/basereversepropeller.py b/bladex/reversepropeller/basereversepropeller.py index 49cb34a..7f457c4 100644 --- a/bladex/reversepropeller/basereversepropeller.py +++ b/bladex/reversepropeller/basereversepropeller.py @@ -183,6 +183,45 @@ def _build_cylinder(self, radius): self.cylinder_lateral_faces_list.append(surface) faces_explorer.Next() + def _build_intersection_cylinder_blade(self): + """ + Private method that constructs the section lines which are the intersections + between the cylinder at a fixed radius and the blade, and the camber points. + """ + # Construction of the section lines between two shapes (in this case the + # blade and the lateral face of the cylinder) + section_builder = BRepAlgoAPI_Section(self.blade_solid, + self.cylinder_lateral_face, False) + # Define and build the parametric 2D curve (pcurve) for the section lines defined above + section_builder.ComputePCurveOn2(True) + section_builder.Build() + self.section = section_builder.Shape() + edgeExplorer = TopExp_Explorer(self.section, TopAbs_EDGE) + wire_maker = BRepBuilderAPI_MakeWire() + + edgeCount = 0 + edgeList = TopTools_ListOfShape() + # Checking if the intersection is null, i.e. no edes from the the section + if not edgeExplorer.More(): + raise ValueError( + "Cylinder radius too small/large: no intersection with blade." \ + "The radii must be in mm and not m" + ) + + while edgeExplorer.More(): + edgeCount = edgeCount + 1 # Numbering from 1 in OCC + edge = topods.Edge(edgeExplorer.Current()) + edgeList.Append(edge) + edgeExplorer.Next() + wire_maker.Add(edgeList) + self.wire = wire_maker.Wire() + self.section_wires_list.append(self.wire) + self.curve_adaptor = BRepAdaptor_CompCurve( + OCC.Core.TopoDS.topods.Wire(self.wire)) + # Length of the curve section (ascissa curvilinea) + self.total_section_length = GCPnts_AbscissaPoint.Length( + self.curve_adaptor) + def _extract_parameters_and_transform_profile(self, radius): """ Private method which extracts the parameters (pitch, rake, skew ,...) related diff --git a/bladex/reversepropeller/reversepropeller.py b/bladex/reversepropeller/reversepropeller.py index 1bc98e2..927ae35 100644 --- a/bladex/reversepropeller/reversepropeller.py +++ b/bladex/reversepropeller/reversepropeller.py @@ -153,38 +153,37 @@ def __init__(self, filename, radii_list, num_points_top_bottom): ind_sec = ind_sec + 1 - def _build_intersection_cylinder_blade(self): - """ - Private method that constructs the section lines which are the intersections - between the cylinder at a fixed radius and the blade, and the camber points. - """ - # Construction of the section lines between two shapes (in this case the - # blade and the lateral face of the cylinder) - section_builder = BRepAlgoAPI_Section(self.blade_solid, - self.cylinder_lateral_face, False) - # Define and build the parametric 2D curve (pcurve) for the section lines defined above - section_builder.ComputePCurveOn2(True) - section_builder.Build() - self.section = section_builder.Shape() - edgeExplorer = TopExp_Explorer(self.section, TopAbs_EDGE) - wire_maker = BRepBuilderAPI_MakeWire() - - edgeCount = 0 - self.total_section_length = 0.0 - edgeList = TopTools_ListOfShape() - while edgeExplorer.More(): - edgeCount = edgeCount + 1 # Numbering from 1 in OCC - edge = topods.Edge(edgeExplorer.Current()) - edgeList.Append(edge) - edgeExplorer.Next() - wire_maker.Add(edgeList) - self.wire = wire_maker.Wire() - self.section_wires_list.append(self.wire) - self.curve_adaptor = BRepAdaptor_CompCurve( - OCC.Core.TopoDS.topods.Wire(self.wire)) - # Length of the curve section (ascissa curvilinea) - self.total_section_length = GCPnts_AbscissaPoint.Length( - self.curve_adaptor) + # def _build_intersection_cylinder_blade(self): + # """ + # Private method that constructs the section lines which are the intersections + # between the cylinder at a fixed radius and the blade, and the camber points. + # """ + # # Construction of the section lines between two shapes (in this case the + # # blade and the lateral face of the cylinder) + # section_builder = BRepAlgoAPI_Section(self.blade_solid, + # self.cylinder_lateral_face, False) + # # Define and build the parametric 2D curve (pcurve) for the section lines defined above + # section_builder.ComputePCurveOn2(True) + # section_builder.Build() + # self.section = section_builder.Shape() + # edgeExplorer = TopExp_Explorer(self.section, TopAbs_EDGE) + # wire_maker = BRepBuilderAPI_MakeWire() + + # edgeCount = 0 + # edgeList = TopTools_ListOfShape() + # while edgeExplorer.More(): + # edgeCount = edgeCount + 1 # Numbering from 1 in OCC + # edge = topods.Edge(edgeExplorer.Current()) + # edgeList.Append(edge) + # edgeExplorer.Next() + # wire_maker.Add(edgeList) + # self.wire = wire_maker.Wire() + # self.section_wires_list.append(self.wire) + # self.curve_adaptor = BRepAdaptor_CompCurve( + # OCC.Core.TopoDS.topods.Wire(self.wire)) + # # Length of the curve section (ascissa curvilinea) + # self.total_section_length = GCPnts_AbscissaPoint.Length( + # self.curve_adaptor) def _camber_points(self, radius): diff --git a/bladex/reversepropeller/reversepropellerbladex.py b/bladex/reversepropeller/reversepropellerbladex.py index 08ee028..3df6d16 100644 --- a/bladex/reversepropeller/reversepropellerbladex.py +++ b/bladex/reversepropeller/reversepropellerbladex.py @@ -111,46 +111,23 @@ def __init__(self, filename, radii_list, num_points_top_bottom): def _build_intersection_cylinder_blade(self): - """ - Private method that constructs the section lines which are the intersections - between the cylinder at a fixed radius and the blade, and the camber points. - """ - # Construction of the section lines between two shapes (in this case the - # blade and the lateral face of the cylinder) - section_builder = BRepAlgoAPI_Section(self.blade_solid, - self.cylinder_lateral_face, False) - # Define and build the parametric 2D curve (pcurve) for the section lines defined above - section_builder.ComputePCurveOn2(True) - section_builder.Build() - self.section = section_builder.Shape() - wire_maker = BRepBuilderAPI_MakeWire() + super()._build_intersection_cylinder_blade() wire_maker_top = BRepBuilderAPI_MakeWire() wire_maker_bottom = BRepBuilderAPI_MakeWire() - - edgeList = TopTools_ListOfShape() edgeList_top = TopTools_ListOfShape() edgeList_bottom = TopTools_ListOfShape() - edgeExplorer = TopExp_Explorer(self.section, TopAbs_EDGE) edgeCount = 0 + edgeExplorer = TopExp_Explorer(self.section, TopAbs_EDGE) while edgeExplorer.More(): edgeCount = edgeCount + 1 # Numbering from 1 in OCC edge = edgeExplorer.Current() - edgeList.Append(edge) if edgeCount % 2 == 1: edgeList_top.Append(edge) else: edgeList_bottom.Append(edge) edgeExplorer.Next() - # Total sectional curve - wire_maker.Add(edgeList) - self.wire = wire_maker.Wire() - self.section_wires_list.append(self.wire) - self.curve_adaptor = BRepAdaptor_CompCurve( - OCC.Core.TopoDS.topods.Wire(self.wire)) - self.total_section_length = GCPnts_AbscissaPoint.Length( - self.curve_adaptor) - # Top part + # Top part of section wire_maker_top.Add(edgeList_top) self.wire_top = wire_maker_top.Wire() self.curve_adaptor_top = BRepAdaptor_CompCurve( @@ -165,6 +142,61 @@ def _build_intersection_cylinder_blade(self): self.total_section_bottom_length = GCPnts_AbscissaPoint.Length( self.curve_adaptor_bottom) + # def _build_intersection_cylinder_blade(self): + # """ + # Private method that constructs the section lines which are the intersections + # between the cylinder at a fixed radius and the blade, and the camber points. + # """ + # # Construction of the section lines between two shapes (in this case the + # # blade and the lateral face of the cylinder) + # section_builder = BRepAlgoAPI_Section(self.blade_solid, + # self.cylinder_lateral_face, False) + # # Define and build the parametric 2D curve (pcurve) for the section lines defined above + # section_builder.ComputePCurveOn2(True) + # section_builder.Build() + # self.section = section_builder.Shape() + # wire_maker = BRepBuilderAPI_MakeWire() + # wire_maker_top = BRepBuilderAPI_MakeWire() + # wire_maker_bottom = BRepBuilderAPI_MakeWire() + + # edgeList = TopTools_ListOfShape() + # edgeList_top = TopTools_ListOfShape() + # edgeList_bottom = TopTools_ListOfShape() + # edgeExplorer = TopExp_Explorer(self.section, TopAbs_EDGE) + # edgeCount = 0 + # while edgeExplorer.More(): + # edgeCount = edgeCount + 1 # Numbering from 1 in OCC + # edge = edgeExplorer.Current() + # edgeList.Append(edge) + # if edgeCount % 2 == 1: + # edgeList_top.Append(edge) + # else: + # edgeList_bottom.Append(edge) + # edgeExplorer.Next() + + # # Total sectional curve + # wire_maker.Add(edgeList) + # self.wire = wire_maker.Wire() + # self.section_wires_list.append(self.wire) + # self.curve_adaptor = BRepAdaptor_CompCurve( + # OCC.Core.TopoDS.topods.Wire(self.wire)) + # self.total_section_length = GCPnts_AbscissaPoint.Length( + # self.curve_adaptor) + # # Top part + # wire_maker_top.Add(edgeList_top) + # self.wire_top = wire_maker_top.Wire() + # self.curve_adaptor_top = BRepAdaptor_CompCurve( + # OCC.Core.TopoDS.topods.Wire(self.wire_top)) + # self.total_section_top_length = GCPnts_AbscissaPoint.Length( + # self.curve_adaptor_top) + # # Bottom part + # wire_maker_bottom.Add(edgeList_bottom) + # self.wire_bottom = wire_maker_bottom.Wire() + # self.curve_adaptor_bottom = BRepAdaptor_CompCurve( + # OCC.Core.TopoDS.topods.Wire(self.wire_bottom)) + # self.total_section_bottom_length = GCPnts_AbscissaPoint.Length( + # self.curve_adaptor_bottom) + def _camber_curve(self, radius): """ From 5848425826e947a5e143d467dd97aca582e833e3 Mon Sep 17 00:00:00 2001 From: Davide Oberto Date: Fri, 6 Mar 2026 09:33:02 +0100 Subject: [PATCH 2/2] Cleaned the code --- bladex/reversepropeller/reversepropeller.py | 33 -------- .../reversepropellerbladex.py | 77 ------------------- 2 files changed, 110 deletions(-) diff --git a/bladex/reversepropeller/reversepropeller.py b/bladex/reversepropeller/reversepropeller.py index 927ae35..763fba5 100644 --- a/bladex/reversepropeller/reversepropeller.py +++ b/bladex/reversepropeller/reversepropeller.py @@ -153,39 +153,6 @@ def __init__(self, filename, radii_list, num_points_top_bottom): ind_sec = ind_sec + 1 - # def _build_intersection_cylinder_blade(self): - # """ - # Private method that constructs the section lines which are the intersections - # between the cylinder at a fixed radius and the blade, and the camber points. - # """ - # # Construction of the section lines between two shapes (in this case the - # # blade and the lateral face of the cylinder) - # section_builder = BRepAlgoAPI_Section(self.blade_solid, - # self.cylinder_lateral_face, False) - # # Define and build the parametric 2D curve (pcurve) for the section lines defined above - # section_builder.ComputePCurveOn2(True) - # section_builder.Build() - # self.section = section_builder.Shape() - # edgeExplorer = TopExp_Explorer(self.section, TopAbs_EDGE) - # wire_maker = BRepBuilderAPI_MakeWire() - - # edgeCount = 0 - # edgeList = TopTools_ListOfShape() - # while edgeExplorer.More(): - # edgeCount = edgeCount + 1 # Numbering from 1 in OCC - # edge = topods.Edge(edgeExplorer.Current()) - # edgeList.Append(edge) - # edgeExplorer.Next() - # wire_maker.Add(edgeList) - # self.wire = wire_maker.Wire() - # self.section_wires_list.append(self.wire) - # self.curve_adaptor = BRepAdaptor_CompCurve( - # OCC.Core.TopoDS.topods.Wire(self.wire)) - # # Length of the curve section (ascissa curvilinea) - # self.total_section_length = GCPnts_AbscissaPoint.Length( - # self.curve_adaptor) - - def _camber_points(self, radius): """ Private method which computes the single points of the camber curve and diff --git a/bladex/reversepropeller/reversepropellerbladex.py b/bladex/reversepropeller/reversepropellerbladex.py index 3df6d16..43d5c5a 100644 --- a/bladex/reversepropeller/reversepropellerbladex.py +++ b/bladex/reversepropeller/reversepropellerbladex.py @@ -73,28 +73,7 @@ def __init__(self, filename, radii_list, num_points_top_bottom): self.trailing_edge_point_on_plane = [] self.param_plane_points = [] self.orig_param_plane_points = [] - # points = [] self._camber_curve(radius) - # for i in range(len(self.vor_us)): - # x, y, z = self.vor_us[i], radius*np.sin(self.vor_vs[i]/radius), radius*np.cos(self.vor_vs[i]/radius) - # pnt = gp_Pnt(float(x), float(y), float(z)) - # points.append(BRepBuilderAPI_MakeVertex(pnt).Vertex()) - # self._camber_curve(radius) - if False: - display, start_display, add_menu, add_function_to_menu = init_display() - # display.DisplayShape(self.blade_solid, update=True) - display.DisplayShape(self.cylinder, update=True) - display.DisplayShape(self.wire_top, color="RED", update=True) - display.DisplayShape(self.wire_bottom, color="BLUE", update=True) - # display.DisplayShape(self.chord_wire, color="ORANGE", update=True) - display.DisplayShape(self.full_camber_wire, color="GREEN", update=True) - display.DisplayShape(self.leading_edge, color="BLACK", update=True) - display.DisplayShape(self.trailing_edge, color="MAGENTA", update=True) - # display.DisplayShape(self.chord_plane, update=True) - display.DisplayShape(self.chord_point, update=True) - display.DisplayShape(self.trimmed_edge, color="BLACK", update=True) - # display.DisplayShape(points, update=True) - start_display() self._initial_leading_trailing_edges_plane(radius) self._initial_camber_points_plane(radius) self._initial_airfoil_points_plane(radius) @@ -142,62 +121,6 @@ def _build_intersection_cylinder_blade(self): self.total_section_bottom_length = GCPnts_AbscissaPoint.Length( self.curve_adaptor_bottom) - # def _build_intersection_cylinder_blade(self): - # """ - # Private method that constructs the section lines which are the intersections - # between the cylinder at a fixed radius and the blade, and the camber points. - # """ - # # Construction of the section lines between two shapes (in this case the - # # blade and the lateral face of the cylinder) - # section_builder = BRepAlgoAPI_Section(self.blade_solid, - # self.cylinder_lateral_face, False) - # # Define and build the parametric 2D curve (pcurve) for the section lines defined above - # section_builder.ComputePCurveOn2(True) - # section_builder.Build() - # self.section = section_builder.Shape() - # wire_maker = BRepBuilderAPI_MakeWire() - # wire_maker_top = BRepBuilderAPI_MakeWire() - # wire_maker_bottom = BRepBuilderAPI_MakeWire() - - # edgeList = TopTools_ListOfShape() - # edgeList_top = TopTools_ListOfShape() - # edgeList_bottom = TopTools_ListOfShape() - # edgeExplorer = TopExp_Explorer(self.section, TopAbs_EDGE) - # edgeCount = 0 - # while edgeExplorer.More(): - # edgeCount = edgeCount + 1 # Numbering from 1 in OCC - # edge = edgeExplorer.Current() - # edgeList.Append(edge) - # if edgeCount % 2 == 1: - # edgeList_top.Append(edge) - # else: - # edgeList_bottom.Append(edge) - # edgeExplorer.Next() - - # # Total sectional curve - # wire_maker.Add(edgeList) - # self.wire = wire_maker.Wire() - # self.section_wires_list.append(self.wire) - # self.curve_adaptor = BRepAdaptor_CompCurve( - # OCC.Core.TopoDS.topods.Wire(self.wire)) - # self.total_section_length = GCPnts_AbscissaPoint.Length( - # self.curve_adaptor) - # # Top part - # wire_maker_top.Add(edgeList_top) - # self.wire_top = wire_maker_top.Wire() - # self.curve_adaptor_top = BRepAdaptor_CompCurve( - # OCC.Core.TopoDS.topods.Wire(self.wire_top)) - # self.total_section_top_length = GCPnts_AbscissaPoint.Length( - # self.curve_adaptor_top) - # # Bottom part - # wire_maker_bottom.Add(edgeList_bottom) - # self.wire_bottom = wire_maker_bottom.Wire() - # self.curve_adaptor_bottom = BRepAdaptor_CompCurve( - # OCC.Core.TopoDS.topods.Wire(self.wire_bottom)) - # self.total_section_bottom_length = GCPnts_AbscissaPoint.Length( - # self.curve_adaptor_bottom) - - def _camber_curve(self, radius): """ Computation of the camber points. We get the chord, move along it and fint the intersection