# This file is a python port of the following files : # # /src/geometry/CTiglGordonSurfaceBuilder.cpp # /src/geometry/CTiglInterpolateCurveNetwork.cpp # # from the Tigl library : https://github.com/DLR-SC/tigl under Apache-2 license #InterpolateCurveNetwork(profile_curves, guide_curves, tol3, tol2) #make_curves_compatible #parametrize curves to 0:1 #compute intersection parameters #sort_curves (curve_network_sorter) #compute average newParameters (intersectionParamsU, intersectionParamsV) (bsa.reparametrizeBSplineContinuouslyApprox) #GordonSurfaceBuilder(self.profiles, self.guides, self.intersectionParamsU, self.intersectionParamsV, self.tolerance, self.par_tolerance) #surface_gordon() #create_gordon_surface(self.profiles, self.guides, self.intersectionParamsU, self.intersectionParamsV) #check_curve_network_compatibility(profiles, guides, intersection_params_spline_u, intersection_params_spline_v, self.tolerance) #S1 and S2 (bsa.curvesToSurface) #S3 (bsa.pointsToSurface) #increase degree #createCommonKnotsVectorSurface #S1 + S2 - S3 -> self.gordonSurf import FreeCAD import Part from math import pi from freecad.Curves.BSplineAlgorithms import BSplineAlgorithms from freecad.Curves import curve_network_sorter DEBUG = True def debug(o): if not DEBUG: return() if isinstance(o,Part.BSplineCurve): #FreeCAD.Console.PrintWarning("\nBSplineCurve\n") FreeCAD.Console.PrintWarning("\nDegree: {} / NbPoles: {}\n".format(o.Degree, o.NbPoles)) #FreeCAD.Console.PrintWarning("NbPoles: {}\n".format(o.NbPoles)) FreeCAD.Console.PrintWarning("Closed: {} / Periodic: {}\n".format(o.isClosed(), o.isPeriodic())) #FreeCAD.Console.PrintWarning("Knots: %d (%0.2f - %0.2f)\n"%(o.NbKnots, o.FirstParameter, o.LastParameter)) kstr = ["{:4.2f}".format(k) for k in o.getKnots()] mstr = ["{:4d}".format(m) for m in o.getMultiplicities()] FreeCAD.Console.PrintWarning("Knots: {}\n".format(kstr)) FreeCAD.Console.PrintWarning("Mults: {}\n".format(mstr)) elif isinstance(o,Part.BSplineSurface): FreeCAD.Console.PrintWarning("\n************ BSplineSurface\n") try: u = o.uIso(o.UKnotSequence[0]) debug(u) except Part.OCCError: FreeCAD.Console.PrintError("Failed to compute uIso curve\n") try: v = o.vIso(o.VKnotSequence[0]) debug(v) except Part.OCCError: FreeCAD.Console.PrintError("Failed to compute vIso curve\n") FreeCAD.Console.PrintWarning("************\n") else: FreeCAD.Console.PrintMessage("%s\n"%o) def find(val, array, tol=1e-5): for i in range(len(array)): if abs(val-array[i]) < tol: return(int(i)) return(-1) class GordonSurfaceBuilder(object): """Build a Gordon surface from a network of curves""" def __init__(self, profiles, guides, params_u, params_v, tol=1e-5, par_tol=1e-7): debug("-- GordonSurfaceBuilder initialisation") debug("%d profiles and %d guides"%(len(profiles),len(guides))) debug(params_u) debug(params_v) if (len(profiles) < 2) or (len(guides) < 2): self.error("Not enough guides or profiles") else: self.profiles = profiles self.guides = guides self.intersectionParamsU = params_u self.intersectionParamsV = params_v self.has_performed = False if tol > 0.0: self.tolerance = tol if par_tol > 0.0: self.par_tol = par_tol def error(self,mes): print(mes) def perform(self): if self.has_performed: return() self.create_gordon_surface() #self.profiles, self.guides, self.intersectionParamsU, self.intersectionParamsV) self.has_performed = True def surface_gordon(self): self.perform() return(self.gordonSurf) def surface_profiles(self): self.perform() return(self.skinningSurfProfiles) def surface_guides(self): self.perform() return(self.skinningSurfGuides) def surface_intersections(self): self.perform() return(self.tensorProdSurf) def curve_network(self): self.perform() profiles = Part.Compound([c.toShape() for c in self.profiles]) guides = Part.Compound([c.toShape() for c in self.guides]) return(Part.Compound([profiles,guides])) def create_gordon_surface(self): # self.profiles, self.guides, self.intersectionParamsU, self.intersectionParamsV): # check whether there are any u-directional and v-directional B-splines in the vectors if len(self.profiles) < 2: self.error("There must be at least two self.profiles for the gordon surface.") if len(self.guides) < 2: self.error("There must be at least two self.guides for the gordon surface.") # check B-spline parametrization is equal among all curves umin = self.profiles[0].FirstParameter umax = self.profiles[0].LastParameter # TODO #for (CurveArray::const_iterator it = m_self.profiles.begin(); it != m_self.profiles.end(); ++it) { #assertRange(*it, umin, umax, 1e-5); vmin = self.guides[0].FirstParameter vmax = self.guides[0].LastParameter # TODO #for (CurveArray::const_iterator it = m_self.guides.begin(); it != m_self.guides.end(); ++it) { #assertRange(*it, vmin, vmax, 1e-5); # TODO: Do we really need to check compatibility? # We don't need to do this, if the curves were reparametrized before # In this case, they might be even incompatible, as the curves have been approximated self.check_curve_network_compatibility() #self.profiles, self.guides, self.intersectionParamsU, self.intersectionParamsV, self.tolerance) # setting everything up for creating Tensor Product Surface by interpolating intersection points of self.profiles and self.guides with B-Spline surface # find the intersection points: intersection_pnts = [[0]*len(self.intersectionParamsV) for i in range(len(self.intersectionParamsU))] #TColgp_Array2OfPnt intersection_pnts(1, static_cast<Standard_Integer>(self.intersectionParamsU.size()), # 1, static_cast<Standard_Integer>(self.intersectionParamsV.size())); # use splines in u-direction to get intersection points for spline_idx in range(len(self.profiles)): #(size_t spline_idx = 0; spline_idx < self.profiles.size(); ++spline_idx) { for intersection_idx in range(len(self.intersectionParamsU)): #(size_t intersection_idx = 0; intersection_idx < self.intersectionParamsU.size(); ++intersection_idx) { spline_u = self.profiles[spline_idx] parameter = self.intersectionParamsU[intersection_idx] intersection_pnts[intersection_idx][spline_idx] = spline_u.value(parameter) # check, whether to build a closed continuous surface bsa = BSplineAlgorithms(self.par_tol) curve_u_tolerance = bsa.REL_TOL_CLOSED * bsa.scale(self.guides) curve_v_tolerance = bsa.REL_TOL_CLOSED * bsa.scale(self.profiles) tp_tolerance = bsa.REL_TOL_CLOSED * bsa.scale_pt_array(intersection_pnts) # TODO No IsEqual in FreeCAD makeUClosed = bsa.isUDirClosed(intersection_pnts, tp_tolerance)# and self.guides[0].toShape().isPartner(self.guides[-1].toShape()) #.isEqual(self.guides[-1], curve_u_tolerance); makeVClosed = bsa.isVDirClosed(intersection_pnts, tp_tolerance)# and self.profiles[0].toShape().IsPartner(self.profiles[-1].toShape()) # Skinning in v-direction with u directional B-Splines debug("- Skinning profiles") debug("VClosed = %s"%makeVClosed) surfProfiles = bsa.curvesToSurface(self.profiles, self.intersectionParamsV, makeVClosed) debug(surfProfiles) # therefore reparametrization before this method # Skinning in u-direction with v directional B-Splines debug("- Skinning guides") debug("UClosed = %s"%makeUClosed) surfGuides = bsa.curvesToSurface(self.guides, self.intersectionParamsU, makeUClosed) debug(surfGuides) # flipping of the surface in v-direction; flipping is redundant here, therefore the next line is a comment! surfGuides = bsa.flipSurface(surfGuides) # if there are too little points for degree in u-direction = 3 and degree in v-direction=3 creating an interpolation B-spline surface isn't possible in Open CASCADE # Open CASCADE doesn't have a B-spline surface interpolation method where one can give the u- and v-directional parameters as arguments tensorProdSurf = bsa.pointsToSurface(intersection_pnts, self.intersectionParamsU, self.intersectionParamsV, makeUClosed, makeVClosed) debug(tensorProdSurf) # match degree of all three surfaces degreeU = max(max(surfGuides.UDegree, surfProfiles.UDegree), tensorProdSurf.UDegree) degreeV = max(max(surfGuides.VDegree, surfProfiles.VDegree), tensorProdSurf.VDegree) # check whether degree elevation is necessary (does method elevate_degree_u()) and if yes, elevate degree surfGuides.increaseDegree(degreeU, degreeV) surfProfiles.increaseDegree(degreeU, degreeV) tensorProdSurf.increaseDegree(degreeU, degreeV) debug("** Matching to degree %dx%d**"%(degreeU, degreeV)) debug("surfProfiles : %d x %d"%(surfProfiles.NbUPoles, surfProfiles.NbVPoles)) debug("surfGuides : %d x %d"%(surfGuides.NbUPoles, surfGuides.NbVPoles)) debug("tensorProdSurf : %d x %d"%(tensorProdSurf.NbUPoles, tensorProdSurf.NbVPoles)) surfaces_vector_unmod = [surfGuides, surfProfiles, tensorProdSurf] # create common knot vector for all three surfaces surfaces_vector = bsa.createCommonKnotsVectorSurface(surfaces_vector_unmod, self.par_tol) assert(len(surfaces_vector) == 3) self.skinningSurfGuides = surfaces_vector[0] self.skinningSurfProfiles = surfaces_vector[1] self.tensorProdSurf = surfaces_vector[2] debug("After createCommonKnotsVectorSurface L1234") debug("skinningSurfGuides : %d x %d"%(self.skinningSurfGuides.NbUPoles, self.skinningSurfGuides.NbVPoles)) debug("skinningSurfProfiles : %d x %d"%(self.skinningSurfProfiles.NbUPoles, self.skinningSurfProfiles.NbVPoles)) debug("tensorProdSurf : %d x %d"%(self.tensorProdSurf.NbUPoles, self.tensorProdSurf.NbVPoles)) assert(self.skinningSurfGuides.NbUPoles == self.skinningSurfProfiles.NbUPoles and self.skinningSurfProfiles.NbUPoles == self.tensorProdSurf.NbUPoles) assert(self.skinningSurfGuides.NbVPoles == self.skinningSurfProfiles.NbVPoles and self.skinningSurfProfiles.NbVPoles == self.tensorProdSurf.NbVPoles) self.gordonSurf = self.skinningSurfProfiles.copy() # creating the Gordon Surface = s_u + s_v - tps by adding the control points for cp_u_idx in range(1, self.gordonSurf.NbUPoles+1): #(int cp_u_idx = 1; cp_u_idx <= self.gordonSurf->NbUPoles(); ++cp_u_idx) { for cp_v_idx in range(1, self.gordonSurf.NbVPoles+1): #(int cp_v_idx = 1; cp_v_idx <= self.gordonSurf->NbVPoles(); ++cp_v_idx) { cp_surf_u = self.skinningSurfProfiles.getPole(cp_u_idx, cp_v_idx) cp_surf_v = self.skinningSurfGuides.getPole(cp_u_idx, cp_v_idx) cp_tensor = self.tensorProdSurf.getPole(cp_u_idx, cp_v_idx) self.gordonSurf.setPole(cp_u_idx, cp_v_idx, cp_surf_u + cp_surf_v - cp_tensor) def check_curve_network_compatibility(self): # self.profiles, self.guides, self.intersectionParamsU, self.intersectionParamsV, tol): # find out the 'average' scale of the B-splines in order to being able to handle a more approximate dataset and find its intersections bsa = BSplineAlgorithms(self.par_tol) splines_scale = 0.5 * (bsa.scale(self.profiles) + bsa.scale(self.guides)) if abs(self.intersectionParamsU[0]) > (splines_scale * self.tolerance) or abs(self.intersectionParamsU[-1] - 1.) > (splines_scale * self.tolerance): self.error("WARNING: B-splines in u-direction must not stick out, spline network must be 'closed'!") if abs(self.intersectionParamsV[0]) > (splines_scale * self.tolerance) or abs(self.intersectionParamsV[-1] - 1.) > (splines_scale * self.tolerance): self.error("WARNING: B-splines in v-direction mustn't stick out, spline network must be 'closed'!") # check compatibility of network #ucurves = list() #vcurves = list() debug("check_curve_network_compatibility") for u_param_idx in range(len(self.intersectionParamsU)): #(size_t u_param_idx = 0; u_param_idx < self.intersectionParamsU.size(); ++u_param_idx) { spline_u_param = self.intersectionParamsU[u_param_idx] spline_v = self.guides[u_param_idx] #vcurves.append(spline_v.toShape()) for v_param_idx in range(len(self.intersectionParamsV)): #(size_t v_param_idx = 0; v_param_idx < self.intersectionParamsV.size(); ++v_param_idx) { spline_u = self.profiles[v_param_idx] #ucurves.append(spline_u.toShape()) spline_v_param = self.intersectionParamsV[v_param_idx] #debug("spline_u_param, spline_v_param = %0.5f,%0.5f"%(spline_u_param, spline_v_param)) p_prof = spline_u.value(spline_u_param) p_guid = spline_v.value(spline_v_param) #debug("p_prof, p_guid = %s,%s"%(p_prof, p_guid)) distance = p_prof.distanceToPoint(p_guid) #debug("distance = %f"%(distance)) if (distance > splines_scale * self.tolerance): self.error("\nB-spline network is incompatible (e.g. wrong parametrization) or intersection parameters are in a wrong order!") self.error("\nprofile {} - guide {}".format(u_param_idx, v_param_idx)) #Part.show(Part.Compound(ucurves)) #Part.show(Part.Compound(vcurves)) class InterpolateCurveNetwork(object): """Bspline surface interpolating a network of curves""" def __init__(self, profiles, guides, tol=1e-5, tol2=1e-10): self.tolerance = 1e-5 self.par_tolerance = 1e-10 self.max_ctrl_pts = 80 self.has_performed = False if (len(profiles) < 2) or (len(guides) < 2): self.error("Not enough guides or profiles") self.profiles = [p.copy() for p in profiles] self.guides = [g.copy() for g in guides] if tol > 0.0: self.tolerance = tol if tol2 > 0.0: self.par_tolerance = tol2 def error(self,mes): print(mes) def perform(self): if self.has_performed: return() debug("-> ") self.make_curves_compatible() debug("-> make_curves_compatible -> OK") builder = GordonSurfaceBuilder(self.profiles, self.guides, self.intersectionParamsU, self.intersectionParamsV, self.tolerance, self.par_tolerance) debug("-> GordonSurfaceBuilder -> OK") self.gordon_surf = builder.surface_gordon() debug("-> builder.surface_gordon -> OK") self.skinning_surf_profiles = builder.surface_profiles() debug("-> builder.surface_profiles -> OK") self.skinning_surf_guides = builder.surface_guides() debug("-> builder.surface_guides -> OK") self.tensor_prod_surf = builder.surface_intersections() self.curve_network = builder.curve_network() self.has_performed = True debug("-> builder successfully finished") def surface_profiles(self): self.perform() return(self.skinning_surf_profiles) def surface_guides(self): self.perform() return(self.skinning_surf_guides) def surface_intersections(self): self.perform() return(self.tensor_prod_surf) def parameters_profiles(self): self.perform() return(self.intersection_params_v) def parameters_guides(self): self.perform() return(self.intersection_params_u) def surface(self): self.perform() return(self.gordon_surf) def curve_network(self): self.perform() return(self.curve_network) def compute_intersections(self, intersection_params_u, intersection_params_v): debug("\ncompute_intersections") for spline_u_idx in range(len(self.profiles)): for spline_v_idx in range(len(self.guides)): debug("Intersection of profile #%d with guide #%d"%(spline_u_idx, spline_v_idx)) currentIntersections = BSplineAlgorithms(self.par_tolerance).intersections(self.profiles[spline_u_idx], self.guides[spline_v_idx], self.par_tolerance) if len(currentIntersections) < 1: self.error("U-directional B-spline and v-directional B-spline don't intersect each other!") self.error("profile %d / guide %d"%(spline_u_idx, spline_v_idx)) elif len(currentIntersections) == 1: intersection_params_u[spline_u_idx][spline_v_idx] = currentIntersections[0][0] intersection_params_v[spline_u_idx][spline_v_idx] = currentIntersections[0][1] debug(currentIntersections) # for closed curves elif len(currentIntersections) == 2: debug("*** 2 intersections") debug(currentIntersections) # only the u-directional B-spline curves are closed if (self.profiles[0].isClosed()): debug("U-closed") if (spline_v_idx == 0): intersection_params_u[spline_u_idx][spline_v_idx] = min(currentIntersections[0][0], currentIntersections[1][0]) elif (spline_v_idx == len(self.guides) - 1): intersection_params_u[spline_u_idx][spline_v_idx] = max(currentIntersections[0][0], currentIntersections[1][0]) # intersection_params_vector[0].second == intersection_params_vector[1].second intersection_params_v[spline_u_idx][spline_v_idx] = currentIntersections[0][1] # only the v-directional B-spline curves are closed if (self.guides[0].isClosed()): debug("V-closed") if (spline_u_idx == 0): intersection_params_v[spline_u_idx][spline_v_idx] = min(currentIntersections[0][1], currentIntersections[1][1]) elif (spline_u_idx == len(self.profiles) - 1): intersection_params_v[spline_u_idx][spline_v_idx] = max(currentIntersections[0][1], currentIntersections[1][1]) # intersection_params_vector[0].first == intersection_params_vector[1].first intersection_params_u[spline_u_idx][spline_v_idx] = currentIntersections[0][0] debug("-> [%f,%f]"%(intersection_params_u[spline_u_idx][spline_v_idx], intersection_params_v[spline_u_idx][spline_v_idx])) # TODO: both u-directional splines and v-directional splines are closed # elif len(currentIntersections) == 4: else: self.error("U-directional B-spline and v-directional B-spline have more than two intersections with each other!") for spline_u_idx in range(len(self.profiles)): for spline_v_idx in range(len(self.guides)): debug("%dx%d = (%.4f, %.4f)"%(spline_u_idx, spline_v_idx, intersection_params_u[spline_u_idx][spline_v_idx], intersection_params_v[spline_u_idx][spline_v_idx])) def sort_curves(self, intersection_params_u, intersection_params_v): sorterObj = curve_network_sorter.CurveNetworkSorter(self.profiles, self.guides, intersection_params_u, intersection_params_v) sorterObj.Perform() # get the sorted matrices and vectors intersection_params_u = sorterObj.parmsIntersProfiles intersection_params_v = sorterObj.parmsIntersGuides # TODO check the code below # copy sorted curves back into our curve arrays #struct Caster { #Handle(Geom_BSplineCurve) operator()(const Handle(Geom_Curve)& curve) { #return Handle(Geom_BSplineCurve)::DownCast(curve); #} #} caster; #std::transform(sorterObj.Profiles().begin(), sorterObj.Profiles().end(), m_profiles.begin(), caster); #std::transform(sorterObj.Guides().begin(), sorterObj.Guides().end(), m_guides.begin(), caster); self.profiles = sorterObj.profiles self.guides = sorterObj.guides return(intersection_params_u, intersection_params_v) def make_curves_compatible(self): # reparametrize into [0,1] bsa = BSplineAlgorithms() for c in self.profiles: bsa.reparametrizeBSpline(c, 0., 1., self.par_tolerance) for c in self.guides: bsa.reparametrizeBSpline(c, 0., 1., self.par_tolerance) # now the parameter range of all profiles and guides is [0, 1] nGuides = len(self.guides) nProfiles = len(self.profiles) # now find all intersections of all B-splines with each other intersection_params_u = [[0]*nGuides for k in range(nProfiles)] #(0, nProfiles - 1, 0, nGuides - 1); intersection_params_v = [[0]*nGuides for k in range(nProfiles)] #(0, nProfiles - 1, 0, nGuides - 1); self.compute_intersections(intersection_params_u, intersection_params_v) debug("------make_curves_compatible------") debug("intersection_params_u\n%s"%intersection_params_u) debug("intersection_params_v\n%s"%intersection_params_v) # sort intersection_params_u and intersection_params_v and u-directional and v-directional B-spline curves intersection_params_u, intersection_params_v = self.sort_curves(intersection_params_u, intersection_params_v) # eliminate small inaccuracies of the intersection parameters: self.eliminate_inaccuracies_network_intersections(self.profiles, self.guides, intersection_params_u, intersection_params_v) newParametersProfiles = list() for spline_v_idx in range(1, nGuides+1): #(int spline_v_idx = 1; spline_v_idx <= nGuides; ++spline_v_idx) { summ = 0 for spline_u_idx in range(1, nProfiles+1): summ += intersection_params_u[spline_u_idx - 1][spline_v_idx - 1] newParametersProfiles.append(1.0 * summ / nProfiles) newParametersGuides = list() for spline_u_idx in range(1, nProfiles+1): summ = 0 for spline_v_idx in range(1, nGuides+1): summ += intersection_params_v[spline_u_idx - 1][spline_v_idx - 1] newParametersGuides.append(1.0 * summ / nGuides) debug("newParametersProfiles\n%s"%newParametersProfiles) debug("newParametersGuides\n%s"%newParametersGuides) if (newParametersProfiles[0] > self.tolerance or newParametersGuides[0] > self.tolerance): self.error("At least one B-splines has no intersection at the beginning.") # Get maximum number of control points to figure out detail of spline max_cp_u = 0 max_cp_v = 0 for c in self.profiles: max_cp_u = max(max_cp_u, c.NbPoles) for c in self.guides: max_cp_v = max(max_cp_v, c.NbPoles) # we want to use at least 10 and max "self.max_ctrl_pts" control points to be able to reparametrize the geometry properly mincp = 10 maxcp = self.max_ctrl_pts # since we interpolate the intersections, we cannot use fewer control points than curves # We need to add two since we want c2 continuity, which adds two equations min_u = max(nGuides + 2, mincp) min_v = max(nProfiles + 2, mincp) max_u = max(min_u, maxcp); max_v = max(min_v, maxcp); # Clamp(val, min, max) : return std::max(min, std::min(val, max)); max_cp_u = max(min_u, min(max_cp_u + 10, max_u)) max_cp_v = max(min_v, min(max_cp_v + 10, max_v)) progressbar = FreeCAD.Base.ProgressIndicator() progressbar.start("Computing Gordon surface ...",nProfiles+nGuides) # reparametrize u-directional B-splines for spline_u_idx in range(nProfiles): #(int spline_u_idx = 0; spline_u_idx < nProfiles; ++spline_u_idx) { oldParametersProfile = list() for spline_v_idx in range(nGuides): oldParametersProfile.append(intersection_params_u[spline_u_idx][spline_v_idx]) # eliminate small inaccuracies at the first knot if (abs(oldParametersProfile[0]) < self.tolerance): oldParametersProfile[0] = 0. if (abs(newParametersProfiles[0]) < self.tolerance): newParametersProfiles[0] = 0. # eliminate small inaccuracies at the last knot if (abs(oldParametersProfile[-1] - 1.) < self.tolerance): oldParametersProfile[-1] = 1. if (abs(newParametersProfiles[-1] - 1.) < self.tolerance): newParametersProfiles[-1] = 1. profile = self.profiles[spline_u_idx] debug("\nreparametrizing u curve %d"%spline_u_idx) debug(profile) self.profiles[spline_u_idx] = bsa.reparametrizeBSplineContinuouslyApprox(profile, oldParametersProfile, newParametersProfiles, max_cp_u) #debug(self.profiles[spline_u_idx]) progressbar.next() # reparametrize v-directional B-splines for spline_v_idx in range(nGuides): oldParameterGuide = list() for spline_u_idx in range(nProfiles): oldParameterGuide.append(intersection_params_v[spline_u_idx][spline_v_idx]) # eliminate small inaccuracies at the first knot if (abs(oldParameterGuide[0]) < self.tolerance): oldParameterGuide[0] = 0. if (abs(newParametersGuides[0]) < self.tolerance): newParametersGuides[0] = 0. # eliminate small inaccuracies at the last knot if (abs(oldParameterGuide[-1] - 1.) < self.tolerance): oldParameterGuide[-1] = 1. if (abs(newParametersGuides[-1] - 1.) < self.tolerance): newParametersGuides[-1] = 1. guide = self.guides[spline_v_idx] debug("\nreparametrizing v curve %d"%spline_v_idx) debug(guide) self.guides[spline_v_idx] = bsa.reparametrizeBSplineContinuouslyApprox(guide, oldParameterGuide, newParametersGuides, max_cp_v) #debug(self.guides[spline_v_idx]) progressbar.next() progressbar.stop() self.intersectionParamsU = newParametersProfiles self.intersectionParamsV = newParametersGuides def eliminate_inaccuracies_network_intersections(self, sortedProfiles, sortedGuides, intersection_params_u, intersection_params_v): nProfiles = len(sortedProfiles) nGuides = len(sortedGuides) #tol = 0.001 # eliminate small inaccuracies of the intersection parameters: # first intersection for spline_u_idx in range(nProfiles): if (abs(intersection_params_u[spline_u_idx][0] - sortedProfiles[0].getKnot(1)) < self.tolerance): if (abs(sortedProfiles[0].getKnot(1)) < self.par_tolerance): intersection_params_u[spline_u_idx][0] = 0 else: intersection_params_u[spline_u_idx][0] = sortedProfiles[0].getKnot(1) for spline_v_idx in range(nGuides): if (abs(intersection_params_v[0][spline_v_idx] - sortedGuides[0].getKnot(1)) < self.tolerance): if (abs(sortedGuides[0].getKnot(1)) < self.par_tolerance): intersection_params_v[0][spline_v_idx] = 0 else: intersection_params_v[0][spline_v_idx] = sortedGuides[0].getKnot(1) # last intersection for spline_u_idx in range(nProfiles): if (abs(intersection_params_u[spline_u_idx][nGuides - 1] - sortedProfiles[0].getKnot(sortedProfiles[0].NbKnots)) < self.tolerance): intersection_params_u[spline_u_idx][nGuides - 1] = sortedProfiles[0].getKnot(sortedProfiles[0].NbKnots) for spline_v_idx in range(nGuides): if (abs(intersection_params_v[nProfiles - 1][spline_v_idx] - sortedGuides[0].getKnot(sortedGuides[0].NbKnots)) < self.tolerance): intersection_params_v[nProfiles - 1][spline_v_idx] = sortedGuides[0].getKnot(sortedGuides[0].NbKnots)