Skip to content

Commit

Permalink
EMSUSD-1891 Don't dirty stage when loading
Browse files Browse the repository at this point in the history
- Don't create light attributes when reading them.
- Make all set function create the attribute if it does not exists.
- Add a unit test for loading stage with lights not being dirty.
  • Loading branch information
pierrebai-adsk committed Dec 4, 2024
1 parent 8883de1 commit 160f07c
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 39 deletions.
86 changes: 53 additions & 33 deletions lib/mayaUsd/ufe/UsdLight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,10 @@ void setLightIntensity(const UsdPrim& prim, float attrVal)
const UsdLuxLightAPI lightSchema(prim);
const PXR_NS::UsdAttribute lightAttribute = lightSchema.GetIntensityAttr();

lightAttribute.Set(attrVal);
if (!lightAttribute)
lightSchema.CreateIntensityAttr(VtValue(attrVal));
else
lightAttribute.Set(attrVal);
}

Ufe::Light::IntensityUndoableCommand::Ptr UsdLight::intensityCmd(float li)
Expand Down Expand Up @@ -172,8 +175,10 @@ void setLightColor(const UsdPrim& prim, const Ufe::Color3f& attrVal)
{
const UsdLuxLightAPI lightSchema(prim);
const PXR_NS::UsdAttribute lightAttribute = lightSchema.GetColorAttr();

lightAttribute.Set(GfVec3f(attrVal.r(), attrVal.g(), attrVal.b()));
if (!lightAttribute)
lightSchema.CreateColorAttr(VtValue(GfVec3f(attrVal.r(), attrVal.g(), attrVal.b())));
else
lightAttribute.Set(GfVec3f(attrVal.r(), attrVal.g(), attrVal.b()));
}

Ufe::Light::ColorUndoableCommand::Ptr UsdLight::colorCmd(float r, float g, float b)
Expand All @@ -194,12 +199,6 @@ bool getLightShadowEnable(const UsdPrim& prim)
const UsdLuxShadowAPI shadowAPI(prim);
PXR_NS::UsdAttribute lightAttribute = shadowAPI.GetShadowEnableAttr();

if (!lightAttribute) {
// If the shadow enable attribute is not created yet, create one here
lightAttribute = shadowAPI.CreateShadowEnableAttr(VtValue(true));
return true;
}

bool val = false;
lightAttribute.Get(&val);
return val;
Expand All @@ -210,9 +209,10 @@ void setLightShadowEnable(const UsdPrim& prim, bool attrVal)
const UsdLuxShadowAPI shadowAPI(prim);
const PXR_NS::UsdAttribute lightAttribute = shadowAPI.GetShadowEnableAttr();

if (lightAttribute) {
if (lightAttribute)
lightAttribute.Set(attrVal);
}
else
shadowAPI.CreateShadowEnableAttr(VtValue(attrVal));
}

Ufe::Light::ShadowEnableUndoableCommand::Ptr UsdLight::shadowEnableCmd(bool se)
Expand All @@ -232,11 +232,6 @@ Ufe::Color3f getLightShadowColor(const UsdPrim& prim)
const UsdLuxShadowAPI shadowAPI(prim);
PXR_NS::UsdAttribute lightAttribute = shadowAPI.GetShadowColorAttr();

if (!lightAttribute) {
// If the shadow color attribute is not created yet, create one here
lightAttribute = shadowAPI.CreateShadowColorAttr();
}

GfVec3f val(0.f, 0.f, 0.f);
lightAttribute.Get(&val);
return Ufe::Color3f(val[0], val[1], val[2]);
Expand All @@ -246,8 +241,10 @@ void setLightShadowColor(const UsdPrim& prim, const Ufe::Color3f& attrVal)
{
const UsdLuxShadowAPI shadowAPI(prim);
const PXR_NS::UsdAttribute lightAttribute = shadowAPI.GetShadowColorAttr();

lightAttribute.Set(GfVec3f(attrVal.r(), attrVal.g(), attrVal.b()));
if (!lightAttribute)
shadowAPI.CreateShadowColorAttr(VtValue(GfVec3f(attrVal.r(), attrVal.g(), attrVal.b())));
else
lightAttribute.Set(GfVec3f(attrVal.r(), attrVal.g(), attrVal.b()));
}

