-
Notifications
You must be signed in to change notification settings - Fork 124
ExamplesPrimitivesParticleSurfacing
Ben Toogood edited this page Jun 13, 2013
·
2 revisions
This example fills a mesh primitive with particles, then creates a new mesh primitive by surfacing those particles using marching cubes and an implicit surface function.
In production, particle caches are read from disk using a Particle Reader and the resulting meshes are used for rendering the particle surface.
As of Cortex 4.1.0 there are particle readers for Cortex Points Primitives (.cob), Maya (.pdc), Renderman (.ptc), Maya nParticles (.mc), and Houdini (.bgeo).
import os
import IECore
def createParticleSurface( particles, smoothingRadius, marchResolution, marchThreshold ) :
isoFn = IECore.ZhuBridsonImplicitSurfaceFunctionV3dd(
particles['P'].data,
particles['radius'].data,
smoothingRadius
)
bound = IECore.Box3d( particles['boundMin'].data.value, particles['boundMax'].data.value )
builder = IECore.MeshPrimitiveBuilder()
marcher = IECore.MarchingCubesd( isoFn, builder )
marcher.march( bound, marchResolution, marchThreshold )
mesh = builder.mesh()
return mesh
def fillMeshWithParticles( meshFile, numParticles ) :
mesh = IECore.Reader.create( meshFile ).read()
mesh = IECore.TriangulateOp()( input=mesh, throwExceptions=False )
meshEvaluator = IECore.MeshPrimitiveEvaluator( mesh )
bound = mesh.bound()
boundMin = bound.min
boundMax = bound.max
boundSize = bound.size()
positions = IECore.V3dVectorData()
radii = IECore.DoubleVectorData()
particleBound = IECore.Box3d()
random = IECore.Rand32()
while len(positions) < numParticles :
p = random.nextV3f() * boundSize + boundMin
d = meshEvaluator.signedDistance( p )
if d < 0.0 :
p = IECore.V3d( p )
positions.append( p )
particleBound.extendBy( p )
radii.append( 1.0 )
particles = IECore.PointsPrimitive( len(positions) )
particles['P'] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Vertex, positions )
particles['radius'] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Vertex, radii )
particles['boundMin'] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Constant, IECore.V3d( boundMin ) )
particles['boundMax'] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Constant, IECore.V3d( boundMax ) )
return particles
particleFile = '/tmp/myParticles.cob'
if os.path.exists( particleFile ) :
particles = IECore.Reader.create( particleFile ).read()
else :
particles = fillMeshWithParticles( "human.cob", 100000 )
IECore.Writer.create( particles, particleFile ).write()
smoothing = 0.75
resolution = IECore.V3i( 200, 300, 200 )
threshold = 0.9
mesh = createParticleSurface( particles, smoothing, resolution, threshold )
writer = IECore.ObjectWriter( mesh, '/tmp/myMesh.cob' )
writer.write()
- Introduction
- General Functionality
- Data Handling
- Parameters and Ops
- Point Primitives
- Mesh Primitives
- Image Primitives
- Procedurals
- Cortex & Python
- Cortex & Maya
- Cortex & Houdini