Print current frame during command line render? - terminal

Is there a way to basically print my own output during a command line render?
Let's say I don't need/want all the other output that maya spits out by default, I know you can change the verbosity level, but there's very specific things I'd like to output but I can't figure it out. I currently render out the verbosity output to file, so I wanted to print in the terminal (I'm using MAC) the frame that the render is currently up to.
This may just be simple minded, but here's what I tried:
Render -preFrame "print `currentTime -q`;" -s 1 -e 20 -rd /render/directory/ maya_file.mb
Obviously, -preFrame expects a string, according to the docs this can take mel commands, but obviously this is limited to certain commands, I'm assuming the currentTime command is pulling the information from the timeline in maya, not queering it from the Renderer it self... When I run the above command, straight away, it spits out this: -bash: currentTime: command not found and soon after the render fails/doesn't start.
Idealy, I'd like to print the following as it starts each frame:
"Started rendering frame XXXX at TIME GOES HERE", that way, I can quickly look at the terminal, and see if the renderer has failed, stuck or where it's up to and when it started it.
So my question is, seeing is currentTime is a mel command used from within Maya, is there another way I could print this information?
Cheers,
Shannon

After many hours of searching for this answer, I ended up finding out that you can start maya as an interactive shell. By doing this, I was able to source a script as I opened it, and run whatever I want into memory as If I had Maya open at the time.
/Applications/Autodesk/maya2014/Maya.app/Contents/MacOS/maya -prompt -script "/Volumes/raid/farm_script/setupRender.mel"
In the setupRender.mel file, I was able to assign variables, containing options for renders etc, in doing this, I was also able to create a global variable for the frame number, and increment it during the preFrame callback, like so:
int $startFrame = 100;
int $endFrame = 1110;
global int $frameCount = 0;
string $preRenderStatistics = "'global int $frameCount; $frameCount = " + $startFrame + ";'";
string $preFrameStatistics = "'print(\"Rendering frame: \" + $frameCount++)'";
string $additionalFlags = "";
string $sceneFilePath = "'/Volumes/path/to/file/intro_video_001.mb'";
system("Render -preRender " + $preRenderStatistics + " -preFrame " + $preFrameStatistics + " -s " + $startFrame + " -e " + $endFrame + " -x " + $additionalFlags + " " + $sceneFilePath);
This is a very simplified version of what I currently have, but hopefully this will help others if they stumble across it.

Take a look at the pre render layer MEL and/or pre render frame MEL section of the Render Settings.
It expects MEL, so you'll either need to write it in MEL or wrap your python in MEL. For such a simple use, I'd say just write it in MEL:
print `currentTime -q`

Related

ZPL command length limit?

I am generating ZPL command string and the printer (ZT410) does not print all the labels sent. I simply loop through the following code and send the string to the printer (via the IP address on port 9100). Each loop contains a unique set of data where row['item_desc'],row['our_part_number'], and part number change each iteration (so I am not just trying to print 522 identical labels).
command += '^XA';
command += '^LT23';
command += '^FO125,30';
command += '^A0N,85,50';
command += '^FB950,1,,C'
command += '^FD'+row['item_desc']+'^FS';
command += '^FO20,260';
command += '^A0N,50,50';
command += '^FD'+part_number+'^FS';
command += '^FO122,260';
command += '^A0N,50,50';
command += '^FB950,1,,C'
command += '^FD'+row['our_part_number']+'^FS';
command += '^FO935,255';
command += '^A0N,25,25';
command += '^FB200,2,,R'
command += '^FDMy Company Name Phone_Number ^FS';
command += '^FO'+margin+',105';
command += '^BY3';
command += '^B3N,N,144,N,N';
command += '^FD'+row['our_part_number']+'^FS';
command += '^XZ';
My test lot is 522 labels. Before adding the company info and barcode, the printer printed all 522 labels, but with the code above, it only prints 485 labels.
Where is the limit? Is there a limit on the string length that can be sent to the port? Should I add a carriage return and line feed after each label (so the printer knows where to break the string)? Or is there a IP:port timeout?
The printer prints the labels, but doesn't respond in any way to the port that sent the command. If I break the labels into individual command strings and send them sequentially without pause, the printer didn't print ANY labels. Is it possible to query the printer to know when to send the next command string?
Normally, I would just experiment with trial and error, but in this case that method is expensive and wasteful...
Try
^PQ522
as a command before the ^XZ.
I'd suggest you only send it once though. Sending it 522 times (or even 485 times) might just be a tad wasteful.
Use FN fields and save the label locally on the printer(using ^DF), then just call the label and populate the dynamic data in the FN fields

