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

    Update Issue with ObjectData

    SDK Help
    0
    4
    345
    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 31/01/2013 at 01:14, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   R14 
      Platform:   Windows  ;   
      Language(s) :

      ---------
      Hey guys,

      I trying to do the following:
      I got an objectdata generator plugin which takes a spline and generate maybe an extrude nurbs with that spline.
      But here special is, that the spline should not be under the generator, it should be the previous or parent.

      If I use spline = op->GetPred() it works but the editor does not update correct not until I click in the editor view.
      If I use spline = op->GetUp() it does not work, c4d crash.
      If I use spline = op->GetDown() all is fine.

      Check dirty of spline does not work, but you will see the effect if you toggle xray or change any other data of the generator (color, name...).

      #include "c4d.h"  
        
      #define ID_PLUGIN_TESTOBJECT 12345678  
        
      class TestObject : public ObjectData  
      {  
         
        INSTANCEOF(TestObject, ObjectData)  
        
        public:  
            virtual BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh);  
        
            static NodeData* Alloc(void) { return gNew TestObject; }  
      };  
        
      BaseObject* TestObject::GetVirtualObjects(BaseObject* op, HierarchyHelp* hh)  
      {  
        BaseObject *spline = op->GetPred();  
        //BaseObject *spline = op->GetUp();  
        //BaseObject *spline = op->GetDown();  
        if (!spline || (spline->GetInfo() & OBJECT_ISSPLINE) != OBJECT_ISSPLINE) return NULL;  
        
        // check cache for validity and check master object for changes  
        Bool dirty = op->CheckCache(hh) || op->IsDirty(DIRTYFLAGS_DATA);  
        
        // check spline for changes - does not work  
        dirty |= spline->IsDirty(DIRTYFLAGS_DATA) || spline->IsDirty(DIRTYFLAGS_MATRIX) || spline->IsDirty(DIRTYFLAGS_CACHE);  
        
        // if no change has been detected, return original cache  
        if (!dirty) return op->GetCache(hh);  
        
        BaseObject *obj = BaseObject::Alloc(Oextrude);  
        BaseObject *splineClone = (BaseObject* ) spline->GetClone(COPYFLAGS_0, NULL);  
        splineClone->InsertUnder(obj);  
        
        return obj;  
      }  
        
      Bool RegisterTestObject(void)  
      {  
        return RegisterObjectPlugin(ID_PLUGIN_TESTOBJECT, "TestObject", OBJECT_GENERATOR, TestObject::Alloc, "", NULL, 0);  
      }
      
      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 31/01/2013 at 07:59, xxxxxxxx wrote:

        Hi Toni,

        With op->GetUp() it crashes because you call spline->GetClone() and both the spline and the generator itself are copied.
        To only copy the spline, call spline->GetClone(COPYFLAGS_NO_HIERARCHY, NULL).

        Generators aren't modifiers: you can't take a parent or sibling object as input object(s).
        A generator object plugin can be registered with the OBJECT_INPUT flag but this will only work in the pipeline of CINEMA if you take the subobject(s) as input.

        Also checking the dirty flag works better with C4DAtom::GetDirty():

        ULONG dirty = spline->GetDirty(DIRTYFLAGS_DATA|DIRTYFLAGS_MATRIX);
        if (dirty==this->dirtyCount)
            return op->GetCache(hh);
        

        dirtyCount is a member of the generator and caches the last dirty count for the comparison.

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

          On 31/01/2013 at 08:18, xxxxxxxx wrote:

          Thank you for your replay.
          You are right, the op->GetUp() was a silly idea. o.O

          I figured out that spline->GetClone() is my problem. If I use a Generator with a Link Attribute (Linked to a spline) and use spline->GetClone(), the same "buggy" update happen:

          GetVirtualObjects is called, but not until I click in the 3d view the editor is redrawn.

          If I clone the spline manual (rewriting points and tangents) it works better.

          Would it be save?

          SplineObject* CopySpline(SplineObject *spline)  
          {  
            LONG pcnt = spline->GetPointCount();  
            LONG scnt = spline->GetSegmentCount();  
            LONG tcnt = spline->GetTangentCount();  
            
            SplineObject *newSpline = SplineObject::Alloc(pcnt, spline->GetInterpolationType());  
            newSpline->ResizeObject(pcnt, scnt);  
            newSpline->SetData(spline->GetData(), FALSE);  
              
            // Copy Points  
            const Vector *points = spline->GetPointR();  
            Vector *newPoints = newSpline->GetPointW();  
            for (LONG i = 0; i < pcnt; i++)  
            {  
                newPoints[i] = points[i];  
            }  
            
            // Copy Tangents  
            const Tangent *tangents = spline->GetTangentR();  
            Tangent *newTangents = newSpline->GetTangentW();  
            for (LONG i = 0; i < tcnt; i++)  
            {  
                newTangents[i] = tangents[i];  
            }  
            
            const Segment *segment = spline->GetSegmentR();  
            Segment *newSegment = newSpline->GetSegmentW();  
            for (LONG i = 0; i < scnt; i++)  
            {  
                newSegment[i] = segment[i];  
            }  
            newSpline->Message(MSG_UPDATE);  
            
            return newSpline;  
          }
          
          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 01/02/2013 at 05:26, xxxxxxxx wrote:

            Yes, it's safe if you copy manually all the spline data.

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