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
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)
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
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)