Skip to main content
Participant
August 29, 2024
Question

How to correctly use AEGP_SetCameraFilmSize?

  • August 29, 2024
  • 1 reply
  • 241 views

Hello,

 

I'm not sure if it's a bug, or if I'm just missing something.

 

We have an internal representation of camera data inside our plug-in and we need to exchange it with After Effects. We used to only read the camera data for rendering, but now we'd like to write back modified data as well. However, AEGP_SetCameraFilmSize is causing us some trouble.

 

We have a button and we handle the click on a PF_Cmd_EVENT. Here's a very trimmed down function that gets called when the appropriate button is clicked. It only tries to write the film size.

void AePluginConnection::BakeCamera(AeData *aeData, AeParams& params, const bool singleFrame)
{
	AEGP_SuiteHandler suites(aeData->inData->pica_basicP);

	constexpr auto checkErr = [](A_Err e) { assert(e == PF_Err_NONE); };

	AEGP_LayerH curLayer;
	checkErr(suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(aeData->inData->effect_ref, &curLayer));

	AEGP_CompH curComp;
	checkErr(suites.LayerSuite5()->AEGP_GetLayerParentComp(curLayer, &curComp));

	std::u16string layerName = u"NAME";

	A_FloatPoint centerPoint;
	centerPoint.x = 0;
	centerPoint.y = 0;

	AEGP_LayerH cameraLayer;
	checkErr(suites.CompSuite7()->AEGP_CreateCameraInComp(reinterpret_cast<const A_UTF16Char*>(layerName.c_str()), centerPoint, curComp, &cameraLayer));
	checkErr(suites.LayerSuite5()->AEGP_SetLayerFlag(cameraLayer, AEGP_LayerFlag_LOOK_AT_POI, FALSE));
	checkErr(suites.LayerSuite5()->AEGP_SetLayerFlag(cameraLayer, AEGP_LayerFlag_AUTO_ORIENT_ROTATION, FALSE));

	AEGP_ObjectType objectType;
	checkErr(suites.LayerSuite5()->AEGP_GetLayerObjectType(cameraLayer, &objectType));
	if (objectType != AEGP_ObjectType_CAMERA) { assert(false); }

	const float pixelsToCm = params.ReadFloat(ParamRenderUnitsScale);

	double filmSize = 25.0f * pixelsToCm * 0.1f;
	checkErr(suites.CameraSuite2()->AEGP_SetCameraFilmSize(cameraLayer, AEGP_FilmSizeUnits_HORIZONTAL, &filmSize));
}

This creates a new enabled camera layer with default values and a zero transform. If I try to call AEGP_GetCameraFilmSize immediately, I get back the correct values I've just set. Since the camera is on top of the layer list, it becomes the active one. Also, if I open the Camera Settings dialog, I see that the Film Size is set correctly (e.g., in the code snippet above, this would be the hard-coded 25.0f, but any number works).

 

However, in PF_Cmd_SMART_RENDER, when I try to read back the value of the film size by using this simplified snippet below, AEGP_GetCameraFilmSize returns AEGP_FilmSizeUnits_NONE and a film size of 0.

constexpr auto checkErr = [](A_Err e) { assert(e == PF_Err_NONE); };

AEGP_LayerH curLayer, cameraLayer;
A_Time currentTime;
AEGP_CompH currentComp;

AEGP_SuiteHandler suites(aeData->inData->pica_basicP);
checkErr(suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(aeData->inData->effect_ref, &curLayer));
checkErr(suites.LayerSuite5()->AEGP_GetLayerParentComp(curLayer, &currentComp));
checkErr(suites.PFInterfaceSuite1()->AEGP_ConvertEffectToCompTime(aeData->inData->effect_ref, std::max((A_long)0, aeData->inData->current_time), aeData->inData->time_scale, &currentTime));
checkErr(suites.PFInterfaceSuite1()->AEGP_GetEffectCamera(aeData->inData->effect_ref, &currentTime, &cameraLayer));

double filmSize = 102.0472;
AEGP_FilmSizeUnits filmUnits = AEGP_FilmSizeUnits_HORIZONTAL;
checkErr(suites.CameraSuite2()->AEGP_GetCameraFilmSize(cameraLayer, &filmUnits, &filmSize));

In contrast, if I make a new camera by using the UI, or edit the film size manually, the  AEGP_GetCameraFilmSize in PF_Cmd_SMART_RENDER picks up the new value immediately.

 

Surprisingly, restarting AE or re-opening the project seem to fix the value returned by AEGP_GetCameraFilmSize even if the value is being pulled from a layer that was created using the BakeCamera code.

 

I have noticed in the docs that the CameraSuite is described next to various Artisan suites. Our plug-in is not an Artisan. Does that mean we cannot use this suite to read and write the camera data? We are actually using the film size in our own rendering code, so, now I'm worried about calling AEGP_GetCameraFilmSize as well.

 

Any help would be highly appreciated. Thanks!

This topic has been closed for replies.

1 reply

Community Expert
September 11, 2024

that is indeed very strange. what happens if instead of re-opening the project you purge the ram cache? does the error correct then?

Participant
September 30, 2024

Sorry about the late reply! I had other issues to look into. Purging the cache did not help. AEGP_GetCameraFilmSize still returns AEGP_FilmSizeUnits_NONE and a film size of 0.

 

Also, I was looking into a different internal bug report, which turned out to be related to this. Specifically, even if a camera is created by an external plug-in (e.g., the 3D Camera Tracker), the AEGP_GetCameraFilmSize call in our plug-in will still return the wrong values for the new camera until I reload the project.

 

I've also tried using a script to create a camera:

app.project.item(1).layers.addCamera("CAMERA", [0, 0]);

 

Trying to make sure that the issue is not in our plug-in, I even added the following snippet to the Render function of the SmartyPants example project and built it:

const auto checkErr = [](A_Err e) { assert(e == PF_Err_NONE); };

AEGP_SuiteHandler suites(in_data->pica_basicP);

AEGP_LayerH curLayer, cameraLayer;
A_Time currentTime;
AEGP_CompH currentComp;

checkErr(suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(in_data->effect_ref, &curLayer));
checkErr(suites.LayerSuite5()->AEGP_GetLayerParentComp(curLayer, &currentComp));
checkErr(suites.PFInterfaceSuite1()->AEGP_ConvertEffectToCompTime(in_data->effect_ref, max((A_long)0, in_data->current_time), in_data->time_scale, &currentTime));
checkErr(suites.PFInterfaceSuite1()->AEGP_GetEffectCamera(in_data->effect_ref, &currentTime, &cameraLayer));

if (cameraLayer)
{
	double filmSize = 102.0472;
	AEGP_FilmSizeUnits filmUnits = AEGP_FilmSizeUnits_HORIZONTAL;
	checkErr(suites.CameraSuite2()->AEGP_GetCameraFilmSize(cameraLayer, &filmUnits, &filmSize));

	char buffer[512];
	snprintf(buffer, 512, "CAMERA: %d %f\n", filmUnits, filmSize);

	OutputDebugStringA(buffer);
}

 
It behaved in the exact same way - the cameras created by the camera tracker or the script were returning AEGP_FilmSizeUnits_NONE and a film size of 0 until I saved and reloaded the project.

So, either there's something I'm missing that's needed to check-out or reload the AEGP_GetCameraFilmSize value, or I've found a bug.

 

Please tell me if there's anything else I should try. Thank you!