Коммит 61cc300f создал по автору generalpancakemstr's avatar generalpancakemstr
Просмотр файлов

Integrate pyOpenSubdiv and OpenSubdiv node into Sverchok.

владелец 47a9e026
......@@ -150,6 +150,17 @@ except ImportError:
info(numba_d.message)
numba = None
pyOpenSubdiv_d = sv_dependencies["pyOpenSubdiv"] = SvDependency("pyOpenSubdiv","https://github.com/GeneralPancakeMSTR/pyOpenSubdivision")
pyOpenSubdiv_d.pip_installable = True
try:
import pyOpenSubdiv
pyOpenSubdiv_d.message = "pyOpenSubdiv package is available"
pyOpenSubdiv_d.module = pyOpenSubdiv
except ImportError:
pyOpenSubdiv_d.message = "sv: pyOpenSubdiv package is not available, Catmull-Clark subdivision will not be available"
info(pyOpenSubdiv_d.message)
pyOpenSubdiv = None
good_names = [d.package for d in sv_dependencies.values() if d.module is not None and d.package is not None]
if good_names:
info("sv: Dependencies available: %s.", ", ".join(good_names))
......
......@@ -21,8 +21,17 @@ from bpy.props import IntProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, match_long_repeat
from sverchok.utils.modules.ctypes_pyOpenSubdiv import pyOpenSubdiv
openSubdivide = pyOpenSubdiv
# from sverchok.utils.modules.ctypes_pyOpenSubdiv import pyOpenSubdiv
# openSubdivide = pyOpenSubdiv
enable_module = False
try:
import pyOpenSubdiv
from pyOpenSubdiv.pysubdivision import pysubdivide
enable_module = True
except ModuleNotFoundError:
enable_module = False
from itertools import chain
import traceback
......@@ -44,6 +53,9 @@ class SvOpenSubdivideNode(bpy.types.Node,SverchCustomTreeNode):
self.outputs.new('SvStringsSocket', "Faces")
def process(self):
if not enable_module:
raise Exception("The dependent library is not installed (pyOpenSubdiv).")
vert_sets = self.inputs['Vertices'].sv_get(default=[],deepcopy=False)
edges = []
face_sets = self.inputs['Faces'].sv_get(default=[],deepcopy=False)
......@@ -69,7 +81,7 @@ class SvOpenSubdivideNode(bpy.types.Node,SverchCustomTreeNode):
faceVerts = list(chain.from_iterable(faces))
vertsPerFace = [len(face) for face in faces]
new_mesh = openSubdivide(subdivision_level,vertices,faceVerts,vertsPerFace)
new_mesh = pysubdivide(subdivision_level,vertices,faceVerts,vertsPerFace)
new_meshes['vertices'].append(new_mesh['vertices']) # ctypes implementation
new_meshes['edges'].append(new_mesh['edges'])
......@@ -90,6 +102,3 @@ def register():
def unregister():
bpy.utils.unregister_class(SvOpenSubdivideNode)
......@@ -573,6 +573,7 @@ dependencies, or install only some of them.""")
draw_message(box, "circlify")
draw_message(box, "cython")
draw_message(box, "numba")
draw_message(box, "pyOpenSubdiv")
draw_freecad_ops()
......
import ctypes
import sys
from sys import platform
import numpy as np
if platform == 'linux' or platform == 'linux2':
OpenSubdiv_clib = ctypes.cdll.LoadLibrary('./ctypes_OpenSubdiv.so')
elif platform == 'darwin':
# OSX
pass
elif platform == 'win32':
import os
here = os.path.dirname(__file__).replace('\\','/')
OpenSubdiv_clib = ctypes.CDLL(os.path.join(here,"ctypes_OpenSubdiv.dll"))
def pyOpenSubdiv(subdivision_level,vertices,faceVerts,vertsPerFace):
################ Subdivide ################
refine_topology = OpenSubdiv_clib.subdivider_refine_topology
refine_topology.argtypes = [
ctypes.c_int, # maxlevel
ctypes.c_int, # n_verts
ctypes.c_int, # n_faces
ctypes.POINTER((ctypes.c_float)*3), # vertices
ctypes.POINTER(ctypes.c_int), # faceVerts
ctypes.POINTER(ctypes.c_int) # vertsPerFace
]
n_verts = len(vertices)
n_faces = len(vertsPerFace)
vertices_array = ctypes.ARRAY(n_verts,ctypes.c_float*3)(*[(ctypes.c_float*3)(*vert) for vert in vertices])
faceVerts_array = (ctypes.c_int*len(faceVerts))(*faceVerts)
vertsPerFace_array = (ctypes.c_int*n_faces)(*vertsPerFace)
refine_topology(
subdivision_level,
n_verts,
n_faces,
vertices_array, # vertices (as c array)
faceVerts_array, # faceVerts (as c array)
vertsPerFace_array # vertsPerFace (as c array)
)
################ Get Results ################
#### Gather New Mesh Information ####
OpenSubdiv_clib.nn_verts.restypes = ctypes.c_int
new_nverts = OpenSubdiv_clib.nn_verts()
OpenSubdiv_clib.nn_edges.restypes = ctypes.c_int
new_nedges = OpenSubdiv_clib.nn_edges()
OpenSubdiv_clib.nn_faces.restypes = ctypes.c_int
new_nfaces = OpenSubdiv_clib.nn_faces()
#### Extract New Vertices ####
# new_vert_arrays = []
# for i in range(new_nverts):
# new_vert_arrays.append((ctypes.c_float*3)(*[0,0,0]))
# (ctypes.c_float*3)(*[0,0,0])
# Turns out you can do this in one line
# It's absolutely absurd, though.
new_vertices = (ctypes.ARRAY(new_nverts,ctypes.c_float*3))(*[(ctypes.c_float*3)(*[0,0,0])])
OpenSubdiv_clib.new_vertices.argtypes = [ctypes.ARRAY(new_nverts,ctypes.c_float*3)]
OpenSubdiv_clib.new_vertices(new_vertices)
#### Extract New Edges ####
new_edges = (ctypes.ARRAY(new_nedges,ctypes.c_int*2))(*[(ctypes.c_int*2)(*[0,0])])
OpenSubdiv_clib.new_edges.argtypes = [ctypes.ARRAY(new_nedges,ctypes.c_int*2)]
OpenSubdiv_clib.new_edges(new_edges)
#### Extract New Faces ####
new_faces = (ctypes.ARRAY(new_nfaces,ctypes.c_int*4))(*[(ctypes.c_int*4)(*[0,0,0,0])])
OpenSubdiv_clib.new_faces.argtypes = [ctypes.ARRAY(new_nfaces,ctypes.c_int*4)]
OpenSubdiv_clib.new_faces(new_faces)
################ Return ################
# print(timeit.timeit(lambda: np.ctypeslib.as_array(new_vertices),number=10000)) # This is instantaneous
# print(timeit.timeit(lambda: np.ctypeslib.as_array(new_vertices).tolist(),number=10000)) # This is ridiculously slow
# tolist() is quite slow but it seems necessary for blender.
# Er, well, maybe it's not that bad idk.
new_mesh = {
'vertices' : np.ctypeslib.as_array(new_vertices).tolist(),
'edges' : np.ctypeslib.as_array(new_edges).tolist(),
'faces' : np.ctypeslib.as_array(new_faces).tolist()
}
return new_mesh
if __name__=="__main__":
import timeit
from itertools import chain
verts = [
[-0.5,-0.5, 0.5],
[ 0.5,-0.5, 0.5],
[-0.5, 0.5, 0.5],
[ 0.5, 0.5, 0.5],
[-0.5, 0.5,-0.5],
[ 0.5, 0.5,-0.5],
[-0.5,-0.5,-0.5],
[ 0.5,-0.5,-0.5]
]
faces = [
[0, 1, 3, 2],
[2, 3, 5, 4],
[4, 5, 7, 6],
[6, 7, 1, 0],
[1, 7, 5, 3],
[6, 0, 2, 4]
]
faceVerts = list(chain.from_iterable(faces))
vertsPerFace = [len(face) for face in faces]
new_mesh = pyOpenSubdiv(1,verts,faceVerts,vertsPerFace)
for i,vert in enumerate(new_mesh['vertices']):
print(f'v {vert}')
if(i>8):
print('...')
break
for i,edge in enumerate(new_mesh['edges']):
print(f'e {edge}')
if(i>8):
print('...')
break
for i,face in enumerate(new_mesh['faces']):
print(f'f {face}')
if(i>8):
print('...')
break
# Pretty fast?
# print(timeit.timeit(lambda: pyOpenSubdiv(2,verts,faceVerts,vertsPerFace),number = 10000))
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать