| Author |
Share Topic Topic Search Topic Options
|
kuroyume0161
Member
Joined: 2002 Oct 29
Location: United States
Online Status: Offline
Posts: 2639
|
Post Options
Quote Reply
Topic: ActiveObject, but only certain objects? Posted: 2006 Nov 12 at 9:21pm |
User Information: Cinema 4D Version: 8.2-10.0
Platform: Windows ; Mac ;
Mac OSX ;
Language(s):
C++ ;
--------- I'm setting up a dialog that uses the basic structure of 'ActiveObject.cpp' from the cinema4dsdk. But instead of just mirroring the Object Manager, I'd like to only show certain objects (that contain my plugin's tag).
How would one go about this?
Should I be doing some checking/restricting in the TreeViewFunctions GetFirst(), GetNext(), GetPred(), GetDown() methods?
Thanks!
|
|
|
 |
kuroyume0161
Member
Joined: 2002 Oct 29
Location: United States
Online Status: Offline
Posts: 2639
|
Post Options
Quote Reply
Posted: 2006 Nov 12 at 9:47pm |
Well, trying something that seemed logical, was, hmm, logical. :)
void* GetFirst(void* root, void* userdata)
{
BaseDocument* doc = (BaseDocument*)root;
return GetObject(doc->GetFirstObject());
}
void* GetNext(void* root, void* userdata, void* obj)
{
BaseObject* op;
for (op = ((BaseObject*)obj)->GetNext(); op; op = op->GetNext())
{
if (op->GetTag(ID_IPPFIGURETAG) || op->GetTag(ID_IPPOBJECTTAG)) break;
}
return op;
}
void* GetPred(void* root, void* userdata, void* obj)
{
BaseObject* op;
for (op = ((BaseObject*)obj)->GetPred(); op; op = op->GetPred())
{
if (op->GetTag(ID_IPPFIGURETAG) || op->GetTag(ID_IPPOBJECTTAG)) break;
}
return op;
}
void* GetDown(void* root, void* userdata, void* obj)
{
return GetObject(((BaseObject*)obj)->GetDown());
}
void* GetObject(BaseObject* op)
{
BaseObject* down;
for (op; op; op = op->GetNext())
{
if (op->GetTag(ID_IPPFIGURETAG) || op->GetTag(ID_IPPOBJECTTAG)) return op;
if (op->GetDown())
{
if (down = (BaseObject*)GetObject(op->GetDown())) return down;
}
}
return NULL;
}
|
This code only shows Objects with the two restrictive tags - no matter where they reside. Cool! :)
|
|
|
 |
Matthias Bober
Forum Moderator
Joined: 2006 Oct 16
Location: Germany
Online Status: Offline
Posts: 1644
|
Post Options
Quote Reply
Posted: 2006 Nov 13 at 1:04am |
|
Thanks for sharing your findings.
cheers,
Matthias
|
|
MAXON
developer support
|
 |
kuroyume0161
Member
Joined: 2002 Oct 29
Location: United States
Online Status: Offline
Posts: 2639
|
Post Options
Quote Reply
Posted: 2006 Nov 13 at 2:20pm |
|
Looks like I spoke too soon. Some OM hierarchy arrangements will not work with this filtering. I'm exploring alternatives (especially now that the filtering has been expanded). A 'filtered' AtomArray may be the only real approach to a sparse hierarchy - the result will be a list in the TreeView though (only GetFirst(), GetNext(), GetPred()).
|
|
|
 |
