Example #1
0
def _process_fuse(compound, divide_closed, name):
    # For VSP fuselages, the longitudinal direction is u, and the
    # circumferential direction is v.
    # Build the solid.
    solid, invalid = _build_solid(compound, divide_closed)
    if not solid:
        return None, invalid

    fuselage = Body(solid, name)

    faces = compound.faces
    if len(faces) == 1:
        vsp_surf = faces[0].surface
        fuselage.metadata.set('vsp surface', vsp_surf)

    return fuselage, invalid
Example #2
0
    def save_bodies(self, fn):
        """
        Save the Body instances.

        :param str fn: The filename. The extension will be ".xbf" and appended
            if not provided.

        :return: *True* if saved, *False* otherwise.
        :rtype: bool

        .. note::

            This method only saves the label, shape, and color of the Body.
            User-defined metadata is currently not saved.
        """
        bodies = list(self.bodies.values())
        return Body.save_bodies(fn, *bodies)
Example #3
0
def _process_wing(compound, divide_closed, bspline_restrict, tol, reloft,
                  name):
    # Note that for VSP wings, the spanwise direction is u and the chord
    # direction is v, where v=0 is the TE and follows the lower surface fwd to
    # the LE, and then aft along the upper surface to the TE.

    # Process based on number of faces in compound assuming split/no split
    # option was used.
    faces = compound.faces
    vsp_surf = None
    if len(faces) == 1:
        solid, invalid = _process_unsplit_wing(compound, divide_closed, reloft,
                                               tol)
        vsp_surf = faces[0].surface
    else:
        solid, invalid = _build_solid(compound, divide_closed)

    if not solid:
        return None

    if bspline_restrict:
        solid = _bspline_restrict(solid, tol)

    wing = Body(solid, name)

    if vsp_surf:
        wing.metadata.set('vsp surface', vsp_surf)
        upr_srf = vsp_surf.copy()
        v_le = vsp_surf.local_to_global_param('v', 0.5)
        upr_srf.segment(vsp_surf.u1, vsp_surf.u2, v_le, vsp_surf.v2)
        wing.metadata.set('upper surface', upr_srf)
        lwr_srf = vsp_surf.copy()
        lwr_srf.segment(vsp_surf.u1, vsp_surf.u2, vsp_surf.v1, v_le)
        wing.metadata.set('lower surface', lwr_srf)

    return wing, invalid
Example #4
0
    def import_step(self, fn):
        """
        Import a STEP file generated by the OpenVSP version that has been
        modified to include metadata.

        :param str fn: The full path to the file.

        :return: None.
        """
        # Store data as dictionaries.
        bodies = {}
        indx = 0

        # Dictionaries to attach wing reference surfaces to wing bodies using
        # reference surface ID as the key.
        wing_bodies = {}
        ref_surfs = {}

        # Data structures for fuselage reference surfaces
        fuselage_bodies = {}
        href_surfs = {}
        vref_surfs = {}

        # Read STEP file
        step_reader = StepRead(fn)
        master_shape = step_reader.shape

        # Iterate over master shape to find compounds for geometric sets. These
        # sets contain the metadata and the surfaces that make up the
        # component.
        for compound in master_shape.shape_iter:
            # Get the metadata
            name = step_reader.name_from_shape(compound)

            # Unnamed body
            if not name:
                indx += 1
                comp_name = '.'.join(['Body', str(indx)])
                msg = ' '.join(['---Processing OpenVSP component:', comp_name])
                logger.info(msg)
                solid, invalid = _build_solid(compound, self._divide)
                self._invalid += invalid
                if solid is not None:
                    body = Body(solid, comp_name)
                    bodies[comp_name] = body
                continue
            metadata = json.loads(name)

            # Process reference surfaces and continue
            key = 'm_SurfType'
            if key in metadata and metadata[key] == 99:
                # Get surface
                sref = ImportVSP.process_sref(compound)
                # Get Sref ID
                sref_id = metadata['ID']
                ref_surfs[sref_id] = sref
                continue
            elif key in metadata and metadata[key] == 100:
                # Fuselage horizontal sref
                f = compound.faces[0]
                sref = f.surface
                sref.set_udomain(-1., 1.)
                sref.set_vdomain(0., 1.)
                sref.object.ExchangeUV()
                sref.object.UReverse()
                sref_id = metadata['ID']
                href_surfs[sref_id] = sref
                continue
            elif key in metadata and metadata[key] == 101:
                f = compound.faces[0]
                sref = f.surface
                sref.set_udomain(-1., 1.)
                sref.set_vdomain(0., 1.)
                sref.object.ExchangeUV()
                sref.object.UReverse()
                sref_id = metadata['ID']
                vref_surfs[sref_id] = sref
                continue

            comp_name = metadata['m_Name']
            if comp_name in bodies:
                indx += 1
                comp_name = '.'.join([comp_name, str(indx)])

            # Process component.
            msg = ' '.join(['---Processing OpenVSP component:', comp_name])
            logger.info(msg)

            # Wing
            if metadata['m_Type'] == 5 and metadata['m_SurfType'] != 99:
                wing, invalid = _process_wing(compound, self._divide,
                                              self._restrict, self._tol,
                                              self._reloft, comp_name)
                self._invalid += invalid
                if wing is not None:
                    bodies[comp_name] = wing
                    sref_id = metadata['Sref ID']
                    wing_bodies[sref_id] = wing

            # Fuselage
            elif metadata['m_Type'] in [4, 9]:
                fuse, invalid = _process_fuse(compound, self._divide,
                                              comp_name)
                self._invalid += invalid
                if fuse is not None:
                    bodies[comp_name] = fuse
                    sref_id = metadata['Sref ID']
                    fuselage_bodies[sref_id] = fuse

            # Unknown
            else:
                solid, invalid = _build_solid(compound, self._divide)
                self._invalid += invalid
                if solid:
                    body = Body(solid, comp_name)
                    bodies[comp_name] = body

        # Attach wing reference surfaces to the bodies.
        for sref_id in wing_bodies:
            if sref_id not in ref_surfs:
                continue
            wing = wing_bodies[sref_id]
            sref = ref_surfs[sref_id]
            wing.set_sref(sref)

        # Attach fuselage reference surfaces to the bodies.
        for sref_id in fuselage_bodies:
            if sref_id in href_surfs:
                fuselage = fuselage_bodies[sref_id]
                sref = href_surfs[sref_id]
                fuselage.metadata.set('hsref', sref)
            if sref_id in vref_surfs:
                fuselage = fuselage_bodies[sref_id]
                sref = vref_surfs[sref_id]
                fuselage.metadata.set('vsref', sref)

        # Update
        self._bodies.update(bodies)