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

    GVO PolygonObject inside NullObject untargetable

    SDK Help
    0
    10
    2.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 27/04/2018 at 13:02, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   R19.053 
      Platform:   Windows  ;   
      Language(s) :     C++  ;

      ---------
      Hi! I have a generator plugin that creates PolygonObjects and returns them collectively under a
      single Null-Object.

      It may choose to reuse some of the PolygonObjects from the previously generated  cache. it does
      so using the cach e from op- >GetCache(hh); , then finding the res pectivePolygonObject, calling
      Remove() and inserting it under the new Null-Object that will be returned with InsertUnderLast().

      When it creates the PolygonObject from scratch, it allocates it, uses ResizeObject() , then sets
      the polygons and points in GetPointW() and GetPolygonW() and calls Message(MSG_UPDATE);.

      The reason why I think that the MSG_UPDATE message has no effect is because the bounding
      box of the PolygonObject does not seem to be updated properly. Also the PolygonObject returned
      by the generator can not be target with the "navigation pivot" in the C4D viewport.

      Is there anything else that I need to do to "complete" the PolygonObject after I built it?

      Thanks,
      Niklas

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

        On 30/04/2018 at 02:08, xxxxxxxx wrote:

        Hi Niklas,

        Polygon objects within a cache are read-only.
        You can't modify them, but you can clone it and then SetPoint/Polygon will work.

        About your issue of the bounding box, make sure to override GetDimension.

        Cheers,
        Maxime

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

          On 03/05/2018 at 02:51, xxxxxxxx wrote:

          Hi,

          not sure, this is already solved.
          Still, I'd like to add a link to the extended number of ObjectData examples for future readers.

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

            On 03/05/2018 at 06:01, xxxxxxxx wrote:

            Hi Maxime & Andreas, thanks for the reply.

            >> Polygon objects within a cache are read-only.

            I am not making modifications to the polygon objects inside existing caches -- I am creating new
            Polygon Objects. However when I recognize that the Polygon Object that I would build from scratch
            already exists in the cache due to the previous call to GetVirtualObjects(), I want to re-use that.

            Similar to returning the whole cache, as it can be seen in some of the example ObjectData plugins:

            if (nothing changed) {  
              return op->GetCache(hh);  
            }
            

            I may want to select only some of the Polygon Objects in the cache.

            AutoAlloc<BaseObject> root(Onull);  
            BaseObject* cache = op->GetCache(hh);  
            for (auto&& obj : input_objects) {  
              if (nothing_changed && cache) {  
              BaseObject* cache_obj = FindObjectInCache(cache, GetUuid(obj));  
              if (cache_obj) {  // Reuse the object  
                cache_obj->Remove();  
                cache_obj->InsertUnder(root);  
                continue;  
              }  
              AutoAlloc<PolygonObject> poly(0, 0);  
              // ... build polygon object  
              poly->InsertUnder(root);  
              poly.Release();  
              }  
            }
            

            This works without problems as far as I can see. Just to check whether this causes the issue that
            you can not navigate on top of the object, I tried cloning the object from the cache (which would
            not be desirable) and I get the same problem.

                if (cache_obj) {  // Reuse the object  
                cache_obj = (BaseObject* ) cache_obj->GetClone(COPYFLAGS_0, nullptr);  
                if (cache_obj) {  
                 cache_obj->Remove();  
                    cache_obj->InsertUnder(root);  
                 continue;  
                }  
              }
            

            >> About your issue of the bounding box, make sure to override GetDimension.

            Overriding GetDimension() will not solve the problem that I am facing.

            I try to be more descriptive: When you have an object in the Viewport, you can press ALT and LEFT
            MOUSE BUTTON to pivot around the object at the location where your cursor intersects with the
            geometry.

            This does not work in my case. And I am wondering if you have any clues where this could be
            coming from. My initial guess was that I needed to use MSG_UPDATE before I return the object,
            but that didn't help.

            Here is a small video that hopefully clarifies the issues: https://public.niklasrosenstein.com/_quickshare/2018-05-03-generator-polygonobject-navpivot.flv

            The cube is a standard cube, the two cars are both Polygon Objects returned by my generator.

            Any idea what could cause the Pivot to not recognize the geometry from my generator?

            Thanks for looking into this.

            Cheers,
            Niklas

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

              On 04/05/2018 at 02:57, xxxxxxxx wrote:

              Hi Niklas,

              just as a test, can you please leave all optimizations aside. If you build the output of your generator from scratch, does it work properly then?

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

                On 05/05/2018 at 03:02, xxxxxxxx wrote:

                Hi Andreas,  I get the same problem without reusing the cache but building the PolygonObject
                anew every time (although the geometry information does come from a different representation
                fromanother SDK).

                However from your suggestions, I tried to reproduce it my just building a simply triangle to be sure
                that it's not an issue with the geometry that I get from the SDK. It seems like the culprit is actually
                that the PolygonObject is inside a Null-Object. When I return the PolygonObject directly, it works
                fine.

                    AutoAlloc<BaseObject> root(Onull);  
                  AutoAlloc<PolygonObject> poly(3, 1);  
                  auto p = poly->GetPointW();  
                  p[0] = Vector(100, 0, 0);  
                  p[1] = Vector(100, 0, 100);  
                  p[2] = Vector(0, 0, 100);  
                  auto c = poly->GetPolygonW();  
                  c[0] = CPolygon(0, 1, 2);  
                  poly->InsertUnder(root);  
                  poly->Message(MSG_UPDATE);  
                  poly.Release();  
                  return root.Release();
                

                Cheers,
                Niklas

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

                  On 05/05/2018 at 06:48, xxxxxxxx wrote:

                  Renamed from MSG_UPDATE for PolygonObject has no effect in GVO to GVO PolygonObject inside NullObject untargetable.

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

                    On 08/05/2018 at 08:16, xxxxxxxx wrote:

                    Hi Niklas,

                    I need to ask you for a bit of patience. I can reproduce the issue, but to be honest I don't get it. Take for example the Array object with a polygon object as input. The resulting cache structure is exactly the same and there it works as expected. Haven't been able to spot the difference, yet. Stay tuned.

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

                      On 14/05/2018 at 06:04, xxxxxxxx wrote:

                      Hi Niklas,

                      sorry, this took a bit longer. In the end it's a matter of proper use of the cache. The "pivot feature" relies on a somewhat constant cache.
                      By just adding these three lines to the top of your example, the pivot feature works just fine:

                        Bool dirty = op->CheckCache(hh) || op->IsDirty(DIRTYFLAGS_DATA);
                        if (!dirty)
                          return op->GetCache(hh);
                      
                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 15/05/2018 at 09:26, xxxxxxxx wrote:

                        Thank you Andreas. Making sure that I keep returning the same Null-Object makes it work.
                        I pick certain objects from the cache and insert them under a new hierarchy. Now instead of
                        returning that new hierarchy, I simply replace the parent of the hierarchy with the previous
                        parent.

                            // The navigation pivot in C4D seems to require a rather "constant cache"  
                          // from the object if a Null-Object is used as root. We'll just reuse the  
                          // previous cache null object if there is any.  
                          if (cache) {  
                            for (BaseObject* child = cache->GetDown(); child;) {  
                              BaseObject* next = child->GetNext();  
                              BaseObject::Free(child);  
                              child = next;  
                            }  
                            for (BaseObject* child = root->GetDown(); child;) {  
                              BaseObject* next = child->GetNext();  
                              child->Remove();  
                              child->InsertUnderLast(cache);  
                              child = next;  
                            }  
                            return cache;  
                          }  
                          
                          return root.Release();
                        

                        Cheers,
                        Niklas

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