How to use GetDbIndex()?
-
On 01/11/2013 at 10:11, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 13
Platform: Windows ;
Language(s) : C++ ;---------
Hi,I'm not getting the expected results from the GetDbIndex() function.
What I'm trying to do is search through the Content Browser presets (The saved items in these folders).
But that function is always returning the value of 1.How do I get the actual correct Index# for the CB items?
Without understanding how it works. And how to get a correct IndexDb#. I can't use most of the other CB functions.This example sort of works. And gets the PresetName of the object listed in the user_dir path
However. The IndexDb# seems to be wrong (it's always 1)?
I can't use it to search for the other items. Or even get the next saved item in the same folder.#include "lib_browser.h" Filename user_dir = "preset://user.lib4d/Objects/Cube"; //The URL path to the object SDKBrowser *cb = NULL; //Create a Content Browser instance cb->OpenNewBrowser(user_dir.GetString(), 0); //Notice how we use GetString() function Bool exists = cb->ExistsPreset(user_dir.GetString()); //Checks if the .lib4d object or directory exists or not GePrint(LongToString(exists)); //Prints 1. Confirming that the object does exist String name = ""; //The string variable we'll put the preset name in later on //Get the DbIndex# for the presets LONG index = cb->GetDbIndex(user_dir.GetString(), 0); //<---Always returns 0 or 1? Why not 2,3,4,etc.....? GePrint(LongToString(index)); cb->GetPresetName(index, user_dir.GetString(), LanguageUS, name); //Results in getting the name "Cube" GePrint(name);
-ScottA
-
On 04/11/2013 at 02:17, xxxxxxxx wrote:
Hi,
GetDbIndex() always returns 1 (or UserPresetDb) for the user preset library.
And if you need to browse through the items you have to use the class SDKBrowsePresets. -
On 04/11/2013 at 08:30, xxxxxxxx wrote:
Hi Yannick,
Nice to hear from you. I thought you were abducted by aliens or something.We have a Bool function called ExistsPreset() for checking if something exits.
And the docs say GetDbIndex() is supposed to return a LONG value.
So if GetDbIndex() is indeed supposed to return 1. Then I don't understand how that is of any use to us?
Or how to use it in the other CB functions?Example:
Filename broadDir = "preset://Broadcast.lib4d"; //Start at the Broadcast preset SDKBrowserURL url(broadDir); //The URL for the Broadcast preset SDKBrowsePresets *browse = NULL; //Create an instance of the browser class browse->Alloc(?); //<----What do I put in the param? browse->GetNext(url, ?); //<----What do I use for the pluginID param? browse->Free(browse);
On a separate issue.
I'm also very confused about how to write CB plugins.
There's several classes throughout the SDK. And I can't make sense out of how to use them.
-SDKBrowserPluginInterface
-SDKBrowserPluginInterfaceInfo
-SDKBrowserPreviewDialog
-RegisterPresetLibrary(constSDKBrowserURL
[URL-REMOVED]& domain, constString
[URL-REMOVED]& name, constFilename
[URL-REMOVED]& f)If I wanted to save a preset using: static Bool SavePresetObject(const
SDKBrowserURL
[URL-REMOVED]& url,BaseList2D
[URL-REMOVED]* bl).
Do I have to write a full blown SDKBrowserPluginInterface plugin to do that?
Or can I do this without writing a plugin?I do have an SDKBrowserPluginInterface plugin example that was posted here years ago by a user. But it's not a complete working example. It's just a basic framework with empty methods.
It complies but it doesn't do anything.I'm just generally confused. And looking for clarification.
The docs don't really explain things very well.-ScottA
[URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.
-
On 05/11/2013 at 04:19, xxxxxxxx wrote:
Originally posted by xxxxxxxx
Nice to hear from you. I thought you were abducted by aliens or something.
We aren't allowed to browse the main preset database (Broadcast.lib4d, Prime.lib4d, Studio.lib4d etc). SDKBrowser::GetDbIndex() returns 0 in this case and SDKBrowsePresets::Alloc() returns a null pointer.
Here's how to use SDKBrowsePresets:
String path("preset://user.lib4d/Objects"); Int32 presetIndex = SDKBrowser::GetDbIndex(path); if (presetIndex!=SDKBrowser::InvalidPresetDb) { AutoAlloc<SDKBrowsePresets> presets(presetIndex); if (presets==nullptr) return FALSE; SDKBrowserURL url; Int32 plugin_id; while (presets->GetNext(url, plugin_id)) GePrint(url.GetString()); }
Note that SDKBrowsePresets only works with an entire preset database but you can filter the presets with their URLs.
Originally posted by xxxxxxxx
If I wanted to save a preset using: static Bool SavePresetObject(const
SDKBrowserURL
[URL-REMOVED]& url,BaseList2D
[URL-REMOVED]* bl).
Do I have to write a full blown SDKBrowserPluginInterface plugin to do that?
Or can I do this without writing a plugin?Yes, you don't need a plugin to use SDKBrowser::SavePresetObject().
You have just to make sure to create a preset node with SDKBrowser::CreatePresetNode() before calling it.
[URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.
-
On 05/11/2013 at 10:40, xxxxxxxx wrote:
Thanks.
The browsing is working now. But I still can't create my own presets.I'm trying to create my own preset named "MyPreset" with a folder in it called "MyObject".
Then save an object in the scene to this new "MyObject" folder.
But the problem is the CreatePresetNode() function requires index value, and plugin_id values. And they don't exist yet.
I can't figure out how to deal with this problem.String path("preset://MyPresets.lib4d/MyObject"); //The URL to the preset I want to create (it doesn't exist yet) LONG presetIndex = SDKBrowser::GetDbIndex(path); //Gets the preset's index (1=found, 0=Not found) SDKBrowserURL url; //The variable we will store what we find while browsing the preset LONG plugin-id = NULL; BaseObject *obj = doc->GetFirstObject(); //The scene object I want to save to the preset folder named "MyPreset/MyObject" if(!obj) return FALSE; SDKBrowser::CreatePresetNode(presetIndex, url, plugin_id, 0); //Create the MyPreset preset folder SDKBrowser::SavePresetObject(url, obj); //Save the object to the new preset
I don't understand how we're supposed to create our own presets, directories(folders) within the custom preset, and lastly, save objects within these folders.
-ScottA
-
On 06/11/2013 at 03:16, xxxxxxxx wrote:
Hi,
You can print the plugin types or plugin IDs of the presets in the browse loop:
AutoAlloc<SDKBrowsePresets> presets(SDKBrowser::UserPresetDb); if (presets==nullptr) return false; SDKBrowserURL url; Int32 plugin_id; while (presets->GetNext(url, plugin_id)) GePrint(url.GetString() + " - " + String::IntToString(plugin_id));
You can see that folders have the ID 0.
In fact, except the ID for folders all the standard content browserplugin types are declared in lib_browser.h
[URL-REMOVED] but not well documented and referenced://---------------------------------------------------------------------------------------- // Interface base class of a browser plugin //---------------------------------------------------------------------------------------- enum // basic plugins for the browser { CBPluginTypeImage = 1018021, CBPluginTypeMovie = 1018022, CBPluginTypeScene = 1018023, CBPluginTypeCategory = 1018024, CBPluginTypeCatalog = 1018025, CBPluginTypeUnknown = 1018026, CBPluginTypeFolder = 1018027, CBPluginTypeMaterial = 1018028, CBPluginTypeDummy = 1018029, CBPluginTypeDefaults = 1018030, CBPluginTypeFilePreset = 1018031, CBPluginTypeObjectPreset = 1018107, CBPluginTypeMaterialPreset = 1018108, CBPluginTypeTagPreset = 1018109, CBPluginTypeRenderDataPreset = 1018110, CBPluginTypeShaderPreset = 1018111, CBPluginTypeVideoPostPreset = 1018112, CBPluginTypeXPressoPreset = 1018113, CBPluginTypePresetLibrary = 1018760, CBPluginTypeCatalogFile = 1018761, CBPluginTypeScriptFile = 1018762 };
So here's how we can create a new preset library and add an object to it:
// Get the active object BaseObject* op = doc->GetActiveObject(); if (op==nullptr) return true; String path("preset://MyPresets"); SDKBrowser::CreatePresetNode(SDKBrowser::UserPresetDb, path, 0); path += "/MyObject"; SDKBrowser::CreatePresetNode(SDKBrowser::UserPresetDb, path, CBPluginTypeObjectPreset); if (SDKBrowser::SavePresetObject(path, op)) GePrint("Object Preset Saved Successfully");
Note that CreatePresetNode() returns false even if it was successfull.
I even tried to check if the preset node was created but ExistsPreset() returns false too.
[URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.
-
On 06/11/2013 at 08:06, xxxxxxxx wrote:
Awesome!
I knew about the plugin_ids already. But I just couldn't figure out how to bring everything together.I'm posting all of my Content Library notes here. So other people have working code examples to play around with:
//CallCommand(300000112); //The save Object Preset command //CallCommand(1018429) //New Preset Library command //CallCommand(1018428) //New Catalog command //Items can be saved into regular folders. Or as library presets that have the .lib4d file extention //There are two places that library presets are saved. The Appdata folder, and the Program Files\Maxon\Your C4D version\library\browser folder Examples: Filename user_dir = "preset://Studio.lib4d/Character/Flabio.c4d"; //Gets the flabio character preset //This folder is located in the Program Files\Maxon\Your C4D version\library\browser folder Filename user_dir = "preset://user.lib4d/Objects/Cube.c4d"; //Gets a cube saved to the "User" folder using the "Save Object Preset.." command in C4D //This folder is located in the AppData\Roaming\Maxon\Your C4D version\library\broswer folder //This code opens the content browser window at a specific standard type folder and file location (if it exists) //*WARNING!! The filepath used here is for the regular folders found in Program Files\Maxon\libraries folder..Do not use C4D_PATH_LIBRARY_USER!! //*The saved library items in the AppData folder are accessed using this type of syntax: "preset://user.lib4d/Objects" #include "lib_browser.h" //This looks for a regular type of directory..NOT!! for a .lib4d type of directory Filename user_dir = GeGetC4DPath(C4D_PATH_LIBRARY) + "Scott" + "MyScene.c4d"; SDKBrowser *cb = NULL; //Create a ContentBrowser instance cb->OpenNewBrowser(user_dir, 0); //Opens the CB at the specific folder //This code opens the ContentBrowser window at the User/Objects .lib4d type folder(if it exists) which is in the AppData folder //IMPORTANT! You have to use GetString() on the URL paths for the .lib4d presets #include "lib_browser.h" Filename user_dir = "preset://user.lib4d/Objects"; //The URL path to a specific .lib4d type directory SDKBrowser *cb = NULL; //Create a ContentBrowser instance cb->OpenNewBrowser(user_dir.GetString(), 0); //Notice how we use GetString() function //This code shows how to get a specific preset #include "lib_browser.h" Filename user_dir = "preset://user.lib4d/Objects/Cube"; //The Filename path to a specific folder/saved item SDKBrowser *cb = NULL; //Create a ContentBrowser instance cb->OpenNewBrowser(user_dir.GetString(), 0); //Notice how we use GetString() function SDKBrowserURL url(user_dir); //Gets the URL for the preset GePrint(url.GetString()); //Prints file://localhost/preset://user.lib4d/Objects/Cube GePrint(url.GetDirectory().GetString()); //Prints file://localhost/preset://user.lib4d/Objects String item = url.GetFileString(); //Gets the name of the preset without the path GePrint(item); //Prints Cube SDKBrowserURL dir = url.GetDirectory(); //Get the parent folder of the item GePrint(dir.GetString()); //Prints file://localhost/preset://user.lib4d/Objects Bool exists = cb->ExistsPreset(user_dir.GetString()); //Check if a preset exists GePrint(LongToString(exists)); Bool empty = url.GetDirectory().Content(); //<---Something is wrong here..always true!!?? GePrint(LongToString(empty)); //This code saves *ONLY* the the active object in the scene to a custom folder on your HD (NOTE: This does not save to any of the .lib4d folders) //In this example we create a new custom folder named "Scott" in the AppData\libraries\ folder //NOTE: The custom folder is overwritten if it already exists...Or...is created if it doesn't already exist #include "lib_browser.h" Filename library_dir = GeGetC4DPath(C4D_PATH_LIBRARY_USER); //The library folder in the AppData folder GeFCreateDir(library_dir + Filename("Scott")); //Creates a new sub folder in the library folder named "Scott" Filename user_dir = GeGetC4DPath(C4D_PATH_LIBRARY_USER) + "Scott" + "MyScene.c4d"; //The full path. Including the file's name to be saved BaseObject *obj = doc->GetActiveObject(); //Get the active object if (!obj) return FALSE; BaseDocument *tempDoc = BaseDocument::Alloc(); //Create a temporary document if (!tempDoc) return FALSE; BaseObject *clone = (BaseObject* )obj->GetClone(COPYFLAGS_0,NULL); //Clone the active object if (!clone) { BaseDocument::Free(tempDoc); return FALSE; } tempDoc->InsertObject(clone,NULL,NULL); //Insert the clone into the temp. document SaveDocument(tempDoc, user_dir, SAVEDOCUMENTFLAGS_0, FORMAT_C4DEXPORT); //Save the .c4d file in the desired folder BaseDocument::Free(tempDoc); //Free the tempDoc memory pointer's memory //This code loads a preset from the user.lib4d file found in the AppData folder //Not from a regular folder in the programs tree Filename librarypath = "preset://user.lib4d/Objects/Cube"; //The specific saved object inside of the User/Objects folder to load MergeDocument(doc, librarypath, SCENEFILTER_MERGESCENE, NULL); LoadFile(librarypath); //These are the CB presets we can look through CBPluginTypeImage=1018021, CBPluginTypeMovie=1018022, CBPluginTypeScene=1018023, CBPluginTypeCategory=1018024, CBPluginTypeCatalog=1018025, CBPluginTypeUnknown=1018026, CBPluginTypeFolder=1018027, CBPluginTypeMaterial=1018028, CBPluginTypeDummy=1018029, CBPluginTypeDefaults=1018030, CBPluginTypeFilePreset=1018031, CBPluginTypeObjectPreset=1018107, //Gets the objects presets. Including the User/Objects folder: preset://user.lib4d/Objects/the objects you've saved CBPluginTypeMaterialPreset=1018108, //Gets the materials presets CBPluginTypeTagPreset=1018109, //Gets the User/Tags folder: EX: preset://user.lib4d/Tags/the tags you've saved CBPluginTypeRenderDataPreset=1018110, CBPluginTypeShaderPreset=1018111, //Gets the brick shaders: EX: preset://brick shader.lib4d/Purely Procedural/Tiles 01 CBPluginTypeVideoPostPreset=1018112, CBPluginTypeXPressoPreset=1018113, CBPluginTypePresetLibrary=1018760, CBPluginTypeCatalogFile=1018761, CBPluginTypeScriptFile=1018762, //This code prints the plugin types (plugin IDs) of the presets in the browse loop //Note that folders have the ID 0 AutoAlloc<SDKBrowsePresets>presets(SDKBrowser::UserPresetDb); if(presets==nullptr) return false; SDKBrowserURL url; LONG plugin_id; while (presets->GetNext(url, plugin_id)) GePrint(url.GetString() + " - " + String::IntToString(plugin_id)); //Here is an example that displays all object presets in a pop up window. And does something when you select one of them //The CallBack method is where you put the task that you want to do when you select one of the presets //For the "presettypeid" parameter you have to pass a valid browser preset plugin ID. The one returned in SDKBrowserPluginInterfaceInfo::GetPluginID() //So for instance if you have written your own preset plugin. You would use the ID of your preset plugin #include "lib_browser.h" //This is the callback method that the BrowserLibraryPopup() function requires to peform your task //Reminder: Put this at the top of your plugin code... *NOT* inside of any classes void browserCB(void* userdata, LONG cmd, SDKBrowserURL& url) { if(url.GetString() == "preset://user.lib4d/Objects/Cube") //If you clicked on this specific preset { GePrint(url.GetString()); //Do something... } } Bool MenuTest::Execute(BaseDocument *doc) { BaseContainer state; GetInputState(BFM_INPUT_MOUSE, 0, state); //Gets the up/down state of the LMB LONG mx = state.GetReal(BFM_INPUT_X); //Get the X&Y position of the mouse LONG my = state.GetReal(BFM_INPUT_Y); LONG MYWINDOWID = 1000; //This can be any number you like. The window just needs a unique ID# BrowserLibraryPopup(mx, my, 200, 200, MYWINDOWID, CBPluginTypeObjectPreset, NULL, browserCB); return TRUE; } //This is how to search through the CB presets(NOTE: we can't search the built-in presets Studio.lib4d, etc...) //SDKBrowsePresets only works with an entire preset database. But you can filter the presets with their URLs String path("preset://user.lib4d/Objects"); //The URL to the User preset called "Objects" LONG presetIndex = SDKBrowser::GetDbIndex(path); //Gets the preset's index(1=found, 0=Not found) if (presetIndex != SDKBrowser::InvalidPresetDb) //If the value of presetIndex == 1 { AutoAlloc<SDKBrowsePresets>presets(presetIndex); //Create an instance of the SDKBrowsePresets class if (presets == nullptr) return FALSE; //If the instance fails to be created. End the program SDKBrowserURL url; //The variable we will store what we find while browsing the preset LONG plugin_id; while (presets->GetNext(url, plugin_id)) { GePrint(url.GetString()); } //Print all the items in this preset(the User folder) } //This creates a custom preset in the ContentBrowser //Then it creates a custom folder in the preset //Then it saves the active object to that new folder //The object that we will save to a new preset library BaseObject *obj = doc->GetActiveObject(); if(!obj) return FALSE; //The name for the new preset String presetName = "MyPreset"; //The path to the library/browser folder in AppData Filename cbPath = GeGetC4DPath(C4D_PATH_LIBRARY_USER); if (!cbPath.Content()) return SDKBrowser::InvalidPresetDb; //The full path to the new preset String fullPath = cbPath.GetString() + "//browser//" + presetName + ".lib4d"; //The path to the new preset(needed for the RegisterPresetLibrary() function next) String dbUrl = "preset://" + presetName + ".lib4d"; //We have to register the new preset using RegisterPresetLibrary() //If we don't register it. The preset will disappear when we close C4D LONG dbIndex = SDKBrowser::RegisterPresetLibrary(dbUrl, presetName, fullPath); //Create a URL type variable using the location of the newly created preset //This will be anew folder inside of the preset where the active object will be saved SDKBrowserURL url(String("preset://MyPresets.lib4d/MyObject")); //Get the database index for the newly created preset LONG index = SDKBrowser::GetDbIndex(String("preset://MyPresets.lib4d")); //Add the object to the preset library SDKBrowser::CreatePresetNode(index, url, CBPluginTypeObjectPreset); SDKBrowser::SavePresetObject(url, obj); //This is how to create and add a new custom preset in AppData using custom methods //A custom method that creates a new CB preset which is located in the AppData folder Bool CreatePresetLibrary(String dbName) { //The preset library is created in the user directory "library/browser" folder Filename dbPath = GeGetC4DPath(C4D_PATH_LIBRARY_USER); if (!dbPath.Content()) return SDKBrowser::InvalidPresetDb; dbPath += "//browser"; dbPath += "//" + dbName + ".lib4d"; String dbUrl("preset://" + dbName + ".lib4d"); LONG dbIndex = SDKBrowser::RegisterPresetLibrary(dbUrl, dbName, dbPath); return dbIndex != SDKBrowser::InvalidPresetDb; } //A custom method that adds a new CB preset Bool AddObjectPreset(BaseObject*op, LONG dbIndex, SDKBrowserURL url) { SDKBrowser::CreatePresetNode(dbIndex, url, CBPluginTypeObjectPreset); return SDKBrowser::SavePresetObject(url, op); } //This is how to use the above custom methods to create & add a new custom preset Bool MenuTest::Execute(BaseDocument* doc) { //Create a preset library named "MyPresets" if (!CreatePresetLibrary("MyPresets")) return true; //Get the active object BaseObject* op = doc->GetActiveObject(); if (op == nullptr) return true; //Create a URL within the previously created preset to save the active object to SDKBrowserURL url(String("preset://MyPresets.lib4d/MyObject")); //Get the preset library database index LONG index = SDKBrowser::GetDbIndex(String("preset://MyPresets.lib4d")); //Finally add the object to the preset library if (AddObjectPreset(op, index, url)) { GePrint("Object \"" + op->GetName() + "\" Saved to Preset \"" + url.GetString() + "\" Successfully"); } return true; }
Thank You Yannick,
-ScottA -
On 06/11/2013 at 10:57, xxxxxxxx wrote:
Hi,
I wasn't happy with my previous code because it wasn't creating a preset library .lib4d file and also the preset wasn't saved between sessions.
So here's below some code to create a preset library and to add an object to it. It works fine and the preset is saved as expected.
It wouldn't be too hard to add some code to add materials, files to the preset library.Bool CreatePresetLibrary(String dbName) { // The preset library is created in the user directory "library/browser" folder Filename dbPath = GeGetC4DPath(C4D_PATH_LIBRARY_USER); if (!dbPath.Content()) return SDKBrowser::InvalidPresetDb; dbPath += "//browser"; dbPath += "//" + dbName + ".lib4d"; String dbUrl("preset://" + dbName + ".lib4d"); Int32 dbIndex = SDKBrowser::RegisterPresetLibrary(dbUrl, dbName, dbPath); return dbIndex!=SDKBrowser::InvalidPresetDb; } Bool AddObjectPreset(BaseObject*op, Int32 dbIndex, SDKBrowserURL url) { SDKBrowser::CreatePresetNode(dbIndex, url, CBPluginTypeObjectPreset); return SDKBrowser::SavePresetObject(url, op); } Bool MenuTest::Execute(BaseDocument* doc) { // Create a preset library named "MyPresets" if (!CreatePresetLibrary("MyPresets")) return true; // Get the active object BaseObject* op = doc->GetActiveObject(); if (op==nullptr) return true; // Create a URL within the previously created preset to save the active object to SDKBrowserURL url(String("preset://MyPresets.lib4d/MyObject")); // Get the preset library database index Int32 index = SDKBrowser::GetDbIndex(String("preset://MyPresets.lib4d")); // Finally add the object to the preset library if (AddObjectPreset(op, index, url)) GePrint("Object \"" + op->GetName() + "\" Saved to Preset \"" + url.GetString() + "\" Successfully"); return true; }
-
On 06/11/2013 at 12:38, xxxxxxxx wrote:
Ok. Thanks.
I will add this one to my notes as well.-ScottA