// Internal validation // ------------------------------------------------- public override void ValidateNode() { var isInError = false; // all children nodes needs to be updated first // so do that here var slots = ListPool <MaterialSlot> .Get(); GetInputSlots(slots); foreach (var inputSlot in slots) { inputSlot.hasError = false; var edges = owner.GetEdges(inputSlot.slotReference); foreach (var edge in edges) { var fromSocketRef = edge.outputSlot; var outputNode = owner.GetNodeFromGuid(fromSocketRef.nodeGuid); if (outputNode == null) { continue; } outputNode.ValidateNode(); if (outputNode.hasError) { isInError = true; } } } ListPool <MaterialSlot> .Release(slots); var dynamicInputSlotsToCompare = DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Get(); var skippedDynamicSlots = ListPool <DynamicValueMaterialSlot> .Get(); // iterate the input slots s_TempSlots.Clear(); GetInputSlots(s_TempSlots); foreach (var inputSlot in s_TempSlots) { // if there is a connection var edges = owner.GetEdges(inputSlot.slotReference).ToList(); if (!edges.Any()) { if (inputSlot is DynamicValueMaterialSlot) { skippedDynamicSlots.Add(inputSlot as DynamicValueMaterialSlot); } continue; } // get the output details var outputSlotRef = edges[0].outputSlot; var outputNode = owner.GetNodeFromGuid(outputSlotRef.nodeGuid); if (outputNode == null) { continue; } var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId); if (outputSlot == null) { continue; } if (outputSlot.hasError) { inputSlot.hasError = true; continue; } var outputConcreteType = outputSlot.concreteValueType; // dynamic input... depends on output from other node. // we need to compare ALL dynamic inputs to make sure they // are compatable. if (inputSlot is DynamicValueMaterialSlot) { dynamicInputSlotsToCompare.Add((DynamicValueMaterialSlot)inputSlot, outputConcreteType); continue; } // if we have a standard connection... just check the types work! if (!ImplicitConversionExists(outputConcreteType, inputSlot.concreteValueType)) { inputSlot.hasError = true; } } m_MultiplyType = GetMultiplyType(dynamicInputSlotsToCompare.Values); // Resolve dynamics depending on matrix/vector configuration switch (m_MultiplyType) { // If all matrix resolve as per dynamic matrix case MultiplyType.Matrix: var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicMatrixType); } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(dynamicMatrixType); } break; // If mixed handle differently: // Iterate all slots and set their concretes based on their edges // Find matrix slot and convert its type to a vector type // Reiterate all slots and set non matrix slots to the vector type case MultiplyType.Mixed: foreach (var dynamicKvP in dynamicInputSlotsToCompare) { SetConcreteValueTypeFromEdge(dynamicKvP.Key); } MaterialSlot matrixSlot = GetMatrixSlot(); ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { if (dynamicKvP.Key != matrixSlot) { dynamicKvP.Key.SetConcreteType(vectorType); } } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(vectorType); } break; // If all vector resolve as per dynamic vector default: var dynamicVectorType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicVectorType); } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(dynamicVectorType); } break; } s_TempSlots.Clear(); GetInputSlots(s_TempSlots); var inputError = s_TempSlots.Any(x => x.hasError); // configure the output slots now // their slotType will either be the default output slotType // or the above dynanic slotType for dynamic nodes // or error if there is an input error s_TempSlots.Clear(); GetOutputSlots(s_TempSlots); foreach (var outputSlot in s_TempSlots) { outputSlot.hasError = false; if (inputError) { outputSlot.hasError = true; continue; } if (outputSlot is DynamicValueMaterialSlot) { // Apply similar logic to output slot switch (m_MultiplyType) { // As per dynamic matrix case MultiplyType.Matrix: var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values); (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicMatrixType); break; // Mixed configuration // Find matrix slot and convert type to vector // Set output concrete to vector case MultiplyType.Mixed: MaterialSlot matrixSlot = GetMatrixSlot(); ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType); (outputSlot as DynamicValueMaterialSlot).SetConcreteType(vectorType); break; // As per dynamic vector default: var dynamicVectorType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values); (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicVectorType); break; } continue; } } isInError |= inputError; s_TempSlots.Clear(); GetOutputSlots(s_TempSlots); isInError |= s_TempSlots.Any(x => x.hasError); isInError |= CalculateNodeHasError(); hasError = isInError; if (!hasError) { ++version; } ListPool <DynamicValueMaterialSlot> .Release(skippedDynamicSlots); DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare); }
public override void EvaluateDynamicMaterialSlots(List <MaterialSlot> inputSlots, List <MaterialSlot> outputSlots) { var dynamicInputSlotsToCompare = DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Get(); var skippedDynamicSlots = ListPool <DynamicVectorMaterialSlot> .Get(); var dynamicMatrixInputSlotsToCompare = DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Get(); var skippedDynamicMatrixSlots = ListPool <DynamicMatrixMaterialSlot> .Get(); // iterate the input slots { foreach (var inputSlot in inputSlots) { inputSlot.hasError = false; // if there is a connection var edges = owner.GetEdges(inputSlot.slotReference).ToList(); if (!edges.Any()) { if (inputSlot is DynamicVectorMaterialSlot) { skippedDynamicSlots.Add(inputSlot as DynamicVectorMaterialSlot); } if (inputSlot is DynamicMatrixMaterialSlot) { skippedDynamicMatrixSlots.Add(inputSlot as DynamicMatrixMaterialSlot); } continue; } // get the output details var outputSlotRef = edges[0].outputSlot; var outputNode = outputSlotRef.node; if (outputNode == null) { continue; } var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId); if (outputSlot == null) { continue; } if (outputSlot.hasError) { inputSlot.hasError = true; continue; } var outputConcreteType = outputSlot.concreteValueType; // dynamic input... depends on output from other node. // we need to compare ALL dynamic inputs to make sure they // are compatable. if (inputSlot is DynamicVectorMaterialSlot) { dynamicInputSlotsToCompare.Add((DynamicVectorMaterialSlot)inputSlot, outputConcreteType); continue; } else if (inputSlot is DynamicMatrixMaterialSlot) { dynamicMatrixInputSlotsToCompare.Add((DynamicMatrixMaterialSlot)inputSlot, outputConcreteType); continue; } } // and now dynamic matrices var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicMatrixInputSlotsToCompare.Values); foreach (var dynamicKvP in dynamicMatrixInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicMatrixType); } foreach (var skippedSlot in skippedDynamicMatrixSlots) { skippedSlot.SetConcreteType(dynamicMatrixType); } // we can now figure out the dynamic slotType // from here set all the var dynamicType = SlotValueHelper.ConvertMatrixToVectorType(dynamicMatrixType); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicType); } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(dynamicType); } bool inputError = inputSlots.Any(x => x.hasError); if (inputError) { owner.AddConcretizationError(objectId, string.Format("Node {0} had input error", objectId)); hasError = true; } // configure the output slots now // their slotType will either be the default output slotType // or the above dynanic slotType for dynamic nodes // or error if there is an input error foreach (var outputSlot in outputSlots) { outputSlot.hasError = false; if (inputError) { outputSlot.hasError = true; continue; } if (outputSlot is DynamicVectorMaterialSlot) { (outputSlot as DynamicVectorMaterialSlot).SetConcreteType(dynamicType); continue; } else if (outputSlot is DynamicMatrixMaterialSlot) { (outputSlot as DynamicMatrixMaterialSlot).SetConcreteType(dynamicMatrixType); continue; } } if (outputSlots.Any(x => x.hasError)) { owner.AddConcretizationError(objectId, string.Format("Node {0} had output error", objectId)); hasError = true; } } CalculateNodeHasError(); ListPool <DynamicVectorMaterialSlot> .Release(skippedDynamicSlots); DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare); ListPool <DynamicMatrixMaterialSlot> .Release(skippedDynamicMatrixSlots); DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Release(dynamicMatrixInputSlotsToCompare); }
public override void ValidateNode() { var isInError = false; var errorMessage = k_validationErrorMessage; var dynamicInputSlotsToCompare = DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Get(); var skippedDynamicSlots = ListPool <DynamicVectorMaterialSlot> .Get(); var dynamicMatrixInputSlotsToCompare = DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Get(); var skippedDynamicMatrixSlots = ListPool <DynamicMatrixMaterialSlot> .Get(); // iterate the input slots s_TempSlots.Clear(); GetInputSlots(s_TempSlots); foreach (var inputSlot in s_TempSlots) { inputSlot.hasError = false; // if there is a connection var edges = owner.GetEdges(inputSlot.slotReference).ToList(); if (!edges.Any()) { if (inputSlot is DynamicVectorMaterialSlot) { skippedDynamicSlots.Add(inputSlot as DynamicVectorMaterialSlot); } if (inputSlot is DynamicMatrixMaterialSlot) { skippedDynamicMatrixSlots.Add(inputSlot as DynamicMatrixMaterialSlot); } continue; } // get the output details var outputSlotRef = edges[0].outputSlot; var outputNode = owner.GetNodeFromGuid(outputSlotRef.nodeGuid); if (outputNode == null) { continue; } var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId); if (outputSlot == null) { continue; } if (outputSlot.hasError) { inputSlot.hasError = true; continue; } var outputConcreteType = outputSlot.concreteValueType; // dynamic input... depends on output from other node. // we need to compare ALL dynamic inputs to make sure they // are compatable. if (inputSlot is DynamicVectorMaterialSlot) { dynamicInputSlotsToCompare.Add((DynamicVectorMaterialSlot)inputSlot, outputConcreteType); continue; } else if (inputSlot is DynamicMatrixMaterialSlot) { dynamicMatrixInputSlotsToCompare.Add((DynamicMatrixMaterialSlot)inputSlot, outputConcreteType); continue; } // if we have a standard connection... just check the types work! if (!AbstractMaterialNode.ImplicitConversionExists(outputConcreteType, inputSlot.concreteValueType)) { inputSlot.hasError = true; } } // and now dynamic matrices var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicMatrixInputSlotsToCompare.Values); foreach (var dynamicKvP in dynamicMatrixInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicMatrixType); } foreach (var skippedSlot in skippedDynamicMatrixSlots) { skippedSlot.SetConcreteType(dynamicMatrixType); } // we can now figure out the dynamic slotType // from here set all the var dynamicType = SlotValueHelper.ConvertMatrixToVectorType(dynamicMatrixType); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicType); } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(dynamicType); } s_TempSlots.Clear(); GetInputSlots(s_TempSlots); var inputError = s_TempSlots.Any(x => x.hasError); // configure the output slots now // their slotType will either be the default output slotType // or the above dynanic slotType for dynamic nodes // or error if there is an input error s_TempSlots.Clear(); GetOutputSlots(s_TempSlots); foreach (var outputSlot in s_TempSlots) { outputSlot.hasError = false; if (inputError) { outputSlot.hasError = true; continue; } if (outputSlot is DynamicVectorMaterialSlot) { (outputSlot as DynamicVectorMaterialSlot).SetConcreteType(dynamicType); continue; } else if (outputSlot is DynamicMatrixMaterialSlot) { (outputSlot as DynamicMatrixMaterialSlot).SetConcreteType(dynamicMatrixType); continue; } } isInError |= inputError; s_TempSlots.Clear(); GetOutputSlots(s_TempSlots); isInError |= s_TempSlots.Any(x => x.hasError); isInError |= CalculateNodeHasError(ref errorMessage); hasError = isInError; if (isInError) { ((GraphData)owner).AddValidationError(tempId, errorMessage); } else { ++version; } ListPool <DynamicVectorMaterialSlot> .Release(skippedDynamicSlots); DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare); ListPool <DynamicMatrixMaterialSlot> .Release(skippedDynamicMatrixSlots); DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Release(dynamicMatrixInputSlotsToCompare); }
// Internal validation // ------------------------------------------------- public override void EvaluateDynamicMaterialSlots() { var dynamicInputSlotsToCompare = DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Get(); var skippedDynamicSlots = ListPool <DynamicValueMaterialSlot> .Get(); // iterate the input slots using (var tempSlots = PooledList <MaterialSlot> .Get()) { GetInputSlots(tempSlots); foreach (var inputSlot in tempSlots) { inputSlot.hasError = false; // if there is a connection var edges = owner.GetEdges(inputSlot.slotReference).ToList(); if (!edges.Any()) { if (inputSlot is DynamicValueMaterialSlot) { skippedDynamicSlots.Add(inputSlot as DynamicValueMaterialSlot); } continue; } // get the output details var outputSlotRef = edges[0].outputSlot; var outputNode = owner.GetNodeFromGuid(outputSlotRef.nodeGuid); if (outputNode == null) { continue; } var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId); if (outputSlot == null) { continue; } if (outputSlot.hasError) { inputSlot.hasError = true; continue; } var outputConcreteType = outputSlot.concreteValueType; // dynamic input... depends on output from other node. // we need to compare ALL dynamic inputs to make sure they // are compatable. if (inputSlot is DynamicValueMaterialSlot) { dynamicInputSlotsToCompare.Add((DynamicValueMaterialSlot)inputSlot, outputConcreteType); continue; } } m_MultiplyType = GetMultiplyType(dynamicInputSlotsToCompare.Values); // Resolve dynamics depending on matrix/vector configuration switch (m_MultiplyType) { // If all matrix resolve as per dynamic matrix case MultiplyType.Matrix: var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicMatrixType); } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(dynamicMatrixType); } break; // If mixed handle differently: // Iterate all slots and set their concretes based on their edges // Find matrix slot and convert its type to a vector type // Reiterate all slots and set non matrix slots to the vector type case MultiplyType.Mixed: foreach (var dynamicKvP in dynamicInputSlotsToCompare) { SetConcreteValueTypeFromEdge(dynamicKvP.Key); } MaterialSlot matrixSlot = GetMatrixSlot(); ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { if (dynamicKvP.Key != matrixSlot) { dynamicKvP.Key.SetConcreteType(vectorType); } } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(vectorType); } break; // If all vector resolve as per dynamic vector default: var dynamicVectorType = ConvertDynamicVectorInputTypeToConcrete(dynamicInputSlotsToCompare.Values); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicVectorType); } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(dynamicVectorType); } break; } tempSlots.Clear(); GetInputSlots(tempSlots); bool inputError = tempSlots.Any(x => x.hasError); if (inputError) { owner.AddConcretizationError(guid, string.Format("Node {0} had input error", guid)); hasError = true; } // configure the output slots now // their slotType will either be the default output slotType // or the above dynanic slotType for dynamic nodes // or error if there is an input error tempSlots.Clear(); GetOutputSlots(tempSlots); foreach (var outputSlot in tempSlots) { outputSlot.hasError = false; if (inputError) { outputSlot.hasError = true; continue; } if (outputSlot is DynamicValueMaterialSlot) { // Apply similar logic to output slot switch (m_MultiplyType) { // As per dynamic matrix case MultiplyType.Matrix: var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values); (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicMatrixType); break; // Mixed configuration // Find matrix slot and convert type to vector // Set output concrete to vector case MultiplyType.Mixed: MaterialSlot matrixSlot = GetMatrixSlot(); ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType); (outputSlot as DynamicValueMaterialSlot).SetConcreteType(vectorType); break; // As per dynamic vector default: var dynamicVectorType = ConvertDynamicVectorInputTypeToConcrete(dynamicInputSlotsToCompare.Values); (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicVectorType); break; } continue; } } tempSlots.Clear(); GetOutputSlots(tempSlots); if (tempSlots.Any(x => x.hasError)) { owner.AddConcretizationError(guid, string.Format("Node {0} had output error", guid)); hasError = true; } } CalculateNodeHasError(); ListPool <DynamicValueMaterialSlot> .Release(skippedDynamicSlots); DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare); }