def distances(self): """ Compute the distance between the input points. """ n = len(self) self.dist = [] for i in range(n-1): p, q = self.points[i],self.points[i+1] self.dist.append(norm(q-p))
def distances(self): """ Compute the distance between the input points. """ n = len(self) self.dist = [] for i in range(n - 1): p, q = self.points[i], self.points[i + 1] self.dist.append(norm(q - p))
def cubic_bezier3D (ctrl_points, uniform = False, stride = 60) : """Construct a nurbs from a set of ctrl_points ctrl_points are control points in space that define a cubic bezier nurbs as proposed in svg norm http://www.w3.org/TR/SVG/paths.html#PathDataCurveCommands An arc `i` of the resulting curve will interpolate points 4 * i, 4 * i +1, 4 * i + 2, 4 * i + 3. :Parameters: - `ctrl_points` (list of Vector) - a list of control points - `uniform` (bool) - if True, the parameterization of the curve will be chosen such that each segment will be of length 1 in u space, wathever its real geometrical size. - `stride` (int) - number of points to discretize the curve :Returns Type: :class:NurbsCurve """ degree = 3 ctrl_points = [Vector3(*vec) for vec in ctrl_points] nb_pts = len(ctrl_points) nb_arc = (nb_pts - 1) / degree nb_knots = degree + nb_pts p = 0. param = [p] for i in xrange(nb_arc) : if uniform : p += 1 else : p += norm(ctrl_points[degree * i] \ - ctrl_points[degree * (i + 1)]) param.append(p) kv = [param[0]] for p in param : for j in xrange(degree) : kv.append(p) kv.append(param[-1]) #curve return NurbsCurve([Vector4(v,1.) for v in ctrl_points], kv, degree, stride)
def cubic_bezier3D(ctrl_points, uniform=False, stride=60): """Construct a nurbs from a set of ctrl_points ctrl_points are control points in space that define a cubic bezier nurbs as proposed in svg norm http://www.w3.org/TR/SVG/paths.html#PathDataCurveCommands An arc `i` of the resulting curve will interpolate points 4 * i, 4 * i +1, 4 * i + 2, 4 * i + 3. :Parameters: - `ctrl_points` (list of Vector) - a list of control points - `uniform` (bool) - if True, the parameterization of the curve will be chosen such that each segment will be of length 1 in u space, wathever its real geometrical size. - `stride` (int) - number of points to discretize the curve :Returns Type: :class:NurbsCurve """ degree = 3 ctrl_points = [Vector3(*vec) for vec in ctrl_points] nb_pts = len(ctrl_points) nb_arc = (nb_pts - 1) / degree nb_knots = degree + nb_pts p = 0. param = [p] for i in xrange(nb_arc): if uniform: p += 1 else: p += norm(ctrl_points[degree * i] \ - ctrl_points[degree * (i + 1)]) param.append(p) kv = [param[0]] for p in param: for j in xrange(degree): kv.append(p) kv.append(param[-1]) #curve return NurbsCurve([Vector4(v, 1.) for v in ctrl_points], kv, degree, stride)
def __init__(self, points, is_closed=False): """ Create a CSpline from a set of 2d or 3d points. """ if len(points) != 0: self.dim = len(points[0]) if self.dim == 2: self.points = pgl.Point2Array(points) elif self.dim == 3: self.points = pgl.Point3Array(points) elif self.dim == 4: self.points = pgl.Point4Array(points) else: self.dim = 3 self.points = points self.is_closed = is_closed if is_closed: if norm(points[-1]-points[0]) > epsilon: self.points.append(points[0]) self.nurbs= None self.dist = None self.der = None
def __init__(self, points, is_closed=False): """ Create a CSpline from a set of 2d or 3d points. """ if len(points) != 0: self.dim = len(points[0]) if self.dim == 2: self.points = pgl.Point2Array(points) elif self.dim == 3: self.points = pgl.Point3Array(points) elif self.dim == 4: self.points = pgl.Point4Array(points) else: self.dim = 3 self.points = points self.is_closed = is_closed if is_closed: if norm(points[-1] - points[0]) > epsilon: self.points.append(points[0]) self.nurbs = None self.dist = None self.der = None
def refine_triangular_mesh (mesh, position, fids) : """ refine a face of the mesh by subdividing the longest edge of the face using Rivara algorithm divide linked faces if necessary to maintain conformity of the mesh """ already_divided_edges={} to_divide_face=set(fids) divided_faces=[] divided_edges=[] while len(to_divide_face)>0 : fid=to_divide_face.pop() edges=list(mesh.borders(2,fid)) #calcul de la longueur de chacune de aretes edge_length={} for eid in edges : pid1,pid2=mesh.borders(1,eid) edge_length[eid]=norm(position[pid1]-position[pid2]) real_length=[] for eid in edges : if eid in already_divided_edges and already_divided_edges[eid] in edges : real_length.append( (edge_length[eid]+edge_length[already_divided_edges[eid]],eid) ) else : real_length.append( (edge_length[eid],eid) ) real_length.sort() div_eid=real_length[-1][1] if div_eid not in already_divided_edges : #subdivision de l'edge pid1,pid2=mesh.borders(1,div_eid) pid=mesh.add_wisp(0) position[pid]=(position[pid1]+position[pid2])/2. eid1=mesh.add_wisp(1) mesh.link(1,eid1,pid1) mesh.link(1,eid1,pid) eid2=mesh.add_wisp(1) mesh.link(1,eid2,pid2) mesh.link(1,eid2,pid) #raccord avec les faces faces=set(mesh.regions(1,div_eid)) for bid in faces : mesh.link(2,bid,eid1) mesh.link(2,bid,eid2) #ajout a la liste des faces a traiter faces.remove(fid) to_divide_face|=faces #retrait de l'ancienne edge mesh.remove_wisp(1,div_eid) divided_edges.append( (div_eid,(eid1,eid2)) ) #mise a jour de div_eid div_eid=eid1 already_divided_edges[eid1]=eid2 already_divided_edges[eid2]=eid1 #division de la face en deux #recherche du sommet oppose a div_eid #recherche des trois sommets du triangle face_corners=set(mesh.borders(2,fid,2)) edges=list(mesh.borders(2,fid)) for eid in edges : if eid in already_divided_edges : eid2=already_divided_edges[eid] if eid2 in edges : edges.remove(eid2) #recherche point commun aux deux edges common_pid=set(mesh.borders(1,eid))&set(mesh.borders(1,eid2)) face_corners-=common_pid assert len(face_corners)==3 #retrait des deux points de la edge divisee eid2=already_divided_edges[div_eid] edge_pts=set(mesh.borders(1,div_eid))|set(mesh.borders(1,eid2)) face_corners-=edge_pts top_pid=face_corners.pop() #creation de la nouvelle edge new_eid=mesh.add_wisp(1) mesh.link(1,new_eid,top_pid) common_pid=set(mesh.borders(1,div_eid))&set(mesh.borders(1,eid2)) common_pid=common_pid.pop() mesh.link(1,new_eid,common_pid) #division de la face fid1=mesh.add_wisp(2) mesh.link(2,fid1,new_eid) mesh.link(2,fid1,div_eid) eid=div_eid pid=opposite_point(mesh,eid,common_pid) while pid!=top_pid : eid=opposite_edge(mesh,fid,eid,pid) mesh.link(2,fid1,eid) pid=opposite_point(mesh,eid,pid) fid2=mesh.add_wisp(2) mesh.link(2,fid2,new_eid) mesh.link(2,fid2,eid2) eid=eid2 pid=opposite_point(mesh,eid,common_pid) while pid!=top_pid : eid=opposite_edge(mesh,fid,eid,pid) mesh.link(2,fid2,eid) pid=opposite_point(mesh,eid,pid) #retrait de l'ancienne face mesh.remove_wisp(2,fid) #mise a jour des faces modifiees divided_faces.append( (fid,[fid1,fid2]) ) #ajout des faces a la liste des faces a traiter si necessaire for fid in (fid1,fid2) : if mesh.nb_borders(2,fid)>3 : to_divide_face.add(fid) return divided_faces,divided_edges
def refine_triangular_mesh(mesh, position, fids): """ refine a face of the mesh by subdividing the longest edge of the face using Rivara algorithm divide linked faces if necessary to maintain conformity of the mesh """ already_divided_edges = {} to_divide_face = set(fids) divided_faces = [] divided_edges = [] while len(to_divide_face) > 0: fid = to_divide_face.pop() edges = list(mesh.borders(2, fid)) #calcul de la longueur de chacune de aretes edge_length = {} for eid in edges: pid1, pid2 = mesh.borders(1, eid) edge_length[eid] = norm(position[pid1] - position[pid2]) real_length = [] for eid in edges: if eid in already_divided_edges and already_divided_edges[ eid] in edges: real_length.append( (edge_length[eid] + edge_length[already_divided_edges[eid]], eid)) else: real_length.append((edge_length[eid], eid)) real_length.sort() div_eid = real_length[-1][1] if div_eid not in already_divided_edges: #subdivision de l'edge pid1, pid2 = mesh.borders(1, div_eid) pid = mesh.add_wisp(0) position[pid] = (position[pid1] + position[pid2]) / 2. eid1 = mesh.add_wisp(1) mesh.link(1, eid1, pid1) mesh.link(1, eid1, pid) eid2 = mesh.add_wisp(1) mesh.link(1, eid2, pid2) mesh.link(1, eid2, pid) #raccord avec les faces faces = set(mesh.regions(1, div_eid)) for bid in faces: mesh.link(2, bid, eid1) mesh.link(2, bid, eid2) #ajout a la liste des faces a traiter faces.remove(fid) to_divide_face |= faces #retrait de l'ancienne edge mesh.remove_wisp(1, div_eid) divided_edges.append((div_eid, (eid1, eid2))) #mise a jour de div_eid div_eid = eid1 already_divided_edges[eid1] = eid2 already_divided_edges[eid2] = eid1 #division de la face en deux #recherche du sommet oppose a div_eid #recherche des trois sommets du triangle face_corners = set(mesh.borders(2, fid, 2)) edges = list(mesh.borders(2, fid)) for eid in edges: if eid in already_divided_edges: eid2 = already_divided_edges[eid] if eid2 in edges: edges.remove(eid2) #recherche point commun aux deux edges common_pid = set(mesh.borders(1, eid)) & set( mesh.borders(1, eid2)) face_corners -= common_pid assert len(face_corners) == 3 #retrait des deux points de la edge divisee eid2 = already_divided_edges[div_eid] edge_pts = set(mesh.borders(1, div_eid)) | set(mesh.borders(1, eid2)) face_corners -= edge_pts top_pid = face_corners.pop() #creation de la nouvelle edge new_eid = mesh.add_wisp(1) mesh.link(1, new_eid, top_pid) common_pid = set(mesh.borders(1, div_eid)) & set(mesh.borders(1, eid2)) common_pid = common_pid.pop() mesh.link(1, new_eid, common_pid) #division de la face fid1 = mesh.add_wisp(2) mesh.link(2, fid1, new_eid) mesh.link(2, fid1, div_eid) eid = div_eid pid = opposite_point(mesh, eid, common_pid) while pid != top_pid: eid = opposite_edge(mesh, fid, eid, pid) mesh.link(2, fid1, eid) pid = opposite_point(mesh, eid, pid) fid2 = mesh.add_wisp(2) mesh.link(2, fid2, new_eid) mesh.link(2, fid2, eid2) eid = eid2 pid = opposite_point(mesh, eid, common_pid) while pid != top_pid: eid = opposite_edge(mesh, fid, eid, pid) mesh.link(2, fid2, eid) pid = opposite_point(mesh, eid, pid) #retrait de l'ancienne face mesh.remove_wisp(2, fid) #mise a jour des faces modifiees divided_faces.append((fid, [fid1, fid2])) #ajout des faces a la liste des faces a traiter si necessaire for fid in (fid1, fid2): if mesh.nb_borders(2, fid) > 3: to_divide_face.add(fid) return divided_faces, divided_edges