Free and Alloc called several times

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 06/05/2008 at 04:33, xxxxxxxx wrote:

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

---------
Hi, a general question: is it usual for a tag plugin that alloc is called several times? Everytime I send a message by clicking in the attribute manager the alloc function is called, though it is not used anywhere in the code.

Additionally when activating e.g. a checkbox in the attribute manager and I do an undo call, the view isn't refreshed until the tag is deactivated and activated again.

Any ideas?

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 13/05/2008 at 03:52, xxxxxxxx wrote:

Really no idea? Every time I drag a slider or activate a checkbox "alloc tag" is called. This leads to some serious problems with undoing. Some help would be fantastic... Thx

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 13/05/2008 at 06:06, xxxxxxxx wrote:

Can you post some source code because I can not really follow you here?

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 13/05/2008 at 06:19, xxxxxxxx wrote:

The Alloc and Free-Functions:

> <code>
>
>           static NodeData *Alloc(void) { GePrint ("Alloc MoCap");return gNew MoCap;}
>
>           virtual void Free(GeListNode *node){SetBackIDs(node); GePrint ("Free MoCap");
> </code>

The Message-Function. Everytime I hit the "Add Bone"-button and Undo afterwards, the Attribute Manager doesn't refresh until I select and deselect. Also, the Free-method is called...

> <code>
> Bool MoCap::Message (GeListNode *node, LONG type, void *data)
> {
>      BaseDocument *doc=node->GetDocument();
>      BaseTag          *tag = (BaseTag* )node;     //Mocap Tag
>      BaseContainer *bc = tag->GetDataInstance();
>      switch (type)
>      {
> //...
>                if (dc->id[0].id==ADD_BONE_BUTTON)
>                {
>                     GePrint ("Add bone button");
>                     long jointCount = bc->GetLong (DESC_COUNTER)+1;
>                     doc->StartUndo();
>                     doc->AddUndo(UNDO_CHANGE, tag);
>                     bc->SetLong (DESC_COUNTER, jointCount);
>                     bc->SetLink (JOINTS + jointCount - 1, NULL);
>                     bc->SetLink(JOINT_PARENTS + jointCount - 1, NULL);
>                     doc->EndUndo();
>                     EventAdd();
>                     break;
>                }
>               
>                if (dc->id[0].id==REMOVE_BONE_BUTTON)
>                {
>                     GePrint ("Remove Bone button");
>                     doc->StartUndo();
>                     if (bc->GetLong (DESC_COUNTER) >0){
>                          long jointCount = bc->GetLong (DESC_COUNTER)-1;
>                          bc->SetLong (DESC_COUNTER, jointCount);
>                          doc->AddUndo(UNDO_CHANGE, tag);
>                     }
>                     doc->EndUndo();
>                     EventAdd();
>                     break;
>                }
>
> //...
>
>      return TRUE;
> }
> </code>

Apparently, while undoing the first tag instance is deleted. As previously posted, Cinema generates new instances when doing something in the Attribute Manager. but why?

Thx

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 13/05/2008 at 09:14, xxxxxxxx wrote:

So, here's the entire code though I don't think anyone wants to read this whole stuff.

> <code>
>
>
> #include "c4d.h"
> #include "c4d_symbols.h"
> #include "c4d_gui.h"
> #include "tmoCap.h"
> #include <string.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <iostream>
> #include <sstream>
> #include <vector>
> #include <lib_ca.h>
> using namespace std;
> using std::cout;
>
>
>
> #include "lib_description.h"
> #include "customgui_priority.h"
>
>
>
>
>
> class MoCap : public TagData
> {
>      public:
>
>           static int instance;
>
>           virtual Bool Init(GeListNode *node);
>
>           virtual Bool SetAllIDs (BaseDocument *doc);
>
>           virtual LONG Execute(PluginTag *tag, BaseDocument *doc, BaseObject *op, BaseThread *bt, LONG priority, LONG flags);
>
>      //     virtual string longToStr (long l);
>           
>           virtual String boolToStr (bool b);
>
>           virtual Bool GetDDescription(GeListNode* node, Description* description, LONG& flags);
>
>           virtual Bool activeChildren (BaseTag *tag);
>
>           virtual Bool Message (GeListNode *node, LONG type, void *data);
>           
>           virtual LONG NumberOfChildren(BaseObject *obj);
>
>           virtual Vector CalcMiddle (BaseTag *tag, BaseTime time);
>
>           virtual Bool generateObject(BaseTag *tag);
>
>           virtual Bool generateJoint (BaseTag *tag);
>
>           virtual BaseObject * FindParent (BaseLink *parentLink);
>
>           virtual Vector SetChildCoordinates (CAJointObject *JointObject, Vector PosJoint);
>
>           virtual void SetBackIDs(GeListNode *node);
>
>           static NodeData *Alloc(void) { GePrint ("Alloc MoCap");return gNew MoCap;}
>
>           virtual void Free(GeListNode *node){SetBackIDs(node); GePrint ("Free MoCap");}
>
>
>           
>      private:
>
>           long counter;
>
>           long uniqueIP;
>
>           vector <BaseObject*>children;
>
>           BaseObject *jointOrigin;
>
> };
>
> int MoCap::instance = 0;
>
> Bool MoCap::Init(GeListNode *node)
> {
>      GePrint ("Init");
>      BaseDocument *doc = GetActiveDocument();
>      BaseTag                    *tag = (BaseTag* )node;     //initialisierter Tag
>      BaseContainer *data = tag->GetDataInstance();     //zugehöriger Container
>
>      GeData d;
>      if (node->GetParameter(DescLevel(EXPRESSION_PRIORITY),d,0))
>      {
>           PriorityData *pd = (PriorityData* )d.GetCustomDataType(CUSTOMGUI_PRIORITY_DATA);
>           if (pd) pd->SetPriorityValue(PRIORITYVALUE_CAMERADEPENDENT,GeData(TRUE));
>           node->SetParameter(DescLevel(EXPRESSION_PRIORITY),d,0);
>      }
>      data->SetBool(USE_CHECKBOX, TRUE);
>      data->SetLong (DESC_COUNTER, 0);
>      data->SetBool (DESC_NO_ORIGIN, TRUE);
>      data->SetLong(DESC_INSTANCE, instance);
>
>      instance++;
>
>      Bool result = SetAllIDs (doc);
>
>      jointOrigin = NULL;
>      uniqueIP = 0;
>      return TRUE;
> }
>
> Bool MoCap::SetAllIDs (BaseDocument *doc){
>      BaseObject * op = doc->GetFirstObject();
>
>      if (op == NULL)
>           return FALSE;
>
>      BaseContainer *opContainer = op->GetDataInstance();
>      opContainer->SetLong (DESC_JOINT_ID, 0);
>      BaseObject *current;
>      Bool used;
>
>      while (op!= NULL){
>           current = op->GetDown();
>           if (current == NULL)
>                current = op->GetNext();
>           if (current == NULL)
>                break;
>           opContainer = current->GetDataInstance();
>           used = opContainer->GetBool (DESC_USED);
>           if (!used)
>                opContainer->SetLong (DESC_JOINT_ID, 0);
>           op = current;
>           }
>      return TRUE;
> }
>
> Bool MoCap::GetDDescription(GeListNode* node, Description* description, LONG& flags){     
>      
>      if (!description->LoadDescription(node->GetType())) return FALSE;
>      
>      BaseTag                    *tag = (BaseTag* )node;     //initialisierter Tag
>      BaseContainer *data = tag->GetDataInstance();     //zugehöriger Container
>      BaseDocument *doc=node->GetDocument();
>
>      BaseContainer locked = GetCustomDataTypeDefault(DTYPE_BOOL);
>      locked.SetString(DESC_NAME, "SPECIAL Locked");
>      locked.SetBool (DESC_DEFAULT, TRUE);
>
>      if(!description->SetParameter(DescLevel(USE_CHECKBOX, DTYPE_BOOL, 0), locked, DescLevel(MAIN_GROUP))) return TRUE;
>
>      BaseContainer count = GetCustomDataTypeDefault(DTYPE_LONG);
>      count.SetString(DESC_NAME, "Count");
>      if (!description->SetParameter(DescLevel(NUMBER_OF_CHILDREN, DTYPE_LONG, 0), count, DescLevel(MAIN_GROUP))) return TRUE;
>
>      BaseContainer trackers = GetCustomDataTypeDefault(DTYPE_GROUP);
>      trackers.SetString(DESC_NAME, "Trackers");
>      if (!description->SetParameter(DescLevel(TRACKER_TYPE_GROUP, DTYPE_GROUP, 0), trackers, DescLevel(MAIN_GROUP))) return TRUE;
>
>
>      long i;
>      bool mergeable;
>      Real mergeValue;
>
>      BaseObject *currentObject = (BaseObject* ) node;
>      BaseContainer *currentContainer = currentObject->GetDataInstance();
>
>      BaseContainer currentLayout = GetCustomDataTypeDefault (DTYPE_GROUP);
>      BaseContainer firstColumn = GetCustomDataTypeDefault (DTYPE_GROUP);
>      BaseContainer secondColumn = GetCustomDataTypeDefault (DTYPE_GROUP);
>      BaseContainer thirdColumn = GetCustomDataTypeDefault (DTYPE_GROUP);
>
>      BaseContainer box = GetCustomDataTypeDefault(DTYPE_BOOL);
>      BaseContainer slider = GetCustomDataTypeDefault(DTYPE_REAL);
>      BaseContainer boxNames = GetCustomDataTypeDefault(DTYPE_STATICTEXT);
>
>      slider.SetLong (DESC_CUSTOMGUI,CUSTOMGUI_REALSLIDER);
>      slider.SetReal (DESC_MIN, 0.0);
>      slider.SetReal (DESC_MAX, 1.0);
>      slider.SetReal (DESC_STEP, 0.01);
>      slider.SetLong(DESC_UNIT,DESC_UNIT_PERCENT);
>      slider.SetLong(DESC_ANIMATE,DESC_ANIMATE_ON);
>      slider.SetBool (DESC_ALIGNLEFT, TRUE);
>
>
>      box.SetBool(DESC_DEFAULT, FALSE);
>
>      currentLayout.SetBool(DESC_LAYOUTGROUP, TRUE);
>      currentLayout.SetLong(DESC_COLUMNS, 3);
>
>      for (i = 0; i<counter; i++){
>
>           currentObject = children _;
>
>           if (currentObject->GetType() == Onull){
>                currentContainer = currentObject->GetDataInstance();
>
>
>                if(!description->SetParameter(DescLevel(ROW_GROUPS + i, DTYPE_GROUP, 0), currentLayout, DescLevel(TRACKER_TYPE_GROUP))) return TRUE;
>               
>                if(!description->SetParameter(DescLevel(FIRST_COLUMN_GROUPS + i, DTYPE_GROUP, 0), firstColumn, DescLevel(ROW_GROUPS + i))) return TRUE;
>                if(!description->SetParameter(DescLevel(ENABLE_BOXES + i, DTYPE_BOOL, 0), box, DescLevel(FIRST_COLUMN_GROUPS + i))) return TRUE;
>
>                mergeable = currentContainer->GetBool(DESC_MERGEABLE);
>                data->SetBool(ENABLE_BOXES + i, mergeable);
>
>                if(!description->SetParameter(DescLevel(SECOND_COLUMN_GROUPS + i, DTYPE_GROUP, 0), secondColumn, DescLevel(ROW_GROUPS + i))) return TRUE;
>                if(!description->SetParameter(DescLevel(WEIGHT_SLIDERS + i, CUSTOMGUI_REALSLIDER, 0), slider, DescLevel(SECOND_COLUMN_GROUPS + i))) return TRUE;
>           
>                mergeValue = currentContainer->GetReal(DESC_MERGE_VALUE);
>                data->SetReal (WEIGHT_SLIDERS + i, mergeValue);
>           
>                String aktName = currentObject->GetName();
>                boxNames.SetString (DESC_NAME, aktName);
>
>                if(!description->SetParameter(DescLevel(THIRD_COLUMN_GROUPS + i, DTYPE_GROUP, 0), thirdColumn, DescLevel(ROW_GROUPS + i))) return TRUE;
>                if(!description->SetParameter(DescLevel(BOX_NAMES + i, DTYPE_STATICTEXT, 0), boxNames, DescLevel(THIRD_COLUMN_GROUPS + i))) return TRUE;
>
>           }
>      }
>
>      if (counter > 0){
>
>           BaseTime endOfDoc = doc->GetMaxTime();
>           long docFps = doc->GetFps();
>           long frames = endOfDoc.GetFrame(docFps);
>
>           BaseContainer start = GetCustomDataTypeDefault(DTYPE_LONG);
>           start.SetString(DESC_NAME, "Start");
>           start.SetLong (DESC_MIN, 0);
>           start.SetLong (DESC_MAX, frames);
>           if (!description->SetParameter(DescLevel(KEY_START, DTYPE_LONG, 0), start, DescLevel(TRACKER_TYPE_GROUP))) return TRUE;
>
>           BaseContainer ende = GetCustomDataTypeDefault(DTYPE_LONG);
>           ende.SetString(DESC_NAME, "Ende");
>           ende.SetLong (DESC_MIN, 0);
>           ende.SetLong (DESC_MAX, frames);
>           if (!description->SetParameter(DescLevel(KEY_ENDE, DTYPE_LONG, 0), ende, DescLevel(TRACKER_TYPE_GROUP))) return TRUE;
>
>           BaseContainer apply = GetCustomDataTypeDefault(DTYPE_BUTTON);
>           apply.SetString (DESC_NAME, "Apply");
>           apply.SetData(DESC_CUSTOMGUI, CUSTOMGUI_BUTTON);
>           if (!description->SetParameter(DescLevel(APPLY_BUTTON, DTYPE_BUTTON, 0), apply, DescLevel(TRACKER_TYPE_GROUP))) return TRUE;
>      }
>
>      if (counter > 0){
>
>           BaseContainer boneConnections = GetCustomDataTypeDefault(DTYPE_GROUP);
>           boneConnections.SetString(DESC_NAME, "Bone Connections");
>           if (!description->SetParameter(DescLevel(BONE_TYPE_GROUP, DTYPE_GROUP, 0), boneConnections, DescLevel(MAIN_GROUP))) return TRUE;
>
>
>           BaseContainer jointLink = GetCustomDataTypeDefault(DTYPE_GROUP);
>           jointLink.SetLong (DESC_COLUMNS, 2);
>
>           BaseContainer joint = GetCustomDataTypeDefault(DTYPE_BASELISTLINK);
>           joint.SetString (DESC_NAME, "Joint");
>
>           BaseContainer jointParent = GetCustomDataTypeDefault(DTYPE_BASELISTLINK);
>           jointParent.SetString (DESC_NAME, "Parent");
>
>           long jointCount = data->GetLong (DESC_COUNTER);
>           
>           for (long i = 0; i<jointCount; i++){
>                if (!description->SetParameter(DescLevel(BONE_ROW_GROUPS + i, DTYPE_GROUP, 0), jointLink, DescLevel(BONE_TYPE_GROUP))) return TRUE;
>                if (!description->SetParameter(DescLevel(JOINTS + i, DTYPE_BUTTON, 0), joint, DescLevel(BONE_ROW_GROUPS + i))) return TRUE;
>                if (!description->SetParameter(DescLevel(JOINT_PARENTS + i, DTYPE_BUTTON, 0), jointParent, DescLevel(BONE_ROW_GROUPS + i))) return TRUE;
>           }
>           
>           BaseContainer addBone = GetCustomDataTypeDefault(DTYPE_BUTTON);
>           addBone.SetString (DESC_NAME, "Add Joint");
>           addBone.SetData(DESC_CUSTOMGUI, CUSTOMGUI_BUTTON);
>           if (!description->SetParameter(DescLevel(ADD_BONE_BUTTON, DTYPE_BUTTON, 0), addBone, DescLevel(BONE_TYPE_GROUP))) return TRUE;
>           
>           BaseContainer addChild = GetCustomDataTypeDefault(DTYPE_BUTTON);
>           addChild.SetString (DESC_NAME, "Remove Joint");
>           addChild.SetData(DESC_CUSTOMGUI, CUSTOMGUI_BUTTON);
>           if (!description->SetParameter(DescLevel(REMOVE_BONE_BUTTON, DTYPE_BUTTON, 0), addChild, DescLevel(BONE_TYPE_GROUP))) return TRUE;
>           
>           BaseContainer genBone = GetCustomDataTypeDefault(DTYPE_BUTTON);
>           genBone.SetString (DESC_NAME, "Generate");
>           genBone.SetData(DESC_CUSTOMGUI, CUSTOMGUI_BUTTON);
>           if (!description->SetParameter(DescLevel(GENERATE_BONE_BUTTON, DTYPE_BUTTON, 0), genBone, DescLevel(BONE_TYPE_GROUP))) return TRUE;
>
>      }
>
>
>      flags |= DESCFLAGS_DESC_LOADED;
>
>      return TRUE;
> }
>
>
>
>
> LONG MoCap::Execute(PluginTag *tag, BaseDocument *doc, BaseObject *op, BaseThread *bt, LONG priority, LONG flags)
> {
>      
>      BaseContainer *data = tag->GetDataInstance();     //zugehöriger Container
>
>      children.clear();
>      counter = NumberOfChildren (op);
>
>
>
>      data->SetReal (6004, counter);
>      return EXECUTION_RESULT_OK;
> }
>
> LONG MoCap::NumberOfChildren(BaseObject *obj){
>
>      BaseObject *current = NULL;
>      current = obj->GetDown();
>
>      long trackers = 0;
>      
>      while (current != NULL)
>      {
>           if (current->GetType() ==Onull){
>                trackers ++;
>                children.push_back (current);
>           }
>           current = current->GetNext();
>      }
>
>
>      return trackers;
>
> }
>
> Bool MoCap::generateObject (BaseTag *tag){
>
>      BaseDocument *doc=tag->GetDocument();
>      doc->StartUndo();
>      GePrint ("StartUndo");
>      BaseObject *parent = tag->GetObject();
>      BaseContainer *data = tag->GetDataInstance();
>      BaseObject *newObject = BaseObject::Alloc (Onull);
>
>      Real difference;
>      Real start_value = data->GetLong (KEY_START);
>      Real end_value = data->GetLong (KEY_ENDE);
>      if (start_value > end_value)
>           return FALSE;
>      difference = end_value - start_value +1;
>
>      newObject->InsertUnderLast (parent);
>      doc->AddUndo(UNDO_NEW, newObject);
>
>      CKey *keyX;
>      CKey *keyY;
>      CKey *keyZ;
>      Vector result;
>      BaseTime time;
>      long frameRate = doc->GetFps();
>
>      CTrack *trackX = CTrack::Alloc(newObject,DescID(DescLevel(ID_BASEOBJECT_POSITION,DTYPE_VECTOR,0),DescLevel(VECTOR_X,DTYPE_REAL,0)));
>      if (!trackX ) return FALSE;
>      CTrack *trackY = CTrack::Alloc(newObject,DescID(DescLevel(ID_BASEOBJECT_POSITION,DTYPE_VECTOR,0),DescLevel(VECTOR_Y,DTYPE_REAL,0)));
>      if (!trackY ) return FALSE;
>      CTrack *trackZ = CTrack::Alloc(newObject,DescID(DescLevel(ID_BASEOBJECT_POSITION,DTYPE_VECTOR,0),DescLevel(VECTOR_Z,DTYPE_REAL,0)));
>      if (!trackZ ) return FALSE;
>      newObject->InsertTrackSorted(trackX);
>      newObject->InsertTrackSorted(trackY);
>      newObject->InsertTrackSorted(trackZ);
>
>      for (long i = 0; i<difference; i++){
>           time = BaseTime (start_value, frameRate);
>           result = CalcMiddle (tag, time);
>           newObject->SetPos(result);
>
>           keyX = trackX->GetCurve()->AddKey(time);
>           if (!keyX) return FALSE;
>           keyX->SetValue(trackX->GetCurve(),result.x);
>
>           keyY = trackY->GetCurve()->AddKey(time);
>           if (!keyY) return FALSE;
>           keyY->SetValue(trackY->GetCurve(),result.y);
>
>           keyZ = trackZ->GetCurve()->AddKey(time);
>           if (!keyZ) return FALSE;
>           keyZ->SetValue(trackZ->GetCurve(),result.z);
>           start_value++;
>      }
>      //doc->EndUndo();
>
>      return TRUE;
> }
>
> Bool MoCap::generateJoint(BaseTag *tag){
>
>      GePrint ("Generate Joint");
>
>      BaseDocument *doc=tag->GetDocument();
>      doc->StartUndo();
>      GePrint ("StartUndo");
>      BaseContainer *data = tag->GetDataInstance();
>      BaseObject *object = tag->GetObject();
>      Real inst = data->GetLong (DESC_INSTANCE);    
>      
>      GePrint ("instance:");
>      GePrint (RealToString(inst));
>
>      BaseObject *parent = NULL;
>
>      Bool noOrigin = data->GetBool (DESC_NO_ORIGIN);
>
>      if(noOrigin){
>
>           GePrint ("No Origin");
>           BaseObject *origin = BaseObject::Alloc(Onull);
>           origin->SetName ("Joint Hierarchy");
>           jointOrigin = origin;
>           doc->InsertObject (jointOrigin, NULL, NULL);
>
>           doc->AddUndo(UNDO_NEW, origin);
>
>           BaseTag *oTag = PluginTag::Alloc(10005);
>
>           BaseContainer *originContainer = oTag->GetDataInstance();
>           originContainer->SetBool (DESC_ORIGIN, TRUE);
>           originContainer->SetLink (DESC_TAGLINK, tag);
>           origin->InsertTag(oTag);
>
>           data->SetBool (DESC_NO_ORIGIN, FALSE);
>      }
>
>
>      long jointCount = data->GetLong (DESC_COUNTER);
>           
>      BaseTime time;
>
>      BaseObject *tracker;
>      BaseContainer *trackerContainer;
>
>      BaseLink *jointLink = NULL;
>      BaseLink *parentLink = NULL;
>
>      for (long i = 0; i < jointCount; i++){
>           jointLink = data->GetBaseLink (JOINTS + i);
>           parentLink = data->GetBaseLink (JOINT_PARENTS + i);
>      
>      
>           if (jointLink->GetLink(doc)!= NULL){
>                GePrint ("GotBaseLink");
>
>                tracker = (BaseObject * )jointLink->GetLink (doc);
>                if (parentLink != NULL)
>                     parent = (BaseObject * )parentLink->GetLink (doc);
>                trackerContainer = tracker->GetDataInstance();
>
>                Bool used = trackerContainer->GetBool (DESC_USED);
>               
>                if (!used){
>               
>                     uniqueIP++;
>
>                     CAJointObject *jointObject = CAJointObject::Alloc ();
>                     doc->AddUndo(UNDO_NEW, jointObject);
>
>                     String name = tracker->GetName();
>                     jointObject->SetName(name);
>
>                     GePrint ("name");
>                     GePrint (name);
>
>                     BaseContainer *jointContainer = jointObject->GetDataInstance();
>                     jointContainer->SetLong (DESC_JOINT_ID, uniqueIP);
>                     jointContainer->SetBool (DESC_USED, TRUE);
>
>                     trackerContainer->SetLong (DESC_JOINT_ID, uniqueIP);
>                     trackerContainer->SetBool (DESC_USED, TRUE);
>
>
>                     BaseTag *jTag = PluginTag::Alloc(10005);
>
>                     BaseContainer *tagContainer = jTag->GetDataInstance();
>                     tagContainer->SetLink (DESC_COUNTERPART, tracker);
>                     tagContainer->SetBool (DESC_ORIGIN, FALSE);
>                     jointObject->InsertTag(jTag);
>
>
>                     if (parentLink->GetLink(doc) != NULL){
>                          parent = FindParent (parentLink);
>                          if (parent != NULL){
>                              BaseContainer *parentContainer = parent->GetDataInstance();
>                              Bool equal = (parentContainer->GetLong (DESC_JOINT_ID) == trackerContainer->GetLong (DESC_JOINT_ID));
>                              if (!equal){
>                                    jointObject->InsertUnderLast (parent);
>                                    GePrint ("parent != NULL");
>                              }
>                              else
>                              {
>                                    jointObject->InsertUnderLast (jointOrigin);
>                                    GePrint ("parent == NULL");
>                              }
>                          }
>                          else{
>                              jointObject->InsertUnderLast (jointOrigin);
>                              GePrint ("AfterInsertUnderLast");
>                          }
>                     }
>                     else {
>                          jointObject->InsertUnderLast (jointOrigin);
>                     }
>
>
>                     BaseTime endOfDoc = doc->GetMaxTime();
>                     long docFps = doc->GetFps();
>                     long frames = endOfDoc.GetFrame(docFps);
>               
>                     Vector PosJoint;     
>                     CKey *keyX;
>                     CKey *keyY;
>                     CKey *keyZ;
>
>                     CTrack *trackX = CTrack::Alloc(jointObject,DescID(DescLevel(ID_BASEOBJECT_POSITION,DTYPE_VECTOR,0),DescLevel(VECTOR_X,DTYPE_REAL,0)));
>                     if (!trackX ) return FALSE;
>                     CTrack *trackY = CTrack::Alloc(jointObject,DescID(DescLevel(ID_BASEOBJECT_POSITION,DTYPE_VECTOR,0),DescLevel(VECTOR_Y,DTYPE_REAL,0)));
>                     if (!trackY ) return FALSE;
>                     CTrack *trackZ = CTrack::Alloc(jointObject,DescID(DescLevel(ID_BASEOBJECT_POSITION,DTYPE_VECTOR,0),DescLevel(VECTOR_Z,DTYPE_REAL,0)));
>                     if (!trackZ ) return FALSE;
>                     jointObject->InsertTrackSorted(trackX);
>                     jointObject->InsertTrackSorted(trackY);
>                     jointObject->InsertTrackSorted(trackZ);
>
>                     for (long i = 0; i<frames; i++){
>                          time = BaseTime (i, docFps);
>                          doc->SetTime (time);
>                          doc->AnimateDocument (NULL, FALSE, TRUE);
>                          EventAdd();
>                          PosJoint = tracker->GetPos();
>
>                          jointObject->SetPos(PosJoint);
>                          if (parent != NULL)
>                              PosJoint = SetChildCoordinates (jointObject, PosJoint);
>
>                          keyX = trackX->GetCurve()->AddKey(time);
>                          if (!keyX) return FALSE;
>                          keyX->SetValue(trackX->GetCurve(),PosJoint.x);
>
>                          keyY = trackY->GetCurve()->AddKey(time);
>                          if (!keyY) return FALSE;
>                          keyY->SetValue(trackY->GetCurve(),PosJoint.y);
>
>                          keyZ = trackZ->GetCurve()->AddKey(time);
>                          if (!keyZ) return FALSE;
>                          keyZ->SetValue(trackZ->GetCurve(),PosJoint.z);
>                     }
>                }
>           }
>      }
>      data->SetLong (DESC_COUNTER, 0);
>      //doc->EndUndo();
>      return TRUE;
> }
>
>
> BaseObject * MoCap::FindParent (BaseLink *parentLink){
>      GePrint ("FindParent");
>      BaseDocument *doc = GetActiveDocument();
>      if (parentLink->GetLink(doc) == NULL){
>           return NULL;
>      }
>      BaseObject *obj = (BaseObject * )parentLink->GetLink(doc);
>      BaseContainer *objContainer = obj->GetDataInstance();
>      long objID = objContainer->GetLong (DESC_JOINT_ID);
>      long currID = 0;
>      GePrint (obj->GetName());
>      bool found = FALSE;
>
>      GePrint ("Origin:");
>      if (jointOrigin ==NULL)
>           GePrint ("NULL");
>      BaseObject *current = jointOrigin->GetDown();
>      GePrint ("JointOrigin->GetDown");
>      BaseObject *next = current;
>      BaseObject *up = current;
>      BaseContainer *currContainer;
>
>      while (next != NULL){
>           current = next;
>           up = next;
>           currContainer = current->GetDataInstance();
>           currID = currContainer->GetLong (DESC_JOINT_ID);
>           next = current->GetDown();
>           if (next ==NULL)
>                next = current->GetNext();
>           if (next ==NULL){
>                while (up != jointOrigin && next == NULL){
>                     up = up->GetUp();
>                     next = up->GetNext();
>                }
>                if (up == jointOrigin){
>                     GePrint ("up == jointOrigin");
>                     next = NULL;
>                }
>           }
>           if (currID == objID){
>                GePrint ("found");
>                found = TRUE;
>                break;
>           }
>      }
>
>      if (found)
>           return current;
>      else
>           return NULL;
> }
>
> Vector MoCap::SetChildCoordinates (CAJointObject *JointObject, Vector PosJoint){
>      BaseObject *parObject = JointObject->GetUp();
>      while (parObject != jointOrigin){
>           PosJoint = PosJoint - parObject->GetPos();
>           parObject = parObject->GetUp();
>      }
>      return PosJoint;
> }
>
> Bool MoCap::Message (GeListNode *node, LONG type, void *data)
> {
>      BaseDocument *doc=node->GetDocument();
>      BaseTag          *tag = (BaseTag* )node;     //Mocap Tag
>      BaseContainer *bc = tag->GetDataInstance();
>      switch (type)
>      {
>           case MSG_DESCRIPTION_COMMAND:
>           {
>                DescriptionCommand *dc = (DescriptionCommand* ) data;
>                if (dc->id[0].id==APPLY_BUTTON)
>                {
>                     BaseObject *parent = tag->GetObject();
>                     if (activeChildren (tag)){
>                          Bool result = generateObject (tag);
>                          }
>                     //EventAdd();
>                     break;
>                     }
>
>                if (dc->id[0].id==ADD_BONE_BUTTON)
>                {
>                     long jointCount = bc->GetLong (DESC_COUNTER)+1;
>                     //doc->StartUndo();
>                     GePrint ("StartUndo");
>                     //doc->AddUndo(UNDO_CHANGE, doc);
>                     bc->SetLong (DESC_COUNTER, jointCount);
>                     bc->SetLink (JOINTS + jointCount - 1, NULL);
>                     bc->SetLink(JOINT_PARENTS + jointCount - 1, NULL);
>                     GePrint ("Added Bone");
>                     //doc->EndUndo();
>                     //EventAdd();
>                     break;
>                }
>               
>                if (dc->id[0].id==REMOVE_BONE_BUTTON)
>                {
>                     //doc->StartUndo();
>                     GePrint ("StartUndo");
>                     if (bc->GetLong (DESC_COUNTER) >0){
>                          long jointCount = bc->GetLong (DESC_COUNTER)-1;
>                          bc->SetLong (DESC_COUNTER, jointCount);
>                          //doc->AddUndo(UNDO_CHANGE, tag);
>                     }
>                     //doc->EndUndo();
>                     //EventAdd();
>                     break;
>                }
>
>                if (dc->id[0].id==GENERATE_BONE_BUTTON)
>                {
>                     Bool result = generateJoint (tag);
>                     //EventAdd();
>                     break;
>                }
>
>                }
>           case MSG_DESCRIPTION_CHECKUPDATE:
>                {
>                     GePrint ("Check Update");
>                     DescriptionCheckUpdate *dch = (DescriptionCheckUpdate* ) data;
>                     DescID descID = *(dch->descid);
>                     LONG paramID = descID[0].id;
>
>                     if (tag)
>                     {
>                          Bool enabled;
>                          Real weight;
>                          BaseObject *current = NULL;
>                          BaseContainer *currentContainer;
>                          current = (BaseObject* ) children[0];
>                          long i=0;
>                          bool changed = FALSE;
>
>                          while (current != NULL && !changed){
>                              if (current->GetType() == Onull){
>                                    currentContainer = current->GetDataInstance();
>                                    enabled = bc->GetBool(ENABLE_BOXES + i);
>                                    weight = bc->GetReal(WEIGHT_SLIDERS + i);
>                                    Bool mergeable = currentContainer->GetBool (DESC_MERGEABLE);
>                                    Real mergeValue = currentContainer->GetReal (DESC_MERGE_VALUE);
>
>                                    if (mergeable != enabled || mergeValue != weight){
>                                         //doc->StartUndo();
>                                         //GePrint ("StartUndo");
>                                        doc->AddUndo(UNDO_CHANGE,current);
>                                         currentContainer->SetBool (DESC_MERGEABLE, enabled);
>                                         currentContainer->SetReal (DESC_MERGE_VALUE, weight);
>                                         changed = TRUE;
>                                         //doc->EndUndo();
>                                    }
>                              }
>                              current = current->GetNext();
>                              i++;
>                          }
>                     }
>                     //EventAdd();
>                     break;
>                }
>           case MSG_DESCRIPTION_USERINTERACTION_END:
>                {
>                     //GePrint ("End Undo");
>                     //doc->EndUndo();
>                     break;
>                }
>      }
>
>      return TRUE;
> }
>
>
> /*
> string MoCap::longToStr (long l)
> {
>      ostringstream oss;
>      oss << l;
>      string str (oss.str());
>      return str;
> }
> */
>
> String MoCap::boolToStr (bool b)
> {
>      String s;
>      if (b==TRUE)
>           s = "TRUE";
>      else
>           s = "FALSE";
>      return s;
> }
>
>
> Bool MoCap::activeChildren (BaseTag *tag){
>      bool activeChild = FALSE;
>      for (long i = 0; i<counter; i++){
>           if (tag->GetDataInstance()->GetBool(ENABLE_BOXES + i))
>                activeChild = TRUE;
>      }
>      return activeChild;
> }
>
>
>
> Vector MoCap::CalcMiddle (BaseTag *tag, BaseTime time){
>
>      BaseDocument *doc=GetActiveDocument();
>      doc->SetTime (time);
>      doc->AnimateDocument (NULL, FALSE, TRUE);
>      EventAdd();
>      Vector middle (0.0, 0.0, 0.0);
>      BaseObject *current = NULL;
>      BaseObject *parent = tag->GetObject();
>      current = parent->GetDown();
>      BaseContainer * data = tag->GetDataInstance();
>
>      bool active = FALSE;
>      long i = 0;
>      Real weighter = 0;
>      
>      while (current != NULL)
>      {
>           active = data->GetBool(ENABLE_BOXES + i);
>           if (active)
>           {
>                Vector pos = current->GetPos();
>                Real weight = data->GetReal(WEIGHT_SLIDERS + i);
>
>                middle.x += pos.x * weight;
>                middle.y += pos.y * weight;
>                middle.z += pos.z * weight;
>
>                weighter += weight;
>           }
>           current = current->GetNext();
>           i++;
>      }
>
>      if (weighter == 0)
>           return NULL;
>      else
>      {
>           middle /= weighter;
>           return middle;
>      }
> }
>
>
>
>
>
> void MoCap::SetBackIDs (GeListNode *node){
>
>      GePrint ("SetBackIDs");
>
>      BaseTag *tag = (BaseTag * ) node;
>      BaseContainer *data = tag->GetDataInstance();
>      Real inst = data->GetLong (DESC_INSTANCE);    
>      
>      GePrint ("FreeInstance:");
>      GePrint (RealToString(inst));
>
>      BaseObject *obj = tag->GetObject();
>
>      if (obj != NULL){
>           GePrint ("obj!=NULL");
>
>           BaseObject *op = obj->GetDown();
>           BaseObject *current;
>           BaseContainer *opContainer = op->GetDataInstance();
>
>           while (op!= NULL){
>                opContainer = op->GetDataInstance();
>                opContainer->SetBool (DESC_USED, FALSE);
>                opContainer->SetLong (DESC_JOINT_ID, 0);
>                current = op->GetDown();
>                if (current == NULL)
>                     current = op->GetNext();
>                if (current == NULL)
>                     current = op->GetUp()->GetNext();
>                op = current;
>           }
>      }
> }
>
> // be sure to use a unique ID obtained from www.plugincafe.com
> #define ID_MOCAP     10004
>
> Bool RegisterMoCap(void)
> {
>      // decide by name if the plugin shall be registered - just for user convenience
>      String name=GeLoadString(IDS_MOCAPTAG); if (!name.Content()) return TRUE;
>      return RegisterTagPlugin(ID_MOCAP,name,TAG_EXPRESSION|TAG_VISIBLE,MoCap::Alloc,"Tmocap","mocap.tif",0);
> }
>
> </code>

The most important thing to me is the repeated call of the alloc and free-methods, because I don't get why they are called and how I should place the undo-commands to avoid the confusing results. A simple answer to this would be a big help.

Thx

J.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 14/05/2008 at 02:48, xxxxxxxx wrote:

What you seeing here is Cinema's undo/redo system at work. It has to create instances when you change something in the AM and free them if you are undoing things.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 14/05/2008 at 07:09, xxxxxxxx wrote:

OK, I'm sorry for the confusion:) This is the first time I try to understand the undo behaviour and I still didn't really succeed. Somewhere I read that Attribute Manager items like checkboxes are handled automatically and that causes a lot of trouble. Before the Message-method is called, it creates an instance (for the undo call?), and it doesn't work properly with Message() :

> \> \> Bool MoCap::Message (GeListNode \*node, LONG type, void \*data) \> { \>      BaseDocument \*doc=node->GetDocument(); \>      BaseTag          \*tag = (BaseTag\* )node;      \>      BaseContainer \*bc = tag->GetDataInstance(); \> \>      switch (type) \>      { \>           case MSG_DESCRIPTION_INITUNDO: \>           { \>                GePrint ("MSG_DESCRIPTION_INITUNDO"); \>                StopAllThreads(); \>                doc->StartUndo(); \>                break; \>           } \>           case MSG_DESCRIPTION_COMMAND: \>           { \>                DescriptionCommand \*dc = (DescriptionCommand\* ) data; \>                if (dc->id[0].id==APPLY_BUTTON) \>                { \>                     GePrint ("StartUndo"); \>                     BaseObject \*parent = tag->GetObject(); \>                     if (activeChildren (tag)){ \>                          Bool result = generateObject (tag); \>                          } \>                     break; \>                     } \> \>                if (dc->id[0].id==ADD_BONE_BUTTON) \>                { \>                     long jointCount = bc->GetLong (DESC_COUNTER)+1; \>                     GePrint ("StartUndo"); \>                     doc->AddUndo(UNDO_CHANGE_SMALL, tag); \>                     GePrint ("AddUndo"); \>                     bc->SetLong (DESC_COUNTER, jointCount); \>                     bc->SetLink (JOINTS + jointCount - 1, NULL); \>                     bc->SetLink(JOINT_PARENTS + jointCount - 1, NULL); \>                     GePrint ("Added Bone"); \>                     break; \>                } \>                \>                if (dc->id[0].id==REMOVE_BONE_BUTTON) \>                { \>                     GePrint ("StartUndo"); \>                     if (bc->GetLong (DESC_COUNTER) >0){ \>                          long jointCount = bc->GetLong (DESC_COUNTER)-1; \>                          doc->AddUndo(UNDO_CHANGE_SMALL, tag); \>                          bc->SetLong (DESC_COUNTER, jointCount); \>                     } \>                     break; \>                } \> \>                if (dc->id[0].id==GENERATE_BONE_BUTTON) \>                { \>                     GePrint ("StartUndo"); \>                     Bool result = generateJoint (tag); \>                     break; \>                } \> \>                } \>           case MSG_DESCRIPTION_CHECKUPDATE: \>                { \>                     GePrint ("Check Update"); \>                     DescriptionCheckUpdate \*dch = (DescriptionCheckUpdate\* ) data; \>                     DescID descID = \*(dch->descid); \>                     LONG paramID = descID[0].id; \> \>                     if (tag) \>                     { \>                          Bool enabled; \>                          Real weight; \>                          Real start, end; \>                          BaseObject \*current = NULL; \>                          BaseContainer \*currentContainer; \>                          current = (BaseObject\* ) children[0]; \>                          long i=0; \>                          bool changed = FALSE; \> \>                          while (current != NULL && !changed){ \>                              if (current->GetType() == Onull){ \>                                    currentContainer = current->GetDataInstance(); \>                                    enabled = bc->GetBool(ENABLE_BOXES + i); \>                                    weight = bc->GetReal(WEIGHT_SLIDERS + i); \>                                    Bool mergeable = currentContainer->GetBool (DESC_MERGEABLE); \>                                    Real mergeValue = currentContainer->GetReal (DESC_MERGE_VALUE); \> \>                                    if (mergeable != enabled || mergeValue != weight){ \>                                         GePrint ("if"); \>                \>                                        doc->AddUndo(UNDO_CHANGE_NOCHILDS,tag); \>                                        doc->AddUndo(UNDO_CHANGE_SMALL,current); \>                                         currentContainer->SetBool (DESC_MERGEABLE, enabled); \>                                         currentContainer->SetReal (DESC_MERGE_VALUE, weight); \>                                         changed = TRUE; \>                                          \>                                    } \>                              } \>                              current = current->GetNext(); \>                              i++; \>                          } \>                     } \>                     break; \>                } \>           case MSG_DESCRIPTION_USERINTERACTION_END: \>                { \>                     GePrint ("End Undo"); \>                     doc->EndUndo(); \>                     break; \>                } \>      } \> \>      return TRUE; \> } \> \>

The buttons "Add bone" and "Remove Bone" work properly with undo, but in all other cases the original instance of the tag gets deleted. I assume I do not work correctly in case MSG_DESCRIPTION_CHECKUPDATE. Does anyone see the problem?

Thx