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

    Scene Overlay

    SDK Help
    0
    11
    900
    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 30/04/2013 at 07:38, xxxxxxxx wrote:

      Hi Markus,

      you could use BaseDraw.DrawTexture() to place a Bitmap with an alpha channel in a 
      BaseDraw. Or you use simply an ObjectData plugin and return a  textured plane with 
      a DisplayTag attached to it, to ensure it is displayed shaded.

      I think i am misunderstanding your problem or what you are after.

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

        On 01/05/2013 at 01:33, xxxxxxxx wrote:

        If you want to display an overlayed image in the viewport without having a corresponding object or tag in the document hierarchy, a SceneHook is in deed the right choice.

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

          On 01/05/2013 at 03:38, xxxxxxxx wrote:

          As c4dJack says. 🙂

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

            On 01/05/2013 at 07:50, xxxxxxxx wrote:

            He asked for an example. And there is one that's been floating around the forum:
            https://developers.maxon.net/forum/topic/6062/6237_scenehook-plugin-problem&KW=SceneHook&PID=26152#26152

            But I have two questions about that:

            1- In the Message() code where it listens if a new document is opened. If I add some task there. For example create a polygon. It works fine if C4D is already open.
            But this causes C4D to crash when it launches.
            How do we use MSG_DOCUMENTINFO_TYPE_LOAD in a SH to execute something when a new document is opened. But not execute when C4D is launching for the first time?

            *Edit:
            I guess I should also say that to even be able to test and play around with the SH code and not have it crash on start up. This is the hack I'm using in the main.cpp file.
            But this is obviously wrong:

            Bool PluginMessage(LONG id, void *data)  
            {  
              //use the following lines to set a plugin priority  
              switch (id)  
              {  
                  case C4DPL_INIT_SYS:  
                  if (!resource.Init()) return FALSE; // don't start plugin without resource  
              
              return TRUE;  
              
                  case C4DPL_PROGRAM_STARTED:  
                      if (!RegisterMyNode()) return FALSE;          <------ My hack to prevent C4D from crashing!!!  
                      if (!RegisterMySceneHook()) return FALSE;  
              
                  etc....
            

            2- In the SH example provided by Matthias.
            If I add an Init() to the Node class. And do something like for example create a sphere. It does work.
            But when I open a document. The SH creates a whole new (second) document and puts the sphere in there. And that's not good.
            How would I make the SH put the sphere into the document I'm opening instead?

            -ScottA

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

              On 01/05/2013 at 09:24, xxxxxxxx wrote:

              1. No hacks are necessary. A SceneHook does not crash if written right.
              2. What does RegisterMyNode() even do, anyway?
              3. Since a SceneHook is part of the document itself, I don't think it would create an additional document. You are doing something wrong there.
              4. To answer your original question: ScenHooks provide an execution hook inside your document. It does not make any sence to have them execute or not execute based on if Cinema has just started or not.

              You might have to rethink your approach.

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

                On 01/05/2013 at 11:41, xxxxxxxx wrote:

                I know I'm not doing it right.
                The example from Matthias is a nice starting point. But it leaves me with too many unanswered questions on how to use it.
                The guy is looking for an example. And so am I.

                -ScottA

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

                  On 01/05/2013 at 14:08, xxxxxxxx wrote:

                  Oh Duh. 😊
                  I just realized that you posted an example of this on your blog Frank.
                  http://c4dprogramming.wordpress.com/2012/11/15/2d-drawing-using-a-scenehook/

                  I'm so used to using my own special drawing trick to draw things. That I forgot all about it.
                  The example Matthias posted is for combining a NodeData plugin with a SceneHook. And that approach is different than just drawing things on the screen.

                  -ScottA

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

                    On 01/05/2013 at 14:11, xxxxxxxx wrote:

                    Hi,

                    here's a quick example of drawing an image over the editor window:

                    /**
                     * Copyright (C) 2013, Niklas Rosenstein
                     * All rights reserved.
                     *
                     * This program is free software: you can redistribute it and/or modify
                     * it under the terms of the GNU Lesser General Public License as published
                     * by the Free Software Foundation, either version 3 of the License, or
                     * (at your option) any later version.
                     * 
                     * This program is distributed in the hope that it will be useful,
                     * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
                     * GNU Lesser General Public License for more details.
                     * 
                     * You should have received a copy of the Lesser GNU General Public License
                     * along with this program. If not, see <http://www.gnu.org/licenses/>.
                     */
                      
                    #include <c4d.h>
                    #include <lib_clipmap.h>
                      
                    typedef struct Rect {
                        LONG x1, y1, x2, y2;
                    } Rect_t;
                      
                    class OverlayHook : public SceneHookData {
                      
                        AutoAlloc<GeClipMap> image;
                        BaseTime last_time;
                        Bool drawn;
                      
                    public:
                      
                        static NodeData* Alloc() { return gNew OverlayHook; }
                      
                        OverlayHook();
                      
                        void FillOverlay(const Rect_t& rect, LONG frame, Bool update_fill);
                      
                        //////// SceneHookData Overrides
                      
                        Bool Draw(BaseSceneHook* host, BaseDocument* doc, BaseDraw* bd, BaseDrawHelp* bh,
                                  BaseThread* bt, SCENEHOOKDRAW flags);
                      
                    };
                      
                      
                    OverlayHook::OverlayHook() : drawn(FALSE) {
                    }
                      
                    void OverlayHook::FillOverlay(const Rect_t& rect, LONG frame, Bool update_fill) {
                        LONG width = rect.x2 - rect.x1;
                        LONG height = rect.y2 - rect.y1;
                      
                        // Ensure that the image is large enough, reallocate if
                        // necessary!
                        if (image->GetBw() < width || image->GetBh() < height) {
                            GeDebugOut("  Reallocating image...");
                            image->Destroy();
                            if (image->Init(width, height, 32) != IMAGERESULT_OK) {
                                return;
                            }
                            update_fill = TRUE;
                        }
                      
                        if (!update_fill) return;
                      
                        GeDebugOut("  Updating fill..");
                      
                        image->BeginDraw();
                        for (LONG x=0; x < width; x++) {
                            for (LONG y=0; y < height; y++) {
                                Real v = (SNoise(Vector(x / 50.0, y / 50.0, frame)) + 1) / 2;
                                v *= (Real) x / width;
                                LONG g = (LONG) (v * 255);
                      
                                image->SetPixelRGBA(x, y, 255, 255, 255, g);
                            }
                        }
                        image->EndDraw();
                      
                        drawn = TRUE;
                    }
                      
                    Bool OverlayHook::Draw(BaseSceneHook* host, BaseDocument* doc, BaseDraw* bd, BaseDrawHelp* bh,
                                           BaseThread* bt, SCENEHOOKDRAW flags) {
                        if (!host || !doc || !bd || !bh || !bt) return FALSE;
                        if (flags != SCENEHOOKDRAW_DRAW_PASS) return TRUE;
                      
                        Rect_t rect;
                        bd->GetSafeFrame(&rect.x1, &rect.y1, &rect.x2, &rect.y2);
                      
                        // Draw something on the overlay image.
                        BaseTime time = doc->GetTime();
                        Bool update_fill = time != last_time || !drawn;
                      
                        last_time = time;
                        FillOverlay(rect, time.GetFrame(doc->GetFps()), update_fill);
                      
                        // Draw the overlay image on the screen.
                        BaseBitmap* bmp = image->GetBitmap();
                        if (!bmp) return TRUE;
                      
                        bd->SetMatrix_Screen();
                      
                        Vector padr4[4];
                        padr4[0] = Vector(rect.x1, rect.y1, 0);
                        padr4[1] = Vector(rect.x2, rect.y1, 0);
                        padr4[2] = Vector(rect.x2, rect.y2, 0);
                        padr4[3] = Vector(rect.x1, rect.y2, 0);
                      
                        Vector uvadr[4];
                        uvadr[0] = Vector(0, 0, 0);
                        uvadr[1] = Vector(1, 0, 0);
                        uvadr[2] = Vector(1, 1, 0);
                        uvadr[3] = Vector(0, 1, 0);
                      
                        bd->DrawTexture(bmp, padr4, NULL, NULL, uvadr, 4,
                                        DRAW_ALPHA_FROM_IMAGE, DRAW_TEXTUREFLAGS_0);
                      
                        return TRUE;
                    }
                      
                      
                    Bool RegisterOverlayHook() {
                        LONG flags = PLUGINFLAG_SCENEHOOK_NOTDRAGGABLE;
                        DataAllocator* alloc = OverlayHook::Alloc;
                        return RegisterSceneHookPlugin(1000001, "Overlay Hook", flags, alloc, 0, 0);
                    }
                      
                    Bool PluginStart() {
                        return RegisterOverlayHook();
                    }
                      
                    Bool PluginMessage(LONG type, void* pData) {
                        return TRUE;
                    }
                      
                    void PluginEnd() {
                    }
                    

                    I had immense problems figuring out how to actually apply the DrawTexture() method, so that
                    took most of the time, the rest was really easy. It's not working 100% satisfieng (see this thread)
                    but actually does it's job.

                    What also still needs to be added, is that the pixels are actually drawn 1 by 1 on the screen. Atm,
                    the whole bitmap is drawn into the editor window. The bitmap might actually exceed the window
                    resolution because I reallocate it when it was to small to fit in it, but do not reallocate it when it
                    would exceed (which would eat lots of power).

                    Best,
                    -Niklas

                    EDIT: Added missing line (orange).

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

                      On 01/05/2013 at 14:24, xxxxxxxx wrote:

                      Thanks Nik,

                      I got it all figured out from the code on that blog.
                      But your is helpful too.

                      -ScottA

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

                        On 06/05/2013 at 03:38, xxxxxxxx wrote:

                        Hi All,

                        Sorry I couldn't respond earlier. Thank you all for the wealth of information. I haven't managed to digest it all, yet, though.

                        Markus

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