OCC AIS Viewer

ilpup

CAD practitioner
I was trying the AIS example class on gitlab lesson14.
I noticed that StartMessageLoop() must be always called at the end:

C++:
Viewer vout(0, 50, 500, 500);
// add geometry to viewer
vout.StartMessageLoop();

However I think it would have been better to have something like

C++:
Viewer vout(0, 50, 500, 500);
vout.StartMessageLoop();

// add geometry to viewer
// add geometry to viewer
// ...

vout.Refresh();

Eventually what has to be modified ?

Thanks
 

JSlyadne

Administrator
Staff member
Hey ilpup! It's a design intent of our lessons to keep the StartMessageLoop() as a final step of the workflow. Feel free to adapt this approach on your own way in the applications where you reuse the lesson's code. I don't know the reasons of moving StartMessageLoop() as you showed but keep in mind that the code below will never executed until you destroy the host window. Likely, you need to think more about architecture of your application.
 

ilpup

CAD practitioner
knowing very little on win32 API I not sure it make sense something like the following (tested, it works)

C++:
    void Viewer::AddShape(const TopoDS_Shape& shape)
    {
        m_shapes.push_back(shape);
        CreateAISShape(shape);
    }

    void Viewer::CreateAISShape(const TopoDS_Shape& sh)
    {   
            Handle(AIS_Shape) shape = new AIS_Shape(sh);
            m_context->Display(shape, Standard_False);
            m_context->UpdateCurrentViewer();

             // Adjust selection style.
            ::AdjustSelectionStyle(m_context);

            // Activate selection modes.
            m_context->Activate(4, true); // faces
            m_context->Activate(3, true); // wires


            if(::MsgWaitForMultipleObjectsEx(0, NULL, 12, QS_ALLINPUT, 0) == WAIT_OBJECT_0)
            {
                MSG Msg;
                ::PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE);

                    ::TranslateMessage(&Msg);
                    ::DispatchMessage(&Msg);             
            }

    }

//the loop moved to constructor's class

 MSG Msg;
        while (!m_bQuit)
        {
            switch (::MsgWaitForMultipleObjectsEx(0, NULL, 12, QS_ALLINPUT, 0))
            {
            case WAIT_OBJECT_0:
            {
                while (::PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
                {
                    if (Msg.message == WM_QUIT)
                        m_bQuit = true;// return;

                    ::TranslateMessage(&Msg);
                    ::DispatchMessage(&Msg);
                }
            }
            }
        }
 

JSlyadne

Administrator
Staff member
I still cannot understand what is your goal, sorry. The event loop stays endless until m_bQuit is true. So, if you moved it to the constructor of Viewer class and the code below is still workable, I would suppose m_bQuit is true by default, i.e. the event loop doesn't actually work and doesn't do its job. Did you check whether mouse interactions properly work with your modifications?
 
Last edited:

ilpup

CAD practitioner
never mind, you were right, nothing change.
The problem was because I didn't invalidate the view before redrawing (for an animation).

In fact the lesson's codes are a big help, so a big thank you!
 
Top