예제 #1
0
    def add_simple_hole_from_offset(self, thickness):
        """

        :param float or int thickness: wall_thickenss in mm
        :return:
        """
        logger = logging.getLogger(__name__)
        # path = prim.Path(prim.GeometricFunctions.offset_curve(self.get_path(), thickness, dir=1, divisions=1))
        path = copy.deepcopy(self.get_path())
        path = prim.GeometricFunctions.clean_intersections(
            prim.GeometricFunctions.parallel_curve(path, thickness, 1, False),
            path, thickness)
        self.holes = [CrossSection(prim.Path(path))]
예제 #2
0
    def slice_into_cross_sections(self, origin_plane, spacing, length):
        """

        :param Plane origin_plane:
        :param float spacing:
        :return:
        """
        self.trimesh_cross_sections = list()
        heights = list()
        for i in range(length):
            heights.append(spacing * i)
        origin = np.array(origin_plane.origin)
        normal = np.array(origin_plane.normal)
        sections = self.mesh.section_multiplane(plane_origin=origin,
                                                plane_normal=normal,
                                                heights=heights)
        if sections is not None:
            self.trimesh_cross_sections.extend(sections)
            self.cross_sections = list()
            for section in sections:
                points = list()
                for ind in range(0, len(section.discrete[0])):
                    points.append(
                        prim.Point(section.discrete[0][ind][0],
                                   section.discrete[0][ind][1], 0))
                path = prim.GeometricFunctions.normalize_path_points(
                    PointManip.reorder_2d_cw(points, method=1), 516)
                self.cross_sections.append(
                    CrossSection(section_list=[prim.Path(path)]))
                self.logger.debug('section: %s', self.cross_sections[-1])

            self.center_cross_sections()
            self.close_sections()
        else:
            raise AttributeError(
                'Error: Plane with origin(%s) does not intersect the STL' %
                origin_plane.origin)
예제 #3
0
 def close_sections(self):
     for ind in range(0, len(self.cross_sections)):
         self.cross_sections[ind] = CrossSection(
             prim.Path(
                 prim.GeometricFunctions.close_path(
                     self.cross_sections[ind].get_path())))
