Jump to content

Camera IO Translator


Recommended Posts

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.

 

Link to comment
Share on other sites

Guest mantragora

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 by mantragora
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by Kalina
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Guest mantragora

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? :D

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 by mantragora
Link to comment
Share on other sites

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);
}
Link to comment
Share on other sites

Guest mantragora

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);
}

Thanks!

CL_ClipIO have private constructor, so we cannot inherit from it :D. 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 by mantragora
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...