I wrote an MEL script in Maya. So I want to select a joint, then run the MEL script and it selects that joint and all its children. I very new to MEL, So with running the code, it throws a bunch of errors. Can you help me reduce error or better to get rid of all of them?
The Script:
string $joints[];
string $current[] = 'ls -selection';
proc selectJoints (){
if ('searchJoints($joints)' == 0){
$joints['size($joints)'] = $current[0];
pickWalk -d down;
$current[0] = 'ls -sl';
selectJoints();
}
else{
pickWalk -d right;
$current[0] = 'ls -sl';
if('searchJoints($joints)' == 0){
selectJoints();
}
else{
pickWalk -d up;
$current[0] = 'ls -sl';
if($current[0] == $joints[0]){
selectJoints();
}
}
}
return;
}
select ($Joints);
proc int searchJoints (string $jns[]){
int $result = 0;
for ($joint in $jns[]){
if ($current[0] == $joint){
return 1;
}
}
return 0;
}
So, I know your question is about MEL, and I am sorry for not being able to help you with that BUT i think i can help you with python and pymel.
Try this code in a Python tab in the script editor:
import pymel.core as pm
# get selected joint
selectedJoint = pm.selected()[0]
#get all children from the selected joint and puts it in a list
joints = selectedJoint.listRelatives(allDescendents = True)
#adds first selected joint to same list
joints.append(selectedJoint)
#clears selection
pm.select(clear = True)
#loop thru list of joints
for item in joints:
#toggle selection on selected joint and all its descendents
pm.select(item, tgl = True)
I am not sure why to use MEL, I started directly with pymel and it seems more powerful. Could you tell me why MEL?...I think I might be missing out on something. Anyway, I think this short code does the trick. Good luck! Be aware that there are no fail safes there. so, make sure you select ONE joint to run before running the script.
You can simply do:
select -hi;
Related
I'm new to mel script. I know that I can toggle manually xray with the code.
displaySurface -xRay true; //Xray on
displaySurface -xRay false; //Xray off
But I want it to toggle automatically, like
if(xRay on)
set xRay off
else
set xRay on
I know that I can check xRay on or off with the command
displaySurface -query -xRay;
But I just can't put this command into if block. I tried many things like the code below, but nothing works.
if(`displaySurface -query -xRay` == 1) // Error: line 1: Cannot use data of type int[] in a scalar operation. //
print("To be or not to be");
Looks like displaySurface -query -xRay is returning an array. This worked for me:
int $y[] = `displaySurface -query -xRay`;
if( $y[0] == 1)
print("To be or not to be");
The brackets after int in the error Cannot use data of type int[] indicates that the function returns an integer array. So you need to take the first element [0] of the array.
$xRayOnArray = `displaySurface -q -xRay`;
if ($xRayOnArray[0] == 0) {
print("X-Ray is enabled");
} else {
print("X-Ray is disabled");
}
Why it returns an array is a puzzle. It isn't documented and the function can only query a single object at a time.
I'm trying to insert a file into TYPO3 db through frontend using core functions or FileRepository, exactly into sys_file table.
While investigating I've seen few solutions like,
$storageRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
$storage = $storageRepository->findByUid(1);
$fileObject = $storage->addFile('/tmp/myfile', $storage->getRootLevelFolder(), 'newFile');
echo $fileObject->getIdentifier(); // Should output "/newFile"
But I still can't find this addFile() in storageRepository class. Am I missing some thing here?
The line $storageRepository->findByUid(1) return a ResourceStorage Object with the Method addFile().
Here is a Documenttion of this class.
https://typo3.org/api/typo3cms/class_t_y_p_o3_1_1_c_m_s_1_1_core_1_1_resource_1_1_resource_storage.html
#mario Thanks. By the way I've achieved what I planned. Here's what I did..
public function uploadFile($uploadedfile) {
$storage = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
$filePath = 'uploads/tx_fileupload/'.$uploadedfile['updata']['name'];
$title = $uploadedfile['updata']['name'];
$size = $uploadedfile['updata']['size'];
// Moving the physical file to destined folder
\TYPO3\CMS\Core\Utility\GeneralUtility::upload_copy_move($uploadedfile['updata']['tmp_name'],$filePath);
// Adding a record in sys_file_storage
$fileObject = $storage->createLocalStorage($uploadedfile['updata']['name'],$uploadedfile['updata']['tmp_name'],$filePath,'');
// Inserting file in sys_file
$repositoryFileObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->retrieveFileOrFolderObject($filePath);
return $repositoryFileObject;
}
Now moving onto adding corresponding sys_file_reference record.
I have a PowerShell script with the following excerpt:
foreach ($pc in $ComputerName) {
$appnames = $appnames | Sort-Object
Write-Debug "Number of entries in `$appnames = $($appnames.count)"
if ($AsHTML) {#Switch Parameter
Write-Verbose "Generating HTML Report..."
$th = "<TR><TH>Application Name</TH>" #Create Top header
foreach ($pc in $ComputerName) {
$th += "<TH>$pc</TH>" #Another header for each pc
}
$th += "</TR>" #Header finished
$rows = ""
foreach ($app in $appnames) {
$rows += "<TR><TH>$app</TH>"
foreach ($pc in $ComputerName) {
Write-Debug $RegistryEntries[$pc].Value[$app]
$currentApp = $RegistryEntries[$pc].Value[$app]
if ($currentApp) {
if ($currentApp.DisplayVersion) {
$status = $currentApp.DisplayVersion
} else {
$status = "Version-nr. N/A"
}
} else {
$status = "Application N/A"
}
$rows += "<TD>$status</TD>" #Intersection cell for each pc
}
$rows += "</TR>"
}
Write-Verbose "Finishing html report..."
$html = "
<html>
<head>
<style>
body { background-color:#FFFFCC;
font-family:Tahoma;
font-size:12pt; }
td, th { border:1px solid #000033;
border-collapse:collapse; }
th { color:white;
background-color:#000033; }
table, tr, td, th { padding: 0px; margin: 0px }
table { margin-left:10px; }
</style>
<Title>Application versions Report</Title>
</head>
<body>
<table>
$th
$rows
</table>
</body>
</html>"
}
}
So, to explain the wall of text above a bit;
$RegistryEntries is a Hashtable of Hashtables, with the top-level keys being computer names, and the low-level hashtable keys being application names found in the Uninstall part of the registry. The corresponding values to the Application-name-keys are custom PSObjects with three general properties: .Displayname, .DisplayVersion, and .UninstallString. (Not all objects have all of the three properties, but each object has at least one).
What I hope to achieve with this HTML-table is to get some kind of "pivot-table" (ref. Wikipedia entry for Pivot Tables, but not quite), where I can get Application Names on the Y-axis, and computer names on the X-axis, and the Version number of said application on said computer where they intersect.
So again, with that in mind, could someone help me understand why my script when run prompts me in the shell for permission to add application names to the array $appnames (elsewhere in the script), as well as doing the same with the HTML input that is being put into $rows?
Another thing which is a bit on the side (maybe even off-topic), my $RegistryEntries object, the hashtable of hashtables, is for some reason not possible to access in the way I do it on the two following lines:
Write-Debug $RegistryEntries[$pc].Value[$app]
$currentApp = $RegistryEntries[$pc].Value[$app]
Would anyone be able to tell me why?
To sum up/TL;DR:
Why does my function when trying to add items to an array created inside the script prompt me for permission to do just this in the shell?
With the custom object I've described above holding the data I want to display in my HTML table, what am I doing wrong in trying to access it in the above code excerpt?
PS: The script works in the sense that if I sit throughout all the prompts I get in the shell, hitting A + Return all the time, I will get a HTML table of the kind that I want, but all the cells where an application name interstices a computername will say "Application N/A".
I guess you have your $DebugPreference and/or VerbosePreference set to Inquire which will prompt every time Write-Debug or Write-Verbose are called, respectively:
Confirm
Continue with this operation?
[Y] Yes [A] Yes to All [H] Halt Command [S] Suspend [?] Help (default is "Y"):
You probably want to set them to Continue instead. Another source might be the -Debug switch.
Regarding your second question, it's a little long to explain, but for arguments to commands you have to put such expressions in parentheses:
Write-Debug ($RegistryEntries[$pc].Value[$app])
$currentApp = $RegistryEntries[$pc].Value[$app]
I just have a question about writing a function that will search a directory for the most recent log in a directory. I currently came up with one, but I'm wondering if there is a better (perhaps more proper) way of doing this.
I'm currently using hdsentinel to create logs on computer and placing the log in a directory. The logs are saved like so:
/directory/hdsentinel-computername-date
ie. C:/hdsentinel-owner-2010-11-11.txt
So I wrote a quick script that loops through certain variables to check for the most recent (within the past week) but after looking at it, I'm question how efficient and proper it is to do things this way.
Here is the script:
String directoryPath = "D:"
def computerName = InetAddress.getLocalHost().hostName
def dateToday = new Date()
def dateToString = String.format('%tm-%<td-%<tY', dateToday)
def fileExtension = ".txt"
def theFile
for(int i = 0; i < 7; i++) {
dateToString = String.format('%tY-%<tm-%<td', dateToday.minus(i))
fileName = "$directoryPath\\hdsentinel-$computerName-$dateToString$fileExtension"
theFile = new File(fileName)
if(theFile.exists()) {
println fileName
break;
} else {
println "Couldn't find the file: " + fileName
}
}
theFile.eachLine { print it }
The script works fine, perhaps it has some flaws. I felt I should go ahead and ask what the typical route is for this type of thing before I continue with it.
All input is appreciated.
Though a bit messy, you could implement a multi-column sort via the 'groupBy' method (Expounding on Aaron's code)..
def today = new Date()
def recent = {file -> today - new Date(file.lastModified()) < 7}
new File('/yourDirectory/').listFiles().toList()
.findAll(recent)
.groupBy{it.name.split('-')[1]}
.collect{owner, logs -> logs.sort{a,b -> a.lastModified() <=> b.lastModified()} }
.flatten()
.each{ println "${new Date(it.lastModified())} ${it.name}" }
This finds all logs created within the last week, groups them by owner name, and then sorts according to date modified.
If you have files other than logs in the directory, you may first need to grep for files containing 'hdsentinel.'
I hope this helps.
EDIT:
From the example you provided, I cannot determine if the least significant digit in the format:
C:/hdsentinel-owner-2010-11-11.txt
represents the month or the day. If the latter, sorting by file name would automatically prioritize by owner, and then by date created (without all of the chicanery of the above code).
For Instance:
new File('/directory').listFiles().toList().findAll(recent).sort{it.name}
Hopefully this helps some..This sorts a given path by date modified in a groovier way. The lists them out.
you can limit the list, and add other conditions in the closure to get the desired results
new File('/').listFiles().sort() {
a,b -> a.lastModified().compareTo b.lastModified()
}.each {
println it.lastModified() + " " + it.name
}
As I was trying to solve a similar problem, learnt a much cleaner approach.
Define a closure for sorting
def fileSortCondition = { it.lastModified() }
And File.listFiles() has other variation which accepts FileFilter and FilenameFilter in Java, and these interfaces has a single method called accept, Implement the interface as a closure.
def fileNameFilter = { dir, filename ->
if(filename.matches(regrx))
return true
else
return false
} as FilenameFilter
And lastly
new File("C:\\Log_Dir").listFiles(fileNameFilter).sort(fileSortCondition).reverse()
Implement FileFilter interface if filtering is to be done by File attributes.
def fileFilter = { file ->
if(file.isDirectory())
return false
else
return true } as FileFilter
I am wondering is there an easy way to make a copy of a tree structure that consists of one model with a parent_id that actsAs a tree?
I was thinking it should be easy to recursively go through a given tree, remove all ids and lft, rght fields; however, as I add the new fields parent_id won't match up correctly. I suppose it should be easy enough to write my own function to handle this, but I just wanted to know if there was already something to handle this?
Thanks!!
First, I used Multi Tree Behaviour ( http://bakery.cakephp.org/articles/view/multitree-behavior ) as it allows several trees to be managed in one table.
My examples are perhaps a little complex and confused with application specific code, but I'm sure you can pick your way through it!
Pretty much anything you do with the tree is going to need a recursive 'tree-walker'. I wrote a task manager with sub-tasks etc. and this is an example of a method I used to walk the tree:
function _walkTasksTree($nodes, $model='Task')
{
foreach($nodes as $node)
{
$task = $node[$model];
$id = $task['id'];
$title = $task['name'];
$level = $task['level'];
$children = $this->_walkTasksTree($node['children'],$model);
if(empty($children))
{
$data[$id] = array('level'=>$level,'title'=>$title);
}
else
{
$data[$id] = array('level'=>$level,'title'=>$title,'children' => $children);
}
}
$data = (isset($data))?$data:array();
return $data;
}
My application has a 'repository' of common tasks which can be cloned into a project. The basic model is ProjectTask [1:1] ProjectTaskDescriptor - the descriptor holding the data, and the task holding the tree position. I use this method to traverse and clone trees and/or branches
function _saveTaskTree($subTasks,$parent_id,$root_id,$projId,$exclude=null)
{
foreach($subTasks as $node)
{
if(#$exclude!=$node['Task']['id'])
{
$node['Task']['id'] = null;
$node['Task']['root_id'] = $root_id;
$node['Task']['parent_id'] = $parent_id;
$node['Task']['project_id'] = $projId;
$this->ProjectTask->create();
$saved = $this->ProjectTask->save($node['Task']);
$this->ProjectTaskDescriptor->create();
$PTD = $node['TaskDescriptor'];
$PTD['project_task_id'] = $this->ProjectTask->id;
$this->ProjectTaskDescriptor->save($PTD);
}
else
{
$saved = true; //skip the first one - we've already done it.
}
if($saved)
{
if(#$node['children'])
$children = $this->_saveTaskTree($node['children'],$this->ProjectTask->id,$root_id,$projId);
}
}
}
It is a very hands on process and in terms of future understanding and maintenance of the code it is worthwhile fully understanding what is going on.