A proper way to make animation of AIS_Shape on scene

Hello. What is the best way to use animation of objects on scene (preferably, AIS_Shape entries)?

I have looked at the mfc-related example, but it was not clear for me. Now I'd like to start from simpler example - move a cyllinder with certain speed to a point and the stop. There are two ways:

1. Use AIS_Animation class ( https://www.opencascade.com/doc/occt-7.3.0/refman/html/class_a_i_s___ani... ). It is unclear how to use it anyway, there are no examples how to use it!

2. Simple use transformation within the thread, like it is described here: https://www.opencascade.com/content/rotating-and-translating-cylinder-3d...

Kirill Gavrilov's picture

AIS_Animation is a centralized tool for handling simple and complex (nested) animations in a reliable way,
introducing concepts like presentation timestamp, high-resolution timer, animation speed, interpolation routines, etc.
In case of local transformation applied to object, AIS_AnimationObject would do internally the same things as in referred links in your post.
MFC animation sample just have not been updated for using AIS_Animation.

AIS_Animation wouldn't do everything for you "automatically" - it should be properly initialized (defining animation sequence(s) - key frames) and used (to redraw viewer at proper intervals) at application level.
See also tests\v3d\anim\ Draw Harness tests demonstrating usage of vanimation command.

Ivan P's picture

Thanks for extended answer. I have started the draw.bat (a Draw Harness), issued File > Load Script, opened tests\v3d\anim\objects and got the following message in console:

Viewer animation - animate object moving
bgerror failed to handle background error.
    Original error: can't read "imagedir": no such variable
    Error in bgerror:

Objects loaded, but animation did not start.

Kirill Gavrilov's picture

Tests in OCCT are executed using test and testgrid commands, e.g.:

> test v3d anim propeller 1
> vanimation anim -play
Ivan P's picture

Dear Admin! Please, make a C++ example of animation.

Ivan P's picture

I have defined the following fragment for animation :

 std::vector<Handle(AIS_InteractiveObject)> privateSimpleRig; // I fill it while populating scene . I push_back here AIS_Shape handles, it is OK

gp_Trsf firstTransformation;
gp_Trsf secondTransformation; 
cyllindricalAnimation = new AIS_AnimationObject( TCollection_AsciiString(22), privateAISContext, privateSimpleRig[2], firstTransformation, secondTransformation);

But animation does not work. Am I missing something? an item stands in place without moving.

Kirill Gavrilov's picture

> AIS_Animation wouldn't do everything for you "automatically" - it should be properly initialized (defining animation sequence(s) - key frames)
> and used (to redraw viewer at proper intervals) at application level.

AIS_Animation::StartTimer() starts its internal timer returning elapsed time, the actual update of current frame is done by AIS_Animation::UpdateTimer(), which should be called before redrawing new frame in 3D Viewer.
Redrawing the viewer should be done by application itself, and will depend on used GUI framework and application design.

Ivan P's picture

That's clarifies something. Should I further subclass AIS_AnimationObject, (re)implement AIS_Animation::UpdateTimer() and call this routine on screen update?

Kirill Gavrilov's picture

You don't need re-implementing AIS_Animation::UpdateTimer(), standard implementation should be enough in most cases.
General idea is:
- Define single AIS_Animation instance at application level as a container for active animation(s) and main playback controller.
- Define animation atoms like AIS_AnimationObject/AIS_AnimationCamera and insert them into AIS_Animation container (AIS_Animation::Add()). Each item should define its own duration (should not be 0) and start presentation timestamp (PTS, 0 by default), so that AIS_Animation container will automatically calculate the complete animation duration as summary of its children. Nested AIS_Animation containers are also possible.
- Start AIS_Animation playback AIS_Animation::StartTimer(), and call AIS_Animation::UpdateTimer() within each Viewer redraw (for example, on multimedia timer triggering update at desired time intervals, as provided by GUI framework) until animation is not finished (AIS_Animation::IsStopped()). AIS_Animation controller will automatically execute (update) children, so that only one root AIS_Animation instance (controller) should be managed with StartTimer()/UpdateTimer()/IsStopped() calls.
- Custom animation items (similar to AIS_AnimationObject/AIS_AnimationCamera) should inherit AIS_Animation and override AIS_Animation::update() method. Existing implementation can be used as a reference. The main input for ::update() is a current presentation timestamp (PTS) and normalized (0..1) progress inside this specific item (based on own duration), which should be used for updating scene (for instance, by applying linear interpolation between two key frames), see also AIS_AnimationProgress definition.

2271801720_140466's picture

I make an example below, like a main function in c.

TopoDS_Shape obj1 = BRepPrimAPI_MakeBox(100, 500, 20);
Handle(AIS_Shape) ais_obj1 = new AIS_Shape(obj1);
g_pDoc->myAISContext->Display(ais_obj1, true);

gp_Trsf start_pnt, end_pnt;
start_pnt.SetValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0);
end_pnt.SetValues(1, 0, 0, 100, 0, 1, 0, 100, 0, 0, 1, 100);
Handle(AIS_Animation) ais_animation = new AIS_Animation("obj1");
Handle(AIS_AnimationObject) ais_ao = new AIS_AnimationObject("obj1", g_pDoc->myAISContext, ais_obj1, start_pnt, end_pnt);

double duration = ais_animation->Duration();

ais_animation->StartTimer(0, 1.0, true);

while (!ais_animation->IsStopped())
kangzixiang6_144903's picture

Thanks for your contribution

m.nserat_157086's picture

thanks very much for your code.
I don't know if I should ask here, 
this code worked correctly 
but I tried to write this code within another "thread"  to get other functionalities in my app, like rotation,
so when I tried that  I had some problems:

1- the Viewer did not update, and I could not see it moving.

2- if I made another process in the main thread, I will get an exception in function "UpdateCurrentViewer"

can you give me some help, please?

TIAN DAJIANG's picture

Hi,Have you resolved this problem? I have same problem!