From 0b56d4cb58159849842c60a8b32e005e7c7a9f8a Mon Sep 17 00:00:00 2001 From: Vector Date: Tue, 11 Nov 2025 08:29:27 +0000 Subject: [PATCH 1/3] final commit --- .gitignore | 3 + .vscode/launch.json | 1 - src/GDTFManager.cpp | 123 +++- src/GDTFManager.h | 8 +- src/Implementation/CGdtfDmxChannel.cpp | 12 +- src/Implementation/CGdtfDmxChannel.h | 1 + .../CGdtfDmxChannelFunction.cpp | 2 +- src/Include/IMediaRessourceVectorInterface.h | 1 + unittest/ResolutionTest.cpp | 564 ++++++++++++++++++ unittest/ResolutionTest.h | 35 ++ unittest/files/description.xml | 78 +++ unittest/files/resolution_test_16bit.xml | 67 +++ unittest/files/resolution_test_8bit.xml | 73 +++ unittest/files/resolution_test_edge_cases.xml | 83 +++ unittest/files/resolution_test_multi.xml | 98 +++ unittest/files/test_resolution_xml.gdtf | Bin 0 -> 3974 bytes unittest/files/test_setresolution_api.gdtf | Bin 0 -> 2005 bytes unittest/files/test_validation.gdtf | Bin 0 -> 2044 bytes unittest/main.cpp | 6 +- 19 files changed, 1129 insertions(+), 26 deletions(-) create mode 100644 unittest/ResolutionTest.cpp create mode 100644 unittest/ResolutionTest.h create mode 100644 unittest/files/description.xml create mode 100644 unittest/files/resolution_test_16bit.xml create mode 100644 unittest/files/resolution_test_8bit.xml create mode 100644 unittest/files/resolution_test_edge_cases.xml create mode 100644 unittest/files/resolution_test_multi.xml create mode 100644 unittest/files/test_resolution_xml.gdtf create mode 100644 unittest/files/test_setresolution_api.gdtf create mode 100644 unittest/files/test_validation.gdtf diff --git a/.gitignore b/.gitignore index fcb8c32a..fd3f1e41 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,6 @@ build_v8a/ node_modules output + +# Copilot instruction files +copilot-instructions.md diff --git a/.vscode/launch.json b/.vscode/launch.json index 9a57d11f..68c94526 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,7 +5,6 @@ "version": "0.2.0", "configurations": [ { -CreateDmxChannelSet "preLaunchTask": "build" }, { diff --git a/src/GDTFManager.cpp b/src/GDTFManager.cpp index fb8f41ac..f9b6cb79 100644 --- a/src/GDTFManager.cpp +++ b/src/GDTFManager.cpp @@ -5274,7 +5274,7 @@ size_t GdtfDmxMode::GetFootPrintForBreak(size_t breakId) } void GdtfDmxMode::GetAddressesFromChannel(TDMXAddressArray& addresses, GdtfDmxChannel* channel, DMXAddress offset) const { - EGdtfChannelBitResolution resolution = channel->GetChannelBitResolution(); + EGdtfChannelBitResolution resolution = channel->GetResolution(); if(resolution >= eGdtfChannelBitResolution_8) { addresses.push_back(channel->GetCoarse() + offset);} if(resolution >= eGdtfChannelBitResolution_16) { addresses.push_back(channel->GetFine() + offset);} if(resolution >= eGdtfChannelBitResolution_24) { addresses.push_back(channel->GetUltra() + offset);} @@ -5293,6 +5293,7 @@ GdtfDmxChannel::GdtfDmxChannel(GdtfDmxMode* parent) { fName_AutoGenerated = ""; fDmxBreak = 1; + fResolution = eGdtfChannelBitResolution_8; fCoarse = 0; fFine = 0; fUltra = 0; @@ -5321,6 +5322,11 @@ void GdtfDmxChannel::SetDmxBreak(Sint32 dmxBreak) fDmxBreak = dmxBreak; } +void GdtfDmxChannel::SetResolution(EGdtfChannelBitResolution resolution) +{ + fResolution = resolution; +} + void GdtfDmxChannel::SetDmxCoarse(Sint32 coarse) { fCoarse = coarse; @@ -5369,12 +5375,11 @@ void GdtfDmxChannel::OnPrintToFile(IXMLFileNodePtr pNode) // Call the parent GdtfObject::OnPrintToFile(pNode); - EGdtfChannelBitResolution chanelReso = GetChannelBitResolution(); // ------------------------------------------------------------------------------------ // Print node attributes pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelDMXBreak, GdtfConverter::ConvertDmxBreak(fDmxBreak)); pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelOffset, GdtfConverter::ConvertDmxOffset(fCoarse, fFine, fUltra, fUber)); - pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelHighlight, GdtfConverter::ConvertDMXValue(fHeighlight, chanelReso, fHeighlightNone)); + pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelHighlight, GdtfConverter::ConvertDMXValue(fHeighlight, fResolution, fHeighlightNone)); if (fGeomRef) { pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelGeometry, fGeomRef->GetNodeReference()); } if (fInitialFunction) { pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelInitialFunction, fInitialFunction->GetNodeReference()); } @@ -5402,11 +5407,13 @@ void GdtfDmxChannel::OnReadFromNode(const IXMLFileNodePtr& pNode) GdtfConverter::ConvertDmxOffset(offset, pNode, fCoarse, fFine, fUltra, fUber); } + fResolution = ExtractResolutionFromDMXFrom(pNode); + // In GDTF 1.0, default value was in the DMX channel, this is for old files : TXString defVal; if (pNode->GetNodeAttributeValue(XML_GDTF_DMXChannelFuntionDefault, defVal) == kVCOMError_NoError) { - GdtfConverter::ConvertDMXValue(defVal, pNode, this->GetChannelBitResolution(), fDefaultValue_old); + GdtfConverter::ConvertDMXValue(defVal, pNode, this->GetResolution(), fDefaultValue_old); } // ------------------------------------------------------------------------------------ @@ -5414,7 +5421,7 @@ void GdtfDmxChannel::OnReadFromNode(const IXMLFileNodePtr& pNode) TXString highlight; if(VCOM_SUCCEEDED(pNode->GetNodeAttributeValue(XML_GDTF_DMXChannelHighlight, highlight) )) { - GdtfConverter::ConvertDMXValue(highlight, pNode, this->GetChannelBitResolution(), fHeighlight, fHeighlightNone); + GdtfConverter::ConvertDMXValue(highlight, pNode, this->GetResolution(), fHeighlight, fHeighlightNone); } pNode->GetNodeAttributeValue(XML_GDTF_DMXChannelGeometry, fUnresolvedGeomRef); @@ -5517,6 +5524,11 @@ Sint32 GdtfDmxChannel::GetDmxBreak() const return fDmxBreak; } +EGdtfChannelBitResolution GdtfDmxChannel::GetResolution() const +{ + return fResolution; +} + Sint32 GdtfDmxChannel::GetCoarse() const { return fCoarse; @@ -5587,7 +5599,7 @@ const TGdtfDmxLogicalChannelArray GdtfDmxChannel::GetLogicalChannelArray() return fLogicalChannels; } -EGdtfChannelBitResolution SceneData::GdtfDmxChannel::GetChannelBitResolution() +EGdtfChannelBitResolution SceneData::GdtfDmxChannel::GetCalculatedChannelBitResolution() { // 0 is false, everything else is true if ((!fCoarse) && !fFine && !fUltra && !fUber) { return EGdtfChannelBitResolution::eGdtfChannelBitResolution_32; } @@ -5601,9 +5613,78 @@ EGdtfChannelBitResolution SceneData::GdtfDmxChannel::GetChannelBitResolution() return EGdtfChannelBitResolution::eGdtfChannelBitResolution_8; } +EGdtfChannelBitResolution SceneData::GdtfDmxChannel::ExtractResolutionFromDMXFrom(const IXMLFileNodePtr& pNode) +{ + auto extractFromDMXValue = [](const TXString& dmxValue) -> EGdtfChannelBitResolution { + if (dmxValue.IsEmpty()) { + return EGdtfChannelBitResolution::eGdtfChannelBitResolution_8;//Invalid + } + + ptrdiff_t splitPos = dmxValue.Find("/"); + if (splitPos == -1) { + return EGdtfChannelBitResolution::eGdtfChannelBitResolution_8;//Invalid + } + + TXString resolutionPart = dmxValue.Mid(splitPos + 1); + resolutionPart.Trim(); + + if (!resolutionPart.IsCompleteNumber()) { + return EGdtfChannelBitResolution::eGdtfChannelBitResolution_8;//Invalid + } + + Sint32 byteSpecifier = resolutionPart.atoi(); + + switch (byteSpecifier) { + case 1: return EGdtfChannelBitResolution::eGdtfChannelBitResolution_8; + case 2: return EGdtfChannelBitResolution::eGdtfChannelBitResolution_16; + case 3: return EGdtfChannelBitResolution::eGdtfChannelBitResolution_24; + case 4: return EGdtfChannelBitResolution::eGdtfChannelBitResolution_32; + default: return EGdtfChannelBitResolution::eGdtfChannelBitResolution_8;//Invalid + } + }; + + EGdtfChannelBitResolution foundResolution = EGdtfChannelBitResolution::eGdtfChannelBitResolution_8; + bool found = false; + + GdtfConverter::TraverseNodes(pNode, "", XML_GDTF_DMXLogicalChannelNodeName, [&](IXMLFileNodePtr logicalChannelNode) -> void { + if (CheckAbort() || found) return; + + GdtfConverter::TraverseNodes(logicalChannelNode, "", XML_GDTF_DMXChannelFuntionNodeName, [&](IXMLFileNodePtr functionNode) -> void { + if (CheckAbort() || found) return; + + TXString dmxFrom; + if (functionNode->GetNodeAttributeValue(XML_GDTF_DMXChannelFuntionDMXFrom, dmxFrom) == kVCOMError_NoError) { + + if (dmxFrom.Find("/") != -1) { + EGdtfChannelBitResolution result = extractFromDMXValue(dmxFrom); + + if (result != EGdtfChannelBitResolution::eGdtfChannelBitResolution_8 || dmxFrom.Find("/1") != -1) { + foundResolution = result; + found = true; + return; + } + } + } + }); + }); + + if (found) { + return foundResolution; + } + + EGdtfChannelBitResolution calculatedRes = GetCalculatedChannelBitResolution(); + + printf("[DEBUG] No DMXFrom resolution found, using calculated: %d-bit\n", + calculatedRes == EGdtfChannelBitResolution::eGdtfChannelBitResolution_8 ? 8 : + calculatedRes == EGdtfChannelBitResolution::eGdtfChannelBitResolution_16 ? 16 : + calculatedRes == EGdtfChannelBitResolution::eGdtfChannelBitResolution_24 ? 24 : 32); + + return calculatedRes; +} + DmxValue SceneData::GdtfDmxChannel::GetChannelMaxDmx() { - return GdtfConverter::GetChannelMaxDmx(this->GetChannelBitResolution()); + return GdtfConverter::GetChannelMaxDmx(this->GetResolution()); } bool SceneData::GdtfDmxChannel::IsVirtual() const @@ -5988,7 +6069,7 @@ void GdtfDmxChannelFunction::OnPrintToFile(IXMLFileNodePtr pNode) // Call the parent GdtfObject::OnPrintToFile(pNode); - EGdtfChannelBitResolution chanelReso = GetParentDMXChannel()->GetChannelBitResolution(); + EGdtfChannelBitResolution chanelReso = GetParentDMXChannel()->GetResolution(); // ------------------------------------------------------------------------------------ // Print node attributes @@ -6020,16 +6101,16 @@ void GdtfDmxChannelFunction::OnPrintToFile(IXMLFileNodePtr pNode) ASSERTN(kEveryone, (fModeMaster_Function == nullptr)); pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelFuntionModeMaster, fModeMaster_Channel->GetNodeReference()); - pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelFuntionModeFrom, GdtfConverter::ConvertDMXValue(fDmxModeStart, fModeMaster_Channel->GetChannelBitResolution())); - pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelFuntionModeTo, GdtfConverter::ConvertDMXValue(fDmxModeEnd, fModeMaster_Channel->GetChannelBitResolution())); + pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelFuntionModeFrom, GdtfConverter::ConvertDMXValue(fDmxModeStart, fModeMaster_Channel->GetResolution())); + pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelFuntionModeTo, GdtfConverter::ConvertDMXValue(fDmxModeEnd, fModeMaster_Channel->GetResolution())); } if(fModeMaster_Function) { ASSERTN(kEveryone, (fModeMaster_Channel == nullptr)); pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelFuntionModeMaster, fModeMaster_Function->GetNodeReference()); - pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelFuntionModeFrom, GdtfConverter::ConvertDMXValue(fDmxModeStart, fModeMaster_Function->GetParentDMXChannel()->GetChannelBitResolution())); - pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelFuntionModeTo, GdtfConverter::ConvertDMXValue(fDmxModeEnd, fModeMaster_Function->GetParentDMXChannel()->GetChannelBitResolution())); + pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelFuntionModeFrom, GdtfConverter::ConvertDMXValue(fDmxModeStart, fModeMaster_Function->GetParentDMXChannel()->GetResolution())); + pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelFuntionModeTo, GdtfConverter::ConvertDMXValue(fDmxModeEnd, fModeMaster_Function->GetParentDMXChannel()->GetResolution())); } // ------------------------------------------------------------------------------------ @@ -6117,7 +6198,7 @@ void GdtfDmxChannelFunction::OnReadFromNode(const IXMLFileNodePtr& pNode) // ------------------------------------------------------------------------------------ // Print node attributes - EGdtfChannelBitResolution channelReso = fParentLogicalChannel->GetParentDMXChannel()->GetChannelBitResolution(); + EGdtfChannelBitResolution channelReso = fParentLogicalChannel->GetParentDMXChannel()->GetResolution(); pNode->GetNodeAttributeValue(XML_GDTF_DMXChannelFuntionName, fName); pNode->GetNodeAttributeValue(XML_GDTF_DMXChannelFuntionOriginalAttribute, fOrignalAttribute); @@ -6637,7 +6718,7 @@ void GdtfDmxChannelSet::OnPrintToFile(IXMLFileNodePtr pNode) // Call the parent GdtfObject::OnPrintToFile(pNode); - EGdtfChannelBitResolution chanelReso = GetParentDMXChannel()->GetChannelBitResolution(); + EGdtfChannelBitResolution chanelReso = GetParentDMXChannel()->GetResolution(); // ------------------------------------------------------------------------------------ // Print node attributes pNode->SetNodeAttributeValue(XML_GDTF_DMXChannelSetName, fUniqueName); @@ -6663,7 +6744,7 @@ void GdtfDmxChannelSet::OnReadFromNode(const IXMLFileNodePtr& pNode) // Print node attributes pNode->GetNodeAttributeValue(XML_GDTF_DMXChannelSetName, fUniqueName); - EGdtfChannelBitResolution channelReso = fParentChnlFunction->GetParentDMXChannel()->GetChannelBitResolution(); + EGdtfChannelBitResolution channelReso = fParentChnlFunction->GetParentDMXChannel()->GetResolution(); TXString dmxfrom; pNode->GetNodeAttributeValue(XML_GDTF_DMXChannelSetDMXFrom, dmxfrom); fValid = GdtfConverter::ConvertDMXValue (dmxfrom, pNode, channelReso, fDmxStart); TXString wheelId; pNode->GetNodeAttributeValue(XML_GDTF_DMXChannelSetWheelSlotIndexRef, wheelId); GdtfConverter::ConvertInteger(wheelId, pNode, fWheelSlotIdx); @@ -8366,7 +8447,7 @@ void GdtfFixture::ResolveMacroRefs(GdtfDmxModePtr dmxMode) { DmxValue dmxVal = 0; - GdtfConverter::ConvertDMXValue(value->GetUnresolvedDMXValue(), node, value->GetDMXChannel()->GetChannelBitResolution(), dmxVal); + GdtfConverter::ConvertDMXValue(value->GetUnresolvedDMXValue(), node, value->GetDMXChannel()->GetResolution(), dmxVal); value->SetValue(dmxVal); } else @@ -8403,7 +8484,7 @@ void GdtfFixture::ResolveMacroRefs(GdtfDmxModePtr dmxMode) value->GetNode(node); DmxValue dmxVal = 0; - GdtfConverter::ConvertDMXValue(value->GetUnresolvedDMXValue(), node, channelFunction->GetParentDMXChannel()->GetChannelBitResolution(), dmxVal); + GdtfConverter::ConvertDMXValue(value->GetUnresolvedDMXValue(), node, channelFunction->GetParentDMXChannel()->GetResolution(), dmxVal); value->SetDmxValue(dmxVal); } } @@ -8489,7 +8570,7 @@ void GdtfFixture::ResolveDMXModeMasters() { function->SetModeMaster_Channel(channelPtr); resolved = true; - resolution = channelPtr->GetChannelBitResolution(); + resolution = channelPtr->GetResolution(); } GdtfDmxChannelFunctionPtr functionPtr = getDmxFunctionByRef(unresolvedModeMaster, mode); @@ -8497,7 +8578,7 @@ void GdtfFixture::ResolveDMXModeMasters() { function->SetModeMaster_Function(functionPtr); resolved = true; - resolution = functionPtr->GetParentDMXChannel()->GetChannelBitResolution(); + resolution = functionPtr->GetParentDMXChannel()->GetResolution(); } ASSERTN(kEveryone, resolved); @@ -11355,7 +11436,7 @@ void SceneData::GdtfMacroDMXValue::OnPrintToFile(IXMLFileNodePtr pNode) ASSERTN(kEveryone, fDMXChannel != nullptr); if(fDMXChannel) { - resolution = fDMXChannel->GetChannelBitResolution(); + resolution = fDMXChannel->GetResolution(); } //------------------------------------------------------------------------------------ @@ -11668,7 +11749,7 @@ void SceneData::GdtfMacroVisualValue::OnPrintToFile(IXMLFileNodePtr pNode) EGdtfChannelBitResolution resolution = EGdtfChannelBitResolution::eGdtfChannelBitResolution_8; ASSERTN(kEveryone, fChannelFunctionRef != nullptr); - if(fChannelFunctionRef) {resolution = fChannelFunctionRef->GetParentDMXChannel()->GetChannelBitResolution(); } + if(fChannelFunctionRef) {resolution = fChannelFunctionRef->GetParentDMXChannel()->GetResolution(); } //------------------------------------------------------------------------------------ // Print the attributes diff --git a/src/GDTFManager.h b/src/GDTFManager.h index 4acacc57..1a2f9041 100644 --- a/src/GDTFManager.h +++ b/src/GDTFManager.h @@ -1748,6 +1748,7 @@ namespace SceneData private: TXString fName_AutoGenerated; Sint32 fDmxBreak; + EGdtfChannelBitResolution fResolution; DMXAddress fCoarse; DMXAddress fFine; DMXAddress fUltra; @@ -1771,6 +1772,7 @@ namespace SceneData const TXString& GetName(); Sint32 GetDmxBreak() const; + EGdtfChannelBitResolution GetResolution() const; Sint32 GetCoarse() const; Sint32 GetFine() const; Sint32 GetUltra() const; @@ -1783,12 +1785,13 @@ namespace SceneData TXString GetUnresolvedGeomRef() const; GdtfDmxChannelFunctionPtr GetInitialFunction(); TXString GetUnresolvedInitialFunction() const; - EGdtfChannelBitResolution GetChannelBitResolution(); + EGdtfChannelBitResolution GetCalculatedChannelBitResolution(); DmxValue GetChannelMaxDmx(); bool IsVirtual() const; void SetName(const TXString& name); void SetDmxBreak(Sint32 dmxBreak); + void SetResolution(EGdtfChannelBitResolution resolution); void SetDmxCoarse(Sint32 coarse); void SetDmxFine(Sint32 fine); void SetDmxUltra(Sint32 ultra); @@ -1802,6 +1805,9 @@ namespace SceneData // Get Parent GdtfDmxMode* GetParentMode(); + // Resolution extraction from ChannelFunction's DMXFrom value + EGdtfChannelBitResolution ExtractResolutionFromDMXFrom(const IXMLFileNodePtr& pNode); + protected: virtual TXString GetNodeName(); virtual void OnPrintToFile(IXMLFileNodePtr pNode); diff --git a/src/Implementation/CGdtfDmxChannel.cpp b/src/Implementation/CGdtfDmxChannel.cpp index 7653f854..c3cdeb03 100644 --- a/src/Implementation/CGdtfDmxChannel.cpp +++ b/src/Implementation/CGdtfDmxChannel.cpp @@ -148,7 +148,7 @@ VectorworksMVR::VCOMError VectorworksMVR::CGdtfDmxChannelImpl::GetResolution(Gdt // Check Pointer if ( ! fChannel) { return kVCOMError_NotInitialized; } - resolution = fChannel->GetChannelBitResolution(); + resolution = fChannel->GetResolution(); return kVCOMError_NoError; } @@ -234,6 +234,16 @@ VectorworksMVR::VCOMError VectorworksMVR::CGdtfDmxChannelImpl::SetGeometry(IGdtf return kVCOMError_NoError; } +VectorworksMVR::VCOMError VectorworksMVR::CGdtfDmxChannelImpl::SetResolution(GdtfDefines::EGdtfChannelBitResolution resolution) +{ + // Check Pointer + if ( ! fChannel) { return kVCOMError_NotInitialized; } + + fChannel->SetResolution(resolution); + + return kVCOMError_NoError; +} + VectorworksMVR::VCOMError VectorworksMVR::CGdtfDmxChannelImpl::GetLogicalChannelCount(size_t &count) { // Check Pointer diff --git a/src/Implementation/CGdtfDmxChannel.h b/src/Implementation/CGdtfDmxChannel.h index 79877af3..9423ca22 100644 --- a/src/Implementation/CGdtfDmxChannel.h +++ b/src/Implementation/CGdtfDmxChannel.h @@ -33,6 +33,7 @@ namespace VectorworksMVR virtual VCOMError VCOM_CALLTYPE SetUber(Sint32 uber); virtual VCOMError VCOM_CALLTYPE SetHighlight(DmxValue highlight); virtual VCOMError VCOM_CALLTYPE SetGeometry(IGdtfGeometry* model); + virtual VCOMError VCOM_CALLTYPE SetResolution(GdtfDefines::EGdtfChannelBitResolution resolution); virtual VCOMError VCOM_CALLTYPE GetLogicalChannelCount(size_t& count); virtual VCOMError VCOM_CALLTYPE GetLogicalChannelAt(size_t at, IGdtfDmxLogicalChannel** channel); diff --git a/src/Implementation/CGdtfDmxChannelFunction.cpp b/src/Implementation/CGdtfDmxChannelFunction.cpp index 3d3c291e..22f28eca 100644 --- a/src/Implementation/CGdtfDmxChannelFunction.cpp +++ b/src/Implementation/CGdtfDmxChannelFunction.cpp @@ -293,7 +293,7 @@ VectorworksMVR::VCOMError VectorworksMVR::CGdtfDmxChannelFunctionImpl::GetResolu // Check Pointer if ( ! fFunction) { return kVCOMError_NotInitialized; } - resolution = fFunction->GetParentDMXChannel()->GetChannelBitResolution(); + resolution = fFunction->GetParentDMXChannel()->GetResolution(); return kVCOMError_NoError; } diff --git a/src/Include/IMediaRessourceVectorInterface.h b/src/Include/IMediaRessourceVectorInterface.h index 263400cc..94380500 100644 --- a/src/Include/IMediaRessourceVectorInterface.h +++ b/src/Include/IMediaRessourceVectorInterface.h @@ -1148,6 +1148,7 @@ namespace VectorworksMVR // 0.3.20 virtual VCOMError VCOM_CALLTYPE GetResolution(GdtfDefines::EGdtfChannelBitResolution& resolution) = 0; + virtual VCOMError VCOM_CALLTYPE SetResolution(GdtfDefines::EGdtfChannelBitResolution resolution) = 0; // GDTF 1.1 virtual VCOMError VCOM_CALLTYPE GetInitialFunction(IGdtfDmxChannelFunction** function) = 0; diff --git a/unittest/ResolutionTest.cpp b/unittest/ResolutionTest.cpp new file mode 100644 index 00000000..5cde88ba --- /dev/null +++ b/unittest/ResolutionTest.cpp @@ -0,0 +1,564 @@ +//----------------------------------------------------------------------------- +//----- Copyright MVR Group +//----------------------------------------------------------------------------- +#include "Unittest.h" +#include "ResolutionTest.h" +#include +#include "Utility.h" +#include "Include/VectorworksMVR.h" + +using namespace VectorworksMVR; +using namespace VectorworksMVR::GdtfDefines; + +#define __checkVCOM(x) this->checkVCOM(x, #x) +#define __checkVCOM_NotSet(x) this->checkVCOM_NotSet(x, #x) + +ResolutionTest::ResolutionTest(const std::string& currentDir) +{ +} + +ResolutionTest::~ResolutionTest() +{ +} + +bool ResolutionTest::ExecuteTest() +{ + std::cout << "= ResolutionTest Unit Test =" << std::endl; + + bool allTestsPassed = true; + + // Test 1: Resolution extraction from DMXFrom field + std::cout << "\n--- Test 1: Resolution Extraction from DMXFrom ---" << std::endl; + if (!TestResolutionExtractionFromDMXFrom()) { + std::cout << "❌ TestResolutionExtractionFromDMXFrom FAILED" << std::endl; + allTestsPassed = false; + } else { + std::cout << "✅ TestResolutionExtractionFromDMXFrom PASSED" << std::endl; + } + + // Test 2: SetResolution API functionality + std::cout << "\n--- Test 2: SetResolution API ---" << std::endl; + if (!TestSetResolutionAPI()) { + std::cout << "❌ TestSetResolutionAPI FAILED" << std::endl; + allTestsPassed = false; + } else { + std::cout << "✅ TestSetResolutionAPI PASSED" << std::endl; + } + + // Test 3: Resolution in XML output + std::cout << "\n--- Test 3: Resolution in XML Output ---" << std::endl; + if (!TestResolutionInXMLOutput()) { + std::cout << "❌ TestResolutionInXMLOutput FAILED" << std::endl; + allTestsPassed = false; + } else { + std::cout << "✅ TestResolutionInXMLOutput PASSED" << std::endl; + } + + // Test 4: Mixed resolution channels + std::cout << "\n--- Test 4: Mixed Resolution Channels ---" << std::endl; + if (!TestMixedResolutionChannels()) { + std::cout << "❌ TestMixedResolutionChannels FAILED" << std::endl; + allTestsPassed = false; + } else { + std::cout << "✅ TestMixedResolutionChannels PASSED" << std::endl; + } + + // Test 5: Resolution validation + std::cout << "\n--- Test 5: Resolution Validation ---" << std::endl; + if (!TestResolutionValidation()) { + std::cout << "❌ TestResolutionValidation FAILED" << std::endl; + allTestsPassed = false; + } else { + std::cout << "✅ TestResolutionValidation PASSED" << std::endl; + } + + std::cout << "\n=== Resolution Test Summary ===" << std::endl; + if (allTestsPassed) { + std::cout << "🎉 ALL RESOLUTION TESTS PASSED!" << std::endl; + } else { + std::cout << "⚠️ SOME RESOLUTION TESTS FAILED!" << std::endl; + } + + return allTestsPassed; +} + +bool ResolutionTest::TestResolutionExtractionFromDMXFrom() +{ + // Test with a test GDTF file that has mixed resolutions + std::string path = UnitTestUtil::GetTestResourceFolder() + kSeparator + "allWorking.gdtf"; + + IGdtfFixturePtr gdtfFile(IID_IGdtfFixture); + if (!__checkVCOM(gdtfFile->ReadFromFile(path.c_str()))) { + std::cout << "Failed to open " << path << std::endl; + return false; + } + + // Get the first DMX mode + size_t modeCount; + if (!__checkVCOM(gdtfFile->GetDmxModeCount(modeCount))) { + std::cout << "Failed to get DMX mode count" << std::endl; + return false; + } + if (modeCount == 0) { + std::cout << "No DMX modes found" << std::endl; + return false; + } + + IGdtfDmxModePtr mode; + if (!__checkVCOM(gdtfFile->GetDmxModeAt(0, &mode))) { + std::cout << "Failed to get DMX mode" << std::endl; + return false; + } + + size_t channelCount; + if (!__checkVCOM(mode->GetDmxChannelCount(channelCount))) { + std::cout << "Failed to get DMX channel count" << std::endl; + return false; + } + std::cout << "Found " << channelCount << " DMX channels" << std::endl; + + bool testPassed = true; + + // Check each channel + for (size_t i = 0; i < channelCount; i++) { + IGdtfDmxChannelPtr channel; + if (__checkVCOM(mode->GetDmxChannelAt(i, &channel))) { + EGdtfChannelBitResolution resolution; + if (!__checkVCOM(channel->GetResolution(resolution))) { + std::cout << "Failed to get channel resolution" << std::endl; + continue; + } + + std::cout << "Channel " << i << ": "; + PrintResolutionInfo(resolution, "Extracted"); + + // Based on description.xml analysis: + // Channel 0: DMXFrom="0/1" should be 8-bit + // Channel 1: DMXFrom="0/4" should be 32-bit + // Channel 2: DMXFrom="0/1" should be 8-bit + EGdtfChannelBitResolution expectedResolution; + if (i == 0) { + expectedResolution = EGdtfChannelBitResolution::eGdtfChannelBitResolution_8; + } else if (i == 1) { + expectedResolution = EGdtfChannelBitResolution::eGdtfChannelBitResolution_32; + } else if (i == 2) { + expectedResolution = EGdtfChannelBitResolution::eGdtfChannelBitResolution_8; + } else { + expectedResolution = EGdtfChannelBitResolution::eGdtfChannelBitResolution_8; // default + } + + if (!VerifyChannelResolution(channel, expectedResolution)) { + testPassed = false; + } + } + } + + return testPassed; +} + +bool ResolutionTest::TestSetResolutionAPI() +{ + // Create a test fixture + std::string testPath = UnitTestUtil::GetTestResourceFolder() + kSeparator + "test_setresolution_api.gdtf"; + + if (!CreateTestFixture(testPath, "SetResolutionTestFixture")) { + std::cout << "Failed to create test fixture" << std::endl; + return false; + } + + // Open for write + IGdtfFixturePtr gdtfWrite(IID_IGdtfFixture); + MvrUUID uuid = VectorworksMVR::MvrUUID(1, 2, 3, 4); + + if (!__checkVCOM(gdtfWrite->OpenForWrite(testPath.c_str(), "TestFixture", "TestManufacturer", uuid))) { + std::cout << "Failed to open GDTF for write" << std::endl; + return false; + } + + // Create attribute + IGdtfAttributePtr attr; + if (!__checkVCOM(gdtfWrite->CreateAttribute("Dimmer", "Dimmer", &attr))) { + std::cout << "Failed to create attribute" << std::endl; + return false; + } + + // Create model and geometry + IGdtfModelPtr model; + if (!__checkVCOM(gdtfWrite->CreateModel("TestModel", &model))) { + std::cout << "Failed to create model" << std::endl; + return false; + } + + IGdtfGeometryPtr geometry; + if (!__checkVCOM(gdtfWrite->CreateGeometry(EGdtfObjectType::eGdtfGeometry, "TestGeometry", model, STransformMatrix(), &geometry))) { + std::cout << "Failed to create geometry" << std::endl; + return false; + } + + // Create DMX mode + IGdtfDmxModePtr dmxMode; + if (!__checkVCOM(gdtfWrite->CreateDmxMode("TestMode", &dmxMode))) { + std::cout << "Failed to create DMX mode" << std::endl; + return false; + } + + // Create DMX channel + IGdtfDmxChannelPtr dmxChannel; + if (!__checkVCOM(dmxMode->CreateDmxChannel(geometry, &dmxChannel))) { + std::cout << "Failed to create DMX channel" << std::endl; + return false; + } + + dmxChannel->SetCoarse(1); + + // Test SetResolution with different bit resolutions + bool allResolutionTests = true; + + // Test 8-bit + std::cout << "Testing SetResolution(8-bit)..." << std::endl; + if (__checkVCOM(dmxChannel->SetResolution(EGdtfChannelBitResolution::eGdtfChannelBitResolution_8))) { + if (!VerifyChannelResolution(dmxChannel, EGdtfChannelBitResolution::eGdtfChannelBitResolution_8)) { + allResolutionTests = false; + } + } else { + std::cout << "Failed to set 8-bit resolution" << std::endl; + allResolutionTests = false; + } + + // Test 16-bit + std::cout << "Testing SetResolution(16-bit)..." << std::endl; + if (__checkVCOM(dmxChannel->SetResolution(EGdtfChannelBitResolution::eGdtfChannelBitResolution_16))) { + if (!VerifyChannelResolution(dmxChannel, EGdtfChannelBitResolution::eGdtfChannelBitResolution_16)) { + allResolutionTests = false; + } + } else { + std::cout << "Failed to set 16-bit resolution" << std::endl; + allResolutionTests = false; + } + + // Test 24-bit + std::cout << "Testing SetResolution(24-bit)..." << std::endl; + if (__checkVCOM(dmxChannel->SetResolution(EGdtfChannelBitResolution::eGdtfChannelBitResolution_24))) { + if (!VerifyChannelResolution(dmxChannel, EGdtfChannelBitResolution::eGdtfChannelBitResolution_24)) { + allResolutionTests = false; + } + } else { + std::cout << "Failed to set 24-bit resolution" << std::endl; + allResolutionTests = false; + } + + // Test 32-bit + std::cout << "Testing SetResolution(32-bit)..." << std::endl; + if (__checkVCOM(dmxChannel->SetResolution(EGdtfChannelBitResolution::eGdtfChannelBitResolution_32))) { + if (!VerifyChannelResolution(dmxChannel, EGdtfChannelBitResolution::eGdtfChannelBitResolution_32)) { + allResolutionTests = false; + } + } else { + std::cout << "Failed to set 32-bit resolution" << std::endl; + allResolutionTests = false; + } + + gdtfWrite->Close(); + + return allResolutionTests; +} + +bool ResolutionTest::TestResolutionInXMLOutput() +{ + // Create a fixture with different resolution channels and verify XML output + std::string testPath = UnitTestUtil::GetTestResourceFolder() + kSeparator + "test_resolution_xml.gdtf"; + + IGdtfFixturePtr gdtfWrite(IID_IGdtfFixture); + MvrUUID uuid = VectorworksMVR::MvrUUID(5, 6, 7, 8); + + if (!__checkVCOM(gdtfWrite->OpenForWrite(testPath.c_str(), "XMLTestFixture", "TestManufacturer", uuid))) { + return false; + } + + // Create attribute + IGdtfAttributePtr attr; + if (!__checkVCOM(gdtfWrite->CreateAttribute("Dimmer", "Dimmer", &attr))) { + return false; + } + + // Create model and geometry + IGdtfModelPtr model; + if (!__checkVCOM(gdtfWrite->CreateModel("XMLTestModel", &model))) { + return false; + } + + IGdtfGeometryPtr geometry; + if (!__checkVCOM(gdtfWrite->CreateGeometry(EGdtfObjectType::eGdtfGeometry, "XMLTestGeometry", model, STransformMatrix(), &geometry))) { + return false; + } + + // Create DMX mode + IGdtfDmxModePtr dmxMode; + if (!__checkVCOM(gdtfWrite->CreateDmxMode("XMLTestMode", &dmxMode))) { + return false; + } + + // Create channels with different resolutions + for (int i = 0; i < 4; i++) { + IGdtfDmxChannelPtr dmxChannel; + if (!__checkVCOM(dmxMode->CreateDmxChannel(geometry, &dmxChannel))) { + return false; + } + + dmxChannel->SetCoarse(i + 1); + + // Set different resolutions + EGdtfChannelBitResolution resolution; + switch (i) { + case 0: resolution = EGdtfChannelBitResolution::eGdtfChannelBitResolution_8; break; + case 1: resolution = EGdtfChannelBitResolution::eGdtfChannelBitResolution_16; break; + case 2: resolution = EGdtfChannelBitResolution::eGdtfChannelBitResolution_24; break; + case 3: resolution = EGdtfChannelBitResolution::eGdtfChannelBitResolution_32; break; + } + + if (!__checkVCOM(dmxChannel->SetResolution(resolution))) { + return false; + } + + // Create logical channel and channel function + IGdtfDmxLogicalChannelPtr logicalChannel; + if (!__checkVCOM(dmxChannel->CreateLogicalChannel(attr, &logicalChannel))) { + return false; + } + + IGdtfDmxChannelFunctionPtr channelFunction; + if (!__checkVCOM(logicalChannel->CreateDmxFunction("TestFunction", &channelFunction))) { + return false; + } + } + + gdtfWrite->Close(); + + // Now read back and verify + IGdtfFixturePtr gdtfRead(IID_IGdtfFixture); + if (!__checkVCOM(gdtfRead->ReadFromFile(testPath.c_str()))) { + return false; + } + + IGdtfDmxModePtr readMode; + if (!__checkVCOM(gdtfRead->GetDmxModeAt(0, &readMode))) { + return false; + } + + size_t channelCount; + if (!__checkVCOM(readMode->GetDmxChannelCount(channelCount))) { + std::cout << "Failed to get channel count" << std::endl; + return false; + } + if (channelCount != 4) { + std::cout << "Expected 4 channels, got " << channelCount << std::endl; + return false; + } + + // Verify each channel's resolution + EGdtfChannelBitResolution expectedResolutions[] = { + EGdtfChannelBitResolution::eGdtfChannelBitResolution_8, + EGdtfChannelBitResolution::eGdtfChannelBitResolution_16, + EGdtfChannelBitResolution::eGdtfChannelBitResolution_24, + EGdtfChannelBitResolution::eGdtfChannelBitResolution_32 + }; + + bool allCorrect = true; + for (size_t i = 0; i < channelCount; i++) { + IGdtfDmxChannelPtr channel; + if (__checkVCOM(readMode->GetDmxChannelAt(i, &channel))) { + if (!VerifyChannelResolution(channel, expectedResolutions[i])) { + allCorrect = false; + } + } + } + + std::cout << "XML output test: " << (allCorrect ? "PASSED" : "FAILED") << std::endl; + + return allCorrect; +} + +bool ResolutionTest::TestMixedResolutionChannels() +{ + // Use an existing GDTF file + std::string path = UnitTestUtil::GetTestResourceFolder() + kSeparator + "allWorking.gdtf"; + + IGdtfFixturePtr gdtfFile(IID_IGdtfFixture); + if (!__checkVCOM(gdtfFile->ReadFromFile(path.c_str()))) { + return false; + } + + IGdtfDmxModePtr mode; + if (!__checkVCOM(gdtfFile->GetDmxModeAt(0, &mode))) { + return false; + } + + size_t channelCount; + if (!__checkVCOM(mode->GetDmxChannelCount(channelCount))) { + std::cout << "Failed to get channel count" << std::endl; + return false; + } + std::cout << "Testing mixed resolution channels (" << channelCount << " channels)" << std::endl; + + bool hasMultipleResolutions = false; + EGdtfChannelBitResolution firstResolution = EGdtfChannelBitResolution::eGdtfChannelBitResolution_8; + bool firstSet = false; + + for (size_t i = 0; i < channelCount; i++) { + IGdtfDmxChannelPtr channel; + if (__checkVCOM(mode->GetDmxChannelAt(i, &channel))) { + EGdtfChannelBitResolution resolution; + if (!__checkVCOM(channel->GetResolution(resolution))) { + continue; + } + + if (!firstSet) { + firstResolution = resolution; + firstSet = true; + } else if (resolution != firstResolution) { + hasMultipleResolutions = true; + std::cout << "Found mixed resolutions: "; + PrintResolutionInfo(firstResolution, "First"); + std::cout << " and "; + PrintResolutionInfo(resolution, "Other"); + std::cout << std::endl; + break; + } + } + } + + if (hasMultipleResolutions) { + std::cout << "✅ Successfully detected mixed resolution channels" << std::endl; + return true; + } else { + std::cout << "⚠️ All channels have the same resolution - this might be expected" << std::endl; + return true; // This is not necessarily an error + } +} + +bool ResolutionTest::TestResolutionValidation() +{ + // Test edge cases and validation + IGdtfFixturePtr gdtfWrite(IID_IGdtfFixture); + MvrUUID uuid = VectorworksMVR::MvrUUID(9, 10, 11, 12); + + std::string testPath = UnitTestUtil::GetTestResourceFolder() + kSeparator + "test_validation.gdtf"; + + if (!__checkVCOM(gdtfWrite->OpenForWrite(testPath.c_str(), "ValidationTestFixture", "TestManufacturer", uuid))) { + return false; + } + + // Create basic structure + IGdtfAttributePtr attr; + if (!__checkVCOM(gdtfWrite->CreateAttribute("Dimmer", "Dimmer", &attr))) { + return false; + } + + // Create model and geometry + IGdtfModelPtr model; + if (!__checkVCOM(gdtfWrite->CreateModel("ValidationModel", &model))) { + return false; + } + + IGdtfGeometryPtr geometry; + if (!__checkVCOM(gdtfWrite->CreateGeometry(EGdtfObjectType::eGdtfGeometry, "ValidationGeometry", model, STransformMatrix(), &geometry))) { + return false; + } + + IGdtfDmxModePtr dmxMode; + if (!__checkVCOM(gdtfWrite->CreateDmxMode("ValidationMode", &dmxMode))) { + return false; + } + + IGdtfDmxChannelPtr dmxChannel; + if (!__checkVCOM(dmxMode->CreateDmxChannel(geometry, &dmxChannel))) { + return false; + } + + // Test all valid resolution values + std::vector validResolutions = { + EGdtfChannelBitResolution::eGdtfChannelBitResolution_8, + EGdtfChannelBitResolution::eGdtfChannelBitResolution_16, + EGdtfChannelBitResolution::eGdtfChannelBitResolution_24, + EGdtfChannelBitResolution::eGdtfChannelBitResolution_32 + }; + + bool allValidationsPassed = true; + + for (auto resolution : validResolutions) { + if (!__checkVCOM(dmxChannel->SetResolution(resolution))) { + std::cout << "Failed to set valid resolution: "; + PrintResolutionInfo(resolution, "Validation"); + std::cout << std::endl; + allValidationsPassed = false; + } else { + if (!VerifyChannelResolution(dmxChannel, resolution)) { + allValidationsPassed = false; + } + } + } + + gdtfWrite->Close(); + + std::cout << "Resolution validation: " << (allValidationsPassed ? "PASSED" : "FAILED") << std::endl; + + return allValidationsPassed; +} + +bool ResolutionTest::CreateTestFixture(const std::string& filePath, const std::string& fixtureName) +{ + // Helper method to create basic test fixtures + return true; // Implementation would go here if needed +} + +bool ResolutionTest::VerifyChannelResolution(IGdtfDmxChannelPtr channel, EGdtfChannelBitResolution expectedResolution) +{ + if (!channel) { + std::cout << "Channel is null" << std::endl; + return false; + } + + EGdtfChannelBitResolution actualResolution; + if (!__checkVCOM(channel->GetResolution(actualResolution))) { + std::cout << "Failed to get channel resolution" << std::endl; + return false; + } + + if (actualResolution == expectedResolution) { + std::cout << "✅ Resolution matches: "; + PrintResolutionInfo(actualResolution, "Verified"); + std::cout << std::endl; + return true; + } else { + std::cout << "❌ Resolution mismatch - Expected: "; + PrintResolutionInfo(expectedResolution, "Expected"); + std::cout << ", Got: "; + PrintResolutionInfo(actualResolution, "Actual"); + std::cout << std::endl; + return false; + } +} + +void ResolutionTest::PrintResolutionInfo(EGdtfChannelBitResolution resolution, const std::string& context) +{ + const char* resolutionStr; + switch (resolution) { + case EGdtfChannelBitResolution::eGdtfChannelBitResolution_8: + resolutionStr = "8-bit"; + break; + case EGdtfChannelBitResolution::eGdtfChannelBitResolution_16: + resolutionStr = "16-bit"; + break; + case EGdtfChannelBitResolution::eGdtfChannelBitResolution_24: + resolutionStr = "24-bit"; + break; + case EGdtfChannelBitResolution::eGdtfChannelBitResolution_32: + resolutionStr = "32-bit"; + break; + default: + resolutionStr = "Unknown"; + break; + } + + std::cout << context << ": " << resolutionStr; +} \ No newline at end of file diff --git a/unittest/ResolutionTest.h b/unittest/ResolutionTest.h new file mode 100644 index 00000000..33fe2ac8 --- /dev/null +++ b/unittest/ResolutionTest.h @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +//----- Copyright MVR Group +//----------------------------------------------------------------------------- +#pragma once +#include "Unittest.h" + +class ResolutionTest : public Unittest +{ +public: + ResolutionTest(const std::string& currentDir); + virtual ~ResolutionTest(); +protected: + bool virtual ExecuteTest(); + +private: + // Test resolution extraction from DMXFrom field + bool TestResolutionExtractionFromDMXFrom(); + + // Test SetResolution API functionality + bool TestSetResolutionAPI(); + + // Test resolution in XML output + bool TestResolutionInXMLOutput(); + + // Test mixed resolution channels + bool TestMixedResolutionChannels(); + + // Test resolution validation + bool TestResolutionValidation(); + + // Helper methods + bool CreateTestFixture(const std::string& filePath, const std::string& fixtureName); + bool VerifyChannelResolution(VectorworksMVR::IGdtfDmxChannelPtr channel, VectorworksMVR::GdtfDefines::EGdtfChannelBitResolution expectedResolution); + void PrintResolutionInfo(VectorworksMVR::GdtfDefines::EGdtfChannelBitResolution resolution, const std::string& context); +}; \ No newline at end of file diff --git a/unittest/files/description.xml b/unittest/files/description.xml new file mode 100644 index 00000000..aa2405be --- /dev/null +++ b/unittest/files/description.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/unittest/files/resolution_test_16bit.xml b/unittest/files/resolution_test_16bit.xml new file mode 100644 index 00000000..247624da --- /dev/null +++ b/unittest/files/resolution_test_16bit.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/unittest/files/resolution_test_8bit.xml b/unittest/files/resolution_test_8bit.xml new file mode 100644 index 00000000..b9fb07ce --- /dev/null +++ b/unittest/files/resolution_test_8bit.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/unittest/files/resolution_test_edge_cases.xml b/unittest/files/resolution_test_edge_cases.xml new file mode 100644 index 00000000..049dd113 --- /dev/null +++ b/unittest/files/resolution_test_edge_cases.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/unittest/files/resolution_test_multi.xml b/unittest/files/resolution_test_multi.xml new file mode 100644 index 00000000..db298206 --- /dev/null +++ b/unittest/files/resolution_test_multi.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/unittest/files/test_resolution_xml.gdtf b/unittest/files/test_resolution_xml.gdtf new file mode 100644 index 0000000000000000000000000000000000000000..dc5bc9a46be7810e683e6bf8f7caca208d501281 GIT binary patch literal 3974 zcmeGf+iu%7)ZL{I1&Y1o0|-7hk=kTiAEXwoJvl|}#z@p8!=4!F*d`{ChD3QWhJMbz zWFN9$*&!{8l$~Ngx0hg*V@EuP=YAp2?Ck4r4hH%;cvbxJ=O5F*9)C9&=r8^aa;US4 zuN0T!=&mfH*Z4!$P}K;C>GPwI5)hfpxmd*XLz*1Eq@-3%aM0_aUtbu4c!6$m7RK;%_1tXYq!L_IB7N@b9 z;%laX<4QKGI&i22m{xxe-Z6A+d@-$QBVLwJQ8HU@YM!y;1B%wJ7J#q{l-k6!-Q&p& z_LxTwv~NIky#y#ar6ViMi>6aD8p=Xemn)V5naUi)R9}qW+E7qWi#K_0{KN`J(g{IZ z$E<9W4@h{SFzq}RKb2hVfJW1sStaMZ0Dt4~;$3ekg@8=S9y26cL8Ul2V^E88gkj{w zB8AetVz9_5Uo2yK5+1pv{0+0gE}e$R;2LnVB3G8pdnZV-opSDH8o`MK!<9<&l zBJKUc*|J?@%@w9}w(>lM$OObfp;?`Z{qiyFbXIY6I$xVA$7UgNo$!!jHC>I9N($vl z#`{%6IeQ5o?yl5f2&ADfuCb7NF z^gARPE*Vylmti{yf_vUpz<$LOh7#+b&Wjd6O*Iv|NNnfY23V7IeNywrVw%W>ZgZ_@ z()F>f%W0t+yMUCJFwwc{XWNw3*e|S{DZfpaZc#Qqn8bpu%vrS~8D+OZlSW`Smx2tN zTFKHLA1D{IzeHXET8mATHH8+fS5tOpPFd3}aLMsFbRxGL%n8-9rsTZh3ocmU8R(jP zE2k?V+XPbSOSu3f&oU@X|I+8Y6RB}KmfO16IvULl`o8Y@BMMyn`v?dB_u)4e3#-q= z3IB^;_;K|m{GV0*#}Bjmk9*;IKvVD#I z<9Oo9f_kZ=B%bfz*Xdop|FF|A&(3lB{qT>!dB53cnD1xA5-8$ajI>a4?QV87mzJkvc z)@occRa|Y6Wsp$b7t#69WPFkq|6gfYmvDTjJ3nFv37w_q#Aq9QSmhsdI@TG zpL)6KixgbO*6qc@QAr80Rtw5dYy`O$PzQrv+#rUPlYH#2*VL*xqN zKx0^Q7oFKDb(xkDm~k;F=Ns3AOiZ^!f}`}%33DZNJufyHOC&QjE@{2M3|;2E6A7&6 zuPF;Mk0M!!$QFiq3&~*}P#NF=JEgbSwCrMB3gv1sDYd<9fJ$(RsZmAQ%>n&oX~|gj#TK;>xcP96POIWfvgxoI48@fs8!D_fS Va_{ovCqvu7Pk{fw@#1bY{sKIQAszq# literal 0 HcmV?d00001 diff --git a/unittest/files/test_validation.gdtf b/unittest/files/test_validation.gdtf new file mode 100644 index 0000000000000000000000000000000000000000..15608f229ccb7558d7ed25a4e353dd5e33fe9fac GIT binary patch literal 2044 zcmb_dTTk0C6fV0;NN6wo0LxE%pfpUAwn+{M+NB^UR1hxHo=kGuT1)IIaXYGwAG62( zy#0e6r*Yz5&|a3Rt@EAZbHDUYpTF2{m}h%G`TF74pSM3>HyY;q2C*3OC=+8Xl-zwt z6Lx?>Zd|D@wn?~_+NP4Ce2n&#N_ zj>?nQp3^8fQ*wCDQ?!bb9+#5=kBrjHry=CpMJSo`-S9-j+&FJIN~M%s!XOBZl&g`- zv=teSCh5K8A~BTe`?1W+)p%gU?8M0I`fidsF4=a!jNvJ zCgZ$SlLFwzixs>QSc`Ghlpc0OnnFfNe>BTQ#FJ}OZ6YoKu?)1H`LyJ5bhcK6vl?1; zfZdJ&lFDdil{rbRjbv?=sO)OYBOpB$W47|k?vc$1b*wmy<04KxsjpN@(AO?cC)x!9 zk!Y+wN5tn;=q0GryX$9aAQEsH+m|N`uS!aYv|12`*T#@(0ktz|#RX!RIXMg=EsmHh zax8`;pT75Y>)QN|)nH$13sJx=AhRY|ixUjSdY&^F9{-DtwN?y7sLcDCR4^0$r1oY0 zj;)sz9W>YH7(~uM4mG+}nYhwLg+xS_>g!T~H}t8#@JHu~|{eI2!7aQU+sr(v(7G z7$%h$_3hIi*4Le<50C$oX~)CQ-ec8mthM4B!$vVKI0aH7%fouvLvzc{y<+y^z4nM> zM>*BDL?Fm>lmY*SONSC0BR8BDqeXKirf2LRn Date: Tue, 11 Nov 2025 11:32:00 +0000 Subject: [PATCH 2/3] Remove Printf --- src/GDTFManager.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/GDTFManager.cpp b/src/GDTFManager.cpp index f9b6cb79..e54eac37 100644 --- a/src/GDTFManager.cpp +++ b/src/GDTFManager.cpp @@ -5674,11 +5674,6 @@ EGdtfChannelBitResolution SceneData::GdtfDmxChannel::ExtractResolutionFromDMXFro EGdtfChannelBitResolution calculatedRes = GetCalculatedChannelBitResolution(); - printf("[DEBUG] No DMXFrom resolution found, using calculated: %d-bit\n", - calculatedRes == EGdtfChannelBitResolution::eGdtfChannelBitResolution_8 ? 8 : - calculatedRes == EGdtfChannelBitResolution::eGdtfChannelBitResolution_16 ? 16 : - calculatedRes == EGdtfChannelBitResolution::eGdtfChannelBitResolution_24 ? 24 : 32); - return calculatedRes; } From 94fcb4817b732aaba26706dcc15dfbb204f5ce9d Mon Sep 17 00:00:00 2001 From: Vector Date: Fri, 21 Nov 2025 08:22:11 +0000 Subject: [PATCH 3/3] Extraction is now only for virtual channels --- src/GDTFManager.cpp | 12 +++++------- src/GDTFManager.h | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/GDTFManager.cpp b/src/GDTFManager.cpp index e54eac37..78de9508 100644 --- a/src/GDTFManager.cpp +++ b/src/GDTFManager.cpp @@ -5407,7 +5407,7 @@ void GdtfDmxChannel::OnReadFromNode(const IXMLFileNodePtr& pNode) GdtfConverter::ConvertDmxOffset(offset, pNode, fCoarse, fFine, fUltra, fUber); } - fResolution = ExtractResolutionFromDMXFrom(pNode); + fResolution = GetCalculatedChannelBitResolution(pNode); // In GDTF 1.0, default value was in the DMX channel, this is for old files : TXString defVal; @@ -5599,10 +5599,10 @@ const TGdtfDmxLogicalChannelArray GdtfDmxChannel::GetLogicalChannelArray() return fLogicalChannels; } -EGdtfChannelBitResolution SceneData::GdtfDmxChannel::GetCalculatedChannelBitResolution() +EGdtfChannelBitResolution SceneData::GdtfDmxChannel::GetCalculatedChannelBitResolution(const IXMLFileNodePtr& pNode) { // 0 is false, everything else is true - if ((!fCoarse) && !fFine && !fUltra && !fUber) { return EGdtfChannelBitResolution::eGdtfChannelBitResolution_32; } + if ((!fCoarse) && !fFine && !fUltra && !fUber) { return ExtractResolutionFromDMXFrom(pNode); } else if (( fCoarse) && !fFine && !fUltra && !fUber) { return EGdtfChannelBitResolution::eGdtfChannelBitResolution_8; } else if (( fCoarse) &&( fFine) && !fUltra && !fUber ) { return EGdtfChannelBitResolution::eGdtfChannelBitResolution_16; } else if (( fCoarse) &&( fFine) && ( fUltra) && !fUber ) { return EGdtfChannelBitResolution::eGdtfChannelBitResolution_24; } @@ -5671,10 +5671,8 @@ EGdtfChannelBitResolution SceneData::GdtfDmxChannel::ExtractResolutionFromDMXFro if (found) { return foundResolution; } - - EGdtfChannelBitResolution calculatedRes = GetCalculatedChannelBitResolution(); - - return calculatedRes; + + return EGdtfChannelBitResolution::eGdtfChannelBitResolution_32; } DmxValue SceneData::GdtfDmxChannel::GetChannelMaxDmx() diff --git a/src/GDTFManager.h b/src/GDTFManager.h index 1a2f9041..6f7ec24c 100644 --- a/src/GDTFManager.h +++ b/src/GDTFManager.h @@ -1785,7 +1785,7 @@ namespace SceneData TXString GetUnresolvedGeomRef() const; GdtfDmxChannelFunctionPtr GetInitialFunction(); TXString GetUnresolvedInitialFunction() const; - EGdtfChannelBitResolution GetCalculatedChannelBitResolution(); + EGdtfChannelBitResolution GetCalculatedChannelBitResolution(const IXMLFileNodePtr& pNode); DmxValue GetChannelMaxDmx(); bool IsVirtual() const;