Support for Windows Subsystem for Linux (#56)

This commit is contained in:
Chuck Walbourn 2021-01-08 02:02:15 -08:00 коммит произвёл GitHub
Родитель 9c41d6617e
Коммит 8ab5f141a0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
12 изменённых файлов: 180 добавлений и 117 удалений

7
.gitignore поставляемый
Просмотреть файл

@ -18,7 +18,7 @@
*.VC.db
*.nupkg
.vs
Bin
[Bb]in
/ipch
Debug
Profile
@ -28,3 +28,8 @@ packages
/Tests
/wiki
/out
/CMakeCache.txt
/CMakeFiles
/Makefile
/cmake
/cmake_install.cmake

Просмотреть файл

@ -119,6 +119,12 @@ if(MSVC)
string(REPLACE "/GR " "/GR- " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
endif()
if (NOT WIN32)
find_package(directx-headers CONFIG REQUIRED)
find_package(directxmath CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE Microsoft::DirectX-Headers Microsoft::DirectXMath)
endif()
#--- Package
include(CMakePackageConfigHelpers)
@ -154,7 +160,7 @@ install(
DESTINATION cmake/)
#--- Command-line tool
if(BUILD_TOOLS)
if(BUILD_TOOLS AND WIN32)
find_package(directxmesh CONFIG REQUIRED COMPONENTS library utils)
find_package(directxtex CONFIG REQUIRED)
@ -172,38 +178,38 @@ endif()
if(MSVC)
target_compile_options(${PROJECT_NAME} PRIVATE /fp:fast)
if(BUILD_TOOLS)
if(BUILD_TOOLS AND WIN32)
target_compile_options(uvatlastool PRIVATE /fp:fast)
endif()
if (${CMAKE_SIZEOF_VOID_P} EQUAL "4")
target_compile_options(${PROJECT_NAME} PRIVATE /arch:SSE2)
if(BUILD_TOOLS)
if(BUILD_TOOLS AND WIN32)
target_compile_options(uvatlastool PRIVATE /arch:SSE2)
endif()
endif()
endif()
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(WarningsLib "-Wpedantic" "-Wextra")
target_compile_options(${PROJECT_NAME} PRIVATE ${WarningsLib})
if(BUILD_TOOLS)
if(BUILD_TOOLS AND WIN32)
set(WarningsEXE ${WarningsLib} "-Wno-c++98-compat" "-Wno-c++98-compat-pedantic" "-Wno-switch" "-Wno-switch-enum" "-Wno-exit-time-destructors" "-Wno-switch" "-Wno-switch-enum" "-Wno-language-extension-token" "-Wno-missing-prototypes")
target_compile_options(uvatlastool PRIVATE ${WarningsEXE})
endif()
endif()
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(${PROJECT_NAME} PRIVATE /permissive- /JMC- /Zc:__cplusplus)
if(BUILD_TOOLS)
if(BUILD_TOOLS AND WIN32)
target_compile_options(uvatlastool PRIVATE /permissive- /Zc:__cplusplus)
endif()
if(ENABLE_CODE_ANALYSIS)
target_compile_options(${PROJECT_NAME} PRIVATE /analyze)
if(BUILD_TOOLS)
if(BUILD_TOOLS AND WIN32)
target_compile_options(uvatlastool PRIVATE /analyze)
endif()
endif()
@ -211,7 +217,7 @@ if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.26)
target_compile_options(${PROJECT_NAME} PRIVATE /Zc:preprocessor /wd5105)
if(BUILD_TOOLS)
if(BUILD_TOOLS AND WIN32)
target_compile_options(uvatlastool PRIVATE /Zc:preprocessor /wd5105)
endif()
endif()
@ -219,12 +225,12 @@ if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
if(UVATLAS_USE_OPENMP)
target_compile_options(${PROJECT_NAME} PRIVATE /openmp /Zc:twoPhase-)
if(BUILD_TOOLS)
if(BUILD_TOOLS AND WIN32)
target_compile_options(uvatlastool PRIVATE /openmp /Zc:twoPhase-)
endif()
endif()
if(BUILD_TOOLS)
if(BUILD_TOOLS AND WIN32)
set(WarningsEXE "/wd4365" "/wd4668" "/wd4710" "/wd4820" "/wd5039" "/wd5045" "/wd4061" "/wd4062" "/wd5219")
target_compile_options(uvatlastool PRIVATE ${WarningsEXE})
endif()
@ -239,12 +245,12 @@ if(MSVC)
target_compile_definitions(${PROJECT_NAME} PRIVATE _WIN32_WINNT=0x0601)
endif()
if(BUILD_TOOLS)
if(BUILD_TOOLS AND WIN32)
target_compile_definitions(uvatlastool PRIVATE _UNICODE UNICODE _WIN32_WINNT=0x0601)
endif()
endif()
if(BUILD_TOOLS)
if(BUILD_TOOLS AND WIN32)
set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT uvatlastool)
else()
set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME})

