Programmatically Rename Assembly with iParts

By Barbara Han

Issue

I want to programmatically rename all documents (for instance an assembly containing a part). I can do this successfully (I first open the part, and saves part with its new name, then open the assembly, call ReplaceReference on the part reference and then save the assembly with its new name).
However, if iParts are involved, I run into some issues.
I’ve a project containing the following hierarchy of documents:

// Top.iam
// A-4.ipt (iPart member)
//   A.ipt (iPart factory)
// A-6.ipt (iPart member)
//   A.ipt (iPart factory)
So there are 2 iPart members of the same iPart factory inserted into the assembly.
Now I want to rename the files according to a given naming scheme. In the sample code I use the following name changes:
// Rename "Top.iam" -> "001.iam"
// Rename "A.ipt" -> "002.ipt"
//
// The iPart member names will follow the updated iPart factory name, so that:
// "A-4.ipt" -> "002-4.ipt"
// "A-6.ipt" -> "002-6.ipt"

After the renaming operations, I did the following observations of the renamed files.

"001.iam": I get exclamation icons for both of the inserted iPart members. There is a red cross appearing in the title bar of Inventor, and if I press it, it opens "Design Doctor". There i get a message that "Member row deleted in factory".

"002.ipt" (iPart factory): If I right click the table in the tree view, I get a message "The values in the Active Row of the table do not match the document’s current values. Do you wish to update the table before continuing? Part Number : "A-01" != "002"".

Solution

In this case, iPart member file needs to be re-generated and then be replaced in the assembly file. The exclamation icon will be gone with this way.

Please refer to below C# sample code snippet:

//

// The following code will take an assembly containing 2 iPart members

// and rename all files.

//

// Original file references:

//

// Top.iam

// A-4.ipt (iPart member)

// A.ipt (iPart factory)

// A-6.ipt (iPart member)

// A.ipt (iPart factory)

//

// Rename "Top.iam" -> "001.iam"

// Rename "A.ipt" -> "002.ipt"

//

// The iPart member names will follow the updated iPart factory name, so that:

// "A-4.ipt" -> "002-4.ipt"

// "A-6.ipt" -> "002-6.ipt"

//

// First modify iPart factory

//

string partFactoryName = Path.Combine(sourceDir, "A.ipt");

Debug.WriteLine("Opening iPart factory " + partFactoryName);

Inventor._PartDocument part = (Inventor._PartDocument)Application.Documents.Open(partFactoryName, false);

Inventor.PartComponentDefinition partComponentDefinition = part.ComponentDefinition;

if (!partComponentDefinition.IsiPartFactory)

{

throw new Exception("Expected a factory");

}

Inventor.iPartFactory factory = partComponentDefinition.iPartFactory;

if (factory.CustomFactory)

{

throw new Exception("Custom factories not supporteed");

}

// Modify each member row

string oldPartNumber = (string)factory.DefaultRow[2].Value;

foreach (Inventor.iPartTableRow row in factory.TableRows)

{

string newRowPartName = row.PartName.Replace("A-", "002-");

//remove the .ipt in the string

newRowPartName = newRowPartName.Remove(newRowPartName.Length – 4);

row.PartName = newRowPartName;

}

//

// Save the modified factory to its new name

//

string newPartFactoryName = Path.Combine(destinationDir, "002.ipt");

Debug.WriteLine("Saving part factory with new name: " + newPartFactoryName);

//update the Part Number property in the iPart factory file to make it

//synchronous with the Part //Number in the iPart table

part.PropertySets["{32853F0F-3444-11d1-9E93-0060B03C1CA6}"].get_ItemByPropId(

(int)Inventor.PropertiesForDesignTrackingPropertiesEnum.

kPartNumberDesignTrackingProperties).Value=oldPartNumber;

part.SaveAs(newPartFactoryName,true);

part.Close(false); // already saved, so close with false

//re-generate the iPart member file

part = (Inventor._PartDocument)Application.Documents.Open(newPartFactoryName, false);

factory = part.ComponentDefinition.iPartFactory;

foreach (Inventor.iPartTableRow row in factory.TableRows)

{

factory.CreateMember(row);

}

part.Close(false); // already saved, so close with false

//

// Now modify the iPart members

//

string partMemberFileName1;

string newPartMemberFileName1;

string partMemberFileName2;

string newPartMemberFileName2;

//A-4 -> 002-4

partMemberFileName1 = Path.Combine(sourcePartMemberDir, "A-4.ipt");

newPartMemberFileName1 = Path.Combine(destinationPartMemberDir, "002-4.ipt");

//A-6 -> 002-6

partMemberFileName2 = Path.Combine(sourcePartMemberDir, "A-6.ipt");

newPartMemberFileName2 = Path.Combine(destinationPartMemberDir, "002-6.ipt");

//

// Open assembly, update references or replace iPart member occurrance, and save with new name

//

Inventor._AssemblyDocument assembly = (Inventor._AssemblyDocument)Application.Documents.Open(Path.Combine(sourceDir,

"Top.iam"), false);

foreach (Inventor.ComponentOccurrence occ in assembly.ComponentDefinition.Occurrences)

{

if (occ.ReferencedFileDescriptor.FullFileName.Equals(partMemberFileName1, StringComparison.OrdinalIgnoreCase))

{

occ.Replace(newPartMemberFileName1, true);

}

else if (occ.ReferencedFileDescriptor.FullFileName.Equals(partMemberFileName2,

StringComparison.OrdinalIgnoreCase))

{

occ.Replace(newPartMemberFileName2,
true);

}

}

assembly.Update();

// "Top.iam" -> "001.iam"

string newAssemblyFileName = Path.Combine(destinationDir, "001.iam");

Debug.WriteLine("Saving assembly with new name: " + newAssemblyFileName);

assembly.SaveAs(newAssemblyFileName, true);

assembly.Close(false);

//

// Open assembly and one of the iPart members to make sure they look correct after renaming

//

Application.Documents.Open(Path.Combine(destinationPartMemberDir, "002-4.ipt"), true);

Application.Documents.Open(Path.Combine(destinationDir, "001.iam"), true);

Debug.WriteLine("completed");

<

p style=”line-height: normal;margin: 0in 0in 0pt;background: white”>}


Comments

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading