Giter Site home page Giter Site logo

microsoft / uvatlas Goto Github PK

View Code? Open in Web Editor NEW
799.0 80.0 144.0 1.67 MB

UVAtlas isochart texture atlas

Home Page: https://walbourn.github.io/uvatlas-return-of-the-isochart/

License: MIT License

C++ 98.42% CMake 1.56% PowerShell 0.02%
microsoft directx cpp-library texture-atlas uvatlas directxmesh directxtex

uvatlas's Introduction

DirectX Logo

UVAtlas - isochart texture atlasing

http://go.microsoft.com/fwlink/?LinkID=512686

Copyright (c) Microsoft Corporation.

February 21, 2024

This package contains UVAtlas, a shared source library for creating and packing an isochart texture atlas.

This code is designed to build with Visual Studio 2019 (16.11), Visual Studio 2022, clang for Windows v12 or later, or MinGW 12.2. Use of the Windows 10 May 2020 Update SDK (19041) or later is required for Visual Studio. It can also be built for Windows Subsystem for Linux using GCC 11 or later.

These components are designed to work without requiring any content from the legacy DirectX SDK. For details, see Where is the DirectX SDK?.

Directory Layout

  • Inc\

    • Public Header File (in the DirectX C++ namespace):

      • UVtlas.h
        • UVAtlasCreate
        • UVAtlasPartition
        • UVAtlasPack
        • UVAtlasComputeIMTFromPerVertexSignal
        • UVAtlasComputeIMTFromSignal
        • UVAtlasComputeIMTFromTexture
        • UVAtlasComputeIMTFromPerTexelSignal
        • UVAtlasApplyRemap
  • geodesics\, isochart\

    • Library source files
  • UVAtasTool\

    • Command line tool and sample for UVAtlas library
  • build\

    • Contains YAML files for the build pipelines along with some miscellaneous build files and scripts.

Documentation

Documentation is available on the GitHub wiki.

Notices

All content and source code for this package are subject to the terms of the MIT License.

For the latest version of UVAtlas, bug reports, etc. please visit the project site on GitHub.

Further reading

Zhou et al, "Iso-charts: Stretch-driven Mesh Parameterization using Spectral Analysis", Eurographics Symposium on Geometry Processing (2004) pdf

Sander et al. "Signal-Specialized Parametrization" Europgraphics 2002 pdf

Release Notes

  • Starting with the December 2020 release, this library makes use of typed enum bitmask flags per the recommendation of the C++ Standard section 17.5.2.1.3 Bitmask types. This is consistent with Direct3D 12's use of the DEFINE_ENUM_FLAG_OPERATORS macro. This may have breaking change impacts to client code:

    • You cannot pass the 0 literal as your option flags value. Instead you must make use of the appropriate default enum value: UVATLAS_DEFAULT or UVATLAS_IMT_DEFAULT.

    • Use the enum type instead of DWORD if building up flags values locally with bitmask operations. For example, UVATLAS options = UVATLAS_DEFAULT; if (...) options |= UVATLAS_GEODESIC_FAST;

  • The UWP projects and the Win10 classic desktop project include configurations for the ARM64 platform. Building these requires installing the ARM64 toolset.

  • When using clang/LLVM for the ARM64 platform, the Windows 11 SDK (22000) or later is required.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.

Thanks to Andrew Farrier and Scott Matloff for their on-going help with code reviews.

uvatlas's People

Contributors

dependabot[bot] avatar iamalsaher avatar jasjuang avatar jpetermugaas avatar walbourn avatar wurmd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

uvatlas's Issues

Export UV map in Numpy format

Given a 3D mesh model geometry, with only the vertices and faces in a format like the following, how can I generate the (H, W, 2) UV maps in Numpy or a format that can be read in python and converted to Numpy? (Do I even need the texture info, as mtl lines in the .obj file?)

The .obj file only has the faces and vertices in this way:
v 0.57735 -0.57735 -0.57735
v 0.57735 -0.57735 0.57735
v -0.57735 -0.57735 -0.57735

f 19 3 2
f 12 19 2
f 15 12 2

UVAtlasPartition generates NAN UVs when IMT is provided on input for certain meshes

I have noticed that when I provide tensors as input to UVAtlasPartition I sometimes get NAN UVs out. This only happens on some meshes, and seems to happen regardless of what the tensor values are (I even tried identity [1,0,1]).

For the purposes of getting something that I can actually share and to make debugging easier I progressively clipped triangles out of a mesh until the issue stopped occurring. Attached is the last iteration of the problem reproducing. The mesh as a result is a bit weird, and contains 3 islands of polygons. Deleting any island causes the issue to go away (I think the issue is related between the ratio between the smallest triangle and the total bounds of the mesh?).

The issue can be reproduced in UVAtlasTool in debug mode via uvatlastool -iv TEXCOORD bad_mesh2.obj which actually will throw an assert due to m_PixelWidth ending up as nan which causes an out of bounds vector index.

bad_mesh2.zip

Free 20% speed-up with simple #pragma omp parallel for

Adding to https://github.com/microsoft/UVAtlas/blob/master/CMakeLists.txt

# #pragma omp is used to specify Directives and Clauses. If /openmp is not specified in a compilation, the compiler ignores OpenMP clauses and directives
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/openmp>)

And to https://github.com/microsoft/UVAtlas/blob/master/UVAtlas/isochart/meshoptimizestretch.cpp#L387

-    for (size_t ii=0; ii<chartList.size(); ii++)
+#pragma omp parallel for
+    for (int ii = 0; ii < chartList.size(); ii++)
     {
         float fEii = chartList[ii]->m_fParamStretchL2;
         float faii = chartList[ii]->m_fChart2DArea;
-        bAllChartSatisfiedStretch =
+        bAllChartSatisfiedStretch =
             (bAllChartSatisfiedStretch && (fEii == faii));

-        fSumSqrtEiiaii += IsochartSqrtf(fEii * faii);
+        auto temp = IsochartSqrtf(fEii * faii); // For max speed-up
+#pragma atomic
+        fSumSqrtEiiaii += temp;

Gives a 20% speed up in a machine with 12 cores, for "free", since if the compiler doesn't accept the /openmp flag it should ignore the changes suggested here and proceed as normal single-threaded

I tried pull-requesting, but no permissions

SymmetricMatrix::GetEigen infinite loop

I am occasionally getting infinite loops in GetEigen() on certain assets (like 2 meshes out of several thousand). Sadly I can't share the meshes that I am seeing this on, but I am using the DirectXMesh functions for generating adjacency and running Clean as well. So it should be a nice clean+manifold mesh.

It looks like sometimes the tt variable in GetEigen ends up as zero, results in divide-by-zero and the resulting NaN values causes the loop to never meet the condition necessary to break.

I am going to continue to dig into this on my own, but wanted to post this issue early in case its already a known issue to someone.

Repro

  constexpr size_t dimension_count = 4;
  constexpr size_t max_range = 2;

  constexpr float test_matrix[dimension_count * dimension_count] = {
    0x1.887c48p+2, -0x1.d3ebfap+1, -0x1.7fb8fcp+0, -0x1.f4c058p-1,
    -0x1.d3ebfcp+1, 0x1.4213f6p+2, -0x1.2b4fap-4, -0x1.4dc2e2p+0,
    -0x1.7fb8fep+0, -0x1.2b4f6p-4, 0x1.633914p-1, 0x1.c1a2d4p-1,
    -0x1.f4c06p-1, -0x1.4dc2ep+0, 0x1.c1a2dp-1, 0x1.6751a8p+0,
  };

  float eigen_value[max_range] = {};
  float eigen_vector[dimension_count * max_range] = {};

  Isochart::CSymmetricMatrix<float>::GetEigen(
    dimension_count,
    test_matrix,
    eigen_value,
    eigen_vector,
    max_range
  );

Why UVAtlasCreate()'s Parameter "vMeshOutIndexBuffer" is type of uint8_t?

parameter:vMeshOutIndexBuffer is vector<uint8_t>, Is that mean the single value always below 256?

 HRESULT __cdecl UVAtlasCreate(
        _In_reads_(nVerts)                  const XMFLOAT3* positions,
        _In_                                size_t nVerts,
        _When_(indexFormat == DXGI_FORMAT_R16_UINT, _In_reads_bytes_(nFaces * 3 * sizeof(uint16_t)))
        _When_(indexFormat != DXGI_FORMAT_R16_UINT, _In_reads_bytes_(nFaces * 3 * sizeof(uint32_t))) const void* indices,
        _In_                                DXGI_FORMAT indexFormat,
        _In_                                size_t nFaces,
        _In_                                size_t maxChartNumber,
        _In_                                float maxStretch,
        _In_                                size_t width,
        _In_                                size_t height,
        _In_                                float gutter,
        _In_reads_(nFaces * 3)                const uint32_t* adjacency,
        _In_reads_opt_(nFaces * 3)            const uint32_t* falseEdgeAdjacency,
        _In_reads_opt_(nFaces * 3)            const float* pIMTArray,
        _In_opt_                            std::function<HRESULT __cdecl(float percentComplete)> statusCallBack,
        _In_                                float callbackFrequency,
        _In_                                UVATLAS options,
        _Inout_ std::vector<UVAtlasVertex>& vMeshOutVertexBuffer,
        _Inout_ std::vector<uint8_t>& vMeshOutIndexBuffer,
        _Inout_opt_ std::vector<uint32_t>* pvFacePartitioning = nullptr,
        _Inout_opt_ std::vector<uint32_t>* pvVertexRemapArray = nullptr,
        _Out_opt_                           float* maxStretchOut = nullptr,
        _Out_opt_                           size_t* numChartsOut = nullptr);

Retire VS 2017 support

Visual Studio 2017 reaches it's mainstream end-of-life on April 12, 2022. I should retire these projects that time:

  • UVAtlas_2017_Win10.vcxproj
  • UVAtlas_Windows10_2017.vcxproj
  • UVAtlasTool_2017.vcxproj

Along with all the associated test suite VS 2017 projects.

I am not sure when I'll be retiring Xbox One XDK support which is not supported for VS 2019 or later. That means I'm not sure if I'll delete UVAtlas_XboxOneXDK_2017.vcxproj or not with this change.

How to generate Multi-atlas ???

Hello, The UVAtlasCreate() only generate single atlas. Now how can i generate Multi-atlas?
Firstly, use UVAtlasPartition to Partition one mesh ; secondly, UVAtlasPack Partitions to multi-atlas?

Build with Unity iOS platform

I need to compile this library with unity for ios.
In my mind, there are two way to achive it:

1.take souce code to unity, then build together with ic2cpp.

C++source code plugins for IL2CPP

2.build static lib for unity.(use xcode build static lib)

Two ways not available now. Do you have any plan to support this?

Is there a way to keep existing UVs?

I have a model with existing UVs for texturing, but I want to calculate new UVs for lightmapping. That means I need to be able to keep the existing UVs. Is there a way to do that? It'd be nice if there were a way to end up with a model with 2 UV channels, one with the existing UVs and one with the new atlas UV coords.

Finish warning cleanup for clang LLVM

I cleaned up a lot of warnings in this pull request, but I ran out of time/steam to do them all. In the end, I set it to /W4 /Wpedantic /Wextra instead of /Wall /Wpedantic /Wextra.

This issue is to get back and do the rest of the warning cleanup to be able to use /Wall for clang/LLVM in CMakeLists.txt instead of /W4.

Primarily it's -Wold-style-cast and -Wsign-conversion warnings.

Retire Windows 8.1 Store and VS 2013 projects

At some point we should remove support for this older version in favor of UWP apps

UVatlas_Windows81.vcxproj

This would also be a good time to retire the VS 2013 complier support:

UVAtlas_2013.vcxproj

Please put any requests for continued support here.

Parameter `callbackFrequency` seems to have no effect

When calling UVAtlasCreate with a callback for a given mesh, the number of times the callback is called is always the same no matter callbackFrequency was given: about once per 1 ms.

Would it be a bug or something that I missed?

Compile to single DLL file

There are many files under compiled floder when I switch lib to dll.
Is there any way to compile into single DLL file?
I'm newbee in c++,thank you answer first.

How to make all baked objects have the same world scale?

I have injected UVAtlas into our project to generate lightmap uv, and after I have generated them all, their uv almost have the range [0, 1), no matter how big they are. Then I can not assignment them into lightmaps according to their size.
I wanna know if there is a way in UVAtlas to make all baked objects have a same world scale.If not, I have to write a uv generation code I think.

UVAtlas outputting invalid indexes with larger meshes

https://stackoverflow.com/questions/59973896/how-to-use-uvatlas-to-process-larger-meshes-65k-uint16

Adding the following test to https://github.com/walbourn/uvatlastest UVAtlas outputs an invalid number of indexes which fails this test (ib.size() / (sizeof(uint32_t) * 3)) != nFaces || facePart.size() != nFaces

bool Test11()
{
	wchar_t szPath[MAX_PATH] = { L"C:\\Users\\wurmd\\Work\\UVAtlas3\\Tests\\data\\John40K.obj" };

	std::unique_ptr<WaveFrontReader<uint32_t>> mesh(new WaveFrontReader<uint32_t>());
	mesh->Load(szPath);

	size_t nFaces = mesh->indices.size() / 3;
	size_t nVerts = mesh->vertices.size();

	std::unique_ptr<XMFLOAT3[]> pos(new XMFLOAT3[mesh->vertices.size()]);
	for (size_t j = 0; j < mesh->vertices.size(); ++j)
		pos[j] = mesh->vertices[j].position;
	std::unique_ptr<uint32_t[]> adj(new uint32_t[mesh->indices.size()]);
	memset(adj.get(), 0xff, sizeof(uint32_t) *  mesh->indices.size());
	GenerateAdjacencyAndPointReps(mesh->indices.data(), mesh->vertices.size() / 3, pos.get(), mesh->vertices.size(), 0.f, nullptr, adj.get());

	HRESULT hr;

	std::vector<UVAtlasVertex> vb;
	std::vector<uint8_t> ib;
	std::vector<uint32_t> facePart;
	std::vector<uint32_t> remap;
	float maxStretch = 0.f;
	size_t numCharts = 0;
	hr = UVAtlasCreate(pos.get(), mesh->vertices.size(), mesh->indices.data(), DXGI_FORMAT_R32_UINT, mesh->vertices.size() / 3,
		0, 0.f, 512, 512, 1.f,
		adj.get(), nullptr, nullptr, UVAtlasCallback, UVATLAS_DEFAULT_CALLBACK_FREQUENCY,
		UVATLAS_DEFAULT, vb, ib, &facePart, &remap, &maxStretch, &numCharts);

	if (FAILED(hr))
	{
		printe("\nERROR: create atlas failed (%08X)\n%S\n", hr, szPath);
	}
	else if (vb.size() < nVerts
		|| (ib.size() / (sizeof(uint32_t) * 3)) != nFaces
		|| facePart.size() != nFaces
		|| remap.size() != vb.size()
		|| !numCharts)
	{
		std::cout << "[ERROR] (vb.size() < nVerts || (ib.size() / (sizeof(uint32_t) * 3)) != nFaces || facePart.size() != nFaces || remap.size() != vb.size() || !numCharts)" << std::endl;
		std::cout << "        (" << vb.size() << " < " << nVerts << " || " << (ib.size() / (sizeof(uint32_t) * 3)) << " != " << nFaces << " || " << facePart.size() << " != " << nFaces << " || " << remap.size() << " != " << vb.size() << " || " << !numCharts << ")" << std::endl;
		printe("\nERROR: Unexpected results from create atlas:\n%S\n\tverts %zu\n\tfaces %zu (%zu bytes)\n\tface partitions %zu\n\tremap array %zu\n\tmaxStretch %f\n\tnumCharts %zu\n",
			szPath, vb.size(), nFaces, ib.size(), facePart.size(), remap.size(), maxStretch, numCharts);
	}
	else if (!IsValidVertexRemap(reinterpret_cast<const uint32_t*>(ib.data()), nFaces, remap.data(), vb.size(), true))
	{
		printe("\nERROR: Vertex remap invalid from create atlas:\n%S\n", szPath);
	}
	else if (!IsValidFacePartition(facePart.data(), nFaces, numCharts))
	{
		printe("\nERROR: Face partition invalid from create atlas:\n%S\n", szPath);
	}
	else if (!VerifyVertices(pos.get(), nVerts, vb.data(), remap.data(), vb.size()))
	{
		printe("\nERROR: Vertex data doesn't match remap:\n%S\n", szPath);
	}
	else
	{
		std::wstring msgs;
		hr = Validate(reinterpret_cast<const uint32_t*>(ib.data()), nFaces, vb.size(), nullptr, VALIDATE_DEFAULT, &msgs);
		if (FAILED(hr))
		{
			printe("\nERROR: Invalid index buffer from create atlas (%08X):\n%S\n%S\n", hr, szPath, msgs.c_str());
		}
	}

	return true;
}

Issue reproducible with this data: https://www.dropbox.com/s/0h9imgomldqipi4/John40K.zip?dl=0

Windows phone platform support

The UVAtlas library can be used to create content suited for Windows phone 8, but those tools are primarily Win32 desktop apps.

The UVAtlas library builds fine for Windows phone, but at the moment I don't provide vcxproj files for Windows phone 8 or Windows phone 8.1

Retire Windows Vista support

The library is written using Direct3D and Windows APIs that work on Windows Vista Service Pack 2 with KB971644 installed (a.k.a. the DirectX 11.0 Runtime). At this point, there's little need for Windows Vista support, and I don't really have any way to support or test such an ancient operating system.

Gutter usage

Great library, it works as I was hopping, thank you.
I am not sure if it's an issue or simply I do not know how to use it: I expect by setting the gutter parameter for ex to 2, that the atlas packing reserves an extra border of 2 pixels thickness around each chart. However when I draw the texture using the computed uv coordinates the charts are using the entire space (touche the limits of the image) without letting any space for me to fill in with the border pixels.
I feel I am missing something fundamental here, pls help.

Why 2 partitions in 1 iteration?

In the function CIsochartEngine::PartitionByGlobalAvgL2Stretch inside file isochartengine.cpp, there are 2 function calls to perform chart partition in the do while loop: one is ParameterizeChartsInHeapParallelized which calls pChart->Partition(), and the other one is GenerateNewChartsToParameterize which calls pChartWithMaxL2Stretch->Bipartition3D().

So my question is why calling 2 partitions in every 1 iteration of the do while loop. What if only Partition() or Bipartition3D() is called? And what's the difference between Partition() and Bipartition3D()?

Thanks.

[Question] isochartpartition parallelization

I'm working to further parallelize UVAtlas.
Reading the paper Zhou et al, "Iso-charts: Stretch-driven Mesh Parameterization using Spectral Analysis", Eurographics Symposium on Geometry Processing (2004), and inspecting the code.

The first step of the isochart algorithm is "1. Compute the surface spectral analysis, providing an initial parameterization"

80% of the current processing time is spent on this step, namely in CIsochartEngine::ParameterizeChartsInHeap(bCountParition, MaxChartNumber));
This function works on a chart heap (implemented based on a vector), going one by one doing the parameterization and if the results for that chart aren't good enough, splits it and adds the two child charts to the end of the heap

