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()
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()
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())
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())
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())
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
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)
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)
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
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())
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())
def __init__(self, wire): edge = brepalgo.ConcatenateWireC0(wire.object) self._wire = Wire(BRepBuilderAPI_MakeWire(edge).Wire())