driven animation curves in OpenMaya - python

I am a bit stuck trying to create driven (unitless) animCurves with OpenMaya
I am in maya 2017, using OpenMaya api 2.0
I am trying to use MFnAnimCurve to create multiple keyframes at the same time. this seems to work when using timed curve types (using MTimeArray as first argument) but it fails when using unitless curves and a MDoubleArray for the first argument..
Am I missing something? should i be using a different type for the first argument?
import maya.api.OpenMaya as om
import maya.api.OpenMayaAnim as oma
graph_modifier = om.MDGModifier()
m_object = om.MFnDependencyNode().create('transform', 'locator1')
node = om.MFnDependencyNode(m_object)
m_plug = node.findPlug(node.attribute('translateX'), True)
out_plug = node.findPlug(node.attribute('translateY'), True)
mfn_anim_curve = oma.MFnAnimCurve()
curve_type = mfn_anim_curve.unitlessAnimCurveTypeForPlug(m_plug)
#curve_type = mfn_anim_curve.timedAnimCurveTypeForPlug(m_plug)
anim_curve_m_object = oma.MFnAnimCurve().create(m_plug, animCurveType=curve_type)
anim_curve = oma.MFnAnimCurve(anim_curve_m_object)
in_plug = anim_curve.findPlug(anim_curve.attribute('input'), True)
graph_modifier.connect(out_plug, in_plug)
graph_modifier.doIt()
in_values = om.MDoubleArray()
out_values = om.MDoubleArray()
for x in range(5):
in_values.append(float(x))
for x in range(5):
out_values.append(float(x))
print in_values, out_values
anim_curve.addKey(1.0, 1.0)
anim_curve.addKey(2.0, 2.0)
#This Fails
anim_curve.addKeys(in_values, out_values)

Someone pointed out to me, That the documentation for MFnAnimCurve.addKeys() does specify that it only works for kAnimCurveTA, kAnimCurveTL, and kAnimCurveTU. Whereas the type being returned by unitlessAnimCurveTypeForPlug() is kAnimCurveUL

Related

Google Earth Engine python

