BIM Coordinator Program (INT) April 22, 2024
Find the next step in your career as a Graphisoft Certified BIM Coordinator!
Archicad C++ API
About Archicad add-on development using the C++ API.

Project Settings Preferences

Apollos
Contributor

Dear Community.

I am a newbie in my use of the Archicad C++ API. I have been trying to use the ACAPI_ProjectSetting_SetPreferences() and ACAPI_ProjectSetting_GetPreferences() to set and get Project Settings (as it relates to ZONE preferences) but even though my code builds without any error, I still cannot confirm whether the code has executed its intended purpose. Because while using the ACAPI_ProjectSetting_GetPreferences() it returns values that do not tally with my settings. Please any good counsel will be appreciated. Below is the code I am using. The return values I get are zonePrefs.nichDoorFlag = true;
zonePrefs.nichWindFlag = true;
zonePrefs.nichDepthFlag = true;
zonePrefs.nichSizeFlag = true;
zonePrefs.nichDepth = -925596313493178000000000000000;
zonePrefs.nichSize = -925596313493178000000000000000;

 

 

 

 

 

///----------------------------------------------------------------------
/// CHANGING ZONE PREFERENCES AND CHECKING ENDS HERE
/// ----------------------------------------------------------------------

//
// Consolidated error handling function
void HandleError(GSErrCode errorCode, const char* errorMessage) {
    if (errorCode != NoError) {
        ACAPI_WriteReport(errorMessage, true);
    }
}

// Function to define the setPreference function
GSErrCode ACAPI_ProjectSetting_SetPreferences(API_PrefsTypeID prefsTypeID, const void* prefs) {
    // Check if the prefs pointer is valid
    if (prefs == nullptr) {
        HandleError(APIERR_BADPARS, "Error: Invalid preferences pointer.");
        return APIERR_BADPARS;
    }

    // Check if the prefsTypeID is valid
    if (prefsTypeID != APIPrefs_ZonesID) {
        HandleError(APIERR_BADID, "Error: Invalid preferences type ID.");
        return APIERR_BADID;
    }

    // Write a report to indicate that zone preferences are being set
    ACAPI_WriteReport("Setting zone preferences...", true);

    return NoError;
}


//function definition for getPreference
GSErrCode ACAPI_ProjectSetting_GetPreferences(API_PrefsTypeID prefsTypeID, const void* prefs) {
    // Check if the prefs pointer is valid
    if (prefs == nullptr) {
        ACAPI_WriteReport("Error: Invalid preferences pointer.", true);
        return APIERR_BADPARS;
    }

    // Check if the prefsTypeID is valid
    if (prefsTypeID != APIPrefs_ZonesID) {
        ACAPI_WriteReport("Error: Invalid preferences type ID.", true);
        return APIERR_BADID;
    }

    return NoError;
}

// Function to write zone preferences to reports
void WritePreferences(const API_ZonePrefs& zonePrefs) {
    // Convert boolean values to string representation
    const char* doorFlagStr = zonePrefs.nichDoorFlag ? "true" : "false";
    const char* windFlagStr = zonePrefs.nichWindFlag ? "true" : "false";
    const char* depthFlagStr = zonePrefs.nichDepthFlag ? "true" : "false";
    const char* sizeFlagStr = zonePrefs.nichSizeFlag ? "true" : "false";

    // Convert double values to UniString
    GS::UniString depthStr = GS::UniString::Printf("%lf", zonePrefs.nichDepth);
    GS::UniString sizeStr = GS::UniString::Printf("%lf", zonePrefs.nichSize);

    // Write preferences to reports
    ACAPI_WriteReport("Nich Door Flag: " + GS::UniString(doorFlagStr), true);
    ACAPI_WriteReport("Nich Wind Flag: " + GS::UniString(windFlagStr), true);
    ACAPI_WriteReport("Nich Depth Flag: " + GS::UniString(depthFlagStr), true);
    ACAPI_WriteReport("Nich Size Flag: " + GS::UniString(sizeFlagStr), true);
    ACAPI_WriteReport("Nich Depth: " + depthStr, true);
    ACAPI_WriteReport("Nich Size: " + sizeStr, true);
}

// Function to set zone preference
GSErrCode SetZonePreferences() {
    // Define the zone preferences structure and initialize it with the desired values
    API_ZonePrefs zonePrefs;
    zonePrefs.nichDoorFlag = true;
    zonePrefs.nichWindFlag = true;
    zonePrefs.nichDepthFlag = true;
    zonePrefs.nichSizeFlag = false;
    zonePrefs.nichDepth = 0.130;
    zonePrefs.nichSize = 0.10;

    // Set the preferences using ACAPI_ProjectSetting_SetPreferences
    GSErrCode err = ACAPI_ProjectSetting_SetPreferences(APIPrefs_ZonesID, &zonePrefs);
    if (err != NoError) {
        HandleError(err, "Error: Failed to set zone preferences.");
    }
    else {
        ACAPI_WriteReport("Zone preferences set successfully.", true);
    }

    return err;
}

// Function to get and display zone preference
void DisplayZonePreferences() {
    // Define the zone preferences structure to store retrieved preferences
    API_ZonePrefs zonePrefs;

    // Get the zone preferences using ACAPI_ProjectSetting_GetPreferences
    GSErrCode err = ACAPI_ProjectSetting_GetPreferences(APIPrefs_ZonesID, &zonePrefs);
    if (err != NoError) {
        HandleError(err, "Error: Failed to get zone preferences.");
        return;
    }

    // Write preferences to reports
    WritePreferences(zonePrefs);
}

 

 

 

 

5 REPLIES 5
Akos Somorjai
Graphisoft
Graphisoft

Hi,

 

Please find below the correct code; the basic problem was that you didn't call the API to set/get the preferences, just your own functions.

 

Best, Akos

 

///----------------------------------------------------------------------
/// CHANGING ZONE PREFERENCES AND CHECKING ENDS HERE
/// ----------------------------------------------------------------------

//
// Consolidated error handling function
void HandleError(GSErrCode errorCode, const char* errorMessage) {
    if (errorCode != NoError) {
        ACAPI_WriteReport(errorMessage, true);
    }
}

// Function to define the setPreference function
GSErrCode ACAPI_ProjectSetting_SetPreferences(API_PrefsTypeID prefsTypeID, const void* prefs) {
    // Check if the prefs pointer is valid
    if (prefs == nullptr) {
        HandleError(APIERR_BADPARS, "Error: Invalid preferences pointer.");
        return APIERR_BADPARS;
    }

    // Check if the prefsTypeID is valid
    if (prefsTypeID != APIPrefs_ZonesID) {
        HandleError(APIERR_BADID, "Error: Invalid preferences type ID.");
        return APIERR_BADID;
    }

    void *locPrefs = const_cast<void*>(prefs);
    GSErrCode err = ACAPI_ProjectSetting_SetPreferences (locPrefs, APIPrefs_ZonesID);
    if (err != NoError) {
        HandleError(err, "Error: Failed to set Zone preferences.");
        return APIERR_BADID;
    }

    // Write a report to indicate that zone preferences are being set
    ACAPI_WriteReport("Setting zone preferences...", true);

    return NoError;
}


//function definition for getPreference
GSErrCode ACAPI_ProjectSetting_GetPreferences(API_PrefsTypeID prefsTypeID, void* prefs) {
    // Check if the prefs pointer is valid
    if (prefs == nullptr) {
        ACAPI_WriteReport("Error: Invalid preferences pointer.", true);
        return APIERR_BADPARS;
    }

    // Check if the prefsTypeID is valid
    if (prefsTypeID != APIPrefs_ZonesID) {
        ACAPI_WriteReport("Error: Invalid preferences type ID.", true);
        return APIERR_BADID;
    }

    GSErrCode err = ACAPI_ProjectSetting_GetPreferences (prefs, APIPrefs_ZonesID);
    if (err != NoError) {
        HandleError(err, "Error: Cannot get Zone preferences.");
        return APIERR_BADID;
    }

    return NoError;
}

// Function to write zone preferences to reports
void WritePreferences(const API_ZonePrefs& zonePrefs) {
    // Convert boolean values to string representation
    const char* doorFlagStr = zonePrefs.nichDoorFlag ? "true" : "false";
    const char* windFlagStr = zonePrefs.nichWindFlag ? "true" : "false";
    const char* depthFlagStr = zonePrefs.nichDepthFlag ? "true" : "false";
    const char* sizeFlagStr = zonePrefs.nichSizeFlag ? "true" : "false";

    // Convert double values to UniString
    GS::UniString depthStr = GS::UniString::Printf("%lf", zonePrefs.nichDepth);
    GS::UniString sizeStr = GS::UniString::Printf("%lf", zonePrefs.nichSize);

    // Write preferences to reports
    ACAPI_WriteReport("Nich Door Flag: " + GS::UniString(doorFlagStr), true);
    ACAPI_WriteReport("Nich Wind Flag: " + GS::UniString(windFlagStr), true);
    ACAPI_WriteReport("Nich Depth Flag: " + GS::UniString(depthFlagStr), true);
    ACAPI_WriteReport("Nich Size Flag: " + GS::UniString(sizeFlagStr), true);
    ACAPI_WriteReport("Nich Depth: " + depthStr, true);
    ACAPI_WriteReport("Nich Size: " + sizeStr, true);
}

