I am using Processing IDE to generate hundred short video clips for a computer vision project. Right now, I am using Python to create a .pde file and run it. This looks roughly like:
PATH = "/my/local/director/"
list_of_variables = [1, 2, etc.]
for i in list_of_variables:
naming = "p5_{:02d}_myfile".format(i)
os.mkdir(PATH + naming)
with open(PATH + naming + "/" + naming + ".pde", 'w') as pdefile:
pdefile.write("contents of file go here " + i ";\n")
pdefile.write("saveFrame(\"frames/######.tif\");\n")
subprocess.Popen(["processing-ide", "--sketch=" + PATH + naming, "--run"], stdout=subprocess.DEVNULL)
subprocess.call(["ffmpeg", "-i", PATH + naming + "/frames/%06d.tif", PATH + naming + "out.mp4"], stdout=subprocess.DEVNULL)
shutil.rmtree(PATH + naming + "/frames/")
Every time code is executed, Processing IDE opens a preview window to show what is happening. Is there an option I can pass in the execution step or in the .pde file creation that will prevent the preview window from showing. This is taking a long time, and I'm hoping this would speed things up.
Note: Yes, I have considered that there are better options for generating these videos. In retrospect, I should have used OpenCV in Python to speed things up, but that isn't the thrust of this question.
#KevinWorkman's advice is great! If you really really really need to do this with Processing and headless, that's the way forward.
What would the code look like for a sketch ?
If it's simple drawing instructions you could rewrite it in multiple ways.
One option would be simply use an offscreen PGraphics buffer, without the whole PApplet part.
Here's a basic example:
import processing.core.PGraphicsJava2D;
public class PGraphicsBufferTest {
public static void main(String[] args) {
PGraphicsJava2D pg = new PGraphicsJava2D();
// set dimensions
pg.setSize(300, 300);
// set as offline (shouldn't expect a PApplet parent)
pg.setPrimary(false);
// draw
pg.beginDraw();
pg.background(0);
pg.ellipse(150, 150, 250, 250);
pg.endDraw();
// save to disk: in absence of parent PApplet, must use absolute path
pg.save("/path/to/dataset/sequence/frame.png");
}
}
If you save this as PGraphicsBufferTest.java (and have Processing's core.jar in the same folder), as an example you could:
compile: javac -cp core.jar PGraphicsBufferTest.java
run: java -cp .:core.jar PGraphicsBufferTest
This may still briefly generate a window, but hopefully will be a simpler/faster setup.
(I deliberately chose Java2D because it's already part of core.jar. You can use PGraphics2D of course, just remember to also add the OpenGL dependencies (gluegen-rt, jogl), and set the classpath (-cp), but also the native path (-Djava.library.path) arguments)
For example, there's an older pyprocessing pip package which uses Pyglet (OpenGL wrapper).
Because Pyglet can run headless, hopefully, so would pyprocessing.
I haven't tested this myself, however if it does work, you can keep a very similar syntax.
If it's simple 2D drawing instruction and this if for a computer vision project, by all means, OpenCV's drawing functions should suffice.
There are other Python packages that offer 2D drawing features with headless configurations (Pillow's ImageDraw module comes to mind).
Another option I can think that is just as, if not even more so overcomplicated than what you're already doing, is to use openFrameworks. It's C++, but inspired by Processing therefore very similar (e.g. setup() = setup(), draw() = update() + draw(), line(x1,y1,x2,y2) = ofDrawLine(x1,y1,x2,y2), etc.) and can run headless.
Related
Scilab can really be automated.
For instance you can use make to automatically start Scilab that will generate plots and save them to SVG with xs2svg, then start Inkscape to integrate it into a Latex document (with Latex code in legends!).
When using make it is convenient to run Scilab without the main interface by calling it with -nw. If you do not need graphics it can even run without java if called with -nogui.
It would be nice to be able to write scripts that can be either run by a user or by make. With that you could prevent code duplication while allowing easy debugging and report writing.
But that means:
closing the script when it's done
being able to skip some plots that should not be saved
etc
So how to detect options -nw or -nogui from within the script?
Using getargs
function y = nowindows()
y = (getenv("SCILAB_NW","undefined") ~= "undefined")
endfunction
then you can use this function:
if nowindows() then
mprintf("Running without a window.\n")
exit()
end
And if you set the environnement variable SCILAB_NW, nowindows() will return true.
SCILAB_NW="true" scilab -nw -f yourscript.sce
This solution adds redundancy to the command used to run Scilab but I found no other way. I also tried to use the sciargs function but I found it less convenient.
I need to get the list of co-ordinates for my box2d world- I'm trying to get a wrap around effect so that particles that go off the side of the screen appear on the opposite side. box2d is not well documented for Processing and the only example I could find was in java (I know its the parent language but it needs translating). This is here.
I think the action is here:
private function updateWorld(e:Event):void {
world.Step(1/30,10,10);
world.ClearForces();
for (var b:b2Body=world.GetBodyList(); b; b=b.GetNext()) {
if (b.GetType()==b2Body.b2_dynamicBody) {
if (b.GetJointList()==null) {
if (b.GetPosition().x*worldScale>640) {
b.SetPosition(new b2Vec2(0,b.GetPosition().y));
}
if (b.GetPosition().x*worldScale<0) {
b.SetPosition(new b2Vec2(640/worldScale,b.GetPosition().y));
}
}
}
}
world.DrawDebugData();
}
So I have tried translating this although I get stuck at the point of world.GetBodyList
I assume world is the instantiated box2d world I have created. I that is so, Processing doesn't seem to recognise this. Basically how to I just get an array of all the particle co-ordinates. Should be easier....
Anything you can do in Java, you can do in Processing. But the code you posted is not Java. It's C++. (Edit: George pointed out that it looks like ActionScript. Either way, it's not Java!)
Box2D is the original library, written in C++. Your code is an example of using that library.
JBox2D is a Java wrapper of the C++ library, so you can write Java code that interacts with the C++ library.
Processing is written in Java, so you can use JBox2D in Processing.
Processing also has a few libraries that simplify JBox2D, like Daniel Shiffman's Box2D for Processing or BoxWrap2d.
You don't need to use these libraries in order to use JBox2D from Processing.
You can find the documentation for JBox2D here.
To answer your question, yes, the world variable would be the instance of World you created when you set up your physics environment.
If you're using one of the Processing libraries, the creation of the World instance might be hidden from you. You might have to use JBox2D directly yourself.
I'd like to know what works in Processing 3 but doesn't work or isn't supported (yet) in Processing.js? Seems like many of the new examples in Processing 3's GUI don't work once converted to js.
I'm using this tool to convert: http://processingjs.org/tools/processing-helper.html
You're going to have a hard time tracking down everything that breaks between Processing 3 and Processing.js. They are two separate projects maintained by two separate groups of people.
The best thing you can do is try something, see specifically what breaks, and then try to find a workaround. Take each example one at a time, try to get it working, and post a question here if you get stuck on something specific.
That being said, one place to start looking for things that might not work is the Changes in 3.0 page on Processing's GitHub.
Specifically, anything involving the new surface variable is not going to work in Processing.js. Similarly, the new settings() function won't work either. Some additional functions in PVector also won't work.
Here is a link for a beta JavaScript mode for Processing 3, but you might be better off just waiting for Processing.js to catch up with Processing 3. In the meantime, take the examples one at a time, the workarounds shouldn't be too complicated to figure out.
Processing 3 (P3) is a java library, while processing.js (PJS) is a JS library, so each library will use their respective language's methods. As a basic example, a function in PJS will be declared like function myFunction () {} or in some cases var myFunction = function () {}; while P3 would look like void myFunction () {}. Another difference is strong type, in JS you can simply declare any type of variable with var myVariable = 0; but in java and therefore P3, you need to use int myVariable = 0; or boolean myBoolean = false;. Of course these aren't the only differences, but I hope they give you an idea of the differences in porting something from PJS to P3; while the library is very similar in both languages and can do many of the same things, it is mostly a difference between languages not libraries.
I need a way to intercept the code before it goes into the compiler, change it, AND have it remain the same in the file / in Xcode afterwards.
I thought build scripts were a sort of stream interception but that doesn't seem to be the case. Another method might be to run a script both before and after build. Are there any implications with this I should be aware of?
----- EDIT -----
Why? I have an idea for an auto-logging system based on a certain comment syntax. I want to be able, on build, to parse a certain string and replace it with a logging function but have the code remain unchanged. Is it possible?
----- UPDATE -----
It seems a custom compiler might be the way forward, or at least a plugin that wraps current LLVM clang. I've been investigating this. Here's a related question for those interested: Xcode custom compiler which wraps and does a passthru to clang
If by "on build" you mean before actually compiling the code, that means you need to open Xcode every time you want to run your script. I don't believe there is a way to do this. However, you CAN use Automator to receive a string before running the code, but you would need to use Automator to build the app, which is limiting. Another method would be to make 2 classes in your app: a pre-run class and a main class. The pre-run class will prompt the user or read a file (or something like that) to get the string, and run the main class in a special way depending on the string.
Edit: response to comment
I don't know how to do this in Objective-C, but you can always rename your main file to main.mm (.mm files contain both C++ and Objective-C code) and add C++ code to it. However, this is using the Console:
using namespace std // all (this line is optional)
string s = ""; // this
cin >> s; // is C++ (if you omitted the optional line above, the correct code is std::cin >> s;
MainClass mc = //constructor for your "main class" here in Objective-C
if(s == someCertainString){ //hypothetical string and C++ condition checking for a C++ string
[mc doThisACertainWay:];
}else if(s == someOtherString){ // again, hypothetical string that you need to declare
[mc doThisADifferentWay];
}
I'm not on a PC now so I can't check code, but you can search for how to read and write to files in C++ and Obj-C. The only hint I can give right now is that you need #include <iostream> at the beginning if you use C++ to read/write the file.
If you don't want to use the console (which is normal if you wan to publish this) you can also make a dialog. In this example, you don't need C++ so you don't rename the main file. Make a new window (referred to as theDialog from now on) that is visible at start and make sure that your main graphical interface does NOT show up startup. Add a text field to theDialog and give it a name (in this example, tf). Add a label to tell the user what to put in the text field. Add a button and link it to an action. In this action, put the following code:
MainClass mc = // constructor here
NSString *str = [self.tf stringValue];
if([str equalsString:someString]){ // hypothetical string and possible error in the condition checking, I'm new to Obj-C
[mc doThisInACertainWay];
} else {
[mc doThisInADifferentWay];
}
Does anyone know what parameters to pass to dwmapi.dll ordinal #113? (Windows 7)
I'm trying to incorporate this method into an application that I'm writing. From what I can tell, this method is responsible for doing the Aero peek thing for windows. If I pass no params to the method it will show the desktop and outlines of all open, non-maximized windows. Nothing happens when I try passing parameters - which I've done using trial and error.. mostly error.
Any help would be greatly appreciated.
Don't do it. It's undocumented for a reason and is subject to change and/or removal at any time. Given that Windows 7 hasn't been release yet you won't even be able to guarantee that it'll be there in the final version.
Your tags are inconsistent. An API is an application programming interface. Ordinal #113 is undocumented because it's not part of the interfaces for applications. It is likely present because the OS needs it itself, or because the current RC hasn't finished removing it, etc.
Well, I've used to mimic Alt-Tab with AeroPeek feature.
using System.Runtime.InteropServices;
...
[DllImport("dwmapi.dll", EntryPoint = "#113", SetLastError = true)]
internal static extern uint DwmpActivateLivePreview(uint a, IntPtr b, uint c, uint d);
...
//To call it
IntPtr peekHwnd = //<-- here goes the application Handle to aeropeek
//to enable
DwmpActivateLivePreview(1, peekHwnd, 0, 1);
...
//to disable
DwmpActivateLivePreview(0, peekHwnd, 0, 1);
Use it carefully, since many comments tell you that it is undocumented for some reason.
I think is because aeropeek is not supported by all windows editions, home basic is not supported, maybe you can implement your own window peek or at least fake it using alpha transparency (while drawing some border) and querying for underlying windows using the window rectangle coordinates like the rectangle collision detection algorithm.
Please go read Raymond Chen's blog until you realize this is a really, really, really bad idea!
There's a reason that apps can't activate Aero Peek - the user gets to choose when that happens, not you.