method can't be called from inside for loop? - python

I really don't now why I can't call the method setTRSKey from inside my for loop. Am I missing something? This makes no sense to me at all. Pycharm declares it as an unsolved reference
Here is the code:
import math
import nuke
originNode = nuke.selectedNode()
world_matrix = originNode['world_matrix'] # this is an iArray Knob with 16 fields
mResult = nuke.math.Matrix4() # Matrix to copy iArray to
# Ask user for Frame Range operation
ret = nuke.getFramesAndViews('Frame range', '%s-%s' % (nuke.root().firstFrame(), nuke.root().lastFrame()))
if ret != None:
nuke.nodeCopy("%clipboard%") # creating node duplicate
originNode.setSelected(False)
newNode = nuke.nodePaste("%clipboard%") # creating origin node duplicate
newNode['translate'].clearAnimated()
newNode['translate'].setValue(0)
newNode['translate'].setAnimated()
newNode['rotate'].clearAnimated()
newNode['rotate'].setValue(0)
newNode['rotate'].setAnimated()
newNode['scaling'].clearAnimated()
newNode['scaling'].setValue(0)
newNode['scaling'].setAnimated()
frange = nuke.FrameRange(ret[0]) # convert to frange object
for frame in frange:
for i in xrange(0, 16):
mResult[i] = world_matrix.valueAt(frame)[i]
mResult.transpose() # row become columns and vice versa
mTranslate = nuke.math.Matrix4(mResult)
mTranslate.translationOnly()
mRotate = nuke.math.Matrix4(mResult)
mRotate.rotationOnly()
mScale = nuke.math.Matrix4(mResult)
mScale.scaleOnly()
translate = (mTranslate[12], mTranslate[13], mTranslate[14])
rotateRad = mRotate.rotationsZXY()
rotate = (math.degrees(rotateRad[0]), math.degrees(rotateRad[1]),
math.degrees(rotateRad[2])) # convert from radiants to defrees
scale = (mScale.xAxis().x, mScale.yAxis().y, mScale.zAxis().z)
setTRSKey(frame, translate, rotate, scale)
else:
print "User canceled the operation"
def setTRSKey(frame, translate, rotate, scale):
print type(translate(0))
newNode['translate'].setValueAt(translate(0), frame, 0)
newNode['translate'].setValueAt(translate(1), frame, 1)
newNode['translate'].setValueAt(translate(2), frame, 2)
edit: Example with classes where loadDataFromScript is called before defining
class Connecthor(QtWidgets.QDialog, Ui_Dialog):
#
allowedNodes = ["Read", "Write", "Merge", "Keymix", "ChannelMerge", "Roto", "RotoPaint", "Copy", "Shuffle", "PostageStamp", "Camera", "Camera2", "ScanlineRender", "Connector", "ReadGeo", "ReadGeo2", "BackdropNode"]
script_path = os.path.dirname(os.path.realpath(__file__))
#constructor
def __init__(self, parent=None):
super(Connecthor, self).__init__(parent)
self.setupUi(self)
self.setFixedSize(self.size())
#self.setWindowOpacity(0.95)
popupmenu = QtWidgets.QMenu(self.btn_settings)
#popupmenu.addAction("save links for script", self.writeListDictToJson)
#popupmenu.addAction("import links from json", self.readJsonToDict)
popupmenu.addAction("save links for script (manual)", self.saveDatatoScript)
popupmenu.addAction("settings", self.opensetting)
self.btn_settings.setMenu(popupmenu)
self.btn_settings.setIcon(QtGui.QIcon(os.path.join(iconpath, "settings.png")))
self.btn_addSelectedNodes.setIcon(QtGui.QIcon(os.path.join(iconpath, "add.png")))
self.btn_addSelectedNodes.clicked.connect(self.addSelectedNodes)
# #Loading test Json
#self.readJsonToDict()
self.loadDataFromScript()

