Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    no join() in C4DThread? [SOLVED]

    SDK Help
    0
    13
    923
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      On 25/07/2015 at 23:26, xxxxxxxx wrote:

      after some testing, it is not consistent using C4DThread, images sometimes appear black, makes it unusable "as it sometimes generates correct images, sometimes generates some images and others are black, undefined behavior"

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 27/07/2015 at 08:27, xxxxxxxx wrote:

        Hi Mohamed,

        I think, the strange behavior of your threads will be difficult to diagnose without code.
        Also I don't understand, why you don't want to use MPThreadPool. I think, speed-wise it may improve over firing a thread for every image as soon as it is done. But of course that's your decision.

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 27/07/2015 at 10:50, xxxxxxxx wrote:

          Hi Andreas,

          here is the thread function:

            
          void SevenPhotonsImageThread::Main(void)
          {
          	AutoAlloc<BaseBitmap> bitmap;
          	bitmap->Init(w,h, 32);
            
          	BaseShader* clone = (BaseShader* )shader->GetClone(COPYFLAGS_0,nullptr);
          	RenderShaderPreview(mat->GetDocument()->GetDocumentPath(),clone,shader,this->Get(),bitmap,nullptr,0,RENDER_PREVIEW_USE_BMP_SIZE);//same behavior if I use nullptr in thread argument.
          	
          	for(Int32 line = 0; line < h; ++line)
          		bitmap->GetPixelCnt(0, line, w, &imageData->data[w * line * COLORBYTES_RGB], COLORBYTES_RGB, COLORMODE_RGB, PIXELCNT_0);
          	imageData->is_float = false;//because we use uchars, if we use floats then this is true, may be dynamic later
          	imageData->width = w;
          	imageData->height = h;
          	imageData->depth = 1;
          	imageData->channels = COLORBYTES_RGB;
            
          	BaseShader::Free(clone);
          }
          

          sometimes it works, sometimes it gives black images.
          the same code in std::thread works without any flaws.

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 28/07/2015 at 07:51, xxxxxxxx wrote:

            Hi Mohamed,

            still, hard to tell. At a first glance your code looks ok.
            I have set up a simple command plugin. On a button press, it creates a BaseArray of C4DThreads (storing active material and its first shader in member variables of the thread), starts all threads and then waits for them to finish. Afterwards it uses ShowBitmap() to display the results, before deleting the thread instances.
            The threads do basically the same as yours (without setting all the member variables).
            This works just fine here and I did not use any std library functionality.

            Can you perhaps try to narrow it down on your side?
            Did you check the result of RenderShaderPreview()? Do all threads get correctly started? And did you make sure, your cleanup doesn't kill threads, before they have finished? Assuming imageData is a member of your thread class, does this data get consumed before you destroy the thread instances?

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 28/07/2015 at 09:24, xxxxxxxx wrote:

              Hi Andreas,

              this is how the imageData is created

                
                                                                      images.push_back(SevenPhotonsImageData());  
              							SevenPhotonsImageData *imageData = &(images.back());
              							Int32 w = kndData->nodes[n].getInternalData(input + 1).GetInt32();
              							Int32 h = kndData->nodes[n].getInternalData(input + 2).GetInt32();
              							imageData->data.resize(w * h * COLORBYTES_RGB);
                
              							const void * address = static_cast<const void*>(imageData);//used inside the renderer later with a function callback to get the image  
              

              images is a std::list<>, it is a member of the VideoPost plugin class.
              so what I do is:
              allocate memory for imageData inside main thread, take its pointer to my renderer
              then fill this memory inside a thread, imageData member variable is just a pointer.
              my second reply got some code about how the thread data is filled.

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 28/07/2015 at 09:25, xxxxxxxx wrote:

                I didn't check the result of RenderShaderPreview(), will check soon.

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 28/07/2015 at 09:39, xxxxxxxx wrote:

                  after some testing, threads Start() correctly, RenderShaderPreview() returns RENDERRESULT_OK.
                  in my test scene, I have 30 textures, checking images with ShowBitmap(bitmap),
                  last x images (x is any number, 5, 20, 15, ..) got filled randomly "for example 20% scanline fill, 60%, ...".

                  tested the same code again with std::thread, no errors, all images fills correctly.

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    On 28/07/2015 at 09:49, xxxxxxxx wrote:

                    last test was weird to identify the problem:
                    RenderShaderPreview(mat->GetDocument()->GetDocumentPath(),clone,shader,this->Get(),bitmap,nullptr,0,RENDER_PREVIEW_USE_BMP_SIZE) //undefined behavior, random fill.

                    RenderShaderPreview(mat->GetDocument()->GetDocumentPath(),clone,shader,nullptr,bitmap,nullptr,0,RENDER_PREVIEW_USE_BMP_SIZE) //works fine

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 28/07/2015 at 10:01, xxxxxxxx wrote:

                      Internally the thread pointer is used to interrupt/break the thread.
                      I think, this is might be a hint, that your threads get aborted too early for some reason.

                      One more thing, you might already know: ShowBitmap() needs to called from the main thread.

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 28/07/2015 at 10:41, xxxxxxxx wrote:

                        aha, I see now the problem!!
                        when I have too many images, each thread got queue of tasks "function calls" , which are executed in a loop.
                        when I call (*threadIterator)->End(), it exits without finishing the current function, I see that happens from the pointer as you mentioned, via signal of thread break.

                        I changed (*threadIterator)->End() to (*threadIterator)->Wait() and it works fine now
                        thanks Andreas for the help , you can consider this solved.

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post