// Function to set zone preference
GSErrCode SetZonePreferences() {
    // Define the zone preferences structure and initialize it with the desired values
    API_ZonePrefs zonePrefs;
    // Load the current values
    ACAPI_ProjectSetting_GetPreferences (&zonePrefs, APIPrefs_ZonesID);
    // Modify those that we need
    zonePrefs.nichDoorFlag = true;
    zonePrefs.nichWindFlag = true;
    zonePrefs.nichDepthFlag = true;
    zonePrefs.nichSizeFlag = false;
    zonePrefs.nichDepth = 0.130;
    zonePrefs.nichSize = 0.10;

    // Set the preferences using ACAPI_ProjectSetting_SetPreferences
    GSErrCode err = ACAPI_ProjectSetting_SetPreferences(APIPrefs_ZonesID, &zonePrefs);
    if (err != NoError) {
        HandleError(err, "Error: Failed to set zone preferences.");
    }
    else {
        ACAPI_WriteReport("Zone preferences set successfully.", true);
    }

    return err;
}

// Function to get and display zone preference
void DisplayZonePreferences() {
    // Define the zone preferences structure to store retrieved preferences
    API_ZonePrefs zonePrefs;

    // Get the zone preferences using ACAPI_ProjectSetting_GetPreferences
    GSErrCode err = ACAPI_ProjectSetting_GetPreferences(APIPrefs_ZonesID, &zonePrefs);
    if (err != NoError) {
        HandleError(err, "Error: Failed to get zone preferences.");
        return;
    }

    // Write preferences to reports
    WritePreferences(zonePrefs);
}
Apollos
Contributor

Thank you @Akos Somorjai . I have been waiting for any meaningful help. I tried the code you suggested. It built without any errors, but the Archicad 26 crashing when ever I call the SetPreferences function. Here is the code I used. Maybe you can guide me with specifics. I am concerned because I can not find any example in the documentation. Thank you for your time.

 

///----------------------------------------------------------------------
/// CHANGING ZONE PREFERENCES AND CHECKING ENDS HERE
/// ----------------------------------------------------------------------


// Consolidated error handling function
void HandleError(GSErrCode errorCode, const char* errorMessage) {
    if (errorCode != NoError) {
        ACAPI_WriteReport(errorMessage, true);
    }
}

// Function to define the setPreference function
GSErrCode ACAPI_ProjectSetting_SetPreferences(API_PrefsTypeID prefsTypeID, const void* prefs) {
    // Check if the prefs pointer is valid
    if (prefs == nullptr) {
        HandleError(APIERR_BADPARS, "Error: Invalid preferences pointer.");
        return APIERR_BADPARS;
    }

    // Check if the prefsTypeID is valid
    if (prefsTypeID != APIPrefs_ZonesID) {
        HandleError(APIERR_BADID, "Error: Invalid preferences type ID.");
        return APIERR_BADID;
    }

    void* locPrefs = const_cast<void*>(prefs);
    GSErrCode err = ACAPI_ProjectSetting_SetPreferences(APIPrefs_ZonesID, locPrefs);
    if (err != NoError) {
        HandleError(err, "Error: Failed to set Zone preferences.");
        return APIERR_BADID;
    }

    // Write a report to indicate that zone preferences are being set
    ACAPI_WriteReport("Setting zone preferences...", true);

    return NoError;
}


//function definition for getPreference
GSErrCode ACAPI_ProjectSetting_GetPreferences(API_PrefsTypeID prefsTypeID, void* prefs) {
    // Check if the prefs pointer is valid
    if (prefs == nullptr) {
        ACAPI_WriteReport("Error: Invalid preferences pointer.", true);
        return APIERR_BADPARS;
    }

    // Check if the prefsTypeID is valid
    if (prefsTypeID != APIPrefs_ZonesID) {
        ACAPI_WriteReport("Error: Invalid preferences type ID.", true);
        return APIERR_BADID;
    }

    GSErrCode err = ACAPI_ProjectSetting_GetPreferences(prefs, APIPrefs_ZonesID);
    if (err != NoError) {
        HandleError(err, "Error: Cannot get Zone preferences.");
        return APIERR_BADID;
    }

    return NoError;
}

