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

    Noise() function is very slowwwww

    SDK Help
    0
    18
    1.2k
    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 17/05/2013 at 08:14, xxxxxxxx wrote:

      Call Cinema 4D from the command-line just like you would call any other program from the command-line.

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

        On 17/05/2013 at 08:35, xxxxxxxx wrote:

        Ah. Ok.
        I was confusing "command args" with "command line". !LOL[URL-REMOVED]

        Thanks,
        -ScottA


        [URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.

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

          On 17/05/2013 at 09:49, xxxxxxxx wrote:

          Since there are no examples in the SDK for how to use the Noise() function.
          I'm posting a simple example. Just in case anyone needs it:

            
          //This is an example of using the Noise() function in a shader plugin  
            
          #include "c4d.h"  
          #include "c4d_symbols.h"  
          #include "myshader.h"  
          #include "lib_noise.h"  
            
          #define PLUGIN_ID 1000000  //temp ID only!!!  
            
            
          class MyShader : public ShaderData  
          {  
            private:   
            C4DNoise *mynoise;  
            
            public:  
                virtual Bool               Init(GeListNode *node);  
                virtual    Vector             Output(BaseShader *chn, ChannelData *cd);  
                virtual    INITRENDERRESULT   InitRender(BaseShader *sh, const InitRenderStruct &irs);  
                virtual    void               FreeRender(BaseShader *sh);  
            
                static NodeData *Alloc(void) { return gNew MyShader; }  
          };  
            
          Bool MyShader::Init(GeListNode *node)  
          {  
            BaseContainer *data = ((BaseShader* )node)->GetDataInstance();  
            
            mynoise = NULL;  
            
            return TRUE;  
          }  
            
          INITRENDERRESULT MyShader::InitRender(BaseShader *sh, const InitRenderStruct &irs)  
          {  
            BaseContainer *data = sh->GetDataInstance();  
            
            LONG seed = 555;  
            mynoise = C4DNoise::Alloc(seed);  
              
            return INITRENDERRESULT_OK;  
          }  
            
          Vector MyShader::Output(BaseShader *chn, ChannelData *cd)  
          {      
            Vector p = cd->p;  
            p *= 10;            //The number of repeats  
            
            Real n = mynoise->Noise(NOISE_CRANAL, FALSE, p, 0.0, 1.0, FALSE, 0.25, 0.25, 0);  
            
            return Vector(n);  
          }  
            
          void MyShader::FreeRender(BaseShader *sh)  
          {  
            mynoise->Free(mynoise);  
          }  
            
          Bool RegisterShaderPlugin(void)  
          {  
            return RegisterShaderPlugin(PLUGIN_ID,GeLoadString(IDS_MY_SHADER),0, MyShader::Alloc,"myshader",0);  
          }
          

          -ScottA

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

            On 17/05/2013 at 10:07, xxxxxxxx wrote:

            Scott, I'm so confused when you say "function" everytime, because this word relates to a global
            function in the usual terms. The Noise() "function" is a method in this case, a method of the
            C4DThread class. 🙂

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

              On 17/05/2013 at 10:16, xxxxxxxx wrote:

              Dangerous, Scott 🙂

              You should definitely check 'mynoise' for NULL after allocating it in InitRender(), and then return INITRENDERRESULT_OUTOFMEMORY if it's NULL. If I think about it, you should always check all pointers for NULL:

                
              INITRENDERRESULT MyShader::InitRender(BaseShader *sh, const InitRenderStruct &irs;)   
              {   
                  if (!sh)   
                      return INITRENDERRESULT_OUTOFMEMORY;   
                  BaseContainer *data = sh->GetDataInstance();   
                
                  LONG seed = 555;   
                  mynoise = C4DNoise::Alloc(seed);   
                  if (!mynoise)   
                      return INITRENDERRESULT_OUTOFMEMORY;   
                     
                  return INITRENDERRESULT_OK;   
              }   
              

              The line in FreeRender() will probably not work. Since Free() is a static function of the BaseShader class, it has to be as follows (also add a NULL check here, just in case).

              void MyShader::FreeRender(BaseShader *sh)   
              {   
                  if (mynoise) BaseShader::Free(mynoise);   
              }
              

              And as a last tip: I would not set the mynoise pointer to NULL in the Init() function. To have a defined state of the MyShader class after allocation, you must initialize all members in the class constructor. Also use the INSTANCEOF() macro to indicate that your shader class is an instance of BaseShader. That enables you to use SUPER to call the parent class' functions (shown further down in Init()).

                
              class MyShader : public ShaderData   
              {   
                  INSTANCEOF(MyShader, BaseShader)   
                
                  private:   
                  C4DNoise *mynoise;   
                
                  public:   
                      virtual Bool               Init(GeListNode *node);   
                      virtual    Vector             Output(BaseShader *chn, ChannelData *cd);   
                      virtual    INITRENDERRESULT   InitRender(BaseShader *sh, const InitRenderStruct &irs;);   
                      virtual    void               FreeRender(BaseShader *sh);   
                
                      static NodeData *Alloc(void) { return gNew MyShader; }   
                
                      MyShader() : mynoise(NULL)   
                      { }   
              };   
              

              Use Init() only to initialize (= set default values for) the parameters in your shader's BaseContainer. And again, an additional NULL pointer check for 'data'.

                
              Bool MyShader::Init(GeListNode *node)   
              {   
                  BaseContainer *data = ((BaseShader* )node)->GetDataInstance();   
                  if (!   
                
                  // Set default parameters in 'data' here   
                  data->SetReal(MYSHADER_PARAMETER_BLAH, 1.0);   
                  data->SetLong(MYSHADER_PARAMETER_FOOBAR, 123);   
                
                  return SUPER::Init(node);   
              }   
              
              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 17/05/2013 at 10:30, xxxxxxxx wrote:

                I'm just curious: Why does the C4D API use the INSTANCEOF() macro? In my humble opinion, it
                is doing some "hidden magic" (which is what macros always do) and this one is making even darker
                magic. From the name itself it is almost not possible to conclude it typedefs the parent class as
                SUPER.

                > typedef ShaderData SUPER;

                So clear, and even a bit shorter. 🙂

                -Nik

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

                  On 17/05/2013 at 10:49, xxxxxxxx wrote:

                  Thanks Frank.
                  The code I posted works works fine for me with no memory leaks. But I do admit that it's very lean, and not using of defensive code.

                  I didn't now that about the INSTANCEOF() macro.
                  That code has always been a bit of a mystery to me about what it's really used for.

                  I do usually use the style:  type::Free(instance) to free allocated memory.
                  And I only do it that way because that's how other people use it. Not knowing why I'm using it that way. Rather than using the style: mynoise- >Free(mynoise);
                  Most of the time I can't use the style: mynoise->Free(mynoise); because it doesn't free the memory.
                  But in this case it worked. So that's what I used.
                  But I really don't have a good grasp of why one style works. And one style doesn't.
                  I'm self taught. And C++ memory management is something I've never really understood properly.

                  -ScottA

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

                    On 17/05/2013 at 10:58, xxxxxxxx wrote:

                    Originally posted by xxxxxxxx

                    I didn't now that about the INSTANCEOF() macro.
                    That code has always been a bit of a mystery to me about what it's really used for.

                    And here's my proof, thanks Scott. 😉 The INSTANCEOF() macro is one of the most confusing things
                    I have seen in the C4D API. 😄

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

                      On 17/05/2013 at 12:42, xxxxxxxx wrote:

                      Nah, it's not confusing. It just enables you to use SUPER::blah() instead of ShaderData::Blah(). You don't have to use it, but it saves you some typing work, especially if you override more functions than just one. No voodoo going on here.

                      If you ever wonder what stuff does, just look up how it's defined.

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

                        On 17/05/2013 at 12:48, xxxxxxxx wrote:

                        class MyShader : public ShaderData {
                          
                            typedef ShaderData SUPER;
                            INSTANCEOF(MyShader, ShaderData);
                          
                        };
                        

                        Shorter! 🙂 And those lines are equal. Of course if you know very well what the macro does, this
                        line won't interfere you while analyzing code. But for someone just getting started in C++, this
                        is very confusing because

                        1. he doesn't know what the macro does, and it's name is not really implying that it typedefs the
                        base class to SUPER. Yes, this is in the documentation, but having to look up what a macro
                        actually does is IMHO a bad design. Though, this is really just my subjective opinion.
                        2. he wonders why the compiler complains that SUPER is not defined when he is creating is first
                        subclass (he obviously forgot about the INSTANCEOF() part).

                        That's at least what I remember from back then. Until I actually saw the definition line in the C4D
                        header files, I assumed it to be some black magic.

                        Best,
                        -Niklas

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

                          On 18/05/2013 at 04:38, xxxxxxxx wrote:

                          Originally posted by xxxxxxxx

                          but having to look up what a macro actually does is IMHO a bad design

                          If you don't look it up, how would you ever know what it does (except if it's indicated by the macro's name)? That is not bad design, it just normal to look things up. There are functions and macros and structures and lots of other stuff... if you don't know what they are for, look it up. It's just one click.

                          If you only assume what stuff is good for, without verifying your assumptions, and then considering stuff black magic based on your assumption, you should rethink your strategy. Remember that old saying: "Every catastrophe's beginning is a s**tty assumption."

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