In Python you must define functions before they are called. Move your setTRSKey definition above the for loop. Generally speaking, function definitions are one of the very first things in the file after imports, though this is not always the case.

Related

Meshcat not showing the changes to a Free Body's Pose

I've been trying to create my own ManipulationStation for a different robot arm using Pydrake, but I've been unsuccessful so far in adding clutter to my ManipulationStation. For some odd reason, Meshcat won't show the updated poses of my objects.
import numpy as np
import glob
from pydrake.geometry import MeshcatVisualizerCpp
from pydrake.math import RigidTransform, RotationMatrix
from pydrake.systems.analysis import Simulator
from pydrake.systems.framework import DiagramBuilder
from pydrake.all import (
DiagramBuilder, FindResourceOrThrow,
SceneGraph, Diagram,
MultibodyPlant, Parser, Simulator, MeshcatVisualizerCpp,
UniformlyRandomRotationMatrix, RandomGenerator)
from pydrake.geometry import Meshcat
class DexterPPStation(Diagram):
def __init__(self, time_step, file_path):
super().__init__()
self.time_step = time_step
self.path = file_path
self.plant = MultibodyPlant(self.time_step)
self.scene_graph = SceneGraph()
self.plant.RegisterAsSourceForSceneGraph(self.scene_graph)
self.controller_plant = MultibodyPlant(self.time_step)
self.object_ids = []
self.object_poses = []
def AddObject(self, file, name, pose):
model_idx = Parser(self.plant).AddModelFromFile(file, name)
indices = self.plant.GetBodyIndices(model_idx)
self.object_ids.append(indices[0])
self.object_poses.append(pose)
return model_idx
def CreateBins(self, path, XP_B1, XP_B2):
bin1 = Parser(self.plant).AddModelFromFile(path, "bin1")
self.plant.WeldFrames(self.plant.world_frame(), self.plant.GetFrameByName("bin_base", bin1), XP_B1)
bin2 = Parser(self.plant).AddModelFromFile(path, "bin2")
self.plant.WeldFrames(self.plant.world_frame(), self.plant.GetFrameByName("bin_base", bin2), XP_B2)
def CreateRandomPickingObjects(self, n = 4):
choices = [f for f in glob.glob("/opt/drake/share/drake/manipulation/models/ycb/sdf/*.sdf")]
z = 0.1
rs = np.random.RandomState()
generator = RandomGenerator(rs.randint(1000))
for i in range(n):
obj = choices[i]
pose = RigidTransform(
UniformlyRandomRotationMatrix(generator),
[rs.uniform(.35,0.6), rs.uniform(-.2, .2), z])
model = self.AddObject(obj, obj.split("/")[-1].split(".")[0] + str(i), pose)
body_idx = self.plant.GetBodyIndices(model)[0]
self.object_ids.append(body_idx)
self.object_poses.append(pose)
z+=0.1
def SetRandomPoses(self, station_context):
plant_context = self.GetSubsystemContext(self.plant, station_context)
for i in range(len(self.object_ids)):
self.plant.SetFreeBodyPose(plant_context, self.plant.get_body(self.object_ids[i]), self.object_poses[i])
def Finalize(self):
self.plant.Finalize()
self.controller_plant.Finalize()
builder = DiagramBuilder()
builder.AddSystem(self.plant)
builder.AddSystem(self.controller_plant)
builder.AddSystem(self.scene_graph)
builder.Connect(self.plant.get_geometry_poses_output_port(), self.scene_graph.get_source_pose_port(self.plant.get_source_id()))
builder.Connect(self.scene_graph.get_query_output_port(), self.plant.get_geometry_query_input_port())
builder.ExportOutput(self.scene_graph.get_query_output_port(), "query_object")
builder.ExportOutput(self.plant.get_geometry_poses_output_port(), "geometry_poses")
builder.ExportOutput(self.scene_graph.get_query_output_port(), "geometry_query")
builder.ExportOutput(self.plant.get_contact_results_output_port(),"contact_results")
builder.ExportOutput(self.plant.get_state_output_port(),"plant_continuous_state")
builder.BuildInto(self)
To test my code, I've been running the script below.
def test():
builder = DiagramBuilder()
station = DexterPPStation(1e-4, "drake/manipulation/models/final_dexter_description/urdf/dexter.urdf")
station.CreateBins("/opt/drake/share/drake/examples/manipulation_station/models/bin.sdf", RigidTransform(np.array([0.5,0,0])), RigidTransform(np.array([0,0.5,0])))
station.CreateRandomPickingObjects(1)
station.Finalize()
builder.AddSystem(station)
station_context = station.CreateDefaultContext()
station.SetRandomPoses(station_context)
MeshcatVisualizerCpp.AddToBuilder(builder, station.GetOutputPort("query_object"), meshcat)
diagram = builder.Build()
simulator = Simulator(diagram)
simulator.set_target_realtime_rate(1.0)
simulator.AdvanceTo(0.1)
test()
I've tried to call the SetRandomPoses() function from inside my Finalize() method, but since I needed to pass in a context to the function, I wasn't sure what to do. I'm new to Drake, so any input would be greatly appreciated.
You've created a station_context and set it to the random poses, but then you don't use it anywhere. When you create the simulator, it is creating another Context (with the default values), which is getting published when you call AdvanceTo.
The solution here, I think, is to not create your own station_context, but do e.g.
simulator = Simulator(diagram)
diagram_context = simulator.get_mutable_context()
station_context = station.GetMyMutableContextFromRoot(diagram_context)
station.SetRandomPoses(station_context)
then you can call AdvanceTo.

