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

    Getting Dependence of Object

    Cinema 4D SDK
    c++ r20
    2
    3
    548
    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.
    • D
      d_schmidt
      last edited by

      Hello!

      I'm working on a plugin were I want to take an input child object spline and use its points as a basis for an output. I'm able to get when the object is dirty reliably and only update when I have to. But when I have an object like an Oinstance or an Oconnector, I'm not getting a dirty message from them if the object inputting into them has been updated.

      Aside from manually checking the object type and checking INSTANCEOBJECT_LINK and CONNECTOBJECT_LINK respectively I can't figure out a way to get if they have actually updated and therefore I have to update.

      Is there way to get the dependence list for a given object so I can manually check it? Since the linked connect/instance isn't being marked as dirty I don't know another approach to use. Or is there a better way to know when an input into one of those objects has updated?

      Dan

      1 Reply Last reply Reply Quote 0
      • ManuelM
        Manuel
        last edited by Manuel

        hello

        I was trying to do what you want for your project and maybe i found something. (pick a hierarchy and return a spline)

        Seems that you can use GetAndCheckHierarchyClone()
        This function check if something have changed. Return A hierarchy of PolygonObject or SplineObject so you don't have to use makeeditable or get cache or what ever.

        I didn't thought immediately but you can add several flag like so HIERARCHYCLONEFLAGS::ASPOLY | HIERARCHYCLONEFLAGS::ASSPLINE

        This function return the cache if nothing have changed.

        I've created a function to create a BaseArray of all objects but you can pick your own solution.

        
        maxon::BaseArray<BaseObject*> PC11572::HierarchyIterator(BaseObject* obj)
        {
        	maxon::BaseArray<BaseObject*> objArray;
        	while (obj != nullptr)
        	{
        		objArray.Append(obj);
        		// we can append the array from another array.
        		objArray.Append(HierarchyIterator(obj->GetDown()));
        		obj = obj->GetNext();
        	}
        	
        	return objArray;
        }
        
        
        BaseObject* PC11572::GetVirtualObjects(BaseObject *op, HierarchyHelp *hh)
        {
        	
        	if (op == nullptr || hh == nullptr)
        	{
        		return BaseObject::Alloc(Onull);
        	}
        
        	BaseObject* firstChild = op->GetDown();
        
        
        	if (firstChild == nullptr)
        	{
        		return nullptr;
        	}
        
        	BaseObject* res = nullptr;
        	
        	Bool dirty = false;
        	AutoAlloc <AliasTrans> trans;
        	if (!trans) return nullptr;
        	if (!trans->Init(hh->GetDocument())) return nullptr;
        
        	res = op->GetAndCheckHierarchyClone(hh, firstChild, HIERARCHYCLONEFLAGS::ASPOLY | HIERARCHYCLONEFLAGS::ASSPLINE, &dirty, trans, true);
        	trans->Translate(true);
        
        	if (!res)
        	{
        		return BaseObject::Alloc(Onull);;
        	}
        
        	if (dirty)
        	{
        		DiagnosticOutput("This is dirty Create a new spline");
        		// Gets an array of every object 
        		maxon::BaseArray<BaseObject*> myList = HierarchyIterator(res);
        		// Creates a new spline
        		SplineObject* newSpline = SplineObject::Alloc(0, SPLINETYPE::LINEAR);
        		// Gets the revers Matrix (to go from global space to local space
        		const Matrix invOpMg = ~op->GetMg();
        		
        		maxon::Int32 lastPoint = 0;
        
        		for (auto &child : myList)
        		{
        			// The object should already be Opoint or Ospline but extra check doesn't hurt
        			if (child->IsInstanceOf(Opoint) || child->IsInstanceOf(Ospline))
        			{
        				const maxon::Int32 pcnt = ToPoly(child)->GetPointCount();
        				const Vector* childPadr = ToPoly(child)->GetPointR();
        
        				// Don't waste time if there's no point to add
        				if (pcnt == 0)
        					continue;
        
        				// Resizes the spline without changing the Segment number (one segment should be created for each object / each spline segment)
        				newSpline->ResizeObject(lastPoint + pcnt, 1);
        				// Gets write access to the points
        				Vector* padr = newSpline->GetPointW();
        				// Gets the first element in the writable segments array
        				Segment* seg = newSpline->GetSegmentW();
        				// Changes the number of points in that segment
        				seg->cnt = lastPoint + pcnt;
        				// Gets the matrix of the child to go from local to global
        				const Matrix childMg = child->GetMg();
        
        				for (maxon::Int32 i = lastPoint, j = 0 ; i < lastPoint + pcnt; i++, j++)
        				{
        					// Updates the points position from child, by going from local to global to local.
        					padr[i] = invOpMg * (childMg * childPadr[j]);
        				}
        				// Updates last points index so the next object will go behind.
        				lastPoint += pcnt;
        			}
        
        		}
        		return newSpline;
        
        	}
        	else
        	{
        		DiagnosticOutput("There nothing to do");
        		// returning res because GetAndCheckHierarchyClone return cache if not dirty
        		return res;
        	}
        
        	
        	return BaseObject::Alloc(Onull);
        	
        	
        }
        
        

        Cheers
        Manuel

        MAXON SDK Specialist

        MAXON Registered Developer

        1 Reply Last reply Reply Quote 1
        • ManuelM
          Manuel
          last edited by

          hello,

          this topics will be considered as resolved if you have nothing to add.

          Cheers
          Manuel

          MAXON SDK Specialist

          MAXON Registered Developer

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