From d77cf0d69fc822a562850b8ff033f174c7cc9b62 Mon Sep 17 00:00:00 2001 From: Linnea May Date: Mon, 21 Nov 2022 16:17:21 -0800 Subject: [PATCH 1/3] start hello model --- ...LSamplesGallery (Package) - Backup.wapproj | 138 ------------------ .../WinMLSamplesGallery (Package).wapproj | 2 +- .../WinMLSamplesGallery.csproj | 2 +- .../WinMLSamplesGalleryNative.Interop.csproj | 4 +- .../SegmentModel.cpp | 17 +++ .../WinMLSamplesGalleryNative/SegmentModel.h | 9 ++ .../WinMLSamplesGalleryNative.vcxproj | 16 +- .../WinMLSamplesGalleryNative/packages.config | 5 +- 8 files changed, 41 insertions(+), 152 deletions(-) delete mode 100644 Samples/WinMLSamplesGallery/WinMLSamplesGallery (Package)/WinMLSamplesGallery (Package) - Backup.wapproj diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGallery (Package)/WinMLSamplesGallery (Package) - Backup.wapproj b/Samples/WinMLSamplesGallery/WinMLSamplesGallery (Package)/WinMLSamplesGallery (Package) - Backup.wapproj deleted file mode 100644 index a89ede6c..00000000 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGallery (Package)/WinMLSamplesGallery (Package) - Backup.wapproj +++ /dev/null @@ -1,138 +0,0 @@ - - - - 15.0 - - - - Debug - x86 - - - Release - x86 - - - Debug - x64 - - - Release - x64 - - - Debug - arm64 - - - Release - arm64 - - - - $(MSBuildExtensionsPath)\Microsoft\DesktopBridge\ - WinMLSamplesGallery\ - - - - dea7791f-55cf-4ed5-bc99-3870997b1242 - 10.0.19041.0 - True - net5.0-windows$(TargetPlatformVersion);$(AssetTargetFallback) - 10.0.17763.0 - en-US - False - ..\WinMLSamplesGallery\WinMLSamplesGallery.csproj - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - - Designer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - Properties\PublishProfiles\win10-$(Platform).pubxml - - - - - - - - - - - \ No newline at end of file diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGallery (Package)/WinMLSamplesGallery (Package).wapproj b/Samples/WinMLSamplesGallery/WinMLSamplesGallery (Package)/WinMLSamplesGallery (Package).wapproj index 9ba44356..75930b15 100644 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGallery (Package)/WinMLSamplesGallery (Package).wapproj +++ b/Samples/WinMLSamplesGallery/WinMLSamplesGallery (Package)/WinMLSamplesGallery (Package).wapproj @@ -141,7 +141,7 @@ - + \ No newline at end of file diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGallery/WinMLSamplesGallery.csproj b/Samples/WinMLSamplesGallery/WinMLSamplesGallery/WinMLSamplesGallery.csproj index 5f4749f0..a5aebd7a 100644 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGallery/WinMLSamplesGallery.csproj +++ b/Samples/WinMLSamplesGallery/WinMLSamplesGallery/WinMLSamplesGallery.csproj @@ -96,7 +96,7 @@ - + diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative.Interop/WinMLSamplesGalleryNative.Interop.csproj b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative.Interop/WinMLSamplesGalleryNative.Interop.csproj index 1893f7ca..dd70dab9 100644 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative.Interop/WinMLSamplesGalleryNative.Interop.csproj +++ b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative.Interop/WinMLSamplesGalleryNative.Interop.csproj @@ -9,7 +9,7 @@ - + @@ -20,7 +20,7 @@ - + diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.cpp b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.cpp index e5aa3754..85da2ce6 100644 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.cpp +++ b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.cpp @@ -40,6 +40,7 @@ enum OnnxDataType : long { const int32_t opset = 12; + /**** Style transfer model ****/ void StyleTransfer::InitializeSession(int w, int h) { @@ -78,6 +79,22 @@ LearningModel StyleTransfer::GetModel() return LearningModel::LoadFromFilePath(modelPath.c_str()); } +void WindowsHello::InitializeSession(int w, int h) { + SetImageSize(w, h); + + // Preprocessing: grayscale model + + m_session = CreateLearningModelSession(GetModel()); + m_binding = LearningModelBinding(m_session); + +} + +LearningModel WindowsHello::GetModel() { + auto modelPath = std::filesystem::path(m_modelBasePath.c_str()); + modelPath.append("retina_rgb.onnx"); + return LearningModel::LoadFromFilePath(modelPath.c_str()); +} + void BackgroundBlur::InitializeSession(int w, int h) { w /= m_scale; h /= m_scale; diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.h b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.h index d74fa7d0..ca72cc89 100644 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.h +++ b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.h @@ -117,6 +117,15 @@ class StyleTransfer : public StreamModelBase LearningModel GetModel(); }; +class WindowsHello : public StreamModelBase { +public: + WindowsHello() : StreamModelBase() {}; + void InitializeSession(int w, int h); + void Run(IDirect3DSurface src, IDirect3DSurface dest); +private: + LearningModel GetModel(); + +}; class BackgroundBlur : public StreamModelBase { diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/WinMLSamplesGalleryNative.vcxproj b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/WinMLSamplesGalleryNative.vcxproj index a2645499..c6ca94b4 100644 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/WinMLSamplesGalleryNative.vcxproj +++ b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/WinMLSamplesGalleryNative.vcxproj @@ -1,7 +1,7 @@ - - + + @@ -254,26 +254,26 @@ - - + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - + + + + diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/packages.config b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/packages.config index 68a7bb27..7a583312 100644 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/packages.config +++ b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/packages.config @@ -1,8 +1,9 @@  - - + + + \ No newline at end of file From 84ccefdd37a34a426bcef33783dbaca983897658 Mon Sep 17 00:00:00 2001 From: Linnea May Date: Tue, 22 Nov 2022 14:40:44 -0800 Subject: [PATCH 2/3] start hello model but messy --- .../SegmentModel.cpp | 57 ++++++++++++++++++- .../WinMLSamplesGalleryNative/SegmentModel.h | 10 +++- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.cpp b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.cpp index 85da2ce6..6a6948ba 100644 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.cpp +++ b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.cpp @@ -38,7 +38,7 @@ enum OnnxDataType : long { } OnnxDataType; -const int32_t opset = 12; +const int32_t opset = 13; /**** Style transfer model ****/ @@ -83,12 +83,52 @@ void WindowsHello::InitializeSession(int w, int h) { SetImageSize(w, h); // Preprocessing: grayscale model + m_sessionPreprocess = CreateLearningModelSession(GrayScale(1, 3, m_imageHeightInPixels, m_imageWidthInPixels)); + m_bindingPreprocess = LearningModelBinding(m_sessionPreprocess); m_session = CreateLearningModelSession(GetModel()); m_binding = LearningModelBinding(m_session); } +void WindowsHello::Run(IDirect3DSurface src, IDirect3DSurface dest) +{ + VideoFrame inVideoFrame = VideoFrame::CreateWithDirect3D11Surface(src); + VideoFrame outVideoFrame = VideoFrame::CreateWithDirect3D11Surface(dest); + SetVideoFrames(inVideoFrame, outVideoFrame); + auto outputBindProperties = PropertySet(); + + // Shape validation + assert((UINT32)m_inputVideoFrame.Direct3DSurface().Description().Height == m_imageHeightInPixels); + assert((UINT32)m_inputVideoFrame.Direct3DSurface().Description().Width == m_imageWidthInPixels); + + // Preprocessing: grayscale + std::vector shape = { 1, 1, m_imageHeightInPixels, m_imageWidthInPixels }; + ITensor intermediateTensor = TensorFloat::Create(shape); + hstring inputName = m_sessionPreprocess.Model().InputFeatures().GetAt(0).Name(); + hstring outputName = m_sessionPreprocess.Model().OutputFeatures().GetAt(0).Name(); + + m_bindingPreprocess.Bind(inputName, m_inputVideoFrame); + outputBindProperties.Insert(L"DisableTensorCpuSync", PropertyValue::CreateBoolean(true)); + m_bindingPreprocess.Bind(outputName, intermediateTensor, outputBindProperties); + m_sessionPreprocess.Evaluate(m_bindingPreprocess, L""); + + // Run through actual model + std::vector helloOutputShape = {1, -1, 4}; // TODO: How many bboxes? + ITensor helloOutput = TensorFloat::Create(helloOutputShape); + m_binding.Bind(m_session.Model().InputFeatures().GetAt(0).Name(), intermediateTensor); + m_binding.Bind(m_session.Model().OutputFeatures().GetAt(0).Name(), helloOutput, outputBindProperties); + m_session.Evaluate(m_binding, L""); + + //m_.CopyToAsync(outVideoFrame); + // Draw bboxes on videoframe?? For now just print them out + auto bbox = helloOutput.as().GetAsVectorView(); + m_inputVideoFrame.CopyToAsync(outVideoFrame).get(); + OutputDebugString(L"BOUNDING BOX: "); + OutputDebugString(std::to_wstring(bbox.GetAt(0)).c_str()); + OutputDebugString(L"\n"); +} + LearningModel WindowsHello::GetModel() { auto modelPath = std::filesystem::path(m_modelBasePath.c_str()); modelPath.append("retina_rgb.onnx"); @@ -226,6 +266,21 @@ LearningModel Invert(long n, long c, long h, long w) return builder.CreateModel(); } +LearningModel GrayScale(long n, long c, long h, long w) +{ + // Go from [n, c, h, w] -> [1, 1, h, w] + // Start with simple reduction of mean across channels + auto builder = LearningModelBuilder::Create(opset) + .Inputs().Add(LearningModelBuilder::CreateTensorFeatureDescriptor(L"Input", TensorKind::Float, { 1, c, h, w })) + .Outputs().Add(LearningModelBuilder::CreateTensorFeatureDescriptor(L"Output", TensorKind::Float, { 1, 1, h, w })) + .Operators().Add(LearningModelOperator(L"ReduceMean") + .SetInput(L"data", L"Input") + .SetConstant(L"axes", TensorFloat::CreateFromIterable({ 1 }, { 1.f })) + .SetOutput(L"reduced", L"Output") + ); + return builder.CreateModel(); +} + LearningModel Normalize0_1ThenZScore(long h, long w, long c, const std::array& means, const std::array& stddev) { assert(means.size() == c); diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.h b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.h index ca72cc89..f3ee3e31 100644 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.h +++ b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.h @@ -110,7 +110,7 @@ class StreamModelBase class StyleTransfer : public StreamModelBase { public: - StyleTransfer() : StreamModelBase() {}; + StyleTransfer() : StreamModelBase(){}; void InitializeSession(int w, int h); void Run(IDirect3DSurface src, IDirect3DSurface dest); private: @@ -119,12 +119,16 @@ class StyleTransfer : public StreamModelBase class WindowsHello : public StreamModelBase { public: - WindowsHello() : StreamModelBase() {}; + WindowsHello() : + StreamModelBase(), + m_sessionPreprocess(nullptr), + m_bindingPreprocess(nullptr) {}; void InitializeSession(int w, int h); void Run(IDirect3DSurface src, IDirect3DSurface dest); private: LearningModel GetModel(); - + LearningModelSession m_sessionPreprocess; + LearningModelBinding m_bindingPreprocess; }; class BackgroundBlur : public StreamModelBase From dac874d5f47201d4cd1eae954fc7be0fe384780c Mon Sep 17 00:00:00 2001 From: Linnea May Date: Wed, 23 Nov 2022 14:58:38 -0800 Subject: [PATCH 3/3] inference for bbox but garbage output --- .../WinMLSamplesGallery.csproj | 4 ++ .../SegmentModel.cpp | 58 +++++++++++-------- .../WinMLSamplesGalleryNative/SegmentModel.h | 8 ++- .../TransformAsync.cpp | 2 +- 4 files changed, 45 insertions(+), 27 deletions(-) diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGallery/WinMLSamplesGallery.csproj b/Samples/WinMLSamplesGallery/WinMLSamplesGallery/WinMLSamplesGallery.csproj index a5aebd7a..2b36541a 100644 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGallery/WinMLSamplesGallery.csproj +++ b/Samples/WinMLSamplesGallery/WinMLSamplesGallery/WinMLSamplesGallery.csproj @@ -36,6 +36,7 @@ + @@ -54,6 +55,9 @@ + + PreserveNewest + PreserveNewest diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.cpp b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.cpp index 6a6948ba..5663b96d 100644 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.cpp +++ b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.cpp @@ -79,11 +79,11 @@ LearningModel StyleTransfer::GetModel() return LearningModel::LoadFromFilePath(modelPath.c_str()); } -void WindowsHello::InitializeSession(int w, int h) { +void BoundBox::InitializeSession(int w, int h) { SetImageSize(w, h); // Preprocessing: grayscale model - m_sessionPreprocess = CreateLearningModelSession(GrayScale(1, 3, m_imageHeightInPixels, m_imageWidthInPixels)); + m_sessionPreprocess = CreateLearningModelSession(Grayscale(1, 3, m_imageHeightInPixels, m_imageWidthInPixels)); m_bindingPreprocess = LearningModelBinding(m_sessionPreprocess); m_session = CreateLearningModelSession(GetModel()); @@ -91,7 +91,7 @@ void WindowsHello::InitializeSession(int w, int h) { } -void WindowsHello::Run(IDirect3DSurface src, IDirect3DSurface dest) +void BoundBox::Run(IDirect3DSurface src, IDirect3DSurface dest) { VideoFrame inVideoFrame = VideoFrame::CreateWithDirect3D11Surface(src); VideoFrame outVideoFrame = VideoFrame::CreateWithDirect3D11Surface(dest); @@ -103,6 +103,7 @@ void WindowsHello::Run(IDirect3DSurface src, IDirect3DSurface dest) assert((UINT32)m_inputVideoFrame.Direct3DSurface().Description().Width == m_imageWidthInPixels); // Preprocessing: grayscale + // TODO: make a real grayscale std::vector shape = { 1, 1, m_imageHeightInPixels, m_imageWidthInPixels }; ITensor intermediateTensor = TensorFloat::Create(shape); hstring inputName = m_sessionPreprocess.Model().InputFeatures().GetAt(0).Name(); @@ -111,27 +112,34 @@ void WindowsHello::Run(IDirect3DSurface src, IDirect3DSurface dest) m_bindingPreprocess.Bind(inputName, m_inputVideoFrame); outputBindProperties.Insert(L"DisableTensorCpuSync", PropertyValue::CreateBoolean(true)); m_bindingPreprocess.Bind(outputName, intermediateTensor, outputBindProperties); - m_sessionPreprocess.Evaluate(m_bindingPreprocess, L""); + m_sessionPreprocess.Evaluate(m_bindingPreprocess, L""); // Run through actual model - std::vector helloOutputShape = {1, -1, 4}; // TODO: How many bboxes? + std::vector helloOutputShape = {1, 20400, 4}; // TODO: How many bboxes? + ITensor shapeTensor = TensorInt64Bit::CreateFromArray({ 2 }, { m_imageHeightInPixels, m_imageWidthInPixels }); ITensor helloOutput = TensorFloat::Create(helloOutputShape); m_binding.Bind(m_session.Model().InputFeatures().GetAt(0).Name(), intermediateTensor); + m_binding.Bind(m_session.Model().InputFeatures().GetAt(1).Name(), shapeTensor); m_binding.Bind(m_session.Model().OutputFeatures().GetAt(0).Name(), helloOutput, outputBindProperties); m_session.Evaluate(m_binding, L""); + // Choose top bounding box //m_.CopyToAsync(outVideoFrame); // Draw bboxes on videoframe?? For now just print them out - auto bbox = helloOutput.as().GetAsVectorView(); + auto bboxes = helloOutput.as().CreateReference(); + auto capacity = bboxes.Capacity(); + auto data = bboxes.data(); + auto bbox = std::vector{ data, data + capacity }; // All but divided into chunks of 4? m_inputVideoFrame.CopyToAsync(outVideoFrame).get(); OutputDebugString(L"BOUNDING BOX: "); - OutputDebugString(std::to_wstring(bbox.GetAt(0)).c_str()); + OutputDebugString(std::to_wstring(bbox.at(0)).c_str()); + OutputDebugString(std::to_wstring(bbox.at(4)).c_str()); OutputDebugString(L"\n"); } -LearningModel WindowsHello::GetModel() { +LearningModel BoundBox::GetModel() { auto modelPath = std::filesystem::path(m_modelBasePath.c_str()); - modelPath.append("retina_rgb.onnx"); + modelPath.append("bounding_box.onnx"); return LearningModel::LoadFromFilePath(modelPath.c_str()); } @@ -247,6 +255,24 @@ LearningModel BackgroundBlur::PostProcess(long n, long c, long h, long w, long a return builder.CreateModel(); } + +LearningModel Grayscale(long n, long c, long h, long w) +{ + // Go from [n, c, h, w] -> [1, 1, h, w] + // Start with simple reduction of mean across channels + auto builder = LearningModelBuilder::Create(opset) + .Inputs().Add(LearningModelBuilder::CreateTensorFeatureDescriptor(L"Input", TensorKind::Float, { 1, c, h, w })) + .Outputs().Add(LearningModelBuilder::CreateTensorFeatureDescriptor(L"Output", TensorKind::Float, { 1, 1, h, w })) + .Operators().Add(LearningModelOperator(L"ReduceMean") + .SetInput(L"data", L"Input") + .SetAttribute(L"axes",TensorInt64Bit::CreateFromArray({ 1 }, { 1 })) + .SetAttribute(L"keepdims", TensorInt64Bit::CreateFromArray({ 1 }, { 1 })) + .SetOutput(L"reduced", L"Output") + ); + return builder.CreateModel(); +} + + LearningModel Invert(long n, long c, long h, long w) { auto builder = LearningModelBuilder::Create(opset) @@ -266,20 +292,6 @@ LearningModel Invert(long n, long c, long h, long w) return builder.CreateModel(); } -LearningModel GrayScale(long n, long c, long h, long w) -{ - // Go from [n, c, h, w] -> [1, 1, h, w] - // Start with simple reduction of mean across channels - auto builder = LearningModelBuilder::Create(opset) - .Inputs().Add(LearningModelBuilder::CreateTensorFeatureDescriptor(L"Input", TensorKind::Float, { 1, c, h, w })) - .Outputs().Add(LearningModelBuilder::CreateTensorFeatureDescriptor(L"Output", TensorKind::Float, { 1, 1, h, w })) - .Operators().Add(LearningModelOperator(L"ReduceMean") - .SetInput(L"data", L"Input") - .SetConstant(L"axes", TensorFloat::CreateFromIterable({ 1 }, { 1.f })) - .SetOutput(L"reduced", L"Output") - ); - return builder.CreateModel(); -} LearningModel Normalize0_1ThenZScore(long h, long w, long c, const std::array& means, const std::array& stddev) { diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.h b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.h index f3ee3e31..1f8a4c7d 100644 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.h +++ b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/SegmentModel.h @@ -27,6 +27,7 @@ using namespace winrt::Windows::Media; LearningModel Normalize0_1ThenZScore(long height, long width, long channels, const std::array& means, const std::array& stddev); LearningModel ReshapeFlatBufferToNCHW(long n, long c, long h, long w); LearningModel Invert(long n, long c, long h, long w); +LearningModel Grayscale(long n, long c, long h, long w); class StreamModelBase { @@ -117,12 +118,14 @@ class StyleTransfer : public StreamModelBase LearningModel GetModel(); }; -class WindowsHello : public StreamModelBase { +class BoundBox : public StreamModelBase { public: - WindowsHello() : + BoundBox() : StreamModelBase(), m_sessionPreprocess(nullptr), m_bindingPreprocess(nullptr) {}; + virtual ~BoundBox() {} + void InitializeSession(int w, int h); void Run(IDirect3DSurface src, IDirect3DSurface dest); private: @@ -148,5 +151,4 @@ class BackgroundBlur : public StreamModelBase std::array m_mean = { 0.485f, 0.456f, 0.406f }; std::array m_stddev = { 0.229f, 0.224f, 0.225f }; - }; \ No newline at end of file diff --git a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/TransformAsync.cpp b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/TransformAsync.cpp index 4f63654b..25778387 100644 --- a/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/TransformAsync.cpp +++ b/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/TransformAsync.cpp @@ -652,7 +652,7 @@ HRESULT TransformAsync::InitializeTransform() // Set up circular queue of StreamModelBases for (int i = 0; i < m_numThreads; i++) { // TODO: Have a dialogue to select which model to select for real-time inference. - m_models.push_back(std::make_unique()); + m_models.push_back(std::make_unique()); } return S_OK;