This seems to be a good candidate for parallellization.

Question: Are you aware of something in the algorithm that outright prevents this step from being parallelizable? (chart parameterization needs to be computed serially as they depend on each other?)

How to make consistent UV atlases?

I have 2 meshes that are very similar; they only differ in the positions and connectivity of a few vertices. However, the generated UV atlases from those 2 meshes are totally different: not only is the packing different, the partition is also very different. For example, the head is in a single chart from the partition of one mesh, but in the partition of the other mesh, the face is divided into 2 charts.

I wonder if there is a way to make consistent atlases from similar meshes. In other words, given 2 similar meshes, the partition should be roughly the same (cut from roughly the same locations), and the packing should put similar charts from the 2 meshes at roughly the same location in the UV space (e.g. the charts containing head are both placed at the top-left corners of the UV space of the 2 meshes).

Thanks!

crashes

trying to process this mesh results in a crash
this particular mesh is not looking nice, I submit this one as it is the smallest one I was able to reproduce the problem; there are many more crashing but are much larger; all of them are manifold, and free of any problems as much as I can tell
scene_mesh_texture.zip

any idea what the problem is?

loading an obj doesnt work

hi, im compiling the code or using the binary tool you provide: loading a obj file from assets: directxmeshmedia
impossible to load any obj file... indices and vertices are always 0....
i am sure im a loading the obj, in the debug ptr: wfReader is valid
any clue about what is going on ? thx

    WaveFrontReader<uint32_t> wfReader;
    HRESULT hr = wfReader.Load(szFilename, ccw);
    if (FAILED(hr))
        return hr;

    inMesh.reset(new (std::nothrow) Mesh);
    if (!inMesh)
        return E_OUTOFMEMORY;

    if (wfReader.indices.empty() || wfReader.vertices.empty()) <== always 0, 
        return E_FAIL;