kuroyume0161
Member
Joined: 2002 Oct 29
Location: United States
Online Status: Offline
Posts: 2639
|
Post Options
Quote Reply
Posted: 2006 Nov 13 at 4:27pm |
Alrighty then. This set works, but it is very loop/recursion oriented so as to traverse every possible branch no matter the filter settings or hierarchical arrange - as best as can be tested.
Note that the filter Booleans are being set in the dialog. I'm being lazy about hiding the variables and using setters instead.
BOOL filterFigures;
BOOL filterProps;
BOOL filterCameras;
BOOL filterLights;
BOOL filterBases;
void* GetFirst(void* root, void* userdata)
{
return FindFirst(((BaseDocument*)root)->GetFirstObject());
}
void* GetDown(void* root, void* userdata, void* obj)
{
return FindDown(((BaseObject*)obj)->GetDown());
}
void* GetNext(void* root, void* userdata, void* obj)
{
BaseObject* op;
op = ((BaseObject*)obj)->GetNext();
if (op)
{
BaseObject* next = FindDown(op);
if (next) return next;
}
op = ((BaseObject*)obj)->GetUp();
if (op)
{
BaseObject* next = FindNext(op);
if (next) return next;
}
return NULL;
}
void* GetPred(void* root, void* userdata, void* obj)
{
BaseObject* op;
op = ((BaseObject*)obj)->GetPred();
if (op)
{
BaseObject* pred = FindDownPred(op);
if (pred) return pred;
}
op = ((BaseObject*)obj)->GetUp();
if (op)
{
BaseObject* pred = FindPred(op);
if (pred) return pred;
}
return NULL;
}
// *** START Helpers
BaseObject* FindFirst(BaseObject* op)
{
BaseObject* down;
for (op; op; op = op->GetNext())
{
if (op->GetTag(ID_IPPFIGURETAG) && filterFigures) return op;
else if (op->GetTag(ID_IPPOBJECTTAG) && ((op->IsInstanceOf(Opolygon) && filterProps) || (op->IsInstanceOf(Ocamera) && filterCameras) || (op->IsInstanceOf(Olight) && filterLights))) return op;
else if (op->IsInstanceOf(ID_IPPBASE) && filterBases) return op;
if (!op->GetDown()) continue;
down = FindFirst(op->GetDown());
if (down) return down;
}
return NULL;
}
BaseObject* FindDown(BaseObject* op)
{
BaseObject* down;
for (op; op; op = op->GetNext())
{
if (op->GetTag(ID_IPPFIGURETAG) && filterFigures) return op;
else if (op->GetTag(ID_IPPOBJECTTAG) && ((op->IsInstanceOf(Opolygon) && filterProps) || (op->IsInstanceOf(Ocamera) && filterCameras) || (op->IsInstanceOf(Olight) && filterLights))) return op;
else if (op->IsInstanceOf(ID_IPPBASE) && filterBases) return op;
if (!op->GetDown()) continue;
down = FindDown(op->GetDown());
if(down) return down;
}
return NULL;
}
BaseObject* FindDownPred(BaseObject* op)
{
BaseObject* down;
for (op; op; op = op->GetPred())
{
if (op->GetTag(ID_IPPFIGURETAG) && filterFigures) return op;
else if (op->GetTag(ID_IPPOBJECTTAG) && ((op->IsInstanceOf(Opolygon) && filterProps) || (op->IsInstanceOf(Ocamera) && filterCameras) || (op->IsInstanceOf(Olight) && filterLights))) return op;
else if (op->IsInstanceOf(ID_IPPBASE) && filterBases) return op;
if (!op->GetDown()) continue;
down = FindDown(op->GetDown());
if(down) return down;
}
return NULL;
}
BaseObject* FindNext(BaseObject* op)
{
BaseObject* down;
BaseObject* obj;
for (op; op; op = op->GetUp())
{
for (obj = op->GetNext(); obj; obj = obj->GetNext())
{
if (obj->GetTag(ID_IPPFIGURETAG) && filterFigures) return obj;
else if (obj->GetTag(ID_IPPOBJECTTAG) && ((obj->IsInstanceOf(Opolygon) && filterProps) || (obj->IsInstanceOf(Ocamera) && filterCameras) || (obj->IsInstanceOf(Olight) && filterLights))) return obj;
else if (obj->IsInstanceOf(ID_IPPBASE) && filterBases) return obj;
if (obj->GetDown())
{
down = FindDown(obj->GetDown());
if(down) return down;
}
}
}
return NULL;
}
BaseObject* FindPred(BaseObject* op)
{
BaseObject* down;
BaseObject* obj;
for (op; op; op = op->GetUp())
{
for (obj = op->GetPred(); obj; obj = obj->GetPred())
{
if (obj->GetTag(ID_IPPFIGURETAG) && filterFigures) return obj;
else if (obj->GetTag(ID_IPPOBJECTTAG) && ((obj->IsInstanceOf(Opolygon) && filterProps) || (obj->IsInstanceOf(Ocamera) && filterCameras) || (obj->IsInstanceOf(Olight) && filterLights))) return obj;
else if (obj->IsInstanceOf(ID_IPPBASE) && filterBases) return obj;
if (obj->GetDown())
{
down = FindDown(obj->GetDown());
if(down) return down;
}
}
}
return NULL;
}
// *** END Helpers
|
|
|
|
 |