Просмотреть файл

@ -9,12 +9,21 @@
#pragma once
#if defined(_XBOX_ONE) && defined(_TITLE)
#if defined(WIN32) || defined(WINAPI_FAMILY)
#ifdef _GAMING_XBOX_SCARLETT
#include <d3d12_xs.h>
#elif defined(_GAMING_XBOX)
#include <d3d12_x.h>
#elif defined(_XBOX_ONE) && defined(_TITLE)
#include <d3d11_x.h>
#else
#include <Windows.h>
#include <dxgiformat.h>
#endif
#else // !WIN32
#include <directx/dxgiformat.h>
#include <wsl/winadapter.h>
#endif
#include <cstddef>
#include <cstdint>

Просмотреть файл

@ -115,7 +115,7 @@ namespace
if ((sizeof(IndexType) == sizeof(uint16_t)) && (*nNewVerts > 0x0fffe))
{
DPF(0, "Resulting mesh is too large to fit in 16-bit mesh.");
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
return HRESULT_E_INVALID_DATA;
}
try
@ -159,7 +159,7 @@ namespace
return E_POINTER;
if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
return HRESULT_E_ARITHMETIC_OVERFLOW;
// put all vertices in their own equivalency class
std::unique_ptr<uint32_t[]> equivs(new (std::nothrow) uint32_t[nFaces * 3]);
@ -190,7 +190,7 @@ namespace
if (k >= 3)
{
DPF(0, "Adjacency data is invalid, %u is a neighbor of %zu, but not vice versa.", neighbor, i);
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
return HRESULT_E_INVALID_DATA;
}
uint32_t v1 = static_cast<uint32_t>(i * 3 + j);
@ -229,7 +229,7 @@ namespace
if (FindEquivParent(pEquivs, v1) != FindEquivParent(pEquivs, v2))
{
DPF(0, "False edge data is invalid, %d and %d are only connected by false edges.", pIndexData[v1], pIndexData[v2]);
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
return HRESULT_E_INVALID_DATA;
}
}
}
@ -289,7 +289,7 @@ namespace
}
if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
return HRESULT_E_ARITHMETIC_OVERFLOW;
if (maxChartNumber > nFaces)
maxChartNumber = nFaces;
@ -304,7 +304,7 @@ namespace
(falseEdgeAdjacency[i] != uint32_t(-1)))
{
DPF(0, "False edge found on triangle with no adjacent triangle.");
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
return HRESULT_E_INVALID_DATA;
}
}
@ -500,7 +500,7 @@ namespace
assert(nFaces > 0);
if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
return HRESULT_E_ARITHMETIC_OVERFLOW;
if (vPartitionResultAdjacency.size() != (nFaces * 3))
{
@ -767,7 +767,7 @@ HRESULT __cdecl DirectX::UVAtlasComputeIMTFromPerVertexSignal(
}
if ((uint64_t(signalDimension) * 3) >= UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
return HRESULT_E_ARITHMETIC_OVERFLOW;
std::unique_ptr<float[]> signalData(new (std::nothrow) float[3 * signalDimension]);
if (!signalData)
@ -886,7 +886,7 @@ HRESULT __cdecl DirectX::UVAtlasComputeIMTFromSignal(
}
if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
return HRESULT_E_ARITHMETIC_OVERFLOW;
auto pdwIndexData = reinterpret_cast<const uint32_t*>(indices);
auto pwIndexData = reinterpret_cast<const uint16_t*>(indices);
@ -1004,7 +1004,7 @@ namespace
j = std::max(0, std::min<int>(j, int(pTexDesc->uHeight) - 1));
j2 = std::max(0, std::min<int>(j2, int(pTexDesc->uHeight) - 1));
//
//
// C1 ---- C2 ^ dv
// | . | | |
// | | | |
@ -1071,7 +1071,7 @@ namespace
j = std::max(0, std::min<int>(j, int(pTexDesc->uHeight) - 1));
j2 = std::max(0, std::min<int>(j2, int(pTexDesc->uHeight) - 1));
//
//
// C1 ---- C2 ^ dv
// | . | | |
// | | | |
@ -1138,7 +1138,7 @@ namespace
if (j2 < 0)
j2 += int(pTexDesc->uHeight);
//
//
// C1 ---- C2 ^ dv
// | . | | |
// | | | |
@ -1209,7 +1209,7 @@ namespace
if (j2 < 0)
j2 += int(pTexDesc->uHeight);
//
//
// C1 ---- C2 ^ dv
// | . | | |
// | | | |
@ -1274,7 +1274,7 @@ HRESULT __cdecl DirectX::UVAtlasComputeIMTFromTexture(
}
if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
return HRESULT_E_ARITHMETIC_OVERFLOW;
LPIMTSIGNALCALLBACK pSignalCallback = nullptr;
if ((options & UVATLAS_IMT_WRAP_UV) == UVATLAS_IMT_WRAP_UV)
@ -1413,7 +1413,7 @@ namespace
j = std::max(0, std::min<int>(j, int(pTexDesc->uHeight) - 1));
j2 = std::max(0, std::min<int>(j2, int(pTexDesc->uHeight) - 1));
//
//
// C1 ---- C2 ^ dv
// | . | | |
// | | | |
@ -1478,7 +1478,7 @@ namespace
j = std::max(0, std::min<int>(j, int(pTexDesc->uHeight) - 1));
j2 = std::max(0, std::min<int>(j2, int(pTexDesc->uHeight) - 1));
//
//
// C1 ---- C2 ^ dv
// | . | | |
// | | | |
@ -1543,7 +1543,7 @@ namespace
if (j2 < 0)
j2 += int(pTexDesc->uHeight);
//
//
// C1 ---- C2 ^ dv
// | . | | |
// | | | |
@ -1611,7 +1611,7 @@ namespace
if (j2 < 0)
j2 += int(pTexDesc->uHeight);
//
//
// C1 ---- C2 ^ dv
// | . | | |
// | | | |
@ -1677,7 +1677,7 @@ HRESULT __cdecl DirectX::UVAtlasComputeIMTFromPerTexelSignal(
}
if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
return HRESULT_E_ARITHMETIC_OVERFLOW;
if (nComponents < signalDimension)
{
@ -1800,7 +1800,7 @@ HRESULT __cdecl DirectX::UVAtlasApplyRemap(
return E_INVALIDARG;
if (vbin == vbout)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
return HRESULT_E_NOT_SUPPORTED;
auto sptr = reinterpret_cast<const uint8_t*>(vbin);
auto dptr = reinterpret_cast<uint8_t*>(vbout);

Просмотреть файл

@ -37,40 +37,50 @@ void IIsochartEngine::ReleaseIsochartEngine(
CIsochartEngine::CIsochartEngine() :
m_state(ISOCHART_ST_UNINITILAIZED),
#ifdef WIN32
m_hMutex(nullptr),
#endif
m_dwOptions(_OPTION_ISOCHART_DEFAULT)
{
}
CIsochartEngine::~CIsochartEngine()
{
// if other thread is calling public method of CIsochartEngine this time,
// if other thread is calling public method of CIsochartEngine this time,
// Free will return with "busy". So loop until free successfully.
while (FAILED(Free()))
{
#ifdef WIN32
SwitchToThread();
#else
std::this_thread::yield();
#endif
}
#ifdef WIN32
if (m_hMutex)
{
CloseHandle(m_hMutex);
}
#endif
}
HRESULT CIsochartEngine::CreateEngineMutex()
{
#ifdef WIN32
m_hMutex = CreateMutexEx(nullptr, nullptr, CREATE_MUTEX_INITIAL_OWNER, SYNCHRONIZE);
if (!m_hMutex)
{
return HRESULT_FROM_WIN32(GetLastError());
}
#endif
return S_OK;
}
// ------------------------------------------------------------------------
// Initialize the isochart engine. Must be called before Partition, Optimize & Pack.
//-pMinChartNumber
// size_t pointer. If specified, Initialize() pre-calculate the minimal
// number of charts.In Partition(), MaxChartNumber should be always
// number of charts.In Partition(), MaxChartNumber should be always
// larger than MinChartNumber. Set to nullptr to skip pre-calculation. It
// is faster for Initialization, but only used in "control by stretch
// only" mode.
@ -122,7 +132,7 @@ HRESULT CIsochartEngine::Initialize(
// 3. If engine is already initialized, return error code
// 4. Prepare global basic information table.
// 4. Prepare global basic information table.
if (FAILED(hr = InitializeBaseInfo(
pVertexArray,
VertexCount,
@ -191,7 +201,7 @@ HRESULT CIsochartEngine::Free() noexcept
}
//Partition by number or by stretch only.
//Partition by number or by stretch only.
//Before calling this method, Initialize() should be called.
HRESULT CIsochartEngine::Partition(
size_t MaxChartNumber,
@ -234,7 +244,7 @@ HRESULT CIsochartEngine::Partition(
return hr;
}
// Check if MaxChartNumber is a valid value.
// Check if MaxChartNumber is a valid value.
bool CIsochartEngine::IsMaxChartNumberValid(
size_t MaxChartNumber)
{
@ -257,7 +267,7 @@ HRESULT CIsochartEngine::InitializeCurrentChartHeap()
ReleaseFinalCharts();
}
// Initialize current chart list. Charts in this list are candidates to be
// Initialize current chart list. Charts in this list are candidates to be
// partitioned.
for (size_t i = 0; i < m_initChartList.size(); i++)
{
@ -280,7 +290,7 @@ HRESULT CIsochartEngine::ParameterizeChartsInHeapParallelized(
/// Parallelization:
/// 1st Move heap to vector `parent`
/// 2nd run through parent in parallel, add children to `children`
/// 3rd children = parent, goto 2nd
/// 3rd children = parent, goto 2nd
std::vector<CIsochartMesh*> parent;
while (!m_currentChartHeap.empty())
parent.emplace_back(m_currentChartHeap.cutTopData());
@ -289,7 +299,7 @@ HRESULT CIsochartEngine::ParameterizeChartsInHeapParallelized(
while (!parent.empty() && !FAILED(hrOut))
{
std::vector<CIsochartMesh*> children;
#pragma omp parallel
#pragma omp parallel
{
std::vector<CIsochartMesh*> children_thrd;
@ -303,7 +313,7 @@ HRESULT CIsochartEngine::ParameterizeChartsInHeapParallelized(
assert(pChart != nullptr);
_Analysis_assume_(pChart != nullptr);
// Process current chart, if it's needed to be partitioned again,
// Process current chart, if it's needed to be partitioned again,
// Just partition it.
HRESULT hr = pChart->Partition(); /// Adds children to pChart->m_children // hotspot
if (FAILED(hr))
@ -394,7 +404,7 @@ HRESULT CIsochartEngine::ParameterizeChartsInHeap(
assert(pChart != nullptr);
_Analysis_assume_(pChart != nullptr);
// Process current chart, if it's needed to be partitioned again,
// Process current chart, if it's needed to be partitioned again,
// Just partition it.
HRESULT hr = pChart->Partition();
if (FAILED(hr))
@ -420,7 +430,7 @@ HRESULT CIsochartEngine::ParameterizeChartsInHeap(
}
}
// If A right parameterization (with acceptable face overturn)
// If A right parameterization (with acceptable face overturn)
// has been gotten, add current chart to final Chart List.
else
{
@ -672,9 +682,9 @@ HRESULT CIsochartEngine::PartitionByGlobalAvgL2Stretch(
m_finalChartList,
false));
// 3.3
// 3.3
// For geometric case, get current optical average L^2 Squared Stretch
// For signal case, get max average L^2 Squared stretch around the
// For signal case, get max average L^2 Squared stretch around the
// Charts
fCurrAvgL2SquaredStretch = GetCurrentStretchCriteria();
@ -756,8 +766,8 @@ HRESULT CIsochartEngine::PartitionByGlobalAvgL2Stretch(
FAILURE_RETURN(
OptimizeParameterizedCharts(Stretch, fCurrAvgL2SquaredStretch));
// 6. Export current partition result by set the attribute id of each face
// in original mesh
// 6. Export current partition result by set the attribute id of each face
// in original mesh
if (pFaceAttributeIDOut)
{
hr = ExportCurrentCharts(
@ -1189,10 +1199,10 @@ HRESULT CIsochartEngine::InitializeBaseInfo(
// -----------------------------------------------------------------------------
// function ApplyInitEngine
// function ApplyInitEngine
//
// Description:
// Internal function to initialize engine:
// Description:
// Internal function to initialize engine:
// (1) Check and separate multiple objects in the input mesh.Results are initial charts
// (2) Check and cut multiple boundaries of initial charts.
// (3) Caculated vertex importance order for each initial charts
@ -1237,7 +1247,7 @@ HRESULT CIsochartEngine::ApplyInitEngine(
return hr;
}
// 2. Separate unconnected charts from original mesh. For each chart,
// 2. Separate unconnected charts from original mesh. For each chart,
// Caculate Vertices importance
m_callbackSchemer.InitCallBackAdapt(
@ -1265,7 +1275,7 @@ HRESULT CIsochartEngine::ApplyInitEngine(
}
DPF(3, "Separate to %zu sub-charts", pChart->GetChildrenCount());
// if original mesh has multiple sub-charts or current chart
// if original mesh has multiple sub-charts or current chart
// has multiple boundaies it will generate children.
if (pChart->HasChildren())
@ -1316,10 +1326,10 @@ HRESULT CIsochartEngine::ApplyInitEngine(
}
// ----------------------------------------------------------------------------
// function ReleaseCurrentCharts
// function ReleaseCurrentCharts
//
// Description: release charts in current chart list.
// returns
// Description: release charts in current chart list.
// returns
//
void CIsochartEngine::ReleaseCurrentCharts()
{
@ -1337,9 +1347,9 @@ void CIsochartEngine::ReleaseCurrentCharts()
}
// ----------------------------------------------------------------------------
// function ReleaseFinalCharts
// function ReleaseFinalCharts
//
// Description: release charts in final chart list.
// Description: release charts in final chart list.
void CIsochartEngine::ReleaseFinalCharts()
{
@ -1357,10 +1367,10 @@ void CIsochartEngine::ReleaseFinalCharts()
}
// -----------------------------------------------------------------------------
// function ReleaseInitialCharts
// function ReleaseInitialCharts
//
// Description: release charts in init chart list.
// returns
// Description: release charts in init chart list.
// returns
void CIsochartEngine::ReleaseInitialCharts()
{
@ -1378,12 +1388,12 @@ void CIsochartEngine::ReleaseInitialCharts()
// -----------------------------------------------------------------------------
// function ExportCurrentCharts
// function ExportCurrentCharts
//
// Description:
// Export current partition result by set face attribute for each face in
// Description:
// Export current partition result by set face attribute for each face in
// original mesh.
// returns S_OK if successful, else failure code
// returns S_OK if successful, else failure code
//
HRESULT CIsochartEngine::ExportCurrentCharts(
std::vector<CIsochartMesh*>& finalChartList,
@ -1410,10 +1420,10 @@ HRESULT CIsochartEngine::ExportCurrentCharts(
// ----------------------------------------------------------------------------
// function ExportIsochartResult
// function ExportIsochartResult
//
// Description: Export final result
// returns S_OK if successful, else failure code
// returns S_OK if successful, else failure code
//
HRESULT CIsochartEngine::ExportIsochartResult(
std::vector<CIsochartMesh*>& finalChartList,
@ -1544,7 +1554,7 @@ HRESULT CIsochartEngine::PrepareExportBuffers(
pvFaceIndexArrayOut->clear();
pvVertexRemapArrayOut->clear();
// 1. Compute the output vertices number
// 1. Compute the output vertices number
std::unique_ptr<bool[]> rgbVertUsed(new (std::nothrow) bool[m_baseInfo.dwVertexCount]);
if (!rgbVertUsed)
{
@ -1794,7 +1804,8 @@ HRESULT CIsochartEngine::FillExportFaceAdjacencyBuffer(
HRESULT CIsochartEngine::TryEnterExclusiveSection()
{
// Other thread is using this object.
#ifdef WIN32
// Other thread is using this object.
if (WaitForSingleObjectEx(m_hMutex, 0, FALSE) == WAIT_OBJECT_0)
{
return S_OK;
@ -1803,15 +1814,21 @@ HRESULT CIsochartEngine::TryEnterExclusiveSection()
{
return E_ABORT;
}
#else
return m_mutex.try_lock() ? S_OK : E_ABORT;
#endif
}
void CIsochartEngine::LeaveExclusiveSection()
{
#ifdef WIN32
if (m_hMutex)
{
ReleaseMutex(m_hMutex);
}
#else
m_mutex.unlock();
#endif
}

Просмотреть файл

@ -200,10 +200,10 @@ namespace Isochart
void ReleaseFinalCharts();
// Following methods guarantee Isochart instance is running an exclusive
// Following methods guarantee Isochart instance is running an exclusive
// task.
// Before each public method begins to run, 1 step must be done:
// (1). Try to enter exclusive section, if another thread has entered,
// (1). Try to enter exclusive section, if another thread has entered,
// return error code to indicate busy.
// After each public method complete its work, 1 step must done:
@ -240,7 +240,11 @@ namespace Isochart
EngineState m_state; // Indicate internal state.
HANDLE m_hMutex; // Mutex
#ifdef WIN32
HANDLE m_hMutex;
#else
std::mutex m_mutex;
#endif
unsigned int m_dwOptions;

Просмотреть файл

@ -328,7 +328,7 @@ HRESULT CIsochartMesh::BuildRootChart(
if (!bManifold)
{
pChart->Free();
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
return HRESULT_E_INVALID_DATA;
}
// 4. Get face adjacency for MergeSmallCharts().
@ -572,7 +572,7 @@ namespace
if (!vertIter.Init(iFace, iVert, dwFaceCount))
{
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
return HRESULT_E_INVALID_DATA;
}
uint32_t dwCenterVertID = static_cast<uint32_t>(dwNewVertCount++);
@ -687,7 +687,7 @@ HRESULT CIsochartMesh::PrepareProcessing(
size_t dwBoundaryNumber = 0;
bool bIsSimpleChart = false;
// 1. Check if current chart is a simple chart.
// 1. Check if current chart is a simple chart.
// Otherwise, try to make it simpler (Export individual charts and
// merge multiple boundaries).
hr = PrepareSimpleChart(
@ -714,7 +714,7 @@ HRESULT CIsochartMesh::PrepareProcessing(
return hr;
}
// Partition by stretch only.
// Partition by stretch only.
// See more detail about algorithm of isochart in : [Kun04]
HRESULT CIsochartMesh::Partition()
{
@ -743,7 +743,7 @@ HRESULT CIsochartMesh::Partition()
{
// bIsSimpleChart == false is not an error and need no error code
// under this condition, current chart has already been changed to
// simpler charts contained in current charts children list.
// simpler charts contained in current charts children list.
return hr;
}
@ -777,7 +777,7 @@ HRESULT CIsochartMesh::Partition()
}
// 3. Detect and process trivial shape.
// Trivial shape includes:
// Trivial shape includes:
// a. chart with only one face
// b. chart been degenerated to a point
if (FAILED(hr = ProcessTrivialShape(
@ -979,7 +979,7 @@ HRESULT CIsochartMesh::Bipartition3D()
representativeVertsIdx[0] = 0;
representativeVertsIdx[1] = 1;
// 2. Partition
// 2. Partition
FAILURE_RETURN(
PartitionGeneralShape(
pfVertGeoDistance,
@ -1118,7 +1118,7 @@ LEnd:
// Simple chart
// A chart with 1 boundary, and all vertices in the chart are connected.
// Because isomap can only process simple charts, each chart must be
// Because isomap can only process simple charts, each chart must be
// simplifed to simple chart before applying isomap on it
HRESULT CIsochartMesh::PrepareSimpleChart(
bool bIsForPartition,
@ -1153,11 +1153,11 @@ HRESULT CIsochartMesh::PrepareSimpleChart(
}
// 2. Now the chart has only one object
// Check if it has multiple boundaries, if true, merge 2 boundaries
// and return.
// Check if it has multiple boundaries, if true, merge 2 boundaries
// and return.
// Note, if the original chart has N boundaries, it decreases only 1
// boundary each time and builds a new chart with N-1 boundaries.
// Note, if the original chart has N boundaries, it decreases only 1
// boundary each time and builds a new chart with N-1 boundaries.
// The new chart will be processed in future.
// Note that because cut boundaies caused complex change of mesh,
// topology and sometime generated multiple objects, simple iteration
@ -1299,8 +1299,8 @@ HRESULT CIsochartMesh::IsomapParameterlization(
goto LEnd;
}
// if CIsomap::GetPrimaryEnergyDimension discard too many vector
// demensions which are needed by special-shape detecting, just
// if CIsomap::GetPrimaryEnergyDimension discard too many vector
// demensions which are needed by special-shape detecting, just
// set it back to DIMENSION_TO_CHECK_SPECIAL_SHAPE
if (dwPrimaryEigenDimension < DIMENSION_TO_CHECK_SPECIAL_SHAPE
&& dwCalculatedDimension >= DIMENSION_TO_CHECK_SPECIAL_SHAPE)
@ -1417,7 +1417,7 @@ HRESULT CIsochartMesh::BuildFullConnection(bool& bIsManifold)
return hr;
}
// 5. Build Adjacent vertices array of each vertex.
// 5. Build Adjacent vertices array of each vertex.
// sort them in the same order.
hr = SortAdjacentVertices(bIsManifold);
if (FAILED(hr) || !bIsManifold)
@ -1669,7 +1669,7 @@ HRESULT CIsochartMesh::CleanNonmanifoldMesh(bool& bCleaned)
ISOCHARTEDGE& edge = m_edges[dwMainEdge];
// Find One face culster
// Find One face culster
vertexFaceList.clear();
for (size_t kk = 0; kk < 2; kk++)
{
@ -1730,7 +1730,7 @@ HRESULT CIsochartMesh::CleanNonmanifoldMesh(bool& bCleaned)
return E_OUTOFMEMORY;
}
// 2. Split vertices to fix bowtie.
// 2. Split vertices to fix bowtie.
assert(m_dwVertNumber + newVertMap.size() == dwNewVertID);
if (dwNewVertID == m_dwVertNumber)
@ -1779,7 +1779,7 @@ HRESULT CIsochartMesh::CleanNonmanifoldMesh(bool& bCleaned)
HRESULT CIsochartMesh::SetEdgeSplitAttribute()
{
// The the bCanBeSplit item of each edge. If user don't specified the parameter, all edges can
// The the bCanBeSplit item of each edge. If user don't specified the parameter, all edges can
// be splitted
HRESULT hr = S_OK;
if (!m_baseInfo.pdwSplitHint)
@ -1814,7 +1814,7 @@ HRESULT CIsochartMesh::SetEdgeSplitAttribute()
bool CIsochartMesh::IsAllFaceVertexOrderValid()
{
//.Algorithm
// For each edges, if it isn't a boundary edge, make sure that the two faces
// For each edges, if it isn't a boundary edge, make sure that the two faces
// are sit in different side of it.
for (size_t i = 0; i < m_dwEdgeNumber; i++)
{
@ -2215,7 +2215,7 @@ CIsochartMesh::SortAdjacentVerticesOfInternalVertex(
// Compute adjacent faces for each face. This algorithm can only process manifold meshes.
// Algorithm:
// For each face in mesh, get adjacent faces using the edge adjacent faces information
// For each face in mesh, get adjacent faces using the edge adjacent faces information
// gotten by BuildFullConnection.
void CIsochartMesh::GetFaceAdjacentArray(
uint32_t* pdwFaceAdjacentArray) const
@ -2418,7 +2418,7 @@ HRESULT CIsochartMesh::ExtractIndependentObject(
if (!bManifold)
{
delete pChart;
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
return HRESULT_E_INVALID_DATA;
}
if (m_baseInfo.pfFaceAreaArray)
@ -2434,7 +2434,7 @@ HRESULT CIsochartMesh::ExtractIndependentObject(
// If the chart has 2 or more boundaries, cut the chart along edge paths
// to connect these boundaies. Each call for this function can decrease one
// to connect these boundaies. Each call for this function can decrease one
// boundary.
HRESULT CIsochartMesh::CheckAndCutMultipleBoundaries(
size_t& dwBoundaryNumber)
@ -2499,7 +2499,7 @@ HRESULT CIsochartMesh::CheckAndCutMultipleBoundaries(
// Clustering the boundaies edges in chart
// Algorithm:
// Scan each boundary vertex, if one has not been put into an existent boundary set,
// create a new boundary set and put this vertex and all the bounday vertices which
// create a new boundary set and put this vertex and all the bounday vertices which
// have connection path to this vertex into the new boundary set.
HRESULT CIsochartMesh::FindAllBoundaries(
size_t& dwBoundaryNumber,
@ -2629,7 +2629,7 @@ HRESULT CIsochartMesh::CalMinPathToOtherBoundary(
pCurrentVertex++;
}
// 2. Init the source vertice
// 2. Init the source vertice
for (size_t i = dwStartIdx; i < dwEndIdx; i++)
{
pCurrentVertex = allBoundaryList[i];
@ -2647,7 +2647,7 @@ HRESULT CIsochartMesh::CalMinPathToOtherBoundary(
}
}
// 3. iteration of computing distance, from the one ring neighorhood to the outside
// 3. iteration of computing distance, from the one ring neighorhood to the outside
uint32_t dwCurrentBoundaryID =
pdwVertBoundaryID[allBoundaryList[dwStartIdx]->dwID];
@ -2928,7 +2928,7 @@ HRESULT CIsochartMesh::CutChartAlongPath(std::vector<uint32_t>& dijkstraPath)
{
if (!bManifold)
{
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
hr = HRESULT_E_INVALID_DATA;
goto LEnd;
}
@ -2952,7 +2952,7 @@ LEnd:
}
// Scan the dijkstraPath to find the vertices that need to
// Scan the dijkstraPath to find the vertices that need to
// split. (Remove all boundary edges from dijkstraPath, only
// reserve internal edges.
HRESULT CIsochartMesh::FindSplitPath(
@ -3372,7 +3372,7 @@ HRESULT CIsochartMesh::CalculateDijkstraPathToVertex(
return E_OUTOFMEMORY;
}
// 3. iteration of computing distance, from the one ring neighorhood to the outside
// 3. iteration of computing distance, from the one ring neighorhood to the outside
for (size_t i = 0; i < m_dwVertNumber; i++)
{

Просмотреть файл

@ -252,7 +252,7 @@ HRESULT CIsochartMesh::CalculateGeodesicDistance(
)
||
// or the user forces to use the new algorithm
// or the user forces to use the new algorithm
(
m_IsochartEngine.m_dwOptions & _OPTION_ISOCHART_GEODESIC_QUALITY
)
@ -490,7 +490,7 @@ HRESULT CIsochartMesh::CalculateGeodesicDistanceToVertex(
)
||
// or the user forces to use the new algorithm
// or the user forces to use the new algorithm
(
m_IsochartEngine.m_dwOptions & _OPTION_ISOCHART_GEODESIC_QUALITY
)
@ -814,7 +814,7 @@ HRESULT CIsochartMesh::CalculateVertMappingCoord(
if (!m_isoMap.GetDestineVectors(dwPrimaryEigenDimension, pfLandmarkCoords))
{
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
return HRESULT_E_INVALID_DATA;
}
float* pfCoord = pfLandmarkCoords;

Просмотреть файл

@ -32,7 +32,7 @@ using namespace DirectX;
namespace
{
// Define the percent of faces in chart that are need to
// Define the percent of faces in chart that are need to
// re-decide chart ID by graph cut.
const float FUZYY_REGION_PERCENT = 0.30f;
@ -62,7 +62,7 @@ HRESULT CIsochartMesh::OptimizeBoundaryByAngle(
return S_OK;
}
// 1. Calculate dihedral angle for each edge using formula in
// 1. Calculate dihedral angle for each edge using formula in
// [Kun04], section 4
std::unique_ptr<uint32_t[]> pdwFaceChartIDBackup(new (std::nothrow) uint32_t[m_dwFaceNumber]);
std::unique_ptr<bool[]> pbIsFuzzyFatherFace(new (std::nothrow) bool[m_dwFaceNumber]);
@ -277,7 +277,7 @@ HRESULT CIsochartMesh::SpreadFuzzyVert(
}
// Find such boundary vertex:
// In sub-chart it belongs to a boundary edge but in father chart
// In sub-chart it belongs to a boundary edge but in father chart
// it doesn't belongs to a boundary edge.
// These vertices are "fuzzy vertices" needed to be optimized.
HRESULT CIsochartMesh::FindNewBoundaryVert(
@ -418,7 +418,7 @@ HRESULT CIsochartMesh::OptimizeOneBoundaryByAngle(
float* pfEdgeAngleDistance,
float fAverageAngleDistance)
{
// 2.1 Find all fuzzy faces.
// 2.1 Find all fuzzy faces.
std::vector<uint32_t> candidateFuzzyFaceList;
try
{
@ -446,7 +446,7 @@ HRESULT CIsochartMesh::OptimizeOneBoundaryByAngle(
return S_OK;
}
// 2.2 Perform graph cut
// 2.2 Perform graph cut
uint32_t dwNodeNumber = static_cast<uint32_t>(candidateFuzzyFaceList.size());
graphCut.Clear();
@ -588,7 +588,7 @@ HRESULT CIsochartMesh::OptimizeBoundaryByStretch(
pdwFaceChartID,
sizeof(uint32_t) * m_dwFaceNumber);
// 1. Calculate dihedral angle for each edge using formula
// 1. Calculate dihedral angle for each edge using formula
// in [Kun04], section 4
// If failed to caculate dihedral, then just give up optimize
float fAverageAngleDistance = 0;
@ -1581,7 +1581,7 @@ HRESULT CIsochartMesh::ApplyBoundaryOptResult(
pdwFaceChartID,
bIsOptimized)))
{
if (hr == HRESULT_FROM_WIN32(ERROR_INVALID_DATA))
if (hr == HRESULT_E_INVALID_DATA)
{
bIsOptimized = false;
return hr = S_OK;

Просмотреть файл

@ -791,7 +791,7 @@ HRESULT CIsochartMesh::MakePartitionValid(
if (!bIsSatifiedUserRule)
{
DPF(0, "Cannot partition the mesh without breaking false edges.");
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
return HRESULT_E_INVALID_DATA;
}
if (dwIterationCount + 1 >= dwMaxSubchartCount)

Просмотреть файл

@ -3255,7 +3255,7 @@ HRESULT CIsochartMesh::ScanAlongBoundayEdges(
if (pScanEdge)
{
DPF(0, "Vertex %d has more than 2 boundary edges leaving it", pVertex->dwIDInRootMesh);
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
return HRESULT_E_INVALID_DATA;
}
pScanEdge = pTempEdge;
@ -3269,7 +3269,7 @@ HRESULT CIsochartMesh::ScanAlongBoundayEdges(
if (pVertex == pStartVertex)
{
DPF(0, "Chart has more than 2 boundaries");
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
return HRESULT_E_INVALID_DATA;
}
pBoundaryEdge = pScanEdge;

Просмотреть файл

@ -50,9 +50,13 @@
#pragma clang diagnostic ignored "-Wswitch-enum"
#endif
#if defined(WIN32) || defined(WINAPI_FAMILY)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#pragma warning(push)
#pragma warning(disable : 4005)
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#define NODRAWTEXT
#define NOGDI
@ -64,6 +68,10 @@
#include <Windows.h>
#include <objbase.h>
#else
#include <wsl/winadapter.h>
#include <directx/d3d12.h>
#endif
#define _USE_MATH_DEFINES
#include <cmath>
@ -82,6 +90,11 @@
#include <vector>
#include <queue>
#ifndef WIN32
#include <mutex>
#include <thread>
#endif
#define _XM_NO_XMVECTOR_OVERLOADS_
#include <DirectXMath.h>
@ -102,3 +115,12 @@ extern void __cdecl UVAtlasDebugPrintf(unsigned int lvl, _In_z_ _Printf_format_s
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=nullptr; } }
#endif
// HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)
#define HRESULT_E_ARITHMETIC_OVERFLOW static_cast<HRESULT>(0x80070216L)
// HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)
#define HRESULT_E_NOT_SUPPORTED static_cast<HRESULT>(0x80070032L)
// HRESULT_FROM_WIN32(ERROR_INVALID_DATA)
#define HRESULT_E_INVALID_DATA static_cast<HRESULT>(0x8007000DL)