I get all shapes assigned to baseMaterial, select the shapes and then assign the occlusionShader.
for materialClass in materialClassList:
select(materialClass.baseMaterial)
hyperShade(objects="")
hyperShade(a=materialClass.occlusionShader)
works just fine, but if I use it as a pre render script:
Error: line 0: hyperShade command not supported in batch mode
What can I change the two last lines of my function to to make this work?
Here is an example with cmds.sets() to assign a shader :
all = cmds.ls(type='mesh')
shadingEngine = 'initialShadingGroup'
cmds.sets(all, e=True, forceElement=shadingEngine)
as you can guess, to query meshes with the material :
lamb1_mshs = cmds.sets(shadingEngine, q=True)
i got it to work with:
for materialClass in materialClassList:
sets(materialClass.occlusionShadingGroup, e = True, forceElement = materialClass.meshList)
I collect the meshes when I create the materialClass now, which makes much more sense then selecting them for each renderlayer.
Related
I created a graph from a layer using the code below. I want to save this graph to a shapefile for further use in networkx.
I don't want to also save it as a QGIS layer. So how can I simply save it without giving a layer as the first argument of writeAsVectorFormat?
And if I try give an existing layer as argument it gives a strange bug: the code runs, and Windows shows the .shp file at the recent files in Windows Explorer, but when I want to open it it says that the file does not exist, and I also can't see it in the folder where it should be.
I also can't find how to just create a random layer, so if it's really needed to create a layer, can someone tell me how to do it?
Thank you for help
from qgis.analysis import *
vectorLayer = qgis.utils.iface.mapCanvas().currentLayer()
director = QgsVectorLayerDirector(vectorLayer, 12, '2.0', '3.0', '1.0', QgsVectorLayerDirector.DirectionBoth)
# The index of the field that contains information about the edge speed
attributeId = 1
# Default speed value
defaultValue = 50
# Conversion from speed to metric units ('1' means no conversion)
toMetricFactor = 1
strategy = QgsNetworkSpeedStrategy(attributeId, defaultValue, toMetricFactor)
director.addStrategy(strategy)
builder = QgsGraphBuilder(vectorLayer.crs())
startPoint = QgsPointXY(16.8346339,46.8931070)
endPoint = QgsPointXY(16.8376039,46.8971058)
tiedPoints = director.makeGraph(builder, [startPoint, endPoint])
graph = builder.graph()
vl = QgsVectorLayer("Point", "temp", "memory")
QgsVectorFileWriter.writeAsVectorFormat(v1, "zzsh.shp", "CP1250", vectorLayer.crs(), "ESRI Shapefile")
#QgsProject.instance().mapLayersByName('ZZMap07 copy')[0]
I’m really sorry if I’m asking a question that’s been already answered but I couldn’t find an answer.
I’m writing a code that would allow me to connect a translate of several controllers into a blendWeighted node input channels. The amount of the controllers may vary depending on the selection. I’m struggling with the part where they need to connect to a single blendWeighted node input. Could someone tell me how I could connect every new controller to the next input channel of the blendWeighted node?
I’m sorry if my code is a bit childlike, I’m still learning ^^;
sel = mc.ls(sl=True, fl=True)
drvConnect = []
for i in sel:
name = i.split('_Crv')[0]
dGP = mc.createNode('transform', n='%s_Drv'%name, p=i)
drvConnect.append(dGP)
sh = mc.listRelatives(i, shapes=True)[0]
blendX = mc.createNode('blendWeighted', n='%s_X'%name)
blendY = mc.createNode('blendWeighted', n='%s_Y'%name)
blendZ = mc.createNode('blendWeighted', n='%s_Z'%name)
mc.connectAttr(dGP + '.translateX', blendX +'.input')
mc.connectAttr(dGP + '.translateY', blendY +'.input')
mc.connectAttr(dGP + '.translateZ', blendZ +'.input')
I assume you only want to create a single blendWeighted node. If that's the case, consider that the blendWeighted node's input attribute is an array attribute, so if you want to connect multiple items to it you would need to specify the target index.
For example, to connect the three translate outputs of a node to the first three inputs of the blend node you would use something like this:
mc.connectAttr('ctrl.translateX', 'blend.input[0]')
mc.connectAttr('ctrl.translateY', 'blend.input[1]')
mc.connectAttr('ctrl.translateZ', 'blend.input[2]')
(Maya will take care of creating the items in the array)
In our case you could simply keep a counter of the added items while you loop through the selection and the transform components (just a guide - not tested):
sel = mc.ls(sl=True, fl=True)
drvConnect = []
blendNode = mc.createNode('blendWeighted', n='blend_main')
for i in sel:
name = i.split('_Crv')[0]
dGP = mc.createNode('transform', n='%s_Drv'%name, p=i)
drvConnect.append(dGP)
for comp in ('X', 'Y', 'Z'):
mc.connectAttr(
'{}.translate{}'.format(dGP, comp),
'{}.input[{}]'.format(blendNode, blendIndex))
blendIndex += 1
I've encountered something very strange when having a function which generates an NdOverlay of Points to a DynamicMap, where the function is tied to panel widgets (I don't think the panel widgets are important).
The below code is a working example which produces the expected behavior. Whenever you change the widget values a new plot is generated with two sets of Points overlaid, with different colors and respective legend entries. Image shown below code.
a_widget = pn.widgets.Select(name='A', options=[1,2,3,4])
b_widget = pn.widgets.IntSlider(name='B', start=10, end=20, value=10)
widget_box = pn.WidgetBox(a_widget, b_widget, align='center')
#pn.depends(a=a_widget.param.value, b=b_widget.param.value)
def get_points(a, b):
return hv.NdOverlay({x: hv.Points(np.random.rand(10,10)) for x in range(1,3)})
points = hv.DynamicMap(get_points)
pn.Row(widget_box, points)
The second example shown below, is meant to demonstrate that in certain situations you might want to just simply return an empty plot and the way that I've done it in this example is done in the same way as in this example: http://holoviews.org/gallery/demos/bokeh/box_draw_roi_editor.html#bokeh-gallery-box-draw-roi-editor
The result of this code is an empty plot as expected when a == 1, but when a has values other than 1, the result is quite strange as illustrated in the image below the code.
The points all have the same color
When changing the slider for instance, some points are frozen and never changes, which is not the case in the above working example.
a_widget = pn.widgets.Select(name='A', options=[1,2,3,4])
b_widget = pn.widgets.IntSlider(name='B', start=10, end=20, value=10)
widget_box = pn.WidgetBox(a_widget, b_widget, align='center')
#pn.depends(a=a_widget.param.value, b=b_widget.param.value)
def get_points(a, b):
if a == 1:
return hv.NdOverlay({None: hv.Points([])})
else:
return hv.NdOverlay({x: hv.Points(np.random.rand(10,10)) for x in range(1,3)})
points = hv.DynamicMap(get_points)
pn.Row(widget_box, points)
While I can not help the observed issue with NdOverlay, creating plots with or without content can be done with the help of Overlay.
As b_widget is never used in your code, I removed it for simplicity.
a_widget = pn.widgets.Select(name='A', options=[1,2,3,4])
widget_box = pn.WidgetBox(a_widget, align='center')
#pn.depends(a=a_widget.param.value)
def get_points(a):
images = []
if a == 3:
images.append(hv.Points(np.random.rand(10,10), label='None'))
else:
for x in range(1,3):
images.append(hv.Points(np.random.rand(10,10), label=str(x)))
return hv.Overlay(images)
points = hv.DynamicMap(get_points)
pn.Row(widget_box, points)
The way how to use NdOverlay that is described in the documentation for NdOverlay is different to your approach, this might be a reason for the observed problems.
Anyway, to narrow down which part of the code is responsible for the observed issue, I removed all code that is not necessary to reproduce it.
For clarity, I renamed the values of a, and I also made sure, that a start value for a is provided.
It turned out while testing the code, that the if-else-statement is neither important, so I removed that too.
And just to make sure, that variables behave like expected, I added some print-statements.
This gives the following minimal reproducable example:
a_widget = pn.widgets.Select(name='A', value='Test', options=['Test','Test1', 'Test2'])
#pn.depends(a=a_widget.param.value)
def get_points(a):
dict_ = {}
dict_[str(a)] = hv.Points(np.random.rand(10,10))
print(dict_)
overlay = hv.NdOverlay(dict_)
print(overlay)
return overlay
points = hv.DynamicMap(get_points)
# using the server approach here to see the outpout of the
# print-statements
app = pn.Row(a_widget, points)
app.app()
When running this code, and choosing the different options in the select widget, it turns out that option Test is not updated, once one of the options Test1 and Test3 have been choosen.
When we change the default value in the first line like this
a_widget = pn.widgets.Select(name='A', value='Test2', options=['Test','Test1', 'Test2'])
now Test2 is not updated correctly.
So it looks like this is an issue of DynamicMap using NdOverlay.
So I suggest you report this issue to the developers (if not already done), either wait for new release or use a different approach (e.g. as shown above).
I need to create a programmable filter using Paraview.
The idea is to create a vector called Speed equal to the speed in the non-rotating part equal to the speed+rotational speed in the rotational one.
The problem is that I can't accept the value of the speed in each single cell.
input0 = inputs[0]
radius=3
Speed1=input0.PointData["U"]
K=vtk.vtkDoubleArray()
X=input0.PointData["X"]
Y=input0.PointData["Y"]
Z=input0.PointData["Z"]
pdi = self.GetInput()
numPts = pdi.GetNumberOfPoints()
for i in range(0, numPts):
if X.getvalue(i)^2+Y.getvalue(i)^2<radius:
temp=U.getvalue(i)
else:
temp=U.getvalue(i)+rot
Speed.InsertNextValue(1)
output.PointData.append(Speed, "Speed")
The problem is that X.getvalue(i) is not working.
The correct syntax is
X[i]
The documentation can be found here
I'm using a matlab-function in simulink to call a python script, that do some calculations from the input values. The python-script gives me a string back to the matlab-function, that I split to an array. The splitted string has always to be a cell array with 6 variable strings:
dataStringArray = '[[-5.01 0.09785429][-8.01 0.01284927]...' '10.0' '20.0' '80.0' '80.0' '50.0'
To call the functions like strsplit or the python-script itself with a specific m-file, I'm using coder.extrinsic('*') method.
Now I want to index to a specific value for example with dataStringArray(3) to get '20.0' and define it as an output value of the matlab-function, but this doesn't work! I tried to predefine the dataStringArray with dataStringArray = cell(1,6); but get always the same 4 errors:
Subscripting into an mxArray is not supported.
Function 'MATLAB Function' (#23.1671.1689), line 42, column 24:
"dataStringArray(3)"
2x Errors occurred during parsing of MATLAB function 'MATLAB Function'
Error in port widths or dimensions. Output port 1 of 's_function_Matlab/MATLAB Function/constIn5' is a one dimensional vector with 1 elements.
What do I'm wrong?
SAMPLE CODE
The commented code behind the output definitions is what I need.:
function [dataArrayOutput, constOut1, constOut2, constOut3, constOut4, constOut5] = fcn(dataArrayInput, constIn1, constIn2, constIn3, constIn4, constIn5)
coder.extrinsic('strsplit');
% Python-Script String Output
pythonScriptOutputString = '[[-5.01 0.088068861]; [-4.96 0.0]]|10.0|20.0|80.0|80.0|50.0';
dataStringArray = strsplit(pythonScriptOutputString, '|');
% Outputs
dataArrayOutput = dataArrayInput; % str2num(char((dataStringArray(1))));
constOut1 = constIn1; % str2double(dataStringArray(2));
constOut2 = constIn2; % str2double(dataStringArray(3));
constOut3 = constIn3; % str2double(dataStringArray(4));
constOut4 = constIn4; % str2double(dataStringArray(5));
constOut5 = constIn5; % str2double(dataStringArray(6));
SOLUTION 1
Cell arrays are not supported in Matlab function blocks, only the native Simulink datatypes are possible.
A workaround is to define the whole code as normal function and execute it from the MATLAB-Function defined with extrinsic. It`s important to initialize the output variables with a known type and size before executing the extrinsic function.
SOLUTION 2
Another solution is to use the strfind function, that gives you a double matrix with the position of the splitter char. With that, you can give just the range of the char positions back that you need. In this case, your whole code will be in the MATLAB-Function block.
function [dataArrayOutput, constOut1, constOut2, constOut3, constOut4, constOut5] = fcn(dataArrayInput, constIn1, constIn2, constIn3, constIn4, constIn5)
coder.extrinsic('strsplit', 'str2num');
% Python-Script String Output
pythonScriptOutputString = '[[-5.01 0.088068861]; [-4.96 0.0]; [-1.01 7.088068861]]|10.0|20.0|80.0|80.0|50.0';
dataStringArray = strfind(pythonScriptOutputString,'|');
% preallocate
dataArrayOutput = zeros(3, 2);
constOut1 = 0;
constOut2 = 0;
constOut3 = 0;
constOut4 = 0;
constOut5 = 0;
% Outputs
dataArrayOutput = str2num(pythonScriptOutputString(1:dataStringArray(1)-1));
constOut1 = str2num(pythonScriptOutputString(dataStringArray(1)+1:dataStringArray(2)-1));
constOut2 = str2num(pythonScriptOutputString(dataStringArray(2)+1:dataStringArray(3)-1));
constOut3 = str2num(pythonScriptOutputString(dataStringArray(3)+1:dataStringArray(4)-1));
constOut4 = str2num(pythonScriptOutputString(dataStringArray(4)+1:dataStringArray(5)-1));
constOut5 = str2num(pythonScriptOutputString(dataStringArray(5)+1:end));
When using an extrinsic function, the data type returned is of mxArray, which you cannot index into as the error message suggests. To work around this problem, you first need to initialise the variable(s) of interest to cast them to the right data type (e.g. double). See Working with mxArrays in the documentation for examples of how to do that.
The second part of the error message is a dimension. Without seeing the code of the function, the Simulink model and how the inputs/outputs of the function are defined, it's difficult to tell what's going on, but you need to make sure you have the correct size and data type defined in the Ports and Data manager.