def interpolate_points_to_spline_no_tangency(list_of_points, filter_pts=True, closed=False, tolerance=TOLERANCE): ''' GeomAPI_Interpolate is buggy: need to use `fix` in order to get the right points in... ''' def fix(li, _type): '''function factory for 1-dimensional TCol* types''' pts = _type(1, len(li)) for n, i in enumerate(li): pts.SetValue(n + 1, i) pts.thisown = False return pts if filter_pts: list_of_points = filter_points_by_distance(list_of_points, 0.1) fixed_points = fix(list_of_points, TColgp_HArray1OfPnt) try: interp = GeomAPI_Interpolate(fixed_points.GetHandle(), closed, tolerance) interp.Perform() if interp.IsDone(): return interp.Curve() except RuntimeError: # the exception was unclear raise RuntimeError('FAILED TO INTERPOLATE THE POINTS')
def interpolate_points_to_spline(list_of_points, start_tangent, end_tangent, filter_pts=True, tolerance=TOLERANCE): ''' GeomAPI_Interpolate is buggy: need to use `fix` in order to get the right points in... ''' def fix(li, _type): '''function factory for 1-dimensional TCol* types''' pts = _type(1, len(li)) for n, i in enumerate(li): pts.SetValue(n + 1, i) pts.thisown = False return pts if filter_pts: list_of_points = filter_points_by_distance(list_of_points, 0.1) fixed_points = fix(list_of_points, TColgp_HArray1OfPnt) try: interp = GeomAPI_Interpolate(fixed_points.GetHandle(), False, tolerance) interp.Load(start_tangent, end_tangent, False) interp.Perform() if interp.IsDone(): return interp.Curve() except RuntimeError: print("Failed to interpolate the shown points")
def _generate_lower_face(self, maxDeg): """ Private method to generate the blade lower face. :param int maxDeg: Define the maximal U degree of generated surface """ self._import_occ_libs() # Initializes ThruSections algorithm for building a shell passing # through a set of sections (wires). The generated faces between # the edges of every two consecutive wires are smoothed out with # a precision criterion = 1e-10 generator = BRepOffsetAPI_ThruSections(False, False, 1e-10) generator.SetMaxDegree(maxDeg) # Define upper edges (wires) for the face generation for i in range(self.n_sections): npoints = len(self.blade_coordinates_down[i][0]) vertices = TColgp_HArray1OfPnt(1, npoints) for j in range(npoints): vertices.SetValue( j + 1, gp_Pnt(1000 * self.blade_coordinates_down[i][0][j], 1000 * self.blade_coordinates_down[i][1][j], 1000 * self.blade_coordinates_down[i][2][j])) # Initializes an algorithm for constructing a constrained # BSpline curve passing through the points of the blade i-th # section, with tolerance = 1e-9 bspline = GeomAPI_Interpolate(vertices.GetHandle(), False, 1e-9) bspline.Perform() edge = BRepBuilderAPI_MakeEdge(bspline.Curve()).Edge() if i == 0: bound_root_edge = edge # Add BSpline wire to the generator constructor generator.AddWire(BRepBuilderAPI_MakeWire(edge).Wire()) # Returns the shape built by the shape construction algorithm generator.Build() # Returns the Face generated by each edge of the first section self.generated_lower_face = generator.GeneratedFace(bound_root_edge)
def _generate_tip(self, maxDeg): """ Private method to generate the surface that closing the blade tip. :param int maxDeg: Define the maximal U degree of generated surface """ self._import_occ_libs() generator = BRepOffsetAPI_ThruSections(False, False, 1e-10) generator.SetMaxDegree(maxDeg) # npoints_up == npoints_down npoints = len(self.blade_coordinates_down[-1][0]) vertices_1 = TColgp_HArray1OfPnt(1, npoints) vertices_2 = TColgp_HArray1OfPnt(1, npoints) for j in range(npoints): vertices_1.SetValue( j + 1, gp_Pnt(1000 * self.blade_coordinates_down[-1][0][j], 1000 * self.blade_coordinates_down[-1][1][j], 1000 * self.blade_coordinates_down[-1][2][j])) vertices_2.SetValue( j + 1, gp_Pnt(1000 * self.blade_coordinates_up[-1][0][j], 1000 * self.blade_coordinates_up[-1][1][j], 1000 * self.blade_coordinates_up[-1][2][j])) # Initializes an algorithm for constructing a constrained # BSpline curve passing through the points of the blade last # section, with tolerance = 1e-9 bspline_1 = GeomAPI_Interpolate(vertices_1.GetHandle(), False, 1e-9) bspline_1.Perform() bspline_2 = GeomAPI_Interpolate(vertices_2.GetHandle(), False, 1e-9) bspline_2.Perform() edge_1 = BRepBuilderAPI_MakeEdge(bspline_1.Curve()).Edge() edge_2 = BRepBuilderAPI_MakeEdge(bspline_2.Curve()).Edge() # Add BSpline wire to the generator constructor generator.AddWire(BRepBuilderAPI_MakeWire(edge_1).Wire()) generator.AddWire(BRepBuilderAPI_MakeWire(edge_2).Wire()) # Returns the shape built by the shape construction algorithm generator.Build() # Returns the Face generated by each edge of the first section self.generated_tip = generator.GeneratedFace(edge_1)
def interpolate_points_vectors_to_spline(list_of_points, list_of_vectors, vector_mask=None, tolerance=TOLERANCE): ''' build a curve from a set of points and vectors the vectors describe the tangent vector at the corresponding point ''' # GeomAPI_Interpolate is buggy: need to use `fix` in order to # get the right points in... assert len(list_of_points) == len( list_of_vectors), 'vector and point list not of same length' def fix(li, _type): '''function factory for 1-dimensional TCol* types''' pts = _type(1, len(li)) for n, i in enumerate(li): pts.SetValue(n + 1, i) pts.thisown = False return pts if vector_mask is not None: assert len(vector_mask) == len( list_of_points ), 'length vector mask is not of length points list nor []' else: vector_mask = [True for i in range(len(list_of_points))] fixed_mask = fix(vector_mask, TColStd_HArray1OfBoolean) fixed_points = fix(list_of_points, TColgp_HArray1OfPnt) fixed_vectors = fix(list_of_vectors, TColgp_Array1OfVec) try: interp = GeomAPI_Interpolate(fixed_points.GetHandle(), False, tolerance) interp.Load(fixed_vectors, fixed_mask.GetHandle(), False) interp.Perform() if interp.IsDone(): return interp.Curve() except RuntimeError: # the exception was unclear raise RuntimeError('FAILED TO INTERPOLATE THE POINTS')
def points_to_bspline(pnts, deg=3, periodic=False, tangents=None, scale=False, continuity=GeomAbs_C2): """ Points to bspline: originally from pythonocc-utils, changed to allow numpy arrays as input Paramters --------- pnts : list or numpy array array of x, y, z points deg : integer degree of the fitted bspline periodic : Bool (default=False) If true, OCC.GeomAPI_Interpolate will be used instead of the GeomAPI_PointsToBspline. Curve tangent vectors can then be enforced at the interpolation pnts tangents : array (default=None) list of [x,y,z] tangent vectors to be specificied at points: if only 2 tangents are specified, these will be enforced at the start and end points, otherwise tangents should have the same length as pnts and will be enforced at each point. Scale : Bool (default=False) Will scale the tangents (gives a smoother Periodic curve if False) continuity : OCC.GeomAbs.GeomAbs_XX type (default C2) The order of continuity (C^0, C^1, C^2, G^0, ....) Returns ------- crv : OCC.Geom.BSplineCurve Notes ----- """ if not periodic and (tangents is None): _type = TColgp_Array1OfPnt pnts = point_array_to_TColgp_PntArrayType(pnts, _type) # Fit the curve to the point array deg_min = deg deg_max = deg crv = GeomAPI_PointsToBSpline(pnts, deg_min, deg_max, continuity).Curve() else: _type = TColgp_HArray1OfPnt pnts = point_array_to_TColgp_PntArrayType(pnts, _type) tol = 0.001 interp = GeomAPI_Interpolate(pnts.GetHandle(), periodic, tol) if tangents is not None: N = tangents.shape[0] if N == 2: try: interp.Load(gp_Vec(*tangents[0, :]), gp_Vec(*tangents[1, :]), scale) except: # Python 3 issue: using * on numpy array breaks gp_Vec interp.Load(gp_Vec(*tangents[0, :].tolist()), gp_Vec(*tangents[1, :].tolist()), scale) else: tan_array = TColgp_Array1OfVec(1, N) for i in range(1, N + 1): try: tan_array.SetValue(i, gp_Vec(*tangents[i - 1, :])) except TypeError: # Python 3 issue: using * on numpy array breaks gp_Vec tan_array.SetValue(i, gp_Vec(*tangents[i - 1, :].tolist())) tan_flags = TColStd_HArray1OfBoolean(1, N) tan_flags.Init(True) # Set all true i.e. enforce all tangents interp.Load(tan_array, tan_flags.GetHandle(), scale) interp.Perform() crv = interp.Curve() return crv