Gutter helper

The function ID3DXTextureGutterHelper is not required, but can be useful for UVAtlas. It is not currently implemented as part of DirectXTex or DirectXMesh, and like UVAtlas itself combines elements of texture and mesh processing.

This could be useful functionality to consider adding to the library.

ID3DXTextureGutterHelper.ResampleTex was added in the DirectX SDK (August 2005) release.

This is required to implement the /rt switch for the uvatlas sample.

Is there a way to make charts aligned?

When I generate a UV atlas for a model it seems the charts are oriented randomly. It'd help if each chart was rotated to minimize its bounding box. That way the edges of square charts would end up aligned to texels, which would help with things like lightmapping.

Is there a way to do this? If not, can there be?

Reorganize header files to avoid header conflicts

I am in the middle of adding export and install into the CMakeLists and I noticed a problem. There's no sort of guard when including the headers. For example , it includes mathutils.h, this could be a problem if we install UVAtlas along with other open-source and system libraries because it's very possible that some other libraries might also have a header called mathutils.h as well. Would you be open to reorganizing the folder structure so that the code will include the headers like UVAtlas/mathutils.h? With this folder guard, it is guaranteed to not have conflict while installing it alongside with other open-source libraries. This is a common practice done by popular open-source libraries like OpenCV, PCL, CGAL, etc.

