Ejemplo n.º 1
0
    def __init__(self, spine, profile):
        if isinstance(spine, Curve):
            spine = Wire.by_curve(spine)
        elif spine.is_edge:
            spine = Wire.by_edge(spine)

        if not spine.is_wire:
            raise TypeError('Spine is not a wire.')

        profile = Shape.to_shape(profile)
        self._tool = BRepOffsetAPI_MakePipe(spine.object, profile.object)

        self._tool.Build()
Ejemplo n.º 2
0
    def __init__(self, sections, is_solid=False, make_ruled=False,
                 pres3d=1.0e-6, check_compatibility=None,
                 use_smoothing=None, par_type=None, continuity=None,
                 max_degree=None):
        self._tool = BRepOffsetAPI_ThruSections(is_solid, make_ruled, pres3d)

        if check_compatibility is not None:
            self._tool.CheckCompatibility(check_compatibility)

        if use_smoothing is not None:
            self._tool.SetSmoothing(use_smoothing)

        if par_type is not None:
            self._tool.SetParType(par_type)

        if continuity is not None:
            self._tool.SetContinuity(continuity)

        if max_degree is not None:
            self._tool.SetMaxDegree(max_degree)

        for section in sections:
            if section.is_vertex:
                self._tool.AddVertex(section.object)
            elif section.is_edge:
                wire = Wire.by_edge(section)
                self._tool.AddWire(wire.object)
            elif section.is_wire:
                self._tool.AddWire(section.object)
            else:
                raise TypeError('Invalid shape type in loft.')

        self._tool.Build()
Ejemplo n.º 3
0
 def __init__(self, pnts, close=False):
     builder = BRepBuilderAPI_MakePolygon()
     for p in pnts:
         p = CheckGeom.to_point(p)
         builder.Add(p)
     if close:
         builder.Close()
     self._w = Wire(builder.Wire())
Ejemplo n.º 4
0
 def __init__(self,
              spine,
              distance,
              altitude=0.,
              join=Geometry.ARC,
              is_open=False):
     offset = BRepOffsetAPI_MakeOffset(spine.object, join, is_open)
     offset.Perform(distance, altitude)
     self._w = Wire(offset.Shape())
Ejemplo n.º 5
0
    def __init__(self, *edges):
        # Build
        builder = BRepBuilderAPI_MakeWire()
        for e in edges:
            if e is not None and not e.is_null and e.is_edge:
                builder.Add(e.object)

        self._w = Wire(builder.Wire())
        self._last_e = Edge(builder.Edge())
        self._last_v = Vertex(builder.Vertex())
Ejemplo n.º 6
0
    def __init__(self, edges, tol=None, shared=False):
        # Build
        hedges = TopTools_HSequenceOfShape()
        for e in edges:
            hedges.Append(e.object)

        if tol is None:
            tol = max([e.tol_max for e in edges])

        hwires = ShapeAnalysis_FreeBounds.ConnectEdgesToWires_(
            hedges, tol, shared)

        wires = []
        for i in range(1, hwires.Length() + 1):
            w = Wire(hwires.Value(i))
            wires.append(w)

        self._wires = wires
Ejemplo n.º 7
0
    def add_profile(self, profile, with_contact=False, with_correction=False):
        """
        Add the profile to the tool.

        :param profile: The profile to add.
        :type profile: afem.topology.entities.Vertex or
            afem.topology.entities.Edge or afem.topology.entities.Wire
        :param bool with_contact: If *True*, then the profile is translated
            to be in contact with the spine.
        :param bool with_correction: If *True*, then the profile is rotated
            to be orthogonal to the spine's tangent.

        :return: None.

        :raise TypeError: If the profile is not a vertex, edge, or wire.
        """
        if profile.is_edge:
            profile = Wire.by_edge(profile)

        if profile.shape_type not in [Shape.VERTEX, Shape.WIRE]:
            raise TypeError('Invalid profile type.')

        self._tool.Add(profile.object, with_contact, with_correction)