예제 #4
0
    def create_cut_path_from_wing(wing, wire_cutter, debug_kerf=False):
        """

        :param WingSegment wing:
        :param WireCutter wire_cutter:
        :return:
        """
        logger = logging.getLogger(__name__)

        if not wing.prepped:
            raise ValueError('Error: Wing has not been prepped for slicing')

        cut_path = CutPath([], [])
        root_foil = copy.deepcopy(wing.root_airfoil)
        tip_foil = copy.deepcopy(wing.tip_airfoil)

        if wire_cutter.kerf is not None:
            if wing.root_chord > wing.tip_chord:
                kerf_root = wire_cutter.kerf
                kerf_tip = wire_cutter.kerf * wing.root_chord / wing.tip_chord
            else:
                kerf_root = wire_cutter.kerf * wing.root_chord / wing.tip_chord
                kerf_tip = wire_cutter.kerf
            if debug_kerf:
                prim.GeometricFunctions.plot_path(root_foil, 1)
                prim.GeometricFunctions.plot_path(tip_foil, 2)

            root_foil = prim.GeometricFunctions.offset_curve(root_foil,
                                                             kerf_root,
                                                             dir=0,
                                                             divisions=2)
            tip_foil = prim.GeometricFunctions.offset_curve(tip_foil,
                                                            kerf_tip,
                                                            dir=0,
                                                            divisions=2)

            leading_edge_root = prim.GeometricFunctions.get_point_from_min_coord(
                root_foil, 'x')
            leading_edge_tip = prim.GeometricFunctions.get_point_from_min_coord(
                tip_foil, 'x')

            offset = leading_edge_root['x'] if leading_edge_root[
                'x'] < leading_edge_tip['x'] else leading_edge_tip['x']
            if offset < 0:
                PointManip.Transform.translate(root_foil, [-offset, 0, 0])
                PointManip.Transform.translate(tip_foil, [-offset, 0, 0])

            if debug_kerf:
                prim.GeometricFunctions.plot_path(root_foil, 3)
                prim.GeometricFunctions.plot_path(tip_foil, 4)

                plt.legend([
                    'Root Foil', 'Tip Foil',
                    'Root Foil with %smm kerf' % kerf_root,
                    'Tip Foil with %smm kerf' % kerf_tip
                ])
                plt.axis('equal')
                plt.show()

        root_z = root_foil[0]['z']
        tip_z = tip_foil[0]['z']
        logger.debug('Root: %s | Tip: %s' % (root_foil[0], tip_foil[0]))

        start_point1 = prim.Point(0, 0, root_z)
        start_point2 = prim.Point(0, 0, tip_z)
        next_point1 = start_point1 + prim.Point(0, wire_cutter.start_height, 0)
        next_point2 = start_point2 + prim.Point(0, wire_cutter.start_height, 0)
        logger.debug('sp1: %s | sp2: %s | np1: %s | np2: %s' %
                     (start_point1, start_point2, next_point1, next_point2))

        seg_link1 = prim.SectionLink(start_point1, next_point1, fast_cut=True)
        seg_link2 = prim.SectionLink(start_point2, next_point2, fast_cut=True)

        cut_path.add_segment_to_cut_lists(segment_1=seg_link1,
                                          segment_2=seg_link2)

        start_point1 = next_point1
        start_point2 = next_point2
        next_point1 = start_point1 + prim.Point(wire_cutter.start_depth, 0, 0)
        # The start depth of the second axis needs to be offset by the difference between the two foils positioning,
        # this is to account for sweep in the wing
        next_point2 = start_point2 + prim.Point(
            wire_cutter.start_depth -
            (root_foil[0]['x'] - tip_foil[0]['x']), 0, 0)
        logger.debug('sp1: %s | sp2: %s | np1: %s | np2: %s' %
                     (start_point1, start_point2, next_point1, next_point2))

        test_line = prim.Line.line_from_points(next_point1, next_point2)
        p1 = test_line.get_extrapolated_point(0, constraint_dim='z')
        p2 = test_line.get_extrapolated_point(wire_cutter.wire_length,
                                              constraint_dim='z')

        if p1['x'] < wire_cutter.start_depth or p2[
                'x'] < wire_cutter.start_depth:
            offset = max(wire_cutter.start_depth - p1['x'],
                         wire_cutter.start_depth - p2['x'])
            next_point1 += prim.Point(offset, 0, 0)
            next_point2 += prim.Point(offset, 0, 0)

        # Translate both airfoils by the same offset to keep them inline
        logger.debug('Next Point X: %s', next_point1['x'])
        PointManip.Transform.translate(root_foil,
                                       [next_point1['x'], next_point1['y'], 0])
        PointManip.Transform.translate(tip_foil,
                                       [next_point1['x'], next_point1['y'], 0])
        logger.debug('Root Airfoil Leading Edge: %s', root_foil[0])

        next_point1 += root_foil[0] - next_point1
        logger.debug('Next Point X after offset: %s', next_point1['x'])
        next_point2 += tip_foil[0] - next_point2
        logger.debug('Root Airfoil Leading Edge: %s', root_foil[0])

        seg_link1 = prim.SectionLink(start_point1, next_point1, fast_cut=False)
        seg_link2 = prim.SectionLink(start_point2, next_point2, fast_cut=False)

        cut_path.add_segment_to_cut_lists(segment_1=seg_link1,
                                          segment_2=seg_link2)

        root_ind_split = prim.GeometricFunctions.get_index_max_coord(
            root_foil, 'x')
        tip_ind_split = prim.GeometricFunctions.get_index_max_coord(
            tip_foil, 'x')

        top_root = root_foil[0:root_ind_split + 1]
        bottom_root = [root_foil[0]]
        bottom_root.extend(
            sorted(root_foil[root_ind_split:-1], key=lambda point: point['x']))

        top_tip = tip_foil[0:tip_ind_split + 1]
        bottom_tip = [tip_foil[0]]
        bottom_tip.extend(
            sorted(tip_foil[tip_ind_split:-1], key=lambda point: point['x']))

        cut_path.add_segment_to_cut_lists(CrossSection(prim.Path(top_root)),
                                          CrossSection(prim.Path(top_tip)))

        start_point1 = top_root[-1]
        start_point2 = top_tip[-1]
        logger.debug('TE of Top Root: %s | TE of Top Tip: %s' %
                     (start_point1, start_point2))
        next_point1, next_point2 = CutPath._add_loopback(
            cut_path, wire_cutter, root_z, tip_z)

        start_point1 = next_point1
        start_point2 = next_point2
        next_point1 = start_point1 + prim.Point(wire_cutter.start_depth, 0, 0)
        next_point2 = start_point2 + prim.Point(
            wire_cutter.start_depth -
            (root_foil[0]['x'] - tip_foil[0]['x']), 0, 0)
        logger.debug('sp1: %s | sp2: %s | np1: %s | np2: %s' %
                     (start_point1, start_point2, next_point1, next_point2))

        test_line = prim.Line.line_from_points(next_point1, next_point2)
        p1 = test_line.get_extrapolated_point(0, constraint_dim='z')
        p2 = test_line.get_extrapolated_point(wire_cutter.wire_length,
                                              constraint_dim='z')

        if p1['x'] < wire_cutter.start_depth or p2[
                'x'] < wire_cutter.start_depth:
            offset = max(wire_cutter.start_depth - p1['x'],
                         wire_cutter.start_depth - p2['x'])
            next_point1 += prim.Point(offset, 0, 0)
            next_point2 += prim.Point(offset, 0, 0)

        next_point1 += root_foil[0] - next_point1
        logger.debug('Next Point X after offset: %s', next_point1['x'])
        next_point2 += tip_foil[0] - next_point2
        logger.debug('Root Airfoil Leading Edge: %s', root_foil[0])

        seg_link1 = prim.SectionLink(start_point1, next_point1, fast_cut=False)
        seg_link2 = prim.SectionLink(start_point2, next_point2, fast_cut=False)

        cut_path.add_segment_to_cut_lists(segment_1=seg_link1,
                                          segment_2=seg_link2)

        cut_path.add_segment_to_cut_lists(CrossSection(prim.Path(bottom_root)),
                                          CrossSection(prim.Path(bottom_tip)))

        CutPath._add_loopback(cut_path, wire_cutter, root_z, tip_z)

        return cut_path
예제 #5
0
    def subdivide(self, num_sections):
        """

        :param int num_sections:
        :return:
        """
        ret_val = list()
        if num_sections < 2:
            ret_val = [self]
        else:

            center = prim.Point(0, 0, 0)
            points1, points2 = self.get_path()

            start_point1 = points1[0]
            start_point2 = points2[0]

            for point in points1:
                center += point
            center /= len(points1)
            hole1, hole2 = self.section1.get_path_hole(
            ), self.section2.get_path_hole()

            if hole1 is not None:
                start_point1_hole = hole1[0]
                start_point2_hole = hole2[0]
            else:
                start_point1_hole = None
                start_point2_hole = None

            for index in range(num_sections):
                curr_section1 = list()
                curr_section2 = list()
                arc_len = 360 / num_sections
                upper_range = arc_len * (index + 1)
                lower_range = arc_len * index
                for point in points1:
                    theta = (np.rad2deg(
                        np.arctan2(point['y'] - center['y'],
                                   point['x'] - center['x'])) + 180) % 360
                    if lower_range < theta <= upper_range:
                        curr_section1.append(point)
                if hole1 is not None:
                    tmp_list = list()
                    for point in hole1:
                        theta = (np.rad2deg(
                            np.arctan2(point['y'] - center['y'],
                                       point['x'] - center['x'])) + 180) % 360
                        if lower_range < theta <= upper_range:
                            tmp_list.append(point)
                    for point in reversed(tmp_list):
                        curr_section1.append(point)
                else:
                    curr_section1.append(prim.Point(0, 0, 0))

                for point in points2:
                    theta = (np.rad2deg(
                        np.arctan2(point['y'] - center['y'],
                                   point['x'] - center['x'])) + 180) % 360
                    if lower_range < theta <= upper_range:
                        curr_section2.append(point)
                if hole2 is not None:
                    tmp_list = list()
                    for point in hole2:
                        theta = (np.rad2deg(
                            np.arctan2(point['y'] - center['y'],
                                       point['x'] - center['x'])) + 180) % 360
                        if lower_range < theta <= upper_range:
                            tmp_list.append(point)
                    for point in reversed(tmp_list):
                        curr_section2.append(point)
                else:
                    curr_section2.append(prim.Point(0, 0, 0))

                if start_point1 in curr_section1:
                    path1 = prim.GeometricFunctions.close_path(
                        PointManip.reorder_2d_cw(curr_section1, method=2))
                    path2 = prim.GeometricFunctions.close_path(
                        PointManip.reorder_2d_cw(curr_section2, method=2))
                else:
                    path1 = prim.GeometricFunctions.close_path(curr_section1)
                    path2 = prim.GeometricFunctions.close_path(curr_section2)

                ret_val.append(
                    CrossSectionPair(section1=CrossSection(prim.Path(path1)),
                                     section2=CrossSection(prim.Path(path2))))

        return ret_val