Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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
    1. Maxon Developers Forum
    2. JohnTerenece
    J
    • Profile
    • Following 0
    • Followers 0
    • Topics 17
    • Posts 51
    • Best 3
    • Controversial 0
    • Groups 0

    JohnTerenece

    @JohnTerenece

    3
    Reputation
    27
    Profile views
    51
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    JohnTerenece Unfollow Follow

    Best posts made by JohnTerenece

    • RE: DESC_PARENT_COLLAPSE Display

      Thanks for the response.

      DESC_GUIOPEN works having the twirl down open by default. What I'm looking for is the ability to modify whether or not it is actively open based on controls by the user. For example if "Angle Threshold" is greater than 90 degrees than have it twirled down, otherwise have it closed.

      John Terenece

      posted in Cinema 4D SDK
      J
      JohnTerenece
    • BaseTake AddTake

      Hi.

      I am currently working on an object plugin that would utilize Takes for a user to be able to quickly iterate through different potential versions of their scene. I've looked through the sdk and the different manuals that are available and I believe I understand the processes required.

      My issue comes in with the amount of time it take Cinema to run my plugin in regards to the creation of the Takes and if this is just the time that it takes to create them.

      I created a simple scene with a hundred objects underneath my plugin. With the code below I create a Take and assign a layer to each of the child objects. For time testing I create an additional 500 Takes using the first Take as the cloneFrom inside AddTake. This isn't a final version of my code just a test example.

      The code is executed on a button press.

      
      			case idRunTakes:
      			{
      				TakeData* takeData = doc->GetTakeData();
      				if (!takeData)
      					return TRUE;
      
      				LayerObject *hideLayer = LayerObject::Alloc();
      
      				const Vector hsv = Vector(1.0, 0, 0);
      				const Vector rgb = HSVToRGB(hsv);
      				newTakeTime = 0;
      				settingTakeTime = 0;
      				LayerData newdata;
      				newdata.color = rgb;
      				newdata.solo = FALSE;
      				newdata.view = FALSE;
      				newdata.render = FALSE;
      				newdata.manager = TRUE;
      				newdata.locked = FALSE;
      				newdata.generators = FALSE;
      				newdata.deformers = FALSE;
      				newdata.expressions = FALSE;
      				newdata.animation = FALSE;
      				newdata.xref = TRUE;
      				hideLayer->SetLayerData(doc, newdata);
      				hideLayer->SetName("Hide Layer"_s);
      
      				GeListHead* layerList = NULL;
      				layerList = doc->GetLayerObjectRoot();
      
      				layerList->InsertLast(hideLayer);
      				maxon::BaseArray<BaseObject*> childObjArray;
      				GatherAllChildObjects(splineObj->GetDown(), childObjArray);
      
      				DescID aliasLinkDId = DescLevel(ID_LAYER_LINK, DA_ALIASLINK, 0);
      				GeData setData;
      				setData.SetBaseList2D((BaseList2D*)hideLayer);
      
      				Float createNewTakesTime = 0;
      				Float timeStart = 0;
      				Float loopTimeStart = GeGetMilliSeconds();
      
      				timeStart = GeGetMilliSeconds(); 
      				BaseTake* newTake = takeData->AddTake(String("Take " + String::IntToString(0)), nullptr, nullptr);
      				if (newTake == nullptr)
      					return TRUE;
      
      				createNewTakesTime = createNewTakesTime + GeGetMilliSeconds() - timeStart;
      				for (Int32 childObjIndex = 0; childObjIndex < childObjArray.GetCount(); childObjIndex++)
      				{
      					BaseOverride* overrideNode = newTake->FindOrAddOverrideParam(takeData, childObjArray[childObjIndex], aliasLinkDId, setData);
      					if (overrideNode == nullptr)
      						return TRUE;
      
      					childObjArray[childObjIndex]->SetLayerObject(hideLayer);
      					overrideNode->UpdateSceneNode(takeData, aliasLinkDId);
      				}
      
      
      				for (Int32 takeIndex = 1; takeIndex < 501; takeIndex++)
      				{
      					timeStart = GeGetMilliSeconds();
      // This is the line taking up a lot of time
      					BaseTake* loopTake = takeData->AddTake(String("Take " + String::IntToString(takeIndex)), nullptr, newTake);
      					if (loopTake == nullptr)
      						return TRUE;
      					createNewTakesTime = createNewTakesTime + GeGetMilliSeconds() - timeStart;
      					
      				}
      				ApplicationOutput("Take time " + String::FloatToString(createNewTakesTime) + "    " + String::FloatToString(GeGetMilliSeconds() - loopTimeStart - createNewTakesTime));
      				break;
      			}
      
      
      // Code for getting all of the child objects
      void TakeCreatorPlugin::GatherAllChildObjects(BaseObject *childObject, maxon::BaseArray<BaseObject*> &objChildOfNullsArray)
      {
      	if (childObject == nullptr)
      		return;
      
      	while (childObject)
      	{
      		objChildOfNullsArray.Append(childObject);
      
      
      		GatherAllChildObjects(childObject->GetDown(), objChildOfNullsArray);
      		childObject = childObject->GetNext();
      	}
      }
      

      Running the code in my test scene gives the following print out "Take time 1920.243 20.232". So most of the time my plugin is running is taken up by adding the takes into the document. Is this just the time that Cinema takes in this kind of circumstance to create the Takes or am I just missing a crucial step,

      I've looked through the manuals in the sdk and tried to follow them.

      I've also tried to create all of the Takes empty and add the Overrides to each one individually which increases the time that step takes which isn't desirable either.

      Any help would be greatly appreciated.

      JohnTerenece

      posted in Cinema 4D SDK c++ r20 sdk
      J
      JohnTerenece
    • Capsules Drag & Drop

      Hi.

      When working on a tag plugin I've recently been encountering a problem when I try to interact with Capsules, my plugin is meant to have parameters dropped onto it from the object it is attached to.

      In my code I can properly receive the drag and drop operation and get the information from the parameter that was dropped onto it, the issue comes in when I try to determine which object the parameter came from.

      When it comes to the Capsules in the object manager my code does not return the results that I am expecting when I try to verify that the parameters were dragged from the object that the tag is on.

      The code below is a stripped down version of my drag and drop code.

      Bool TagExample::Message(GeListNode* node, Int32 type, void* t_data)
      {
      	BaseDocument* doc = node->GetDocument();
      	if (!doc)
      		return TRUE;
      
      	BaseTag* tag = static_cast<BaseTag*> (node);
              if (!tag)
                 return TRUE;
      	if (type == MSG_DRAGANDDROP)
      	{
      
      		DragAndDrop* dnd = static_cast<DragAndDrop*>(t_data);
      		if (!dnd)
      			return TRUE;
      
                   if (dnd->type == DRAGTYPE_DESCID)
      		{
      
      			DescPropertyDragData* dndid = static_cast<DescPropertyDragData*>(dnd->data);
      
      			AutoAlloc<AtomArray> dndidarr;
      			dndid->arr->CopyTo(dndidarr);
      			if (dndidarr->GetCount() <= 0)
      				return TRUE;
      
      			BaseObject* tagObject = tag->GetObject();
      
      			if (!tagObject)
      				return TRUE;
      
      			BaseObject *draggedObject = (BaseObject*)dndidarr->GetIndex(0);
                              if (!draggedObject)
                                   return TRUE;
      			if (draggedObject != tagObject)
      				ApplicationOutput("Do not equal");
      			else
      				ApplicationOutput("The objects equal")
      
      
      
      			return TRUE;
      		}
      	}
      	
      	return true;
      }
      
      

      For some reason when I drag a parameter from a Neutron Cube, that my tag is on, onto my tag I don't get the expected result of the dragged object and the tag object equalling each other. If I do the same procedure on a regular Cube (Ocube) I am able to properly catch that the objects are one and the same. The same behavior is encountered with other Capsules.

      I'm not very familiar with Capsules, is there a specific way that Capsules need to be interacted with in order to achieve the desired results?

      Any help would be greatly appreciated.

      John Terenece

      posted in Cinema 4D SDK 2023 c++ windows
      J
      JohnTerenece

    Latest posts made by JohnTerenece

    • RE: Capsules Drag & Drop

      Thanks for the response, it's all working properly now.

      John Terenece

      posted in Cinema 4D SDK
      J
      JohnTerenece
    • RE: Capsules Drag & Drop

      Thanks for the detailed response.

      I was able to successfully compile and run the code you provided but I'm running into some weirdness when trying to drag different parameters onto the tag.

      From your code the only change I made was removing the one part you commented as optional.

      BaseList2D* const item = static_cast<BaseList2D*>(dragItems->arr->GetIndex(0));
      
            // Jump ship when we could not make sense of the dragged node or it is not an object. The 
            // latter is optional.
            if (!item)
              return false;
      
            // Now get the scene nodes data for the dragged object.
            maxon::NimbusBaseRef itemHandler = item->GetNimbusRef(maxon::neutron::NODESPACE);
            if (!itemHandler || !itemHandler.GetGraph())
            {
              ApplicationOutput(
                "Drag event for '@', drag data '@' does not hold valid scene nodes graph.",
                tag->GetName(), item->GetName());
              return false;
            }
      

      I'm not very familiar with interacting with Nodes, is there a reason that parameters from the two different tabs would trigger the if statement?

      John Terenece

      posted in Cinema 4D SDK
      J
      JohnTerenece
    • RE: Capsules Drag & Drop

      Thanks for the response.

      I tried implementing the small example bit of code you gave into my own and I was unable to get it properly working. Heres the project file I'm working from that's just a trimmed down version of the sdk example (cinema4dsdk.zip).

      Inside of the example.assets under modules I was able to successfully get it to compile but when I tried to do it inside of the cinema4dsdk module it would continuously give errors that I was missing various header files. When I followed the usual procedure to include the various header files requried I started getting errors inside of the header files themselves saying they were missing other files that they had included that I can't find on my computer.

      This is the first time I'm encountering these kinds of errors so I'm not entirely sure if I'm missing something extremely simple.

      And just to be clear with what I'm attempting to do is I want to be able to catch if a parameter dragged onto my tag is coming from the object that the tag is attached to. With an Ocube my code properly works, with a Neutron Cube my code will not tell me that the dragged parameter's object matches the tag's object.

      John Terenece

      posted in Cinema 4D SDK
      J
      JohnTerenece
    • Capsules Drag & Drop

      Hi.

      When working on a tag plugin I've recently been encountering a problem when I try to interact with Capsules, my plugin is meant to have parameters dropped onto it from the object it is attached to.

      In my code I can properly receive the drag and drop operation and get the information from the parameter that was dropped onto it, the issue comes in when I try to determine which object the parameter came from.

      When it comes to the Capsules in the object manager my code does not return the results that I am expecting when I try to verify that the parameters were dragged from the object that the tag is on.

      The code below is a stripped down version of my drag and drop code.

      Bool TagExample::Message(GeListNode* node, Int32 type, void* t_data)
      {
      	BaseDocument* doc = node->GetDocument();
      	if (!doc)
      		return TRUE;
      
      	BaseTag* tag = static_cast<BaseTag*> (node);
              if (!tag)
                 return TRUE;
      	if (type == MSG_DRAGANDDROP)
      	{
      
      		DragAndDrop* dnd = static_cast<DragAndDrop*>(t_data);
      		if (!dnd)
      			return TRUE;
      
                   if (dnd->type == DRAGTYPE_DESCID)
      		{
      
      			DescPropertyDragData* dndid = static_cast<DescPropertyDragData*>(dnd->data);
      
      			AutoAlloc<AtomArray> dndidarr;
      			dndid->arr->CopyTo(dndidarr);
      			if (dndidarr->GetCount() <= 0)
      				return TRUE;
      
      			BaseObject* tagObject = tag->GetObject();
      
      			if (!tagObject)
      				return TRUE;
      
      			BaseObject *draggedObject = (BaseObject*)dndidarr->GetIndex(0);
                              if (!draggedObject)
                                   return TRUE;
      			if (draggedObject != tagObject)
      				ApplicationOutput("Do not equal");
      			else
      				ApplicationOutput("The objects equal")
      
      
      
      			return TRUE;
      		}
      	}
      	
      	return true;
      }
      
      

      For some reason when I drag a parameter from a Neutron Cube, that my tag is on, onto my tag I don't get the expected result of the dragged object and the tag object equalling each other. If I do the same procedure on a regular Cube (Ocube) I am able to properly catch that the objects are one and the same. The same behavior is encountered with other Capsules.

      I'm not very familiar with Capsules, is there a specific way that Capsules need to be interacted with in order to achieve the desired results?

      Any help would be greatly appreciated.

      John Terenece

      posted in Cinema 4D SDK 2023 c++ windows
      J
      JohnTerenece
    • RE: Breaking Tags Out Of A Shared Folder

      Thanks for the response, that's what I was afraid of.

      John Terenece

      posted in Cinema 4D SDK
      J
      JohnTerenece
    • Breaking Tags Out Of A Shared Folder

      Hi,

      I'm working on a project that is made up of multiple tag plugins. What I'm trying to do is have the tags all separate in the list of Tags instead of under one folder.

      Below I have a screenshot of the compiled base SDK for visual purposes.

      Tag Plugins.png

      So what I'm looking for is to have the three plugins inside of the "Cinema4dsdk Tags" dropdown not be inside of a submenu.

      I know you can do this by compiling them all as separate projects but I would prefer to avoid going that route if there is an alternative.

      Any help would be appreciated.

      John Terenece

      posted in Cinema 4D SDK r21 sdk c++
      J
      JohnTerenece
    • RE: Drag & Drop Undo

      Thanks for the response.

      I figured that something like this would be the case, will have to look into the options you mentioned.

      John Terenece

      posted in Cinema 4D SDK
      J
      JohnTerenece
    • RE: Drag & Drop Undo

      Thanks for the detailed response.

      I implemented the GeIsMainThread() into my code and that itself did not change any of the results I am getting which I would expect it to.

      Running my code with a StartUndo and EndUndo results in this behavior StartEnd Undo.webm

      I have tried the code without any AddUndo and this was the result No AddUndo.webm.

      Sorry I wasn't clear in what I wanted the undos to do. As seen in both videos dropping one tag onto the other causes the dropped tag to move and the link field to change, what I am trying to do is have both of those being undone in a single undo so that the link field would be cleared and the dropped tag moved back to its original position.

      I know that dragging a tag into the link field itself doesn't require an undo, that part of my code works perfectly fine.

      John Terenece

      posted in Cinema 4D SDK
      J
      JohnTerenece
    • Drag & Drop Undo

      Hi.

      I am working on a tag plugin that will have a user drag & dropping another tag onto it, the dragged tag will then be set into a link field for use later. I successfully have the drag and drop working, my issue comes in when I try to implement undo functionality for the drag and drop.

      With the code below (from the sdk) I have the tag only accepting tags of the same type as the plugin itself. After the drag and drop it takes two separate undos to successfully revert the link field to its previous state. I've tried the code below with the StartUndo/EndUndo and it always takes the two undos.

      #include "c4d.h"
      #include "c4d_symbols.h"
      #include "lib_hair.h"
      #include "main.h"
      #include <customgui_descproperty.h>
      
      #include "thairsdkrendering.h"
      
      #define TESTPLUGIN_ID 9000
      //////////////////////////////////////////////////////////////////////////
      
      class HairRenderingTag : public TagData
      {
      	INSTANCEOF(HairRenderingTag, TagData)
      
      public:
      	virtual Bool Init(GeListNode* node);
      	virtual void Free(GeListNode* node);
      	virtual Bool Message(GeListNode* node, Int32 type, void* data);
      	virtual Bool GetDDescription(GeListNode* node, Description* description, DESCFLAGS_DESC& flags);
      	static NodeData* Alloc() { return NewObjClear(HairRenderingTag); }
      
      };
      
      
      //////////////////////////////////////////////////////////////////////////
      
      Bool HairRenderingTag::Init(GeListNode* node)
      {
      	BaseContainer* bc = ((BaseList2D*)node)->GetDataInstance();
      	return true;
      }
      
      void HairRenderingTag::Free(GeListNode* node)
      {
      }
      
      
      
      Bool HairRenderingTag::GetDDescription(GeListNode* node, Description* description, DESCFLAGS_DESC& flags)
      {
      	if (!description->LoadDescription(node->GetType()))
      	{
      
      	}
      
      	const DescID* singleid = description->GetSingleDescID();
      
      	BaseContainer *dataInstance = ((BaseList2D*)node)->GetDataInstance(); // Get the container for the tag
      
      	
      
      	DescID cid = DescLevel(1000, DTYPE_GROUP, 0);
      	if (!singleid || cid.IsPartOf(*singleid, nullptr))	// important to check for speedup c4d!
      	{
      		BaseContainer maingroup = GetCustomDataTypeDefault(DTYPE_GROUP);
      		maingroup.SetString(DESC_NAME, "Links"_s);
      		maingroup.SetInt32(DESC_DEFAULT, 1);
      		if (!description->SetParameter(cid, maingroup, DescLevel(TESTPLUGIN_ID)))
      			return true;
      	}
      	
      	cid = DescLevel(1001, DTYPE_BASELISTLINK, 0);
      	if (!singleid || cid.IsPartOf(*singleid, NULL))    //     important to check for speedup c4d!
      	{
      		BaseContainer bc;
      		bc = GetCustomDataTypeDefault(DTYPE_BASELISTLINK);
      		BaseContainer acceptedObjects;
      		acceptedObjects.InsData(TESTPLUGIN_ID, String()); // matrix
      
      		bc.SetContainer(DESC_ACCEPT, acceptedObjects);
      		bc.SetBool(DESC_SCALEH, true);
      
      		bc.SetString(DESC_NAME, "Link Field"_s);
      		if (!description->SetParameter(cid, bc, 1000))
      			return TRUE;
      	}
      
      
      	flags |= DESCFLAGS_DESC::LOADED;
      
      	return SUPER::GetDDescription(node, description, flags);
      }
      
      
      Bool HairRenderingTag::Message(GeListNode* node, Int32 type, void* data)
      {
      	BaseDocument* doc = node->GetDocument();
      	if (!doc)
      		return TRUE;
      
      	BaseContainer* dataInstance;
      	BaseTag* tag = static_cast<BaseTag*> (node);
      	if (tag == nullptr)
      		return TRUE;
      
      	dataInstance = tag->GetDataInstance();
      	if (!dataInstance)
      		return TRUE;
      
      	if (type == MSG_DRAGANDDROP)
      	{
      		DragAndDrop* dnd = static_cast<DragAndDrop*>(data);
      		if (!dnd)
      			return TRUE;
      		// Drag & drop will only accept tags of the plugin type
      		if (dnd->type == DRAGTYPE_ATOMARRAY)
      		{
      			AtomArray* dndid = static_cast<AtomArray*>(dnd->data);
      
      
      			AutoAlloc<AtomArray> dndidarr;
      			dndid->CopyTo(dndidarr);
      
      			if (dndidarr->GetCount() <= 0)
      				return TRUE;
      
      			if (dndidarr->GetIndex(0) != nullptr)
      			{
      				if (dndidarr->GetIndex(0)->GetType() != TESTPLUGIN_ID)
      					return TRUE;
      			}
      			else
      			{
      				return TRUE;
      			}
      
      			BaseObject* tagsobject = tag->GetObject();
      
      			BaseContainer state;
      
      			if (!GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, state))
      				return TRUE;
      
      
      			// Only run when the mouse is released
      			if (state.GetInt32(BFM_INPUT_VALUE) == 0)
      			{
      				BaseTag *attachedTag = (BaseTag*)dndidarr->GetIndex(0);
      				doc->AddUndo(UNDOTYPE::CHANGE, tag);
      				dataInstance->SetLink(1001, attachedTag);
      				return TRUE;
      			}
      		}
      
      	}
      	return SUPER::Message(node, type, data);
      }
      
      Bool RegisterRenderingTag()
      {
      	return RegisterTagPlugin(TESTPLUGIN_ID, "Link Test"_s, TAG_MULTIPLE | TAG_VISIBLE, HairRenderingTag::Alloc, "Thairsdkrendering"_s, AutoBitmap("hairrendering.tif"_s), 0);
      }
      
      

      I'm not sure if I am doing something fundementally wrong with the undos since I have had undos of other types working in other plugins.

      Any help would be greatly appreciated.

      John Terenece

      posted in Cinema 4D SDK r20 sdk c++
      J
      JohnTerenece
    • RE: Active Controls

      Thanks for the response.

      That's what I figured would be the case.

      posted in Cinema 4D SDK
      J
      JohnTerenece