UVAtlas not using all available texture map space

For this OBJ https://www.dropbox.com/s/jydhp5qzechaxli/manual.obj?raw=1 (with mlt and image )

v   0.0  0.0  0.0
vt  0.0  0.0
vn -0.7  0.0  0.7

v   0.0 10.0  0.0
vt  0.0  1.0
vn -0.7  0.0  0.7

v  10.0  0.0 10.0
vt  0.585  0.0
vn  0.0  0.0  1.0 

v  10.0 10.0 10.0
vt  0.585  1.0
vn  0.0  0.0  1.0 

v  20.0  0.0  0.0
vt  1.0  0.0
vn  0.7  0.0  0.7

v  20.0 10.0  0.0
vt  1.0  1.0
vn  0.7  0.0  0.7

usemtl 2imagesconcatenated
f 1/1/1 3/3/3 2/2/2 
f 2/2/2 3/3/3 4/4/4
f 3/3/3 5/5/5 4/4/4 
f 4/4/4 5/5/5 6/6/6

That exemplifies a complete usage of the texture map thusly
manual

UVAtlas outputs

v 0 0 0
v 0 10 0
v 10 0 10
v 10 10 10
v 20 0 0
v 20 10 0
vt 0.000726879 0.999851
vt 0.000726938 0.5
vt 0.000727028 0.000148656
vt 0.354175 0.999851
vt 0.354175 0.5
vt 0.354175 0.000148698
vn -0.7 0 0.7
vn 0 0 1
vn 0.7 0 0.7
usemtl 2imagesconcatenated
f 1/6/1 3/5/2 2/3/1 
f 2/3/1 3/5/2 4/2/2 
f 3/5/2 5/4/3 4/2/2 
f 4/2/2 5/4/3 6/1/3 

manual obj_new

which only uses the left third of the texture space

[how to]How to input const uint32_t* adjacency

I know mesh base on vertex and triangle index, but where is adjacency from?

    HRESULT __cdecl UVAtlasCreate(
        _In_reads_(nVerts)                  const XMFLOAT3* positions,
        _In_                                size_t nVerts,
        _When_(indexFormat == DXGI_FORMAT_R16_UINT, _In_reads_bytes_(nFaces * sizeof(uint16_t)))
        _When_(indexFormat != DXGI_FORMAT_R16_UINT, _In_reads_bytes_(nFaces * sizeof(uint32_t))) const void* indices,
        _In_                                DXGI_FORMAT indexFormat,
        _In_                                size_t nFaces,
        _In_                                size_t maxChartNumber,
        _In_                                float maxStretch,
        _In_                                size_t width,
        _In_                                size_t height,
        _In_                                float gutter,
        _In_reads_(nFaces * 3)                const uint32_t* adjacency,
        _In_reads_opt_(nFaces * 3)            const uint32_t* falseEdgeAdjacency,
        _In_reads_opt_(nFaces * 3)            const float* pIMTArray,
        _In_opt_                            std::function<HRESULT __cdecl(float percentComplete)> statusCallBack,
        _In_                                float callbackFrequency,
        _In_                                UVATLAS options,
        _Inout_ std::vector<UVAtlasVertex>& vMeshOutVertexBuffer,
        _Inout_ std::vector<uint8_t>& vMeshOutIndexBuffer,
        _Inout_opt_ std::vector<uint32_t>* pvFacePartitioning = nullptr,
        _Inout_opt_ std::vector<uint32_t>* pvVertexRemapArray = nullptr,
        _Out_opt_                           float* maxStretchOut = nullptr,
        _Out_opt_                           size_t* numChartsOut = nullptr);

