Hello,
I try to clip a shape in several pieces by using ClipPlane. In order to do this, I display several times the shape, each one clipped with different ClipPlane. When I do this on shapes like Circle or Square (in fact, a Rectangle with the same width and height), it works well :
But when the Rectangle is really rectangular, it doesn’t always works. If the shape is near the “center’s” ClipPlane, the clipping is effectively done :
And if I try to move away the shape from the “center’s” ClipPlane, it does very weird things like this :
I try several shapes (Circle, Line, Polygon) and the clipping always works. The only case in which it doesn’t work is rectangular rectangle.
Here is the code, if somebody wants to try.
#panda
from pandac.PandaModules import *
# need to be before the Direct Start Import
loadPrcFileData("", "framebuffer-multisample 1")
loadPrcFileData("", "want-directtools 1")
loadPrcFileData("", "want-tk 1")
import direct.directbase.DirectStart
# standlib
import os, sys
mesh_dico = {}
class Primitive (object):
z = 0
def __init__(self, node, pos, scale, heading = None, color = None):
self.node = node
self.setPos(pos)
self.setScale(scale)
if color is not None : self.node.setColor(*color)
if heading is not None : self.node.setHpr(heading, 0, 0)
def setPos(self, pos):
pos = self.add_z(pos)
self.node.setPos(pos)
def add_z(self, point):
assert len(point) == 2
return Vec3(point[0], point[1], self.__class__.z)
def delete(self):
self.node.detachNode()
class Rect(Primitive):
def __init__(self, pos, size, color=None, heading=None, parent = None):
node = create_placeholder(mesh_dico, 'square', parent)
Primitive.__init__(self, node, pos, size, heading, color)
def setScale(self, scale):
self.node.setScale(scale[0], scale[1], 1)
class Circle (Primitive):
def __init__(self, center, radius, color, parent = None):
node = create_placeholder(mesh_dico, 'circle', parent)
Primitive.__init__(self, node, center, radius, color = color)
def setScale(self, scale):
self.node.setScale(scale, scale, 1)
def GEN_counter(i=-1):
while True:
i += 1
yield i
def unique_name(prefix='id', suffix='', g=GEN_counter()):
name = prefix+str(g.next())
return name
def create_placeholder(dico, mesh_name, parent = None):
if parent is None : parent = render.attachNewNode('shader')
placeholder = parent.attachNewNode(unique_name())
dico[mesh_name].instanceTo(placeholder)
return placeholder
def load_meshes():
mesh_dico['square'] = loader.loadModel("square.egg")
mesh_dico['square'].setScale(0.3048,0.3048,0.3048)
mesh_dico['square'].setHpr(0,90,0)
mesh_dico['circle'] = loader.loadModel("circle.egg")
mesh_dico['circle'].setScale(0.3048,0.3048,0.3048)
def TEST_clipping():
#== First part of the Shape
#Uncomment for a square Rectangle
#p = Rect((12,20), (20,20), heading = 0, color = (1,0.3,1,1))
#Uncomment for a circle
#p = Circle((11,15),10, (1,0.3,1,1))
#uncomment for a rectangular rectangle
p = Rect((11,15),(40,30), color = (1,0.3,1,1))
shaderNode = render.find('shader')
p.node.wrtReparentTo(shaderNode)
point_init = Point3(12, 15, 0.0)
vect = Vec3(1, -0.5, 0.0)
plane = Plane(vect, point_init)
planeNode = PlaneNode( 'shapePlane' )
planeNode.setPlane( plane )
planeNode.setVizScale(10)
node = render.attachNewNode( planeNode )
planeNP = NodePath(node)
planeNP.wrtReparentTo(p.node)
planeNP.show()
p.node.setClipPlane(planeNP)
#== Second part of the Shape
#Uncomment for a square Rectangle
#p1 = Rect((12,20), (20,20), heading = 0, color = (0,0,1,1))
#Uncomment for a circle
#p1 = Circle((11,15),10, (0,0,1,1))
#uncomment for a rectangular rectangle
p1 = Rect((11,15),(40,30), color = (0,0,1,1))
shaderNode = render.find('shader')
p1.node.wrtReparentTo(shaderNode)
point_init = Point3(12, 17, 0.0)
vect = Vec3(-1, 0.5, 0.0)
plane = Plane(vect, point_init)
planeNode = PlaneNode( 'shapePlane' )
planeNode.setPlane( plane )
planeNode.setVizScale(10)
node = render.attachNewNode( planeNode )
planeNP = NodePath(node)
planeNP.wrtReparentTo(p1.node)
planeNP.show()
p1.node.setClipPlane(planeNP)
if __name__ == '__main__':
load_meshes()
TEST_clipping()
run()
The meshes loaded can be found on panda’s website in download/3Dmodel/shapes.
After the launch, just push the ‘O’ key in order to see the shape. The camera’s control are these one : http://panda3d.org/manual/index.php/Enhanced_Mouse_Navigation
Thanks in advance for your answers.