mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-28 18:45:54 -05:00
226 lines
No EOL
6.1 KiB
Python
226 lines
No EOL
6.1 KiB
Python
#!BPY
|
|
|
|
"""
|
|
Name: 'OpenCTM (*.ctm)...'
|
|
Blender: 248
|
|
Group: 'Import'
|
|
Tooltip: 'Import an OpenCTM file'
|
|
"""
|
|
|
|
import bpy
|
|
import Blender
|
|
from Blender import Mesh, Scene, Window, sys, Image, Draw
|
|
import BPyMesh
|
|
import math
|
|
import ctypes
|
|
from ctypes import *
|
|
from ctypes.util import find_library
|
|
import os
|
|
|
|
|
|
__author__ = "Marcus Geelnard"
|
|
__version__ = "0.4"
|
|
__bpydoc__ = """\
|
|
This script imports OpenCTM files into Blender. It supports normals,
|
|
colours, and UV coordinates per vertex.
|
|
"""
|
|
|
|
# Copyright (C) 2009-2010: Marcus Geelnard
|
|
#
|
|
# This program is released to the public domain.
|
|
#
|
|
# Portions of this code are taken from ply_import.py in Blender
|
|
# 2.48.
|
|
#
|
|
# The script uses the OpenCTM shared library (.so, .dll, etc). If no
|
|
# such library can be found, the script will exit with an error
|
|
# message.
|
|
#
|
|
# v0.4, 2009-09-14
|
|
# - Updated to OpenCTM API version 0.8 (texture maps are now called UV maps)
|
|
#
|
|
# v0.3, 2009-08-09
|
|
# - Changed vertex color attribute name to "Color"
|
|
#
|
|
# v0.2, 2009-06-30
|
|
# - Better error reporting
|
|
#
|
|
# v0.1, 2009-05-31
|
|
# - First test version with an alpha version of the OpenCTM API
|
|
#
|
|
|
|
def file_callback(filename):
|
|
|
|
Window.WaitCursor(1)
|
|
try:
|
|
# Load the OpenCTM shared library
|
|
if os.name == 'nt':
|
|
libHDL = WinDLL('openctm.dll')
|
|
else:
|
|
libName = find_library('openctm')
|
|
if not libName:
|
|
Blender.Draw.PupMenu('Could not find the OpenCTM shared library')
|
|
return
|
|
libHDL = CDLL(libName)
|
|
if not libHDL:
|
|
Blender.Draw.PupMenu('Could not open the OpenCTM shared library')
|
|
return
|
|
|
|
# Get all the functions from the shared library that we need
|
|
ctmNewContext = libHDL.ctmNewContext
|
|
ctmNewContext.argtypes = [c_int]
|
|
ctmNewContext.restype = c_void_p
|
|
ctmFreeContext = libHDL.ctmFreeContext
|
|
ctmFreeContext.argtypes = [c_void_p]
|
|
ctmGetError = libHDL.ctmGetError
|
|
ctmGetError.argtypes = [c_void_p]
|
|
ctmGetError.restype = c_int
|
|
ctmErrorString = libHDL.ctmErrorString
|
|
ctmErrorString.argtypes = [c_int]
|
|
ctmErrorString.restype = c_char_p
|
|
ctmLoad = libHDL.ctmLoad
|
|
ctmLoad.argtypes = [c_void_p, c_char_p]
|
|
ctmGetInteger = libHDL.ctmGetInteger
|
|
ctmGetInteger.argtypes = [c_void_p, c_int]
|
|
ctmGetInteger.restype = c_int
|
|
ctmGetString = libHDL.ctmGetString
|
|
ctmGetString.argtypes = [c_void_p, c_int]
|
|
ctmGetString.restype = c_char_p
|
|
ctmGetIntegerArray = libHDL.ctmGetIntegerArray
|
|
ctmGetIntegerArray.argtypes = [c_void_p, c_int]
|
|
ctmGetIntegerArray.restype = POINTER(c_int)
|
|
ctmGetFloatArray = libHDL.ctmGetFloatArray
|
|
ctmGetFloatArray.argtypes = [c_void_p, c_int]
|
|
ctmGetFloatArray.restype = POINTER(c_float)
|
|
ctmGetNamedAttribMap = libHDL.ctmGetNamedAttribMap
|
|
ctmGetNamedAttribMap.argtypes = [c_void_p, c_char_p]
|
|
ctmGetNamedAttribMap.restype = c_int
|
|
|
|
# Create an OpenCTM context
|
|
ctm = ctmNewContext(0x0101) # CTM_IMPORT
|
|
try:
|
|
# Load the file
|
|
ctmLoad(ctm, c_char_p(filename))
|
|
err = ctmGetError(ctm)
|
|
if err != 0:
|
|
s = ctmErrorString(err)
|
|
Blender.Draw.PupMenu('Could not load the file: ' + s)
|
|
return
|
|
|
|
# Get the mesh properties
|
|
vertexCount = ctmGetInteger(ctm, 0x0301) # CTM_VERTEX_COUNT
|
|
triangleCount = ctmGetInteger(ctm, 0x0302) # CTM_TRIANGLE_COUNT
|
|
hasNormals = ctmGetInteger(ctm, 0x0303) # CTM_HAS_NORMALS
|
|
texMapCount = ctmGetInteger(ctm, 0x0304) # CTM_UV_MAP_COUNT
|
|
|
|
# Get indices
|
|
pindices = ctmGetIntegerArray(ctm, 0x0601) # CTM_INDICES
|
|
|
|
# Get vertices
|
|
pvertices = ctmGetFloatArray(ctm, 0x0602) # CTM_VERTICES
|
|
|
|
# Get normals
|
|
if hasNormals == 1:
|
|
pnormals = ctmGetFloatArray(ctm, 0x0603) # CTM_NORMALS
|
|
else:
|
|
pnormals = None
|
|
|
|
# Get texture coordinates
|
|
if texMapCount > 0:
|
|
ptexCoords = ctmGetFloatArray(ctm, 0x0700) # CTM_UV_MAP_1
|
|
else:
|
|
ptexCoords = None
|
|
|
|
# Get colors
|
|
colorMap = ctmGetNamedAttribMap(ctm, c_char_p('Color'))
|
|
if colorMap != 0:
|
|
pcolors = ctmGetFloatArray(ctm, colorMap)
|
|
else:
|
|
pcolors = None
|
|
|
|
# We will be creating vectors...
|
|
Vector = Blender.Mathutils.Vector
|
|
|
|
# Create Blender verts and faces
|
|
verts = []
|
|
for i in range(vertexCount):
|
|
verts.append(Vector(pvertices[i * 3], pvertices[i * 3 + 1], pvertices[i * 3 + 2]))
|
|
faces = []
|
|
for i in range(triangleCount):
|
|
faces.append((pindices[i * 3], pindices[i * 3 + 1], pindices[i * 3 + 2]))
|
|
|
|
# Create a new Blender mesh from the loaded mesh data
|
|
objName = Blender.sys.splitext(Blender.sys.basename(filename))[0]
|
|
mesh = bpy.data.meshes.new(objName)
|
|
mesh.verts.extend(verts)
|
|
mesh.faces.extend(faces)
|
|
|
|
# Add normals?
|
|
if pnormals:
|
|
i = 0
|
|
for v in mesh.verts:
|
|
n = Vector(pnormals[i], pnormals[i + 1], pnormals[i + 2])
|
|
v.no = n
|
|
i += 3
|
|
else:
|
|
mesh.calcNormals()
|
|
|
|
# Always use smooth normals - regardless if they are defined or calculated
|
|
for f in mesh.faces:
|
|
f.smooth = 1
|
|
|
|
# Add texture coordinates?
|
|
if ptexCoords:
|
|
mesh.faceUV = 1
|
|
for f in mesh.faces:
|
|
for j, v in enumerate(f.v):
|
|
k = v.index
|
|
if k < vertexCount:
|
|
uv = f.uv[j]
|
|
uv[0] = ptexCoords[k * 2]
|
|
uv[1] = ptexCoords[k * 2 + 1]
|
|
|
|
# Add colors?
|
|
if pcolors:
|
|
mesh.vertexColors = 1
|
|
for f in mesh.faces:
|
|
for j, v in enumerate(f.v):
|
|
k = v.index
|
|
if k < vertexCount:
|
|
col = f.col[j]
|
|
r = int(round(pcolors[k * 4] * 255.0))
|
|
if r < 0: r = 0
|
|
if r > 255: r = 255
|
|
g = int(round(pcolors[k * 4 + 1] * 255.0))
|
|
if g < 0: g = 0
|
|
if g > 255: g = 255
|
|
b = int(round(pcolors[k * 4 + 2] * 255.0))
|
|
if b < 0: b = 0
|
|
if b > 255: b = 255
|
|
col.r = r
|
|
col.g = g
|
|
col.b = b
|
|
|
|
# Select all vertices in the mesh
|
|
mesh.sel = True
|
|
|
|
# Create a new object with the new mesh
|
|
scn = bpy.data.scenes.active
|
|
scn.objects.selected = []
|
|
obj = scn.objects.new(mesh, objName)
|
|
scn.objects.active = obj
|
|
|
|
finally:
|
|
# Free the OpenCTM context
|
|
ctmFreeContext(ctm)
|
|
|
|
finally:
|
|
Window.WaitCursor(0)
|
|
|
|
Blender.Redraw()
|
|
|
|
def main():
|
|
Blender.Window.FileSelector(file_callback, 'Import OpenCTM', '*.ctm')
|
|
|
|
if __name__=='__main__':
|
|
main() |