Commit 33bf0ddb authored by Jonathan Lambrechts's avatar Jonathan Lambrechts Committed by Matthieu Constant
Browse files

single paraview plugin

parent 6ec68d75
all : contacts-extract.xml ids-extract.xml
%.xml : %.py
python python_filter_generator.py $< $@
marblesbag.xml : python_filter_generator.py contacts-extract.py ids-extract.py
python python_filter_generator.py $@ contacts-extract.py ids-extract.py
<ServerManagerConfiguration>
<ProxyGroup name="filters">
<SourceProxy name="MBExtractContact" class="vtkPythonProgrammableFilter" label="Marblesbag extract contacts">
<Documentation
long_help="Generate tubes to represent contacts from marblesbag scontact output"
short_help="Generate tubes to represent contacts from marblesbag scontact output">
</Documentation>
<InputProperty
name="Input"
command="SetInputConnection">
<ProxyGroupDomain name="groups">
<Group name="sources"/>
<Group name="filters"/>
</ProxyGroupDomain>
<DataTypeDomain name="input_type">
<DataType value="vtkMultiBlockDataSet"/>
</DataTypeDomain>
</InputProperty>
<IntVectorProperty
name="nf"
label="nf"
initial_string="nf"
command="SetParameter"
animateable="1"
default_values="5"
number_of_elements="1">
<Documentation></Documentation>
</IntVectorProperty>
<DoubleVectorProperty
name="rf"
label="rf"
initial_string="rf"
command="SetParameter"
animateable="1"
default_values="0.00025"
number_of_elements="1">
<Documentation></Documentation>
</DoubleVectorProperty>
<!-- Output data type: "vtkUnstructuredGrid" -->
<IntVectorProperty command="SetOutputDataSetType"
default_values="4"
name="OutputDataSetType"
number_of_elements="1"
panel_visibility="never">
<Documentation>The value of this property determines the dataset type
for the output of the programmable filter.</Documentation>
</IntVectorProperty>
<StringVectorProperty
name="Script"
command="SetScript"
number_of_elements="1"
default_values="import numpy as np&#xA;&#xA;#input&#xA;#nf = 5&#xA;#rf = 2.5e-4&#xA;&#xA;in_particles,in_bnd,in_contacts = list(inputs[0])&#xA;&#xA;#split bnd cells&#xA;n_disks, n_segments, n_triangles = in_bnd.FieldData[&quot;sizes&quot;]&#xA;if n_disks :&#xA; disks = in_bnd.Cells[1:2*n_disks:2]&#xA;if n_segments :&#xA; segments = in_bnd.Cells[2*n_disks:2*n_disks+3*n_segments].reshape([-1,3])[:,1:]&#xA;if n_triangles :&#xA; triangles = in_bnd.Cells[2*n_disks+3*n_segments,2*n_disks+3*n_segments+4*n_triangles].reshape([-1,4])[:,1:]&#xA;&#xA;vals = []&#xA;points = []&#xA;&#xA;&#xA;#particle-particle contacts&#xA;vals.append(in_contacts.FieldData[&quot;particle_particle&quot;])&#xA;contacts = in_contacts.FieldData[&quot;particle_particle_idx&quot;]&#xA;points.append(in_particles.Points[contacts,:])&#xA;&#xA;#particle-disk contacts&#xA;vals.append(in_contacts.FieldData[&quot;particle_disk&quot;])&#xA;contacts = in_contacts.FieldData[&quot;particle_disk_idx&quot;]&#xA;points_d = np.ndarray((contacts.shape[0],2,3))&#xA;points_d[:,0,:] = in_particles.Points[contacts[:,1],:]&#xA;points_d[:,1,:] = in_bnd.Points[disks[contacts[:,0]],:]&#xA;points.append(points_d)&#xA;&#xA;#particle-segments contacts&#xA;vals.append(in_contacts.FieldData[&quot;particle_segment&quot;])&#xA;contacts = in_contacts.FieldData[&quot;particle_segment_idx&quot;]&#xA;points_s = np.ndarray((contacts.shape[0],2,3))&#xA;points_s[:,0,:] = in_particles.Points[contacts[:,1],:]&#xA;points_s[:,1,:] = np.mean(in_bnd.Points[segments[contacts[:,0],:]],axis=1)&#xA;points.append(points_s)&#xA;&#xA;#particle-triangle contacts&#xA;if &quot;particle_triangle&quot; in in_contacts.FieldData :&#xA; vals.append(in_contacts.FieldData[&quot;particle_triangle&quot;])&#xA; contacts = in_contacts.FieldData[&quot;particle_triangle_idx&quot;]&#xA; points_t = np.ndarray((contacts.shape[0],2,3))&#xA; points_t[:,0,:] = in_particles.Points[contacts[:,1],:]&#xA; points_t[:,1,:] = np.mean(in_bnd.Points[triangles[contacts[:,0],:]],axis=1)&#xA; points.append(points_t)&#xA;&#xA;#merge everything&#xA;points = np.vstack(points)&#xA;vals = np.hstack(vals)&#xA;&#xA;#generate tubes&#xA;t = points[:,0,:]-points[:,1,:]&#xA;t /= np.sqrt(t[:,0,None]**2+t[:,1,None]**2+t[:,2,None]**2)&#xA;ez = np.where(t[:,1,None]&gt;t[:,2,None],np.array([[0,0,1]]),np.array([[0]]))&#xA;n1 = np.cross(t,ez)&#xA;n2 = np.cross(t,n1)&#xA;alphas = np.arange(0,2*np.pi, 2*np.pi/nf)&#xA;r = rf*vals**(1./2)*1&#xA;opoints = points[:,None,:,:] \&#xA; +n1[:,None,None,:]*r[:,None,None,None]*np.sin(-alphas)[None,:,None,None] \&#xA; +n2[:,None,None,:]*r[:,None,None,None]*np.cos(-alphas)[None,:,None,None]&#xA;output.Points = opoints.reshape(-1,3)&#xA;output.PointData.append(np.repeat(vals,2*nf),&quot;Reaction&quot;)&#xA;n = points.shape[0]&#xA;pattern = np.ndarray([nf,4], np.int)&#xA;for i in range(nf) :&#xA; j = (i+1)%nf&#xA; pattern[i,:] = (i*2,i*2+1,j*2+1,j*2)&#xA;types = np.full([n*nf],9,np.uint8)&#xA;locations = np.arange(0,5*n*nf,5,np.uint32)&#xA;cells = np.ndarray([n,nf,5],np.uint32)&#xA;cells[:,:,0] = 4&#xA;cells[:,:,1:] = np.arange(0,n*nf*2,nf*2,np.uint32)[:,None,None]+pattern[None,:,:]&#xA;output.SetCells(types, locations, cells.reshape([-1]))&#xA;"
panel_visibility="advanced">
<Hints>
<Widget type="multi_line"/>
</Hints>
<Documentation>This property contains the text of a python program that
the programmable source runs.</Documentation>
</StringVectorProperty>
</SourceProxy>
</ProxyGroup>
</ServerManagerConfiguration>
<ServerManagerConfiguration>
<ProxyGroup name="filters">
<SourceProxy name="MBExtractIds" class="vtkPythonProgrammableFilter" label="Marblesbag extract ids">
<Documentation
long_help="Marblesbag extract ids"
short_help="Marblesbag extract ids">
</Documentation>
<InputProperty
name="Input"
command="SetInputConnection">
<ProxyGroupDomain name="groups">
<Group name="sources"/>
<Group name="filters"/>
</ProxyGroupDomain>
<DataTypeDomain name="input_type">
<DataType value="vtkPolyData"/>
</DataTypeDomain>
</InputProperty>
<!-- Output data type: "vtkPolyData" -->
<IntVectorProperty command="SetOutputDataSetType"
default_values="0"
name="OutputDataSetType"
number_of_elements="1"
panel_visibility="never">
<Documentation>The value of this property determines the dataset type
for the output of the programmable filter.</Documentation>
</IntVectorProperty>
<StringVectorProperty
name="Script"
command="SetScript"
number_of_elements="1"
default_values="import numpy as np&#xA;output.CopyAttributes(self.GetInputDataObject(0,0))&#xA;ids = np.arange(0,output.Points.shape[0],dtype=np.float32)&#xA;output.PointData.append(ids,&quot;id&quot;)&#xA;del ids&#xA;"
panel_visibility="advanced">
<Hints>
<Widget type="multi_line"/>
</Hints>
<Documentation>This property contains the text of a python program that
the programmable source runs.</Documentation>
</StringVectorProperty>
</SourceProxy>
</ProxyGroup>
</ServerManagerConfiguration>
......@@ -280,7 +280,6 @@ def generatePythonFilter(info):
outputXml = '''\
<ServerManagerConfiguration>
<ProxyGroup name="%s">
<SourceProxy name="%s" class="vtkPythonProgrammableFilter" label="%s">
......@@ -301,7 +300,6 @@ def generatePythonFilter(info):
</SourceProxy>
</ProxyGroup>
</ServerManagerConfiguration>
''' % (proxyGroup, proxyName, proxyLabel, longHelp, shortHelp, inputPropertyXml,
filterProperties, extraXml, outputDataSetType, scriptProperties)
......@@ -334,30 +332,27 @@ def replaceFunctionWithSourceString(namespace, functionName, allowEmpty=False):
namespace[functionName] = sourceCode
def generatePythonFilterFromFiles(scriptFile, outputFile):
namespace = {}
exec(compile(open(scriptFile).read(), scriptFile, 'exec'), namespace)
replaceFunctionWithSourceString(namespace, 'RequestData')
replaceFunctionWithSourceString(namespace, 'RequestInformation', allowEmpty=True)
replaceFunctionWithSourceString(namespace, 'RequestUpdateExtent', allowEmpty=True)
xmlOutput = generatePythonFilter(namespace)
open(outputFile, 'w').write(xmlOutput)
def generatePythonFilterFromFiles(scriptFiles, outputFile):
with open(outputFile, "w") as f :
f.write("<ServerManagerConfiguration>\n")
for scriptFile in scriptFiles :
print("process", scriptFile)
namespace = {}
exec(compile(open(scriptFile).read(), scriptFile, 'exec'), namespace)
replaceFunctionWithSourceString(namespace, 'RequestData')
replaceFunctionWithSourceString(namespace, 'RequestInformation', allowEmpty=True)
replaceFunctionWithSourceString(namespace, 'RequestUpdateExtent', allowEmpty=True)
xmlOutput = generatePythonFilter(namespace)
f.write(xmlOutput)
f.write("</ServerManagerConfiguration>\n")
def main():
if len(sys.argv) != 3:
print(('Usage: %s <python input filename> <xml output filename>' % sys.argv[0]))
sys.exit(1)
inputScript = sys.argv[1]
outputFile = sys.argv[2]
inputScripts = sys.argv[2:]
outputFile = sys.argv[1]
generatePythonFilterFromFiles(inputScript, outputFile)
generatePythonFilterFromFiles(inputScripts, outputFile)
if __name__ == '__main__':
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment