Skip to content

Silent geometry invisibility caused by primitive variable with mismatched point count #6937

Description

@LinasBeres

Version: 1.6.18.0-linux
Third-party tools: N/A
Third-party modules: N/A

Description

A mesh appears in the scene hierarchy and the Primitive Inspector shows its primitive variables, but it is completely invisible in the viewport and in renders. The root cause was a custom primitive variable that contained empty values for certain points. There is no error or warning generated and the geometry silently fails to display, making this very difficult to diagnose.

Deleting the offending primitive variable via a DeletePrimitiveVariables node restores visibility.

Steps to reproduce

  1. Load a mesh that has a primitive variable with empty/missing values for a subset of points.
  2. Connect it into a SceneBuilderCustomAttributesIsolateDeletePrimitiveVariables network.
  3. Mesh appears in the hierarchy and Primitive Inspector, but is invisible in the viewport.
  4. No error or warning is produced.
  5. Adding a DeletePrimitiveVariables node targeting the problematic variable causes the mesh to become visible again.

Expected behaviour

Gaffer should emit a warning or error when a primitive variable contains empty/malformed values that cause geometry to not display, rather than silently hiding the object.

Debug log

N/A

Create Bad .scc

import imath
import IECore
import IECoreScene

# Create a simple plane mesh
mesh = IECoreScene.MeshPrimitive.createPlane( imath.Box2f( imath.V2f( -1 ), imath.V2f( 1 ) ), imath.V2i( 4, 4 ) )

# Add an "inflate" prim var with fewer values than there are points
badData = IECore.FloatVectorData( [ 0.0 ] * 10 )
mesh["inflate"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, badData )

# Write as .scc
writer = IECoreScene.SceneInterface.create( "./mesh_with_bad_prim_var.scc", IECore.IndexedIO.OpenMode.Write )
location = writer.createChild( "hero" ).createChild( "ROOT" ).createChild( "test_body" ).createChild( "test_body_t" )
location.writeObject( mesh, 0.0 )

Gaffer File

import Gaffer
import GafferScene
import IECore
import imath

Gaffer.Metadata.registerValue( parent, "serialiser:milestoneVersion", 1, persistent=False )
Gaffer.Metadata.registerValue( parent, "serialiser:majorVersion", 6, persistent=False )
Gaffer.Metadata.registerValue( parent, "serialiser:minorVersion", 18, persistent=False )
Gaffer.Metadata.registerValue( parent, "serialiser:patchVersion", 0, persistent=False )

__children = {}

__children["SceneReader"] = GafferScene.SceneReader( "SceneReader" )
parent.addChild( __children["SceneReader"] )
__children["SceneReader"].addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue = imath.V2f( 0, 0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) )

__children["PathFilter"] = GafferScene.PathFilter( "PathFilter" )
parent.addChild( __children["PathFilter"] )
__children["PathFilter"].addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue = imath.V2f( 0, 0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) )

__children["CustomAttributes"] = GafferScene.CustomAttributes( "CustomAttributes" )
parent.addChild( __children["CustomAttributes"] )
__children["CustomAttributes"]["attributes"].addChild( Gaffer.NameValuePlug( "", Gaffer.FloatPlug( "value", defaultValue = 0.0, ), True, "member0", Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) )
__children["CustomAttributes"].addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue = imath.V2f( 0, 0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) )

__children["Isolate"] = GafferScene.Isolate( "Isolate" )
parent.addChild( __children["Isolate"] )
__children["Isolate"].addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue = imath.V2f( 0, 0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) )

__children["DeletePrimitiveVariables"] = GafferScene.DeletePrimitiveVariables( "DeletePrimitiveVariables" )
parent.addChild( __children["DeletePrimitiveVariables"] )
__children["DeletePrimitiveVariables"].addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue = imath.V2f( 0, 0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) )

__children["SceneReader"]["fileName"].setValue( './mesh_with_bad_prim_var.scc' )
__children["SceneReader"]["__uiPosition"].setValue( imath.V2f( -3768.21313, 2939.00000 ) )

__children["PathFilter"]["paths"].setValue( IECore.StringVectorData( [ '/hero/ROOT/test_body/test_body_t' ] ) )
__children["PathFilter"]["__uiPosition"].setValue( imath.V2f( -3748.90405, 2923.00000 ) )

__children["CustomAttributes"]["in"].setInput( __children["SceneReader"]["out"] )
__children["CustomAttributes"]["attributes"]["member0"]["name"].setValue( 'scene:visible' )
__children["CustomAttributes"]["attributes"]["member0"]["value"].setValue( 1.0 )
__children["CustomAttributes"]["__uiPosition"].setValue( imath.V2f( -3766.71387, 2923.00000 ) )

__children["Isolate"]["in"].setInput( __children["CustomAttributes"]["out"] )
__children["Isolate"]["filter"].setInput( __children["PathFilter"]["out"] )
__children["Isolate"]["__uiPosition"].setValue( imath.V2f( -3766.71387, 2907.94312 ) )

__children["DeletePrimitiveVariables"]["in"].setInput( __children["Isolate"]["out"] )
__children["DeletePrimitiveVariables"]["names"].setValue( 'inflate' )
__children["DeletePrimitiveVariables"]["__uiPosition"].setValue( imath.V2f( -3766.71387, 2892.00000 ) )

del __children

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Up Next

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions