-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added tests, reimplemented interface, support for writing ctm files
- Loading branch information
Showing
8 changed files
with
105 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
from .io import open, CtmFile | ||
from .io import import_mesh, export_mesh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,80 @@ | ||
from .openctm import * | ||
import numpy as np | ||
from contextlib import contextmanager | ||
|
||
@contextmanager | ||
def open(filename): | ||
ctm_context = ctmNewContext(CTM_IMPORT) | ||
yield CtmFile(ctm_context, filename) | ||
ctmFreeContext(ctm_context) | ||
|
||
class CtmFile: | ||
class CTM: | ||
|
||
def __init__(self, _vertices, _faces, _normals=None): | ||
self.vertices = _vertices | ||
self.faces = _faces | ||
self.normals = _normals | ||
|
||
def __eq__(self, other): | ||
return (self.vertices == other.vertices).all() and (self.faces == other.faces).all() | ||
|
||
|
||
def __init__(self, ctm_context, filename): | ||
self.ctm = ctm_context | ||
ctmLoad(self.ctm, str(filename).encode('utf-8')) | ||
err = ctmGetError(self.ctm) | ||
def import_mesh(_filename): | ||
ctm_context = ctmNewContext(CTM_IMPORT) | ||
try: | ||
ctmLoad(ctm_context, str(_filename).encode('utf-8')) | ||
err = ctmGetError(ctm_context) | ||
if err != CTM_NONE: | ||
raise IOError("Error loading file: " + str(ctmErrorString(err))) | ||
raise IOError("Error loading file: %s" % str(ctmErrorString(err))) | ||
|
||
# read vertices | ||
vertex_count = ctmGetInteger(ctm_context, CTM_VERTEX_COUNT) | ||
vertex_ctm = ctmGetFloatArray(ctm_context, CTM_VERTICES) | ||
|
||
def get_vertices(self): | ||
# get vertices | ||
vertex_count = ctmGetInteger(self.ctm, CTM_VERTEX_COUNT) | ||
vertex_ctm = ctmGetFloatArray(self.ctm, CTM_VERTICES) | ||
# use fromiter to avoid loop | ||
vertices = np.fromiter(vertex_ctm, | ||
dtype=np.float, | ||
count=vertex_count * 3).reshape((-1, 3)) | ||
return vertices | ||
|
||
def get_faces(self): | ||
# get faces | ||
face_count = ctmGetInteger(self.ctm, CTM_TRIANGLE_COUNT) | ||
face_ctm = ctmGetIntegerArray(self.ctm, CTM_INDICES) | ||
# read faces | ||
face_count = ctmGetInteger(ctm_context, CTM_TRIANGLE_COUNT) | ||
face_ctm = ctmGetIntegerArray(ctm_context, CTM_INDICES) | ||
faces = np.fromiter(face_ctm, | ||
dtype=np.int, | ||
count=face_count * 3).reshape((-1, 3)) | ||
return faces | ||
|
||
def get_face_normals(self): | ||
if ctmGetInteger(self.ctm, CTM_HAS_NORMALS) == CTM_TRUE: | ||
normals_ctm = ctmGetFloatArray(self.ctm, CTM_NORMALS) | ||
# read face normals | ||
normals = None | ||
if ctmGetInteger(ctm_context, CTM_HAS_NORMALS) == CTM_TRUE: | ||
normals_ctm = ctmGetFloatArray(ctm_context, CTM_NORMALS) | ||
normals = np.fromiter(normals_ctm, | ||
dtype=np.float, | ||
count=face_count * 3).reshape((-1, 3)) | ||
return normals | ||
# if not available return None | ||
finally: | ||
ctmFreeContext(ctm_context) | ||
|
||
return CTM(vertices, faces, normals) | ||
|
||
|
||
def export_mesh(_ctm, _filename): | ||
ctm_context = ctmNewContext(CTM_EXPORT) | ||
|
||
try: | ||
vertex_count = len(_ctm.vertices) | ||
vertices = _ctm.vertices.reshape((-1, 1)) | ||
p_vertices = ctypes.cast((CTMfloat * vertex_count * 3)(), ctypes.POINTER(CTMfloat)) | ||
for i in range(vertex_count * 3): | ||
p_vertices[i] = CTMfloat(vertices[i]) | ||
|
||
face_count = len(_ctm.faces) | ||
faces = _ctm.faces.reshape((-1, 1)) | ||
p_faces = ctypes.cast((CTMuint * face_count * 3)(), ctypes.POINTER(CTMuint)) | ||
for i in range(face_count * 3): | ||
p_faces[i] = CTMuint(faces[i]) | ||
|
||
if _ctm.normals: | ||
normal_count = len(_ctm.normals) | ||
normals = _ctm.normals.reshape((-1, 1)) | ||
p_normals = ctypes.cast((CTMfloat * normal_count * 3)(), ctypes.POINTER(CTMfloat)) | ||
for i in range(normal_count * 3): | ||
p_normals[i] = CTMfloat(normals[i]) | ||
else: | ||
return None | ||
p_normals = None | ||
|
||
ctmDefineMesh(ctm_context, p_vertices, CTMuint(vertex_count), p_faces, CTMuint(face_count), p_normals) | ||
ctmSave(ctm_context, ctypes.c_char_p(_filename.encode('utf-8'))) | ||
finally: | ||
ctmFreeContext(ctm_context) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,10 @@ | ||
from setuptools import setup, Distribution, Extension | ||
import sys | ||
from setuptools import setup, Extension | ||
|
||
setup( | ||
name='python-openctm', | ||
version='1.0.2', | ||
description='Python Interface for the OpenCTM Library', | ||
long_description='Python Interface for the OpenCTM Library', | ||
version='1.0.3', | ||
description='Python Interface for the OpenCTM File Format', | ||
long_description='Python Interface for the OpenCTM File Format', | ||
url='https://github.com/lejafar/python-openctm', | ||
author='Rafael Hautekiet', | ||
author_email='[email protected]', | ||
|
@@ -24,6 +23,7 @@ | |
"Programming Language :: Python :: 3.4", | ||
"Programming Language :: Python :: 3.5", | ||
"Programming Language :: Python :: 3.6", | ||
"Programming Language :: Python :: 3.7", | ||
"Natural Language :: English", | ||
"Topic :: Scientific/Engineering", | ||
"License :: OSI Approved :: zlib/libpng License", | ||
|
Empty file.
File renamed without changes.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import unittest | ||
import os | ||
|
||
from openctm import import_mesh, export_mesh | ||
|
||
|
||
class BasicTestSuiteFunctions(unittest.TestCase): | ||
|
||
def setUp(self): | ||
self.file_dir = "tests/test-data/" | ||
|
||
def testImportVertices(self): | ||
mesh = import_mesh("%s/squares.ctm" % self.file_dir) | ||
assert len(mesh.vertices) == 124 | ||
|
||
def testImportFaces(self): | ||
mesh = import_mesh("%s/squares.ctm" % self.file_dir) | ||
assert len(mesh.faces) == 284 | ||
|
||
def testExportImport(self): | ||
original_mesh = import_mesh("%s/squares.ctm" % self.file_dir) | ||
export_mesh(original_mesh, "%s/squares_exported.ctm" % self.file_dir) | ||
|
||
exported_mesh = import_mesh("%s/squares_exported.ctm" % self.file_dir) | ||
|
||
assert original_mesh == exported_mesh | ||
os.remove("%s/squares_exported.ctm" % self.file_dir) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |