Using C4D_Falloff



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

    On 04/01/2007 at 16:44, xxxxxxxx wrote:

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

    ---------
    Hello,

    how is the C4D_Falloff class used for own purposes? The interface correctly shows up.

    I am calling the appropriate counterparts like Draw and Message, but the falloff region is not drawn (I always get the "Unlimited" stuff drawn, even when it´s set to cube for example. So it draws something already, but changes are not noticed. :-/

    This is in a Particle Modifier object.

    I call InitFalloff in my Init function. I pass all parameters necessary. Btw. all my falloff parameters are uninitialised. Do I have to initialise them myself? I looked into "ofalloff_panel.h" but there aren´t the necessary IDs available.

    I also check if the falloff is dirty in my ModifyParticles function and if it is, I call InitFalloff again. I am absolutely not sure if this is the correct location. The docs are very sparse in this area. So any info for this would also be very helpful.

    ANY help is appreciated!

    Here is some test code of the important parts. Actually straightforward to implement (good work on this SDK part), but doesn´t work anyway for me. :-(

    Bool TestModifier::Draw(PluginObject *op, LONG drawpass, BaseDraw *bd, BaseDrawHelp *bh)  
    {  
         falloff->Draw(bd,bh,0,op->GetDataInstance());  
         return TRUE;  
    }  
      
    Bool TestModifier::Message(GeListNode *node, LONG type, void *data)  
    {  
         falloff->Message(type, ((BaseObject* )node)->GetDataInstance(), data);  
         return TRUE;  
    }
    

    Thank you!



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

    On 06/01/2007 at 04:48, xxxxxxxx wrote:

    anybody? SUPPORT?? I can almost here an echo...



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

    On 08/01/2007 at 04:46, xxxxxxxx wrote:

    I am on it, but I still have to wait for some answers from the developers as well.

    cheers,
    Matthias



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

    On 08/01/2007 at 05:37, xxxxxxxx wrote:

    ok, thx



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

    On 16/01/2007 at 07:14, xxxxxxxx wrote:

    So, any info from the devs? I want to release DPIT on 26. January and I cannot wait much longer.



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

    On 16/01/2007 at 10:52, xxxxxxxx wrote:

    I have some problems to get the falloff shapes drawn myself. I still have to clarify some things with the devs. As for the initialization of the description, this code sample should help you I hope:

      
    Bool Gravitation::GetDDescription(GeListNode *node, Description *description, LONG &flags;)  
    {  
         BaseContainer *bc = ((PluginObject* )node)->GetDataInstance();  
         if (!bc) return FALSE;  
      
         if (myfalloff)  
         {  
              if (!myfalloff->SetMode(bc->GetLong(FALLOFF_MODE,FALLOFF_MODE_INFINITE),bc)) return FALSE;     //Makes sure that the falloff is inited enough to have an interface and default setup, also sets up the basecontainer settings to match our falloff (needed for scale etc).  
              if(!myfalloff->AddFalloffToDescription(description, NULL)) return FALSE;  
         }  
         flags |= DESCFLAGS_DESC_LOADED;  
         return SUPER::GetDDescription(node,description,flags);  
    }  
    

    cheers,
    Matthias



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

    On 16/01/2007 at 12:19, xxxxxxxx wrote:

    Hi,

    thanks first of all for this! Hopefully we can resolve this before 26th. Will try the initialisatin routine.

    Samir



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

    On 16/01/2007 at 18:27, xxxxxxxx wrote:

    I've been trying to add falloff to a new deformer that I am developing and have been unseccessfull in getting the falloff to just draw in the viewport.
    I've been told that I should use the C4D_falloff class to add falloff to my deformer. But the Cinema SDK also has the FalloffData class. Should I be using this class in combination with the C4D_falloff class? Whats the difference between the two? Or should I be using just the FalloffData class?



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

    On 17/01/2007 at 01:33, xxxxxxxx wrote:

    FalloffData is a class for creating additional falloff types. Take a look at the Randomfalloff example in the SDK.

    cheers,
    Matthias



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

    On 17/01/2007 at 10:55, xxxxxxxx wrote:

    The SetMode function call doesn´t help at all unfortunately. :-/
    It doesn´t change anything, my values are still uninitialised. I honestly see no reason why this should help me initialising the description values.

    My values are still uninitialised, still no bounds preview except for infinity.

    So still hoping for a solution on both issues asap.



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

    On 02/03/2007 at 12:36, xxxxxxxx wrote:

    I would recommend disabling any code dealing with the objects handle interface. I remember that in order to get the display of the falloff I wasn't creating the handles for my deformer correctly, so it would not display but it would function correctly. Try the C4D_Falloff::GetData(void) to get a struct of all the data found within the Falloff tab of your object. More than likely it will be returning the correct data but its not be drawn due to something stupid with the handle functions. I'm 95% sure this was the problem, but I don't remember exactly being that I tried a ton of different things to get the falloff to work correctly.
    But here is some additional info that I got from Per-Anders (programmer who I believe wrote the class) :
    Hi Per,
    I know you're really busy so I'll make this short. I'm writing a deformer for Cinema and I need to incorporate falloff into the deformer. I've never calculated something like that and haven't been able to find any sites that help to understand the math behind falloff. So I was wondering if you have any sites that you know of which will help to understand and solve this. Thanks in advance for any help and direction.
    __
    Regards,
    Josh
    __
    The C4D_Falloff class is what you want to use. It's documented pretty fully. All you have to do is in your deformers GetDDescription, use the "AddFalloffToDescription" routine, then in Message add the likewise called Message call in the falloff, same in GetHandleCount, GetHandle, SetHandle, Draw and CopyTo (your deformer will need these functions for the falloff to work fully), then before calling the "Sample" routine make sure to call the "InitFalloff" routine, samples are in world space so you'll have to multiply them out but that's it really.
    __
    You can add your own additional falloffs to it using the FalloffData plugin type (these falloffs would then be added to all falloff using tools in C4D, so that's MoGraph and Mocca currently till we get the universal falloff into the particle modifiers), there's an example of using this in the SDK.
    __
    Falloffs themselves are very simple to generate/calculate, from any point it's just a distance function between two points, normalised by a user specified length.
    _ _
    __
    So the interface shows up correctly in the attributes manager. But even though I am calling the C4D_Falloff- >Draw() funtion from within my ObjectData::Draw() function nothing gets drawn in the viewport. Is there a specific point at which the C4D_Falloff object needs to allocated, such as in the ObjectData::ModifyObject(). Even in the DropEffector example within the SDK the only thing that really happens is that the C4D_Falloff is allocated from the EffectorData::GetFalloff(). Nothing is really initialized within the example, but the falloff works / drawn correctly. As always, thanks in advance for any help.
    __
    It should be allocated locally to your object at object initialisation, i.e. just use a AutoAlloc:
    __
    class MyObject : public SomeData
    {
    public:
    AutoAlloc <C4D_Falloff>falloff;
    ...
    }
    __
    you then must initialise it before using it or drawing it, this is a very fast routine, however for speed you want to keep down the number of initialisations as much as possible, otherwise it has no matrix, it also handles it's own draw passes, so pass it the flag from the draw routine (and don't filter any draw passes). you may wish to also set the mode in the getddescription in order to make sure that when it comes up the first time it has the correct interface.
    __ 
    Hopefully this helps some
    Josh



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

    On 03/03/2007 at 09:48, xxxxxxxx wrote:

    Hi Josh,

    thx but I haven´t used the handles in the first place but it still doesn´t work for me.

    I only want the falloff region to be visible and to be changeable. I know this info from Per too, but this doesn´t help me.

    I still always only get the "infinite" falloff to be shown in the viewport. It should be simple as one only has to overload the according function calls in the according methods of my object class (as seen in my referenced thread).

    Can you post the snippets? It should all be only 1-liner calls according to the SDK docs, like

    MyTest::Message(...) { falloff->Message(...);}

    (same for the other functions one wants to use. Do you get initialised settings in the AM in the falloff description?)

    thanks
    SAmir



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

    On 21/05/2007 at 23:59, xxxxxxxx wrote:

    Maxon devs finally showed us how to do it:

      
    Here's an example of the falloff in action in a normal object, taken from the morphdeformer object.  
      
    //Header file  
      
    #include "c4d.h"  
    #include "c4d_falloffdata.h"  
      
    class MorphDeformer : public ObjectData  
    {  
    private:  
         AutoAlloc<C4D_Falloff>falloff;  
    public:  
         virtual Bool          Init(GeListNode *node);  
      
         virtual Bool          Draw(PluginObject *op, LONG drawpass, BaseDraw *bd, BaseDrawHelp *bh);  
         virtual LONG          GetHandleCount(PluginObject *op);  
         virtual Vector          GetHandle(PluginObject *op, LONG i);  
         virtual void          SetHandle(PluginObject *op, LONG i, Vector p);  
      
         virtual Bool          GetDDescription(GeListNode *node,Description *description,LONG &flags;);  
      
         virtual LONG          Execute(PluginObject *op,BaseDocument *doc,BaseThread *bt,LONG priority,LONG flags);  
         virtual Bool          AddToExecution(PluginObject *op, PriorityList *list) { list->Add(op, EXECUTION_GENERATOR, -100); return TRUE; }  
      
         virtual Bool          CopyTo(NodeData *dest, GeListNode *snode, GeListNode *dnode, LONG flags, AliasTrans *trn);  
      
         virtual Bool          ModifyObject(PluginObject *mod, BaseDocument *doc, BaseObject *op, const Matrix &op;_mg, const Matrix &mod;_mg, Real lod, LONG flags, BaseThread *thread);  
      
         static NodeData* Alloc(void) { return gNew MorphDeformer; }  
    };  
      
      
    //C++ file  
      
    #include "morphdeformer.h"  
    #include "ge_dynamicarray.h"  
      
    Bool MorphDeformer::Init(GeListNode *node)  
    {  
         if (!node || !falloff) return FALSE;  
      
         PluginObject *op = (PluginObject* )node;  
         BaseContainer *bc = op->GetDataInstance();  
         if (!bc) return FALSE;  
      
         bc->SetReal(MORPHDEFORMER_STRENGTH, 1.0f);  
      
         if (!falloff->InitFalloff(bc,NULL,op)) return FALSE;  
      
         return TRUE;  
    }  
      
    Bool MorphDeformer::Draw(PluginObject *op, LONG drawpass, BaseDraw *bd, BaseDrawHelp *bh)  
    {  
         if (!op->GetDeformMode()) return TRUE;  
      
         BaseContainer *bc = op->GetDataInstance();  
         if (!bc) return FALSE;  
      
         if (falloff) falloff->Draw(bd, bh, drawpass, bc);  
      
         return ObjectData::Draw(op, drawpass, bd, bh);  
    }  
      
    LONG MorphDeformer::GetHandleCount(PluginObject *op)  
    {  
         BaseContainer *bc = op->GetDataInstance();  
         if (!bc) return 0;  
         if (falloff) return falloff->GetHandleCount(bc);  
         return 0;  
    }  
      
    Vector MorphDeformer::GetHandle(PluginObject *op, LONG i)  
    {  
         BaseContainer *bc = op->GetDataInstance();  
         if (!bc) return 0.0;  
         if (falloff) return falloff->GetHandle(i,bc);  
         return 0.0;  
    }  
    void MorphDeformer::SetHandle(PluginObject *op, LONG i, Vector p)  
    {  
         BaseContainer *bc = op->GetDataInstance();  
         if (!bc) return;  
         if (falloff) falloff->SetHandle(i,p,bc);  
    }  
      
    LONG MorphDeformer::Execute(PluginObject *op,BaseDocument *doc,BaseThread *bt,LONG priority,LONG flags)  
    {  
         BaseContainer *bc = op->GetDataInstance();  
         if (!bc) return FALSE;  
      
         if (falloff)  
              if (!falloff->InitFalloff(bc,doc,op)) return EXECUTION_RESULT_MEMORYERROR;  
      
         return EXECUTION_RESULT_OK;  
    }  
      
    Bool MorphDeformer::GetDDescription(GeListNode *node,Description *description,LONG &flags;)  
    {  
         BaseObject *op = (BaseObject* ) node;  
         if (!op) return FALSE;  
         BaseContainer *bc = op->GetDataInstance();  
         if (!bc) return FALSE;  
      
         if (!description->LoadDescription(op->GetType())) return FALSE;  
           
         //---------------------------------  
         //Add the falloff interface  
         if (falloff)  
         {  
              if (!falloff->SetMode(bc->GetLong(FALLOFF_MODE,FALLOFF_MODE_INFINITE),bc)) return FALSE;     //The falloff parameters have to have been setup before it can be added to the description, this like makes sure of that  
              if (!falloff->AddFalloffToDescription(description,bc)) return FALSE;  
         }  
      
         flags |= DESCFLAGS_DESC_LOADED;  
      
         return TRUE;  
    }  
      
    Bool MorphDeformer::CopyTo(NodeData *dest, GeListNode *snode, GeListNode *dnode, LONG flags, AliasTrans *trn)  
    {  
         MorphDeformer *df = (MorphDeformer* ) dest;  
         if (!df) return FALSE;  
      
         if (falloff && df->falloff)   
              if (!falloff->CopyTo(df->falloff)) return FALSE;  
      
         return ObjectData::CopyTo(dest,snode,dnode,flags,trn);  
    }  
      
    Bool MorphDeformer::ModifyObject(PluginObject *mod, BaseDocument *doc, BaseObject *op, const Matrix &op;_mg, const Matrix &mod;_mg, Real lod, LONG flags, BaseThread *thread)  
    {  
         if (!op->IsInstanceOf(Opoint) || !falloff) return TRUE;  
      
         BaseContainer *bc = mod->GetDataInstance(), *bbc = NULL;  
         if (!bc) return TRUE;  
      
         Vector *padr = ToPoint(op)->GetPointW();     //Assuming we will be writing to the points in op here, otherwise use const and GetPointR for speed  
         LONG      pcnt = ToPoint(op)->GetPointCount(),  
              i = 0;  
      
         if (!padr || pcnt == 0) return TRUE;  
      
         Real     res = 0.0,  
              strength = bc->GetReal(MORPHDEFORMER_STRENGTH);  
      
         GeDynamicArray<Real>fall(pcnt);  
         if (!fall) return FALSE;     //Memory error  
      
         Real     *weight = ToPoint(op)->CalcVertexMap(mod);  
      
         if (weight) //Always test that weight exists before using it  
         {  
         for (i = 0; i < pcnt && (!thread || !thread->TestBreak()); i++)  
         {  
              Vector pp =padr _* op_mg;/*Position to sample in world space*/  
              falloff->Sample(pp, &res;);          //Init has to have been called before using this, here it's done in the "execute" routine for speed, though it takes next to zero time to actually run init as all it's doing is setting a few variables from the objects container.  
              fall _= res * weight _* strength;  
         }  
         }  
         else  
         {  
         for (i = 0; i < pcnt && (!thread || !thread->TestBreak()); i++)  
         {  
              Vector pp =padr _* op_mg;/*Position to sample in world space*/  
              falloff->Sample(pp, &res;);  
              fall _= res * strength;  
         }  
         }  
      
         GeFree(weight);  
      
         //Do something using the resulting fall array to the points in op  
         /*..................  
      
      
         .....................*/  
           
         op->Message(MSG_UPDATE);  
      
         return TRUE;  
    }  
      
      
    you will also need to check the dirty status for the source mode.  
      
    void mydeformer::CheckDirty(PluginObject *op, BaseDocument *doc)  
    {  
           
    if (falloff)  
    {  
         BaseContainer *bc = op->GetDataInstance()  
         if (!bc) return;  
         LONG dirty = falloff->GetDirty(bc);  
         if (dirty==lastdirty) return;  
    op->SetDirty(DIRTY_DATA);  
         lastdirty = dirty;  
    }  
      
    }  
    



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

    On 22/05/2007 at 03:33, xxxxxxxx wrote:

    Hi Michael,

    thanks for your dedication. Finally! :)



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

    On 22/05/2007 at 07:19, xxxxxxxx wrote:

    Hi hi you could have asked, too ;-)
    Btw. this example doesn't actually work for me. Execute is never called. However apparently the idea is to call falloff->Init whenever the user changes something, via gui or handles. I'll try to put it in SetHandle, and SetParamter. This will hopefully work.



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

    On 23/05/2007 at 02:37, xxxxxxxx wrote:

    Okay, i just forgot to add the AddToExecution function. It works pretty well now.


Log in to reply