SurfaceBody Appearance Override ignored?

SurfaceBody Appearance Override ignored?

c_hoppen
Advocate Advocate
76 Views
2 Replies
Message 1 of 3

SurfaceBody Appearance Override ignored?

c_hoppen
Advocate
Advocate

As a preview, I want to copy the surface bodies of all the assembly components into the ClientGraphics and make the components invisible.

This works fine, but all surface bodies appear dark grey. It looks like the appearance setting is being ignored.

Here is the code:

                foreach ((string Name, SurfaceBody SrfBody, Matrix Transformation) item in srfBodies)
                {
                    SurfaceBody srfBdy = item.SrfBody;
                    if (srfBdy.AppearanceSourceType == AppearanceSourceTypeEnum.kPartAppearance)
                    {
                        PartComponentDefinition partDef = (PartComponentDefinition)srfBdy.Parent;
                        PartDocument partDoc = (PartDocument)partDef.Document;                        
                        srfBdy.Appearance = partDoc.ActiveAppearance;
                    }
                    GraphicsNode node = cg.AddNode(nodeID++);
                    SurfaceGraphics srfG = node.AddSurfaceGraphics(srfBdy);                                     
                    node.Transformation = item.Transformation;
                }                
                invApp.ActiveView.Update();

Input:

image.png 

Result:

image.png

Before executing the line of code "srfBdy.Appearance = partDoc.ActiveAppearance;", the value of the AppearanceSourceTypeEnum is kPartAppearance. After changing the appearance, it turns into kOverrideAppearance.

Any suggestions?

Thanks & Regards

Christoph

 

0 Likes
Accepted solutions (1)
77 Views
2 Replies
Replies (2)
Message 2 of 3

WCrihfield
Mentor
Mentor

Hi @c_hoppen.  I have not done a lot with component SurfaceGraphics in ClientGraphics that involved specific appearances, but my guess is that the source 'appearance' (an Asset object) will need to be copied from the source document to the assembly document (Asset.CopyTo), then get the 'local copy' of it, before trying to set it as the value of something in the assembly.  That step happens automatically in the background when we do things manually, but not always when doing things through API code.

Out of curiosity, where are you sourcing the SurfaceBody object from?  If from the ComponentOccurrence.SurfaceBodies collection, then those bodies would be in the context of the assembly, and would likely get their appearance form the parent/owning component occurrence (by default), so if the component has already been set to that appearance while in the assembly, then a copy of the same appearance asset may already exist in the assembly.  If from ComponentOccurrence.Definition.SurfaceBodies collection, then they would be in the 'context' of the referenced document, so not sure how that would work.  Since the SurfaceBody.Parent property does not specify that it will return ComponentDefinition Type value, I wander if its Parent could possibly return a ComponentOccurrence object, instead of a ComponentDefinition object.  Just some thoughts.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 3

c_hoppen
Advocate
Advocate
Accepted solution

Finally, I got it!
I think you can't use the occurrence SurfaceBodies, but there is an API sample called 'Imprint bodies within an assembly' that does the following:

' copy to Transient BRep
Dim transBrep As TransientBRep = ThisApplication.TransientBRep
Dim body1 As SurfaceBody =  transBrep.Copy(part1.Definition.SurfaceBodies.Item(1))
Dim body2 As SurfaceBody =  transBrep.Copy(part2.Definition.SurfaceBodies.Item(1))

' Transform the bodies (NOT THE GRAPHICS NODE!) to be in the location represented in the assembly.
Call transBrep.Transform(body1, part1.Transformation)
Call transBrep.Transform(body2, part2.Transformation)

The trick is to assign the appearance to the graphics node rather than to the surface body.

There is an API sample called "Client Graphics - Line". The example gave me the crucial clue:

' Assign a color to the node using an existing appearance asset.
Dim oAppearance As Asset = oDoc.AppearanceAssets(1)
oLineNode.Appearance = oAppearance

So, the inner piece of my loop is like this: 

// copy the part SrfBody to BREP and transform:
SurfaceBody bRepSrfBdy = bRep.Copy(item.SrfBody);
bRep.Transform(bRepSrfBdy, item.Transformation);

// get part appearance and copy to assembly
PartComponentDefinition partDef = (PartComponentDefinition)item.SrfBody.Parent;
PartDocument partDoc = (PartDocument)partDef.Document;
try
{
    _ = partDoc.ActiveAppearance.CopyTo(assmDoc, true);
}
catch { /* appearance already exists */ }
Asset assemblyAppearance = assmDoc.AppearanceAssets[partDoc.ActiveAppearance.Name];

// build the graphics node
GraphicsNode node = cg.AddNode(nodeID++);
SurfaceGraphics srfG = node.AddSurfaceGraphics(bRepSrfBdy);

// assign the appearance
node.Appearance = assemblyAppearance;

Side note: I find it particularly strange that my code was executed without any exceptions.

Regard Christoph