Kalina Posted June 10, 2014 Share Posted June 10, 2014 I want to create a plugin that allows me to import a camera path. Specifically, the format of my external file is: translationX_frame1, translationY_frame1, translationZ_frame1, rotationX_frame1, rotationY_frame1, rotationZ_frame1 translationX_frame2, translationY_frame2, translationZ_frame2, rotationX_frame2, rotationY_frame2, rotationZ_frame2 translationX_frame3, translationY_frame3, translationZ_frame3, rotationX_frame3, rotationY_frame3, rotationZ_frame3 ... I don't really know where to begin. It would make sense to me to be able to create a camera, just set the translation and rotation at each frame. Can I do this in the HDK? Do I want to write a GEO_IOTranslator for this? If so, would I have to create a camera path somehow, or could I just create a camera? Would that be an OBJ_Camera? I would really appreciate being pointed in the right direction, or some help to get a simple example working; e.g. creating a camera looking at (0,0,0) and moving it from (0,0,1) at frame 1 to (0,0,2) at frame 2. Quote Link to comment Share on other sites More sharing options...
Guest mantragora Posted June 10, 2014 Share Posted June 10, 2014 (edited) 0. It sound like you are totally new to Houdini, so why going stright into HDK? 1. I would do this in Python. 2. If you insist, then you can implement custom GEO_IO_Translator, use it to read data into CHOPs and then export it to camera. I think this is better and more universal than implementing your custom camera just to read data from you custom format. Edited June 10, 2014 by mantragora Quote Link to comment Share on other sites More sharing options...
loopyllama Posted June 10, 2014 Share Posted June 10, 2014 it sounds like a job for CHOPS. try loading the file in CHOPS, and exporting the data to the translation and rotation channels of an existing camera. try searching this forum for .chan files... Quote Link to comment Share on other sites More sharing options...
Stalkerx777 Posted June 11, 2014 Share Posted June 11, 2014 translationX_frame1, translationY_frame1, translationZ_frame1, rotationX_frame1, rotationY_frame1, rotationZ_frame1 translationX_frame2, translationY_frame2, translationZ_frame2, rotationX_frame2, rotationY_frame2, rotationZ_frame2 translationX_frame3, translationY_frame3, translationZ_frame3, rotationX_frame3, rotationY_frame3, rotationZ_frame3 I think it's classic chan file format. If it is, everything you need is FileCHOP + RenameCHOP + ReorderCHOP. Good luck. Quote Link to comment Share on other sites More sharing options...
Kalina Posted June 11, 2014 Author Share Posted June 11, 2014 (edited) It doesn't appear that I can use CHOPS. The file type is .wf, and trying to load it into a File CHOP in Houdini gives me "Unable to read file". http://www.sidefx.com/docs/houdini13.0/nodes/chop/file seems to confirm that this is not a valid file type. Also, this .wf file format that I described is the simpler of two camera path file formats that I will need to be able to import, so I thought I would start working on just that one... But the other file type is .vd, and I would like to be able to read in both in a somewhat similar manner if possible (e.g. programmatically, via a plugin). If you must know, the other format looks ilke this: fps 30.00000000 keys 3 0 : 1.02890467643737793 0.0280741788446903229 0.161896556615829468 -8.01320744 -3.913378 -78.6056137 0.00999999978 60 15 : 1.02306999999999992 0.0306226999999998917 0.264749000000000012 -8.99072453 -14.2586266 -69.5562738 0.01 60 32 : 1.01645994186401367 0.0335110984742641449 0.381316006183624268 -8.13035774 -26.0038414 -59.277462 0.00999999978 60 It's not frame-by-frame; here interpolation must be done between keys 0, 15, and 32. Edited June 11, 2014 by Kalina Quote Link to comment Share on other sites More sharing options...
edward Posted June 12, 2014 Share Posted June 12, 2014 It's probably easier to just write a python script that converts the data into an (ascii) .clip file which also looks similar (save out a test .clip file to see the format). Then you can just load it using a File CHOP and export it to whatever parameters you want. Or if you want it to be more integrated you can edit $HFS/houdini/CHOPio to use your python script. GEO_IOTranslator won't work because its for geometry and what you have is channel data. For channel data, the equivalent is to write a CL_ClipReader subclass and register it with CL_ClipIO. 1 Quote Link to comment Share on other sites More sharing options...
Kalina Posted June 12, 2014 Author Share Posted June 12, 2014 It's probably easier to just write a python script that converts the data into an (ascii) .clip file which also looks similar (save out a test .clip file to see the format). Then you can just load it using a File CHOP and export it to whatever parameters you want. Or if you want it to be more integrated you can edit $HFS/houdini/CHOPio to use your python script. GEO_IOTranslator won't work because its for geometry and what you have is channel data. For channel data, the equivalent is to write a CL_ClipReader subclass and register it with CL_ClipIO. Thank you thank you thank you THANK YOU! A CL_ClipReader is what I want in the end, but I couldn't find any examples or information about this, so this will be complicated for a beginner like myself (any advice?). For now, I wrote a simple python wf-to-clip converter script and edited CHOPio, and it works beautifully. 1 Quote Link to comment Share on other sites More sharing options...
edward Posted June 12, 2014 Share Posted June 12, 2014 It's probably not too complicated if you just look at the relevant header files. However, I would only try it if you're already experienced in C++ and running into performance issues. A simple python script like this is helluva easier to maintain. Quote Link to comment Share on other sites More sharing options...
Guest mantragora Posted June 13, 2014 Share Posted June 13, 2014 (edited) It's probably not too complicated if you just look at the relevant header files. However, I would only try it if you're already experienced in C++ and running into performance issues. A simple python script like this is helluva easier to maintain.That's a good occasion to prepare some template if someone would like to follow this road in the future. For GEO_IO I have such a template, so all I have to do is CTRL+C/CTRL+V template *.h/*.cpp files, give them new names and I'm ready to fill in fileRead/fileSave methods + set new extesnion. Don't have to look into example files to try figure out how I should start with it.I see that there are two virtual methods that we can override, but I can't figure out how to set custom extension and register it. There is some mention that they register themself by using registerClipReader()/registerClipWriter() but I still can't see how to set custom extension to test is it working. I will start: FileFormats_Common.h /* This is a place where you should specify common for all file formats include files, names that may be shared between more than one place or operator/selector. IMPORTANT! ------------------------------------------ ----------------------------------------------------- Author: Mantragora (2014) */ #pragma once /* ----------------------------------------------------------------- INCLUDES ----------------------------------------------------------------- */ #include <CL/CL_ClipIO.h> #include <ostream> #include <iostream.h> // -------------------------- using // using std::cout; using std::endl; /* ----------------------------------------------------------------- CL_Template ----------------------------------------------------------------- */ CL_Template.h /* Use this as a starting template for CL file format. IMPORTANT! ------------------------------------------ ----------------------------------------------------- Author: Mantragora (2014) */ #pragma once #include "../FileFormat_Common.h" namespace Mantragora { namespace FileFormat { class CL_Template : public CL_ClipIO { public: CL_Template() {} virtual ~CL_Template() {} virtual auto writeClip(const char* file_name, const CL_Clip& clip) -> bool; virtual auto readClip(const char* file_name, CL_Clip& clip) -> bool; }; } } CL_Template.cpp /* Use this as a starting template for CL file format. IMPORTANT! ------------------------------------------ ----------------------------------------------------- Author: Mantragora (2014) */ #include "CL_Template.h" using namespace Mantragora::FileFormat; auto CL_Template::readClip(const char* file_name, CL_Clip& clip) -> bool { return true; } auto CL_Template::writeClip(const char* file_name, const CL_Clip& clip) -> bool { return true; } Now what? Is there some registerNewClip() function where I should call registerClipReader()/registerClipWriter() and pass to each new extension? registerClipReader(const char* extension, CL_ClipReader& clip_reader) registerClipWriter(const char* extension, CL_ClipWriter& clip_writer) What should be passed as second argument to each of those methods? The same CL_Template class? Edited June 13, 2014 by mantragora Quote Link to comment Share on other sites More sharing options...
edward Posted June 13, 2014 Share Posted June 13, 2014 From CL_ClipIO.h: 133 // These functions are called from shared objects/dll's to register readers 134 // and writers. 135 extern "C" { 136 SYS_VISIBILITY_EXPORT extern void CLregisterClipReader(void *); 137 SYS_VISIBILITY_EXPORT extern void CLregisterClipWriter(void *); 138 } 139 So, putting this together from reading CL_ClipIO.h, you have something like (untested): void CLregisterClipReader(void *) { static CL_Template clip_reader; CL_ClipIO::inst().registerClipReader(".wf", clip_reader); } Quote Link to comment Share on other sites More sharing options...
Guest mantragora Posted June 13, 2014 Share Posted June 13, 2014 (edited) From CL_ClipIO.h: 133 // These functions are called from shared objects/dll's to register readers 134 // and writers. 135 extern "C" { 136 SYS_VISIBILITY_EXPORT extern void CLregisterClipReader(void *); 137 SYS_VISIBILITY_EXPORT extern void CLregisterClipWriter(void *); 138 } 139So, putting this together from reading CL_ClipIO.h, you have something like (untested): void CLregisterClipReader(void *) { static CL_Template clip_reader; CL_ClipIO::inst().registerClipReader(".wf", clip_reader); } Thanks! CL_ClipIO have private constructor, so we cannot inherit from it . So instead I inherit from CL_ClipReader/CL_ClipWriter. It seems to work. Here is modified code: FileFormat_Common.h /* This is a place where you should specify common for all file formats include files, names that may be shared between more than one place or operator/selector. IMPORTANT! ------------------------------------------ ----------------------------------------------------- Author: Mantragora (2014) */ #pragma once /* ----------------------------------------------------------------- INCLUDES ----------------------------------------------------------------- */ #include <CL/CL_ClipIO.h> #include <CL/CL_Clip.h> #include <CL/CL_ClipReader.h> #include <CL/CL_ClipWriter.h> #include <ostream> #include <iostream.h> // -------------------------- using // using std::cout; using std::endl; /* ----------------------------------------------------------------- CL_Template ----------------------------------------------------------------- */ #define CL_TEMPLATE_EXTENSION_NAME ".mantragoraclip" CL_Template.h /* Use this as a starting template for CL file format. IMPORTANT! ------------------------------------------ ----------------------------------------------------- Author: Mantragora (2014) */ #pragma once #include "../FileFormat_Common.h" namespace Mantragora { namespace FileFormat { class CL_Template : public CL_ClipReader, public CL_ClipWriter { public: CL_Template(); virtual ~CL_Template(); virtual auto writeClip(const char* file_name, const CL_Clip& clip) -> bool override; virtual auto readClip(const char* file_name, CL_Clip& clip) -> bool override; }; } } CL_Template.cpp /* Use this as a starting template for CL file format. IMPORTANT! ------------------------------------------ ----------------------------------------------------- Author: Mantragora (2014) */ #include "CL_Template.h" using namespace Mantragora::FileFormat; CL_Template::CL_Template() : CL_ClipReader(), CL_ClipWriter() { } CL_Template::~CL_Template() { } auto CL_Template::readClip(const char* file_name, CL_Clip& clip) -> bool { cout << file_name << endl; return true; } auto CL_Template::writeClip(const char* file_name, const CL_Clip& clip) -> bool { cout << file_name << endl; return true; } FileFormat_Registration.cpp /* This is a place where you should create and register all additional file formats. IMPORTANT! ------------------------------------------ ----------------------------------------------------- Author: Mantragora (2014) */ #define FINAL #include <UT/UT_DSOVersion.h> #include "CL/CL_Template.h" #ifdef FINAL #include "CL/CL_Template.cpp" #endif using namespace Mantragora::FileFormat; /* --------------------------------------------------------------------- CL REGISTRATION --------------------------------------------------------------------- */ // create namespace CL_Instances { static CL_Template clTemplate; } // register readers auto CLregisterClipReader(void*) -> void { CL_ClipIO::inst().registerClipReader(CL_TEMPLATE_EXTENSION_NAME, (CL_ClipReader&)CL_Instances::clTemplate); } // register writers auto CLregisterClipWriter(void*) -> void { CL_ClipIO::inst().registerClipWriter(CL_TEMPLATE_EXTENSION_NAME, (CL_ClipWriter&)CL_Instances::clTemplate); } Edited June 13, 2014 by mantragora Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.