matplotlib - why blitting freezes figure

I have been searching stackoverflow for a solution to the issue of an interactive mpl figure when streaming data to it. I've gotten close with the below example, but when I plot this no matter what mods I make to the code I'm unable to interact with the figure window. What concept am I missing that would allow me to stream data to this window AND drag the window around? As you can see it opens up and plots, but if I grab the frame to move it to a different location it crashes and most of the time is stuck in place.
I'm using Python 2.7, Paycharm and Windows 10.
Here is a helpful example I'm working with.
Example-from-documentation
Is the problem because I'm using plt.show()? My test code consists of 3 files, a datagen, data consumer (plotter) and a top level file (test bench) instantiating and starting the data generator and plotting module. I am just appending 62bytes of sine wave data to the end of an array and plotting it so it looks like it is scrolling by.
Test bench:
NB_DataGen -> NB_Plotter (receives 62 bytes of data and plots).
MODULE1: DATA PLOTTING MODULE
# This is the no blitting data plot module built out as a threaded module.
#
#
# Notes:
# 1. Bug in frame rate code
# 2. Going to try to remove queue from plotter and just have a direct access call for
# direct writes to plot. Queue seems to be bogging down window and I can't drag it
# around.
#
try:
import Queue as queue
except:
import queue
import numpy as np
from matplotlib import pyplot as plt
import time
import threading
import matplotlib
print(matplotlib.__version__)
class BlitManager:
def __init__(self, canvas, animated_artists=()):
"""
Parameters
----------
canvas : FigureCanvasAgg
The canvas to work with, this only works for sub-classes of the Agg
canvas which have the `~FigureCanvasAgg.copy_from_bbox` and
`~FigureCanvasAgg.restore_region` methods.
animated_artists : Iterable[Artist]
List of the artists to manage
"""
self.canvas = canvas
self._bg = None
self._artists = []
for a in animated_artists:
self.add_artist(a)
# grab the background on every draw
self.cid = canvas.mpl_connect("draw_event", self.on_draw)
def on_draw(self, event):
"""Callback to register with 'draw_event'."""
cv = self.canvas
if event is not None:
if event.canvas != cv:
raise RuntimeError
self._bg = cv.copy_from_bbox(cv.figure.bbox)
self._draw_animated()
def add_artist(self, art):
"""
Add an artist to be managed.
Parameters
----------
art : Artist
The artist to be added. Will be set to 'animated' (just
to be safe). *art* must be in the figure associated with
the canvas this class is managing.
"""
if art.figure != self.canvas.figure:
raise RuntimeError
art.set_animated(True)
self._artists.append(art)
def _draw_animated(self):
"""Draw all of the animated artists."""
fig = self.canvas.figure
for a in self._artists:
fig.draw_artist(a)
def update(self):
"""Update the screen with animated artists."""
cv = self.canvas
fig = cv.figure
# paranoia in case we missed the draw event,
if self._bg is None:
self.on_draw(None)
else:
# restore the background
cv.restore_region(self._bg)
# draw all of the animated artists
self._draw_animated()
# update the GUI state
cv.blit(fig.bbox)
# let the GUI event loop process anything it has to do
cv.flush_events()
#
# Main Class
#
class NB_Plotter4(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.i = 0
# thread loop flag
self.thread_event = threading.Event()
self.thread_event.set() # set thread by default
# create plot objects
self.fig = plt.figure()
self.ax1 = self.fig.add_subplot(1,1,1)
self.ax1.grid()
self.line, = self.ax1.plot([], lw=3)
self.text = self.ax1.text(0.8, 0.5, "")
self.x_new = np.linspace(0.0, 200.0, num=1000)
self.y_total = np.empty(1000, dtype=float)
#set limits
self.ax1.set_xlim(self.x_new.min(), self.x_new.max())
self.ax1.set_ylim([-1.1, 1.1])
# start timer for frame counter
self.t_start = time.time()
#self.bm = BlitManager(self.fig.canvas, [self.line, self.text])
self.bm = BlitManager(self.fig.canvas, [self.line])
plt.show(block=False)
plt.pause(0.1)
#
# main thread loop
#
def Write(self, data):
# need to grab y-data here from queue
self.y_ndata = data
self.y_total = np.concatenate([self.y_total[62:], self.y_ndata])
self.i = self.i + 1
#
# Over-ride thread run method
#
def run(self):
while self.thread_event.is_set():
self.line.set_data(self.x_new, self.y_total)
tx = 'Mean Frame Rate:\n {fps:.5f}FPS'.format(fps=((self.i + 1) / (time.time() - self.t_start)))
self.text.set_text(tx)
self.bm.update()
MODULE2: DATA GENERATION MODULE
# This is the no blitting data gen module. This module is intended to produce data
# in 62 byte blocks resulting in sine wave data blocks. This is initally meant to
# spoof my DR500 USB payload size so I can' drive some real time plotting.
#
#
# Notes:
#
#
#
try:
import Queue as queue
except:
import queue
import numpy as np
import threading
import time
#
# Main Class
#
# For the 62 byte class the rounding in the x vector produces some small errors. This shouldn't
# be a big problem since the resolution is so high.
#
class NB_DataGen2(threading.Thread):
def __init__(self, Plotter):
threading.Thread.__init__(self)
self.y_data = np.empty(62, dtype=float)
self.x_data = np.linspace(0.0, np.pi/62.0, num=62)
self.offset_val = self.x_data[1]
self.Plotter_Handle = Plotter
self.inc_cnt = 0.0
self.first_it_flag = 0 # first iteration flag
# thread loop flag
self.thread_event = threading.Event()
self.thread_event.set() # set thread by default
#
# Produce 62 byte packet of sine wave data
# - produce next 62 byte chunk of sine wave data
def Get62ByteSine(self, debug=False):
# hit for iterations > 0
if(self.first_it_flag > 0):
# gen
self.x_data = self.x_data + (np.pi / 62.0) + self.offset_val
self.y_data = np.sin(self.x_data)
if(debug == True):
print(self.y_data)
return self.y_data
# hit for iterations < 1 -> (first iteration)
else:
# first iteration
self.x_data = self.x_data
self.y_data = np.sin(self.x_data)
if (debug == True):
print(self.y_data)
self.inc_cnt = self.inc_cnt + 1.0
# flip first run flag
self.first_it_flag = 1
return self.y_data
#
# Ignore / Not in use
#
# Used to check the error from the last value in one block (62 byte block)
# and the first value of the next block. the difference in the two should
# match the offset value roughly. Enable print funcitons in the above
# Get62ByteSine function for this to work.
#
def CheckError(self):
self.Get62ByteSine(True)
self.Get62ByteSine(True)
self.Get62ByteSine(True)
# print offset
print(self.offset_val)
#
# Kill thread
#
def KillThread(self):
self.thread_event.clear()
#
# main thread loop
#
def run(self):
while self.thread_event.is_set():
self.Plotter_Handle.Write(self.Get62ByteSine())
time.sleep(1)
MODULE3: TOP LEVEL TEST BENCH
# This is the no blitting test bench top module
#
#
# Notes:
#
#
#
from NB_DataGen2 import NB_DataGen2
from NB_Plotter4 import NB_Plotter4
#
# Testbench Class
#
class NB_TestBench(object):
def __init__(self):
# create data/plot objects (DUTs) - obj's under test
self.Plotter = NB_Plotter4()
self.DataGen = NB_DataGen2(self.Plotter)
def Start(self):
self.DataGen.start()
self.DataGen.isDaemon()
self.Plotter.start()
self.Plotter.isDaemon()
# Run test bench
NB = NB_TestBench()
NB.Start()
Long story short - I'm trying to run this code to plot incoming data and be able to drag the window around or just generally interact with it via the mouse. Does anyone see where I went wrong?

In Maya, how can I delete with python some object in the node Mash/Repro?

I have 56 objects in my node repromesh.
I have listed all the attributes of this node, but can't figure how to delete one (or all) the object in order to replace them with another.
There are some attribute like : instancedGroup.instancedMesh but no value/type I can find to access it.
enter image description here
Quite complex one : (EDIT : solution for delete all in the bottom)
if you go to this python file (i found this module by turning on echo all, while removing item) :
print(mash_repro_aetemplate.__file__)
You will find the mash script and the pieces where they call the UI.
import maya.OpenMayaUI as mui
from shiboken2 import wrapInstance
usingPyside2 = False
try:
import PySide2
usingPyside2 = True
except:
pass
from flux.imports import *
from flux.core import pix
import flux.core as fx
import mash_repro_utils
from mash_repro_icons import MASH_REPRO_ICONS
from functools import partial
import MASH.undo as undo
def get_maya_window():
ptr = mui.MQtUtil.mainWindow()
if ptr is not None:
return wrapInstance(long(ptr), qt.QMainWindow)
def refresh_all_aetemplates(force=False):
""" Refresh all the repro aetemplates"""
widgets = get_maya_window().findChildren(AEMASH_ReproTemplate) or []
for widget in widgets:
global SCENE_OPENED
SCENE_OPENED = True
widget.update_data(widget.node, force=force)
SCENE_OPENED = False
here is a way to find the repro node :
widgets = get_maya_window().findChildren(qt.QWidget, 'AEMASH_ReproTemplate') or []
myRepro = widgets[0]
'myRepro' is now the class of the mash repro node.
The Qtreewidget representing your nodes is :
myRepro.objs_widget
you can use from this other class derived from qtree :
# work only on selection, if you want to modify this command, maybe create your own add_sel_bjects(self, objs=[])
myRepro.objs_widget.add_objects()
# work only on the selection in the qtree widget
myRepro.objs_widget.delete_item()
# you can use qtree functions instead :
# myRepro.objs_widget.clear()
items_count = myRepro.objs_widget.topLevelItemCount()
In the delete_item methods, there is this
mash_repro_utils.remove_mesh_group(myRepro.objs_widget.node, id)
mash_repro_utils.remove_proxy_group(self.node, self.instance_index, id)
I didn't had time to investigate but from there, you find :
print(mash_repro_utils.__file__)
# Result: 'maya_path/plug-ins/MASH/scripts/mash_repro_utils.py' #
Go there and there is all the maya python mash functions :
def remove_proxy_group(mash_repro_node, instance_index, index):
"""
Remove a proxy object from the Repro node
:param mash_repro_node: MASH Repro node
:param instance_index: Object index
:param index: Proxy index
:return: None
"""
with ReproUpdating(mash_repro_node):
data = get_data_layout(mash_repro_node)
indices = data[instance_index]['proxies'].keys()
indices.sort()
if index in indices:
position = indices.index(index)
for i in range(position, len(indices)):
clean_proxy_index(mash_repro_node, instance_index, indices[i])
for i in range(position + 1, len(indices)):
if 'group' in data[instance_index]['proxies'][indices[i]]:
new_index = connect_proxy_group(mash_repro_node, data[instance_index]['proxies'][indices[i]]['group'], instance_index)
maya.cmds.setAttr("%s.instancedGroup[%d].proxyGroup[%d].proxyLod" % (mash_repro_node, instance_index, new_index), data[instance_index]['proxies'][indices[i]]['proxyLod'])
hasMASHFlag = maya.cmds.objExists('%s.mashOutFilter' % (data[instance_index]['proxies'][indices[i]]['group']))
if hasMASHFlag:
maya.cmds.deleteAttr( data[instance_index]['proxies'][indices[i]]['group'], at='mashOutFilter' )
You should be able to investigate from there.
You could just make your own delete_all, like this also:
items_count = myRepro.objs_widget.topLevelItemCount()
for id in sorted(range(items_count), reverse=True):
mash_repro_utils.remove_mesh_group(myRepro.objs_widget.node, id)
myRepro.objs_widget.obj_dropped.emit(None)

AttributeError: Class instance has no attribute 'xyz'

For the class below, I'm getting this exception:
AttributeError: LineIntensityProfileLogic instance has no attribute 'probeVolume'
How can I solve this issue? Thanks
class LineIntensityProfileLogic(ScriptedLoadableModuleLogic):
"""This class should implement all the actual
computation done by your module. The interface
should be such that other python code can import
this class and make use of the functionality without
requiring an instance of the Widget.
Uses ScriptedLoadableModuleLogic base class, available at:
https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py
"""
def hasImageData(self,volumeNode):
"""This is a dummy logic method that
returns true if the passed in volume
node has valid image data
"""
if not volumeNode:
print('no volume node')
return False
if volumeNode.GetImageData() == None:
print('no image data')
return False
return True
def takeScreenshot(self,name,description,type=-1):
# show the message even if not taking a screen shot
self.delayDisplay(description)
if self.enableScreenshots == 0:
return
lm = slicer.app.layoutManager()
# switch on the type to get the requested window
widget = 0
if type == slicer.qMRMLScreenShotDialog.FullLayout:
# full layout
widget = lm.viewport()
elif type == slicer.qMRMLScreenShotDialog.ThreeD:
# just the 3D window
widget = lm.threeDWidget(0).threeDView()
elif type == slicer.qMRMLScreenShotDialog.Red:
# red slice window
widget = lm.sliceWidget("Red")
elif type == slicer.qMRMLScreenShotDialog.Yellow:
# yellow slice window
widget = lm.sliceWidget("Yellow")
elif type == slicer.qMRMLScreenShotDialog.Green:
# green slice window
widget = lm.sliceWidget("Green")
else:
# default to using the full window
widget = slicer.util.mainWindow()
# reset the type so that the node is set correctly
type = slicer.qMRMLScreenShotDialog.FullLayout
# grab and convert to vtk image data
qpixMap = qt.QPixmap().grabWidget(widget)
qimage = qpixMap.toImage()
imageData = vtk.vtkImageData()
slicer.qMRMLUtils().qImageToVtkImageData(qimage,imageData)
annotationLogic = slicer.modules.annotations.logic()
annotationLogic.CreateSnapShot(name, description, type, self.screenshotScaleFactor, imageData)
def run(self,volumeNode1,volumeNode2,rulerNode,enableScreenshots=0,screenshotScaleFactor=1):
"""
Run the actual algorithm
"""
print('LineIntensityProfileLogic run() called')
"""
1. get the list(s) of intensity samples along the ruler
2. set up quantitative layout
3. use the chart view to plot the intensity sampless
"""
"""
1. get the list of samples
"""
if not rulerNode or (not volumeNode1 and not volumeNode2):
print('Inputs are not initialized')
return
volumeSamples1 = None
volumeSamples2 = None
if volumeNode1:
volumeSamples1 = self.probeVolume(volumeNode1, rulerNode)
if volumeNode2:
volumeSamples2 = self.probeVolume(volumeNode2, rulerNode)
print('volumeSamples1 = '+str(volumeSamples1))
print('volumeSamples2 = '+str(volumeSamples2))
imageSamples = [volumeSamples1, volumeSamples2]
legendNames = [volumeNode1.GetName()+' - '+rulerNode.GetName(), volumeNode2.GetName+' - '+rulerNode.GetName()]
self.showChart(imageSamples, legendNames)
self.delayDisplay('Running the aglorithm')
self.enableScreenshots = enableScreenshots
self.screenshotScaleFactor = screenshotScaleFactor
self.takeScreenshot('LineIntensityProfile-Start','Start',-1)
return True
def probeVolume(self,volumeNode,rulerNode):
# get ruler endpoints coordinates in RAS
p0ras = rulerNode.GetPolyData().GetPoint(0)+(1,)
p1ras = rulerNode.GetPolyData().GetPoint(1)+(1,)
# Convert RAS to IJK coordinates of the vtkImageData
ras2ijk = vtk.vtkMatrix4x4()
volumeNode.GetRASToIJKMatrix(ras2ijk)
p0ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p0ras)[:3]]
p1ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p1ras)[:3]]
# Create VTK line that will be used for sampling
line = vtk.vtkLineSource()
line.SetResolution(100)
line.SetPoint1(p0ijk[0],p0ijk[1],p0ijk[2])
line.SetPoint2(p1ijk[0],p1ijk[1],p1ijk[2])
# Create VTK probe filter and sample the image
probe = vtk.vtkProbeFilter()
probe.SetInputConnection(line.GetOutputPort())
probe.SetSourceData(volumeNode.GetImageData())
probe.Update()
# return VTK array
return probe.GetOutput().GetPointData().GetArray('ImageScalars')
def showChart(self, samples, names):
print("Logic showing chart")
# Switch to a layout containing a chart viewer
lm = slicer.app.layoutManager()
lm.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutFourUpQuantitativeView)
# Initialize double array MRML node for each sample list since this is ,
# what chart view MRML node needs
doubleArrays = []
for sample in samples:
arrayNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLDoubleArrayNode())
array = arrayNode.GetArray()
nDataPoints = sample.GetNumberOfTuples()
array.SetNumberOfTuples(nDataPoints)
array.SetNumberOfComponents(3)
for i in range(nDataPoints):
array.SetComponent(i, 0, i)
array.SetComponent(i, 1, sample.GetTuple(i))
array.SetComponent(i, 2, 0)
doubleArrays.append(arrayNode)
# Get the chart view MRML node
cvNodes = slicer.mrmlScene.GetNodesByClass('vtkMRMLChartViewNode')
cvNodes.SetReferenceCount(cvNodes.GetReferenceCount()-1)
cvNodes.InitTraversal()
cvNode = cvNodes.GetNextItemAsObject()
# Create a new chart node
chartNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLChartNode())
for pairs in zip(names, doubleArrays):
chartNode.AddArray(pairs[0], pairs[1], GetID())
cvNode.SetChartNodeID(chartNode.GetID())
return
You seem to be using 2 spaces for indentation.
But for the function - probeVolume , it is indented 4 spaces , which caused it to be inside function run , are you sure that indentation is correct?
Not just probeVolume , function - showChart is also indented 4 spaces,

RuntimeError: deleteUI: Object 'Animation_Copy_Tool' not found

Getting this error when pressing the "Close Window" button in my UI. This button should delete the UI window but isn't. Full traceback:
Error: deleteUI: Object 'Animation_Copy_Tool' not found.
Traceback (most recent call last):
File "", line 36, in closeBtnCmd
RuntimeError: deleteUI: Object 'Animation_Copy_Tool' not found. #
# Animation Copy Tool
# Bakari Holmes 5/7/2015
# This is designed to copy and existing animation
# from one rig to another and make the process easier
# with a simple UI
import maya.cmds as mc
import functools
import maya.mel as mm
import pprint
class AnimCopyWindow(object):
##classmethod
def showUI(cls):
win = cls()
win.create()
return win
def __init__(self):
self.window = "Animation Copy Tool"
self.title = "Animation Copier"
self.size = (546,350)
def pasteTheseKeys(self, *args):
self.offsetVal = mc.intFieldGrp(self.int_offset, q=True, value1=True)
self.selObj_pasteKeys = mc.ls(sl=True)
for objectQuant in self.selObj_pasteKeys:
print objectQuant
self.ct = mc.currentTime(query = True)
self.t = self.ct + self.offsetVal
mc.currentTime(self.t)
# mc.selectKey(selObj_pasteKeys[objectQuant])
mc.pasteKey(time=(self.t,self.t), f=(1.0,1.0), option="merge", copies=1, to=0, fo=0, vo=0)
def closeBtnCmd(self,*args):
mc.deleteUI(self.window,window=True)
def create(self):
# check to see if window exists already
if mc.window(self.window,exists=True):
mc.deleteUI(self.window,window=True)
self.window = mc.window(self.window, title=self.title,widthHeight=self.size,menuBar=True)
self.copyAnim = mc.window(title="Transfer Animation Tool", backgroundColor=[0.3,0.3,0.3],sizeable=False,resizeToFitChildren=True)
#set the layout for UI
mc.columnLayout(adjustableColumn=True)
self.tx_src = mc.textFieldGrp(label="Source Object", editable=False, text=sel[0])
self.int_offset = mc.intFieldGrp(label="Frame Offset Amount", value1=0)
#add paste animation button
self.btn1 = mc.button(label="PASTE ANIMATION", command=self.pasteTheseKeys, bgc=[0.1,0.1,0.5])
#add close button window
self.btn2 = mc.button(label="CLOSE WINDOW", command=self.closeBtnCmd, bgc=[0.2,0.2,0.2])
mc.showWindow()
#################################
#####end of class definition#####
#################################
def keys_as_dictionary(channel):
"""return a dictionay of times:values for <channel>"""
keys = mc.keyframe(channel, q=True, tc=True) or []
values = mc.keyframe(channel, q=True, vc=True) or []
return dict(zip(keys, values))
def channels():
"""return a dictionary of <plug>:<channel_dict> for each animated plug selected"""
keys = mc.keyframe(sl=True, n=True, q=True)
result = {}
for k in keys:
plugs = mc.listConnections(k, p=True)[0]
result[plugs]= keys_as_dictionary(k)
return result
#store selected object info
sel = mc.ls(selection=True)
if (len(sel) != 1):
mm.eval("warning Must select one animated object;")
else:
mc.copyKey()
win = AnimCopyWindow()
win.create()
pprint.pprint(channels())
This error almost always means your UI element is not named what you think it is: Maya will automatically rename the items to make sure that no two siblings have the same name -- you can ask for "my_window" and get back "my_window123" . So you need to capture the actual name that is returned from cmds.window() or whatever ui command you use and delete that. Hard coded names are never reliable

Categories