def project_curve_to_surface(curve, surface, dir): ''' Returns a curve as cylindrically projected onto the surface shape Parameters ---------- curve : Geom_curve or TopoDS_Edge/Wire surface : TopoDS_Shape dir : gp_Dir the direction of projection Returns ------- res_curve : geom_curve (bspline only?) ''' try: edge = make_edge(curve) except: # if converting to edge didn't work, assume curve is already an edge edge = curve wire = make_wire(edge) # This will return wire is curve is already a wire from OCC.BRepProj import BRepProj_Projection from OCC.BRepAdaptor import BRepAdaptor_CompCurve proj = BRepProj_Projection(wire, surface, dir) res_wire = proj.Current() res_curve = BRepAdaptor_CompCurve(res_wire).BSpline() return res_curve
def boundary_curve_from_2_points(p1, p2): # first create an edge e0 = BRepBuilderAPI_MakeEdge(p1, p2).Edge() w0 = BRepBuilderAPI_MakeWire(e0).Wire() # boundary for filling adap = BRepAdaptor_CompCurve(w0) p0_h = BRepAdaptor_HCompCurve(adap) boundary = GeomFill_SimpleBound(p0_h.GetHandle(), 1e-6, 1e-6) return boundary.GetHandle()
def wire_to_curve(wire, tolerance=TOLERANCE, order=GeomAbs_C2, max_segment=200, max_order=12): ''' a wire can consist of many edges. these edges are merged given a tolerance and a curve @param wire: ''' adap = BRepAdaptor_CompCurve(wire) hadap = BRepAdaptor_HCompCurve(adap) from OCC.Approx import Approx_Curve3d approx = Approx_Curve3d(hadap.GetHandle(), tolerance, order, max_segment, max_order) with assert_isdone(approx, 'not able to compute approximation from wire'): return approx.Curve().GetObject()
def wire_2_bsplinecurve_edge(occwire): ''' occwire: wire to be converted type: occwire ''' adaptor = BRepAdaptor_CompCurve(occwire) hadap = BRepAdaptor_HCompCurve(adaptor) from OCC.Approx import Approx_Curve3d from OCC.GeomAbs import GeomAbs_C0, GeomAbs_C0, GeomAbs_C2, GeomAbs_C3 approx = Approx_Curve3d(hadap.GetHandle(), 1e-06, GeomAbs_C2, 10000, 12) bspline_handle = approx.Curve() occedge = BRepBuilderAPI_MakeEdge(bspline_handle) return occedge.Edge()
def to_adaptor_3d(curveType): ''' abstract curve like type into an adaptor3d @param curveType: ''' if isinstance(curveType, TopoDS_Wire): return BRepAdaptor_CompCurve(curveType) elif isinstance(curveType, TopoDS_Edge): return BRepAdaptor_Curve(curveType) elif issubclass(curveType.__class__, Geom_Curve): return GeomAdaptor_Curve(curveType.GetHandle()) elif hasattr(curveType, 'GetObject'): _crv = curveType.GetObject() if issubclass(_crv.__class__, Geom_Curve): return GeomAdaptor_Curve(curveType) else: raise TypeError( 'allowed types are Wire, Edge or a subclass of Geom_Curve\nGot a %s' % (curveType.__class__))
def wire_2_bsplinecurve_edge(occwire): """ This function covnerts an OCCwire to a bspline OCCedge. Parameters ---------- occwire : OCCwire The OCCwire to be converted. Returns ------- converted bspline edge : OCCedge The converted OCCedge. """ adaptor = BRepAdaptor_CompCurve(occwire) hadap = BRepAdaptor_HCompCurve(adaptor) from OCC.Approx import Approx_Curve3d from OCC.GeomAbs import GeomAbs_C2 approx = Approx_Curve3d(hadap.GetHandle(), 1e-06, GeomAbs_C2, 10000, 12) bspline_handle = approx.Curve() occedge = BRepBuilderAPI_MakeEdge(bspline_handle) return occedge.Edge()
def get_current_loft(self): wires = [] curves = [] propeller_number_, xz_mirror_, xy_mirror_, yz_mirror_ \ , rot_x_, hub_length, pitch_angle, root_le_pos_x_, \ root_le_pos_y_, root_le_pos_z_, section_1_length_, section_2_length_, \ section_3_length_, section_4_length_, section_5_length_, section_1_profile_, \ section_2_profile_, section_3_profile_, section_4_profile_, section_5_profile_, \ section_1_z_, section_2_z_, section_3_z_, section_4_z_, section_5_z_ \ , section_1_chord_, section_2_chord_, section_3_chord_, section_4_chord_, \ section_5_chord_, section_1_pitch_angle_, section_2_pitch_angle_, \ section_3_pitch_angle_, section_4_pitch_angle_, section_5_pitch_angle_ = read_propeller_parameters( name=self.name) interval = 5 chords = [ section_1_chord_, section_1_chord_, section_2_chord_, section_3_chord_, section_4_chord_, section_5_chord_, 0.001 ] profile = [ section_1_profile_, section_1_profile_, section_2_profile_, section_3_profile_, section_4_profile_, section_5_profile_, section_5_profile_ ] length = [ 0, section_1_length_, section_2_length_, section_3_length_, section_4_length_, section_5_length_ / 2, section_5_length_ / 2 ] z = [ section_1_z_, section_1_z_, section_2_z_, section_3_z_, section_4_z_, section_5_z_, section_5_z_ ] pitch = [ 0, section_1_pitch_angle_, section_2_pitch_angle_, section_3_pitch_angle_, section_4_pitch_angle_, section_5_pitch_angle_, section_5_pitch_angle_ ] n = random.random() lifting_surface = self.config.get_wings().create_wing( f"{n}", len(chords), f"naca4412") sections = [-hub_length / 2, 0.1 * hub_length, hub_length / 2] radius = [ 0.00, rot_x_ / 2, rot_x_ / 2, ] x_ = [] x_.extend(np.linspace(sections[0], sections[1], num=interval)) x_.append(0.9 * hub_length) radii = [] radii.extend(np.linspace(radius[0], radius[1], num=interval)) radii.append((rot_x_ / 2)) print(x_, radii) n = random.random() hub = self.config.get_fuselages().create_fuselage( f"hub{n}", len(x_), "circularProfile") for (x, rad, index) in zip(x_, radii, range(1, len(x_) + 1)): section = hub.get_section(index) sectionElement = section.get_section_element(1) sectionElementCenter = sectionElement.get_ctigl_section_element() sectionElementCenter.set_center(tigl3.geometry.CTiglPoint(x, 0, 0)) sectionElementCenter.set_area(getArea(rad)) n_sections = lifting_surface.get_section_count() lifting_surface.set_root_leposition( tigl3.geometry.CTiglPoint(-chords[0] / 2, 0, 0)) print(n_sections) y = 0.0 x = hub_length / 2 for (z_, chord, length_, pitch_, profile_, idx) in zip(z, chords, length, pitch, profile, range(1, n_sections + 1)): profile__ = "naca" + profile_ constant = 0.0 nacanumber = profile__.split("naca")[1] if nacanumber.isdigit(): if len(nacanumber) == 4: constant = int(nacanumber[2:]) * 0.01 s = lifting_surface.get_section(idx) e = s.get_section_element(1) ce = e.get_ctigl_section_element() ce.set_width(chord) ce.set_height(chord * constant) center = ce.get_center() y += length_ center.x = x center.y = y center.z = 0.0 ce.set_center(center) ce.set_profile_uid(f"{profile_}") e.set_rotation(tigl3.geometry.CTiglPoint(0, pitch_, 0)) lifting_surface.set_rotation( tigl3.geometry.CTiglPoint(0, pitch_angle, 0)) for idx in range(1, n_sections + 1): s = lifting_surface.get_section(idx) e = s.get_section_element(1) ce = e.get_ctigl_section_element() wires.append(ce.get_wire()) for l in wires: adapt = BRepAdaptor_CompCurve(l) curve = Handle_BRepAdaptor_HCompCurve( BRepAdaptor_HCompCurve(adapt)) approx = Approx_Curve3d(curve, 0.001, GeomAbs_C2, 200, 12) if (approx.IsDone() and approx.HasResult()): curves.append(approx.Curve()) surface1 = tigl3.surface_factories.interpolate_curves(curves) face1 = BRepBuilderAPI_MakeFace(surface1, 1e-6).Face() face2 = BRepBuilderAPI_MakeFace(surface1, 1e-6).Face() sew = BRepBuilderAPI_Sewing() sew.Add(face1) sew.Add(face2) sew.Perform() shape = sew.SewedShape() print(shape) tds = topods() model = BRepBuilderAPI_MakeSolid() model.Add(tds.Shell(shape)) solid = model.Solid() print(solid) rot_trafo = tigl3.geometry.CTiglTransformation() rot_trafo.add_rotation_x(90) loft = [] loft.append(hub.get_loft().shape()) loft.append( tigl3.geometry.CNamedShape(rot_trafo.transform(solid), "cut").shape()) if propeller_number_ == 2: trafo = tigl3.geometry.CTiglTransformation() trafo.add_mirroring_at_xzplane() loft.append( tigl3.geometry.CNamedShape(trafo.transform(loft[1]), "cut").shape()) elif propeller_number_ >= 3: delta = 360 / propeller_number_ for i in range(1, propeller_number_ + 1): loft_copy = deepcopy(loft[1]) trafo = tigl3.geometry.CTiglTransformation() trafo.add_rotation_x(delta * i) print(delta * i) loft.append( tigl3.geometry.CNamedShape(trafo.transform(loft_copy), "cut").shape()) builder = BRep_Builder() assembly = TopoDS_Compound() builder.MakeCompound(assembly) for l in loft: builder.Add(assembly, l) trafo = tigl3.geometry.CTiglTransformation() trafo.add_translation(root_le_pos_x_, root_le_pos_y_, root_le_pos_z_) assembly = trafo.transform(assembly) return [assembly]
def curved_surface(self): self.read_parameters() n = random.random() self.lifting_surface = self.wings.create_wing(f"{n}", 5, self.airfoil_type) chords = [ self.section_1_chord_, self.section_2_chord_, self.section_3_chord_, self.section_4_chord_, self.section_5_chord_ ] y = [ self.section_1_y_, self.section_2_y_, self.section_3_y_, self.section_4_y_, self.section_5_y_ ] x = [ self.section_1_x_, self.section_2_x_, self.section_3_x_, self.section_4_x_, self.section_5_x_ ] z = [ self.section_1_z_, self.section_2_z_, self.section_3_z_, self.section_4_z_, self.section_5_z_ ] twist = [ self.section_1_twist_angle_, self.section_2_twist_angle_, self.section_3_twist_angle_, self.section_4_twist_angle_, self.section_5_twist_angle_ ] profile = self.airfoil_type constant = 0.5 nacanumber = profile.split("naca")[1] if nacanumber.isdigit(): if len(nacanumber) == 4: constant = int(nacanumber[2:]) * 0.01 # decrease section size towards wing tips wires = [] curves = [] n_sections = self.lifting_surface.get_section_count() for idx in range(1, n_sections + 1): s = self.lifting_surface.get_section(idx) e = s.get_section_element(1) ce = e.get_ctigl_section_element() ce.set_width(chords[idx - 1]) ce.set_height(chords[idx - 1] * constant) center = ce.get_center() center.x = x[idx - 1] center.y = y[idx - 1] center.z = z[idx - 1] ce.set_center(center) self.lifting_surface.set_rotation( tigl3.geometry.CTiglPoint(self.rot_x_, self.rot_y_, self.rot_z_)) self.lifting_surface.set_root_leposition( tigl3.geometry.CTiglPoint(self.root_le_pos_x_, self.root_le_pos_y_, self.root_le_pos_z_)) for idx in range(1, n_sections + 1): s = self.lifting_surface.get_section(idx) e = s.get_section_element(1) ce = e.get_ctigl_section_element() wires.append(ce.get_wire()) for l in wires: adapt = BRepAdaptor_CompCurve(l) curve = Handle_BRepAdaptor_HCompCurve( BRepAdaptor_HCompCurve(adapt)) approx = Approx_Curve3d(curve, 0.001, GeomAbs_C2, 200, 12) if (approx.IsDone() and approx.HasResult()): curves.append(approx.Curve()) surface = tigl3.surface_factories.interpolate_curves(curves) sew = BRepBuilderAPI_Sewing() face1 = BRepBuilderAPI_MakeFace(surface, 1e-6).Face() face2 = BRepBuilderAPI_MakeFace(surface, 1e-6).Face() sew.Add(face1) sew.Add(face2) sew.Perform() shape = sew.SewedShape() tds = topods() model = BRepBuilderAPI_MakeSolid() model.Add(tds.Shell(shape)) solid = model.Solid() loft = [] loft.append(solid) if self.xy_mirror_: trafo = tigl3.geometry.CTiglTransformation() trafo.add_mirroring_at_xyplane() loft.append( tigl3.geometry.CNamedShape(trafo.transform(loft[0]), "cut").shape()) elif self.xz_mirror_: trafo = tigl3.geometry.CTiglTransformation() trafo.add_mirroring_at_xzplane() loft.append( tigl3.geometry.CNamedShape(trafo.transform(loft[0]), "cut").shape()) elif self.yz_mirror_: trafo = tigl3.geometry.CTiglTransformation() trafo.add_mirroring_at_yzplane() loft.append( tigl3.geometry.CNamedShape(trafo.transform(loft[0]), "cut").shape()) self.old_profile = self.airfoil_type return loft
def __init__(self, wire): self.wire = wire self.balls = [] self.ballParams = [] self.adaptor = BRepAdaptor_CompCurve(self.wire)
class BallCurve: def __init__(self, wire): self.wire = wire self.balls = [] self.ballParams = [] self.adaptor = BRepAdaptor_CompCurve(self.wire) def transform(trsf): mt = BRepBuilerAPI_Transform() self.wire def insertBall(self, index, ball, paramOnCurve): ball.ballCurve = self self.balls.insert(index, ball) self.ballParams.insert(index, paramOnCurve) for i in range(len(self.balls)): self.balls[i].index = i def popBall(self, index): ball = self.balls.pop(index) param = self.ballParams.pop(index) for i in range(len(balls)): ball[i].index = i return (ball, param) def computeLength(self): raise NotImplemented() def spaceBalls(self, firstBallIndex, lastBallIndex): # spaces the balls between firstBallIndex and lastBallIndex evenly on the curve # get the distance on the curve from the first ball to the last ball if firstBallIndex == lastBallIndex: raise Warning("firstBallIndex and lastBallIndex are the same!") u0 = self.ballParams[firstBallIndex] u1 = self.ballParams[lastBallIndex] nSegmentsToQuery = ceil(u1) - floor(u0) firstSegmentToQuery = floor(u0) d = {} print("segments to query: {}".format(nSegmentsToQuery)) for i in range(nSegmentsToQuery): segment = firstSegmentToQuery + i print(segment) p = gp_Pnt() v = gp_Vec() self.adaptor.D1(segment + 0.5, p, v) d[segment] = v.Magnitude() print(d) l = 0.0 if floor(u0) != floor(u1): # u0 and u1 are in different edges print("different edges") l += (ceil(u0) - u0) * d[int(floor(u0))] print("l = {}".format(l)) l += (u1 - floor(u1)) * d[int(floor(u1))] print("l = {}".format(l)) else: # same edge l += (u1 - u0) * d[int(floor(u0))] if nSegmentsToQuery >= 3: for i in range(nSegmentsToQuery - 2): l += d[firstSegmentToQuery + 1 + i] print("l = {}".format(l)) nBallsToMove = lastBallIndex - firstBallIndex - 1 deltaL = l / (nBallsToMove + 1) print("deltaL {}".format(deltaL)) for i in range(nBallsToMove): ballIndex = i + firstBallIndex + 1 print("ballIndex {}".format(ballIndex)) u_base = self.ballParams[ballIndex - 1] converged = False l_from_past_segments = 0.0 while not converged: u = (deltaL - l_from_past_segments) / d[int( floor(u_base))] + u_base if (u - floor(u_base)) > 1.0: print("not converged. u_base={} u={}".format(u_base, u)) l_from_past_segments += d[int( floor(u_base))] * (floor(u_base + 1) - u_base) u_base = floor(u_base + 1) else: print("converged. u_base={} u={}".format(u_base, u)) self.ballParams[ballIndex] = u converged = True def parameterFromNormalizedParameter(self, u_norm): if (u_norm < 0) or (u_norm > 1.0): raise Warning("u_norm must be in the range 0 <= u_norm <= 1") l = self.computeTotalLength() * u_norm return self.compute def getPnt(self, i): return self.adaptor.Value(self.ballParams[i])