I am trying to import nighttime light data on qgis and I keep getting invalid syntax at the last line of my code (Map. centerObject(sydney, 5))
Here is my code
import ee
from ee_plugin import Map
sydney_shp_path = ('Users/macbookpro/Downloads/OpenNightLights-master 2/onl/tutorials/files/city_of_sydney_shapefile')
night_img = ee.ImageCollection("NOAA/VIIRS/DNB/MONTHLY_V1/VCMSLCFG").filterDate('2018-01-01','2018-12-31').select('avg_rad')
NL_mean = night_img.mean()
nightclass = NL_mean.gt(5).add(NL_mean.gt(50)).add(NL_mean.gt(100))
nightclass = nightclass.updateMask(nightclass.neq(0))
Map.addLayer(nightclass.clip(sydney), ({'min':1, 'max':100}, 'VIIRS 2018', 'Nightlight')
Map.centerObject(sydney, 5)
Method Map.addLayer is not closed properly.
I am guessing method takes two parameters one return value of clip and another tuple.
Set center of map Map.setCentre()

Need help to make pandas' df.rolling.apply work in Backtrader (python)

Working on translating the popular Squeeze Momentum indicator from LazyBear (which is available in Pine language on TradingView), to use it in Backtrader in Python.
I used these resources to help me:
https://community.backtrader.com/topic/2893/bollingerbands-squeeze
https://medium.com/geekculture/implementing-the-most-popular-indicator-on-tradingview-using-python-239d579412ab
https://gist.github.com/yongghongg/ec89ada5709abe574ea6fe93a98c1a94
https://school.stockcharts.com/doku.php?id=technical_indicators:ttm_squeeze
More specifically, I have issues with the momentum indicator itself.
It uses the df.rolling.apply syntax from pandas and polyfit from numpy, but the syntax seems incompatible with Backtrader, so I need some help from the community.
I think I need help to help with the last 2 lines of code (fit_y and self.lines.Mom), basically.
The last 2 lines were transcribed from Pine to Python as:
fit_y = np.array(range(0,length_KC))
df['value'] = df['value'].rolling(window = length_KC).apply(lambda x: np.polyfit(fit_y, x, 1)[0] * (length_KC-1) + np.polyfit(fit_y, x, 1)[1], raw=True)
The code I have translated to Backtrader so far:
# Create Momentum indicator
class MomentumInd(bt.Indicator):
lines = ('Mom',)
params = (('period', 20),)
plotinfo = dict(subplot=False)
def _plotlabel(self):
plabels = [self.p.period]
return plabels
def __init__(self):
highest = bt.ind.Highest(self.data.high, period=self.p.period)
lowest = bt.ind.Lowest(self.data.low, period=self.p.period)
midline = (highest + lowest) / 2
mavg = bt.ind.MovingAverageSimple(self.data.close, period=self.p.period)
delta = self.data.close - ((midline + mavg) / 2)
fit_y = np.array(range(0, self.p.period, 1))
self.lines.Mom = delta.rolling(window=self.p.period).apply(lambda x: np.polyfit(fit_y, x, 1)[0] * (self.p.period - 1) + np.polyfit(fit_y, x, 1)[1], raw=True)
Unfortunately when running the code, I get the error:
AttributeError: 'LinesOperation' object has no attribute 'rolling'
I think that it relates to the rolling window function in pandas followed by the apply function (df.rolling.apply), which seems incompatible with Backtrader. Unfortunately, I don't manage to go any further on my own.
Any idea how to translate these last 2 lines in a way that Backtrader can interpret the code, by any chance?
Many thanks for your help!

Colour Difference in The Foundry NUKE

So I am trying to make a painterly node group with Python code straight so I can use it for future projects but I can't seem to get the power part of the formula in nuke to work from this colour difference formula( I'm also new to Nuke so if there is a better way of writing this please let me know it would be awesome thank you, or if I'm doing this wrong completely also let me know)
The following formula for color difference is used to create the
difference image: |(r1,g1,b1) – (r2,g2,b2)| = ((r1 – r2)^2 + (g1
–g2)^2 + (b1 – b2)^2)^1/2.
nRedShuffle = nuke.nodes.Shuffle()
nRedShuffle['red'].setValue('red')
nRedShuffle['green'].setValue('red')
nRedShuffle['blue'].setValue('red')
nRedShuffle['alpha'].setValue('red')
nGreenShuffle = nuke.nodes.Shuffle()
nGreenShuffle['red'].setValue('green')
nGreenShuffle['green'].setValue('green')
nGreenShuffle['blue'].setValue('green')
nGreenShuffle['alpha'].setValue('green')
#...(so on for the rest of rgba1 and rgba2)
nGreenShuffle2 = nuke.nodes.Shuffle()
nGreenShuffle2['red'].setValue('green')
nGreenShuffle2['green'].setValue('green')
nGreenShuffle2['blue'].setValue('green')
nGreenShuffle2['alpha'].setValue('green')
nBlueShuffle2 = nuke.nodes.Shuffle()
nBlueShuffle2['red'].setValue('blue')
nBlueShuffle2['green'].setValue('blue')
nBlueShuffle2['blue'].setValue('blue')
nBlueShuffle2['alpha'].setValue('blue')
#I am having troubles with the powers below
redDiff = nuke.nodes.Merge2(operation='minus', inputs=[nRedShuffle2, nRedShuffle])
redDiffMuli = nuke.nodes.Merge2(operation='multiply', inputs=[redDiff, redDiff])
greenDiff = nuke.nodes.Merge2(operation='minus', inputs=[nGreenShuffle2, nGreenShuffle])
greenDiffMuli = nuke.nodes.Merge2(operation='multiply', inputs=[greenDiff, greenDiff])
blueDiff = nuke.nodes.Merge2(operation='minus', inputs=[nBlueShuffle2, nBlueShuffle])
blueDiffMuli = nuke.nodes.Merge2(operation='multiply', inputs=[blueDiff, blueDiff])
redGreenAdd = nuke.nodes.Merge2(operation='plus', inputs=[redDiffMuli, greenDiffMuli])
redGreenBlueAdd = nuke.nodes.Merge2(operation='plus', inputs=[redGreenAdd, blueDiffMuli])
Here are at least two ways to implement Color Difference formula for two images. You can use difference op in Merge node or you can write a formula in field for each channel inside MergeExpression node:
Expression for each channel is as simple as this:
abs(Ar-Br)
abs(Ag-Bg)
abs(Ab-Bb)
Python commands
You can use .nodes.MergeExpression methodology:
import nuke
merge = nuke.nodes.MergeExpression(expr0='abs(Ar-Br)',
expr1='abs(Ag-Bg)',
expr2='abs(Ab-Bb)')
or regular .createNode syntax:
merge = nuke.createNode('MergeExpression')
merge['expr0'].setValue('abs(Ar-Br)')
merge['expr1'].setValue('abs(Ag-Bg)')
merge['expr2'].setValue('abs(Ab-Bb)')
Full code version
import nuke
import nukescripts
red = nuke.createNode("Constant")
red['color'].setValue([1,0,0,1])
merge = nuke.createNode('MergeExpression')
merge['expr0'].setValue('abs(Ar-Br)')
merge['expr1'].setValue('abs(Ag-Bg)')
merge['expr2'].setValue('abs(Ab-Bb)')
yellow = nuke.createNode("Constant")
yellow['color'].setValue([1,1,0,1])
merge.connectInput(0, yellow)
nuke.toNode('MergeExpression1').setSelected(True)
nukescripts.connect_selected_to_viewer(0)
# Auto-alignment in Node Graph
for everyNode in nuke.allNodes():
everyNode.autoplace()
Consider! MergeExpression node is much slower that regular Merge(difference) node.

Make Hatch object in AutoCAD by the use of COM

I`m working with AutoCAD drawing using Python language and comtypes library. This is fragment of my code:
from comtypes.client import *
from comtypes.automation import *
def connect_acad(self):
self.acad = GetActiveObject("AutoCAD.Application")
self.dwg = self.acad.ActiveDocument
self.mspace = self.dwg.ModelSpace
def mark_point(self, xy, num, lay):
def point(*args):
lst = [0.]*3
if len(args) < 3:
lst[0:2] = [float(x) for x in args[0:2]]
else:
lst = [float(x) for x in args[0:3]]
return VARIANT(array("d",lst))
def variant(data):
return VARIANT(VT_VARIANT, data)
def vararr(*data):
if ( len(data) == 1 and
isinstance(data, collections.Iterable) ):
data = data[0]
return map(variant, data)
p1 = point(xy[0], xy[1])
ent = self.mspace.AddCircle(p1, 0.3)
htch = self.mspace.AddHatch(0, 'SOLID', False)
htch.AppendOuterLoop(vararr([ent,]))
htch.Evaluate()
If anyone interested, full code here: https://github.com/nsedenkov/py_acadcoord/blob/master/acadcoord.py
And anything works correctly, but command htch.AppendOuterLoop raises exception "ComTypeError". Probably, anyone knows the right way to make variant array from AutoCAD graphical entitys for method AppendOuterLoop? Thank you!
The expected types are:
Type: Variant (array of Arc, Circle, Ellipse, Line, Polyline, Region, Spline objects)
And I would also recommend double check the condition:
An array of objects forming a closed boundary. The array can consist of one or more objects. If more than one object is used, their endpoints must coincide for the loop to be created properly.
See complete documentation at http://knowledge.autodesk.com/support/autocad-mechanical/getting-started/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-ActiveX/files/GUID-4CA06494-CDFF-46FA-9E1D-A0E8220F69F4-htm.html

Chaco: 2 tools write the same metadata key

I have this problem with chaco.
In the plot, I need select some points (are points that I generate). This points, I can select with two tools: RangenSelection and ScatterInspector. If I work with only one tool, the code work well and I can detect with points I select, but when I work with both tools, both tools write the same metadata name: selections. This is the most important part of the code:
#this are all the tools.append
my_plot.tools.append(ScatterInspector(my_plot, selection_mode="toggle", persistent_hover=False))
my_plot.overlays.append(
ScatterInspectorOverlay(my_plot,
hover_color = "transparent",
hover_marker_size = 10,
hover_outline_color = "purple",
hover_line_width = 2,
selection_marker_size = 8,
selection_color = "red")
)
my_plot.tools.append(RangeSelection(my_plot, left_button_selects = False, rigth_button_selects = True, auto_handle_event = False))
my_plot.overlays.append(RangeSelectionOverlay(component=my_plot))
my_plot.tools.append(PanTool(my_plot))
my_plot.overlays.append(ZoomTool(my_plot, drag_button="right"))
return plot
#the rest of the code
def _metadata_handler(self):
sel_indices = self.index_datasource.metadata.get('selections', [])
su = self.index_datasource.metadata.get('annotations', [])
print su
print "Selection indices:", sel_indices
def _plot_default(self):
plot = _create_plot_component()
# Retrieve the plot hooked to the tool.
my_plot = plot.plots["my_plot"][0]
# Set up the trait handler for the selection
self.index_datasource = my_plot.index
self.index_datasource.on_trait_change(self._metadata_handler,
"metadata_changed")
return plot
When I run the code, and see what are in annotations, is always empty. But in selections the code write with both tools and this give an error.
How can I tell to some tool in where metadata key write??
Thanks for your help.
The solution is put metadata_name="annotations" in RangeSelection and in RangeSelectionOverlay

Categories