kuroyume0161
Member
Joined: 2002 Oct 29
Location: United States
Online Status: Offline
Posts: 2639
|
Post Options
Quote Reply
Posted: 2006 Nov 30 at 6:34pm |
One more change to FindNext() and FindPred() to make this complete. This will stop adding objects multiple times because it will have been already added by a parent as its next or predecesor. Not harmful, but boggling to work with. :)
//*---------------------------------------------------------------------------*
BaseObject* FindNext(BaseObject* op)
//*---------------------------------------------------------------------------*
{
BaseObject* down;
BaseObject* obj;
for (op; op; op = op->GetUp())
{
// This object will have already added as successor!
if (op->GetTag(ID_IPPFIGURETAG) && filterFigures) return NULL;
else if (op->GetTag(ID_IPPOBJECTTAG) && ((op->IsInstanceOf(Opolygon) && filterProps) || (op->IsInstanceOf(Ocamera) && filterCameras) || (op->IsInstanceOf(Olight) && filterLights))) return NULL;
else if (op->IsInstanceOf(ID_IPPBASE) && filterBases) return NULL;
// Keep looking
for (obj = op->GetNext(); obj; obj = obj->GetNext())
{
if (obj->GetTag(ID_IPPFIGURETAG) && filterFigures) return obj;
else if (obj->GetTag(ID_IPPOBJECTTAG) && ((obj->IsInstanceOf(Opolygon) && filterProps) || (obj->IsInstanceOf(Ocamera) && filterCameras) || (obj->IsInstanceOf(Olight) && filterLights))) return obj;
else if (obj->IsInstanceOf(ID_IPPBASE) && filterBases) return obj;
if (!obj->GetDown()) continue;
down = FindDown(obj->GetDown());
if (down) return down;
}
}
return NULL;
}
//*---------------------------------------------------------------------------*
BaseObject* FindPred(BaseObject* op)
//*---------------------------------------------------------------------------*
{
BaseObject* down;
BaseObject* obj;
for (op; op; op = op->GetUp())
{
// This object will have already added as predecessor!
if (op->GetTag(ID_IPPFIGURETAG) && filterFigures) return NULL;
else if (op->GetTag(ID_IPPOBJECTTAG) && ((op->IsInstanceOf(Opolygon) && filterProps) || (op->IsInstanceOf(Ocamera) && filterCameras) || (op->IsInstanceOf(Olight) && filterLights))) return NULL;
else if (op->IsInstanceOf(ID_IPPBASE) && filterBases) return NULL;
// Keep looking
for (obj = op->GetPred(); obj; obj = obj->GetPred())
{
if (obj->GetTag(ID_IPPFIGURETAG) && filterFigures) return obj;
else if (obj->GetTag(ID_IPPOBJECTTAG) && ((obj->IsInstanceOf(Opolygon) && filterProps) || (obj->IsInstanceOf(Ocamera) && filterCameras) || (obj->IsInstanceOf(Olight) && filterLights))) return obj;
else if (obj->IsInstanceOf(ID_IPPBASE) && filterBases) return obj;
if (!obj->GetDown()) continue;
down = FindDown(obj->GetDown());
if (down) return down;
}
}
return NULL;
}
|
|
|
|
 |