Refresh an object display in the editor
-
On 10/06/2014 at 13:16, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 14
Platform: Mac OSX ;
Language(s) : C++ ;---------
I have a tag that hides some polygons (with SendModelingCommand(MCOMMAND_HIDESELECTED, cd)). It also restores their visibility when the tag is deleted (with SendModelingCommand(MCOMMAND_UNHIDE, cd)).
But the polygons only get invisible/visible after the user changes something in the document (or adjusts the viewport).
How can I force a refresh of the object?
I can't use EvenAdd() as that, somehow, breaks the IRR in the editor.
And op->Message(MSG_CHANGE) doesn't forces a refresh of the object. -
On 10/06/2014 at 16:44, xxxxxxxx wrote:
Can you show how you're getting the object the tag is on?
I don't see how to do that. Even using a class member variable. It crashes for me.The only way I can see how to unhide the polygons for the object that the tag is on is doing it this way:
void MyTag::Free(GeListNode *node) { //This only UnHides the hidden polygons if the object is selected before deleting the tag //If the object is not selected nothing happens when the tag is deleted (but it doesn't crash either) if(GetActiveDocument()->GetActiveObject()) { ModelingCommandData cd; cd.doc = GetActiveDocument(); cd.op = GetActiveDocument()->GetActiveObject(); cd.mode = MODELINGCOMMANDMODE_POLYGONSELECTION; cd.flags = MODELINGCOMMANDFLAGS_0; SendModelingCommand(MCOMMAND_UNHIDE, cd); } return; }
I'm very curious how you're grabbing the object the tag is on.
-ScottA
-
On 11/06/2014 at 02:24, xxxxxxxx wrote:
In the Draw method I save the object (and the document) in a private variable, inside the class.
That was the only way I could make it work. -
On 11/06/2014 at 06:59, xxxxxxxx wrote:
Howdy,
Originally posted by xxxxxxxx
In the Draw method I save the object (and the document) in a private variable, inside the class.
That was the only way I could make it work.You can also save those in the tag's BaseContainer.
You might also consider using the TagData::Message() function instead of TagData::Draw() function for that.
Adios,
Cactus Dan -
On 11/06/2014 at 07:45, xxxxxxxx wrote:
Well...I'm doing something very wrong then.
If I save the object and doc into class variables then C4D locks up and hangs!!
It does the same thing whether I do it in the Draw() or the Message() methods.Exaple:
class SimpleTag : public TagData { INSTANCEOF(SimpleTag,TagData) public: BaseDocument *mydocument; //<--- Saved variables BaseObject *myobject; virtual Bool Message(GeListNode *node, LONG type, void *t_data); virtual Bool Init(GeListNode *node); virtual Bool GetDDescription(GeListNode *node, Description *description,DESCFLAGS_DESC &flags); virtual Bool GetDParameter(GeListNode *node, const DescID &id,GeData &t_data,DESCFLAGS_GET &flags); virtual Bool SetDParameter(GeListNode *node, const DescID &id,const GeData &t_data,DESCFLAGS_SET &flags); virtual Bool Draw(BaseTag* tag, BaseObject* op, BaseDraw* bd, BaseDrawHelp* bh); virtual EXECUTIONRESULT Execute(BaseTag *tag, BaseDocument *doc, BaseObject *op, BaseThread *bt, LONG priority, EXECUTIONFLAGS flags); virtual void Free(GeListNode *node); static NodeData *Alloc(void) { return gNew SimpleTag; } }; Bool SimpleTag::Draw(BaseTag *tag, BaseObject *op, BaseDraw *bd, BaseDrawHelp *bh) { mydocument = GetActiveDocument(); myobject = tag->GetObject(); //...other code here return TRUE; } void SimpleTag::Free(GeListNode *node) { GePrint(myobject->GetName()); //<--This prints the name of the object...But it also makes C4D hang! return; }
I thought we weren't allowed to grab the object from the tag while the tag is being freed. But you guys seem to have found a way to do it.
Can you please explain how you're doing that?-ScottA
-
On 11/06/2014 at 08:35, xxxxxxxx wrote:
Howdy,
Originally posted by xxxxxxxx
Well...I'm doing something very wrong then.
void SimpleTag::Free(GeListNode *node) { GePrint(myobject->GetName()); //<--This prints the name of the object...But it also makes C4D hang! return; }
Your code is not checking to see if the "myobject" pointer is valid.
Try this:
void SimpleTag::Free(GeListNode *node) { if(!myobject) GePrint("myobject is NULL"); else GePrint(myobject->GetName()); }
You'll find that it prints to the console twice. The first time it prints the name of the object and the second time it prints "myobject is NULL".
Adios,
Cactus Dan -
On 11/06/2014 at 08:48, xxxxxxxx wrote:
Inside the Draw method we already have op as one of the provided parameters.
So, I simply do this:BaseDocument *doc=(BaseDocument* ) op->GetDocument();
doc_store=doc;
op_store=op;doc_store and op_store are the private variables.
Inside the Message method I only get GeListNode* node, besides type and data. Of course I could get the object and document out of the node but is there any advantage of getting those inside the Message instead of Draw?
-
On 11/06/2014 at 09:03, xxxxxxxx wrote:
Howdy,
Originally posted by xxxxxxxx
...but is there any advantage of getting those inside the Message instead of Draw?...
Well, either place will work, but the Message() function gets called after everything else has been evaluated, so it's kind of set up to be the function for checking and setting post evaluation parameters, or at least that has been my observation. I make extensive use of the Message() function for a lot of my plugins.
Adios,
Cactus Dan -
On 11/06/2014 at 09:08, xxxxxxxx wrote:
It is good to know that, Dan. Thank you.
I will centralize the storing of variables there.
Now, I only need to deal with the BackfaceCulling problem -
On 11/06/2014 at 09:14, xxxxxxxx wrote:
Thanks a lot guys. I didn't think this sort of thing was allowed.
With those class variables in place. I can now unhide the polygons of the tag object if it's deleted.void SimpleTag::Free(GeListNode *node) { //UnHide all polygons if the tag is deleted from the object if(myobject) { myobject->SetBit(BIT_ACTIVE); //Selects the object first ModelingCommandData cd; cd.doc = GetActiveDocument(); cd.op = GetActiveDocument()->GetActiveObject(); cd.mode = MODELINGCOMMANDMODE_POLYGONSELECTION; cd.flags = MODELINGCOMMANDFLAGS_0; SendModelingCommand(MCOMMAND_UNHIDE, cd); } }
But it would be nice if we could do this without selecting the object.
I guess that's what Rui was asking how to do?-ScottA
-
On 11/06/2014 at 09:18, xxxxxxxx wrote:
The object doesn't need to be selected, Scott.
It is all working fine now.
My problem was with the crash, that was due to the inability of getting the object and document from within the Free method. But, with the private variables, it was solved. -
On 11/06/2014 at 09:27, xxxxxxxx wrote:
It's not working for me unless I select the object first.
But I'm also currently not making any use of the "mydocument" class member variable.
Could I see how you're using that one?-ScottA
*Edit* Doh! - Never mind.
I just realized that I'm not using my class variables in my SMC code. No wonder.
*A giant metal anval falls from the sky and hits Scott on the head* -
On 11/06/2014 at 09:33, xxxxxxxx wrote:
This is the content of my Free method:
if (!op_store || !doc_store) return; ModelingCommandData cd; cd.doc = doc_store; cd.op = op_store; cd.mode = MODELINGCOMMANDMODE_POLYGONSELECTION; cd.flags = MODELINGCOMMANDFLAGS_0; cd.arr=NULL; SendModelingCommand(MCOMMAND_UNHIDE, cd); EventAdd(); return;