Esempio n. 1
0
 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))
Esempio n. 2
0
 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))
Esempio n. 3
0
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)
Esempio n. 4
0
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)
Esempio n. 5
0
    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
Esempio n. 6
0
    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
Esempio n. 7
0
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
Esempio n. 8
0
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