C# Component Occurrence Suppression Error

C# Component Occurrence Suppression Error

ianjwellings
Contributor Contributor
1,950 Views
11 Replies
Message 1 of 12

C# Component Occurrence Suppression Error

ianjwellings
Contributor
Contributor

Hi, I'm trying to loop through an assembly tree and suppress occurrences, the first occurrence is suppressed but I get the following error right afterwards and no more occurrences are suppressed: Unspecified error (Exception from HRESULT: 0x80004005 (E_FAIL))

 

public void AssemblyCount()

        {

            AssemblyDocument oAssemblyDoc = (AssemblyDocument)invApp.ActiveDocument;

            AssemblyComponentDefinition oCompDef = oAssemblyDoc.ComponentDefinition;

            string sMsg = "";

            long iLeafNodes = 0;

            long iSubAssemblies = 0;

 

            foreach (ComponentOccurrence oCompOcc in oCompDef.Occurrences)

            {

                    if (oCompOcc.SubOccurrences.Count == 0)

                    {

                        oCompOcc.Suppress();

                        iLeafNodes++;

                    }

                    else

                    {

                        oCompOcc.Suppress();

                        iSubAssemblies++;

                        processAllSubOcc(oCompOcc, ref sMsg, ref iLeafNodes, ref iSubAssemblies);

                    }

            }

        }

 

 

private void processAllSubOcc(ComponentOccurrence oCompOcc, ref string sMsg, ref long iLeafNodes, ref long iSubAssemblies)

        {

            foreach (ComponentOccurrence oSubCompOcc in oCompOcc.SubOccurrences)

            {

               

                    if (oSubCompOcc.SubOccurrences.Count == 0)

                    {

                        oSubCompOcc.Suppress();

                        iLeafNodes++;

                    }

                    else

                    {                               

oSubCompOcc.Suppress();                   

                        sMsg = sMsg + oSubCompOcc.Name;

                        iSubAssemblies++;

                        processAllSubOcc(oSubCompOcc, ref sMsg, ref iLeafNodes, ref iSubAssemblies);

                    }      

            }

        }

 

0 Likes
Accepted solutions (1)
1,951 Views
11 Replies
Replies (11)
Message 2 of 12

jjstr8
Collaborator
Collaborator

You're trying to access a sub-occurrence after the parent is suppressed.  Make your call to suppress sub-occurrences before suppressing the parent.  It will work its way to the bottom of an assembly tree and suppress the parent assemblies on the way back up.

public void AssemblyCount()
{
    AssemblyDocument oAssemblyDoc = (AssemblyDocument)invApp.ActiveDocument;
    AssemblyComponentDefinition oCompDef = oAssemblyDoc.ComponentDefinition;
    string sMsg = "";
    long iLeafNodes = 0;
    long iSubAssemblies = 0;

    foreach (ComponentOccurrence oCompOcc in oCompDef.Occurrences)
    {
        if (oCompOcc.SubOccurrences.Count == 0)
        {
            oCompOcc.Suppress();
            iLeafNodes++;
        }
        else
        {
            processAllSubOcc(oCompOcc, ref sMsg, ref iLeafNodes, ref iSubAssemblies);
            oCompOcc.Suppress();
            iSubAssemblies++;
        }
    }
}
private void processAllSubOcc(ComponentOccurrence oCompOcc, ref string sMsg, ref long iLeafNodes, ref long iSubAssemblies)
{
    foreach (ComponentOccurrence oSubCompOcc in oCompOcc.SubOccurrences)
    {
        if (oSubCompOcc.SubOccurrences.Count == 0)
        {
            oSubCompOcc.Suppress();
            iLeafNodes++;
        }
        else
        {
            processAllSubOcc(oSubCompOcc, ref sMsg, ref iLeafNodes, ref iSubAssemblies);
            oSubCompOcc.Suppress();
            sMsg = sMsg + oSubCompOcc.Name;
            iSubAssemblies++;
        }
    }
}
0 Likes
Message 3 of 12

ianjwellings
Contributor
Contributor

Thank you for getting back so quickly.  I'm still having the same issue.  I have a datagridview with two columns called OccurenceName and Suppression.  There are currently two rows in the datagridview:

 

Occurence Name    Suppression

PipeRing:1                Suppress

PipeRing:2                Suppress

 

I then have the following code to loop though the datagridview getting the Occurrence name and whether it is set to Suppress or Unsuppress:

 

public string oOcc;
public string oSupp;

private void button1_Click(object sender, EventArgs e)
{
foreach (DataRow row in dataGridView1.Rows)
{
oOcc = row["OccurenceName"].ToString();
oSupp = row["Suppression"].ToString();
AssemblyCount();
}
}