Parse log File and store value in object in Ruby

I have a log file which generates following data:
2015-07-06 11:07:24 +0522 [ERROR]
2015-07-06 11:07:29 +0522 [ERROR] index=healthe-int-legacy host=kdatamap.abc.com com.rp.keplar.collector.CollectorException: Could not process additional data, connection lost to data collector service
I want to store data in different section like date, time, index value and error related information like 'Could not process additional data, connection lost to data collector service' into database. How to parse so that I can easily store in DB? Please guide me.
You want to read up the manual on the really powerful File and String classes.
Consider this rather quick hack:
aFile = File.new("/your/file.dat")
aFile.each_line { |line|
arr = line.split
print "date = " + arr[0] + "\n"
print "time = " + arr[1] + "\n"
print "index = " + arr[4].split('=')[1]
}
It does not take into accout that the file might not exist or that the lines might be aligned differently. Have a look at '''regular''' expressions for implementation of a more robust (but unfortunately more difficult to read) matching algorighm.
Basic I/O is described at http://ruby-doc.com/docs/ProgrammingRuby/html/tut_io.html.

Texture Packer Command line multiple images

I’m using TexturePacker from the command line and am unable to get it to pack multiple sprites into 1 sheet. It allows me to do 1 sprite so the command is fine.
This is the command I am using.
"TexturePacker --format sparrow --texture-format atf --opt DXT5
--max-width 2048 --max-height 2048 --size-constraints POT --pack-mode Best --enable-rotation --trim-mode Trim --algorithm MaxRects
--multipack --border-padding 5 --shape-padding 5 --reduce-border-artifacts --scale " + sheetInfo.scale + " --data " + imageOutputDirectory + "\" + lanfPrefix + "\" + sheetInfo.name +
".xml " + "--sheet " + imageOutputDirectory + "\" + lanfPrefix + "\"
+ sheetInfo.name + ".atf image1.png image2.png";
Any ideas why this isn't working? According to the documentation, it should work.
I was unable to find any real way to fix this even contacted the developer of texture packer but got no response. Instead I was able to accomplish the desired outcome by copying all needed files to a temp directory and then add the directory to the end of the texturepacker call instead of individual images.
Due to the poor TexturePacker documentation, it took me much trial and error to figure this out!
To add multiple images to a single sprite sheet, here is a sample command that will create an atlas called out.png (the default) containing images img_1 to img_4...
TexturePacker --format unity-texture2d img_1.png img_2.png img_3.png img_4.png
The key is the list of image filenames separated only by spaces. I am working from Python, so here is the script I use to create the same atlas that the sample line above will give you. Using glob with wildcards allows me to select images from a folder containing many images and eliminates the need to isolate the files I want into a folder just for TexturePacker's sake.
import subprocess, glob
TP = r"C:\Program Files\CodeAndWeb\TexturePacker\bin\TexturePacker.exe"
baseFrame = "img"
def FillAtlas(baseFrame):
globString = baseFrame + "_*.png"
frameList = glob.glob(globString)
imgList = []
for frame in frameList:
imgList.append(frame)
TPargs = [TP, "--format", "unity-texture2d"] + imgList
subprocess.call(TPargs)
FillAtlas(baseFrame)

How to send control C node.js and child_processes

Hello I want to send to the child_process, for example, ping 8.8.8.8-t, that is, an infinite number of ping. And some of the iterations I want to stop this command and execute a new, but in this case I do not want to kill a child process.
Example:
var spawn = require('child_process').spawn('cmd'),
iconv = require('iconv-lite');
spawn.stdout.on('data', function (data) {
console.log('Stdout: ', iconv.decode(data, 'cp866'));
});
spawn.stderr.on('data', function (data) {
console.log('Stderr: ', iconv.decode(data, 'cp866'));
});
spawn.stdin.write('ping 8.8.8.8 -t'+ '\r\n');
spawn.stdin.write(here control-c...); // WRONG
spawn.stdin.write('dir' + '\r\n');
I found your previous question. Looks like you are trying to create/emulate a terminal from within node.js. You can use readline for reading and writing from a terminal.
To write control character, you can see the example from its docs :
rl.write('Delete me!');
// Simulate ctrl+u to delete the line written previously
rl.write(null, {ctrl: true, name: 'u'});
To directly answer the question, to pass special characters you will need to pass their ASCII values. Ctrl + C becomes ASCII character 0x03. Value taken from here.
spawn.stdin.write("\x03");

