In the middle of implementing Catmull-Clark
This commit is contained in:
parent
8b540012c1
commit
ba1ec89c27
@ -1,7 +1,6 @@
|
|||||||
from .geometry import Vertex, Edge, PolygonMesh
|
from .geometry import Vertex, PolygonMesh
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
Vertex.__name__,
|
Vertex.__name__,
|
||||||
Edge.__name__,
|
|
||||||
PolygonMesh.__name__,
|
PolygonMesh.__name__,
|
||||||
]
|
]
|
||||||
|
@ -25,11 +25,10 @@ def cross(a, b):
|
|||||||
k = a.x * b.y - a.y * b.x
|
k = a.x * b.y - a.y * b.x
|
||||||
return Vertex(i, j, k)
|
return Vertex(i, j, k)
|
||||||
|
|
||||||
|
def centroid(verts):
|
||||||
def _centroid(verts):
|
xs = [v.x for v in verts]
|
||||||
xs = [vertex.x for vertex in verts]
|
ys = [v.y for v in verts]
|
||||||
ys = [vertex.y for vertex in verts]
|
zs = [v.z for v in verts]
|
||||||
zs = [vertex.z for vertex in verts]
|
|
||||||
|
|
||||||
# average each vertex component
|
# average each vertex component
|
||||||
x = sum(xs) / len(xs)
|
x = sum(xs) / len(xs)
|
||||||
@ -38,7 +37,6 @@ def _centroid(verts):
|
|||||||
|
|
||||||
return Vertex(x, y, z)
|
return Vertex(x, y, z)
|
||||||
|
|
||||||
|
|
||||||
class Vertex(object):
|
class Vertex(object):
|
||||||
'''
|
'''
|
||||||
A vertex is a position along with other information such as color, normal
|
A vertex is a position along with other information such as color, normal
|
||||||
@ -86,52 +84,12 @@ class Vertex(object):
|
|||||||
return Vertex(-self.x, -self.y, -self.z)
|
return Vertex(-self.x, -self.y, -self.z)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return pprint.pformat([self.x, self.y, self.z])
|
return u'V{0}'.format([self.x, self.y, self.z])
|
||||||
|
|
||||||
__str__ = __unicode__
|
__str__ = __unicode__
|
||||||
__repr__ = __unicode__
|
__repr__ = __unicode__
|
||||||
|
|
||||||
|
|
||||||
class Edge(object):
|
|
||||||
def __init__(self, v1, v2):
|
|
||||||
self.v1 = v1
|
|
||||||
self.v2 = v2
|
|
||||||
|
|
||||||
@property
|
|
||||||
def centroid(self):
|
|
||||||
return _centroid([self.v1, self.v2])
|
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return pprint.pformat((self.v1, self.v2))
|
|
||||||
|
|
||||||
__str__ = __unicode__
|
|
||||||
__repr__ = __unicode__
|
|
||||||
|
|
||||||
|
|
||||||
class Face(object):
|
|
||||||
'''
|
|
||||||
A face is a closed set of edges, in which a triangle face has three edges,
|
|
||||||
and a quad face has four edges. Blender stores a face as a collection of
|
|
||||||
the verts that compose it, so we shall store them thusly as well.
|
|
||||||
|
|
||||||
Blender historicaly only supported faces with an edge count of three or
|
|
||||||
four. We will cross the N-gon bridge in the future.
|
|
||||||
'''
|
|
||||||
|
|
||||||
def __init__(self, verts=None):
|
|
||||||
self.verts = verts or []
|
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return pprint.pformat(self.verts)
|
|
||||||
|
|
||||||
__str__ = __unicode__
|
|
||||||
__repr__ = __unicode__
|
|
||||||
|
|
||||||
@property
|
|
||||||
def centroid(self):
|
|
||||||
return _centroid(self.verts)
|
|
||||||
|
|
||||||
|
|
||||||
class PolygonMesh(object):
|
class PolygonMesh(object):
|
||||||
'''
|
'''
|
||||||
A polygon object is a collection of the following lists:
|
A polygon object is a collection of the following lists:
|
||||||
@ -146,7 +104,7 @@ class PolygonMesh(object):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.vertices = kwargs['vertices']
|
self.vertices = [Vertex(*v) for v in kwargs['vertices']]
|
||||||
self.edges = kwargs['edges']
|
self.edges = kwargs['edges']
|
||||||
self.faces = kwargs['faces']
|
self.faces = kwargs['faces']
|
||||||
|
|
||||||
@ -168,7 +126,7 @@ class PolygonMesh(object):
|
|||||||
>>> mesh.faces_for_edge[0]
|
>>> mesh.faces_for_edge[0]
|
||||||
[0, 1]
|
[0, 1]
|
||||||
>>> [self.face[i] for i in mesh.faces_for_edge[1]]
|
>>> [self.face[i] for i in mesh.faces_for_edge[1]]
|
||||||
[<Face 0>, <Face 1>]
|
[[...], [...], ...]
|
||||||
|
|
||||||
where 0 and 1 are indices into the face list
|
where 0 and 1 are indices into the face list
|
||||||
"""
|
"""
|
||||||
@ -216,3 +174,7 @@ class PolygonMesh(object):
|
|||||||
|
|
||||||
__str__ = __unicode__
|
__str__ = __unicode__
|
||||||
__repr__ = __unicode__
|
__repr__ = __unicode__
|
||||||
|
|
||||||
|
def centroid(self, vert_ids):
|
||||||
|
verts = [self.vertices[vid] for vid in vert_ids]
|
||||||
|
return centroid(verts)
|
||||||
|
334
surf/subd/cc.py
334
surf/subd/cc.py
@ -1,287 +1,91 @@
|
|||||||
from surf.geometry import Vertex, Edge, PolygonMesh
|
from collections import defaultdict
|
||||||
|
|
||||||
|
from surf.geometry import PolygonMesh, centroid
|
||||||
|
|
||||||
|
from pprint import pprint as pp # XXX
|
||||||
|
|
||||||
|
|
||||||
def sub_edges(self):
|
def refine(mesh):
|
||||||
temp_p = PolygonMesh()
|
new_vertices = list(mesh.vertices)
|
||||||
temp_p.edges = [Edge(), Edge()]
|
f_vert_offset = len(new_vertices)
|
||||||
# temp_p.vertices =
|
|
||||||
sub_edges[0].vertices = [self.vertices[0], self.edge_vertex]
|
|
||||||
sub_edges[1].vertices = [self.edge_vertex, self.vertices[1]]
|
|
||||||
return self.__sub_edges
|
|
||||||
|
|
||||||
|
edge_vids_for = defaultdict(list)
|
||||||
|
face_vids_for = defaultdict(list)
|
||||||
|
|
||||||
def centroid(face, poly):
|
new_edges = list(mesh.edges)
|
||||||
'''
|
new_faces = []
|
||||||
'''
|
|
||||||
|
|
||||||
# gather all face vertex coords
|
# For each face, add a face point
|
||||||
face_vertices = face.vertices
|
for cur_face_id, cur_face in enumerate(mesh.faces):
|
||||||
|
# Set each face point to be the centroid of all original points for the
|
||||||
|
# respective face.
|
||||||
|
|
||||||
xs = [vertex.x for vertex in face_vertices]
|
# here we have already created a list that is a copy of the original
|
||||||
ys = [vertex.y for vertex in face_vertices]
|
# verts. we append the new face points to that same list, and simply
|
||||||
zs = [vertex.z for vertex in face_vertices]
|
# keep track of offsets into the new vert list ... see e_vert_offset
|
||||||
|
|
||||||
# average each vertex component
|
|
||||||
x = sum(xs) / len(xs)
|
|
||||||
y = sum(ys) / len(ys)
|
|
||||||
z = sum(zs) / len(zs)
|
|
||||||
|
|
||||||
return Vertex(poly, x, y, z)
|
|
||||||
|
|
||||||
|
|
||||||
def edge_divide(edge, poly):
|
|
||||||
'''
|
|
||||||
Set each edge vertices to be the average of the two neighboring
|
|
||||||
face vertices and its two original end vertices.
|
|
||||||
'''
|
|
||||||
edge_ids = poly.edge_ids_with_parent(edge.id)
|
|
||||||
|
|
||||||
if edge_ids:
|
|
||||||
return edge_ids
|
|
||||||
else:
|
|
||||||
# otherwise split it
|
|
||||||
xs = []
|
|
||||||
ys = []
|
|
||||||
zs = []
|
|
||||||
for face in edge.faces:
|
|
||||||
centroid_v = centroid(face, None)
|
|
||||||
xs.append(centroid_v.x)
|
|
||||||
ys.append(centroid_v.y)
|
|
||||||
zs.append(centroid_v.z)
|
|
||||||
|
|
||||||
for vertex in edge.vertices:
|
|
||||||
xs.append(vertex.x)
|
|
||||||
ys.append(vertex.y)
|
|
||||||
zs.append(vertex.z)
|
|
||||||
|
|
||||||
x = sum(xs) / len(xs)
|
|
||||||
y = sum(ys) / len(ys)
|
|
||||||
z = sum(zs) / len(zs)
|
|
||||||
|
|
||||||
e0 = Edge(poly)
|
|
||||||
e1 = Edge(poly)
|
|
||||||
edge_vertex = Vertex(poly, x, y, z)
|
|
||||||
|
|
||||||
edge_vertex.edge_ids = [e0.id, e1.id]
|
|
||||||
|
|
||||||
e0.vertex_ids = [edge.vertices[0].id, edge_vertex.id]
|
|
||||||
e1.vertex_ids = [edge_vertex.id, edge.vertices[1].id]
|
|
||||||
|
|
||||||
e0.edge_ids = edge.winged_edges_at_vertex(0)
|
|
||||||
e0.edge_ids.append(e1.id)
|
|
||||||
|
|
||||||
e1.edge_ids = edge.winged_edges_at_vertex(1)
|
|
||||||
e1.edge_ids.append(e0.id)
|
|
||||||
|
|
||||||
e0.parent_id = edge.id
|
|
||||||
e1.parent_id = edge.id
|
|
||||||
|
|
||||||
# add all these to the new polygon
|
|
||||||
poly.edge_ids.append(e0.id)
|
|
||||||
poly.edge_ids.append(e1.id)
|
|
||||||
poly.vertices.append(edge_vertex.id)
|
|
||||||
|
|
||||||
return e0.id, e1.id, edge_vertex.id
|
|
||||||
|
|
||||||
|
|
||||||
def sub_faces(self):
|
|
||||||
setup_sub_divisions()
|
|
||||||
return sub_faces()
|
|
||||||
|
|
||||||
|
|
||||||
def interior_edges(self):
|
|
||||||
setup_sub_divisions()
|
|
||||||
return self.__interior_edges
|
|
||||||
|
|
||||||
|
|
||||||
def setup_sub_divisions(polygon, face):
|
|
||||||
'''
|
|
||||||
v0 ev0 v1
|
|
||||||
*------e0-----*
|
|
||||||
| | |
|
|
||||||
| | |
|
|
||||||
ev3 e|11----f5----e|1 ev1
|
|
||||||
| | |
|
|
||||||
| | |
|
|
||||||
*------e2-----*
|
|
||||||
v3 ev2 v2
|
|
||||||
'''
|
|
||||||
|
|
||||||
# create empty sub_faces that will be filled with edge references
|
|
||||||
# below
|
# below
|
||||||
# these need to at least exist so the interior edges have
|
new_face_point = mesh.centroid(cur_face)
|
||||||
# something to reference
|
new_vertices.append(new_face_point)
|
||||||
|
|
||||||
# sub_faces = [Face(polygon) for edge in face.edge_ids]
|
e_vert_offset = len(new_vertices)
|
||||||
|
|
||||||
# set up empty edge objects to be filled below
|
# For each edge, add an edge point.
|
||||||
# interior_edges = [Edge(polygon) for edge in face.edge_ids]
|
for cur_edge_id, cur_edge in enumerate(mesh.edges):
|
||||||
|
# make mapping from edge -> new_face_vert for later
|
||||||
|
face_ids_for_edge = mesh.faces_for_edge[cur_edge_id]
|
||||||
|
for fid in face_ids_for_edge:
|
||||||
|
edge_vids_for[fid].append(cur_edge_id)
|
||||||
|
|
||||||
# # each interior edge connects the exterior edge vertex (mid-point)
|
tmp_verts = []
|
||||||
# # to the faceVertex (centroid)
|
|
||||||
# for edge_id in range(len(face.edges)):
|
|
||||||
# prevIndex = (edge_id - 1) % len(face.edges)
|
|
||||||
# nextIndex = (edge_id + 1) % len(face.edges)
|
|
||||||
|
|
||||||
# # end vertices are face centroid and currEdge edge_vertex
|
# Set each edge point to be the average of the two neighbouring, (very
|
||||||
# interior_edges[edge_id].vertices = [
|
# recently calculated) face points ...
|
||||||
# face.edges[edge_id],
|
tmp_verts.extend([new_vertices[f + f_vert_offset] for f in face_ids_for_edge])
|
||||||
# edge_vertex, self.centroid
|
|
||||||
# ]
|
|
||||||
|
|
||||||
# # wing edges are the current edge's sub_edges (ordered same as
|
# ... and its two original endpoints.
|
||||||
# # vertex order) and the prev and next interior edges
|
tmp_verts.extend([mesh.vertices[vid] for vid in cur_edge])
|
||||||
# self.__interior_edges[index].edges = [
|
|
||||||
# self.edges[index].sub_edges[0],
|
|
||||||
# self.edges[index].sub_edges[1],
|
|
||||||
# self.__interior_edges[prevIndex],
|
|
||||||
# self.__interior_edges[nextIndex]
|
|
||||||
# ]
|
|
||||||
|
|
||||||
# # edge faces are the new sub_faces (current and next faces), the
|
# centroid == average
|
||||||
# # current will be define below
|
new_vertices.append(centroid(tmp_verts))
|
||||||
# # and the next will be defined on the next iteration (or
|
|
||||||
# # already defined on the last iteration)
|
|
||||||
# self.__interior_edges[index].faces = [
|
|
||||||
# self.__sub_faces[index],
|
|
||||||
# self.__sub_faces[nextIndex]
|
|
||||||
# ]
|
|
||||||
|
|
||||||
# # now reference the current edge back into the faces,
|
# For each face point, add an edge for every edge of the face, connecting
|
||||||
# # and the edge.sub_edges, and the edge.edge_vertex
|
# the face point to each edge point for the face.
|
||||||
|
for trunc_vid in xrange(len(new_vertices[f_vert_offset:e_vert_offset])):
|
||||||
|
overall_vid = f_vert_offset + trunc_vid
|
||||||
|
for edge_vid in edge_vids_for[trunc_vid]:
|
||||||
|
new_edges.append([edge_vid, overall_vid])
|
||||||
|
|
||||||
# # current subFace (same index as current interior edge)
|
# pp(new_edges)
|
||||||
# # set its edges to reference the same edges used to setup the
|
|
||||||
# # interior edge
|
|
||||||
# # order will be pretty important on these steps...
|
|
||||||
# self.__sub_faces[index].edges = [
|
|
||||||
# self.edges[index].sub_edges[0],
|
|
||||||
# self.__interior_edges[index],
|
|
||||||
# self.__interior_edges[prevIndex],
|
|
||||||
# self.edges[prevIndex].sub_edges[1]
|
|
||||||
# ]
|
|
||||||
|
|
||||||
# # just set one of the vertex edges, the other belongs to
|
# For each original point P
|
||||||
# # another face and will get added when that face is run
|
assert f_vert_offset == len(mesh.vertices)
|
||||||
# self.edges[index].edge_vertex.edges.append(
|
for new_vid in xrange(f_vert_offset):
|
||||||
# self.__interior_edges[index])
|
# take the average F of all n face points for faces touching P ...
|
||||||
|
F = centroid([mesh.vertices[vid] for vid in mesh.faces_for_vert[new_vid]])
|
||||||
|
print ">>>", F
|
||||||
|
|
||||||
# self.edges[index].sub_edges[0].faces.append(
|
# and take the average R of all n edge midpoints for edges touching P
|
||||||
# self.__sub_faces[index])
|
# wiki is wrong ... it should be the edge points, not midpoints ...
|
||||||
# self.edges[index].sub_edges[0].faces.append(
|
edges = [mesh.edges[eid] for eid in mesh.edges_for_vert[new_vid]]
|
||||||
# self.__sub_faces[index])
|
e_verts = []
|
||||||
pass
|
for edge in edges:
|
||||||
|
e_verts.extend([mesh.vertices[vid] for vid in edge])
|
||||||
|
|
||||||
|
R = centroid(e_verts)
|
||||||
|
# where each edge midpoint is the average of its two endpoint vertices.
|
||||||
|
# Move each original point to the point (or add it to new_verts)
|
||||||
|
v = (F + 2 * R + (len(edges) - 3) * new_vertices[new_vid]) / len(edges)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def subdivide_face(poly, face):
|
|
||||||
# '''
|
|
||||||
# '''
|
|
||||||
|
|
||||||
# # find face centroid
|
if __name__ == '__main__':
|
||||||
# fc = face.centroid
|
import json
|
||||||
|
from surf.geometry import PolygonMesh
|
||||||
# # find edge vertices
|
from surf.subd.cc import refine
|
||||||
# for edge in face.edges:
|
|
||||||
# x, y, z = edge_mid_vertex(edge)
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def refine(poly):
|
cube = json.load(open('blender/samples/cube.json', 'r'))
|
||||||
'''
|
p = PolygonMesh(**cube)
|
||||||
For each face, add a face vertex
|
q = refine(p)
|
||||||
Set each face vertex to be the centroid of all original vertices for
|
|
||||||
the respective face.
|
|
||||||
For each edge, add an edge vertex.
|
|
||||||
Set each edge vertex to be the average of the two neighbouring face
|
|
||||||
vertices and its two original endvertices.
|
|
||||||
For each face vertex, add an edge for every edge of the face, connecting
|
|
||||||
the face vertex to each edge vertex for the face.
|
|
||||||
For each original vertex P, take the average F of all n face vertices for
|
|
||||||
faces touching P, and take the average R of all n edge midvertices for
|
|
||||||
edges touching P, where each edge midvertex is the average of its two
|
|
||||||
endvertex vertices. Move each original vertex to the vertex
|
|
||||||
'''
|
|
||||||
|
|
||||||
# create a new storage container for the items
|
|
||||||
new_poly = PolygonMesh()
|
|
||||||
|
|
||||||
# for now just test with the first face
|
|
||||||
start_face = poly.faces[0]
|
|
||||||
|
|
||||||
# go through the face vertices and add them to the new polygon
|
|
||||||
for vertex in start_face.vertices:
|
|
||||||
# truly, this needs to be a 'copy' of the vertex, I'll fix that later
|
|
||||||
new_poly.vertices.append(vertex)
|
|
||||||
|
|
||||||
# find the face centroid
|
|
||||||
# and add the face centroid to the new polygon
|
|
||||||
start_centroid = centroid(start_face, new_poly)
|
|
||||||
new_poly.vertices.append(start_centroid)
|
|
||||||
|
|
||||||
# for each edge on the face,
|
|
||||||
for edge in start_face.edges:
|
|
||||||
# divide that edge into two new edges with an edge vertex
|
|
||||||
# set their parent object as the original edge
|
|
||||||
new_e0_id, new_e1_id, edge_v_id = edge_divide(edge, new_poly)
|
|
||||||
|
|
||||||
# create a new edge connecting the centroid to the edge_vertex
|
|
||||||
centroid_to_edge = Edge(new_poly)
|
|
||||||
new_poly.edges.append(centroid_to_edge)
|
|
||||||
|
|
||||||
# set the new edge's vertex references
|
|
||||||
centroid_to_edge.vertex_ids = [edge_v_id, start_centroid.id]
|
|
||||||
|
|
||||||
# set the new edge's winged_edge references
|
|
||||||
# centroid_to_edge.edge_ids = poly.edges ==> get edge by id not yet
|
|
||||||
# implemented... edge_v_id.edges
|
|
||||||
|
|
||||||
# set the edge vertex edge references
|
|
||||||
edge_v_id.edges.append(centroid_to_edge.id)
|
|
||||||
|
|
||||||
# set the centroid's edge reference
|
|
||||||
start_centroid.edge_ids.append(centroid_to_edge.id)
|
|
||||||
|
|
||||||
# now walk through the edges connected to the centroid
|
|
||||||
start_centroid.edges[0]
|
|
||||||
# need to get an adjacent edge, based on the the shared vertex of the
|
|
||||||
# original polygon... centroid to edge_vertex to shared point...
|
|
||||||
|
|
||||||
# start_face.neighbors
|
|
||||||
|
|
||||||
# f = sum(list(
|
|
||||||
# set(face_vertices)), Vertex()) / len(list(set(face_vertices)))
|
|
||||||
# r = sum(list(
|
|
||||||
# set(edge_mid_points)), Vertex())
|
|
||||||
# / len(list(set(edge_mid_points)))
|
|
||||||
# p = vertex
|
|
||||||
# n = len(vertex.edges)
|
|
||||||
# v = (f + 2.0 * r + (n - 3.0) * p) / n
|
|
||||||
# newVertices.append(v)
|
|
||||||
|
|
||||||
# for vertex, newVertex in zip(poly.vertices, newVertices):
|
|
||||||
# vertex.x = newVertex.x
|
|
||||||
# vertex.y = newVertex.y
|
|
||||||
# vertex.z = newVertex.z
|
|
||||||
# # so now what.........
|
|
||||||
# # (F + 2R + (n-3) P) / n
|
|
||||||
# #
|
|
||||||
# # F = average of all face vertices touching P
|
|
||||||
# # R = average of all edge vertices touching P
|
|
||||||
# # P original point
|
|
||||||
# # n = number of edges connecting to P
|
|
||||||
|
|
||||||
# p.faces = faces
|
|
||||||
# p.vertices = vertices
|
|
||||||
# p.edges = edges
|
|
||||||
|
|
||||||
# # plotting these in excel seems to show the correct values (at first
|
|
||||||
# # glace...)
|
|
||||||
|
|
||||||
# # so now what.........
|
|
||||||
# # (F + 2R + (n-3) P) / n
|
|
||||||
# #
|
|
||||||
# # F = average of all face vertices touching P
|
|
||||||
# # R = average of all edge vertices touching P
|
|
||||||
# # P original point
|
|
||||||
# # n = face vertices or edge vertices (should be the same number)
|
|
||||||
# return PolygonMesh(vertices, edges, faces)
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from .vertex import TestVertex
|
from .vertex import TestVertex
|
||||||
from .edge import TestEdge
|
from .edge import TestEdge
|
||||||
from .polymesh import TestPM
|
from .polymesh import TestPM
|
||||||
|
from .subd.cc import TestCC
|
||||||
|
|
||||||
|
|
||||||
# I only use the convoluted Class.__name__ to pass pyflakes (it complains about
|
# I only use the convoluted Class.__name__ to pass pyflakes (it complains about
|
||||||
@ -10,4 +11,5 @@ __all__ = [
|
|||||||
TestVertex.__name__,
|
TestVertex.__name__,
|
||||||
TestEdge.__name__,
|
TestEdge.__name__,
|
||||||
TestPM.__name__,
|
TestPM.__name__,
|
||||||
|
TestCC.__name__,
|
||||||
]
|
]
|
||||||
|
@ -1,22 +1,24 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from surf.geometry import Vertex, Edge
|
from surf.geometry import Vertex, PolygonMesh
|
||||||
|
|
||||||
|
|
||||||
class TestEdge(unittest.TestCase):
|
class TestEdge(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.origin = Vertex(0, 0, 0)
|
path, file_name = os.path.split(__file__)
|
||||||
self.v1 = Vertex(-1, -1, -1)
|
self.samples_dir = os.path.join(path, os.pardir, os.pardir,
|
||||||
self.v2 = Vertex(1, 1, 1)
|
'blender', 'samples')
|
||||||
|
self.cube_file_name = os.path.join(self.samples_dir, 'cube.json')
|
||||||
self.v3 = Vertex(5, 4, 3)
|
cube_json = json.load(open(self.cube_file_name, 'r'))
|
||||||
self.v4 = Vertex(10, -2, 13)
|
self.cube = PolygonMesh(**cube_json)
|
||||||
self.v5 = Vertex(-4, 15.3, 100)
|
|
||||||
|
|
||||||
def test_centroid(self):
|
def test_centroid(self):
|
||||||
e = Edge(self.v1, self.v3)
|
e = self.cube.edges[0]
|
||||||
self.assertEqual(e.centroid, Vertex(2, 1.5, 1))
|
v = self.cube.centroid(e)
|
||||||
|
self.assertEqual(v, Vertex(-1, 0, 1))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -17,9 +17,9 @@ class TestPM(unittest.TestCase):
|
|||||||
def test_cube_load(self):
|
def test_cube_load(self):
|
||||||
p = PolygonMesh(**self.cube)
|
p = PolygonMesh(**self.cube)
|
||||||
v = p.vertices[0]
|
v = p.vertices[0]
|
||||||
self.assertAlmostEqual(v[0], -1.0)
|
self.assertAlmostEqual(v.x, -1.0)
|
||||||
self.assertAlmostEqual(v[1], -1.0)
|
self.assertAlmostEqual(v.y, -1.0)
|
||||||
self.assertAlmostEqual(v[2], -1.0)
|
self.assertAlmostEqual(v.z, -1.0)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
5
surf/test/subd/__init__.py
Normal file
5
surf/test/subd/__init__.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from .cc import TestCC
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
TestCC.__name__,
|
||||||
|
]
|
24
surf/test/subd/cc.py
Normal file
24
surf/test/subd/cc.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from surf.geometry import PolygonMesh
|
||||||
|
from surf.subd import cc
|
||||||
|
|
||||||
|
|
||||||
|
class TestCC(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
path, file_name = os.path.split(__file__)
|
||||||
|
self.samples_dir = os.path.join(path, os.pardir, os.pardir, os.pardir,
|
||||||
|
'blender', 'samples')
|
||||||
|
self.cube_file_name = os.path.join(self.samples_dir, 'cube.json')
|
||||||
|
self.cube = json.load(open(self.cube_file_name, 'r'))
|
||||||
|
|
||||||
|
def test_refine(self):
|
||||||
|
p = PolygonMesh(**self.cube)
|
||||||
|
p2 = cc.refine(p)
|
||||||
|
print p2
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main(verbosity=3)
|
Loading…
Reference in New Issue
Block a user