@@ -31,7 +31,9 @@ namespace
3131 {}
3232
3333 HRESULT initialize (
34- _In_reads_ (nFaces * 3 ) const index_t* indices, size_t nFaces,
34+ _In_reads_ (nFaces * 3 ) const index_t* indices,
35+ size_t nFaces,
36+ size_t nVerts,
3537 _In_reads_(nFaces * 3 ) const uint32_t* adjacency,
3638 const std::vector<std::pair<size_t, size_t>>& subsets)
3739 {
@@ -74,7 +76,13 @@ namespace
7476 index_t i1 = indices[face * 3 + 1 ];
7577 index_t i2 = indices[face * 3 + 2 ];
7678
77- if (i0 == index_t (-1 )
79+ if ((i0 != index_t (-1 ) && i0 >= nVerts)
80+ || (i1 != index_t (-1 ) && i1 >= nVerts)
81+ || (i2 != index_t (-1 ) && i2 >= nVerts))
82+ {
83+ return E_UNEXPECTED;
84+ }
85+ else if (i0 == index_t (-1 )
7886 || i1 == index_t (-1 )
7987 || i2 == index_t (-1 )
8088 || i0 == i1
@@ -163,7 +171,7 @@ namespace
163171 }
164172
165173 HRESULT setSubset (
166- _In_reads_ (nFaces * 3 ) const index_t* indices, size_t nFaces,
174+ _In_reads_ (nFaces * 3 ) const index_t* indices, size_t nFaces, size_t nVerts,
167175 size_t faceOffset, size_t faceCount) noexcept
168176 {
169177 if (!indices || !mListElements )
@@ -202,6 +210,11 @@ namespace
202210 continue ;
203211 }
204212
213+ if (i0 >= nVerts
214+ || i1 >= nVerts
215+ || i2 >= nVerts)
216+ return E_UNEXPECTED;
217+
205218 uint32_t unprocessed = 0 ;
206219
207220 for (uint32_t n = 0 ; n < 3 ; ++n)
@@ -508,7 +521,7 @@ namespace
508521 // ---------------------------------------------------------------------------------
509522 template <class index_t >
510523 HRESULT StripReorderImpl (
511- _In_reads_ (nFaces * 3 ) const index_t* indices, _In_ size_t nFaces,
524+ _In_reads_ (nFaces * 3 ) const index_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
512525 _In_reads_(nFaces * 3 ) const uint32_t* adjacency,
513526 _In_reads_opt_(nFaces) const uint32_t* attributes,
514527 _Out_writes_(nFaces) uint32_t* faceRemap)
@@ -518,7 +531,7 @@ namespace
518531 return E_UNEXPECTED;
519532
520533 mesh_status<index_t > status;
521- HRESULT hr = status.initialize (indices, nFaces, adjacency, subsets);
534+ HRESULT hr = status.initialize (indices, nFaces, nVerts, adjacency, subsets);
522535 if (FAILED (hr))
523536 return hr;
524537
@@ -530,7 +543,7 @@ namespace
530543
531544 for (const auto & it : subsets)
532545 {
533- hr = status.setSubset (indices, nFaces, it.first , it.second );
546+ hr = status.setSubset (indices, nFaces, nVerts, it.first , it.second );
534547 if (FAILED (hr))
535548 return hr;
536549
@@ -585,7 +598,7 @@ namespace
585598 // ---------------------------------------------------------------------------------
586599 template <class index_t >
587600 HRESULT VertexCacheStripReorderImpl (
588- _In_reads_ (nFaces * 3 ) const index_t* indices, _In_ size_t nFaces,
601+ _In_reads_ (nFaces * 3 ) const index_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
589602 _In_reads_(nFaces * 3 ) const uint32_t* adjacency,
590603 _In_reads_opt_(nFaces) const uint32_t* attributes,
591604 _Out_writes_(nFaces) uint32_t* faceRemap,
@@ -596,7 +609,7 @@ namespace
596609 return E_UNEXPECTED;
597610
598611 mesh_status<index_t > status;
599- HRESULT hr = status.initialize (indices, nFaces, adjacency, subsets);
612+ HRESULT hr = status.initialize (indices, nFaces, nVerts, adjacency, subsets);
600613 if (FAILED (hr))
601614 return hr;
602615
@@ -616,7 +629,7 @@ namespace
616629
617630 for (const auto & it : subsets)
618631 {
619- hr = status.setSubset (indices, nFaces, it.first , it.second );
632+ hr = status.setSubset (indices, nFaces, nVerts, it.first , it.second );
620633 if (FAILED (hr))
621634 return hr;
622635
@@ -771,55 +784,57 @@ _Use_decl_annotations_
771784HRESULT DirectX::OptimizeFaces (
772785 const uint16_t * indices,
773786 size_t nFaces,
787+ size_t nVerts,
774788 const uint32_t * adjacency,
775789 uint32_t * faceRemap,
776790 uint32_t vertexCache,
777791 uint32_t restart)
778792{
779- if (!indices || !nFaces || !adjacency || !faceRemap)
793+ if (!indices || !nFaces || !nVerts || ! adjacency || !faceRemap)
780794 return E_INVALIDARG;
781795
782796 if ((uint64_t (nFaces) * 3 ) >= UINT32_MAX)
783797 return HRESULT_E_ARITHMETIC_OVERFLOW;
784798
785799 if (vertexCache == OPTFACES_V_STRIPORDER)
786800 {
787- return StripReorderImpl<uint16_t >(indices, nFaces, adjacency, nullptr , faceRemap);
801+ return StripReorderImpl<uint16_t >(indices, nFaces, nVerts, adjacency, nullptr , faceRemap);
788802 }
789803 else
790804 {
791805 if (restart > vertexCache)
792806 return E_INVALIDARG;
793807
794- return VertexCacheStripReorderImpl<uint16_t >(indices, nFaces, adjacency, nullptr , faceRemap, vertexCache, restart);
808+ return VertexCacheStripReorderImpl<uint16_t >(indices, nFaces, nVerts, adjacency, nullptr , faceRemap, vertexCache, restart);
795809 }
796810}
797811
798812_Use_decl_annotations_
799813HRESULT DirectX::OptimizeFaces (
800814 const uint32_t * indices,
801815 size_t nFaces,
816+ size_t nVerts,
802817 const uint32_t * adjacency,
803818 uint32_t * faceRemap,
804819 uint32_t vertexCache,
805820 uint32_t restart)
806821{
807- if (!indices || !nFaces || !adjacency || !faceRemap)
822+ if (!indices || !nFaces || !nVerts || ! adjacency || !faceRemap)
808823 return E_INVALIDARG;
809824
810825 if ((uint64_t (nFaces) * 3 ) >= UINT32_MAX)
811826 return HRESULT_E_ARITHMETIC_OVERFLOW;
812827
813828 if (vertexCache == OPTFACES_V_STRIPORDER)
814829 {
815- return StripReorderImpl<uint32_t >(indices, nFaces, adjacency, nullptr , faceRemap);
830+ return StripReorderImpl<uint32_t >(indices, nFaces, nVerts, adjacency, nullptr , faceRemap);
816831 }
817832 else
818833 {
819834 if (restart > vertexCache)
820835 return E_INVALIDARG;
821836
822- return VertexCacheStripReorderImpl<uint32_t >(indices, nFaces, adjacency, nullptr , faceRemap, vertexCache, restart);
837+ return VertexCacheStripReorderImpl<uint32_t >(indices, nFaces, nVerts, adjacency, nullptr , faceRemap, vertexCache, restart);
823838 }
824839}
825840
@@ -829,56 +844,58 @@ _Use_decl_annotations_
829844HRESULT DirectX::OptimizeFacesEx (
830845 const uint16_t * indices,
831846 size_t nFaces,
847+ size_t nVerts,
832848 const uint32_t * adjacency,
833849 const uint32_t * attributes,
834850 uint32_t * faceRemap,
835851 uint32_t vertexCache,
836852 uint32_t restart)
837853{
838- if (!indices || !nFaces || !adjacency || !attributes || !faceRemap)
854+ if (!indices || !nFaces || !nVerts || ! adjacency || !attributes || !faceRemap)
839855 return E_INVALIDARG;
840856
841857 if ((uint64_t (nFaces) * 3 ) >= UINT32_MAX)
842858 return HRESULT_E_ARITHMETIC_OVERFLOW;
843859
844860 if (vertexCache == OPTFACES_V_STRIPORDER)
845861 {
846- return StripReorderImpl<uint16_t >(indices, nFaces, adjacency, attributes, faceRemap);
862+ return StripReorderImpl<uint16_t >(indices, nFaces, nVerts, adjacency, attributes, faceRemap);
847863 }
848864 else
849865 {
850866 if (restart > vertexCache)
851867 return E_INVALIDARG;
852868
853- return VertexCacheStripReorderImpl<uint16_t >(indices, nFaces, adjacency, attributes, faceRemap, vertexCache, restart);
869+ return VertexCacheStripReorderImpl<uint16_t >(indices, nFaces, nVerts, adjacency, attributes, faceRemap, vertexCache, restart);
854870 }
855871}
856872
857873_Use_decl_annotations_
858874HRESULT DirectX::OptimizeFacesEx (
859875 const uint32_t * indices,
860876 size_t nFaces,
877+ size_t nVerts,
861878 const uint32_t * adjacency,
862879 const uint32_t * attributes,
863880 uint32_t * faceRemap,
864881 uint32_t vertexCache,
865882 uint32_t restart)
866883{
867- if (!indices || !nFaces || !adjacency || !attributes || !faceRemap)
884+ if (!indices || !nFaces || !nVerts || ! adjacency || !attributes || !faceRemap)
868885 return E_INVALIDARG;
869886
870887 if ((uint64_t (nFaces) * 3 ) >= UINT32_MAX)
871888 return HRESULT_E_ARITHMETIC_OVERFLOW;
872889
873890 if (vertexCache == OPTFACES_V_STRIPORDER)
874891 {
875- return StripReorderImpl<uint32_t >(indices, nFaces, adjacency, attributes, faceRemap);
892+ return StripReorderImpl<uint32_t >(indices, nFaces, nVerts, adjacency, attributes, faceRemap);
876893 }
877894 else
878895 {
879896 if (restart > vertexCache)
880897 return E_INVALIDARG;
881898
882- return VertexCacheStripReorderImpl<uint32_t >(indices, nFaces, adjacency, attributes, faceRemap, vertexCache, restart);
899+ return VertexCacheStripReorderImpl<uint32_t >(indices, nFaces, nVerts, adjacency, attributes, faceRemap, vertexCache, restart);
883900 }
884901}
0 commit comments