Storing baselinks



  • On 20/08/2013 at 13:42, xxxxxxxx wrote:

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

    ---------
    Hi Folks,

    I made a new topic here a few hours a go, but it seems to have disappeared. So my apologies if a similar topic turns up somewhere later...

    I'm trying to make a vector of BaseLinks. The way I've been attempting to is like this:

      
    struct MyStruct   
    {   
        std::vector< std::vector < BaseLink > >    LinkList;   
    }MStr;   
    // deliberate two stage vector...   
    

    The above compiles, but when I try variations of BaseLink/BaseList2D like this:

      
    // below assumes the vector is made/sized correctly somewhere/somehow   
    BaseList2D *ListedObj;   
    ListedObj = MStr.LinkList[1][1].GetLink(doc);   
    

    it gives me a compile error that says this:

      
    'BaseLink::BaseLink' : cannot access private member declared in class 'BaseLink'   
    

    Is it possible to make a vector of baselinks? I know the first code snippet compiles - but is that safe and OK? I haven't used vectors in this way before - though I've used std::vectors for basic things like LONG/Real/String etc.

    Is it possible with a BaseLink? Do I need to Alloc() each vector somehow when making/resizing the vector?

    Regards,

    WP.



  • On 20/08/2013 at 23:43, xxxxxxxx wrote:

    Hi,

    You should always use c4d_misc::BaseArray (or any other array/list class of the c4d_misc namespace) with CINEMA 4D API types and classes.



  • On 20/08/2013 at 23:51, xxxxxxxx wrote:

    Yes, don't use any std:: stuff if you can prevent it.



  • On 21/08/2013 at 02:57, xxxxxxxx wrote:

    Agree with Yannick and c4dJack.



  • On 21/08/2013 at 03:56, xxxxxxxx wrote:

    Thanks folks,

    I thought I'd read somewhere that the std library was much faster than the in built arrays etc, and was particularly noticeable with large data counts. Thinking about it now though, I'm not sure if it was c4d elements timed against the std library, or just the various std library methods timed against each other. But I recall for example, the std::vector was much faster than what the other ways were with large data - which was why I think I went down the std library route.

    I'll have a poke about and see if I can find where I read that to seek some clarification for myself.

    In the meantime, is there going to be a fundamental difference between working with the std library and cinema's in built ways? Or is it just not safe to work between the std library and Cinema's things?

    WP.

    EDIT: small update to text.



  • On 21/08/2013 at 04:46, xxxxxxxx wrote:

    Maybe you're thinking about GeDynamicArray, GeAutoDynamicArray and GeSafeDynamicArray old array classes.

    c4d_misc namespace and its BaseArray, BaseList, BlockArray, SortedArray, PointerArray, HashMap etc. classes were added in release 14 of CINEMA. These array and map classes are incredibly fast and safer to use with CINEMA 4D types and classes than STL.

    c4dJack (a programmer in the CINEMA 4D development team) recently posted a benchmark comparing GeDynamicArray and BaseArray:
    https://plugincafe.maxon.net/topic/7185/8213_storing-objects-in-a-list&PID=34166#34166



  • On 21/08/2013 at 07:41, xxxxxxxx wrote:

    Hi Yannick,

    that link seems familiar with what I thought I'd read. Though one query I have is what to use if I'm wanting to keep the plugin backwards compatible to R12?

    This isn't a necessity - and I don't think I'll worry about anything further back than that. It's more just a safety net I'd like to keep if I can.

    WP.



  • On 22/08/2013 at 00:51, xxxxxxxx wrote:

    Don't be too much concerned about speed issues. Dealing with BaseLinks needs some additional cycles anyways. Jacks Benchmark is cool, but it ignores everything else that would normally happen in a program.

    I guess the old GeDynamicArray classes are okay to use. Perhaps actually use GeAutoDynamicArray. The new c4d_mics::... stuff looks great though :)
    No need for std::vector!

    One thing to watch out for is: The error message in the OP is triggered because BaseLinks have a private copy constructor. You have to use a copy method instead (also allocate with Alloc method). The c4d Array classes must have a way to deal with this in a nice way. I never had Arrays of Alloc'ed classes so i can't tell exactly.



  • On 22/08/2013 at 05:54, xxxxxxxx wrote:

    Thanks Michael,

    I wasn't overly concerned with speed generally, but the difference between some seemed as though they may be noticeable if parts of my plugin required big data counts (which will be user/object specific).

    Re the above, I'm having second thoughts on this. Is there another way to store a link to an object? I first started with GetGUID, but as that was new to R14 I was hoping to find something a little more backwards compatible (back to R12 if possible - though not entirely necessary). Is there an example of getting an object by an ID somewhere I could look at?

    What's GeMarker() used for too?

    WP.



  • On 22/08/2013 at 08:55, xxxxxxxx wrote:

    It looks like the old arrays allocated space in fixed increments and the new ones allocate a multiple of the *current* size when they run out of space, which is what makes them fast. You can preallocate or set the increment "block" if you need to.

    Baselinks give you pointers fast and easy, the other options not - just names basically. GeMarker - i don't know. Never used it. There is GetMarkerStampEx also. Probably getting an object from an ID would incur a speed hit due to the search that has to be made then. You have to decide.

    Look up "Big O notation" if you don't know it already.

    Btw. I just found c4d_baselinkarray.h while searching for GeDynamicArray in the R12 API. It is not documented.



  • On 22/08/2013 at 09:12, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Btw. I just found c4d_baselinkarray.h while searching for GeDynamicArray in the R12 API. It is not documented.

    Yes this class can come in handy. For pre-R14 it was using GeTempDynArray (another undocumented array class, there are actually a lot in the API...) and for post-R14 it is using BaseArray:

    Pre-R14:

    class BaseLinkArray : public GeTempDynArray<BaseLink>
    

    Post-R14:

    class BaseLinkArray : public maxon::BaseArray<BaseLink*>
    


  • On 22/08/2013 at 09:30, xxxxxxxx wrote:

    Why are these undocumented?



  • On 22/08/2013 at 12:04, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Jacks Benchmark is cool, but it ignores everything else that would normally happen in a program.

    For example?

    Originally posted by xxxxxxxx

    I guess the old GeDynamicArray classes are okay to use. Perhaps actually use GeAutoDynamicArray.

    GeAutoDynamicArray is the absoutely slowest array class you can use, especially if you have many Pushs and Pops. Even slower than GeDynamicArray. Read the benchmark again ;-)

    The only the thing that GeDynamicArray is faster with than the BaseArray is Insert. If you're going to make many Inserts (especially if you insert at lower indexes, or even at index 0), have a look at the BlockArray class. Both classes, by the way, are fully interchangeable, so you can use either of them depending on the situation.



  • On 22/08/2013 at 12:25, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Why are these undocumented?

    The are not. Search for "BaseArray" in the R14 SDK docs and you'll find them.
    They are, however, missing in the index... don't ask me why ;-) But with the search you'll find them. They can also be found using the Contents structure (c4d_misc) or by taking a look into the article "Changes in the SDK" -> "Changes since 13.058".



  • On 23/08/2013 at 00:48, xxxxxxxx wrote:

    Sorry, My mistake i just searched the index.

    And, alright ... sure the old Arrays are super slow.

    But assuming that you want R12 compatibility, and if you can perhaps even preallocate storage or guess the number of items approximately, or just have low number of items, then IMO the old arrays are okay to use. For R12 compatibility there are not many options left anyways ...

    Also, sorry, i was mislead by the "Auto" in GeAutoDynamicArray thinking that it was specially made to deal with API object just like AutoAlloc. But it isn't! One should always check! :(



  • On 23/08/2013 at 03:54, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Pre-R14:

    class BaseLinkArray : public GeTempDynArray<BaseLink>
    

    Post-R14:

    class BaseLinkArray : public maxon::BaseArray<BaseLink*>
    

    This means I can (and should) use BaseLinkArray instead of c4d_misc::BaseArray,? 
    Because C4D will take care if it in the background, depending on compiling for R13 or R14?



  • On 23/08/2013 at 04:03, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Originally posted by xxxxxxxx

    Pre-R14:

    class BaseLinkArray : public GeTempDynArray<BaseLink>
    

    Post-R14:

    class BaseLinkArray : public maxon::BaseArray<BaseLink*>
    

    This means I can (and should) use BaseLinkArray instead of c4d_misc::BaseArray,? 
    Because C4D will take care if it in the background, depending on compiling for R13 or R14?

    Exactly if BaseLinkArray fits your needs.


Log in to reply