public void AssemblyCount()
{
AssemblyDocument oAssemblyDoc = (AssemblyDocument)invApp.ActiveDocument;
AssemblyComponentDefinition oCompDef = oAssemblyDoc.ComponentDefinition;
string sMsg = "";
long iLeafNodes = 0;
long iSubAssemblies = 0;

foreach (ComponentOccurrence oCompOcc in oCompDef.Occurrences)
{
if (oCompOcc.SubOccurrences.Count == 0)
{
if ((oCompOcc.Name == oOcc) && (oSupp == "Suppress"))
{
oCompOcc.Suppress();
}
else if ((oCompOcc.Name == oOcc) && (oSupp == "Unsuppress")
{
oCompOcc.Unsuppress();
}
iLeafNodes++;
}
else
{
if ((oCompOcc.Name == oOcc) && (oSupp == "Suppress"))
{
oCompOcc.Suppress();
}
else if ((oCompOcc.Name == oOcc) && (oSupp == "Unsuppress"))
{
oCompOcc.Unsuppress();
}
iSubAssemblies++;
processAllSubOcc(oCompOcc, ref sMsg, ref iLeafNodes, ref iSubAssemblies);
}

}
}

private void processAllSubOcc(ComponentOccurrence oCompOcc, ref string sMsg, ref long iLeafNodes, ref long iSubAssemblies)
{
foreach (ComponentOccurrence oSubCompOcc in oCompOcc.SubOccurrences)
{

if (oSubCompOcc.SubOccurrences.Count == 0)
{
if ((oSubCompOcc.Name == oOcc) && (oSupp == "Suppress"))
{
oSubCompOcc.Suppress();
}
else if ((oSubCompOcc.Name == oOcc) && (oSupp == "Unsuppress"))
{
oSubCompOcc.Unsuppress();
}
iLeafNodes++;
}
else
{
if ((oSubCompOcc.Name == oOcc) && (oSupp == "Suppress"))
{
oSubCompOcc.Suppress();
}
else if ((oSubCompOcc.Name == oOcc) && (oSupp == "Unsuppress"))
{
oSubCompOcc.Unsuppress();
}
sMsg = sMsg + oSubCompOcc.Name;
iSubAssemblies++;
processAllSubOcc(oSubCompOcc, ref sMsg, ref iLeafNodes, ref iSubAssemblies);
}
}
}

 

The first occurrence PipeRing:1 is suppressed but the same error appears straight after suppressing and nothing happens to PipeRing:2

0 Likes
Message 4 of 12

jjstr8
Collaborator
Collaborator

As in your original post, you're calling processAllSubDocs after  (potentially) suppressing the parent.  I don't know where your two occurrences are in the assembly tree, but that could cause an issue.  Since you can't access the children of a suppressed parent, you'll probably only want to call processAllSubOcc only for an unsuppressed parent.  Just as a side note, when your post code, use the </> button to insert code for better readability.

public void AssemblyCount()
{
    AssemblyDocument oAssemblyDoc = (AssemblyDocument)invApp.ActiveDocument;
    AssemblyComponentDefinition oCompDef = oAssemblyDoc.ComponentDefinition;
    string sMsg = "";
    long iLeafNodes = 0;
    long iSubAssemblies = 0;

    foreach (ComponentOccurrence oCompOcc in oCompDef.Occurrences)
    {
        if (oCompOcc.SubOccurrences.Count == 0)
        {
            if ((oCompOcc.Name == oOcc) && (oSupp == "Suppress")) oCompOcc.Suppress();
            else if ((oCompOcc.Name == oOcc) && (oSupp == "Unsuppress")) oCompOcc.Unsuppress();
            iLeafNodes++;
        }
        else
        {
            if ((oCompOcc.Name == oOcc) && (oSupp == "Suppress")) oCompOcc.Suppress();
            else if ((oCompOcc.Name == oOcc) && (oSupp == "Unsuppress"))
            {
                oCompOcc.Unsuppress();
                processAllSubOcc(oCompOcc, ref sMsg, ref iLeafNodes, ref iSubAssemblies);
            }
            iSubAssemblies++;
        }
    }
}

private void processAllSubOcc(ComponentOccurrence oCompOcc, ref string sMsg, ref long iLeafNodes, ref long iSubAssemblies)
{
    foreach (ComponentOccurrence oSubCompOcc in oCompOcc.SubOccurrences)
    {
        if (oSubCompOcc.SubOccurrences.Count == 0)
        {
            if ((oSubCompOcc.Name == oOcc) && (oSupp == "Suppress")) oSubCompOcc.Suppress();
            else if ((oSubCompOcc.Name == oOcc) && (oSupp == "Unsuppress")) oSubCompOcc.Unsuppress();
            iLeafNodes++;
        }
        else
        {
            if ((oSubCompOcc.Name == oOcc) && (oSupp == "Suppress")) oSubCompOcc.Suppress();
            else if ((oSubCompOcc.Name == oOcc) && (oSupp == "Unsuppress"))
            {
                oSubCompOcc.Unsuppress();
                processAllSubOcc(oSubCompOcc, ref sMsg, ref iLeafNodes, ref iSubAssemblies);
            }
            sMsg = sMsg + oSubCompOcc.Name;
            iSubAssemblies++;
        }
    }
}
0 Likes
Message 5 of 12

ianjwellings
Contributor
Contributor

Thank you for your advice, I have tried processing the sub occurrences first and still get the same error.  My assembly is simple it's just an assembly with 3 components but I need to cover all eventualities if there are sub assemblies at some point:

 

Pipe.iam

   Pipe:1

   PipeRing:1

   PipeRing:2

 

After suppressing PipeRing:1 I still get the error?

0 Likes
Message 6 of 12

jjstr8
Collaborator
Collaborator

I can't see why it wouldn't work.  Can you post your current code?  Are the three components parts?  Just as a general suggestion, rather than calling AssemblyCount for each DataRow, I would build a list first and use that in your AssemblyCount method.  Check the entire list as you're traversing the assembly tree.  That will allow you to suppress/unsuppress a child of a parent that's going from a suppressed state to an unsuppressed state.  Your order of components in the DataGrid wouldn't matter at that point.

0 Likes
Message 7 of 12

chandra.shekar.g
Autodesk Support
Autodesk Support

@ianjwellings,

 

Please provide non confidential assembly files to test the behavior.

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes
Message 8 of 12

ianjwellings
Contributor
Contributor

I've attached the application code and the example assembly that I'm using.  I appreciate your help with this, thank you

0 Likes
Message 9 of 12

jjstr8
Collaborator
Collaborator

When you get to "PipeRing:2", your foreach is trying to check for the SubOccurrences count on "PipeRing:1", which is already suppressed.  Inventor only gives you limited access to a suppressed occurrence.  Change your 'if' statements to check if it's a part document instead.

 

if (oCompOcc.DefinitionDocumentType == DocumentTypeEnum.kPartDocumentObject)
0 Likes
Message 10 of 12

jjstr8
Collaborator
Collaborator
Accepted solution

Here's an example of my earlier suggestion of building a list first, then work through the occurrences and sub-occurrences.

0 Likes
Message 11 of 12

chandra.shekar.g
Autodesk Support
Autodesk Support

@ianjwellings,

 

Try below changes in the function "AssemblyCount()".

public void AssemblyCount()
        {
            AssemblyDocument oAssemblyDoc = (AssemblyDocument)invApp.ActiveDocument;
            AssemblyComponentDefinition oCompDef = oAssemblyDoc.ComponentDefinition;
            string sMsg = "";
            long iLeafNodes = 0;
            long iSubAssemblies = 0;

            foreach (ComponentOccurrence oCompOcc in oCompDef.Occurrences)
            {
                if (oCompOcc.Suppressed == false )
                {
                    if (oCompOcc.SubOccurrences.Count == 0)
                    {
                        if ((oCompOcc.Name == oOcc) && (oSupp == "Suppress"))
                        {
                            oCompOcc.Suppress();
                        }
                        else if ((oCompOcc.Name == oOcc) && (oSupp == "Unsuppress"))
                        {
                            oCompOcc.Unsuppress();
                        }
                        iLeafNodes++;
                    }
                    else
                    {
                        if ((oCompOcc.Name == oOcc) && (oSupp == "Suppress"))
                        {
                            oCompOcc.Suppress();
                        }
                        else if ((oCompOcc.Name == oOcc) && (oSupp == "Unsuppress"))
                        {
                            oCompOcc.Unsuppress();
                        }
                        iSubAssemblies++;
                        processAllSubOcc(oCompOcc, ref sMsg, ref iLeafNodes, ref iSubAssemblies);
                    }
                } 

            }
        }

After suppressing any occurrence, suboccurrences are unable to retrieve it. Refer below image for more information.

 

Suppressed_Occurrence.png

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes
Message 12 of 12

ianjwellings
Contributor
Contributor

Thank you very much for your help with this.  I've also tested the code on an assembly with sub assemblies and it works great, also much faster by building the list first.

0 Likes