From 623ff52253e9250c05f1b3dda04a2fe7c70039c6 Mon Sep 17 00:00:00 2001 From: Alesandro Dragnev Date: Tue, 12 May 2026 16:18:44 +0300 Subject: [PATCH 1/7] Implementing Listening Obj type into MVR --- .../CMediaRessourceVectorImpl.cpp | 68 +++++++++++++++++++ .../CMediaRessourceVectorImpl.h | 21 +++--- src/Include/IMediaRessourceVectorInterface.h | 21 +++--- src/Prefix/CommonPrefix.h | 2 + src/SceneDataExchange.cpp | 55 +++++++++++++++ src/SceneDataExchange.h | 60 ++++++++++------ 6 files changed, 187 insertions(+), 40 deletions(-) diff --git a/src/Implementation/CMediaRessourceVectorImpl.cpp b/src/Implementation/CMediaRessourceVectorImpl.cpp index 7fa782e3..0502b8c7 100644 --- a/src/Implementation/CMediaRessourceVectorImpl.cpp +++ b/src/Implementation/CMediaRessourceVectorImpl.cpp @@ -976,6 +976,74 @@ VectorworksMVR::VCOMError VectorworksMVR::CMediaRessourceVectorImpl::CreateProje return kVCOMError_NoError; } +VectorworksMVR::VCOMError VectorworksMVR::CMediaRessourceVectorImpl::CreateListeningPlane(const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outlisteningPlane) +{ + //--------------------------------------------------------------------------- + // Read Container + CSceneObjImpl* pContainer = static_cast(addToContainer); + + ASSERTN(kEveryone, pContainer != nullptr); + if ( ! pContainer) { return kVCOMError_NoValidContainerObj; } + + + SceneData::SceneDataObjWithMatrixPtr obj = nullptr; + ESceneObjType type = ESceneObjType::Layer; + pContainer->GetPointer(obj, type); + + if( ! VectorworksMVR::MvrUtil::isContainerType(type)) { return kVCOMError_NoValidContainerObj; } + + SceneData::SceneDataGroupObjPtr group = static_cast(obj); + + ASSERTN(kEveryone, group != nullptr); + if ( ! group) { return kVCOMError_NoValidContainerObj; } + + //--------------------------------------------------------------------------- + // Create the obj + VWFC::Tools::VWUUID uuid (guid.a,guid.b,guid.c,guid.d); + TXString nameStr ( name ); + + VWTransformMatrix ma; + GdtfUtil::ConvertMatrix(offset, ma); + + SceneData::SceneDataListeningPlaneObjPtr ptr = fExchangeObj.CreateListeningPlane(uuid, ma, nameStr, group); + + //--------------------------------------------------------------------------- + // Initialize Object + CSceneObjImpl* pListeningPlane = nullptr; + + // Query Interface + if (VCOM_SUCCEEDED(VWQueryInterface(IID_SceneObject, (IVWUnknown**) & pListeningPlane))) + { + // Check Casting + CSceneObjImpl* pResultInterface = static_cast(pListeningPlane); + if (pResultInterface) + { + pResultInterface->SetPointer(ptr, GetExchangeObj()); + } + else + { + pResultInterface->Release(); + pResultInterface = nullptr; + return kVCOMError_NoInterface; + } + } + + //--------------------------------------------------------------------------- + // Check Incoming Object + if (*outlisteningPlane) + { + (*outlisteningPlane)->Release(); + *outlisteningPlane = NULL; + } + + //--------------------------------------------------------------------------- + // Set Out Value + *outlisteningPlane = pListeningPlane; + + return kVCOMError_NoError; +} + + VectorworksMVR::VCOMError VectorworksMVR::CMediaRessourceVectorImpl::Close() { //------------------------------------------------------------------ diff --git a/src/Implementation/CMediaRessourceVectorImpl.h b/src/Implementation/CMediaRessourceVectorImpl.h index 4a5db374..5bc0772b 100644 --- a/src/Implementation/CMediaRessourceVectorImpl.h +++ b/src/Implementation/CMediaRessourceVectorImpl.h @@ -55,16 +55,17 @@ namespace VectorworksMVR // Then you can generate all other objects - virtual VCOMError VCOM_CALLTYPE CreateLayerObject( const MvrUUID& guid, MvrString name, ISceneObj** outLayerObj); - virtual VCOMError VCOM_CALLTYPE CreateGroupObject( const MvrUUID& guid, const STransformMatrix& offset, ISceneObj* addToContainer, ISceneObj** outGroupObj); - virtual VCOMError VCOM_CALLTYPE CreateGroupObject( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outGroupObj); - virtual VCOMError VCOM_CALLTYPE CreateFixture( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outFixture); - virtual VCOMError VCOM_CALLTYPE CreateSceneObject( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outSceneObj); - virtual VCOMError VCOM_CALLTYPE CreateFocusPoint( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outFocusPoint); - virtual VCOMError VCOM_CALLTYPE CreateTruss( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outTruss); - virtual VCOMError VCOM_CALLTYPE CreateSupport( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outSupport); - virtual VCOMError VCOM_CALLTYPE CreateVideoScreen( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outVideoScreen); - virtual VCOMError VCOM_CALLTYPE CreateProjector( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outProjector); + virtual VCOMError VCOM_CALLTYPE CreateLayerObject( const MvrUUID& guid, MvrString name, ISceneObj** outLayerObj); + virtual VCOMError VCOM_CALLTYPE CreateGroupObject( const MvrUUID& guid, const STransformMatrix& offset, ISceneObj* addToContainer, ISceneObj** outGroupObj); + virtual VCOMError VCOM_CALLTYPE CreateGroupObject( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outGroupObj); + virtual VCOMError VCOM_CALLTYPE CreateFixture( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outFixture); + virtual VCOMError VCOM_CALLTYPE CreateSceneObject( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outSceneObj); + virtual VCOMError VCOM_CALLTYPE CreateFocusPoint( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outFocusPoint); + virtual VCOMError VCOM_CALLTYPE CreateTruss( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outTruss); + virtual VCOMError VCOM_CALLTYPE CreateSupport( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outSupport); + virtual VCOMError VCOM_CALLTYPE CreateVideoScreen( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outVideoScreen); + virtual VCOMError VCOM_CALLTYPE CreateProjector( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outProjector); + virtual VCOMError VCOM_CALLTYPE CreateListeningPlane( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outListeningPlane); // Add the end call to write the file to disk virtual VCOMError VCOM_CALLTYPE Close(); diff --git a/src/Include/IMediaRessourceVectorInterface.h b/src/Include/IMediaRessourceVectorInterface.h index 2c3266e8..a5f7f8d4 100644 --- a/src/Include/IMediaRessourceVectorInterface.h +++ b/src/Include/IMediaRessourceVectorInterface.h @@ -450,16 +450,17 @@ namespace VectorworksMVR virtual VCOMError VCOM_CALLTYPE CreateMappingDefinitionObject( const MvrUUID& guid, MvrString name, IMappingDefinition** outMapDef) = 0; // Then you can generate all other objects - virtual VCOMError VCOM_CALLTYPE CreateLayerObject( const MvrUUID& guid, MvrString name, ISceneObj** outLayerObj) = 0; - virtual VCOMError VCOM_CALLTYPE CreateGroupObject( const MvrUUID& guid, const STransformMatrix& offset, ISceneObj* addToContainer, ISceneObj** outGroupObj) = 0; - virtual VCOMError VCOM_CALLTYPE CreateGroupObject( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outGroupObj) = 0; - virtual VCOMError VCOM_CALLTYPE CreateFixture( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outFixture) = 0; - virtual VCOMError VCOM_CALLTYPE CreateSceneObject( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outSceneObj) = 0; - virtual VCOMError VCOM_CALLTYPE CreateFocusPoint( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outFocusPoint) = 0; - virtual VCOMError VCOM_CALLTYPE CreateVideoScreen( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outVideoScreen) = 0; - virtual VCOMError VCOM_CALLTYPE CreateTruss( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outTruss) = 0; - virtual VCOMError VCOM_CALLTYPE CreateSupport( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outSupport) = 0; - virtual VCOMError VCOM_CALLTYPE CreateProjector( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outProjector) = 0; + virtual VCOMError VCOM_CALLTYPE CreateLayerObject( const MvrUUID& guid, MvrString name, ISceneObj** outLayerObj) = 0; + virtual VCOMError VCOM_CALLTYPE CreateGroupObject( const MvrUUID& guid, const STransformMatrix& offset, ISceneObj* addToContainer, ISceneObj** outGroupObj) = 0; + virtual VCOMError VCOM_CALLTYPE CreateGroupObject( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outGroupObj) = 0; + virtual VCOMError VCOM_CALLTYPE CreateFixture( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outFixture) = 0; + virtual VCOMError VCOM_CALLTYPE CreateSceneObject( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outSceneObj) = 0; + virtual VCOMError VCOM_CALLTYPE CreateFocusPoint( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outFocusPoint) = 0; + virtual VCOMError VCOM_CALLTYPE CreateVideoScreen( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outVideoScreen) = 0; + virtual VCOMError VCOM_CALLTYPE CreateTruss( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outTruss) = 0; + virtual VCOMError VCOM_CALLTYPE CreateSupport( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outSupport) = 0; + virtual VCOMError VCOM_CALLTYPE CreateProjector( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outProjector) = 0; + virtual VCOMError VCOM_CALLTYPE CreateListeningPlane( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outListeningPlane) = 0; // Add the end call to write the file to disk virtual VCOMError VCOM_CALLTYPE Close() = 0; diff --git a/src/Prefix/CommonPrefix.h b/src/Prefix/CommonPrefix.h index 702244d1..21bf3bd2 100644 --- a/src/Prefix/CommonPrefix.h +++ b/src/Prefix/CommonPrefix.h @@ -245,6 +245,8 @@ #define XML_Val_ProjectorObjectProjection "Projection" #define XML_Val_ProjectorObjectScaleHandling "ScaleHandling" +#define XML_Val_ListeningPlaneObjectNodeName "ListeningPlane" + #define XML_Val_SymbolObjectNodeName "Symbol" #define XML_Val_GuidSymdefAttrName "symdef" diff --git a/src/SceneDataExchange.cpp b/src/SceneDataExchange.cpp index b231634f..cf5db74e 100644 --- a/src/SceneDataExchange.cpp +++ b/src/SceneDataExchange.cpp @@ -2796,6 +2796,35 @@ void SceneDataProjectorObj::OnReadFromNode(const IXMLFileNodePtr& pNode, SceneDa } +// ---------------------------------------------------------------------------------------------------------------------------------- +// SceneDataListeningPlaneObj +SceneDataListeningPlaneObj::SceneDataListeningPlaneObj(const SceneDataGUID& guid) : SceneDataGDTFSpecObj(guid) +{ +} + +SceneDataListeningPlaneObj::~SceneDataListeningPlaneObj() +{ +} + +TXString SceneDataListeningPlaneObj::GetNodeName() +{ + return TXString(XML_Val_ListeningPlaneObjectNodeName); +} + +ESceneDataObjectType SceneDataListeningPlaneObj::GetObjectType() +{ + return ESceneDataObjectType::eListeningPlane; +} + +void SceneDataListeningPlaneObj::OnPrintToFile(IXMLFileNodePtr pNode, SceneDataExchange* exchange) +{ + SceneDataObjWithMatrix::OnPrintToFile( pNode, exchange ); +} + +void SceneDataListeningPlaneObj::OnReadFromNode(const IXMLFileNodePtr& pNode, SceneDataExchange* exchange) +{ + SceneDataObjWithMatrix::OnReadFromNode( pNode, exchange ); +} // ---------------------------------------------------------------------------------------------------------------------------------- // SceneDataSymbolObj @@ -3444,6 +3473,32 @@ SceneDataProjectorObjPtr SceneDataExchange::ReadProjector(const SceneDataGUID& g return newProjectorObj; } +SceneDataListeningPlaneObjPtr SceneDataExchange::CreateListeningPlane(const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer) +{ + SceneDataListeningPlaneObjPtr newListeningPlaneObj = new SceneDataListeningPlaneObj(guid); + addToContainer->AddObject(newListeningPlaneObj); + + newListeningPlaneObj->setName(name); + newListeningPlaneObj->SetTransformMatrix(offset); + + return newListeningPlaneObj; +} + +SceneDataListeningPlaneObjPtr SceneDataExchange::ReadListeningPlane(const SceneDataGUID& guid,const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer) +{ + if ( CheckAbort() ) return nullptr; + //---------------------------------------------------------------------------- + // Create new Object + SceneDataListeningPlaneObjPtr newListeningPlaneObj = new SceneDataListeningPlaneObj(guid); + addToContainer->AddObject(newListeningPlaneObj); + + //---------------------------------------------------------------------------- + // Read + newListeningPlaneObj->ReadFromNode(node, this); + + return newListeningPlaneObj; +} + SceneDataSymbolObjPtr SceneDataExchange::CreateSymbol(const SceneDataGUID& guid, const VWTransformMatrix& offset, SceneDataSymDefObjPtr symDef) { SceneDataSymbolObjPtr newSymbolObj = new SceneDataSymbolObj(guid); diff --git a/src/SceneDataExchange.h b/src/SceneDataExchange.h index afbacc24..b4815fdf 100644 --- a/src/SceneDataExchange.h +++ b/src/SceneDataExchange.h @@ -47,6 +47,7 @@ namespace SceneData eVideoScreen = 7, eProjector = 8, eSupport = 9, + eListeningPlane = 10, eSymDef = -1, eProviderObj = -2, ePosition = -3, @@ -937,6 +938,24 @@ namespace SceneData }; typedef SceneDataProjectorObj* SceneDataProjectorObjPtr; + // ---------------------------------------------------------------------------------------------------------------------------------- + // SceneDataListeningPlaneObj + class SceneDataListeningPlaneObj : public SceneDataGDTFSpecObj + { + + public: + SceneDataListeningPlaneObj(const SceneDataGUID& guid); + virtual ~SceneDataListeningPlaneObj(); + + private: + virtual TXString GetNodeName(); + virtual ESceneDataObjectType GetObjectType(); + virtual void OnPrintToFile(IXMLFileNodePtr pNode, SceneDataExchange* exchange); + virtual void OnReadFromNode(const IXMLFileNodePtr& pNode, SceneDataExchange* exchange); + + }; + typedef SceneDataListeningPlaneObj* SceneDataListeningPlaneObjPtr; + // ---------------------------------------------------------------------------------------------------------------------------------- // SceneDataSymbolObj class SceneDataSymbolObj : public SceneDataGeoInstanceObj @@ -1057,17 +1076,17 @@ namespace SceneData SceneDataMappingDefinitionObjPtr CreateMappingDefinitionObject(const SceneDataGUID& guid, const TXString& name); - SceneDataLayerObjPtr CreateLayerObject( const SceneDataGUID& guid, const TXString& name); - SceneDataGroupObjPtr CreateGroupObject( const SceneDataGUID& guid, const VWTransformMatrix& offset, SceneDataGroupObjPtr addToContainer); - SceneDataGroupObjPtr CreateGroupObject( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); - SceneDataFixtureObjPtr CreateFixture( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); - SceneDataSceneryObjPtr CreateSceneryObject(const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); - SceneDataFocusPointObjPtr CreateFocusPoint( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); - SceneDataTrussObjPtr CreateTruss( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); - SceneDataSupportObjPtr CreateSupport( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); - SceneDataVideoScreenObjPtr CreateVideoScreen( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); - SceneDataProjectorObjPtr CreateProjector( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); - + SceneDataLayerObjPtr CreateLayerObject( const SceneDataGUID& guid, const TXString& name); + SceneDataGroupObjPtr CreateGroupObject( const SceneDataGUID& guid, const VWTransformMatrix& offset, SceneDataGroupObjPtr addToContainer); + SceneDataGroupObjPtr CreateGroupObject( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); + SceneDataFixtureObjPtr CreateFixture( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); + SceneDataSceneryObjPtr CreateSceneryObject( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); + SceneDataFocusPointObjPtr CreateFocusPoint( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); + SceneDataTrussObjPtr CreateTruss( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); + SceneDataSupportObjPtr CreateSupport( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); + SceneDataVideoScreenObjPtr CreateVideoScreen( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); + SceneDataProjectorObjPtr CreateProjector( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); + SceneDataListeningPlaneObjPtr CreateListeningPlane( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); // --------------------------------------------------------------------------------------------------------------------- // Read calls @@ -1079,15 +1098,16 @@ namespace SceneData SceneDataMappingDefinitionObjPtr ReadMappingDefinitionObject(const IXMLFileNodePtr& node); - SceneDataLayerObjPtr ReadLayerObject( const SceneDataGUID& guid,const IXMLFileNodePtr& node); - SceneDataGroupObjPtr ReadGroupObject( const SceneDataGUID& guid,const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); - SceneDataFixtureObjPtr ReadFixture( const SceneDataGUID& guid,const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); - SceneDataSceneryObjPtr ReadSceneryObject( const SceneDataGUID& guid,const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); - SceneDataFocusPointObjPtr ReadFocusPoint( const SceneDataGUID& guid,const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); - SceneDataTrussObjPtr ReadTruss( const SceneDataGUID& guid,const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); - SceneDataSupportObjPtr ReadSupport( const SceneDataGUID& guid,const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); - SceneDataVideoScreenObjPtr ReadVideoScreen( const SceneDataGUID& guid,const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); - SceneDataProjectorObjPtr ReadProjector( const SceneDataGUID& guid,const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); + SceneDataLayerObjPtr ReadLayerObject( const SceneDataGUID& guid, const IXMLFileNodePtr& node); + SceneDataGroupObjPtr ReadGroupObject( const SceneDataGUID& guid, const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); + SceneDataFixtureObjPtr ReadFixture( const SceneDataGUID& guid, const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); + SceneDataSceneryObjPtr ReadSceneryObject( const SceneDataGUID& guid, const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); + SceneDataFocusPointObjPtr ReadFocusPoint( const SceneDataGUID& guid, const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); + SceneDataTrussObjPtr ReadTruss( const SceneDataGUID& guid, const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); + SceneDataSupportObjPtr ReadSupport( const SceneDataGUID& guid, const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); + SceneDataVideoScreenObjPtr ReadVideoScreen( const SceneDataGUID& guid, const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); + SceneDataProjectorObjPtr ReadProjector( const SceneDataGUID& guid, const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); + SceneDataListeningPlaneObjPtr ReadListeningPlane( const SceneDataGUID& guid, const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer ); // --------------------------------------------------------------------------------------------------------------------- // Write calls From 09163583373054fe678359fb168930587e924cb7 Mon Sep 17 00:00:00 2001 From: Alesandro Dragnev Date: Tue, 12 May 2026 16:32:10 +0300 Subject: [PATCH 2/7] Update IMediaRessourceVectorInterface.h --- src/Include/IMediaRessourceVectorInterface.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Include/IMediaRessourceVectorInterface.h b/src/Include/IMediaRessourceVectorInterface.h index a5f7f8d4..c3360717 100644 --- a/src/Include/IMediaRessourceVectorInterface.h +++ b/src/Include/IMediaRessourceVectorInterface.h @@ -327,6 +327,7 @@ namespace VectorworksMVR Fixture, Projector, Support, + ListeningPlane }; class DYNAMIC_ATTRIBUTE ISceneObj : public IVWUnknown From 7aa3323ab449a42f48d85c2a973d0327a5aec3ad Mon Sep 17 00:00:00 2001 From: Alesandro Dragnev Date: Wed, 13 May 2026 15:05:23 +0300 Subject: [PATCH 3/7] Adding Listening Obj type --- src/Implementation/CSceneObjImpl.cpp | 19 ++++++++++--------- src/SceneDataExchange.cpp | 24 +++++++++++------------- src/SceneDataExchange.h | 5 +++-- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/Implementation/CSceneObjImpl.cpp b/src/Implementation/CSceneObjImpl.cpp index 1da2d4f1..91668cff 100644 --- a/src/Implementation/CSceneObjImpl.cpp +++ b/src/Implementation/CSceneObjImpl.cpp @@ -2152,15 +2152,16 @@ void VectorworksMVR::CSceneObjImpl::SetPointer(SceneData::SceneDataObjWithMatrix switch (pointer->GetObjectType()) { - case SceneData::eLayer: fType = ESceneObjType::Layer; break; - case SceneData::eGroup: fType = ESceneObjType::Group; break; - case SceneData::eTruss: fType = ESceneObjType::Truss; break; - case SceneData::eSupport: fType = ESceneObjType::Support; break; - case SceneData::eFixture: fType = ESceneObjType::Fixture; break; - case SceneData::eFocusPoint: fType = ESceneObjType::FocusPoint; break; - case SceneData::eSceneObject: fType = ESceneObjType::SceneObj; break; - case SceneData::eVideoScreen: fType = ESceneObjType::VideoScreen; break; - case SceneData::eProjector: fType = ESceneObjType::Projector; break; + case SceneData::eLayer: fType = ESceneObjType::Layer; break; + case SceneData::eGroup: fType = ESceneObjType::Group; break; + case SceneData::eTruss: fType = ESceneObjType::Truss; break; + case SceneData::eSupport: fType = ESceneObjType::Support; break; + case SceneData::eFixture: fType = ESceneObjType::Fixture; break; + case SceneData::eFocusPoint: fType = ESceneObjType::FocusPoint; break; + case SceneData::eSceneObject: fType = ESceneObjType::SceneObj; break; + case SceneData::eVideoScreen: fType = ESceneObjType::VideoScreen; break; + case SceneData::eProjector: fType = ESceneObjType::Projector; break; + case SceneData::eListeningPlane: fType = ESceneObjType::ListeningPlane; break; default: DSTOP((kEveryone, "Unexpected input!")); diff --git a/src/SceneDataExchange.cpp b/src/SceneDataExchange.cpp index cf5db74e..54209f72 100644 --- a/src/SceneDataExchange.cpp +++ b/src/SceneDataExchange.cpp @@ -2798,7 +2798,7 @@ void SceneDataProjectorObj::OnReadFromNode(const IXMLFileNodePtr& pNode, SceneDa // ---------------------------------------------------------------------------------------------------------------------------------- // SceneDataListeningPlaneObj -SceneDataListeningPlaneObj::SceneDataListeningPlaneObj(const SceneDataGUID& guid) : SceneDataGDTFSpecObj(guid) +SceneDataListeningPlaneObj::SceneDataListeningPlaneObj(const SceneDataGUID& guid) : SceneDataGroupObj(guid) { } @@ -3487,13 +3487,10 @@ SceneDataListeningPlaneObjPtr SceneDataExchange::CreateListeningPlane(const Scen SceneDataListeningPlaneObjPtr SceneDataExchange::ReadListeningPlane(const SceneDataGUID& guid,const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer) { if ( CheckAbort() ) return nullptr; - //---------------------------------------------------------------------------- - // Create new Object + SceneDataListeningPlaneObjPtr newListeningPlaneObj = new SceneDataListeningPlaneObj(guid); addToContainer->AddObject(newListeningPlaneObj); - //---------------------------------------------------------------------------- - // Read newListeningPlaneObj->ReadFromNode(node, this); return newListeningPlaneObj; @@ -4122,14 +4119,15 @@ void SceneDataExchange::ReadChildObjs(const IXMLFileNodePtr& node, SceneDataGrou { SceneDataObjWithMatrixPtr obj = nullptr; - if ( nodeName == XML_Val_FixtureNodeName) { obj = ReadFixture( SceneDataGUID(groupUuid),objNode, addToContainer); } - else if ( nodeName == XML_Val_SceneObjectNodeName) { obj = ReadSceneryObject( SceneDataGUID(groupUuid),objNode, addToContainer); } - else if ( nodeName == XML_Val_FocusPointObjectNodeName) { obj = ReadFocusPoint( SceneDataGUID(groupUuid),objNode, addToContainer); } - else if ( nodeName == XML_Val_TrussObjectNodeName) { obj = ReadTruss( SceneDataGUID(groupUuid),objNode, addToContainer); } - else if ( nodeName == XML_Val_VideoScreenObjectNodeName) { obj = ReadVideoScreen( SceneDataGUID(groupUuid),objNode, addToContainer); } - else if ( nodeName == XML_Val_SupportObjectNodeName) { obj = ReadSupport( SceneDataGUID(groupUuid),objNode, addToContainer); } - else if ( nodeName == XML_Val_ProjectorObjectNodeName) { obj = ReadProjector( SceneDataGUID(groupUuid),objNode, addToContainer); } - else if ( nodeName == XML_Val_GroupNodeName) { obj = ProcessGroup(objNode, addToContainer); } + if ( nodeName == XML_Val_FixtureNodeName) { obj = ReadFixture( SceneDataGUID(groupUuid), objNode, addToContainer); } + else if ( nodeName == XML_Val_SceneObjectNodeName) { obj = ReadSceneryObject( SceneDataGUID(groupUuid), objNode, addToContainer); } + else if ( nodeName == XML_Val_FocusPointObjectNodeName) { obj = ReadFocusPoint( SceneDataGUID(groupUuid), objNode, addToContainer); } + else if ( nodeName == XML_Val_TrussObjectNodeName) { obj = ReadTruss( SceneDataGUID(groupUuid), objNode, addToContainer); } + else if ( nodeName == XML_Val_VideoScreenObjectNodeName) { obj = ReadVideoScreen( SceneDataGUID(groupUuid), objNode, addToContainer); } + else if ( nodeName == XML_Val_SupportObjectNodeName) { obj = ReadSupport( SceneDataGUID(groupUuid), objNode, addToContainer); } + else if ( nodeName == XML_Val_ProjectorObjectNodeName) { obj = ReadProjector( SceneDataGUID(groupUuid), objNode, addToContainer); } + else if ( nodeName == XML_Val_ListeningPlaneObjectNodeName ) { obj = ReadListeningPlane( SceneDataGUID(groupUuid), objNode, addToContainer); } + else if ( nodeName == XML_Val_GroupNodeName) { obj = ProcessGroup(objNode, addToContainer); } auto grp = dynamic_cast(obj); if (grp) diff --git a/src/SceneDataExchange.h b/src/SceneDataExchange.h index b4815fdf..29728ddb 100644 --- a/src/SceneDataExchange.h +++ b/src/SceneDataExchange.h @@ -940,16 +940,17 @@ namespace SceneData // ---------------------------------------------------------------------------------------------------------------------------------- // SceneDataListeningPlaneObj - class SceneDataListeningPlaneObj : public SceneDataGDTFSpecObj + class SceneDataListeningPlaneObj : public SceneDataGroupObj { public: - SceneDataListeningPlaneObj(const SceneDataGUID& guid); + SceneDataListeningPlaneObj(const SceneDataGUID& guid); virtual ~SceneDataListeningPlaneObj(); private: virtual TXString GetNodeName(); virtual ESceneDataObjectType GetObjectType(); + virtual void OnPrintToFile(IXMLFileNodePtr pNode, SceneDataExchange* exchange); virtual void OnReadFromNode(const IXMLFileNodePtr& pNode, SceneDataExchange* exchange); From 4a3f30f118930cc526143afa66acba809e08287f Mon Sep 17 00:00:00 2001 From: Alesandro Dragnev Date: Fri, 15 May 2026 13:56:00 +0300 Subject: [PATCH 4/7] Adding heat map data property --- src/Implementation/CSceneObjImpl.cpp | 40 ++++++++++++++++++++ src/Implementation/CSceneObjImpl.h | 2 + src/Include/IMediaRessourceVectorInterface.h | 4 ++ src/SceneDataExchange.cpp | 14 +++++++ src/SceneDataExchange.h | 5 +++ 5 files changed, 65 insertions(+) diff --git a/src/Implementation/CSceneObjImpl.cpp b/src/Implementation/CSceneObjImpl.cpp index 91668cff..cabbab34 100644 --- a/src/Implementation/CSceneObjImpl.cpp +++ b/src/Implementation/CSceneObjImpl.cpp @@ -1984,6 +1984,46 @@ VectorworksMVR::VCOMError VectorworksMVR::CSceneObjImpl::GetVideoScreenSource(IS return kVCOMError_NoError; } +// ------------------------------------------------------------------------------------------------------------------------------------------ +// Listening Plane +VectorworksMVR::VCOMError VectorworksMVR::CSceneObjImpl::SetAudioDescriptionFile(MvrString fileName) +{ + // Check if this is initialized + ASSERTN(kEveryone,fPtr); + if( ! fPtr) return kVCOMError_NotInitialized; + + // Check the type is right + ASSERTN(kEveryone,fType == ESceneObjType::ListeningPlane); + if( fType != ESceneObjType::ListeningPlane) return kVCOMError_Failed; + + // Try to cast + SceneData::SceneDataListeningPlaneObjPtr listeningPlane = static_cast(fPtr); + if( ! listeningPlane) return kVCOMError_Failed; + + listeningPlane->SetAudioDescriptionFile(fileName); + + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CSceneObjImpl::GetAudioDescriptionFile( MvrString& outFileName ) +{ + // Check if this is initialized + ASSERTN( kEveryone, fPtr ); + if ( !fPtr ) return kVCOMError_NotInitialized; + + // Check the type is right + ASSERTN( kEveryone, fType == ESceneObjType::ListeningPlane ); + if ( fType != ESceneObjType::ListeningPlane ) return kVCOMError_Failed; + + // Try to cast + SceneData::SceneDataListeningPlaneObjPtr listeningPlane = static_cast( fPtr ); + if ( !listeningPlane ) return kVCOMError_Failed; + + outFileName = listeningPlane->GetAudioDescriptionFile(); + + return kVCOMError_NoError; +} + //------------------------------------------------------------------------------------------------------------------------------------------ // Projector VectorworksMVR::VCOMError VectorworksMVR::CSceneObjImpl::SetProjectorSource(MvrString value, MvrString linkedGeometry, GdtfDefines::ESourceType type) diff --git a/src/Implementation/CSceneObjImpl.h b/src/Implementation/CSceneObjImpl.h index 40aceba1..d1484183 100644 --- a/src/Implementation/CSceneObjImpl.h +++ b/src/Implementation/CSceneObjImpl.h @@ -112,6 +112,8 @@ namespace VectorworksMVR virtual VCOMError VCOM_CALLTYPE GetConnectionAt(size_t at, IConnection** outConnection); virtual VCOMError VCOM_CALLTYPE CreateConnection(MvrString own, MvrString other, MvrUUID ToObject, IConnection** addedObj); + virtual VCOMError VCOM_CALLTYPE SetAudioDescriptionFile( MvrString fileName ); + virtual VCOMError VCOM_CALLTYPE GetAudioDescriptionFile( MvrString& outFileName ); // Implementation public: diff --git a/src/Include/IMediaRessourceVectorInterface.h b/src/Include/IMediaRessourceVectorInterface.h index c3360717..406a2c83 100644 --- a/src/Include/IMediaRessourceVectorInterface.h +++ b/src/Include/IMediaRessourceVectorInterface.h @@ -405,6 +405,10 @@ namespace VectorworksMVR virtual VCOMError VCOM_CALLTYPE SetVideoScreenSource(MvrString value, MvrString linkedGeometry, GdtfDefines::ESourceType) = 0; virtual VCOMError VCOM_CALLTYPE GetVideoScreenSource(ISource** outSource) = 0; + // Listening Plane + virtual VCOMError VCOM_CALLTYPE SetAudioDescriptionFile(MvrString value) = 0; + virtual VCOMError VCOM_CALLTYPE GetAudioDescriptionFile(MvrString& outValue) = 0; + // Projector virtual VCOMError VCOM_CALLTYPE SetProjectorSource(MvrString value, MvrString linkedGeometry, GdtfDefines::ESourceType) = 0; virtual VCOMError VCOM_CALLTYPE GetProjectorSource(ISource** outSource) = 0; diff --git a/src/SceneDataExchange.cpp b/src/SceneDataExchange.cpp index 54209f72..03468f2e 100644 --- a/src/SceneDataExchange.cpp +++ b/src/SceneDataExchange.cpp @@ -2806,6 +2806,16 @@ SceneDataListeningPlaneObj::~SceneDataListeningPlaneObj() { } +const TXString& SceneDataListeningPlaneObj::GetAudioDescriptionFile() const +{ + return fAudioDescriptionFile; +} + +void SceneDataListeningPlaneObj::SetAudioDescriptionFile( const TXString& value ) +{ + fAudioDescriptionFile = value; +} + TXString SceneDataListeningPlaneObj::GetNodeName() { return TXString(XML_Val_ListeningPlaneObjectNodeName); @@ -2819,11 +2829,15 @@ ESceneDataObjectType SceneDataListeningPlaneObj::GetObjectType() void SceneDataListeningPlaneObj::OnPrintToFile(IXMLFileNodePtr pNode, SceneDataExchange* exchange) { SceneDataObjWithMatrix::OnPrintToFile( pNode, exchange ); + + pNode->SetNodeAttributeValue("AudioDescriptionFile", fAudioDescriptionFile); } void SceneDataListeningPlaneObj::OnReadFromNode(const IXMLFileNodePtr& pNode, SceneDataExchange* exchange) { SceneDataObjWithMatrix::OnReadFromNode( pNode, exchange ); + + pNode->GetNodeAttributeValue("AudioDescriptionFile", fAudioDescriptionFile); } // ---------------------------------------------------------------------------------------------------------------------------------- diff --git a/src/SceneDataExchange.h b/src/SceneDataExchange.h index 29728ddb..4993215e 100644 --- a/src/SceneDataExchange.h +++ b/src/SceneDataExchange.h @@ -947,7 +947,12 @@ namespace SceneData SceneDataListeningPlaneObj(const SceneDataGUID& guid); virtual ~SceneDataListeningPlaneObj(); + virtual const TXString& GetAudioDescriptionFile() const; + virtual void SetAudioDescriptionFile(const TXString& value); + private: + TXString fAudioDescriptionFile; + virtual TXString GetNodeName(); virtual ESceneDataObjectType GetObjectType(); From 304d951d73ee5971bc46da8d7639034e935ecfa9 Mon Sep 17 00:00:00 2001 From: Alesandro Dragnev Date: Wed, 17 Jun 2026 10:15:11 +0300 Subject: [PATCH 5/7] Updating the windows workflow version --- .github/workflows/artifact.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/artifact.yml b/.github/workflows/artifact.yml index b2bdde4e..8baaa8c1 100644 --- a/.github/workflows/artifact.yml +++ b/.github/workflows/artifact.yml @@ -9,7 +9,7 @@ on: type: choice options: - ubuntu-22.04 - - windows-latest + - windows-2022 - macos-14 jobs: From 76660bf89dbd41e0d196ace73691044ce9332293 Mon Sep 17 00:00:00 2001 From: Alesandro Dragnev Date: Tue, 23 Jun 2026 11:28:46 +0300 Subject: [PATCH 6/7] Adding speaker GDTF support --- src/GDTFManager.cpp | 217 +++++++++++++++ src/GDTFManager.h | 54 ++++ src/Implementation/CGdtfFixture.cpp | 1 + src/Implementation/CGdtfGeometry.cpp | 275 +++++++++++++++++++ src/Implementation/CGdtfGeometry.h | 21 ++ src/Include/GDTFPrefix.h | 1 + src/Include/IMediaRessourceVectorInterface.h | 21 ++ src/Prefix/CommonPrefix.h | 11 + 8 files changed, 601 insertions(+) diff --git a/src/GDTFManager.cpp b/src/GDTFManager.cpp index fbbe30e7..dfdec379 100644 --- a/src/GDTFManager.cpp +++ b/src/GDTFManager.cpp @@ -2220,6 +2220,15 @@ GdtfGeometryPtr GdtfGeometry::AddGeometrySupport(const TXString& name, GdtfModel return geo; } +GdtfGeometryPtr GdtfGeometry::AddGeometrySpeaker(const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma) +{ + GdtfGeometry* geo = new GdtfGeometrySpeaker(name, refToModel, ma, this); + + fInternalGeometries.push_back(geo); + + return geo; +} + GdtfGeometryPtr GdtfGeometry::AddGeometryMagnet(const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma) { GdtfGeometry* geo = new GdtfGeometryMagnet(name, refToModel, ma, this); @@ -2293,6 +2302,7 @@ void GdtfGeometry::OnReadFromNode(const IXMLFileNodePtr& pNode) else if (childNodeName == XML_GDTF_InventoryNodeName) { geometry = new GdtfGeometryInventory(this);} else if (childNodeName == XML_GDTF_StructureNodeName) { geometry = new GdtfGeometryStructure(this);} else if (childNodeName == XML_GDTF_SupportNodeName) { geometry = new GdtfGeometrySupport(this);} + else if (childNodeName == XML_GDTF_SpeakerNodeName) { geometry = new GdtfGeometrySpeaker(this);} else if (childNodeName == XML_GDTF_MagnetNodeName) { geometry = new GdtfGeometryMagnet(this);} else if (childNodeName == XML_GDTF_BreakNodeName) { hasBreak = true; } else if (childNodeName == XML_GDTF_LaserProtocolNodeName) { return; /* Laser Protocols are handled in the Laser OnReadFromNode function */ } @@ -4306,6 +4316,203 @@ TXString GdtfGeometrySupport::GetNodeName() return XML_GDTF_SupportNodeName; } +//------------------------------------------------------------------------------------ +// GdtfGeometrySpeaker +GdtfGeometrySpeaker::GdtfGeometrySpeaker(GdtfGeometry* parent) + :GdtfGeometry(parent) +{ + fFrequencyMin = 0; + fFrequencyMax = 0; + fMaxSPL = 0; + fImpedance = 0; + fSoundAngleRotationMax = 0; + fVerticalCoverageUp = 0; + fVerticalCoverageDown = 0; + fHorizontalCoverageLeft = 0; + fHorizontalCoverageRight= 0; +} + +GdtfGeometrySpeaker::GdtfGeometrySpeaker(const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma, GdtfGeometry* parent) + :GdtfGeometry(name, refToModel, ma, parent) +{ + fFrequencyMin = 0; + fFrequencyMax = 0; + fMaxSPL = 0; + fImpedance = 0; + fSoundAngleRotationMax = 0; + fVerticalCoverageUp = 0; + fVerticalCoverageDown = 0; + fHorizontalCoverageLeft = 0; + fHorizontalCoverageRight= 0; +} + +GdtfGeometrySpeaker::~GdtfGeometrySpeaker() +{ +} + +double GdtfGeometrySpeaker::GetFrequencyMin() const +{ + return fFrequencyMin; +} + +double GdtfGeometrySpeaker::GetFrequencyMax() const +{ + return fFrequencyMax; +} + +double GdtfGeometrySpeaker::GetMaxSPL() const +{ + return fMaxSPL; +} + +double GdtfGeometrySpeaker::GetImpedance() const +{ + return fImpedance; +} + +double GdtfGeometrySpeaker::GetSoundAngleRotationMax() const +{ + return fSoundAngleRotationMax; +} + +double GdtfGeometrySpeaker::GetVerticalCoverageUp() const +{ + return fVerticalCoverageUp; +} + +double GdtfGeometrySpeaker::GetVerticalCoverageDown() const +{ + return fVerticalCoverageDown; +} + +double GdtfGeometrySpeaker::GetHorizontalCoverageLeft() const +{ + return fHorizontalCoverageLeft; +} + +double GdtfGeometrySpeaker::GetHorizontalCoverageRight() const +{ + return fHorizontalCoverageRight; +} + +void GdtfGeometrySpeaker::SetFrequencyMin(double frequencyMin) +{ + fFrequencyMin = frequencyMin; +} + +void GdtfGeometrySpeaker::SetFrequencyMax(double frequencyMax) +{ + fFrequencyMax = frequencyMax; +} + +void GdtfGeometrySpeaker::SetMaxSPL(double maxSPL) +{ + fMaxSPL = maxSPL; +} + +void GdtfGeometrySpeaker::SetImpedance(double impedance) +{ + fImpedance = impedance; +} + +void GdtfGeometrySpeaker::SetSoundAngleRotationMax(double soundAngleRotationMax) +{ + fSoundAngleRotationMax = soundAngleRotationMax; +} + +void GdtfGeometrySpeaker::SetVerticalCoverageUp(double verticalCoverageUp) +{ + fVerticalCoverageUp = verticalCoverageUp; +} + +void GdtfGeometrySpeaker::SetVerticalCoverageDown(double verticalCoverageDown) +{ + fVerticalCoverageDown = verticalCoverageDown; +} + +void GdtfGeometrySpeaker::SetHorizontalCoverageLeft(double horizontalCoverageLeft) +{ + fHorizontalCoverageLeft = horizontalCoverageLeft; +} + +void GdtfGeometrySpeaker::SetHorizontalCoverageRight(double horizontalCoverageRight) +{ + fHorizontalCoverageRight = horizontalCoverageRight; +} + +void GdtfGeometrySpeaker::OnPrintToFile(IXMLFileNodePtr pNode) +{ + //------------------------------------------------------------------------------------ + // Call the parent + GdtfGeometry::OnPrintToFile(pNode); + + pNode->SetNodeAttributeValue(XML_GDTF_SpeakerFrequencyMin, GdtfConverter::ConvertDouble(fFrequencyMin)); + pNode->SetNodeAttributeValue(XML_GDTF_SpeakerFrequencyMax, GdtfConverter::ConvertDouble(fFrequencyMax)); + pNode->SetNodeAttributeValue(XML_GDTF_SpeakerMaxSPL, GdtfConverter::ConvertDouble(fMaxSPL)); + pNode->SetNodeAttributeValue(XML_GDTF_SpeakerImpedance, GdtfConverter::ConvertDouble(fImpedance)); + pNode->SetNodeAttributeValue(XML_GDTF_SpeakerSoundAngleRotationMax, GdtfConverter::ConvertDouble(fSoundAngleRotationMax)); + pNode->SetNodeAttributeValue(XML_GDTF_SpeakerVerticalCoverageUp, GdtfConverter::ConvertDouble(fVerticalCoverageUp)); + pNode->SetNodeAttributeValue(XML_GDTF_SpeakerVerticalCoverageDown, GdtfConverter::ConvertDouble(fVerticalCoverageDown)); + pNode->SetNodeAttributeValue(XML_GDTF_SpeakerHorizontalCoverageLeft, GdtfConverter::ConvertDouble(fHorizontalCoverageLeft)); + pNode->SetNodeAttributeValue(XML_GDTF_SpeakerHorizontalCoverageRight, GdtfConverter::ConvertDouble(fHorizontalCoverageRight)); +} + +void GdtfGeometrySpeaker::OnReadFromNode(const IXMLFileNodePtr& pNode) +{ + //------------------------------------------------------------------------------------ + // Call the parent + GdtfGeometry::OnReadFromNode(pNode); + + TXString frequencyMin; pNode->GetNodeAttributeValue(XML_GDTF_SpeakerFrequencyMin, frequencyMin); GdtfConverter::ConvertDouble(frequencyMin, pNode, fFrequencyMin); + TXString frequencyMax; pNode->GetNodeAttributeValue(XML_GDTF_SpeakerFrequencyMax, frequencyMax); GdtfConverter::ConvertDouble(frequencyMax, pNode, fFrequencyMax); + TXString maxSPL; pNode->GetNodeAttributeValue(XML_GDTF_SpeakerMaxSPL, maxSPL); GdtfConverter::ConvertDouble(maxSPL, pNode, fMaxSPL); + TXString impedance; pNode->GetNodeAttributeValue(XML_GDTF_SpeakerImpedance, impedance); GdtfConverter::ConvertDouble(impedance, pNode, fImpedance); + TXString soundAngleRotationMax; pNode->GetNodeAttributeValue(XML_GDTF_SpeakerSoundAngleRotationMax, soundAngleRotationMax); GdtfConverter::ConvertDouble(soundAngleRotationMax, pNode, fSoundAngleRotationMax); + TXString verticalCoverageUp; pNode->GetNodeAttributeValue(XML_GDTF_SpeakerVerticalCoverageUp, verticalCoverageUp); GdtfConverter::ConvertDouble(verticalCoverageUp, pNode, fVerticalCoverageUp); + TXString verticalCoverageDown; pNode->GetNodeAttributeValue(XML_GDTF_SpeakerVerticalCoverageDown, verticalCoverageDown); GdtfConverter::ConvertDouble(verticalCoverageDown, pNode, fVerticalCoverageDown); + TXString horizontalCoverageLeft; pNode->GetNodeAttributeValue(XML_GDTF_SpeakerHorizontalCoverageLeft, horizontalCoverageLeft); GdtfConverter::ConvertDouble(horizontalCoverageLeft, pNode, fHorizontalCoverageLeft); + TXString horizontalCoverageRight; pNode->GetNodeAttributeValue(XML_GDTF_SpeakerHorizontalCoverageRight, horizontalCoverageRight); GdtfConverter::ConvertDouble(horizontalCoverageRight, pNode, fHorizontalCoverageRight); +} + +void GdtfGeometrySpeaker::OnErrorCheck(const IXMLFileNodePtr& pNode) +{ + //------------------------------------------------------------------------------------ + // Call the parent + GdtfObject::OnErrorCheck(pNode); + + //------------------------------------------------------------------------------------ + // Create needed and optional Attribute Arrays + TXStringArray needed; + TXStringArray optional; + needed.push_back(XML_GDTF_GeometryName); + optional.push_back(XML_GDTF_GeometryModelRef); + needed.push_back(XML_GDTF_GeometryMatrix); + + needed.push_back(XML_GDTF_SpeakerFrequencyMin); + needed.push_back(XML_GDTF_SpeakerFrequencyMax); + needed.push_back(XML_GDTF_SpeakerMaxSPL); + needed.push_back(XML_GDTF_SpeakerImpedance); + needed.push_back(XML_GDTF_SpeakerSoundAngleRotationMax); + needed.push_back(XML_GDTF_SpeakerVerticalCoverageUp); + needed.push_back(XML_GDTF_SpeakerVerticalCoverageDown); + needed.push_back(XML_GDTF_SpeakerHorizontalCoverageLeft); + needed.push_back(XML_GDTF_SpeakerHorizontalCoverageRight); + + //------------------------------------------------------------------------------------ + // Check Attributes for node + GdtfParsingError::CheckNodeAttributes(pNode, needed, optional); +} + +EGdtfObjectType GdtfGeometrySpeaker::GetObjectType() +{ + return EGdtfObjectType::eGdtfGeometrySpeaker; +} + +TXString GdtfGeometrySpeaker::GetNodeName() +{ + return XML_GDTF_SpeakerNodeName; +} + //------------------------------------------------------------------------------------ // GdtfGeometryMagnet GdtfGeometryMagnet::GdtfGeometryMagnet(GdtfGeometry* parent) @@ -9713,6 +9920,7 @@ void GdtfFixture::OnReadFromNode(const IXMLFileNodePtr& pNode) else if (childNodeName == XML_GDTF_InventoryNodeName) { geometry = new GdtfGeometryInventory(nullptr);} else if (childNodeName == XML_GDTF_StructureNodeName) { geometry = new GdtfGeometryStructure(nullptr);} else if (childNodeName == XML_GDTF_SupportNodeName) { geometry = new GdtfGeometrySupport(nullptr);} + else if (childNodeName == XML_GDTF_SpeakerNodeName) { geometry = new GdtfGeometrySpeaker(nullptr);} else if (childNodeName == XML_GDTF_MagnetNodeName) { geometry = new GdtfGeometryMagnet(nullptr);} else { DSTOP((kEveryone,"There is a node that was not expected!")); } @@ -10093,6 +10301,15 @@ GdtfGeometryPtr GdtfFixture::AddGeometrySupport(const TXString& name, GdtfModelP return geo; } +GdtfGeometryPtr GdtfFixture::AddGeometrySpeaker(const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma) +{ + GdtfGeometry* geo = new GdtfGeometrySpeaker(name, refToModel, ma, nullptr); + + fGeometries.push_back(geo); + + return geo; +} + GdtfGeometryPtr GdtfFixture::AddGeometryMagnet(const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma) { GdtfGeometry* geo = new GdtfGeometryMagnet(name, refToModel, ma, nullptr); diff --git a/src/GDTFManager.h b/src/GDTFManager.h index 90535de5..0f77579b 100644 --- a/src/GDTFManager.h +++ b/src/GDTFManager.h @@ -810,6 +810,7 @@ namespace SceneData GdtfGeometry* AddGeometryInventory( const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma); GdtfGeometry* AddGeometryStructure( const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma); GdtfGeometry* AddGeometrySupport( const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma); + GdtfGeometry* AddGeometrySpeaker( const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma); GdtfGeometry* AddGeometryMagnet( const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma); protected: @@ -1329,6 +1330,58 @@ namespace SceneData }; typedef GdtfGeometrySupport* GdtfGeometrySupportPtr; + class GdtfGeometrySpeaker : public GdtfGeometry + { + public: + GdtfGeometrySpeaker(GdtfGeometry* parent); + GdtfGeometrySpeaker(const TXString& name, GdtfModelPtr refToModel,const VWTransformMatrix& ma, GdtfGeometry* parent); + + ~GdtfGeometrySpeaker(); + + private: + double fFrequencyMin; + double fFrequencyMax; + double fMaxSPL; + double fImpedance; + double fSoundAngleRotationMax; + double fVerticalCoverageUp; + double fVerticalCoverageDown; + double fHorizontalCoverageLeft; + double fHorizontalCoverageRight; + + public: + virtual EGdtfObjectType GetObjectType(); + + // Getters + double GetFrequencyMin() const; + double GetFrequencyMax() const; + double GetMaxSPL() const; + double GetImpedance() const; + double GetSoundAngleRotationMax() const; + double GetVerticalCoverageUp() const; + double GetVerticalCoverageDown() const; + double GetHorizontalCoverageLeft() const; + double GetHorizontalCoverageRight() const; + + // Setters + void SetFrequencyMin(double frequencyMin); + void SetFrequencyMax(double frequencyMax); + void SetMaxSPL(double maxSPL); + void SetImpedance(double impedance); + void SetSoundAngleRotationMax(double soundAngleRotationMax); + void SetVerticalCoverageUp(double verticalCoverageUp); + void SetVerticalCoverageDown(double verticalCoverageDown); + void SetHorizontalCoverageLeft(double horizontalCoverageLeft); + void SetHorizontalCoverageRight(double horizontalCoverageRight); + + protected: + virtual TXString GetNodeName(); + virtual void OnPrintToFile(IXMLFileNodePtr pNode); + virtual void OnReadFromNode(const IXMLFileNodePtr& pNode); + virtual void OnErrorCheck(const IXMLFileNodePtr& pNode); + }; + typedef GdtfGeometrySpeaker* GdtfGeometrySpeakerPtr; + class GdtfGeometryMagnet : public GdtfGeometry { public: @@ -2926,6 +2979,7 @@ namespace SceneData GdtfGeometryPtr AddGeometryWiringObject( const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma); GdtfGeometryPtr AddGeometryInventory( const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma); GdtfGeometryPtr AddGeometryStructure( const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma); + GdtfGeometryPtr AddGeometrySpeaker( const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma); GdtfGeometryPtr AddGeometrySupport( const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma); GdtfGeometryPtr AddGeometryMagnet( const TXString& name, GdtfModelPtr refToModel, const VWTransformMatrix& ma); diff --git a/src/Implementation/CGdtfFixture.cpp b/src/Implementation/CGdtfFixture.cpp index e6a6e92b..ae20eab2 100755 --- a/src/Implementation/CGdtfFixture.cpp +++ b/src/Implementation/CGdtfFixture.cpp @@ -1040,6 +1040,7 @@ VectorworksMVR::VCOMError VectorworksMVR::CGdtfFixtureImpl::CreateGeometry(EGdtf case eGdtfGeometryInventory: gdtfGeometry = fFixtureObject->AddGeometryInventory( vwName, scModel, ma); break; case eGdtfGeometryStructure: gdtfGeometry = fFixtureObject->AddGeometryStructure( vwName, scModel, ma); break; case eGdtfGeometrySupport: gdtfGeometry = fFixtureObject->AddGeometrySupport( vwName, scModel, ma); break; + case eGdtfGeometrySpeaker: gdtfGeometry = fFixtureObject->AddGeometrySpeaker( vwName, scModel, ma); break; case eGdtfGeometryMagnet: gdtfGeometry = fFixtureObject->AddGeometryMagnet( vwName, scModel, ma); break; case eGdtfGeometry: gdtfGeometry = fFixtureObject->AddGeometry( vwName, scModel, ma); break; diff --git a/src/Implementation/CGdtfGeometry.cpp b/src/Implementation/CGdtfGeometry.cpp index 75bac241..cb805cd3 100644 --- a/src/Implementation/CGdtfGeometry.cpp +++ b/src/Implementation/CGdtfGeometry.cpp @@ -245,6 +245,7 @@ VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::CreateGeometry(EGdt case eGdtfGeometryInventory: gdtfGeometry = fGeometry->AddGeometryInventory( vwName, scModel, ma); break; case eGdtfGeometryStructure: gdtfGeometry = fGeometry->AddGeometryStructure( vwName, scModel, ma); break; case eGdtfGeometrySupport: gdtfGeometry = fGeometry->AddGeometrySupport( vwName, scModel, ma); break; + case eGdtfGeometrySpeaker: gdtfGeometry = fGeometry->AddGeometrySpeaker( vwName, scModel, ma); break; case eGdtfGeometryMagnet: gdtfGeometry = fGeometry->AddGeometryMagnet( vwName, scModel, ma); break; case eGdtfGeometry: gdtfGeometry = fGeometry->AddGeometry( vwName, scModel, ma); break; @@ -2942,6 +2943,279 @@ VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::SetResistanceZZ(dou return kVCOMError_NoError; } +//--------------------------------------------------------------------------- +// Speaker + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::GetFrequencyMin(double& frequencyMin) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if (fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + frequencyMin = speaker->GetFrequencyMin(); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::GetFrequencyMax(double& frequencyMax) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if (fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + frequencyMax = speaker->GetFrequencyMax(); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::GetMaxSPL(double& maxSPL) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if (fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + maxSPL = speaker->GetMaxSPL(); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::GetImpedance(double& impedance) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if (fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + impedance = speaker->GetImpedance(); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::GetSoundAngleRotationMax(double& soundAngleRotationMax) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if (fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + soundAngleRotationMax = speaker->GetSoundAngleRotationMax(); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::GetVerticalCoverageUp(double& verticalCoverageUp) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if (fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + verticalCoverageUp = speaker->GetVerticalCoverageUp(); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::GetVerticalCoverageDown(double& verticalCoverageDown) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if (fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + verticalCoverageDown = speaker->GetVerticalCoverageDown(); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::GetHorizontalCoverageLeft(double& horizontalCoverageLeft) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if (fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + horizontalCoverageLeft = speaker->GetHorizontalCoverageLeft(); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::GetHorizontalCoverageRight(double& horizontalCoverageRight) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if (fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + horizontalCoverageRight = speaker->GetHorizontalCoverageRight(); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::SetFrequencyMin(double frequencyMin) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if(fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + speaker->SetFrequencyMin(frequencyMin); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::SetFrequencyMax(double frequencyMax) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if(fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + speaker->SetFrequencyMax(frequencyMax); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::SetMaxSPL(double maxSPL) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if(fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + speaker->SetMaxSPL(maxSPL); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::SetImpedance(double impedance) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if(fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + speaker->SetImpedance(impedance); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::SetSoundAngleRotationMax(double soundAngleRotationMax) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if(fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + speaker->SetSoundAngleRotationMax(soundAngleRotationMax); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::SetVerticalCoverageUp(double verticalCoverageUp) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if(fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + speaker->SetVerticalCoverageUp(verticalCoverageUp); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::SetVerticalCoverageDown(double verticalCoverageDown) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if(fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + speaker->SetVerticalCoverageDown(verticalCoverageDown); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::SetHorizontalCoverageLeft(double horizontalCoverageLeft) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if(fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + speaker->SetHorizontalCoverageLeft(horizontalCoverageLeft); + return kVCOMError_NoError; +} + +VectorworksMVR::VCOMError VectorworksMVR::CGdtfGeometryImpl::SetHorizontalCoverageRight(double horizontalCoverageRight) +{ + // Check Pointer + if(!fGeometry) return kVCOMError_NotInitialized; + + // Check if it is the right type + if(fGeometryType != EGdtfObjectType::eGdtfGeometrySpeaker) return kVCOMError_WrongGeometryType; + + SceneData::GdtfGeometrySpeakerPtr speaker = static_cast(fGeometry); + if(!speaker) {return kVCOMError_Failed;} + + speaker->SetHorizontalCoverageRight(horizontalCoverageRight); + return kVCOMError_NoError; +} + //--------------------------------------------------------------------------- void VectorworksMVR::CGdtfGeometryImpl::SetPointer(SceneData::GdtfGeometry* geometry) { @@ -2965,6 +3239,7 @@ void VectorworksMVR::CGdtfGeometryImpl::SetPointer(SceneData::GdtfGeometry* geom fGeometryType == EGdtfObjectType::eGdtfGeometryInventory || fGeometryType == EGdtfObjectType::eGdtfGeometryStructure || fGeometryType == EGdtfObjectType::eGdtfGeometrySupport || + fGeometryType == EGdtfObjectType::eGdtfGeometrySpeaker || fGeometryType == EGdtfObjectType::eGdtfGeometryMagnet); } diff --git a/src/Implementation/CGdtfGeometry.h b/src/Implementation/CGdtfGeometry.h index 08c754e0..adf35bc7 100644 --- a/src/Implementation/CGdtfGeometry.h +++ b/src/Implementation/CGdtfGeometry.h @@ -198,6 +198,27 @@ namespace VectorworksMVR virtual VCOMError VCOM_CALLTYPE SetResistanceYY(double resistanceYY); virtual VCOMError VCOM_CALLTYPE SetResistanceZZ(double resistanceZZ); + // Speaker + virtual VCOMError VCOM_CALLTYPE GetFrequencyMin(double& frequencyMin); + virtual VCOMError VCOM_CALLTYPE GetFrequencyMax(double& frequencyMax); + virtual VCOMError VCOM_CALLTYPE GetMaxSPL(double& maxSPL); + virtual VCOMError VCOM_CALLTYPE GetImpedance(double& impedance); + virtual VCOMError VCOM_CALLTYPE GetSoundAngleRotationMax(double& soundAngleRotationMax); + virtual VCOMError VCOM_CALLTYPE GetVerticalCoverageUp(double& verticalCoverageUp); + virtual VCOMError VCOM_CALLTYPE GetVerticalCoverageDown(double& verticalCoverageDown); + virtual VCOMError VCOM_CALLTYPE GetHorizontalCoverageLeft(double& horizontalCoverageLeft); + virtual VCOMError VCOM_CALLTYPE GetHorizontalCoverageRight(double& horizontalCoverageRight); + + virtual VCOMError VCOM_CALLTYPE SetFrequencyMin(double frequencyMin); + virtual VCOMError VCOM_CALLTYPE SetFrequencyMax(double frequencyMax); + virtual VCOMError VCOM_CALLTYPE SetMaxSPL(double maxSPL); + virtual VCOMError VCOM_CALLTYPE SetImpedance(double impedance); + virtual VCOMError VCOM_CALLTYPE SetSoundAngleRotationMax(double soundAngleRotationMax); + virtual VCOMError VCOM_CALLTYPE SetVerticalCoverageUp(double verticalCoverageUp); + virtual VCOMError VCOM_CALLTYPE SetVerticalCoverageDown(double verticalCoverageDown); + virtual VCOMError VCOM_CALLTYPE SetHorizontalCoverageLeft(double horizontalCoverageLeft); + virtual VCOMError VCOM_CALLTYPE SetHorizontalCoverageRight(double horizontalCoverageRight); + virtual VCOMError VCOM_CALLTYPE BindToObject(void* objAddr); virtual void* VCOM_CALLTYPE GetBoundObject(); diff --git a/src/Include/GDTFPrefix.h b/src/Include/GDTFPrefix.h index 78192812..b0cd2d22 100644 --- a/src/Include/GDTFPrefix.h +++ b/src/Include/GDTFPrefix.h @@ -125,6 +125,7 @@ namespace VectorworksMVR eGdtfSubPhysicalUnit = 90, eGdtfGamut = 91, eGdtfDmxSubChannelSet = 92, + eGdtfGeometrySpeaker = 101, }; enum class EGdtfParsingError : Sint32 diff --git a/src/Include/IMediaRessourceVectorInterface.h b/src/Include/IMediaRessourceVectorInterface.h index 406a2c83..bad8fa8e 100644 --- a/src/Include/IMediaRessourceVectorInterface.h +++ b/src/Include/IMediaRessourceVectorInterface.h @@ -1000,6 +1000,27 @@ namespace VectorworksMVR virtual VCOMError VCOM_CALLTYPE SetResistanceXX(double resistanceXX) = 0; virtual VCOMError VCOM_CALLTYPE SetResistanceYY(double resistanceYY) = 0; virtual VCOMError VCOM_CALLTYPE SetResistanceZZ(double resistanceZZ) = 0; + + // Speaker + virtual VCOMError VCOM_CALLTYPE GetFrequencyMin(double& frequencyMin) = 0; + virtual VCOMError VCOM_CALLTYPE GetFrequencyMax(double& frequencyMax) = 0; + virtual VCOMError VCOM_CALLTYPE GetMaxSPL(double& maxSPL) = 0; + virtual VCOMError VCOM_CALLTYPE GetImpedance(double& impedance) = 0; + virtual VCOMError VCOM_CALLTYPE GetSoundAngleRotationMax(double& soundAngleRotationMax) = 0; + virtual VCOMError VCOM_CALLTYPE GetVerticalCoverageUp(double& verticalCoverageUp) = 0; + virtual VCOMError VCOM_CALLTYPE GetVerticalCoverageDown(double& verticalCoverageDown) = 0; + virtual VCOMError VCOM_CALLTYPE GetHorizontalCoverageLeft(double& horizontalCoverageLeft) = 0; + virtual VCOMError VCOM_CALLTYPE GetHorizontalCoverageRight(double& horizontalCoverageRight) = 0; + + virtual VCOMError VCOM_CALLTYPE SetFrequencyMin(double frequencyMin) = 0; + virtual VCOMError VCOM_CALLTYPE SetFrequencyMax(double frequencyMax) = 0; + virtual VCOMError VCOM_CALLTYPE SetMaxSPL(double maxSPL) = 0; + virtual VCOMError VCOM_CALLTYPE SetImpedance(double impedance) = 0; + virtual VCOMError VCOM_CALLTYPE SetSoundAngleRotationMax(double soundAngleRotationMax) = 0; + virtual VCOMError VCOM_CALLTYPE SetVerticalCoverageUp(double verticalCoverageUp) = 0; + virtual VCOMError VCOM_CALLTYPE SetVerticalCoverageDown(double verticalCoverageDown) = 0; + virtual VCOMError VCOM_CALLTYPE SetHorizontalCoverageLeft(double horizontalCoverageLeft) = 0; + virtual VCOMError VCOM_CALLTYPE SetHorizontalCoverageRight(double horizontalCoverageRight) = 0; }; typedef VCOMPtr IGdtfGeometryPtr; diff --git a/src/Prefix/CommonPrefix.h b/src/Prefix/CommonPrefix.h index 21bf3bd2..aee38dd0 100644 --- a/src/Prefix/CommonPrefix.h +++ b/src/Prefix/CommonPrefix.h @@ -525,6 +525,17 @@ const Sint32 kGDTF_CurrentMinorVersion = 2; #define XML_GDTF_SupportResistanceYY "ResistanceYY" #define XML_GDTF_SupportResistanceZZ "ResistanceZZ" +#define XML_GDTF_SpeakerNodeName "Speaker" +#define XML_GDTF_SpeakerFrequencyMin "FrequencyMin" +#define XML_GDTF_SpeakerFrequencyMax "FrequencyMax" +#define XML_GDTF_SpeakerMaxSPL "MaxSPL" +#define XML_GDTF_SpeakerImpedance "Impedance" +#define XML_GDTF_SpeakerSoundAngleRotationMax "SoundAngleRotationMax" +#define XML_GDTF_SpeakerVerticalCoverageUp "VerticalCoverageUp" +#define XML_GDTF_SpeakerVerticalCoverageDown "VerticalCoverageDown" +#define XML_GDTF_SpeakerHorizontalCoverageLeft "HorizontalCoverageLeft" +#define XML_GDTF_SpeakerHorizontalCoverageRight "HorizontalCoverageRight" + #define XML_GDTF_MagnetNodeName "Magnet" #define XML_GDTF_LampNodeName "Beam" From 985dfe2624f90892c848abf223145f1f5bc7f2f8 Mon Sep 17 00:00:00 2001 From: Alesandro Dragnev Date: Tue, 23 Jun 2026 13:33:35 +0300 Subject: [PATCH 7/7] Adding MVR Support for Speaker --- .../CMediaRessourceVectorImpl.cpp | 67 +++++++++++++++++++ .../CMediaRessourceVectorImpl.h | 3 +- src/Implementation/CSceneObjImpl.cpp | 26 ++++--- src/Include/IMediaRessourceVectorInterface.h | 4 +- src/Prefix/CommonPrefix.h | 2 + src/SceneDataExchange.cpp | 54 +++++++++++++++ src/SceneDataExchange.h | 26 ++++++- src/Utility.cpp | 3 +- 8 files changed, 169 insertions(+), 16 deletions(-) diff --git a/src/Implementation/CMediaRessourceVectorImpl.cpp b/src/Implementation/CMediaRessourceVectorImpl.cpp index 0502b8c7..c4f33a87 100644 --- a/src/Implementation/CMediaRessourceVectorImpl.cpp +++ b/src/Implementation/CMediaRessourceVectorImpl.cpp @@ -1043,6 +1043,73 @@ VectorworksMVR::VCOMError VectorworksMVR::CMediaRessourceVectorImpl::CreateListe return kVCOMError_NoError; } +VectorworksMVR::VCOMError VectorworksMVR::CMediaRessourceVectorImpl::CreateSpeaker(const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outSpeaker) +{ + //--------------------------------------------------------------------------- + // Read Container + CSceneObjImpl* pContainer = static_cast(addToContainer); + + ASSERTN(kEveryone, pContainer != nullptr); + if ( ! pContainer) { return kVCOMError_NoValidContainerObj; } + + + SceneData::SceneDataObjWithMatrixPtr obj = nullptr; + ESceneObjType type = ESceneObjType::Layer; + pContainer->GetPointer(obj, type); + + if( ! VectorworksMVR::MvrUtil::isContainerType(type)) { return kVCOMError_NoValidContainerObj; } + + SceneData::SceneDataGroupObjPtr group = static_cast(obj); + + ASSERTN(kEveryone, group != nullptr); + if ( ! group) { return kVCOMError_NoValidContainerObj; } + + //--------------------------------------------------------------------------- + // Create the obj + VWFC::Tools::VWUUID uuid (guid.a,guid.b,guid.c,guid.d); + TXString nameStr ( name ); + + VWTransformMatrix ma; + GdtfUtil::ConvertMatrix(offset, ma); + + SceneData::SceneDataSpeakerObjPtr ptr = fExchangeObj.CreateSpeaker(uuid, ma, nameStr, group); + + //--------------------------------------------------------------------------- + // Initialize Object + CSceneObjImpl* pSpeaker = nullptr; + + // Query Interface + if (VCOM_SUCCEEDED(VWQueryInterface(IID_SceneObject, (IVWUnknown**) & pSpeaker))) + { + // Check Casting + CSceneObjImpl* pResultInterface = static_cast(pSpeaker); + if (pResultInterface) + { + pResultInterface->SetPointer(ptr, GetExchangeObj()); + } + else + { + pResultInterface->Release(); + pResultInterface = nullptr; + return kVCOMError_NoInterface; + } + } + + //--------------------------------------------------------------------------- + // Check Incoming Object + if (*outSpeaker) + { + (*outSpeaker)->Release(); + *outSpeaker = NULL; + } + + //--------------------------------------------------------------------------- + // Set Out Value + *outSpeaker = pSpeaker; + + return kVCOMError_NoError; +} + VectorworksMVR::VCOMError VectorworksMVR::CMediaRessourceVectorImpl::Close() { diff --git a/src/Implementation/CMediaRessourceVectorImpl.h b/src/Implementation/CMediaRessourceVectorImpl.h index 5bc0772b..b667d1b6 100644 --- a/src/Implementation/CMediaRessourceVectorImpl.h +++ b/src/Implementation/CMediaRessourceVectorImpl.h @@ -66,7 +66,8 @@ namespace VectorworksMVR virtual VCOMError VCOM_CALLTYPE CreateVideoScreen( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outVideoScreen); virtual VCOMError VCOM_CALLTYPE CreateProjector( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outProjector); virtual VCOMError VCOM_CALLTYPE CreateListeningPlane( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outListeningPlane); - + virtual VCOMError VCOM_CALLTYPE CreateSpeaker( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outSpeaker); + // Add the end call to write the file to disk virtual VCOMError VCOM_CALLTYPE Close(); diff --git a/src/Implementation/CSceneObjImpl.cpp b/src/Implementation/CSceneObjImpl.cpp index cabbab34..4913ad3f 100644 --- a/src/Implementation/CSceneObjImpl.cpp +++ b/src/Implementation/CSceneObjImpl.cpp @@ -1996,11 +1996,13 @@ VectorworksMVR::VCOMError VectorworksMVR::CSceneObjImpl::SetAudioDescriptionFile ASSERTN(kEveryone,fType == ESceneObjType::ListeningPlane); if( fType != ESceneObjType::ListeningPlane) return kVCOMError_Failed; - // Try to cast - SceneData::SceneDataListeningPlaneObjPtr listeningPlane = static_cast(fPtr); - if( ! listeningPlane) return kVCOMError_Failed; + if (fType == ESceneObjType::ListeningPlane) + { + SceneData::SceneDataListeningPlaneObjPtr listeningPlane = static_cast(fPtr); + if( ! listeningPlane) return kVCOMError_Failed; + listeningPlane->SetAudioDescriptionFile(fileName); + } - listeningPlane->SetAudioDescriptionFile(fileName); return kVCOMError_NoError; } @@ -2012,14 +2014,15 @@ VectorworksMVR::VCOMError VectorworksMVR::CSceneObjImpl::GetAudioDescriptionFile if ( !fPtr ) return kVCOMError_NotInitialized; // Check the type is right - ASSERTN( kEveryone, fType == ESceneObjType::ListeningPlane ); + ASSERTN( kEveryone, fType == ESceneObjType::ListeningPlane); if ( fType != ESceneObjType::ListeningPlane ) return kVCOMError_Failed; - // Try to cast - SceneData::SceneDataListeningPlaneObjPtr listeningPlane = static_cast( fPtr ); - if ( !listeningPlane ) return kVCOMError_Failed; - - outFileName = listeningPlane->GetAudioDescriptionFile(); + if (fType == ESceneObjType::ListeningPlane) + { + SceneData::SceneDataListeningPlaneObjPtr listeningPlane = static_cast( fPtr ); + if ( !listeningPlane ) return kVCOMError_Failed; + outFileName = listeningPlane->GetAudioDescriptionFile(); + } return kVCOMError_NoError; } @@ -2202,7 +2205,8 @@ void VectorworksMVR::CSceneObjImpl::SetPointer(SceneData::SceneDataObjWithMatrix case SceneData::eVideoScreen: fType = ESceneObjType::VideoScreen; break; case SceneData::eProjector: fType = ESceneObjType::Projector; break; case SceneData::eListeningPlane: fType = ESceneObjType::ListeningPlane; break; - + case SceneData::eSpeaker: fType = ESceneObjType::Speaker; break; + default: DSTOP((kEveryone, "Unexpected input!")); break; diff --git a/src/Include/IMediaRessourceVectorInterface.h b/src/Include/IMediaRessourceVectorInterface.h index bad8fa8e..e14bb6bb 100644 --- a/src/Include/IMediaRessourceVectorInterface.h +++ b/src/Include/IMediaRessourceVectorInterface.h @@ -327,7 +327,8 @@ namespace VectorworksMVR Fixture, Projector, Support, - ListeningPlane + ListeningPlane, + Speaker }; class DYNAMIC_ATTRIBUTE ISceneObj : public IVWUnknown @@ -466,6 +467,7 @@ namespace VectorworksMVR virtual VCOMError VCOM_CALLTYPE CreateSupport( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outSupport) = 0; virtual VCOMError VCOM_CALLTYPE CreateProjector( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outProjector) = 0; virtual VCOMError VCOM_CALLTYPE CreateListeningPlane( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outListeningPlane) = 0; + virtual VCOMError VCOM_CALLTYPE CreateSpeaker( const MvrUUID& guid, const STransformMatrix& offset, MvrString name, ISceneObj* addToContainer, ISceneObj** outSpeaker) = 0; // Add the end call to write the file to disk virtual VCOMError VCOM_CALLTYPE Close() = 0; diff --git a/src/Prefix/CommonPrefix.h b/src/Prefix/CommonPrefix.h index aee38dd0..0520389c 100644 --- a/src/Prefix/CommonPrefix.h +++ b/src/Prefix/CommonPrefix.h @@ -247,6 +247,8 @@ #define XML_Val_ListeningPlaneObjectNodeName "ListeningPlane" +#define XML_Val_SpeakerObjectNodeName "Speaker" + #define XML_Val_SymbolObjectNodeName "Symbol" #define XML_Val_GuidSymdefAttrName "symdef" diff --git a/src/SceneDataExchange.cpp b/src/SceneDataExchange.cpp index 03468f2e..adb174ed 100644 --- a/src/SceneDataExchange.cpp +++ b/src/SceneDataExchange.cpp @@ -2840,6 +2840,36 @@ void SceneDataListeningPlaneObj::OnReadFromNode(const IXMLFileNodePtr& pNode, Sc pNode->GetNodeAttributeValue("AudioDescriptionFile", fAudioDescriptionFile); } +// ---------------------------------------------------------------------------------------------------------------------------------- +// SceneDataSpeakerObj +SceneDataSpeakerObj::SceneDataSpeakerObj(const SceneDataGUID& guid) :SceneDataGDTFSpecObj(guid) +{ +} + +SceneDataSpeakerObj::~SceneDataSpeakerObj() +{ +} + +TXString SceneDataSpeakerObj::GetNodeName() +{ + return TXString(XML_Val_SpeakerObjectNodeName); +} + +ESceneDataObjectType SceneDataSpeakerObj::GetObjectType() +{ + return ESceneDataObjectType::eSpeaker; +} + +void SceneDataSpeakerObj::OnPrintToFile(IXMLFileNodePtr pNode, SceneDataExchange* exchange) +{ + SceneDataGDTFSpecObj::OnPrintToFile( pNode, exchange ); +} + +void SceneDataSpeakerObj::OnReadFromNode(const IXMLFileNodePtr& pNode, SceneDataExchange* exchange) +{ + SceneDataGDTFSpecObj::OnReadFromNode( pNode, exchange ); +} + // ---------------------------------------------------------------------------------------------------------------------------------- // SceneDataSymbolObj SceneDataSymbolObj::SceneDataSymbolObj(const SceneDataGUID& guid) : SceneDataGeoInstanceObj(guid, true /*Is SymbolDef*/) @@ -3510,6 +3540,29 @@ SceneDataListeningPlaneObjPtr SceneDataExchange::ReadListeningPlane(const SceneD return newListeningPlaneObj; } +SceneDataSpeakerObjPtr SceneDataExchange::CreateSpeaker(const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer) +{ + SceneDataSpeakerObjPtr newSpeakerObj = new SceneDataSpeakerObj(guid); + addToContainer->AddObject(newSpeakerObj); + + newSpeakerObj->setName(name); + newSpeakerObj->SetTransformMatrix(offset); + + return newSpeakerObj; +} + +SceneDataSpeakerObjPtr SceneDataExchange::ReadSpeaker(const SceneDataGUID& guid,const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer) +{ + if ( CheckAbort() ) return nullptr; + + SceneDataSpeakerObjPtr newSpeakerObj = new SceneDataSpeakerObj(guid); + addToContainer->AddObject(newSpeakerObj); + + newSpeakerObj->ReadFromNode(node, this); + + return newSpeakerObj; +} + SceneDataSymbolObjPtr SceneDataExchange::CreateSymbol(const SceneDataGUID& guid, const VWTransformMatrix& offset, SceneDataSymDefObjPtr symDef) { SceneDataSymbolObjPtr newSymbolObj = new SceneDataSymbolObj(guid); @@ -4141,6 +4194,7 @@ void SceneDataExchange::ReadChildObjs(const IXMLFileNodePtr& node, SceneDataGrou else if ( nodeName == XML_Val_SupportObjectNodeName) { obj = ReadSupport( SceneDataGUID(groupUuid), objNode, addToContainer); } else if ( nodeName == XML_Val_ProjectorObjectNodeName) { obj = ReadProjector( SceneDataGUID(groupUuid), objNode, addToContainer); } else if ( nodeName == XML_Val_ListeningPlaneObjectNodeName ) { obj = ReadListeningPlane( SceneDataGUID(groupUuid), objNode, addToContainer); } + else if ( nodeName == XML_Val_SpeakerObjectNodeName ) { obj = ReadSpeaker( SceneDataGUID(groupUuid), objNode, addToContainer); } else if ( nodeName == XML_Val_GroupNodeName) { obj = ProcessGroup(objNode, addToContainer); } auto grp = dynamic_cast(obj); diff --git a/src/SceneDataExchange.h b/src/SceneDataExchange.h index 4993215e..7c625cd3 100644 --- a/src/SceneDataExchange.h +++ b/src/SceneDataExchange.h @@ -48,6 +48,7 @@ namespace SceneData eProjector = 8, eSupport = 9, eListeningPlane = 10, + eSpeaker = 11, eSymDef = -1, eProviderObj = -2, ePosition = -3, @@ -962,6 +963,25 @@ namespace SceneData }; typedef SceneDataListeningPlaneObj* SceneDataListeningPlaneObjPtr; + // ---------------------------------------------------------------------------------------------------------------------------------- + // SceneDataSpeakerObj + class SceneDataSpeakerObj : public SceneDataGDTFSpecObj + { + + public: + SceneDataSpeakerObj(const SceneDataGUID& guid); + virtual ~SceneDataSpeakerObj(); + + private: + virtual TXString GetNodeName(); + virtual ESceneDataObjectType GetObjectType(); + + virtual void OnPrintToFile(IXMLFileNodePtr pNode, SceneDataExchange* exchange); + virtual void OnReadFromNode(const IXMLFileNodePtr& pNode, SceneDataExchange* exchange); + + }; + typedef SceneDataSpeakerObj* SceneDataSpeakerObjPtr; + // ---------------------------------------------------------------------------------------------------------------------------------- // SceneDataSymbolObj class SceneDataSymbolObj : public SceneDataGeoInstanceObj @@ -1093,7 +1113,8 @@ namespace SceneData SceneDataVideoScreenObjPtr CreateVideoScreen( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); SceneDataProjectorObjPtr CreateProjector( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); SceneDataListeningPlaneObjPtr CreateListeningPlane( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); - + SceneDataSpeakerObjPtr CreateSpeaker( const SceneDataGUID& guid, const VWTransformMatrix& offset, const TXString& name, SceneDataGroupObjPtr addToContainer); + // --------------------------------------------------------------------------------------------------------------------- // Read calls private: @@ -1114,7 +1135,8 @@ namespace SceneData SceneDataVideoScreenObjPtr ReadVideoScreen( const SceneDataGUID& guid, const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); SceneDataProjectorObjPtr ReadProjector( const SceneDataGUID& guid, const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer); SceneDataListeningPlaneObjPtr ReadListeningPlane( const SceneDataGUID& guid, const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer ); - + SceneDataSpeakerObjPtr ReadSpeaker( const SceneDataGUID& guid, const IXMLFileNodePtr& node, SceneDataGroupObjPtr addToContainer ); + // --------------------------------------------------------------------------------------------------------------------- // Write calls public: diff --git a/src/Utility.cpp b/src/Utility.cpp index ace1742c..bf618f02 100644 --- a/src/Utility.cpp +++ b/src/Utility.cpp @@ -21,7 +21,8 @@ bool MvrUtil::isContainerType(ESceneObjType typ) || typ == ESceneObjType::SceneObj || typ == ESceneObjType::Truss || typ == ESceneObjType::VideoScreen - || typ == ESceneObjType::Support); + || typ == ESceneObjType::Support + || typ == ESceneObjType::Speaker); ASSERTN(kEveryone, res);