Portable version of UVAtlas ?

UVAtlas lib currently relies on Windows.h and DirectXMaths.h which are not available on non Windows platform.
Would a Pull Request replacing all call to Windows specific headers with Platform agnostic lib (glm, Eigen) and a cmake build system be accepted in this repo ?

add information on creating correct adjacency buffers

The current implementation assumes implicitly a specific order of the vertex index buffer and the adjacency buffer. However I haven't found any information on this within the existing documentation. To prevent that other struggle as much as I did, I suggest to replace the current description for adjacency by one similar to that:

adjacency: A 32-bit index array with nFaces * 3 entries containing the adjacent triangles for each face in a mesh. Be aware that the order of the adjacent triangles is prescribed by the vertex order of the index buffer. If a triangle is defined by the indices of v1 / v2 / v3, the corresponding adjacent triangles must share the edges v1v2/ v2v3/ v3v1. If no adjacent triangle exist the index must be set to uint32_t(-1).
Note: The adjacency buffer can be computed from mesh data using DirectXMesh

CMake error: string sub-command REPLACE requires at least four arguments

When I run

git clone https://github.com/microsoft/UVAtlas/
cd UVAtlas && mkdir build && cd build
cmake ..

The below error shows up

CMake Error at CMakeLists.txt:80 (string):
  string sub-command REPLACE requires at least four arguments.


CMake Error at CMakeLists.txt:85 (string):
  string sub-command REPLACE requires at least four arguments.

-- Configuring incomplete, errors occurred!

I am on Ubuntu 18.04, GCC 7.

I looked into the CMakeLists at line 80, and it seems /W3 and /W4 are windows specific compilation flags. Should we try to guard it with an if(MSVC)?

Internal error: Closed surface not correctly partitioned

When trying to call DirectX::UVAtlasCreate with a specific mesh, it consistently fails with a Closed surface not correctly partitioned error. I have uploaded an example project (including the data for the mesh in question) to replicate the issue here:
test_uvatlas.zip
The mesh is rather large, so UVAtlasComputeIMTFromTexture takes a few minutes to complete.

It works fine with other, simpler meshes.

Edit:
I've tried it with another large mesh and got the same error. I have no idea what to look for, otherwise I'd try to narrow it down. Also, DirectX::UVAtlasComputeIMTFromTexture can take a few hours to complete, I'm not sure if that's normal.

Nondeterministic results when run from multiple threads

In UVAtlasRepacker.cpp & meshoptimizestretch.cpp you use rand() which internally uses a global, shared seed state. This will produce nondeterministic results when calling UVAtlas from multiple threads at once, because the order of rand() calls from different threads becomes effectively random.