Ejemplo n.º 8
0
def _process_unsplit_wing(compound, divide_closed, reloft, tol):
    # Process a wing that was generated without "Split Surfs" option.

    faces = compound.faces
    if len(faces) != 1:
        return None, None
    face = faces[0]

    # Get the surface.
    master_surf = face.surface
    # master_surf = NurbsSurface(master_surf.object)
    uknots, vknots = master_surf.uknots, master_surf.vknots
    vsplit = master_surf.local_to_global_param('v', 0.5)

    # Segment off the end caps and the trailing edges.
    u1, u2 = uknots[1], uknots[-2]
    v1, v2 = vknots[1], vknots[-2]
    s1 = master_surf.copy()
    s1.segment(u1, u2, v1, v2)

    # Reloft the surface by tessellating a curve at each spanwise knot. This
    # enforces C1 continuity but assumes linear spanwise wing which may not
    # support blending wing sections in newer versions of OpenVSP. Also, since
    # the tessellated curves may not match up to the wing end caps making
    # sewing unreliable, flat end caps are assumed.
    if reloft:
        s1 = _reloft_wing_surface(s1, tol)

        # Generate new flat end caps using isocurves at the root and tip of
        # this new surface
        c0 = s1.v_iso(s1.v1)
        c1 = s1.v_iso(s1.v2)
        e0 = Edge.by_curve(c0)
        e1 = Edge.by_curve(c1)
        w0 = Wire.by_edge(e0)
        w1 = Wire.by_edge(e1)
        f0 = Face.by_wire(w0)
        f1 = Face.by_wire(w1)

        # Make faces of surfaces
        f = Face.by_surface(s1)
        new_faces = [f, f0, f1]
    else:
        # Reparamterize knots in spanwise direction to be chord length instead
        # of uniform. Use isocurve at quarter-chord to determine knot values.
        # This only works as long as surfaces are linear.
        c0 = s1.u_iso(s1.u1)
        c0.segment(vsplit, c0.u2)
        qc_u = PointFromParameter(c0, vsplit, 0.25 * c0.length).parameter
        c = s1.v_iso(qc_u)
        pnts = [c.eval(u) for u in c.knots]
        new_uknots = geom_utils.chord_parameters(pnts, 0., 1.)
        s1.set_uknots(new_uknots)

        # Segment off end caps
        u1, u2 = uknots[0], uknots[1]
        v1, v2 = vknots[1], vsplit
        s2 = master_surf.copy()
        s2.segment(u1, u2, v1, v2)

        u1, u2 = uknots[0], uknots[1]
        v1, v2 = vsplit, vknots[-2]
        s3 = master_surf.copy()
        s3.segment(u1, u2, v1, v2)

        u1, u2 = uknots[-2], uknots[-1]
        v1, v2 = vknots[1], vsplit
        s4 = master_surf.copy()
        s4.segment(u1, u2, v1, v2)

        u1, u2 = uknots[-2], uknots[-1]
        v1, v2 = vsplit, vknots[-2]
        s5 = master_surf.copy()
        s5.segment(u1, u2, v1, v2)

        # Make faces of surfaces
        new_faces = []
        for s in [s1, s2, s3, s4, s5]:
            f = Face.by_surface(s)
            new_faces.append(f)

    # Segment off TE.
    u1, u2 = uknots[0], uknots[-1]
    v1, v2 = vknots[0], vknots[1]
    s6 = master_surf.copy()
    s6.segment(u1, u2, v1, v2)

    u1, u2 = uknots[0], uknots[-1]
    v1, v2 = vknots[-2], vknots[-1]
    s7 = master_surf.copy()
    s7.segment(u1, u2, v1, v2)

    # Split the TE surface at each u-knot.
    usplits = occ_utils.to_tcolstd_hseq_real(uknots[1:-1])

    split = ShapeUpgrade_SplitSurface()
    split.Init(s6.object)
    split.SetUSplitValues(usplits)
    split.Perform()
    comp_surf1 = split.ResSurfaces()

    split = ShapeUpgrade_SplitSurface()
    split.Init(s7.object)
    split.SetUSplitValues(usplits)
    split.Perform()
    comp_surf2 = split.ResSurfaces()

    # For each patch in the composite surfaces create a face.
    for i in range(1, comp_surf1.NbUPatches() + 1):
        for j in range(1, comp_surf1.NbVPatches() + 1):
            hpatch = comp_surf1.Patch(i, j)
            f = BRepBuilderAPI_MakeFace(hpatch, 0.).Face()
            new_faces.append(f)

    for i in range(1, comp_surf2.NbUPatches() + 1):
        for j in range(1, comp_surf2.NbVPatches() + 1):
            hpatch = comp_surf2.Patch(i, j)
            f = BRepBuilderAPI_MakeFace(hpatch, 0.).Face()
            new_faces.append(f)

    # Put all faces into a compound a generate solid.
    new_compound = Compound.by_shapes(new_faces)

    return _build_solid(new_compound, divide_closed)
Ejemplo n.º 9
0
def _build_solid(compound, divide_closed):
    """
    Try to build a solid from the OpenVSP compound of faces.

    :param afem.topology.entities.Compound compound: The compound.
    :param bool divide_closed: Option to divide closed faces.

    :return: The solid.
    :rtype: afem.topology.entities.Solid
    """
    # Get all the faces in the compound. The surfaces must be split. Discard
    # any with zero area.
    faces = []
    for face in compound.faces:
        area = SurfaceProps(face).area
        if area > 1.0e-7:
            faces.append(face)

    # Replace any planar B-Spline surfaces with planes.
    non_planar_faces = []
    planar_faces = []
    for f in faces:
        srf = f.surface
        try:
            pln = srf.as_plane()
            if pln:
                w = f.outer_wire
                # Fix the wire because they are usually degenerate edges in
                # the planar end caps.
                builder = BRepBuilderAPI_MakeWire()
                for e in w.edges:
                    if LinearProps(e).length > 1.0e-7:
                        builder.Add(e.object)
                w = builder.Wire()
                fix = ShapeFix_Wire()
                fix.Load(w)
                fix.SetSurface(pln.object)
                fix.FixReorder()
                fix.FixConnected()
                fix.FixEdgeCurves()
                fix.FixDegenerated()
                w = Wire(fix.WireAPIMake())
                fnew = Face.by_wire(w)
                planar_faces.append(fnew)
            else:
                non_planar_faces.append(f)
        except RuntimeError:
            logger.info('Failed to check for planar face...')
            non_planar_faces.append(f)

    # Make a compound of the faces
    shape = Compound.by_shapes(non_planar_faces + planar_faces)

    # Split closed faces
    if divide_closed:
        shape = DivideClosedShape(shape).shape

    # Sew shape
    sewn_shape = SewShape(shape).sewed_shape
    if isinstance(sewn_shape, Face):
        sewn_shape = sewn_shape.to_shell()

    # Attempt to unify planar domains
    shell = UnifyShape(sewn_shape).shape

    # Make solid
    if not isinstance(shell, Shell):
        logger.info('\tA valid shell was not able to be generated.')
        check = CheckShape(shell)
        if not check.is_valid:
            logger.info('\tShape errors:')
            check.log_errors()
        return shell, check.invalid_shapes

    solid = Solid.by_shell(shell)

    # Limit tolerance
    FixShape.limit_tolerance(solid)

    # Check the solid and attempt to fix
    invalid = []
    check = CheckShape(solid)
    if not check.is_valid:
        logger.info('\tFixing the solid...')
        solid = FixShape(solid).shape
        check = CheckShape(solid)
        if not check.is_valid:
            logger.info('\t...solid could not be fixed.')
            logger.info('\tShape errors:')
            check.log_errors()
            failed = check.invalid_shapes
            invalid += failed
    else:
        tol = solid.tol_avg
        logger.info(
            '\tSuccessfully generated solid with tolerance={}'.format(tol))

    return solid, invalid
Ejemplo n.º 10
0
 def __init__(self, wire, v):
     v = CheckGeom.to_vector(v)
     builder = BRepPrimAPI_MakePrism(wire.object, v)
     self._shell = Shell(builder.Shape())
     self._w1 = Wire(builder.FirstShape())
     self._w2 = Wire(builder.LastShape())
Ejemplo n.º 11
0
 def __init__(self, wire):
     if isinstance(wire, Curve):
         wire = Wire.by_curve(wire)
     elif isinstance(wire, Edge):
         wire = Wire.by_edge(wire)
     self._f = Face(BRepBuilderAPI_MakeFace(wire.object, True).Face())
Ejemplo n.º 12
0
 def __init__(self, wire):
     edge = brepalgo.ConcatenateWireC0(wire.object)
     self._wire = Wire(BRepBuilderAPI_MakeWire(edge).Wire())