Ufe::Light::ShadowColorUndoableCommand::Ptr UsdLight::shadowColorCmd(float r, float g, float b)
Expand Down Expand Up @@ -280,8 +277,10 @@ void setLightDiffuse(const UsdPrim& prim, float attrVal)
{
const UsdLuxLightAPI lightSchema(prim);
const PXR_NS::UsdAttribute lightAttribute = lightSchema.GetDiffuseAttr();

lightAttribute.Set(attrVal);
if (!lightAttribute)
lightSchema.CreateDiffuseAttr(VtValue(attrVal));
else
lightAttribute.Set(attrVal);
}

Ufe::Light::DiffuseUndoableCommand::Ptr UsdLight::diffuseCmd(float ld)
Expand Down Expand Up @@ -310,8 +309,10 @@ void setLightSpecular(const UsdPrim& prim, float attrVal)
{
const UsdLuxLightAPI lightSchema(prim);
const PXR_NS::UsdAttribute lightAttribute = lightSchema.GetSpecularAttr();

lightAttribute.Set(attrVal);
if (!lightAttribute)
lightSchema.CreateSpecularAttr(VtValue(attrVal));
else
lightAttribute.Set(attrVal);
}

Ufe::Light::SpecularUndoableCommand::Ptr UsdLight::specularCmd(float ls)
Expand Down Expand Up @@ -340,8 +341,10 @@ void setLightAngle(const UsdPrim& prim, float attrVal)
{
const UsdLuxDistantLight lightSchema(prim);
const PXR_NS::UsdAttribute lightAttribute = lightSchema.GetAngleAttr();

lightAttribute.Set(attrVal);
if (!lightAttribute)
lightSchema.CreateAngleAttr(VtValue(attrVal));
else
lightAttribute.Set(attrVal);
}