Saving Tab names and ConqueShells along with Vim sessions

Is there any way to get vim to save the tab names (assigned via the Tab Name script) and/or a terminal emulator (set up via the Conque Shell script) upon issuing the :mksession [fileName] command?
Observe below (zoom in), I have a working session on the left, and the same session loaded via the vim -S fileName command, on the right. The assigned tab labels revert to absolute paths, ConqueShell terminal is interpreted as a file.
After learning some basic VimScript I just gave up and used Python instead (to cite one example, you can't save global information to a session if it is a list). Here is a solution I found for saving tab names (will post a solution for ConqueShell if I find one)
Put the following in your .vimrc file and use whatever mapping you want to quickly save and load your sessions
"Tokenize it so it has the following form (without spaces)
"Label1 JJ Label2 JJ Label3 JJ Label4
"Or if you prefer use something other than 'JJ' but DO NOT
"use symbols as they could interfere with the shell command
"line
function RecordTabNames()
"Start at the first tab with no tab names assigned
let g:TabNames = ''
tabfirst
"Iterate over all the tabs and determine whether g:TabNames
"needs to be updated
for i in range(1, tabpagenr('$'))
"If tabnames.vim created the variable 't:tab_name', append it
"to g:TabNames, otherwise, append nothing, but the delimiter
if exists('t:tab_name')
let g:TabNames = g:TabNames . t:tab_name . 'JJ'
else
let g:TabNames = g:TabNames . 'JJ'
endif
"iterate to next tab
tabnext
endfor
endfunction
func! MakeFullSession()
call RecordTabNames()
mksession! ~/.vim/sessions/Session.vim
"Call the Pythin script, passing to it as an argument, all the
"tab names. Make sure to put g:TabNames in double quotes, o.w.
"a tab label with spaces will be passed as two separate arguments
execute "!mksession.py '" . g:TabNames . "'"
endfunc
func! LoadFullSession()
source ~/.vim/sessions/Session.vim
endfunc
nnoremap <leader>mks :call MakeFullSession()<CR>
nnoremap <leader>lks :call LoadFullSession()<CR>
Now create the following text file and put it somewhere in your PATH variable (echo $PATH to get it, mine is at /home/user/bin/mksession.py) and make sure to make it executable (chmod 0700 /home/user/bin/mksession.py)
#!/usr/bin/env python
"""This script attempts to fix the Session.vim file by saving the
tab names. The tab names must be passed at the command line,
delimitted by a unique string (in this case 'JJ'). Also, although
spaces are handled, symbols such as '!' can lead to problems.
Steer clear of symbols and file names with 'JJ' in them (Sorry JJ
Abrams, that's what you get for making the worst TV show in history,
you jerk)
"""
import sys
import copy
if __name__ == "__main__":
labels = sys.argv[1].split('JJ')
labels = labels[:len(labels)-1]
"""read the session file to add commands after tabedit
" "(replace 'USER' with your username)
"
f = open('/home/USER/.vim/sessions/Session.vim', 'r')
text = f.read()
f.close()
"""If the text file does not contain the word "tabedit" that means there
" "are no tabs. Therefore, do not continue
"""
if text.find('tabedit') >=0:
text = text.split('\n')
"""Must start at index 1 as the first "tab" is technically not a tab
" "until the second tab is added
"""
labelIndex = 1
newText = ''
for i, line in enumerate(text):
newText +=line + '\n'
"""Remember that vim is not very smart with tabs. It does not understand
" "the concept of a single tab. Therefore, the first "tab" is opened
" "as a buffer. In other words, first look for the keyword 'edit', then
" "subsequently look for 'tabedit'. However, when being sourced, the
" "first tab opened is still a buffer, therefore, at the end we will
" "have to return and take care of the first "tab"
"""
if line.startswith('tabedit'):
"""If the labelIndex is empty that means it was never set,
" "therefore, do nothing
"""
if labels[labelIndex] != '':
newText += 'TName "%s"\n'%(labels[labelIndex])
labelIndex += 1
"""Now that the tabbed windowing environment has been established,
" "we can return to the first "tab" and set its name. This serves
" "the double purpose of selecting the first tab (if it has not
" "already been selected)
"""
newText += "tabfirst\n"
newText += 'TName "%s"\n'%(labels[0])
#(replace 'USER' with your username)
f = open('/home/USER/.vim/sessions/Session.vim', 'w')
f.write(newText)
f.close()

Resources