// Function to write zone preferences to reports
void WritePreferences(const API_ZonePrefs& zonePrefs) {
    // Convert boolean values to string representation
    const char* doorFlagStr = zonePrefs.nichDoorFlag ? "true" : "false";
    const char* windFlagStr = zonePrefs.nichWindFlag ? "true" : "false";
    const char* depthFlagStr = zonePrefs.nichDepthFlag ? "true" : "false";
    const char* sizeFlagStr = zonePrefs.nichSizeFlag ? "true" : "false";

    // Convert double values to UniString
    GS::UniString depthStr = GS::UniString::Printf("%lf", zonePrefs.nichDepth);
    GS::UniString sizeStr = GS::UniString::Printf("%lf", zonePrefs.nichSize);

    // Write preferences to reports
    ACAPI_WriteReport("Nich Door Flag: " + GS::UniString(doorFlagStr), true);
    ACAPI_WriteReport("Nich Wind Flag: " + GS::UniString(windFlagStr), true);
    ACAPI_WriteReport("Nich Depth Flag: " + GS::UniString(depthFlagStr), true);
    ACAPI_WriteReport("Nich Size Flag: " + GS::UniString(sizeFlagStr), true);
    ACAPI_WriteReport("Nich Depth: " + depthStr, true);
    ACAPI_WriteReport("Nich Size: " + sizeStr, true);
}

// Function to set zone preference
GSErrCode SetZonePreferences() {
    // Define the zone preferences structure and initialize it with the desired values
    API_ZonePrefs zonePrefs;
    // Load the current values
    ACAPI_ProjectSetting_GetPreferences(&zonePrefs, APIPrefs_ZonesID);
    // Modify those that we need
    zonePrefs.nichDoorFlag = true;
    zonePrefs.nichWindFlag = true;
    zonePrefs.nichDepthFlag = true;
    zonePrefs.nichSizeFlag = false;
    zonePrefs.nichDepth = 0.13;
    zonePrefs.nichSize = 0.10;

    // Set the preferences using ACAPI_ProjectSetting_SetPreferences
    GSErrCode err = ACAPI_ProjectSetting_SetPreferences(APIPrefs_ZonesID, &zonePrefs);
    if (err != NoError) {
        HandleError(err, "Error: Failed to set zone preferences.");
    }
    else {
        ACAPI_WriteReport("Zone preferences set successfully.", true);
    }

    return err;
}

// Function to get and display zone preference
void DisplayZonePreferences2() {
    // Define the zone preferences structure to store retrieved preferences
    API_ZonePrefs zonePrefs;

    // Get the zone preferences using ACAPI_ProjectSetting_GetPreferences
    GSErrCode err = ACAPI_ProjectSetting_GetPreferences(APIPrefs_ZonesID, &zonePrefs);
    if (err != NoError) {
        HandleError(err, "Error: Failed to get zone preferences.");
        return;
    }

    // Write preferences to reports
    WritePreferences(zonePrefs);
}


// Menu command handler
// This function handles menu commands and performs the appropriate actions.
static GSErrCode MenuCommandHandler(const API_MenuParams* menuParams) {
    switch (menuParams->menuItemRef.menuResID) {
    case AddOnMenuID:
        switch (menuParams->menuItemRef.itemIndex) {
        case AddOnCommandID:
            DisplayZonePreferences2();
            SetZonePreferences();
            break;
        }
        break;
    }

    return NoError;
}

 

Hi Apollos,

 

The code I added was for Archicad 27, not Archicad 26. Your code is strange because it uses the function names from Archicad 27 API. Which devkit version do you use, along with which Archicad version?

 

Best, Akos

Apollos
Contributor

Dear @Akos Somorjai

Thank you for your time and counsel. I apologise for failing to inform you that I am using Archicad 26. But as you suggested I will try and use the Archicad 27. Maybe that is why it is crashing. I use Archicad 26 with its Developer Kit. Please do you have any other option for Archicad 26? Even though I will try it on Archicad 27 (& its developer kit) and will give you an update. Once again thank you.

Dear @Apollos ,

 

Unfortunately, this is not possible in Archicad 26 because the SetPreferences function is available from Archicad 27 only.

 

Sorry, Akos

 

Learn and get certified!