<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Replacing Surface Materials based on MaterialName. in Archicad C++ API</title>
    <link>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/662447#M10345</link>
    <description>&lt;P&gt;Do you just want to edit the existing materials rather than reassigning the materials assigned to elements?&lt;/P&gt;</description>
    <pubDate>Wed, 14 May 2025 07:19:18 GMT</pubDate>
    <dc:creator>Ralph Wessel</dc:creator>
    <dc:date>2025-05-14T07:19:18Z</dc:date>
    <item>
      <title>Replacing Surface Materials based on MaterialName.</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/653026#M10154</link>
      <description>&lt;P&gt;Hi! I'm looking into ways to replace Surface Material (&lt;STRONG&gt;API_MaterialID&lt;/STRONG&gt;), based on the name of the Material (after downloading the Material into the project). If I already know that my project has a material A applied to a window/door/wall/slab, and I want to download and import a material say B into the Project and replace all the instances of A in the project, with B, I'm unsure how to replace the instances.&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tried getting the Attribute Indices of A and B and replacing B's&amp;nbsp;&lt;/P&gt;&lt;P class=""&gt;Attr.header.typeID,&amp;nbsp;Attr.header.index,&amp;nbsp;Attr.material and&amp;nbsp;Attr.material.texture.fileLoc values with A's corresponding values and deleting the A Attribute fully. But this doesn't seem to work.&amp;nbsp;&lt;/P&gt;&lt;P class=""&gt;Please let me know if there is any other way to make this replacement work, on surface material level.&lt;/P&gt;&lt;P class=""&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Edit: Let me rename the elements as plain A and B, as I think A1 and B1 is creating some confusions.&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you in Advance.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="cpp"&gt;API_AttributeIndex FindSurfaceMaterialIndex(const char* MaterialName)
{
	API_AttrTypeID	typeID;
	GSErrCode		err = NoError;
	API_AttributeIndex test;

	for (typeID = API_FirstAttributeID; typeID &amp;lt;= API_LastAttributeID; ((Int32&amp;amp;)typeID)++) {
		GS::Array&amp;lt;API_Attribute&amp;gt; attributes;
		err = ACAPI_Attribute_GetAttributesByType(typeID, attributes);
		if (err != NoError) {
			DBPrintf("Error in ACAPI_Attribute_GetAttributesByType", err);
			continue;
		}

		if (typeID == API_MaterialID)
		{
			short count = 1;
			for (API_Attribute&amp;amp; attrib : attributes) {
				char guidStr[64];
				APIGuid2GSGuid(attrib.header.guid).ConvertToString(guidStr);

				if (strcmp(attrib.header.name, MaterialName) == 0) {  // Match found
					test = attrib.header.index;
					return test;
				}
				count++;  //index loc for reference
			}
		}

	}
	return ACAPI_CreateAttributeIndex(0);
}

// Function to replace a surface material
GSErrCode	ReplaceSurfaceMaterial(const char* oldMaterialName, const char* newMaterialName) {
	API_AttributeIndex oldAttribute = FindSurfaceMaterialIndex(oldMaterialName);
	API_AttributeIndex newAttribute = FindSurfaceMaterialIndex(newMaterialName);

	API_Attribute oldAttr, newAttr;
	BNZeroMemory(&amp;amp;oldAttr, sizeof(API_Attribute));
	BNZeroMemory(&amp;amp;newAttr, sizeof(API_Attribute));

	oldAttr.header.typeID = API_MaterialID;
	oldAttr.header.index = oldAttribute;

	newAttr.header.typeID = API_MaterialID;
	newAttr.header.index = newAttribute;

	if (ACAPI_Attribute_Get(&amp;amp;oldAttr) != NoError) {
		return 0;
	}

	// Copy all properties from the new material to the old material
	newAttr.material = oldAttr.material;  
	
	newAttr.material.texture.fileLoc = oldAttr.material.texture.fileLoc;

	char guidStr[64];
	APIGuid2GSGuid(newAttr.header.guid).ConvertToString(guidStr);

	DBPrintf("\n");
	DBPrintf("  [%3s]   {%s}  \"%s\"", newAttr.header.index.ToUniString().ToCStr().Get(), guidStr, newAttr.header.name);

	GSErrCode err2 = ACAPI_Attribute_Delete(oldAttr.header);

	newAttr.header.index = oldAttr.header.index;

	GSErrCode err = ACAPI_Attribute_Modify(&amp;amp;newAttr, nullptr);
	if (err != NoError) {
		return err;
	}

	if (ACAPI_Attribute_Get(&amp;amp;newAttr) != NoError) {
		return 0;
	}

	return NoError;
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 03 Mar 2025 22:44:01 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/653026#M10154</guid>
      <dc:creator>KirthikaSrinivasan-L</dc:creator>
      <dc:date>2025-03-03T22:44:01Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing Surface Materials based on MaterialName.</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/653027#M10155</link>
      <description>&lt;P&gt;The API sub can be found &lt;U&gt;&lt;A href="https://community.graphisoft.com/t5/Archicad-C-API/bd-p/forum-ac-api" target="_self"&gt;here&lt;/A&gt;&lt;/U&gt;&amp;nbsp;for future reference.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;a href="https://community.graphisoft.com/t5/user/viewprofilepage/user-id/7331"&gt;@Barry Kelly&lt;/a&gt;&amp;nbsp;or someone can move this thread for you when they see it.&lt;/P&gt;</description>
      <pubDate>Tue, 25 Feb 2025 07:33:26 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/653027#M10155</guid>
      <dc:creator>Lingwisyer</dc:creator>
      <dc:date>2025-02-25T07:33:26Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing Surface Materials based on MaterialName.</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/653031#M10156</link>
      <description>&lt;P&gt;I am no C++ coder, but are you replacing the information within each material with that of your desired one? Would you not just completely replace the material;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;parse material library for "const char", write result to A1 to An&lt;/LI&gt;
&lt;LI&gt;find index of A1 to An&lt;/LI&gt;
&lt;LI&gt;store string Prior to "const char" for A1 to An&lt;/LI&gt;
&lt;LI&gt;store string After "const char" for A1 to An&lt;/LI&gt;
&lt;LI&gt;delete A1 to An from material library&lt;/LI&gt;
&lt;LI&gt;duplicate B1 =&amp;gt; B2 to Bn&lt;/LI&gt;
&lt;LI&gt;replace the index of B2 to Bn with the stored values from A1 to An?&lt;/LI&gt;
&lt;LI&gt;ammend name B2 to Bn with Prior "const char" After&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Or is that just really memory inefficient?&lt;/P&gt;
&lt;P&gt;Or maybe that is what you have done, I am no C++ coder...&lt;/P&gt;</description>
      <pubDate>Tue, 25 Feb 2025 08:28:08 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/653031#M10156</guid>
      <dc:creator>Lingwisyer</dc:creator>
      <dc:date>2025-02-25T08:28:08Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing Surface Materials based on MaterialName.</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/653854#M10176</link>
      <description>&lt;P&gt;Hi, Your code shows me that you deleted the oldAttr, then you try to use the oldAttr index to modify...&lt;/P&gt;
&lt;P&gt;newAttr.header.index = oldAttr.header.index;&lt;BR /&gt;ACAPI_Attribute_Modify(&amp;amp;newAttr,...&lt;/P&gt;
&lt;P&gt;If you'd modify a material attribute, the material should not be removed.&lt;BR /&gt;HTH.&lt;/P&gt;</description>
      <pubDate>Tue, 04 Mar 2025 03:29:02 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/653854#M10176</guid>
      <dc:creator>Hiromichi Shinkawa</dc:creator>
      <dc:date>2025-03-04T03:29:02Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing Surface Materials based on MaterialName.</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/654755#M10200</link>
      <description>&lt;P&gt;&lt;a href="https://community.graphisoft.com/t5/user/viewprofilepage/user-id/67174"&gt;@Hiromichi Shinkawa&lt;/a&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you for your reply!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;That doesn't fix the problem. The replacement of the Surface Material still doesn't seem to work.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For example, I want the Surface Material used in the&amp;nbsp;API_WindowID and&amp;nbsp;&lt;SPAN&gt;API_DoorID to be overwritten with a new Surface Material, based on the Material Name. &lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;Please let me know how to do this.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 11 Mar 2025 22:49:25 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/654755#M10200</guid>
      <dc:creator>KirthikaSrinivasan-L</dc:creator>
      <dc:date>2025-03-11T22:49:25Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing Surface Materials based on MaterialName.</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/662433#M10344</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://community.graphisoft.com/t5/user/viewprofilepage/user-id/67174"&gt;@Hiromichi Shinkawa&lt;/a&gt;&amp;nbsp;&lt;a href="https://community.graphisoft.com/t5/user/viewprofilepage/user-id/733"&gt;@Ralph Wessel&lt;/a&gt;,&lt;/P&gt;&lt;P&gt;Can you please help?&lt;/P&gt;&lt;P&gt;ACAPI_Attribute_Delete has been removed as per&amp;nbsp;&lt;a href="https://community.graphisoft.com/t5/user/viewprofilepage/user-id/67174"&gt;@Hiromichi Shinkawa&lt;/a&gt;'s suggestion. It didn't seem to fix the issue. I want to replace the old surface material with new surface material, in archicad, based on the surface material's name.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have got the attribute's index using FindSurfaceMaterialIndex().&lt;/P&gt;&lt;P&gt;Can you please let me know how I can perform the replacement of one surface material with another surface material?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="cpp"&gt;API_AttributeIndex FindSurfaceMaterialIndex(const char* MaterialName)
{
	API_AttrTypeID	typeID;
	GSErrCode		err = NoError;
	API_AttributeIndex test;

	for (typeID = API_FirstAttributeID; typeID &amp;lt;= API_LastAttributeID; ((Int32&amp;amp;)typeID)++) {
		GS::Array&amp;lt;API_Attribute&amp;gt; attributes;
		err = ACAPI_Attribute_GetAttributesByType(typeID, attributes);
		if (err != NoError) {
			DBPrintf("Error in ACAPI_Attribute_GetAttributesByType", err);
			continue;
		}

		if (typeID == API_MaterialID)
		{
			short count = 1;
			for (API_Attribute&amp;amp; attrib : attributes) {
				char guidStr[64];
				APIGuid2GSGuid(attrib.header.guid).ConvertToString(guidStr);

				if (strcmp(attrib.header.name, MaterialName) == 0) {  // Match found
					test = attrib.header.index;
					return test;
				}
				count++;  //index loc for reference
			}
		}

	}
	return ACAPI_CreateAttributeIndex(0);
}

// Function to replace a surface material
GSErrCode	ReplaceSurfaceMaterial(const char* oldMaterialName, const char* newMaterialName) {
	API_AttributeIndex oldAttribute = FindSurfaceMaterialIndex(oldMaterialName);
	API_AttributeIndex newAttribute = FindSurfaceMaterialIndex(newMaterialName);

	API_Attribute oldAttr, newAttr;
	BNZeroMemory(&amp;amp;oldAttr, sizeof(API_Attribute));
	BNZeroMemory(&amp;amp;newAttr, sizeof(API_Attribute));

	oldAttr.header.typeID = API_MaterialID;
	oldAttr.header.index = oldAttribute;

	newAttr.header.typeID = API_MaterialID;
	newAttr.header.index = newAttribute;

	if (ACAPI_Attribute_Get(&amp;amp;oldAttr) != NoError) {
		return 0;
	}

	// Copy all properties from the new material to the old material
	newAttr.material = oldAttr.material;  
	
	newAttr.material.texture.fileLoc = oldAttr.material.texture.fileLoc;

	char guidStr[64];
	APIGuid2GSGuid(newAttr.header.guid).ConvertToString(guidStr);

	DBPrintf("\n");
	DBPrintf("  [%3s]   {%s}  \"%s\"", newAttr.header.index.ToUniString().ToCStr().Get(), guidStr, newAttr.header.name);

	newAttr.header.index = oldAttr.header.index;

	GSErrCode err = ACAPI_Attribute_Modify(&amp;amp;newAttr, nullptr);
	if (err != NoError) {
		return err;
	}

	if (ACAPI_Attribute_Get(&amp;amp;newAttr) != NoError) {
		return 0;
	}

	return NoError;
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 14 May 2025 00:20:44 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/662433#M10344</guid>
      <dc:creator>KirthikaSrinivasan-L</dc:creator>
      <dc:date>2025-05-14T00:20:44Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing Surface Materials based on MaterialName.</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/662447#M10345</link>
      <description>&lt;P&gt;Do you just want to edit the existing materials rather than reassigning the materials assigned to elements?&lt;/P&gt;</description>
      <pubDate>Wed, 14 May 2025 07:19:18 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Replacing-Surface-Materials-based-on-MaterialName/m-p/662447#M10345</guid>
      <dc:creator>Ralph Wessel</dc:creator>
      <dc:date>2025-05-14T07:19:18Z</dc:date>
    </item>
  </channel>
</rss>

