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

    Generator too slow [SOLVED]

    SDK Help
    0
    9
    766
    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 19/04/2015 at 11:15, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   15 
      Platform:      Mac OSX  ; 
      Language(s) :     C++  ;

      ---------
      I created a generator object that generates a spline.
      First I created it in python but, since it was resulting in a very slow generation of the spline (it is a very complex calculation), I decided to code it in C++.
      But it is still too slow since it is calculation the spline everytime.
      Is there any way to only re-generate the spline if the parameters were changed?

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

        On 19/04/2015 at 13:36, xxxxxxxx wrote:

        At least for GetVirtualObjects(), you can use GetAndCheckHierarchyClone() to check if the object needs to be recreated or not (if it is dirty or not).  If not, the returned clone can be returned.  Not sure if this applies with GetContour().

        	// Check if needs rebuild and get cloned hierarchy of input objects
        	Bool			dirty = FALSE;
        	mainop =				op->GetAndCheckHierarchyClone(hh, child, HIERARCHYCLONEFLAGS_ASPOLY, &dirty, NULL, TRUE);
        	// - if !dirty then object is already cached and doesn't need to be rebuilt
        	if (!dirty)				return mainop;
        

        As for 'complex calculation', anything (and I literally mean *ANYTHING* ) that can be done once or preprocessed should not be done every time you do this complex calculation.  I would need to see your calculation code in order to offer places to do this - but you should be able to see easily where calculations are invariant and could be done beforehand and then used to enhance speed and reduce complexity.  For instance, if you are dividing real numbers with a real number (say, Q) repeatedly, take the inverse of that real number (1/Q) and multiply.  Division is slower than multiplication in floats.  Avoid Sqrt() whenever possible - again, any calculation to a particular value that is being done more than once (esp. in loops) needs to be done outside of the loop or just once into a variable and reused.

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

          On 19/04/2015 at 15:37, xxxxxxxx wrote:

          I placed this in my code and it didn't work. It crashed Cinema 4D 😞

            
          BaseObject* ArborSkeleton::GetVirtualObjects(BaseObject* op, HierarchyHelp* hh)   
          {   
            
               Bool dirty=false;   
            
               BaseObject* mainop=op->GetAndCheckHierarchyClone(hh, op, HIERARCHYCLONEFLAGS_ASPOLY, &dirty;, NULL, true);   
               if (!dirty)     return mainop;   
            
               BaseDocument* doc=op->GetDocument();   
               return (BaseObject* ) Generate_Arbor(op,doc);   
          }
          
          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 19/04/2015 at 15:45, xxxxxxxx wrote:

            If your generated object is a spline, you should use HIERARCHCLONEFLAGS_ASSPLINE.  Also note that you pass the child of the generator object, not the generator itself (op) :

            	// Get first input object
            	BaseObject*		child =	op->GetDown();
            	if (!child)				return NULL;
              
            	// Generate clones of input objects
            	// NOTE: 'mainop' is the original returned with the generated objects
              
            	// Check if needs rebuild and get cloned hierarchy of input objects
            	Bool			dirty = FALSE;
            	BaseObject* mainop = op->GetAndCheckHierarchyClone(hh, child, HIERARCHYCLONEFLAGS_ASSPLINE, &dirty, NULL, TRUE);
            	// - if !dirty then object is already cached and doesn't need to be rebuilt
            	if (!dirty)				return mainop;
            	if (!mainop)			return NULL;
            
            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 19/04/2015 at 15:55, xxxxxxxx wrote:

              This object has no child. It is simply an object that generates a spline.

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

                On 19/04/2015 at 16:18, xxxxxxxx wrote:

                That ain't gonna work then. 😞

                You will need to do this first in GetVirtualObjects() :

                Bool dirty = op->CheckCache(hh) || op->IsDirty(DIRTYFLAGS_DATA);
                if (!dirty) return op->GetCache(hh);
                

                This should stop continuous rebuilding.

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

                  On 19/04/2015 at 23:58, xxxxxxxx wrote:

                  YES!!! It worked just fine 🙂
                  Now I just have to optimize my code, anyway 🙂

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

                    On 20/04/2015 at 06:52, xxxxxxxx wrote:

                    Hello,

                    I just want to add that an example on how to use the cache in GetVirtualObjects() can be found in the SDK Rounded Tube plugin.

                    If you want to create a Python ObjectData generator plugin you can take advantage of the optimized Cache, see "Optimize Cache".

                    Best wishes,
                    Sebastian

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

                      On 20/04/2015 at 07:16, xxxxxxxx wrote:

                      Well, now that I have it working in C++ (it was already working in python), I guess I will keep on developing this one in C++.
                      And it is already caching quite well 🙂

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