I recommend using C++ <random> with a local generator on the stack to fix this.

Retire support for VS 2015

In 2020, I plan to retire support for VS 2015. The following projects will be removed:

UVAtlas_2015
UVAtlas_2015_Win10
UVAtlas_Windows10_2015
UVAtlas_XboxOneXDK_2015
UVAtlasTool_2015

Please put any requests for continued support for one or more of these here.

Exposed C Interface

Exposed C Interface,please.
So we can call this library as real library from other language(example C#).

How can i re-adjust the UV mapping?

I have a model with a texture, then I remove some useless triangles of the model so that some area of the texture picture can be removed. And i want to compress the texture picture, I have to re-adjust the UV mapping of the model accordingly. How do i use the UVAtlas?maybe i should use the function "UVAtlasCreate"? (An urgent problem TT)

Build failure on manual link source code.(whitout vcpkg)

Reproduce:
operating system:Ubuntu

Link DirectX-Headers and DirectXMath source code instead of vcpkg,
add below code to "UVAtlas/CMakeLists.txt:line123:

line124:set(directx-headers_DIR /Users/user/Desktop/GithubDownload/DirectX-Headers-1.4.9/build)
line125:set(directxmath_DIR /Users/user/Desktop/GithubDownload/DirectXMath-jan2021/build/cmake)

Encountered the error below:

$ make ..
INFO: Using VCPKG for DirectX-Headers and DirectXMath.
CMake Warning (dev) at CMakeLists.txt:124 (find_package):
  Ignoring EXACT since no version is requested.
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Error at /home/user/GithubDownload/DirectX-Headers-1.4.9/build/directx-headers-config.cmake:27 (include):
  include could not find load file:

    /home/user/GithubDownload/DirectX-Headers-1.4.9/build/directx-headers-targets.cmake
Call Stack (most recent call first):
  CMakeLists.txt:124 (find_package)


CMake Warning (dev) at CMakeLists.txt:125 (find_package):
  Ignoring EXACT since no version is requested.
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Error at /home/user/GithubDownload/DirectXMath-jan2021/build/cmake/directxmath-config.cmake:27 (include):
  include could not find load file:

    /home/user/GithubDownload/DirectXMath-jan2021/build/cmake/DirectXMath-targets.cmake
Call Stack (most recent call first):
  CMakeLists.txt:125 (find_package)


-- Configuring incomplete, errors occurred!
See also "/home/user/GithubDownload/UVAtlas-apr2021/Build/CMakeFiles/CMakeOutput.log".

UVAtlas is quadratic in the number of boundaries

In the PrepareProcessing step, this loop

while (!m_currentChartHeap.empty())
will essentially run once per boundary. A bit below in the stack, this function
HRESULT CIsochartMesh::CalMinPathBetweenBoundaries(
will run, calculating the minimum path for each boundaries. Moreover, CalMinPathToOtherBoundary loops through all the vertices multiple times.

This makes the complexity of the prepare step O(number_of_boundaries * number_of_boundaries * number_of_vertices)

I have attached a mesh made out of ~150000 vertices and ~5000 boundaries (mostly composed of 0-area holes, but I don't think that matters). In this case the runtime of PrepareProcessing is unbearably slow (I let it run for 4hrs and it did not terminate). The flame graph looks something like this:

Screenshot from 2021-03-01 07-41-33

I might give a shot at fixing this myself, but I wanted to report this behavior for other users first.

mesh-clean.zip

Windows Subsystem for Linux support

After applying #32, microsoft/DirectXMesh#42, and microsoft/DirectXTex#158, I can successfully configure CMake but I ran into trouble compiling with the below error:

In file included from /home/jasjuang/UVAtlas/UVAtlas/geodesics/ApproximateOneToAll.cpp:10:0:
/home/jasjuang/UVAtlas/UVAtlas/pch.h:64:10: fatal error: Windows.h: No such file or directory
 #include <Windows.h>
          ^~~~~~~~~~~
compilation terminated.

Is UVAtlas intended for Windows only? or is there a way to configure it to make it work on Linux, more specifically Ubuntu 18.04, GCC 7?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.