Node added signal

pcicconepciccone Posts: 661
edited December 1969 in Daz SDK Developer Discussion

Hi.

I'm looking for information about the chain of events triggered in Studio when a node is added.
There is a nodeAdded() signal in DzScene but that signal is emitted at the beginning of the procedure. In the case of a figure, the signal is emitted and then Studio starts adding nodes to it. This makes it hard to use for running tasks that depend on the figure being ready and complete.

In addition, when using the Auto-fit plugin it seems that the scene hierarchy is transformed substantially. First the clothing is added as a figure and then it's converted and the series of objects connected to it changes. This is at least how I figured it out.

Is there a way of receiving signals when a node is completely added to the scene? In other words, when the operation of adding it is completed?

Thanks in advance.

Comments

  • rbtwhizrbtwhiz Posts: 2,250
    edited December 1969

    Pret-A-3D said:
    I'm looking for information about the chain of events triggered in Studio when a node is added.
    There is a nodeAdded() signal in DzScene but that signal is emitted at the beginning of the procedure. In the case of a figure, the signal is emitted and then Studio starts adding nodes to it. This makes it hard to use for running tasks that depend on the figure being ready and complete.

    In addition, when using the Auto-fit plugin it seems that the scene hierarchy is transformed substantially. First the clothing is added as a figure and then it's converted and the series of objects connected to it changes. This is at least how I figured it out.

    Is there a way of receiving signals when a node is completely added to the scene? In other words, when the operation of adding it is completed?

    You'll want to connect to DzScene::sceneLoadStarting() and use it to increment an int member, to keep count of how many loads are in progress. You'll also want to connect to DzScene::sceneLoaded() and use it to decrement the int member, to keep count of how many loads need to finish... blocking against the posting of a custom event until the count reaches 0 (more on that in a moment), and against more than one event in the stack at a time. You'll also want to connect to DzScene::nodeAdded() and DzScene::aboutToRemoveNode() so that you can capture/maintain a DzNodeList while the scene is busy loading. Once the loading is finished (i.e. the int member reaches 0), post a custom event - to allow any remaining events before it to be processed. Then, in your event handler, process the list of DzNode you've collected.

    
    /**
    **/
    class MyEvent: public QEvent
    {
    public:
        MyEvent() : QEvent( QEvent::Type( s_type ) ) {}
    
        static int s_type;
    };
    
    int MyEvent::s_type = QEvent::registerEventType();
    
    /**
    **/
    struct MyClass::Data
    {
        Data() :
            m_sceneCount( 0 ), m_eventPosted( false )
        { }
    
        DzNodeList    m_addedNodes;
        int        m_sceneCount;
        bool        m_eventPosted;
    };
    
    /**
    **/
    MyClass::MyClass() : m_data( new Data )
    {
        DzConnect( dzScene, SIGNAL(sceneLoadStarting()), this, SLOT(sceneLoadStarting()) );
        DzConnect( dzScene, SIGNAL(nodeAdded(DzNode*)), this, SLOT(addNode(DzNode*)) );
        DzConnect( dzScene, SIGNAL(aboutToRemoveNode(DzNode*)), this, SLOT(removeNode(DzNode*)) );
        DzConnect( dzScene, SIGNAL(sceneLoaded()), this, SLOT(sceneLoaded()) );
    }
    
    MyClass::~MyClass()
    {
        delete m_data;
    }
    
    void MyClass::sceneLoadStarting()
    {
        m_data->m_sceneCount++;
    }
    
    void MyClass::sceneLoaded()
    {
        m_data->m_sceneCount--;
        
        postMyEvent();
    }
    
    void MyClass::addNode( DzNode *node )
    {
        m_data->m_addedNodes.append( node );
    
        postMyEvent();
    }
    
    void MyClass::removeNode( DzNode *node )
    {
        m_data->m_addedNodes.removeAll( node );
    
       // Depending on what you are doing... may need to more here
    }
    
    void MyClass::postMyEvent()
    {
        if( m_data->m_eventPosted || m_data->m_sceneCount > 0 )
            return;
    
        if( !dzApp || dzApp->isClosing() )
            return;
    
        m_data->m_eventPosted = true;
        dzApp->postEvent( this, new MyEvent() );
    }
    
    bool MyClass::event( QEvent *e )
    {
        if( e->type() == MyEvent::s_type )
        {
            processAddedNodes();
    
            m_data->m_eventPosted = false;
            return true;
        }
    
        //return MySuperClass::event( e );
        return false;
    }
    
    void MyClass::processAddedNodes()
    {
        DzNodeListIterator nodeIt( m_data->m_addedNodes );
        while( nodeIt.hasNext() ){
            doSomething( nodeIt.next() );
        }
    }

    -Rob

  • pcicconepciccone Posts: 661
    edited December 1969

    Hi Rob.
    Thank you very much for the detailed explanation and code mock-up, it's very much appreciated.
    This is an interesting logic. I have already connections to the sceneLoadStarting() and other signals to handle the merging of scenes. This is an interesting "wrinkle" to explore.
    Does this system work also for .CR2 and for things like the Studio primitives (Cube, Torus etc.)?

    Thanks again.

  • pcicconepciccone Posts: 661
    edited December 1969

    One more question.
    Your suggestion to use a counter implies that there loads can be nested. Can you provide an example of when that happens?

    Also, I tested the method with CR2s (V4) and it works but it doe not work with the primitives.

    Cheers.

  • pcicconepciccone Posts: 661
    edited December 1969

    Hi Rob.

    Just wanted to let you know that your suggestion worked perfectly. The primitives will have to be handled via the nodeAdded() signal but that is not an issue.
    Thanks again.

Sign In or Register to comment.