I need to import multiple files into Maya and assign multiple materials to each one.
I have the following code in Python:
import maya.cmds as cmds
import glob
def importFile(i):
cmds.file(i, i=True, groupReference=True, groupName="myobj")
def moveFile():
cmds.select("myobj")
cmds.scale(1,1,1, r=True)
cmds.move (0, 14, 0, r=True)
cmds.rotate (-90, 0, 0, r=True)
def materialFile():
cmds.select("myobj")
myMaterial = "blinn1"
cmds.sets( e=True, forceElement= myMaterial + 'SG' )
def renderFile(i):
cmds.setAttr("defaultRenderGlobals.imageFilePrefix", i, type="string")
cmds.render(batch=True)
def deleteFile():
cmds.select("myobj")
cmds.delete()
myglob = glob.glob("/The/path/of/your/Obj_files/*.obj")
for i in myglob:
importFile(i)
moveFile()
materialFile()
renderFile(i)
deleteFile()
With this code I can assign only one shader to the whole piece of geometry.
Is it possible to assign different shaders to the same piece of geometry?
Definitely, you can assign different shaders to the same piece of geometry as well as any accessible shader for multiple 3d models.
import maya.cmds as mat
d = 0
shader_node1 = mat.shadingNode( "anisotropic", asShader = True, n = 'ani' )
shader_node2 = mat.shadingNode( "phong", asShader = True, n = 'pho' )
shader_node3 = mat.shadingNode( "lambert", asShader = True, n = 'lam' )
mat.setAttr( (shader_node1 + '.color'), 1.0, 0.0, 0.0, type = 'double3' )
mat.setAttr( (shader_node2 + '.color'), 0.0, 1.0, 0.0, type = 'double3' )
mat.setAttr( (shader_node2 + '.transparency'), 0.25, 0.25, 0.25, type = 'double3' )
mat.setAttr( (shader_node3 + '.color'), 0.0, 0.0, 1.0, type = 'double3' )
shading_group1 = mat.sets( renderable = True, noSurfaceShader = True, empty = True )
shading_group2 = mat.sets( renderable = True, noSurfaceShader = True, empty = True )
shading_group3 = mat.sets( renderable = True, noSurfaceShader = True, empty = True )
mat.connectAttr( '%s.outColor' %shader_node1, '%s.surfaceShader' %shading_group1 )
mat.connectAttr( '%s.outColor' %shader_node2, '%s.surfaceShader' %shading_group2 )
mat.connectAttr( '%s.outColor' %shader_node3, '%s.surfaceShader' %shading_group3 )
mat.polySphere( radius = 5 )
mat.polySphere( radius = 7 )
mat.polySphere( radius = 3 )
mat.select( 'pSphere1' )
mat.move( 7, 6, 0, r = True )
mat.hyperShade( assign = shader_node1 )
mat.select( 'pSphere2' )
mat.hyperShade( assign = shader_node2 )
mat.select( 'pSphere3' )
mat.move( -7, -2, 0, r = True )
mat.hyperShade( assign = shader_node3 )
d += 1
Also you can access your shaders within an array using random function:
import random as random
myArray = [shader_node1, shader_node2, shader_node3]
for i in myArray :
mat.select( 'pSphere1' )
mat.move( 7, 6, 0, r = True )
mat.hyperShade( assign = myArray[int(random.uniform(0,3))] )
mat.select( 'pSphere2' )
mat.hyperShade( assign = myArray[int(random.uniform(0,3))] )
mat.select( 'pSphere3' )
mat.move( -7, -2, 0, r = True )
mat.hyperShade( assign = myArray[int(random.uniform(0,3))] )
Related
Im having trouble getting two definitions to speak to each other using a UI. I would like to create a bunch of locators place them in the scene and name them. Then in a different definition create some joints and use the locators name and position to position the joints and name them according to the locators I previously created.
My problem is the variable named rootJnt is not being recognized in the joint creation definition. All others are except rootJnt. I don't understand why, all the other variables are being recognized. Can some one please explain?
from maya import cmds
def proxySkel (self):
target = cmds.ls (selection = True)
DDD = cmds.textField (textNam,
query = True,
text = True)
# CREATE THE LOCATOR
_endOutLoc = cmds.spaceLocator (position = (0, 0, 0), name = DDD + '_locEndOut')
_startOutLoc = cmds.spaceLocator (position = (0, 0, 0), name = DDD + '_locStartOut')
_rootLoc = cmds.spaceLocator (position = (0, 0, 0), name = DDD + '_locRoot')
# MOVE END LOCATOR IN SPACE
cmds.move (5, 0, 3, _endOutLoc, absolute = True)
cmds.move (0, 0, 3, _startOutLoc, absolute = True)
return _endOutLoc, _startOutLoc, _rootLoc
def jointsCreate (self):
target = cmds.ls (selection = True)
DDD = cmds.textField (textNam,
query = True,
text = True)
# CREATE THE JOINTS
rootJnt = cmds.joint (position = (0.0, 0.0, 0.0), name = _rootLoc + '_jnt')
endOutJnt = cmds.joint (position = (0.0, 0.0, 0.0), name = _endOutLoc[0] + '_jnt')
startOutJnt = cmds.joint (position = (0.0, 0.0, 0.0), name = _startOutLoc[0] + '_jnt')
# PLACE THE JOINTS INTO SPACE
rootConst = cmds.parentConstraint (_rootLoc, rootJnt, mo = False)
endOutConst = cmds.parentConstraint (_endOutLoc, endOutJnt, mo = False)
startInConst = cmds.parentConstraint (_startInLoc, startInJnt, mo = False)
# CREATE THE JOINT HIERARCHY
cmds.parent (startInJnt, rootJnt)
cmds.parent (startInJnt, startOutJnt)
if(cmds.window('window1',q=1,ex=1)):
cmds.deleteUI('window1')
cmds.window('window1',menuBar=1)
cmds.columnLayout()
textNam = cmds.textField(width=150,
text='Name',
backgroundColor=[0.6233005264362554, 1.0, 0.9765011062790875])
cmds.separator()
cmds.rowLayout(numberOfColumns=3)
cmds.button(width=65,
command = proxySkel,
backgroundColor=[0.0, 0.2187533379110399, 1.0],
label='Locators')
cmds.separator(style='none',
width=3)
cmds.button(width=78,
command = jointsCreate,
backgroundColor=[0.7971007858396277, 0.0, 0.0],
label='Joints')
cmds.showWindow('window1')
To have access to your variables between two functions, you have to define them in an outer scope. In your case _endOutLoc, _startOutLoc, _rootLoc are defined locally to ProxySkel function and they are not visible to jointsCreate function
In additional to that, there are several other mistakes
as it was mentioned in the comments to your question, _rootLoc have to be passed with index 0, because it stores value as a list, not as a string
if you are using parent constraint for the alignment, I would guess you want to delete them once the alignment is finished
there is no need to call parent command for the joints, as they are already parented in the order of cmds.joint calls. Here is a note from documentation "In the creation mode, a new joint will be created as a child of a selected transform or starts a hierarchy by itself if no transform is selected." if you don't want such behaviour, you should clear the selection
cmds.window('window1',menuBar=1) have to be always called, not inside the existance window condition, otherwise the UI elements will be attached to the script editor window
here is an updated script
from maya import cmds
global _endOutLoc
global _startOutLoc
global _rootLoc
def proxySkel (self):
global _endOutLoc, _startOutLoc, _rootLoc
target = cmds.ls (selection = True)
DDD = cmds.textField (textNam,
query = True,
text = True)
# CREATE THE LOCATOR
_endOutLoc = cmds.spaceLocator (position = (0, 0, 0), name = DDD + '_locEndOut')
_startOutLoc = cmds.spaceLocator (position = (0, 0, 0), name = DDD + '_locStartOut')
_rootLoc = cmds.spaceLocator (position = (0, 0, 0), name = DDD + '_locRoot')
# MOVE END LOCATOR IN SPACE
cmds.move (5, 0, 3, _endOutLoc, absolute = True)
cmds.move (0, 0, 3, _startOutLoc, absolute = True)
return _endOutLoc, _startOutLoc, _rootLoc
def jointsCreate (self):
global _endOutLoc, _startOutLoc, _rootLoc
if None in [_endOutLoc, _startOutLoc, _rootLoc]:
print('locators are not created yet')
return
target = cmds.ls (selection = True)
DDD = cmds.textField (textNam,
query = True,
text = True)
# CREATE THE JOINTS
rootJnt = cmds.joint (position = (0.0, 0.0, 0.0), name = _rootLoc[0] + '_jnt')
endOutJnt = cmds.joint (position = (0.0, 0.0, 0.0), name = _endOutLoc[0] + '_jnt')
startOutJnt = cmds.joint (position = (0.0, 0.0, 0.0), name = _startOutLoc[0] + '_jnt')
# PLACE THE JOINTS INTO SPACE
rootConst = cmds.parentConstraint (_rootLoc, rootJnt, mo = False)
endOutConst = cmds.parentConstraint (_endOutLoc, endOutJnt, mo = False)
startInConst = cmds.parentConstraint (_startOutLoc, startOutJnt, mo = False)
# DELETE CONSTRAINTS AFTER ALIGNMENT
cmds.delete (rootConst, endOutConst, startInConst)
# CREATE THE JOINT HIERARCHY
#cmds.parent (endOutJnt, rootJnt)
#cmds.parent (startOutJnt, endOutJnt)
if(cmds.window('window1',q=1,ex=1)):
cmds.deleteUI('window1')
cmds.window('window1',menuBar=1)
cmds.columnLayout()
textNam = cmds.textField(width=150,
text='Name',
backgroundColor=[0.6233005264362554, 1.0, 0.9765011062790875])
cmds.separator()
cmds.rowLayout(numberOfColumns=3)
cmds.button(width=65,
command = proxySkel,
backgroundColor=[0.0, 0.2187533379110399, 1.0],
label='Locators')
cmds.separator(style='none',
width=3)
cmds.button(width=78,
command = jointsCreate,
backgroundColor=[0.7971007858396277, 0.0, 0.0],
label='Joints')
cmds.showWindow('window1')
I am working on a plotter for Finite Element Method solutions. I decided to use the Plotly library because of the carpet plots. I have my data to plot and this is my result:
Flow over NACA0012
Each element is represented as a Carpet, and for each carpet the solution is shown as a Countourcarpet. Everything is in place, but the rendering is too slow and the interactive interface is therefore nearly useless. Is there a way to enhance the performance of the rendering? I have read about different renderers in Plotly, but the plot just does not open. Is there a a way to speed up the rendering? Surely I will have to manage larger dataset. In this example I am using 740 carpets.
These are the Contourcarpet settings:
fig.add_trace(go.Contourcarpet(
a = a,
b = b,
z = u, # Sution correspondent at (a,b) parametric location
showlegend = showLegendFlag,
name = "Density",
legendgroup = "Density",
autocolorscale = False,
colorscale = "Inferno",
autocontour = False,
carpet = str(e), # The carpet on which to plot the solution is
# referenced as a string number
contours = dict(
start = start1, # Min value
end = end1, # Max value
size = abs(end1-start1) / countour_number, # Plot colour discretization
showlines = False
),
line = dict(
smoothing = 0
),
colorbar = dict(
len = 0.4,
y = 0.25
)
))
And these are the layout settings:
fig.update_layout(
plot_bgcolor="#FFF",
yaxis = dict(
zeroline = False,
range = [-1.800,1.800],
showgrid = False
),
dragmode = "pan",
height = 700,
xaxis = dict(
zeroline = False,
scaleratio = 1,
scaleanchor = 'y',
range = [-3.800,3.800],
showgrid = False
),
title = "Flow over NACA 0012",
hovermode = "closest",
margin = dict(
r = 80,
b = 40,
l = 40,
t = 80
),
width = 900
)
fig.show()
I have a fairly complex Python based OpenGL code that runs fine on Windows and Mac, but fails with weird banded-spheres on Linux. Views from two angles:
Here is what the same code plots on a Mac:
The problem is not only with spheres, but this is the easiest thing to show. Does this problem suggest anything to anyone with more experience with OpenGL than I?
Thanks for any hints or suggestions.
Here is some sample code that shows this problem
'''Draws a sphere and axis triplet with openGL; rotates with mouse drag.
This works fine on Windows and Mac, but sphere displays strangely on Linux
'''
import sys
import math
import numpy as np
import numpy.linalg as nl
import wx
import wx.glcanvas
import OpenGL.GL as GL
import OpenGL.GLU as GLU
drawingData = {
'oldxy' : [0, 0],
'Quaternion' : np.array([ 0.11783419, 0.87355958, 0.09141639, 0.4633053 ]),
'linecolors': [(np.array([[0, 0, 0], [1, 0, 0]]), [255, 0, 0]),
(np.array([[0, 0, 0], [0, 1, 0]]), [ 0, 255, 0]),
(np.array([[0, 0, 0], [0, 0, 1]]), [ 0, 0, 255])],
}
def Q2Mat(Q):
''' make rotation matrix from quaternion
'''
QN = Q/np.sqrt(np.sum(np.array(Q)**2))
aa = QN[0]**2
ab = QN[0]*QN[1]
ac = QN[0]*QN[2]
ad = QN[0]*QN[3]
bb = QN[1]**2
bc = QN[1]*QN[2]
bd = QN[1]*QN[3]
cc = QN[2]**2
cd = QN[2]*QN[3]
dd = QN[3]**2
M = [[aa+bb-cc-dd, 2.*(bc-ad), 2.*(ac+bd)],
[2*(ad+bc), aa-bb+cc-dd, 2.*(cd-ab)],
[2*(bd-ac), 2.*(ab+cd), aa-bb-cc+dd]]
return np.array(M)
def prodQVQ(Q,V):
"""compute the quaternion vector rotation qvq-1 = v'
"""
T2 = Q[0]*Q[1]
T3 = Q[0]*Q[2]
T4 = Q[0]*Q[3]
T5 = -Q[1]*Q[1]
T6 = Q[1]*Q[2]
T7 = Q[1]*Q[3]
T8 = -Q[2]*Q[2]
T9 = Q[2]*Q[3]
T10 = -Q[3]*Q[3]
M = np.array([[T8+T10,T6-T4,T3+T7],[T4+T6,T5+T10,T9-T2],[T7-T3,T2+T9,T5+T8]])
VP = 2.*np.inner(V,M)
return VP+V
def invQ(Q):
'''get inverse of quaternion q=r+ai+bj+ck; q* = r-ai-bj-ck
'''
return Q*np.array([1,-1,-1,-1])
def AVdeg2Q(A,V):
''' convert angle (degrees) & vector to quaternion
q=r+ai+bj+ck
'''
sind = lambda x: math.sin(x*math.pi/180.)
cosd = lambda x: math.cos(x*math.pi/180.)
Q = np.zeros(4)
d = nl.norm(np.array(V))
if not A: #== 0.!
A = 360.
if d:
V = V/d
p = A/2.
Q[0] = cosd(p)
Q[1:4] = V*sind(p)
else:
Q[3] = 1.
return Q
def prodQQ(QA,QB):
''' Grassman quaternion product, QA,QB quaternions; q=r+ai+bj+ck
'''
D = np.zeros(4)
D[0] = QA[0]*QB[0]-QA[1]*QB[1]-QA[2]*QB[2]-QA[3]*QB[3]
D[1] = QA[0]*QB[1]+QA[1]*QB[0]+QA[2]*QB[3]-QA[3]*QB[2]
D[2] = QA[0]*QB[2]-QA[1]*QB[3]+QA[2]*QB[0]+QA[3]*QB[1]
D[3] = QA[0]*QB[3]+QA[1]*QB[2]-QA[2]*QB[1]+QA[3]*QB[0]
return D
def RenderUnitVectors(x,y,z):
'Show the axes'
GL.glEnable(GL.GL_COLOR_MATERIAL)
GL.glLineWidth(2)
GL.glEnable(GL.GL_BLEND)
GL.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA)
GL.glEnable(GL.GL_LINE_SMOOTH)
GL.glPushMatrix()
GL.glTranslate(x,y,z)
GL.glScalef(1,1,1)
GL.glBegin(GL.GL_LINES)
for line,color in drawingData['linecolors']:
GL.glColor3ubv(color)
GL.glVertex3fv(-line[1]/2.)
GL.glVertex3fv(line[1]/2.)
GL.glEnd()
GL.glPopMatrix()
GL.glColor4ubv([0,0,0,0])
GL.glDisable(GL.GL_LINE_SMOOTH)
GL.glDisable(GL.GL_BLEND)
GL.glDisable(GL.GL_COLOR_MATERIAL)
def RenderSphere(x,y,z,radius,color):
'show a sphere'
GL.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_DIFFUSE,color)
GL.glPushMatrix()
GL.glTranslate(x,y,z)
GL.glMultMatrixf(np.eye(4).T)
GLU.gluSphere(GLU.gluNewQuadric(),radius,20,10)
GL.glPopMatrix()
class myGLCanvas(wx.Panel):
def __init__(self, parent, id=-1,dpi=None,**kwargs):
wx.Panel.__init__(self,parent,id=id,**kwargs)
if 'win' in sys.platform: # for Windows (& darwin==Mac) -- already double buffered
attribs = None
else: # Linux
attribs = [wx.glcanvas.WX_GL_DOUBLEBUFFER,]
self.canvas = wx.glcanvas.GLCanvas(self,-1,attribList=attribs,**kwargs)
self.context = wx.glcanvas.GLContext(self.canvas)
self.canvas.SetCurrent(self.context)
sizer=wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.canvas,1,wx.EXPAND)
self.SetSizer(sizer)
self.canvas.Bind(wx.EVT_MOTION, self.OnMouseMove)
self.Draw()
self.Draw()
return
def OnMouseMove(self,event):
if not event.Dragging():
drawingData['oldxy'] = list(event.GetPosition())
return
# Perform a rotation in x-y space
oldxy = drawingData['oldxy']
if not len(oldxy): oldxy = list(event.GetPosition())
dxy = event.GetPosition()-oldxy
drawingData['oldxy'] = list(event.GetPosition())
V = np.array([dxy[1],dxy[0],0.])
A = 0.25*np.sqrt(dxy[0]**2+dxy[1]**2)
if not A: return
# next transform vector back to xtal coordinates via inverse quaternion & make new quaternion
Q = drawingData['Quaternion']
V = prodQVQ(invQ(Q),np.inner(np.eye(3),V))
Q = prodQQ(Q,AVdeg2Q(A,V))
drawingData['Quaternion'] = Q
self.Draw()
def Draw(self):
GL.glClearColor(0.,0.,0.,0.)
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
GL.glInitNames()
GL.glPushName(0)
GL.glMatrixMode(GL.GL_PROJECTION)
GL.glLoadIdentity()
GL.glViewport(0,0,*self.canvas.GetSize())
GLU.gluPerspective(20.,self.canvas.GetSize()[0]*1./self.canvas.GetSize()[1],7.5,12.5)
GLU.gluLookAt(0,0,10,0,0,0,0,1,0)
# Set Lighting
GL.glEnable(GL.GL_DEPTH_TEST)
GL.glEnable(GL.GL_LIGHTING)
GL.glEnable(GL.GL_LIGHT0)
GL.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE,0)
GL.glLightfv(GL.GL_LIGHT0,GL.GL_AMBIENT,[1,1,1,1])
GL.glLightfv(GL.GL_LIGHT0,GL.GL_DIFFUSE,[1,1,1,1])
GL.glMatrixMode(GL.GL_MODELVIEW)
GL.glLoadIdentity()
matRot = Q2Mat(drawingData['Quaternion'])
matRot = np.concatenate((np.concatenate((matRot,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0)
GL.glMultMatrixf(matRot.T)
GL.glMultMatrixf(np.eye(4).T)
Tx,Ty,Tz = (0.20045985394544949, 0.44135342324377724, 0.40844172594191536)
GL.glTranslate(-Tx,-Ty,-Tz)
RenderUnitVectors(Tx,Ty,Tz)
RenderSphere(0, 0, 0, 0.804, [1., 1., 1.])
self.canvas.SetCurrent(self.context)
self.canvas.SwapBuffers()
class GUI(wx.App):
def OnInit(self):
frame = wx.Frame(None,-1,'ball rendering',wx.DefaultPosition,wx.Size(400,400))
frame.Show()
wx.CallAfter(myGLCanvas,frame,size=wx.Size(400,400)) # wait for frame to be displayed
self.MainLoop()
return True
if __name__ == '__main__':
GUI()
You have to specify the number of the bits for the depth buffer, according to the conditions of your hardware, by setting WX_GL_DEPTH_SIZE. The size of the depth buffer should be 16, 24 or 32.
attribs = [
wx.glcanvas.WX_GL_RGBA,
wx.glcanvas.WX_GL_DOUBLEBUFFER,
wx.glcanvas.WX_GL_DEPTH_SIZE, 16]
See also:
How can I determine the max allowable WX_GL_DEPTH_SIZE for a wx GLCanvas?
OpenGL depth buffer deosn't seem to work in wx.glcanvas?
wx.glcanvas.WX_GL_DEPTH_SIZE
wxGLCanvas
I want to use a checkbox to control the ratio multiplied in slider function.
First I try to change the variable directly, but failed.
Then I try to change the dragCommand, but also failed.
How can I control it?
import pymel.core as pm
import math
myRatio = math.sqrt(2) * 0.5
def myPolyBevel(*args):
# called by convert
def convertOn(*args):
#myRatio = math.sqrt(2) * 0.5
myOffsetSlider.dragCommand = myOffsetOn
def convertOff(*args):
#myRatio = 1.0
myOffsetSlider.dragCommand = myOffsetOff
# called by offset
def myOffsetOn(*args):
temp = pm.floatSliderGrp( myOffsetSlider, query = True, value = True ) * myRatio
pm.setAttr( myBevel.name()+".offset", temp )
def myOffsetOff(*args):
temp = pm.floatSliderGrp( myOffsetSlider, query = True, value = True )
pm.setAttr( myBevel.name()+".offset", temp )
# main
if pm.selected():
# add Bevel
newBevel = pm.polyBevel3( pm.selected(), offset = 0.1 * myRatio, segments = 2, smoothingAngle = 30, chamfer = 1 )
myBevel = newBevel[0]
# UI
bevelWindow = pm.window(title = 'Bevel')
bevelLayout = pm.columnLayout()
myConvert = pm.checkBoxGrp( numberOfCheckBoxes = 1, label = '', label1 = 'Convert', value1 = 1, onCommand = convertOn, offCommand = convertOff )
myOffsetSlider = pm.floatSliderGrp( label='Offset', field = True,
minValue = 0.0, maxValue = 5.0,
fieldMinValue = 0.0, fieldMaxValue = 100.0,
value = 0.1, step = 0.001,
dragCommand = myOffsetOn, changeCommand = myOffsetOn )
pm.showWindow()
# Main
mainWindow = pm.window(title = 'Star')
mainLayout = pm.gridLayout( cellWidthHeight = (40,40), numberOfColumns = 5 )
bevelButton = pm.button( label = 'Bevel', command = myPolyBevel)
pm.showWindow()
You may have to not nest all this command, it makes it harder (or use some Class method)
use partial to pass args :
Maya Python - Using data from UI
here a useful post you can refer, check theodor and my answers on the topic (we often answer this question )
I am attempting to render the output from SciPy SphericalVoronoi using the THREE.js library. I was hoping it would be relatively straight forward based on the matplotlib example in the scipy docs.
Update 2/18/17:
I didn't originally account for the voronoi regions being quads, so this splits them into triangles now. I did get the unit cube example working; however, scaling up the geometry doesn't seem to be complete.
Python script:
import json
import numpy as np
from scipy.spatial import SphericalVoronoi
# http://stackoverflow.com/questions/27050108/convert-numpy-type-to-python/27050186#27050186
class NumpyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, np.integer):
return int(obj)
elif isinstance(obj, np.floating):
return float(obj)
elif isinstance(obj, np.ndarray):
return obj.tolist()
else:
return super(NumpyEncoder, self).default(obj)
def computeVoronoi( data ):
vertices = np.array( data['vertices'] )
lenVerts = int( vertices.shape[0] / 3 )
vertices = np.reshape( vertices, ( lenVerts, 3 ) )
voronoi = SphericalVoronoi( vertices, data['regularRadius'] )
'''
points = np.array([[0, 0, 1], [0, 0, -1], [1, 0, 0], [0, 1, 0], [0, -1, 0], [-1, 0, 0], ])
voronoi = SphericalVoronoi( points, 1, np.array([0, 0, 0]) )
'''
voronoi.sort_vertices_of_regions()
return voronoi
if __name__ == '__main__':
with open( './map.json' ) as infile:
voronoi = computeVoronoi( json.load( infile ) )
indices = []
for region in voronoi.regions:
# need to split the quad into tris for rendering
i1 = region[0]
i2 = region[1]
i3 = region[2]
i4 = region[3]
indices.append( i1 )
indices.append( i2 )
indices.append( i3 )
indices.append( i3 )
indices.append( i4 )
indices.append( i1 )
with open( './voronoi.json', 'w' ) as outfile:
json.dump( {
'indices': indices,
'colors': np.random.random( (len( voronoi.vertices ),3) ).flatten(),
'vertices': voronoi.vertices.flatten()
}, outfile, cls=NumpyEncoder )
THREE.js script:
var loader = new THREE.FileLoader()
loader.load( 'voronoi.json', function( data ) {
vJson = JSON.parse( data )
var geometry = new THREE.BufferGeometry()
geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vJson.vertices ), 3 ) )
geometry.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( vJson.colors ), 3 ) )
geometry.setIndex( new THREE.BufferAttribute( new Uint32Array( vJson.indices ), 1 ) )
var voronoiMesh = new THREE.Mesh(
geometry,
new THREE.MeshBasicMaterial({
color: 0xffffff,
side: THREE.DoubleSide,
vertexColors: THREE.VertexColors,
})
)
scene.add( voronoiMesh )
})
Here's what the render looks like now:
render link