def get_geomentry_table(self): table = Table() table.insert_row([ "", "Ribs", "Chord", "X", "Y", "%", "Arc", "Arc_diff", "AOA", "Z-rotation", "Y-rotation", "profile-merge", "ballooning-merge" ]) shape = self.shape.get_half_shape() for rib_no in range(self.shape.half_rib_num): table[1 + rib_no, 1] = rib_no + 1 for rib_no, chord in enumerate(shape.chords): table[1 + rib_no, 2] = chord for rib_no, p in enumerate(self.shape.baseline): table[1 + rib_no, 3] = p[0] table[1 + rib_no, 4] = p[1] table[1 + rib_no, 5] = self.shape.baseline_pos last_angle = 0 for cell_no, angle in enumerate(self.get_arc_angles()): angle = angle * 180 / math.pi table[1 + cell_no, 6] = angle table[1 + cell_no, 7] = angle - last_angle last_angle = angle for rib_no, aoa in enumerate(self.get_aoa()): table[1 + rib_no, 8] = aoa * 180 / math.pi table[1 + rib_no, 9] = 0 table[1 + rib_no, 10] = 0 return table
def get_table(self): table = Table() for i, p in enumerate(self): for j, coord in enumerate(p): table.set(j, i, coord) return table
def set_airfoils(self): table = Table() for airfoil in self.glider2d.profiles: x = [p[0] for p in airfoil] y = [p[1] for p in airfoil] x.insert(0, airfoil.name) y.insert(0, "") table.add_columns(x, y) self.sheets["Airfoils"] = table
def get_attachment_point_table(self): nodes = self.get_upper_nodes() node_groups = {} num_cells = 0 tables = [] # sort by layer for node in nodes: match = self.regex_node.match(node.name) if match: layer_name = match.group(1) else: layer_name = "none" node_groups.setdefault(layer_name, []) node_groups[layer_name].append(node) num_cells = max(num_cells, node.cell_no) groups = list(node_groups.keys()) # per layer table def sorted(x): res = 0 for i, character in enumerate(x[::-1]): res += (26**i) * (ord(character) - 64) return res groups.sort(key=sorted) for key in groups: table = Table() group_nodes = node_groups[key] for cell_no in range(num_cells): cell_nodes = filter(lambda n: n.cell_no == cell_no, group_nodes) for i, node in enumerate(cell_nodes): # name, cell_pos, rib_pos, force table[0, 4 * i] = "ATP" table[cell_no + 1, 4 * i] = node.name table[cell_no + 1, 4 * i + 1] = node.cell_pos table[cell_no + 1, 4 * i + 2] = node.rib_pos table[cell_no + 1, 4 * i + 3] = node.force tables.append(table) total_table = Table() for table in tables: total_table.append_right(table) return total_table
def set_balloonings(self): table = Table() for ballooning in self.glider2d.balloonings: upper = ballooning.controlpoints[0] lower = ballooning.controlpoints[1] x = [p[0] for p in upper + lower] y = [p[1] for p in upper + lower] x.insert(0, ballooning.name or "ballooning") y.insert(0, "") table.add_columns(x, y) self.sheets["Balloonings"] = table
def get_table(self, start_node=None): line_tree = self.create_tree(start_node=start_node) table = Table() floors = max(self.floors) def insert_block(line, upper, row, column): length = round(line.get_stretched_length() * 1000) table.set(column, row, length) table.set(column + floors + 3, row, line.type.name) if upper: for line, line_upper in upper: row = insert_block(line, line_upper, row, column - 1) else: # Insert a top node name = line.upper_node.name if not name: name = "XXX" table.set(column - 1, row, name) table.set(column + 2 + floors, row, name) row += 1 return row row = 1 for line, upper in line_tree: row = insert_block(line, upper, row, floors) return table
def get_input_table(self): table = Table() def insert_block(line, upper, row, column): table[row, column + 1] = line.line_type.name if upper: table[row, column] = round(line.target_length, 3) for line, line_upper in upper: row = insert_block(line, line_upper, row, column + 2) else: # Insert a top node name = line.upper_node.name if not name: name = "Rib_{}/{}".format(line.upper_node.rib_no, line.upper_node.rib_pos) table[row, column] = name row += 1 return row row = 0 for node in self.get_lower_attachment_points(): tree = self.create_tree(node) table[row, 0] = node.name for line, upper in tree: row = insert_block(line, upper, row, 1) return table
def __init__(self, glider2d): self.glider2d = glider2d self.sheets = collections.OrderedDict([("Geometry", Table()), ("Cell Elements", Table()), ("Rib Elements", Table()), ("Airfoils", Table()), ("Balloonings", Table()), ("Parametric", Table()), ("Lines", Table()), ("Data", Table())])
def get_table_2(self): line_tree = self.create_tree() table = Table() def insert_block(line, upper, row, column): length = round(line.get_stretched_length() * 1000) table[row, column] = line.name table[row, column + 1] = line.type.name table[row, column + 2] = length if upper: for line, line_upper in upper: row = insert_block(line, line_upper, row, column + 4) else: # Insert a top node row += 1 return row row = 1 for line, upper in sorted(line_tree, key=(lambda x: x[0].name)): row = insert_block(line, upper, row, 0) return table
def add_column(cell_no): cuts_this = cuts_per_cell[cell_no] if not cuts_this: return False cut = cuts_this[0] column = Table() column[0, 0] = cut[2] column.insert_row(cut[:2], cell_no + 1) cuts_this.remove(cut) for cell_no_temp in range(cell_no + 1, cell_num): cut_next = find_next(cut, cell_no_temp) if not cut_next: break column.insert_row(cut_next[:2], cell_no_temp) cut = cut_next cuts_table.append_right(column) return column
def set_parametric(self): table = Table() table.add_columns( *self._transpose_columns(self.glider2d.arc.curve, "Arc")) table.add_columns( *self._transpose_columns(self.glider2d.shape.front_curve, "Front")) table.add_columns( *self._transpose_columns(self.glider2d.shape.back_curve, "Back")) table.add_columns(*self._transpose_columns( self.glider2d.shape.rib_distribution, "Dist")) table.add_columns(*self._transpose_columns(self.glider2d.aoa, "AOA")) table.add_columns(*self._transpose_columns( self.glider2d.profile_merge_curve, "Profile_merge")) table.add_columns(*self._transpose_columns( self.glider2d.ballooning_merge_curve, "Ballooning_merge")) self.sheets["Parametric"] = table
def get_cell_sheet(glider): cell_num = glider.shape.half_cell_num row_num = glider.shape.half_cell_num table = Table() for i in range(1, row_num + 1): table[i, 0] = str(i) elems = glider.elements table.append_right(glider.lineset.get_attachment_point_table()) # cuts cuts_table = Table() cuts_per_cell = [] for cell_no in range(cell_num): cuts_this = [] for cut in elems["cuts"]: if cell_no in cut["cells"]: cuts_this.append((cut["left"], cut["right"], cut["type"])) cuts_this.sort(key=lambda x: sum(x[:2])) cuts_per_cell.append(cuts_this) def find_next(cut, cell_no): cuts_this = cuts_per_cell[cell_no] for new_cut in cuts_this: if cut[1] == new_cut[0] and new_cut[2] == cut[2]: cuts_this.remove(new_cut) return new_cut def add_column(cell_no): cuts_this = cuts_per_cell[cell_no] if not cuts_this: return False cut = cuts_this[0] column = Table() column[0, 0] = cut[2] column.insert_row(cut[:2], cell_no + 1) cuts_this.remove(cut) for cell_no_temp in range(cell_no + 1, cell_num): cut_next = find_next(cut, cell_no_temp) if not cut_next: break column.insert_row(cut_next[:2], cell_no_temp) cut = cut_next cuts_table.append_right(column) return column for cell_no in range(cell_num): while add_column(cell_no): pass table.append_right(cuts_table) # Diagonals for diagonal in elems["diagonals"]: diagonal_table = Table() diagonal = copy.copy(diagonal) diagonal_table[0, 0] = "QR" cells = diagonal.pop("cells") _diagonal = DiagonalRib(**diagonal) for cell_no in cells: # center_left, center_right, width_left, width_right, height_left, height_right diagonal_table[cell_no + 1, 0] = _diagonal.center_left diagonal_table[cell_no + 1, 1] = _diagonal.center_right diagonal_table[cell_no + 1, 2] = _diagonal.width_left diagonal_table[cell_no + 1, 3] = _diagonal.width_right diagonal_table[cell_no + 1, 4] = _diagonal.left_front[1] diagonal_table[cell_no + 1, 5] = _diagonal.right_front[1] table.append_right(diagonal_table) # Straps for strap in elems["straps"]: strap_table = Table() strap_table[0, 0] = "STRAP" for cell_no in strap["cells"]: strap_table[cell_no + 1, 0] = (strap["left_front"][0] + strap["left_back"][0]) / 2 strap_table[cell_no + 1, 1] = (strap["right_front"][0] + strap["right_back"][0]) / 2 strap_table[cell_no + 1, 2] = 0.04 table.append_right(strap_table) # Material material_table = Table() for cell_no, cell in enumerate(elems["materials"]): for part_no, part in enumerate(cell): material_table[cell_no + 1, part_no] = part for part_no in range(material_table.num_columns): material_table[0, part_no] = "MATERIAL" table.append_right(material_table) return table
def import_ods_2d(Glider2D, filename, numpoints=4, calc_lineset_nodes=False): ods = ezodf.opendoc(filename) sheets = ods.sheets cell_sheet = sheets[1] rib_sheet = sheets[2] # file-version if cell_sheet[0, 0].value == "V2" or cell_sheet[0, 0].value == "V2": file_version = 2 else: file_version = 1 # ------------ # profiles = [BezierProfile2D(profile) for profile in transpose_columns(sheets[3])] profiles = [ Profile2D(profile, name) for name, profile in transpose_columns(sheets[3]) ] for foil in profiles: foil.normalize() try: geometry = get_geometry_parametric(sheets[5]) except Exception: geometry = get_geometry_explicit(sheets[0]) balloonings = [] for i, (name, baloon) in enumerate(transpose_columns(sheets[4])): ballooning_type = str(sheets[4][0, 2 * i + 1].value).upper() if baloon: if ballooning_type == "V1": i = 0 while baloon[i + 1][0] > baloon[i][0]: i += 1 upper = baloon[:i + 1] lower = [(x, -y) for x, y in baloon[i + 1:]] balloonings.append(BallooningBezier(upper, lower, name=name)) elif ballooning_type == "V2": i = 0 while baloon[i + 1][0] > baloon[i][0]: i += 1 upper = baloon[:i + 1] lower = baloon[i + 1:] balloonings.append(BallooningBezier(upper, lower, name=name)) elif ballooning_type == "V3": balloonings.append(BallooningBezierNeu(baloon)) else: raise ValueError("No ballooning type specified") data = {} datasheet = sheets[-1] assert isinstance(datasheet, ezodf.Sheet) for row in datasheet.rows(): if len(row) > 1: data[row[0].value] = row[1].value # Attachment points: rib_no, id, pos, force attachment_points = get_attachment_points(rib_sheet, cell_sheet) attachment_points_lower = get_lower_aufhaengepunkte(data) # RIB HOLES rib_hole_keywords = ["ribs", "pos", "size"] rib_holes = read_elements(rib_sheet, "QUERLOCH", len_data=2) rib_holes = to_dct(rib_holes, rib_hole_keywords) rib_holes = group(rib_holes, "ribs") rigidfoil_keywords = ["ribs", "start", "end", "distance"] rigidfoils = read_elements(rib_sheet, "RIGIDFOIL", len_data=3) rigidfoils = to_dct(rigidfoils, rigidfoil_keywords) rigidfoils = group(rigidfoils, "ribs") # CUTS def get_cuts(names, target_name): objs = [] for name_src in names: objs += read_elements(cell_sheet, name_src, len_data=2) cuts_this = [{ "cells": cut[0], "left": float(cut[1]), "right": float(cut[2]), "type": target_name } for cut in objs] return group(cuts_this, "cells") cuts = get_cuts(["EKV", "EKH", "folded"], "folded") cuts += get_cuts(["DESIGNM", "DESIGNO", "orthogonal"], "orthogonal") cuts += get_cuts(["singleskin"], "singleskin") # Diagonals: center_left, center_right, width_l, width_r, height_l, height_r diagonals = [] for res in read_elements(cell_sheet, "QR", len_data=6): height1 = res[5] height2 = res[6] # migration if file_version == 1: # height (0,1) -> (-1,1) height1 = height1 * 2 - 1 height2 = height2 * 2 - 1 # --------- diagonals.append({ "left_front": (res[1] - res[3] / 2, height1), "left_back": (res[1] + res[3] / 2, height1), "right_front": (res[2] - res[4] / 2, height2), "right_back": (res[2] + res[4] / 2, height2), "cells": res[0] }) diagonals = group(diagonals, "cells") straps = [] straps_keywords = ["cells", "left", "right"] for res in read_elements(cell_sheet, "VEKTLAENGE", len_data=2): straps.append({ "left_front": (res[1] - 0.02, -1), "left_back": (res[1] + 0.02, -1), "right_front": (res[1] - 0.02, -1), "right_back": (res[1] - 0.02, -1), "cells": res[0] }) for res in read_elements(cell_sheet, "STRAP", len_data=3): # [cell_no, x_left, x_right, width] straps.append({ "left_front": (res[1] - res[3] / 2, -1), "left_back": (res[1] + res[3] / 2, -1), "right_front": (res[2] - res[3] / 2, -1), "right_back": (res[2] + res[3] / 2, -1), "cells": res[0] }) straps = group(straps, "cells") materials = get_material_codes(cell_sheet) # minirib -> y, start (x) miniribs = [] for minirib in read_elements(cell_sheet, "MINIRIB", len_data=2): miniribs.append({ "yvalue": minirib[1], "front_cut": minirib[2], "cells": minirib[0] }) miniribs = group(miniribs, "cells") lineset_table = Table.from_ods_sheet(sheets[6]) lineset = LineSet2D.read_input_table(lineset_table, attachment_points_lower, attachment_points) glider_2d = Glider2D(elements={ "cuts": cuts, "holes": rib_holes, "diagonals": diagonals, "rigidfoils": rigidfoils, "straps": straps, "materials": materials, "miniribs": miniribs }, profiles=profiles, balloonings=balloonings, lineset=lineset, speed=data["SPEED"], glide=data["GLIDE"], **geometry) if calc_lineset_nodes: glider_3d = glider_2d.get_glider_3d() glider_2d.lineset.set_default_nodes2d_pos(glider_3d) return glider_2d