htail = bodies['Htail'] other_htail = bodies['Htail.3'] vtail = bodies['Vtail'] jury = bodies['Jury'] other_jury = bodies['Jury.4'] strut = bodies['Strut'] other_strut = bodies['Strut.5'] gui = Viewer() for body in [ fuselage, wing, other_wing, gear, other_gear, htail, other_htail, vtail, jury, other_jury, strut, other_strut ]: body.set_color(0.5, 0.5, 0.5) body.set_transparency(0.5) gui.add(body) # WING ------------------------------------------------------------------------ GroupAPI.create_group('wing group') # Center wing structure will be based on the intersection between the wings # and fuselage. shape = IntersectShapes(fuselage.shape, wing.shape).shape # Use the y-dimensions of the bounding box of the intersection curve. bbox = BBox() bbox.add_shape(shape) ymax = bbox.ymax # Center wing box xz_plane = PlaneByAxes().plane
# Build a reference surface using chord lines of the cross sections. Make sure # to use the same scaling and rotation parameters. Set the parametric domains # to be between 0 and 1 for convenience. chord1 = cs.build_chord(pln1, scale=c1) chord2 = cs.build_chord(pln2, scale=c2) chord3 = cs.build_chord(pln3, scale=c3, rotate=t3) sref = NurbsSurfaceByInterp([chord1, chord2, chord3], 1).surface sref.set_udomain(0., 1.) sref.set_vdomain(0., 1.) # Set the wing reference surface wing.set_sref(sref) # Show wing and reference surface gui = Viewer() gui.add(wing, wing.sref) gui.start() # Show the underlying shape of the reference surface gui.clear() gui.add(wing.sref_shape) gui.start() # Evaluate point p = wing.sref.eval(0.5, 0.5) # Extract a plane pln = wing.extract_plane(0.5, 0., 0.5, 0.5) face = FaceByPlane(pln, -10, 10, -10, 10).face # Extract a trimmed curve
alg1d = Regular1D(the_gen) edges = the_shape.edges cmp = CompoundByShapes(edges).compound the_mesh.add_hypothesis(hyp1d, cmp) the_mesh.add_hypothesis(alg1d, cmp) # Unstructured quad-dominant hyp2d = NetgenSimple2D(the_gen, 4.) alg2d = NetgenAlgo2D(the_gen) the_mesh.add_hypothesis(hyp2d, the_shape) the_mesh.add_hypothesis(alg2d, the_shape) # Apply mapped quadrangle to internal structure # mapped_hyp = QuadrangleHypo2D(the_gen) # mapped_alg = QuadrangleAlgo2D(the_gen) # for part_ in internal_parts + [skin]: # for face in part_.faces: # if mapped_alg.is_applicable(face, True): # the_mesh.add_hypothesis(mapped_hyp, face) # the_mesh.add_hypothesis(mapped_alg, face) the_gen.compute(the_mesh, the_shape) # View # skin.set_transparency(0.5) v = Viewer() v.add(wingbox) v.start() v.add(the_mesh) v.start()
skin.fuse(*parts) skin.discard_by_dmin(htail.sref_shape, 1.) skin.fix() skin.set_transparency(0.5) # JOIN start = time.time() print('Performing assembly join...') bop = FuseGroups([wing_group, fuse_group, htail_group]) print('Joining complete in ', time.time() - start, ' seconds.') shape = bop.shape tool = ExploreFreeEdges(shape) parts = GroupAPI.get_master().get_parts() # Mesh the_mesh = MeshVehicle(4.) mesh_start = time.time() print('Computing mesh...') status = the_mesh.compute() if not status: print('Failed to compute mesh') else: print('Meshing complete in ', time.time() - mesh_start, ' seconds.') gui = Viewer() gui.add(*tool.free_edges) gui.add(the_mesh) gui.start()
fspar.shape, rspar.shape, wing, d1=30, d2=-30) internal_parts = wingbox.get_parts() skin = SkinByBody('skin', wing).part cref = wing.sref.u_iso(0.5) skin.discard_by_dmin(cref, 1.0) FuseSurfaceParts([skin], internal_parts) group = GroupAPI.get_master() v = Viewer() v.add(group) v.start() # Save print('\nSaving group...') GroupAPI.save_model('structure.xbf') print('done.\n') # Load into new group print('Loading group...') new_group = GroupAPI.create_group('new model') GroupAPI.load_model('structure.xbf', new_group) print('done.') v.clear() v.add(new_group) v.start()
CutParts(ribs, solid) # Wing skin skin = SkinByBody('skin', wing).part skin.set_color(0.5, 0.5, 0.5) skin.set_transparency(0.5) # Discard end caps of skin skin.discard_by_dmin(cref1, 0.5) # Join all the parts parts = GroupAPI.get_parts() SplitParts(parts) gui = Viewer() gui.add(*parts) gui.start() # Mesh print('Computing the mesh...') the_shape = GroupAPI.prepare_shape_to_mesh() the_gen = MeshGen() the_mesh = MeshGen.create_mesh(the_gen) the_mesh.shape_to_mesh(the_shape) # 2-D mesh hyp2d = NetgenSimple2D(the_gen, 1.) alg2d = NetgenAlgo2D(the_gen) the_mesh.add_hypothesis(hyp2d, the_shape) the_mesh.add_hypothesis(alg2d, the_shape)
# Uncomment this to export STEP file. # from afem.io import StepExport # step = StepExport() # step.transfer(shape_to_mesh) # step.write('wingbox.step') return GroupAPI.get_active() if __name__ == '__main__': start = time.time() # Import model fname = '../models/777-200LR.xbf' bodies = Body.load_bodies(fname) wing_in = bodies['Wing'] gui = Viewer() # Build wing box inputs = { 'build aux': True, 'mid spar rib': 10, 'aux rib list': ['2', '5', '8'] } group = build_wingbox(wing_in, inputs) gui.add(group) gui.start() print('Complete in ', time.time() - start, ' seconds.')
gui = Viewer() # Create a point directly from the entity. Default is (0, 0, 0). p1 = Point() # Create a point by array-like p2 = PointByArray([5, 0, 5]).point # Create a point by x-, y-, and z-coordinates. p3 = PointByXYZ(10, 0, 0).point # Interpolate the points with a curve c1 = NurbsCurveByInterp([p1, p2, p3]).curve gui.add(p1, p2, p3, c1) gui.start() # Copy curve and translate c2 = c1.copy() c2.translate((0, 10, 0)) gui.add(c2) gui.start() # Copy and translate again c3 = c2.copy() c3.translate((0, 10, 10)) gui.add(c3) gui.start()
# A few notes about importing an OpenVSP STEP model: # 1) If the model comes from the modified version that includes metadata # then the OpenVSP components can be identified by type and retrieved # by name. Otherwise the import methods just tries to make solid # bodies from the components and gives them a generic name. # 2) The import process attempts to sew the faces of the OpenVSP # components together to form solids. # 3) If a surface is found to be planar, it is replaced with a plane # before sewing. This helps eliminate some degenerated edges. # 4) Faces sharing the same domain are unified. If flat wing caps are # used, this usually results in a single face for the entire cap # rather than two faces split between the upper and lower surface. # View the model v = Viewer() v.add(*vsp_import.all_bodies) v.start() v.clear() # Retrieve relative components by name and set transparency for viewing wing_ = vsp_import.get_body('wing') fuse_ = vsp_import.get_body('fuse') wing_.set_transparency(0.5) fuse_.set_transparency(0.5) # OpenVSP 3.5 was modified by Laughlin Research to construct and export # metadata and reference geometry in the STEP file. For a wing component, # the reference geometry includes a surface that is lofted through the # chord lines at each wing station. This surface is used to define # structure in terms of percent chord and/or semispan. Currently, the # u-direction of the surface is in the chordwise and the v-direction is
from afem.geometry import * from afem.graphics import Viewer from afem.sketch import * from afem.topology import * # Create a new cross section cs = Airfoil() # Generate a 2-D profile by reading and approximating an airfoil file from the # UIUC database. Close the trailing edge if necessary. cs.read_uiuc('../models/clarky.dat', close=True) # Define a plane at the root and scale pln1 = PlaneByAxes(axes='xz').plane cs.build(pln1, scale=5) wire1 = cs.wires[0] # Define plane at the tip and rotate pln2 = PlaneByAxes((3, 15, 0), axes='xz').plane cs.build(pln2, scale=1.5, rotate=3) wire2 = cs.wires[0] # Use the wires to loft a solid shape = LoftShape([wire1, wire2], True).shape gui = Viewer() gui.add(wire1, wire2, shape) gui.start()
from afem.config import Settings from afem.exchange import ImportVSP from afem.graphics import Viewer Settings.log_to_console() # This model has bad shapes. Look at the leading edge and you'll see the # self-intersection. fn = '../models/vsp_bad_geom.stp' vsp_import = ImportVSP(fn) htail = vsp_import['Htail'] gui = Viewer() htail.set_color(0.5, 0.5, 0.5) gui.add(htail) for shape in vsp_import.invalid_shapes: shape.set_color(1, 0, 0) gui.add(shape) gui.start()
from afem.topology import FixShape, FuseShapes Settings.log_to_console() # Import an OpenVSP STEP file. If generated using the modified version that # includes metadata, each Body will be retrievable by its component name. fn = './models/777-200LR.stp' # Import the OpenVSP STEP file vsp_import = ImportVSP(fn) # View the bodies gui = Viewer() solids = [] for body in vsp_import.all_bodies: gui.add(body) solids.append(body.shape) gui.start() gui.clear() # The Boolean fuse operation must have arguments and tools. Pick one solid to # be an argument and the others tools. So far the choice of argument and tools # has not impacted the final fused shape. If you're able to pick the arguments # and tools, perhaps picking the largest/most connected solid is best (like # a fuselage)? args = [solids[0]] tools = solids[1:] # Fuse the shapes fuse = FuseShapes() fuse.set_args(args)
from afem.config import Settings from afem.exchange import ImportVSP from afem.graphics import Viewer Settings.log_to_console() fn = '../models/777-200LR.stp' vsp_import = ImportVSP(fn) v = Viewer() v.add(*vsp_import.all_bodies) v.start()
hyp2d_1 = NetgenSimple2D(gen, 1.) hyp2d_2 = NetgenSimple2D(gen, 1., allow_quads=False) alg1d = Regular1D(gen) hyp1d = MaxLength1D(gen, 0.25) # Add them to the mesh mesh.add_hypotheses([alg2d, hyp2d_1]) mesh.add_hypothesis(hyp2d_2, faces[-1]) mesh.add_hypotheses([alg1d, hyp1d], edges[-1]) # Compute the mesh gen.compute(mesh) # View the mesh gui = Viewer() gui.add(mesh) gui.start() gui.clear() # Get sub-meshes from sub-shapes face_submesh = mesh.get_submesh(faces[0]) edge_submesh = mesh.get_submesh(edges[0]) # View the face sub-mesh (2-D elements) gui.add(face_submesh) gui.start() gui.clear() # View the edge sub-mesh (1-D elements) gui.add(edge_submesh) gui.start()
from afem.exchange import * from afem.graphics import Viewer fn = '../models/777-200LR_Onshape.step' doc = XdeDocument() shapes_label = doc.read_step(fn) gui = Viewer() for child_label in shapes_label.children_iter: gui.add(child_label.shape) print('Name: {}'.format(child_label.name)) gui.start()
frame_pln_face = FaceBySurface(frame.sref).face shape = CommonShapes(below_cargo_floor, frame_pln_face).shape shape = CutShapes(shape, rev_cylinder).shape frame.merge(shape, True) i += 1 main_floor.set_transparency(0.5) cargo_floor.set_transparency(0.5) all_parts = GroupAPI.get_parts(order=True) # Split all parts together join = SplitParts(all_parts) # Mesh the_mesh = MeshVehicle(4.) # Mapped quads applied to applicable faces the_mesh.set_quadrangle_2d(the_mesh.shape) print('Computing the mesh...') the_mesh.compute() # View gui = Viewer() gui.add(GroupAPI.get_master()) gui.start() gui.clear() gui.add(the_mesh) gui.start()
import time from afem.exchange import brep from afem.graphics import Viewer from afem.smesh import * fn = 'wing_body.brep' shape = brep.read_brep(fn) # MeshGems the_gen = MeshGen() the_mesh = the_gen.create_mesh(shape) alg2d = MeshGemsAlgo2D(the_gen) hyp2d = MeshGemsHypo2D(the_gen, 4.) the_mesh.add_hypotheses([alg2d, hyp2d]) print('Computing mesh with MeshGems...') start = time.time() the_gen.compute(the_mesh) print('MeshGems complete in ', time.time() - start, ' seconds.') gui = Viewer() gui.add(the_mesh) gui.start()
# Mesh the_shape = GroupAPI.prepare_shape_to_mesh() the_gen = MeshGen() the_mesh = the_gen.create_mesh(the_shape) # Unstructured quad-dominant ngh = NetgenSimple2D(the_gen, 4.) nga = NetgenAlgo2D(the_gen) the_mesh.add_hypotheses([ngh, nga]) # Max edge length hy1d = MaxLength1D(the_gen, 4.) alg1d = Regular1D(the_gen) the_mesh.add_hypotheses([hy1d, alg1d]) # Mapped quads applied to applicable faces mapped_hyp = QuadrangleHypo2D(the_gen) mapped_algo = QuadrangleAlgo2D(the_gen) for face in the_shape.faces: if mapped_algo.is_applicable(face, True): the_mesh.add_hypotheses([mapped_hyp, mapped_algo], face) the_gen.compute(the_mesh) # View v = Viewer() v.add(GroupAPI.get_master()) v.add(the_mesh) v.start()
p2 = Point(10, 0, 0) p3 = Point(10, 10, 0) p4 = Point(5, 10, 0) p5 = Point(0, 10, 0) wire = Wire.by_points([p1, p2, p3, p4, p5], True) face = Face.by_wire(wire) # Mesh using composite side algorithm to avoid making a vertex at edge the_gen = MeshGen() the_mesh = the_gen.create_mesh(face) hyp1d = LocalLength1D(the_gen, 4) alg1d = CompositeSide1D(the_gen) the_mesh.add_hypotheses([hyp1d, alg1d], wire) hyp2d = NetgenSimple2D(the_gen, 1) alg2d = NetgenAlgo2D(the_gen) the_mesh.add_hypotheses([hyp2d, alg2d], face) the_gen.compute(the_mesh, face) # Get the composite side for e in wire.edges: fside = alg1d.get_face_side(the_mesh, e, face) if fside.num_nodes: break gui = Viewer() gui.view_top() for vert in face.vertices: gui.add(vert) gui.add(the_mesh) gui.start()
# A few notes about importing an OpenVSP STEP model: # 1) If the model comes from the modified version that includes metadata # then the OpenVSP components can be identified by type and retrieved # by name. Otherwise the import methods just tries to make solid # bodies from the components and gives them a generic name. # 2) The import process attempts to sew the faces of the OpenVSP # components together to form solids. # 3) If a surface is found to be planar, it is replaced with a plane # before sewing. This helps eliminate some degenerated edges. # 4) Faces sharing the same domain are unified. If flat wing caps are # used, this usually results in a single face for the entire cap # rather than two faces split between the upper and lower surface. # View the model gui = Viewer() gui.add(*vsp_import.all_bodies) gui.start() gui.clear() # Retrieve relative components by name and set transparency for viewing wing_ = vsp_import['wing'] fuse_ = vsp_import['fuse'] wing_.set_transparency(0.5) fuse_.set_transparency(0.5) # OpenVSP 3.5 was modified by Laughlin Research to construct and export # metadata and reference geometry in the STEP file. For a wing component, # the reference geometry includes a surface that is lofted through the # chord lines at each wing station. This surface is used to define # structure in terms of percent chord and/or semispan. Currently, the # u-direction of the surface is in the chordwise and the v-direction is
""" Test case from: https://github.com/tpaviot/pythonocc-core/issues/522 """ from afem.exchange import StepRead from afem.graphics import Viewer # Read the file reader = StepRead('../models/geometry_names.step') shape = reader.shape # Traverse all the faces and find the desired ones based on their name faces = [] for f in shape.faces: name = reader.name_from_shape(f) if name == 'CYLINDER_TOP': f.set_color(1, 0, 0) elif name == 'FACE_UP': f.set_color(0, 0, 1) else: f.set_color(0.5, 0.5, 0.5) faces.append(f) # Show the model with named faces as different colors gui = Viewer() gui.add(*faces) gui.start()
Settings.log_to_console() # Set units to inch. Settings.set_units('in') # Initialize a viewer gui = Viewer() # Import an OpenVSP model that includes OML reference geometry fn = r'../models/simple_wing.stp' vsp_import = ImportVSP(fn) wing = vsp_import['WingGeom'] wing.set_color(1., 0., 0.) wing.set_transparency(0.75) gui.add(wing.sref, wing) gui.start() gui.clear() # Define a group to put the structure in wingbox = GroupAPI.create_group('wing box') spars_assy = wingbox.create_subgroup('spar assy', active=True) ribs_assy = wingbox.create_subgroup('rib assy', active=False) # Define a front spar between parameters on the wing reference surface fspar = SparByParameters('fspar', 0.15, 0.1, 0.15, 0.98, wing).part gui.add(wing.sref, fspar, fspar.cref, fspar.cref.p1, fspar.cref.p2) gui.start() # Define a rear spar between parameters on the wing reference surface
DiscardByCref(internal_parts) skin = SkinByBody('skin', wing).part skin.fuse(*internal_parts) skin.set_transparency(0.5) # Vtail structure GroupAPI.create_group('vtail group') fspar = SparByParameters('vtail fspar', 0.15, 0.01, 0.15, 0.99, vtail).part rspar = SparByParameters('vtail rspar', 0.70, 0.01, 0.70, 0.99, vtail).part RibByPoints('vtail root rib', fspar.p1, rspar.p1, vtail) RibByPoints('vtail tip rib', fspar.p2, rspar.p2, vtail) RibsAlongCurveByDistance('vtail rib', rspar.cref, 18, fspar.shape, rspar.shape, vtail, d1=18, d2=-30) internal_parts = GroupAPI.get_parts() FuseSurfacePartsByCref(internal_parts) DiscardByCref(internal_parts) skin = SkinByBody('vtail skin', vtail).part skin.fuse(*internal_parts) skin.discard_by_dmin(vtail.sref_shape, 1.) skin.fix() # View skin.set_transparency(0.5) v = Viewer() v.add(GroupAPI.get_master()) v.start()
fspar.shape, rspar.shape, wing, d1=30, d2=-30) internal_parts = wingbox.get_parts() skin = SkinByBody('skin', wing).part cref = wing.sref.u_iso(0.5) skin.discard_by_dmin(cref, 1.0) FuseSurfaceParts([skin], internal_parts) group = GroupAPI.get_master() gui = Viewer() gui.add(group) gui.start() # Save print('\nSaving group...') GroupAPI.save_model('structure.xbf') print('done.\n') # Load into new group print('Loading group...') new_group = GroupAPI.create_group('new model') GroupAPI.load_model('structure.xbf', new_group) print('done.') gui.clear() gui.add(new_group) gui.start()
doc = XdeDocument(False) # Add label for the main shape main = doc.add_shape(solid, 'The Box') # Add labels for the sub-shapes doc.add_subshape(main, f1, 'top face') doc.add_subshape(main, f2, 'bottom face') doc.add_subshape(main, f3, 'front face') doc.add_subshape(main, f4, 'back face') doc.add_subshape(main, f5, 'left face') doc.add_subshape(main, f6, 'right face') # Save document doc.save_as('named_box') # Close and then reopen the document doc.close() doc.open('named_box') # Get the top-level shape label = doc.get_shape_by_name('The Box') # Print the child labels for child in label.children_iter: print('Sub-label name:', child.name) gui = Viewer() gui.add(label.shape) gui.start()
DiscardByCref(internal_parts) skin = SkinByBody('skin', wing).part skin.fuse(*internal_parts) skin.set_transparency(0.5) # Vtail structure GroupAPI.create_group('vtail group') fspar = SparByParameters('vtail fspar', 0.15, 0.01, 0.15, 0.99, vtail).part rspar = SparByParameters('vtail rspar', 0.70, 0.01, 0.70, 0.99, vtail).part RibByPoints('vtail root rib', fspar.cref.p1, rspar.cref.p1, vtail) RibByPoints('vtail tip rib', fspar.cref.p2, rspar.cref.p2, vtail) RibsAlongCurveByDistance('vtail rib', rspar.cref, 18, fspar.shape, rspar.shape, vtail, d1=18, d2=-30) internal_parts = GroupAPI.get_parts() FuseSurfacePartsByCref(internal_parts) DiscardByCref(internal_parts) skin = SkinByBody('vtail skin', vtail).part skin.fuse(*internal_parts) skin.discard_by_dmin(vtail.sref_shape, 1.) skin.fix() # View skin.set_transparency(0.5) gui = Viewer() gui.add(GroupAPI.get_master()) gui.start()
def show_shapes(*shapes): gui = Viewer() gui.add(*shapes) gui.start()
beam2 = Beam1DByCurve('beam 2', cref2).part # Create a solid to cut the ribs with face = FaceByPlanarWire(circle1).face solid = SweepShape(cref1, face).shape CutParts(ribs, solid) # Wing skin skin = SkinByBody('skin', wing).part skin.set_color(0.5, 0.5, 0.5) skin.set_transparency(0.5) # Discard end caps of skin skin.discard_by_dmin(cref1, 0.5) # Join all the parts parts = GroupAPI.get_parts() SplitParts(parts) gui = Viewer() gui.add(*parts) gui.start() # Mesh print('Computing the mesh...') mesh = MeshVehicle(1.) mesh.compute() gui.clear() gui.add(mesh) gui.start()
from afem.config import Settings from afem.exchange import ImportVSP from afem.graphics import Viewer Settings.log_to_console() fn = '../models/777-200LR.stp' vsp_import = ImportVSP(fn) gui = Viewer() gui.add(*vsp_import.all_bodies) gui.start()
# Tail bulkhead bbox = BBox() bbox.add_shape(fuselage.shape) xmax = bbox.xmax pln = PlaneByAxes((xmax - 36, 0, 0), 'yz').plane tail_bh = BulkheadByShape('tail bh', pln, fuselage).part # Aft frames plns = [rear_pressure_bh_pln, tail_bh.plane] frames = [] for pln1, pln2 in misc_utils.pairwise(plns): builder = FramesBetweenPlanesByDistance('frame', pln1, pln2, 24., fuselage, 8, 36., -36., first_index=next_index) frames += builder.parts next_index = builder.next_index # Join # FuseSurfaceParts([fwd_bh, rear_bh, aft_bh, floor, fskin], frames) master = GroupAPI.get_master() v = Viewer() v.add(master) v.start()