| 230 | } |
| 231 | |
| 232 | Exec_AttributeValueInvalidationResult |
| 233 | Exec_Program::InvalidateAttributeAuthoredValues( |
| 234 | TfSpan<const SdfPath> invalidAttributes) |
| 235 | { |
| 236 | TRACE_FUNCTION(); |
| 237 | |
| 238 | const size_t numInvalidAttributes = invalidAttributes.size(); |
| 239 | |
| 240 | VdfMaskedOutputVector leafInvalidationRequest; |
| 241 | leafInvalidationRequest.reserve(numInvalidAttributes); |
| 242 | TfBits compiledProperties(numInvalidAttributes); |
| 243 | _inputNodesRequiringInvalidation.reserve( |
| 244 | _inputNodesRequiringInvalidation.size() + numInvalidAttributes); |
| 245 | EfTimeInterval totalInvalidInterval; |
| 246 | bool isTimeDependencyChange = false; |
| 247 | |
| 248 | for (size_t i = 0; i < numInvalidAttributes; ++i) { |
| 249 | const SdfPath &path = invalidAttributes[i]; |
| 250 | const auto it = _attributeInputNodes.find(path); |
| 251 | |
| 252 | // Not every invalid property is also an input to the exec network. |
| 253 | // If any of these properties have been included in an exec request, |
| 254 | // clients still expect to receive invalidation notices, though. |
| 255 | // However, we can skip including this property in the search for |
| 256 | // dependent leaf nodes in that case. |
| 257 | const bool isCompiled = it != _attributeInputNodes.end(); |
| 258 | if (!isCompiled) { |
| 259 | continue; |
| 260 | } |
| 261 | |
| 262 | // Indicate this property was compiled. |
| 263 | compiledProperties.Set(i); |
| 264 | |
| 265 | // Get the input node from the network. |
| 266 | _AttributeInputNodeEntry &entry = it->second; |
| 267 | Exec_AttributeInputNode *const node = entry.node; |
| 268 | |
| 269 | // Make sure that the input node's internal value resolution state is |
| 270 | // updated after scene changes that could affect where resolved values |
| 271 | // are sourced from. |
| 272 | node->UpdateValueResolutionState(); |
| 273 | |
| 274 | // Figure out if the input node's time dependence has changed based on |
| 275 | // the authored value change. |
| 276 | if (node->UpdateTimeDependence()) { |
| 277 | _InvalidateTimeDependentOutputs(); |
| 278 | isTimeDependencyChange = true; |
| 279 | } |
| 280 | |
| 281 | // Since this is an input node to the exec network, we need to make sure |
| 282 | // that executors are invalidated before the next round of evaluation. |
| 283 | _inputNodesRequiringInvalidation.push_back(node->GetId()); |
| 284 | |
| 285 | // Queue the input node's output(s) for leaf node invalidation. |
| 286 | leafInvalidationRequest.emplace_back( |
| 287 | node->GetOutput(), VdfMask::AllOnes(1)); |
| 288 | |
| 289 | // Accumulate the invalid time interval, but only if the interval |
no test coverage detected