Choose your top Archicad wishes!

Read more
Archicad C++ API
About Archicad add-on development using the C++ API.

Programatically loading GDL not importing surfaces

Not applicable

Continuing on from my Reserve Library issue we are now able to programatically extract our GDL from the LCF and import it into the Embedded Library. The problem we're now encountering is that the textures/surfaces defined in the GDL are not immediately available in Archicad. Specifically if I go into Attributes/Surfaces the surfaces are not listed. However, if I save and reload the file then the surfaces do appear. Additionally, if I manually load the GDL into the Emedded Library via the UI then the surfaces do immediately appear. I am assuming that the script isn't being executed when I copy and register it programatically but it is executed when the file is opened, or manually loaded in.

This is problematic as the next step we perform after loading the GDL to define the surfaces is create building materials that reference them. This fails since the surfaces are not available.

Note this issue has nothing to do with teamwork, it happens even with normal solo files.

The GDLs in question are master scripts from the LCF. In fact they are the only items in the LCF as all we need to do is define the textures/surfaces and it was easier in our pipeline to make LCFs like this than programatically create surfaces. I've have attached a sample GDL that shows the issue. The code we use to import is as follows:

/// @param path the path on the filesystem to the GDL to import
/// @param library_folder path within the embedded library to import the item to
GS::Int32 Archlog_import::add_to_embedded_library(const IO::Location &path, const IO::RelativeLocation &library_folder)
	if (path.IsEmpty()) {
		return -2;

	GS::Array<API_LibraryInfo>    activeLibs;
	GSErrCode            err;
	GS::Int32 embeddedLibraryIndex = -1;

	err = ACAPI_Environment(APIEnv_GetLibrariesID, &activeLibs, &embeddedLibraryIndex);
	if (err != NoError || embeddedLibraryIndex == -1) {
		// no embedded library
		return -4;

	IO::Location embedded_folder = activeLibs[embeddedLibraryIndex].location;	
	IO::RelativeLocation folders(IO::Name("Arch-LOG"));

	for (USize i = 0; i < folders.GetLength(); ++i) {
		IO::Name folder;
		folders.GetName(i, &folder);
		err = ACAPI_Environment(APIEnv_CreateFolderInLibraryID, &embedded_folder);
		if (err != NoError) {
			return -5;
	GS::Array<IO::Location> fileToCopy;
	bool overwrite=true;
	err = ACAPI_Environment(APIEnv_CopyFilesIntoLibraryID, &embedded_folder, &fileToCopy, &overwrite);
	if (err != NoError) {
		return -6;
	IO::Location embedded_file(embedded_folder);
	IO::Name name;

	API_LibPart libPart;
	BNZeroMemory(&libPart, sizeof(API_LibPart));
	libPart.typeID = APILib_ObjectID;
	libPart.location = &embedded_file;
	err = ACAPI_LibPart_Register(&libPart);
	return err == NoError ? 0 : -7;
Is there some additional step we need to take to get the script to execute? Note that setting the part typeID to macro doesn't help.


Ralph Wessel
I haven't tested this, but you might be able to get the desired result by doing something that makes the script run, e.g. modifying the default tool settings by changing a parameter. You can do this with APIAny_ChangeAParameterID (and set the target object as the default for the tool).
Ralph Wessel BArch
Not applicable
Can look into something like this but given the script doesn't actually define a part their aren't any parameters to modify. Is there any other calls we could make that would trigger script execution?
Barry Kelly
Forgive me for chiming in here as I know nothing about API development.
But is it possible to force a re-load of the embedded library?

One of the forum moderators.
Versions 6.5 to 27
Dell XPS- i7-6700 @ 3.4Ghz, 16GB ram, GeForce GTX 960 (2GB), Windows 10
Lenovo Thinkpad - i7-1270P 2.20 GHz, 32GB RAM, Nvidia T550, Windows 11
Ralph Wessel
I don't think you can reload just the embedded library, but it's worth trying a full library reload…
Ralph Wessel BArch
Not applicable
OK, we've found that we can get it to run the script by doing a APIEnv_GetLibrariesID followed by a APIEnv_SetLibrariesID with the same list. However this doesn't work in Teamwork mode since we can't programatically reserve the library list (as noted in my Reserve Library thread).

Is there any other way we can for the script to be executed?
Akos Somorjai

Please call ACAPI_LibPart_Register() for your images after copying them into the embedded library.

Best, Akos

Didn't find the answer?

Check other topics in this Forum

Back to Forum

Read the latest accepted solutions!

Accepted Solutions

Start a new conversation!