Using BaseArrays [SOLVED]
-
On 11/01/2015 at 12:12, xxxxxxxx wrote:
User Information:
Cinema 4D Version: R16
Platform: Windows ;
Language(s) :---------
So I'm transitioning a completed python plugin to C++ and C++ doesn't have easy to use dictionaries like Python. Or at least know that Maxon recommends I use in their best coding practices. That's fine, I can use a BaseArray. The question is how does one initialize a BaseArray with a set of known values. A second part to that would be how I might use a resource of some sort to load a BaseArray with values. -
On 11/01/2015 at 13:57, xxxxxxxx wrote:
In C++ dictionaries are called maps.
These are the R14 examples I have in my notes.
I haven't used these in R16 yet. So the code might need to written slightly different. But hopefully it will give you a quick boost in using them.//The HashMap array in R14++ is similar to a dictionary //Each array element has a key, and a value //The key can be used to look up the elements in the array. Instead of using element index numbers //The key and value types must bet set up when creating the HM: maxon::HashMap<type, type> myHmap; //NOTE: You can use HM->put to add new items to the array if you don't want to check if an entry already exists Example #1 maxon::HashMap<Int, String> myHmap; auto entry1 = myHmap.Put(1, "first"); // 1 is the key "first" is the value auto entry2 = myHmap.Put(2, "second"); // 2 is the key "second" is the value GePrint(entry1->GetValue()); //Or GePrint(myHmap.FindEntry(2)->GetValue()); //Find using the key (which is 2 in this example) Example #2 maxon::HashMap<Int, Float> myHmap; auto entry1 = myHmap.Put(1, 5.5); // 1 is the key 5.5 is the value auto entry2 = myHmap.Put(2, 22.4); // 2 is the key 22.4 is the value GePrint(String::FloatToString(entry1->GetValue())); //Or GePrint(String::FloatToString( myHmap.FindEntry(2)->GetValue())); //Find using the key (which is 2 in this example) //This is an example of filling a HashMap with Atom objects as the keys //Then assigning String values to them BaseObject *obj1 = doc->GetFirstObject(); if(!obj1) return false; BaseObject *obj2 = obj1->GetNext(); if(!obj2) return false; //Create a HashMap array and insert the two objects into it. And set their values as text //The key values lets us look up the items in the HashMap array maxon::HashMap<C4DAtom*, String> myHmap; maxon::Bool created = false; auto entry1 = myHmap.FindOrCreateEntry(obj1, created); if(created) entry1->SetValue("first"); auto entry2 = myHmap.FindOrCreateEntry(obj2, created); if(created) entry2->SetValue("second"); //Iterate through the HM array using an iterator //The iterator 'it' is the value of each array element for(auto it = myHmap.Begin(); it != myHmap.End(); ++it) { auto value = it; Int32 t = it->GetKey()->GetType(); //Get the type of object in the HM array String keyVal = it->GetValue(); //Get the key value in the HM for this object //We can change the keys in the HashMap if we want if (keyVal == "first") entry1->SetValue("newKeyValue"); GePrint(String::IntToString(t) + " " + keyVal); } //Print the new key value in the HashMap GePrint(entry1->GetValue());
-ScottA
-
On 11/01/2015 at 16:16, xxxxxxxx wrote:
As always thanks Scott. I saw that the standard library had maps, but I didn't know the SDK had one too. That's solid, I'll try it out.
-
On 11/01/2015 at 19:36, xxxxxxxx wrote:
I appear to have ran into another problem. Apparently the maxon string class isn't supported as a key?
Error 1 error C2039: 'GetHashCode' : is not a member of 'String'
-
On 12/01/2015 at 14:02, xxxxxxxx wrote:
Just documenting my progress for anyone else who stumbles on this. I did a workaround by using char* as the key, but FindEntry isn't matching up the char strings, still looking into that.
-
On 13/01/2015 at 13:27, xxxxxxxx wrote:
Hi eldiren,
Here's some info that I think can help you with the problems you're having with C4D's hash code:
Link in help to GetHashCode() call, takes a const Char* key and returns a static UInt:
Link to GetHashCode() call
[URL-REMOVED]Example code to create a C-String from C4D's String class:
// Create a char* null terminated C-string from a C4D String size_t keyLength = keyString.GetCStringLen(STRINGENCODING_8BIT); char* keyCharString = new char[keyLength + 1]; keyString.GetCString(keyCharString, keyLength + 1, STRINGENCODING_8BIT); // Get the hash code using keyCharString UInt hashCode = GetHashCode(keyCharString); // *** Use the hashCode value here // Delete the string when you're done, or you'll leak memory delete [] keyCharString; keyCharString = nullptr;
I hope that helps!
Joey Gaspe
SDK Support Engineer
[URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.
-
On 13/01/2015 at 17:10, xxxxxxxx wrote:
@j_gaspe Thanks for that. That's kinda what I ended up coming up with. In my put functions for the HashMap I used GetHashCode to hash the strings. Then I basically had to take to take the GetName function of a BaseObject and run GetHashCode on that and then compare it to my keys using HashMap's FindEntry function. Roundabout but it got the job done.
-
On 14/01/2015 at 06:38, xxxxxxxx wrote:
Hi eldiren,
Thanks for letting me know it worked out. I'll close the topic as being solved.
Joey Gaspe
SDK Support Engineer