Ufe::Light::AngleUndoableCommand::Ptr UsdDirectionalInterface::angleCmd(float la)
Expand Down Expand Up @@ -371,8 +374,10 @@ void setLightSphereProps(const UsdPrim& prim, const Ufe::Light::SphereProps& att
{
const UsdLuxSphereLight lightSchema(prim);
const PXR_NS::UsdAttribute lightAttribute = lightSchema.GetRadiusAttr();

lightAttribute.Set(attrVal.radius);
if (!lightAttribute)
lightSchema.CreateRadiusAttr(VtValue(attrVal.radius));
else
lightAttribute.Set(attrVal.radius);
}

Ufe::Light::SpherePropsUndoableCommand::Ptr
Expand Down Expand Up @@ -416,12 +421,22 @@ void setLightConeProps(const UsdPrim& prim, const Ufe::Light::ConeProps& attrVal
{
const UsdLuxShapingAPI lightSchema(prim);
const PXR_NS::UsdAttribute focusAttribute = lightSchema.GetShapingFocusAttr();
if (!focusAttribute)
lightSchema.CreateShapingFocusAttr(VtValue(attrVal.focus));
else
focusAttribute.Set(attrVal.focus);

const PXR_NS::UsdAttribute coneAngleAttribute = lightSchema.GetShapingConeAngleAttr();
const PXR_NS::UsdAttribute coneSoftnessAttribute = lightSchema.GetShapingConeSoftnessAttr();
if (!coneAngleAttribute)
lightSchema.CreateShapingConeAngleAttr(VtValue(attrVal.angle));
else
coneAngleAttribute.Set(attrVal.angle);

focusAttribute.Set(attrVal.focus);
coneAngleAttribute.Set(attrVal.angle);
coneSoftnessAttribute.Set(attrVal.softness);
const PXR_NS::UsdAttribute coneSoftnessAttribute = lightSchema.GetShapingConeSoftnessAttr();
if (!coneSoftnessAttribute)
lightSchema.CreateShapingConeSoftnessAttr(VtValue(attrVal.softness));
else
coneSoftnessAttribute.Set(attrVal.softness);
}

Ufe::Light::ConePropsUndoableCommand::Ptr
Expand Down Expand Up @@ -459,7 +474,10 @@ void setLightNormalize(const UsdPrim& prim, bool attrVal)
const UsdLuxRectLight rectLight(prim);
const PXR_NS::UsdAttribute lightAttribute = rectLight.GetNormalizeAttr();

lightAttribute.Set(attrVal);
if (!lightAttribute)
rectLight.CreateNormalizeAttr(VtValue(attrVal));
else
lightAttribute.Set(attrVal);
}

Ufe::Light::NormalizeUndoableCommand::Ptr UsdAreaInterface::normalizeCmd(bool nl)
Expand Down Expand Up @@ -505,8 +523,10 @@ void setLightVolumeProps(const UsdPrim& prim, const UFE_LIGHT_BASE::VolumeProps&
{
const UsdLuxSphereLight lightSchema(prim);
const PXR_NS::UsdAttribute lightAttribute = lightSchema.GetRadiusAttr();

lightAttribute.Set(attrVal.radius);
if (!lightAttribute)
lightSchema.CreateRadiusAttr(VtValue(attrVal.radius));
else
lightAttribute.Set(attrVal.radius);
}

void UsdCylinderInterface::volumeProps(float radius, float length)
Expand Down
38 changes: 32 additions & 6 deletions test/lib/ufe/testLight.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import ufeUtils
import usdUtils

from pxr import Gf
from pxr import Gf, Sdf

from maya import cmds
from maya import standalone
Expand Down Expand Up @@ -75,9 +75,10 @@ def _StartTest(self, testName):
cmds.file(force=True, new=True)
self._testName = testName
testFile = testUtils.getTestScene("light", self._testName + ".usda")
mayaUtils.createProxyFromFile(testFile)
shapeNode, shapeStage = mayaUtils.createProxyFromFile(testFile)
globalSelection = ufe.GlobalSelection.get()
globalSelection.clear()
return shapeNode, shapeStage

def _TestSpotLight(self, ufeLight, usdLight):
# Trust that the USD API works correctly, validate that UFE gives us
Expand Down Expand Up @@ -240,8 +241,9 @@ def _TestAreaProps(self, ufeLight, usdLight):
self.assertEqual(usdAttr.Get(), ufeLight.areaInterface().normalize())

def testUsdLight(self):
self._StartTest('SimpleLight')
mayaPathSegment = mayaUtils.createUfePathSegment('|stage|stageShape')
shapeNode, _ = self._StartTest('SimpleLight')

mayaPathSegment = mayaUtils.createUfePathSegment(shapeNode)

# test spot light
spotlightUsdPathSegment = usdUtils.createUfePathSegment('/lights/spotLight')
Expand Down Expand Up @@ -281,8 +283,8 @@ def testUsdLight(self):

@unittest.skipUnless(os.getenv('UFE_VOLUME_LIGHTS_SUPPORT', 'FALSE') == 'TRUE', 'UFE has volume light support.')
def testUsdVolumeLights(self):
self._StartTest('SimpleLight')
mayaPathSegment = mayaUtils.createUfePathSegment('|stage|stageShape')
shapeNode, _ = self._StartTest('SimpleLight')
mayaPathSegment = mayaUtils.createUfePathSegment(shapeNode)
# test cylinder light
cylinderlightUsdPathSegment = usdUtils.createUfePathSegment('/lights/cylinderLight')
cylinderlightPath = ufe.Path([mayaPathSegment, cylinderlightUsdPathSegment])
Expand Down Expand Up @@ -319,6 +321,30 @@ def testUsdVolumeLights(self):
usdDomeLight = usdUtils.getPrimFromSceneItem(domelightItem)
self._TestDomeLight(ufeDomeLight, usdDomeLight)

def testLoadingLight(self):
'''
Verify that the act of loading a stage with lights does not dirty the stage.
'''
shapeNode, stage = self._StartTest('SimpleLight')
mayaPathSegment = mayaUtils.createUfePathSegment(shapeNode)

# Verify the stage is not dirty
def verifyClean():
layer: Sdf.Layer = stage.GetRootLayer()
self.assertFalse(layer.dirty)

verifyClean()

# Access the cylinder light shadow enable attribute.
noAttrlightUsdPathSegment = usdUtils.createUfePathSegment('/lights/noAttrLight')
noAttrlightPath = ufe.Path([mayaPathSegment, noAttrlightUsdPathSegment])
noAttrlightItem = ufe.Hierarchy.createItem(noAttrlightPath)

ufeLight = ufe.Light.light(noAttrlightItem)
self.assertFalse(ufeLight.shadowEnable())

verifyClean()


if __name__ == '__main__':
unittest.main(verbosity=2)
5 changes: 5 additions & 0 deletions test/testSamples/light/SimpleLight.usda
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,10 @@ def Xform "lights"
color3f inputs:shadow:color
bool inputs:shadow:enable = 1
}

def CylinderLight "noAttrLight"
{
}

}

0 comments on commit 160f07c

Please sign in to comment.