Hi,
I implemented a class called Sheet, very similar to the Rope class but that uses a NurbsSurfaceEvaluator and a SheetNode instead of a NurbsCurveEvaluator and a RopeNode.
I’ve several problems, the first, most obvious, is that it’s awfully slow. A test with a simple surface with 6 subdivisions along u and v runs at 8fps. I don’t see anything weird in PStats but maybe I’m not looking in the correct place.
Second problem, I can’t see the back face when not in wireframe mode.
Here’s the Sheet class and a test file:
# -*- coding: utf-8-*-
from pandac.PandaModules import NodePath, SheetNode, NurbsSurfaceEvaluator
from pandac.PandaModules import VBase3, Point3
class Sheet(NodePath):
showSheet = base.config.GetBool('show-sheet', 1)
def __init__(self, name="sheet"):
self.sheetNode = SheetNode(name)
self.surface = NurbsSurfaceEvaluator()
self.sheetNode.setSurface(self.surface)
self.sheetNode.setUseVertexColor(True)
NodePath.__init__(self, self.sheetNode)
self.name = name
def setup(self, uOrder, vOrder, uVertsNum, verts, uKnots=None, vKnots=None):
self.uOrder = uOrder
self.vOrder = vOrder
self.verts = verts
self.uVertsNum = uVertsNum
self.vVertsNum = len(self.verts) / self.uVertsNum
self.uKnots = uKnots
self.vKnots = vKnots
self.recompute()
def recompute(self):
if not self.showSheet:
return
numVerts = len(self.verts)
self.surface.reset(numVerts, numVerts)
self.surface.setUOrder(self.uOrder)
self.surface.setVOrder(self.vOrder)
defaultNodePath = None
defaultPoint = (0, 0, 0)
defaultColor = (1, 1, 1, 1)
useVertexColor = self.sheetNode.getUseVertexColor()
# this function exists for ropeNode but not for sheetNode ?
vcd = 0 #self.sheetNode.getVertexColorDimension()
idx = 0
for v in range(self.vVertsNum):
for u in range(self.uVertsNum):
vertex = self.verts[idx]
if isinstance(vertex, tuple):
nodePath, point = vertex
color = defaultColor
else:
nodePath = vertex.get('node', defaultNodePath)
point = vertex.get('point', defaultPoint)
color = vertex.get('color', defaultColor)
if isinstance(point, tuple):
if (len(point) >= 4):
self.surface.setVertex(u, v, \
VBase4(point[0], point[1], point[2], point[3]))
else:
self.surface.setVertex(u, v, \
VBase3(point[0], point[1], point[2]))
else:
self.surface.setVertex(u, v, point)
if nodePath:
self.surface.setVertexSpace(u, v, nodePath)
if useVertexColor:
self.surface.setExtendedVertex(u, v, vcd + 0, color[0])
self.surface.setExtendedVertex(u, v, vcd + 1, color[1])
self.surface.setExtendedVertex(u, v, vcd + 2, color[2])
self.surface.setExtendedVertex(u, v, vcd + 3, color[3])
idx +=1
if self.uKnots != None:
for i in range(len(self.uKnots)):
self.surface.setUKnot(i, self.uKnots[i])
if self.vKnots != None:
for i in range(len(self.vKnots)):
self.surface.setVKnot(i, self.vKnots[i])
self.sheetNode.resetBound(self)
def normalize(self, uKnots = True, vKnots = True):
if uKnots:
self.surface.normalizeUKnots()
if vKnots:
self.surface.normalizeVKnots()
def getPoints(self, len):
result = self.surface.evaluate(self)
numPts = len
sheetPts = []
for i in range(numPts):
pt = Point3()
u = v = i / float(numPts -1)
result.evalPoint(u,v, pt)
sheetPts.append(pt)
return sheetPts
And a test file:
# -*- coding: utf-8-*-
from pandac.PandaModules import loadPrcFileData
loadPrcFileData("", "show-frame-rate-meter t")
loadPrcFileData("", "want-tk #t")
loadPrcFileData("", "want-pstats 1")
loadPrcFileData("", "pstats-tasks 1")
import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from sheet import Sheet
import sys
base.oobe()
do = DirectObject()
do.accept("escape", sys.exit)
do.accept("w", lambda : base.wireframeOn())
vKnot = uKnot = [0,0,0,0,1,1,1,1]
surface = Sheet("flat")
verts = [{'node':None, 'point': (3, 0, 0), 'color' : (0,0,0,0)} ,
{'node':None, 'point': (6, 0, 0), 'color' : (0,0,0,0)} ,
{'node':None, 'point': (9, 0, 0), 'color' : (0,0,0,0)} ,
{'node':None, 'point': (12, 0, 0), 'color' : (0,0,0,0)} ,
{'node':None, 'point': (3, 3, 0), 'color' : (0,1,0,0)} ,
{'node':None, 'point': (6, 3, 0), 'color' : (0,1,0,0)} ,
{'node':None, 'point': (9, 3, 0), 'color' : (0,1,0,0)} ,
{'node':None, 'point': (12, 3, 0), 'color' : (0,1,0,0)} ,
{'node':None, 'point': (3, 6, 0), 'color' : (0,0,1,0)} ,
{'node':None, 'point': (6, 6, 0), 'color' : (0,0,1,0)} ,
{'node':None, 'point': (9, 6, 0), 'color' : (0,0,1,0)} ,
{'node':None, 'point': (12, 6, 0), 'color' : (0,0,1,0)} ,
{'node':None, 'point': (3, 10, 0), 'color' : (0,1,1,0)} ,
{'node':None, 'point': (6, 10, 0), 'color' : (0,1,1,0)} ,
{'node':None, 'point': (9, 10, 0), 'color' : (0,1,1,0)} ,
{'node':None, 'point': (12, 10, 0), 'color' : (0,1,1,0)}
]
#surface.setup(4,4,4, verts, uKnot, vKnot)
#surface.reparentTo(render)
surface2 = Sheet("curve")
verts = [
{'node':None, 'point': (-7.5, -8., 0.), 'color' : (0,0,0,0)} ,
{'node':None, 'point': (-5., -8.3,- 3.), 'color' : (0,0,0,0)} ,
{'node':None, 'point': (5., -8.3,- 3.), 'color' : (0,0,0,0)} ,
{'node':None, 'point': (7.5, -8, 0.), 'color' : (0,0,0,0)} ,
{'node':None, 'point': (-9.8, -2.7, 3.), 'color' : (0,0.5,0,0)} ,
{'node':None, 'point': (-5.3, -7.2, -3.), 'color' : (0,0.5,0,0)} ,
{'node':None, 'point': (5.3, -7.2, -3.), 'color' : (0,1,0,0)} ,
{'node':None, 'point': (9.8, -2.7, 3.), 'color' : (0,1,0,0)} ,
{'node':None, 'point': (-11., 4.0, 3.), 'color' : (0,1,0,0)} ,
{'node':None, 'point': (-6., -1.8, 3.), 'color' : (0,1,0,0)} ,
{'node':None, 'point': (6., -1.8, 3.), 'color' : (0,0.5,0,0)} ,
{'node':None, 'point': (11, 4.0, 3.), 'color' : (0,0.5,0,0)} ,
{'node':None, 'point': (-9.5, 9.5, -3.), 'color' : (0,0,0,0)} ,
{'node':None, 'point': (-7., 7.8, 3.), 'color' : (0,0,0,0)} ,
{'node':None, 'point': (7., 7.8, 3.), 'color' : (0,0,0,0)} ,
{'node':None, 'point': (9.5, 9.5, -3.), 'color' : (0,0,0,0)} ,
]
surface2.setup(4,4,4, verts, uKnot, vKnot)
surface2.sheetNode.setNumUSubdiv(6)
surface2.sheetNode.setNumVSubdiv(6)
surface2.reparentTo(render)
surface2.flattenStrong()
render.analyze()
run()
I don’t master yet all the maths behind NURBS surfaces so I guess that if it’s running so slowly I may have done something wrong. Any ideas ?