예제 #1
0
    def duplicate(self, name, features, quantity, distance, squantity, primary,
                  secondary, body):

        if not primary or not primary.isValid:
            raise PrimaryAxisMissing

        entities = ObjectCollection.create()
        for feature in features:
            entities.add(feature)

        patterns = body.parentComponent.features.rectangularPatternFeatures

        quantity = vi.createByReal(quantity)
        distance = vi.createByReal(distance)

        input_ = patterns.createInput(entities, primary, quantity, distance,
                                      EDT)
        # input_.patternComputeOption = pco.IdenticalPatternCompute
        input_.patternComputeOption = pco.AdjustPatternCompute

        self.configure_secondary_axis(input_, secondary, squantity)

        pattern = patterns.add(input_)

        if pattern.healthState > 0:
            pattern.patternComputeOption = pco.AdjustPatternCompute

        pattern.name = name
        return pattern
예제 #2
0
    def extrude(self, profiles, body, extrudes, name, edge_offset):
        selection = ObjectCollection.create()

        for profile in profiles:
            selection.add(profile)

        dist = vi.createByReal(-self.properties.adjusted_depth.value)
        cut_input = extrudes.createInput(selection, CFO)
        cut_input.setDistanceExtent(False, dist)
        cut_input.participantBodies = [body]

        if edge_offset:
            offset = OffsetStartDefinition.create(
                vi.createByReal(-abs(edge_offset)))
            cut_input.startExtent = offset

        cut = extrudes.add(cut_input)
        cut.name = name

        return cut
def create_rib_body(component, comp_occurrence, wing_body, root_plane, dist_from_root, thickness):
    """
    Creates 2 construction planes and a solid rib body using a boundary fill between the 2 planes and the wing body
    """
    # Create 2 construction planes:
    #   1) offset from root sketch plane
    #   2) offset from the first
    planes = component.constructionPlanes

    plane1_input = planes.createInput()
    plane1_input.setByOffset(root_plane, ValueInput.createByReal(dist_from_root))
    plane1 = planes.add(plane1_input)

    plane2_input = planes.createInput()
    plane2_input.setByOffset(plane1, ValueInput.createByReal(thickness))
    plane2 = planes.add(plane2_input)

    rib_body = boundary_fill_between_planes(component, comp_occurrence, wing_body, plane1, plane2)

    # hide the construction planes
    plane1.isLightBulbOn = False
    plane2.isLightBulbOn = False

    return rib_body, plane1, plane2
    def create_rib(self, dist_from_root, rib_thickness, rib_inset, rib_name,
                   rib_post_relative_positions, rib_post_width, rib_post_triangle_len):
        root_plane = self.root_sketch.referencePlane

        # Create rib body and return it and the 2 construction planes along each fact
        rib_body, plane1, plane2 = create_rib_body(self.component, self.component_occurrence, self.wing_body,
                                                   root_plane, dist_from_root,
                                                   rib_thickness)
        rib_body.name = rib_name

        # find the chordwise extremities of the wing body
        start_coord = chordwise_coord(rib_body.boundingBox.minPoint)
        end_coord = chordwise_coord(rib_body.boundingBox.maxPoint)
        rib_post_locs = [relative_location(start_coord, end_coord, frac) for frac in rib_post_relative_positions]

        for i, rib_post_loc in enumerate(rib_post_locs):
            post = create_rib_vertical_post(self.component, self.component_occurrence, self.wing_body, rib_body,
                                            rib_post_loc, rib_post_width,
                                            rib_post_triangle_len)
            post.name = '{}_post_{}'.format(rib_name, i + 1)

        # find the faces aligned with the construction planes
        plane1_face = find_coplanar_face(rib_body, plane1)
        plane2_face = find_coplanar_face(rib_body, plane2)
        assert plane1_face is not None, 'plane1'
        assert plane2_face is not None, 'plane2'

        # use shell tool to remove center of rib, and the 2 faces
        # Create a collection of entities for shell
        entities1 = ObjectCollection.create()
        entities1.add(plane1_face)
        entities1.add(plane2_face)

        # Create a shell feature
        shell_feats = self.component.features.shellFeatures
        is_tangent_chain = False
        shell_feature_input = shell_feats.createInput(entities1, is_tangent_chain)
        rib_thickness = ValueInput.createByReal(rib_inset)
        shell_feature_input.insideThickness = rib_thickness
        shell_feats.add(shell_feature_input)
예제 #5
0
    def extrude(self, thickness: Dim, operation, name_body=False):
        """Extrudes the sketch a specified distance in a specified way.

        This should not be used on sketches with multiple profiles unless care
        is taken to ensure the last profile is the desired one.  Profiles are
        not well-labeled and so inferring the correct profile is application
        dependent.

        Args:
            thickness (Dim): distance to extrude
            operation (FeatureOperations): type of extrusion (e.g., cut or new
                component)
            name_body (bool): if true, assign current sketch name to the new
                body.
        """
        profiles = self.sketch.profiles
        # Take the last profile (arbitrary)
        profile = profiles.item(profiles.count - 1)
        extrudes = self.root_comp.features.extrudeFeatures
        extrude_distance = ValueInput.createByReal(
            thickness.dist * self.conv_factor)
        ext = extrudes.addSimple(profile, extrude_distance, operation)
        if name_body:
            ext.bodies.item(0).name = self.name
예제 #6
0
def create_spar_from_line(component, component_occurrence, wing_body,
                          spar_lines_sketch, line, spar_width):
    log(line)
    start_point = spar_lines_sketch.sketchToModelSpace(
        line.startSketchPoint.geometry)
    end_point = spar_lines_sketch.sketchToModelSpace(
        line.endSketchPoint.geometry)
    log(start_point, end_point)

    # create construction plane, centered on line, at 90 degrees to horizontal plan
    planes = component.constructionPlanes
    plane_input = planes.createInput()

    angle = ValueInput.createByString('90.0 deg')
    plane_input.setByAngle(line, angle, horizontal_plane(component))
    center_plane = planes.add(plane_input)

    # create offset planes one either side of the center plane
    plane_input = planes.createInput()
    offset = ValueInput.createByReal(spar_width / 2)
    plane_input.setByOffset(center_plane, offset)
    plane1 = planes.add(plane_input)

    plane_input = planes.createInput()
    offset = ValueInput.createByReal(-1 * spar_width / 2)
    plane_input.setByOffset(center_plane, offset)
    plane2 = planes.add(plane_input)

    for p in [center_plane, plane1, plane2]:
        p.isLightBulbOn = False

    # now use boundary fill to create spar between construction planes and wing body
    spar = boundary_fill_between_planes(component, component_occurrence,
                                        wing_body, plane1, plane2)

    # now get bounding box of spar and find min an max spanwise dimensions

    min_point = spar.boundingBox.minPoint
    max_point = spar.boundingBox.maxPoint
    sw1 = project_coord(min_point.asArray(), SPANWISE_DIRECTION.asArray())
    sw2 = project_coord(max_point.asArray(), SPANWISE_DIRECTION.asArray())
    min_spanwise = min(sw1, sw2)
    max_spanwise = max(sw1, sw2)

    v1 = project_coord(min_point.asArray(), VERTICAL_UP_DIRECTION.asArray())
    v2 = project_coord(max_point.asArray(), VERTICAL_UP_DIRECTION.asArray())

    min_vertical = min(v1, v2)
    max_vertical = max(v1, v2)
    log("Spanwise range = {} to {}".format(min_spanwise, max_spanwise))
    log("Vertical range = {} to {}".format(min_vertical, max_vertical))

    # create sketch and draw circles in a row spanwise
    spar_face_sketch = component.sketches.add(center_plane)
    circle_locs = []
    loc = min_spanwise + settings.SPAR_CIRCLE_SPACING_CM
    while loc + settings.SPAR_CIRCLE_DIAMETER_CM / 2 < max_spanwise:
        circle_locs.append(loc)
        loc = loc + settings.SPAR_CIRCLE_SPACING_CM

    log('Circle locs:', circle_locs)
    vertical_center = 0

    # sketch origin seems to be centered on the body. x seems to be spanwise
    # TODO: formalise this, for different part orientations. Need a way to deduce sketch orientation
    x_offset = (max_spanwise - min_spanwise) / 2
    # create circles
    for loc in circle_locs:
        spar_face_sketch.sketchCurves.sketchCircles.addByCenterRadius(
            Point3D.create(loc - x_offset, vertical_center, 0),
            settings.SPAR_CIRCLE_DIAMETER_CM / 2)

    profiles = ObjectCollection.create()
    for c in spar_face_sketch.profiles:
        profiles.add(c)
    # now extrude the circles to cut the spar
    extrudes = component.features.extrudeFeatures
    extrude_input = extrudes.createInput(profiles,
                                         FeatureOperations.CutFeatureOperation)
    # extrude_input.setAllExtent(ExtentDirections.SymmetricExtentDirection)
    distanceForCut = ValueInput.createByString(
        '2 cm')  # some distance > we need.
    extrude_input.setSymmetricExtent(distanceForCut, True)
    extrude_input.participantBodies = [spar]

    extrudes.add(extrude_input)

    return spar
예제 #7
0

def set_normal_value(i, v, node):
    i.value = v


SettingType = namedtuple('SettingType', ['to_input', 'from_input', 'to_str', 'from_str', 'set_value'])

setting_types = {
    'bool': SettingType(
        to_input=lambda k, desc, inp, v: inp.addBoolValueInput(k, desc['label'], True, '', bool(v)),
        to_str=lambda v: str(v).lower(), from_str=bool, from_input=(lambda i, node: i.value),
        set_value=set_normal_value),
    'float': SettingType(
        to_input=lambda k, desc, inp, v: inp.addValueInput(k, desc['label'], '',
                                                           ValueInput.createByReal(float(v) if v else 0), ),
        to_str=str, from_str=float, from_input=lambda i, node: i.value, set_value=set_normal_value),
    'int': SettingType(
        to_input=lambda k, desc, inp, v: inp.addIntegerSpinnerCommandInput(k, desc['label'], 0, 300000, 1,
                                                                           int(v) if v else 0),
        to_str=str, from_str=int, from_input=lambda i, node: i.value, set_value=set_normal_value),
    'str': SettingType(
        to_input=lambda k, desc, inp, v: inp.addStringValueInput(k, desc['label'], v if v else ''),
        to_str=lambda v: v, from_str=lambda v: v, from_input=lambda i, node: i.value, set_value=set_normal_value),
    'enum': SettingType(to_input=add_enum_input, to_str=str, from_str=str,
                        from_input=lambda i, node:
                        [k for (k, v) in node['options'].items() if v == i.selectedItem.name][0],
                        set_value=set_enum_value),
    'optional_extruder': SettingType(
        to_input=lambda k, desc, inp, v: inp.addIntegerSpinnerCommandInput(k, desc['label'], -1, 16,
                                                                           1, int(v) if v else 0),
def create_rib_vertical_post(component, comp_occurrence, wing_body, rib_body, rib_post_loc, rib_post_width,
                             rib_post_triangle_len):
    """
    create a vertical rib post
    """
    # log('creating rib post of width', rib_post_width, ' at ', rib_post_loc)
    # create 2 planes, rib_post_width apart, centered on rib_post_loc

    p1loc = rib_post_loc - (rib_post_width / 2)
    p2loc = rib_post_loc + (rib_post_width / 2)
    planes = component.constructionPlanes

    plane1_input = planes.createInput()
    plane1_input.setByOffset(vert_spanwise_plane(component), ValueInput.createByReal(p1loc))
    plane1 = planes.add(plane1_input)

    plane2_input = planes.createInput()
    plane2_input.setByOffset(vert_spanwise_plane(component), ValueInput.createByReal(p2loc))
    plane2 = planes.add(plane2_input)

    post = boundary_fill_between_planes(component, comp_occurrence, rib_body, plane1, plane2)

    # hide the construction planes
    plane1.isLightBulbOn = False
    plane2.isLightBulbOn = False

    # get dimensions of post
    bounding_box = post.boundingBox
    top = project_coord(bounding_box.maxPoint.asArray(), VERTICAL_UP_DIRECTION.asArray())
    bottom = project_coord(bounding_box.minPoint.asArray(), VERTICAL_UP_DIRECTION.asArray())
    spanwise_mid = project_coord(centroid_of_bounding_box(bounding_box).asArray(), SPANWISE_DIRECTION.asArray())

    assert plane1.isValid

    sketch = component.sketches.add(plane2, comp_occurrence)
    lines = sketch.sketchCurves.sketchLines

    tri_side = rib_post_triangle_len

    # only create triangles if the section is tall enough
    if top - bottom > 2 * tri_side:
        p1 = sketch.modelToSketchSpace(point(chordwise=p1loc, spanwise=spanwise_mid, vertical=top - tri_side))
        p2 = sketch.modelToSketchSpace(point(chordwise=p1loc, spanwise=spanwise_mid + tri_side, vertical=top))
        p3 = sketch.modelToSketchSpace(point(chordwise=p1loc, spanwise=spanwise_mid - tri_side, vertical=top))

        lines.addByTwoPoints(p1, p2)
        lines.addByTwoPoints(p2, p3)
        lines.addByTwoPoints(p3, p1)

        p1 = sketch.modelToSketchSpace(point(chordwise=p1loc, spanwise=spanwise_mid, vertical=bottom + tri_side))
        p2 = sketch.modelToSketchSpace(point(chordwise=p1loc, spanwise=spanwise_mid + tri_side, vertical=bottom))
        p3 = sketch.modelToSketchSpace(point(chordwise=p1loc, spanwise=spanwise_mid - tri_side, vertical=bottom))

        lines.addByTwoPoints(p1, p2)
        lines.addByTwoPoints(p2, p3)
        lines.addByTwoPoints(p3, p1)

        # extrude the 2 triangular profiles just created
        assert sketch.profiles.count == 2, "expected 2 triangle profiles in the sketch just created"
        profile = sketch.profiles.item(0)
        extrudes = component.features.extrudeFeatures
        top_triangle_extrusion = extrudes.addSimple(profile, ValueInput.createByReal(rib_post_width),
                                                    FeatureOperations.NewBodyFeatureOperation)
        top_triangle = top_triangle_extrusion.bodies.item(0)
        top_triangle.name = 'top_triangle'

        profile = sketch.profiles.item(1)
        extrudes = component.features.extrudeFeatures
        bottom_triangle_extrusion = extrudes.addSimple(profile, ValueInput.createByReal(rib_post_width),
                                                       FeatureOperations.NewBodyFeatureOperation)
        bottom_triangle = bottom_triangle_extrusion.bodies.item(0)
        bottom_triangle.name = 'bottom_triangle'

        # now trim the triangles to the intersection with the wing body
        tool_bodies = ObjectCollection.create()
        tool_bodies.add(wing_body)
        combines = component.features.combineFeatures

        combine_input = combines.createInput(top_triangle, tool_bodies)
        combine_input.isKeepToolBodies = True
        combine_input.isNewComponent = False
        combine_input.operation = FeatureOperations.IntersectFeatureOperation
        combines.add(combine_input)

        combine_input = combines.createInput(bottom_triangle, tool_bodies)
        combine_input.isKeepToolBodies = True
        combine_input.isNewComponent = False
        combine_input.operation = FeatureOperations.IntersectFeatureOperation
        combines.add(combine_input)

    return post
예제 #9
0
 def configure_secondary_axis(self, input_, secondary, squantity):
     if self.properties.distance_two.value and secondary and secondary.isValid:
         value = abs(self.properties.distance_two.value)
         second_distance = vi.createByReal(value)
         input_.setDirectionTwo(secondary, vi.createByReal(squantity),
                                second_distance)