From d13d83b1ffd1c8f31c5ce8c8b031a979183aeea4 Mon Sep 17 00:00:00 2001 From: Jcen <172036972@qq.com> Date: Tue, 1 Oct 2024 19:48:12 +0800 Subject: [PATCH] Initial commit --- .gitignore | 65 +- CMakeLists.txt | 113 +++ LICENSE.md | 21 + README.md | 42 + images/UVsInNegative.png | Bin 0 -> 12355 bytes images/concaveUVs.png | Bin 0 -> 14243 bytes images/reversedUVs.png | Bin 0 -> 74561 bytes images/udimIntersections.png | Bin 0 -> 18879 bytes images/unMappedFaces.png | Bin 0 -> 41909 bytes images/zeroAreaUVFaces.png | Bin 0 -> 49730 bytes include/ThreadPool.hpp | 98 +++ include/utils.hpp | 61 ++ meshChecker/CMakeLists.txt | 15 + meshChecker/README.md | 35 + meshChecker/src/meshChecker.cpp | 723 ++++++++++++++++++ meshChecker/src/meshChecker.hpp | 36 + uvChecker/CMakeLists.txt | 15 + uvChecker/README.md | 50 ++ uvChecker/python/removeUnassginedUVs.py | 109 +++ uvChecker/src/uvChecker.cpp | 545 +++++++++++++ uvChecker/src/uvChecker.hpp | 36 + uvOverlapChecker/CMakeLists.txt | 34 + uvOverlapChecker/README.md | 30 + .../src/bentleyOttmann/bentleyOttmann.cpp | 263 +++++++ .../src/bentleyOttmann/bentleyOttmann.hpp | 34 + uvOverlapChecker/src/bentleyOttmann/event.cpp | 32 + uvOverlapChecker/src/bentleyOttmann/event.hpp | 34 + .../src/bentleyOttmann/lineSegment.cpp | 124 +++ .../src/bentleyOttmann/lineSegment.hpp | 54 ++ uvOverlapChecker/src/bentleyOttmann/main.cpp | 88 +++ .../src/bentleyOttmann/point2D.cpp | 43 ++ .../src/bentleyOttmann/point2D.hpp | 28 + .../bentleyOttmann/testData/DataA-Table_1.csv | 22 + .../bentleyOttmann/testData/DataB-Table_1.csv | 21 + .../src/bentleyOttmann/testData/dataSet.cpp | 30 + .../src/bentleyOttmann/testData/dataSet.hpp | 17 + .../src/bentleyOttmann/vector2D.cpp | 41 + .../src/bentleyOttmann/vector2D.hpp | 19 + uvOverlapChecker/src/findUvOverlaps.cpp | 392 ++++++++++ uvOverlapChecker/src/findUvOverlaps.hpp | 57 ++ 40 files changed, 3294 insertions(+), 33 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 LICENSE.md create mode 100644 images/UVsInNegative.png create mode 100644 images/concaveUVs.png create mode 100644 images/reversedUVs.png create mode 100644 images/udimIntersections.png create mode 100644 images/unMappedFaces.png create mode 100644 images/zeroAreaUVFaces.png create mode 100644 include/ThreadPool.hpp create mode 100644 include/utils.hpp create mode 100644 meshChecker/CMakeLists.txt create mode 100644 meshChecker/README.md create mode 100644 meshChecker/src/meshChecker.cpp create mode 100644 meshChecker/src/meshChecker.hpp create mode 100644 uvChecker/CMakeLists.txt create mode 100644 uvChecker/README.md create mode 100644 uvChecker/python/removeUnassginedUVs.py create mode 100644 uvChecker/src/uvChecker.cpp create mode 100644 uvChecker/src/uvChecker.hpp create mode 100644 uvOverlapChecker/CMakeLists.txt create mode 100644 uvOverlapChecker/README.md create mode 100644 uvOverlapChecker/src/bentleyOttmann/bentleyOttmann.cpp create mode 100644 uvOverlapChecker/src/bentleyOttmann/bentleyOttmann.hpp create mode 100644 uvOverlapChecker/src/bentleyOttmann/event.cpp create mode 100644 uvOverlapChecker/src/bentleyOttmann/event.hpp create mode 100644 uvOverlapChecker/src/bentleyOttmann/lineSegment.cpp create mode 100644 uvOverlapChecker/src/bentleyOttmann/lineSegment.hpp create mode 100644 uvOverlapChecker/src/bentleyOttmann/main.cpp create mode 100644 uvOverlapChecker/src/bentleyOttmann/point2D.cpp create mode 100644 uvOverlapChecker/src/bentleyOttmann/point2D.hpp create mode 100644 uvOverlapChecker/src/bentleyOttmann/testData/DataA-Table_1.csv create mode 100644 uvOverlapChecker/src/bentleyOttmann/testData/DataB-Table_1.csv create mode 100644 uvOverlapChecker/src/bentleyOttmann/testData/dataSet.cpp create mode 100644 uvOverlapChecker/src/bentleyOttmann/testData/dataSet.hpp create mode 100644 uvOverlapChecker/src/bentleyOttmann/vector2D.cpp create mode 100644 uvOverlapChecker/src/bentleyOttmann/vector2D.hpp create mode 100644 uvOverlapChecker/src/findUvOverlaps.cpp create mode 100644 uvOverlapChecker/src/findUvOverlaps.hpp diff --git a/.gitignore b/.gitignore index e257658..3e0774e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,34 +1,33 @@ -# ---> C++ -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers +*.un~ *.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - +*.txt +tags +*.pyc +*.attr +*.DS_Store +.clang_complete +tags +ctags +build/ +*/vc/ +vc/ +*/xcode/ +xcode/ +*.sublime-project +*.sublime-workspace +uvChecker/.idea/ +uvChecker/cmake-build-debug/ +modules/ +plug-ins/ +.idea/ +.idea +cmake-build-debug/ +cmake-build-release/ +cmake-build-maya/ +cmake-build-maya_debug +cmake-build-maya_release +!CMakeLists.txt +.clang +sublimeBuild.bat +*ccls* +settings.json diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..e04bb0e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,113 @@ +cmake_minimum_required(VERSION 3.8) +project(CheckTools CXX) + +include(CMakeParseArguments) + +if(NOT MAYA_ROOT_DIR) + message(FATAL_ERROR "MAYA_ROOT_DIR must be set!") +else() + message(STATUS "Using MAYA_ROOT_DIR ${MAYA_ROOT_DIR}") +endif() + +add_library(Maya INTERFACE) +target_compile_features(Maya INTERFACE cxx_std_11) +set_target_properties(Maya PROPERTIES + INTERFACE_POSITION_INDEPENDENT_CODE ON + ) +target_compile_definitions(Maya INTERFACE + REQUIRE_IOSTREAM + _BOOL + ) +target_compile_options(Maya INTERFACE + $<$:pthread -Wall -Wextra -Wconversion -Wsign-conversion -pedantic> + $<$:/W4> + ) +# OS specific +if (WIN32) + target_compile_definitions(Maya INTERFACE NT_PLUGIN) + set(MAYA_INCLUDE_DIR ${MAYA_ROOT_DIR}/include) + set(MAYA_LIB_DIR ${MAYA_ROOT_DIR}/lib) + set(MAYA_PLUGIN_SUFFIX ".mll") +elseif (APPLE) + target_compile_definitions(Maya INTERFACE OSMac_) + set(MAYA_INCLUDE_DIR ${MAYA_ROOT_DIR}/include) + set(MAYA_LIB_DIR ${MAYA_ROOT_DIR}/Maya.app/Contents/MacOS) + set(MAYA_PLUGIN_SUFFIX ".bundle") +elseif (UNIX) + target_compile_definitions(Maya INTERFACE LINUX) + set(MAYA_INCLUDE_DIR ${MAYA_ROOT_DIR}/include) + set(MAYA_LIB_DIR ${MAYA_ROOT_DIR}/lib) + set(MAYA_PLUGIN_SUFFIX ".so") +else() + message(FATAL_ERROR "Operating system not supported") +endif() + +# find MPxCommand header +find_path(MPX_COMMAND_HEADER MPxCommand.h + PATH ${MAYA_INCLUDE_DIR}/maya + NO_DEFAULT_PATH + ) +if(MPX_COMMAND_HEADER) + message(STATUS "Header: MPxCommand.h - FOUND") +else() + message(FATAL_ERROR "Header: MPxCommand.h - NOT FOUND") +endif() + +target_include_directories(Maya SYSTEM INTERFACE ${MAYA_INCLUDE_DIR}) + +# find libs +set(MAYA_LIBS + Foundation + OpenMaya + OpenMayaAnim + OpenMayaFX + OpenMayaRender + OpenMayaUI +) + +foreach(MAYA_LIB ${MAYA_LIBS}) + find_library(LIB-${MAYA_LIB} ${MAYA_LIB} + PATH ${MAYA_LIB_DIR} + NO_DEFAULT_PATH) + if(LIB-${MAYA_LIB}) + message(STATUS "Library: ${MAYA_LIB} - FOUND") + else() + message(FATAL_ERROR "Library: ${MAYA_LIB} - NOT FOUND") + endif() + + target_link_libraries(Maya INTERFACE ${LIB-${MAYA_LIB}}) +endforeach() + +# add_maya_library +function(add_maya_library) + set(opt) + set(one NAME) + set(mul PRIVATE_SOURCE PUBLIC_SOURCE) + cmake_parse_arguments(ADD_MAYA_LIB "${opt}" "${one}" "${mul}" ${ARGN}) + + add_library(${ADD_MAYA_LIB_NAME} SHARED "") + target_link_libraries(${ADD_MAYA_LIB_NAME} PRIVATE Maya) + set_target_properties(${ADD_MAYA_LIB_NAME} PROPERTIES + PREFIX "" + SUFFIX ${MAYA_PLUGIN_SUFFIX} + $<$: LINK_FLAGS /export:initializePlugin /export:uninitializePlugin> + ) + target_sources(${ADD_MAYA_LIB_NAME} + PUBLIC + ${ADD_MAYA_LIB_PUBLIC_SOURCE} + PRIVATE + ${ADD_MAYA_LIB_PRIVATE_SOURCE} + ) +endfunction(add_maya_library) + +add_subdirectory(meshChecker) +add_subdirectory(uvChecker) +add_subdirectory(uvOverlapChecker) + + +if(MAYA_VERSION) + message(STATUS "MAYA_VERSION : ${MAYA_VERSION}") +else() + message(STATUS "MAYA_VERSION not set for install directory") +endif() +set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..874922c --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Michi Inoue + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 1139135..6cf384c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,44 @@ # CheckTools +Mesh/UV check commands for maya +## [meshChecker](https://github.com/minoue/CheckTools/blob/master/meshChecker/) +Mesh/Topology checker + +## [uvChecker](https://github.com/minoue/CheckTools/blob/master/uvChecker/) +General UV checker + +## [findUvOverlaps](https://github.com/minoue/CheckTools/blob/master/uvOverlapChecker/) +UV overlap checker based on the Bentley–Ottmann algorithm + + ⚠️ **Warning** ⚠️ +* Be sure to check if a mesh has no **unassigned UVs**, otherwise maya clashes. + +## GUI + +[ModelCheckerForMaya](https://github.com/minoue/ModelCheckerForMaya) + +## Build + +### Build requirements +C++11 + +### Linux/MacOS +``` +>git clone https://github.com/minoue/CheckTools +>cd CheckTools +>mkdir build +>cd build +>cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DMAYA_VERSION=2020 -DMAYA_ROOT_DIR=path_to_maya_directory ../ +>cmake --build . --config Release --target install +``` + +### Windows +eg. VS2019 and Maya2020 +``` +>git clone https://github.com/minoue/CheckTools +>cd CheckTools +>mkdir build +>cd build +>cmake -G "Visual Studio 16 2019" -DMAYA_VERSION=2020 -DMAYA_ROOT_DIR="C:\Program Files\Autodesk\Maya2020" ../ +>cmake --build . --config Release --target install +``` diff --git a/images/UVsInNegative.png b/images/UVsInNegative.png new file mode 100644 index 0000000000000000000000000000000000000000..57e33edc4fdf5c0fcfd0b0a8593ae681ebf48d67 GIT binary patch literal 12355 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

k)?ntt&}L|A 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∨f)wx()3BtLHh`7=Q&YOUo+TNxkrz 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 tI6}U~9UsMoa-$l^fY38T5^Dz3J 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 O=ZT!EY>D&>|NjDH!f#Ok literal 0 HcmV?d00001 diff --git a/images/zeroAreaUVFaces.png b/images/zeroAreaUVFaces.png new file mode 100644 index 0000000000000000000000000000000000000000..b4598d3233dd9d999c703af1327deffa19b3ba81 GIT binary patch literal 49730 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 literal 0 HcmV?d00001 diff --git a/include/ThreadPool.hpp b/include/ThreadPool.hpp new file mode 100644 index 0000000..4183203 --- /dev/null +++ b/include/ThreadPool.hpp @@ -0,0 +1,98 @@ +#ifndef THREAD_POOL_H +#define THREAD_POOL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class ThreadPool { +public: + ThreadPool(size_t); + template + auto enqueue(F&& f, Args&&... args) + -> std::future::type>; + ~ThreadPool(); +private: + // need to keep track of threads so we can join them + std::vector< std::thread > workers; + // the task queue + std::queue< std::function > tasks; + + // synchronization + std::mutex queue_mutex; + std::condition_variable condition; + bool stop; +}; + +// the constructor just launches some amount of workers +inline ThreadPool::ThreadPool(size_t threads) + : stop(false) +{ + for(size_t i = 0;i task; + + { + std::unique_lock lock(this->queue_mutex); + this->condition.wait(lock, + [this]{ return this->stop || !this->tasks.empty(); }); + if(this->stop && this->tasks.empty()) + return; + task = std::move(this->tasks.front()); + this->tasks.pop(); + } + + task(); + } + } + ); +} + +// add new work item to the pool +template +auto ThreadPool::enqueue(F&& f, Args&&... args) + -> std::future::type> +{ + using return_type = typename std::result_of::type; + + auto task = std::make_shared< std::packaged_task >( + std::bind(std::forward(f), std::forward(args)...) + ); + + std::future res = task->get_future(); + { + std::unique_lock lock(queue_mutex); + + // don't allow enqueueing after stopping the pool + if(stop) + throw std::runtime_error("enqueue on stopped ThreadPool"); + + tasks.emplace([task](){ (*task)(); }); + } + condition.notify_one(); + return res; +} + +// the destructor joins all threads +inline ThreadPool::~ThreadPool() +{ + { + std::unique_lock lock(queue_mutex); + stop = true; + } + condition.notify_all(); + for(std::thread &worker: workers) + worker.join(); +} + +#endif diff --git a/include/utils.hpp b/include/utils.hpp new file mode 100644 index 0000000..7181ddb --- /dev/null +++ b/include/utils.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include +#include + +#include +#include +#include + + +inline float getTriangleArea(float Ax, float Ay, float Bx, float By, float Cx, float Cy) +{ + return ((Ax * (By - Cy)) + (Bx * (Cy - Ay)) + (Cx * (Ay - By))) * 0.5F; +} + +enum class ResultType { + Face, + Vertex, + Edge, + UV +}; + +inline void createResultString(const MDagPath& dagPath, ResultType type, int index, std::string& outPath) +{ + outPath = std::string(dagPath.fullPathName().asChar()); + + switch (type) { + case ResultType::Face: { + outPath += ".f[" + std::to_string(index) + "]"; + break; + } + case ResultType::Vertex: { + outPath += ".vtx[" + std::to_string(index) + "]"; + break; + } + case ResultType::Edge: { + outPath += ".e[" + std::to_string(index) + "]"; + break; + } + case ResultType::UV: { + outPath += ".map[" + std::to_string(index) + "]"; + break; + } + } +} + +void buildHierarchy(const MDagPath& path, std::vector& result) +{ + + MString name; + + MItDag dagIter; + for (dagIter.reset(path, MItDag::kDepthFirst); !dagIter.isDone(); dagIter.next()) { + MObject obj = dagIter.currentItem(); + + if (obj.apiType() == MFn::kMesh) { + name = dagIter.fullPathName(); + result.push_back(name.asChar()); + } + } +} \ No newline at end of file diff --git a/meshChecker/CMakeLists.txt b/meshChecker/CMakeLists.txt new file mode 100644 index 0000000..9fc11f4 --- /dev/null +++ b/meshChecker/CMakeLists.txt @@ -0,0 +1,15 @@ +project(meshChecker CXX) + +add_maya_library(NAME ${PROJECT_NAME} + PRIVATE_SOURCE + src/meshChecker.cpp + src/meshChecker.hpp + ) + +if (WIN32) + set(MAYA_TARGET_TYPE RUNTIME) +else () + set(MAYA_TARGET_TYPE LIBRARY) +endif() +set(INSTALL_DIR ../plug-ins/${MAYA_VERSION}) +install(TARGETS ${PROJECT_NAME} ${MAYA_TARGET_TYPE} DESTINATION ${INSTALL_DIR}) \ No newline at end of file diff --git a/meshChecker/README.md b/meshChecker/README.md new file mode 100644 index 0000000..d9e0587 --- /dev/null +++ b/meshChecker/README.md @@ -0,0 +1,35 @@ +# MeshChecker +Mesh/Topology checker for my own + +## Check numbers +0. Triangles +1. Ngons +2. Non-manifold edges +3. Lamina faces +4. Bi-valent faces +5. Zero area faces +6. Mesh border edges +7. Crease edges +8. Zero length edges +9. Vertex pnts attributes +10. Empty geometry (geo with 0 vertices) +11. Instance shpaes +12. Channel connections + +## Flags +| Longname | Shortname | Argument types | Default | Properties | +|:---------|----------:|:--------------:|:-------:|:----------:| +|check|c|int||C| +|maxFaceaArea|mfa|float|0.00001|C| +|minEdgeLength|mel|float|0.000001|C| +|doFix|fix|bool|false|c| + +* 'fix' flag can be used for 'vertex pnts attribute' check + +## Example +```python +from maya import cmds +e = cmds.checkMesh("|pSphere1", c=0) +print e +[u'|pSphere1.f[360]', u'|pSphere1.f[361]', u'|pSphere1.f[362]', u'|pSphere1.f[363]', u'|pSphere1.f[364]', u'|pSphere1.f[365]', u'|pSphere1.f[366]', u'|pSphere1.f[367]', u'|pSphere1.f[368]', u'|pSphere1.f[369]', u'|pSphere1.f[370]', u'|pSphere1.f[371]', u'|pSphere1.f[372]', u'|pSphere1.f[373]', u'|pSphere1.f[374]', u'|pSphere1.f[375]', u'|pSphere1.f[376]', u'|pSphere1.f[377]', u'|pSphere1.f[378]', u'|pSphere1.f[379]', u'|pSphere1.f[380]', u'|pSphere1.f[381]', u'|pSphere1.f[382]', u'|pSphere1.f[383]', u'|pSphere1.f[384]', u'|pSphere1.f[385]', u'|pSphere1.f[386]', u'|pSphere1.f[387]', u'|pSphere1.f[388]', u'|pSphere1.f[389]', u'|pSphere1.f[390]', u'|pSphere1.f[391]', u'|pSphere1.f[392]', u'|pSphere1.f[393]', u'|pSphere1.f[394]', u'|pSphere1.f[395]', u'|pSphere1.f[396]', u'|pSphere1.f[397]', u'|pSphere1.f[398]', u'|pSphere1.f[399]'] +``` diff --git a/meshChecker/src/meshChecker.cpp b/meshChecker/src/meshChecker.cpp new file mode 100644 index 0000000..00f1192 --- /dev/null +++ b/meshChecker/src/meshChecker.cpp @@ -0,0 +1,723 @@ +#include "meshChecker.hpp" +#include "../../include/ThreadPool.hpp" +#include "../../include/utils.hpp" +#include "maya/MApiNamespace.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static const char* const pluginCommandName = "checkMesh"; +static const char* const pluginVersion = "2.3.0"; +static const char* const pluginAuthor = "Michi Inoue"; + +namespace { + +std::vector findTriangles(std::vector* paths) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + std::vector result; + std::string errorPath; + + unsigned int length = list.length(); + + MDagPath dagPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + MFnMesh mesh(dagPath); + int numPoly = mesh.numPolygons(); + + for (int j = 0; j < numPoly; j++) { + if (mesh.polygonVertexCount(j) == 3) { + createResultString(dagPath, ResultType::Face, j, errorPath); + result.push_back(errorPath); + } + } + } + return result; +} + +std::vector findNgons(std::vector* paths) +{ + + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + std::vector result; + std::string errorPath; + + unsigned int length = list.length(); + + MDagPath dagPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + MFnMesh mesh(dagPath); + int numPoly = mesh.numPolygons(); + + for (int i = 0; i < numPoly; i++) { + if (mesh.polygonVertexCount(i) >= 5) { + createResultString(dagPath, ResultType::Face, i, errorPath); + result.push_back(errorPath); + } + } + } + return result; +} + +std::vector findNonManifoldEdges(std::vector* paths) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + std::vector result; + std::string errorPath; + + unsigned int length = list.length(); + + MDagPath dagPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + + for (MItMeshEdge edgeIter(dagPath); !edgeIter.isDone(); edgeIter.next()) { + int face_count; + edgeIter.numConnectedFaces(face_count); + if (face_count > 2) { + createResultString(dagPath, ResultType::Edge, edgeIter.index(), errorPath); + result.push_back(errorPath); + } + } + } + return result; +} + +std::vector findLaminaFaces(std::vector* paths) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + std::vector result; + std::string errorPath; + + unsigned int length = list.length(); + + MDagPath dagPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + + for (MItMeshPolygon polyIter(dagPath); !polyIter.isDone(); polyIter.next()) { + if (polyIter.isLamina()) { + createResultString(dagPath, ResultType::Face, static_cast(polyIter.index()), errorPath); + result.push_back(errorPath); + } + } + } + return result; +} + +std::vector findBiValentFaces(std::vector* paths) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + std::vector result; + std::string errorPath; + + unsigned int length = list.length(); + + MDagPath dagPath; + + MIntArray connectedFaces; + MIntArray connectedEdges; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + + for (MItMeshVertex vtxIter(dagPath); !vtxIter.isDone(); vtxIter.next()) { + vtxIter.getConnectedFaces(connectedFaces); + vtxIter.getConnectedEdges(connectedEdges); + + if (connectedFaces.length() == 2 && connectedEdges.length() == 2) { + createResultString(dagPath, ResultType::Vertex, vtxIter.index(), errorPath); + result.push_back(errorPath); + } + } + } + return result; +} + +std::vector findZeroAreaFaces(std::vector* paths, double maxFaceArea) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + std::vector result; + std::string errorPath; + + unsigned int length = list.length(); + + MDagPath dagPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + + for (MItMeshPolygon polyIter(dagPath); !polyIter.isDone(); polyIter.next()) { + double area; + polyIter.getArea(area); + if (area < maxFaceArea) { + createResultString(dagPath, ResultType::Face, static_cast(polyIter.index()), errorPath); + result.push_back(errorPath); + } + } + } + return result; +} + +std::vector findMeshBorderEdges(std::vector* paths) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + std::vector result; + std::string errorPath; + + unsigned int length = list.length(); + + MDagPath dagPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + + for (MItMeshEdge edgeIter(dagPath); !edgeIter.isDone(); edgeIter.next()) { + if (edgeIter.onBoundary()) { + createResultString(dagPath, ResultType::Edge, edgeIter.index(), errorPath); + result.push_back(errorPath); + } + } + } + return result; +} + +std::vector findCreaseEdges(std::vector* paths) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + unsigned int length = list.length(); + + std::vector result; + std::string errorPath; + + MDagPath dagPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + MFnMesh mesh(dagPath); + + MUintArray edgeIds; + MDoubleArray creaseData; + mesh.getCreaseEdges(edgeIds, creaseData); + + unsigned int edgeIdLength = edgeIds.length(); + + for (unsigned int j = 0; j < edgeIdLength; j++) { + createResultString(dagPath, ResultType::Edge, static_cast(edgeIds[j]), errorPath); + result.push_back(errorPath); + } + } + return result; +} + +std::vector findZeroLengthEdges(std::vector* paths, double minEdgeLength) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + std::vector result; + std::string errorPath; + + unsigned int length = list.length(); + + MDagPath dagPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + for (MItMeshEdge edgeIter(dagPath); !edgeIter.isDone(); edgeIter.next()) { + double length; + edgeIter.getLength(length); + if (length < minEdgeLength) { + createResultString(dagPath, ResultType::Edge, static_cast(edgeIter.index()), errorPath); + result.push_back(errorPath); + } + } + } + return result; +} + +std::vector hasVertexPntsAttr(std::vector* paths) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + std::vector result; + + unsigned int length = list.length(); + + MDagPath dagPath; + + MStatus status; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + dagPath.extendToShape(); + MFnDagNode dagNode(dagPath); + MFnMesh mesh(dagPath); + MPlug pntsArray = mesh.findPlug("pnts", false); + MDataHandle dataHandle = pntsArray.asMDataHandle(); + MArrayDataHandle arrayDataHandle(dataHandle); + MDataHandle outputHandle; + + unsigned int numElements = arrayDataHandle.elementCount(); + + if (numElements == 0) { + continue; + } + + while (true) { + outputHandle = arrayDataHandle.outputValue(); + + const float3& xyz = outputHandle.asFloat3(); + + if (xyz[0] != 0.0) { + result.push_back(dagPath.fullPathName().asChar()); + break; + } + if (xyz[1] != 0.0) { + result.push_back(dagPath.fullPathName().asChar()); + break; + } + if (xyz[2] != 0.0) { + result.push_back(dagPath.fullPathName().asChar()); + break; + } + + // end of iterator + status = arrayDataHandle.next(); + if (status != MS::kSuccess) { + break; + } + } + pntsArray.destructHandle(dataHandle); + } + return result; +} + +std::vector isEmptyGeometry(std::vector* paths) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + std::vector result; + + unsigned int length = list.length(); + MDagPath dagPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + MFnMesh mesh(dagPath); + int numVerts = mesh.numVertices(); + if (numVerts == 0) { + result.push_back(dagPath.fullPathName().asChar()); + } + } + return result; +} + +std::vector findUnusedVertices(std::vector* paths) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + std::vector result; + std::string errorPath; + + unsigned int length = list.length(); + MDagPath dagPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + int edgeCount; + + for (MItMeshVertex vtxIter(dagPath); !vtxIter.isDone(); vtxIter.next()) { + vtxIter.numConnectedEdges(edgeCount); + + if (edgeCount == 0) { + createResultString(dagPath, ResultType::Vertex, vtxIter.index(), errorPath); + result.push_back(errorPath); + } + } + } + return result; +} + +std::vector findInstances(std::vector* paths) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + std::vector result; + std::string errorPath; + + unsigned int length = list.length(); + MDagPath dagPath; + MFnDagNode fnDag; + + for (unsigned int i=0; i < length; i++) { + list.getDagPath(i, dagPath); + fnDag.setObject(dagPath); + if (fnDag.isInstanced()) { + MObject mObj = fnDag.parent(0); + MFnDagNode dataParent(mObj); + MString instanceSource = dataParent.fullPathName(); + dagPath.pop(1); + MString hierarchyParent = dagPath.fullPathName(); + if (hierarchyParent != instanceSource) { + result.push_back(dagPath.fullPathName().asChar()); + } + } + } + + return result; +} + +std::vector findConnections(std::vector* paths) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + std::vector CON_LIST = { + "translateX", + "translateY", + "translateZ", + "rotateX", + "rotateY", + "rotateZ", + "rotateOrder", + "parentInverseMatrix", + "rotatePivot", + "rotatePivotTranslate" + }; + + std::vector result; + + unsigned int length = list.length(); + + MDagPath dagPath; + + for (unsigned int i=0; i < length; i++) { + + MPlugArray plugs; + + list.getDagPath(i, dagPath); + dagPath.pop(1); + MObject mObj = dagPath.node(); + MFnDependencyNode fnDep(mObj); + fnDep.getConnections(plugs); + unsigned int numPlugs = plugs.length(); + for (unsigned int j=0; j(check_value); + + // TODO check if exeds value + } else { + MGlobal::displayError("Check type required."); + return MS::kFailure; + } + + std::vector hierarchy; + buildHierarchy(path, hierarchy); + + // Number of threads to use + size_t numTasks = 8; + + // Split sub-vectors to pass to each thread + std::vector> splitGroups; + + splitGroups.resize(numTasks); + size_t n = hierarchy.size() / numTasks + 1; + size_t idCounter = 0; + for (size_t groupID = 0; groupID < numTasks; groupID++) { + splitGroups[groupID].reserve(n); + } + + for (size_t a = 0; a < numTasks; a++) { + for (size_t b = 0; b < n; b++) { + if (idCounter == hierarchy.size()) { + break; + } + splitGroups[a].emplace_back(hierarchy[idCounter]); + idCounter++; + } + } + + ThreadPool pool(8); + std::vector>> results; + + double maxFaceArea { 0.000001 }; + if (argData.isFlagSet("-maxFaceArea")) + argData.getFlagArgument("-maxFaceArea", 0, maxFaceArea); + + double minEdgeLength = 0.000001; + if (argData.isFlagSet("-minEdgeLength")) + argData.getFlagArgument("-minEdgeLength", 0, minEdgeLength); + + for (size_t i = 0; i < numTasks; i++) { + if (check_type == MeshCheckType::TRIANGLES) { + results.push_back(pool.enqueue(findTriangles, &splitGroups[i])); + } else if (check_type == MeshCheckType::NGONS) { + results.push_back(pool.enqueue(findNgons, &splitGroups[i])); + } else if (check_type == MeshCheckType::NON_MANIFOLD_EDGES) { + results.push_back(pool.enqueue(findNonManifoldEdges, &splitGroups[i])); + } else if (check_type == MeshCheckType::LAMINA_FACES) { + results.push_back(pool.enqueue(findLaminaFaces, &splitGroups[i])); + } else if (check_type == MeshCheckType::BI_VALENT_FACES) { + results.push_back(pool.enqueue(findBiValentFaces, &splitGroups[i])); + } else if (check_type == MeshCheckType::ZERO_AREA_FACES) { + results.push_back(pool.enqueue(findZeroAreaFaces, &splitGroups[i], maxFaceArea)); + } else if (check_type == MeshCheckType::MESH_BORDER) { + results.push_back(pool.enqueue(findMeshBorderEdges, &splitGroups[i])); + } else if (check_type == MeshCheckType::CREASE_EDGE) { + results.push_back(pool.enqueue(findCreaseEdges, &splitGroups[i])); + } else if (check_type == MeshCheckType::ZERO_LENGTH_EDGES) { + results.push_back(pool.enqueue(findZeroLengthEdges, &splitGroups[i], minEdgeLength)); + } else if (check_type == MeshCheckType::UNFROZEN_VERTICES) { + results.push_back(pool.enqueue(hasVertexPntsAttr, &splitGroups[i])); + } else if (check_type == MeshCheckType::EMPTY_GEOMETRY) { + results.push_back(pool.enqueue(isEmptyGeometry, &splitGroups[i])); + } else if (check_type == MeshCheckType::UNUSED_VERTICES) { + results.push_back(pool.enqueue(findUnusedVertices, &splitGroups[i])); + } else if (check_type == MeshCheckType::INSTANCE) { + results.push_back(pool.enqueue(findInstances, &splitGroups[i])); + } else if (check_type == MeshCheckType::CONNECTIONS) { + results.push_back(pool.enqueue(findConnections, &splitGroups[i])); + } else { + MGlobal::displayError("Invalid check number"); + return MS::kFailure; + } + } + + std::vector intermediateResult; + + for (auto&& result : results) { + std::vector temp = result.get(); + for (auto& r : temp) { + intermediateResult.push_back(r); + } + } + + MStringArray outputResult; + + for (std::string& path : intermediateResult) { + outputResult.append(path.c_str()); + } + + setResult(outputResult); + + return redoIt(); +} + +MStatus MeshChecker::redoIt() +{ + return MS::kSuccess; +} + +MStatus MeshChecker::undoIt() +{ + return MS::kSuccess; +} + +bool MeshChecker::isUndoable() const +{ + return false; +} + +void* MeshChecker::creator() +{ + return new MeshChecker; +} + +MSyntax MeshChecker::newSyntax() +{ + MSyntax syntax; + syntax.addArg(MSyntax::kString); + syntax.addFlag("-c", "-check", MSyntax::kUnsigned); + syntax.addFlag("-mfa", "-maxFaceArea", MSyntax::kDouble); + syntax.addFlag("-mel", "-minEdgeLength", MSyntax::kDouble); + syntax.addFlag("-fix", "-doFix", MSyntax::kBoolean); + return syntax; +} + +MStatus initializePlugin(MObject mObj) +{ + MStatus status; + + std::string version_str(pluginVersion); + std::string compile_date_str(__DATE__); + std::string compile_time_str(__TIME__); + std::string version(version_str + " / " + compile_date_str + " / " + compile_time_str); + + MFnPlugin fnPlugin(mObj, pluginAuthor, version.c_str(), "Any"); + + status = fnPlugin.registerCommand(pluginCommandName, MeshChecker::creator, MeshChecker::newSyntax); + if (!status) { + status.perror("registerCommand"); + return status; + } + + return MS::kSuccess; +} + +MStatus uninitializePlugin(MObject mObj) +{ + MStatus status; + + MFnPlugin fnPlugin(mObj); + + status = fnPlugin.deregisterCommand(pluginCommandName); + if (!status) { + status.perror("deregisterCommand"); + return status; + } + + return MS::kSuccess; +} diff --git a/meshChecker/src/meshChecker.hpp b/meshChecker/src/meshChecker.hpp new file mode 100644 index 0000000..8c34892 --- /dev/null +++ b/meshChecker/src/meshChecker.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include + +enum class MeshCheckType { + TRIANGLES = 0, + NGONS, + NON_MANIFOLD_EDGES, + LAMINA_FACES, + BI_VALENT_FACES, + ZERO_AREA_FACES, + MESH_BORDER, + CREASE_EDGE, + ZERO_LENGTH_EDGES, + UNFROZEN_VERTICES, + EMPTY_GEOMETRY, + UNUSED_VERTICES, + INSTANCE, + CONNECTIONS, + TEST +}; + +class MeshChecker final : public MPxCommand { +public: + static void* creator(); + static MSyntax newSyntax(); + + // command interface + MStatus doIt(const MArgList& argList) final; + MStatus undoIt() final; + MStatus redoIt() final; + bool isUndoable() const final; + +private: + MeshChecker(); +}; diff --git a/uvChecker/CMakeLists.txt b/uvChecker/CMakeLists.txt new file mode 100644 index 0000000..4703894 --- /dev/null +++ b/uvChecker/CMakeLists.txt @@ -0,0 +1,15 @@ +project(uvChecker CXX) + +add_maya_library(NAME ${PROJECT_NAME} + PRIVATE_SOURCE + src/uvChecker.cpp + src/uvChecker.hpp + ) + +if (WIN32) + set(MAYA_TARGET_TYPE RUNTIME) +else () + set(MAYA_TARGET_TYPE LIBRARY) +endif() +set(INSTALL_DIR ../plug-ins/${MAYA_VERSION}) +install(TARGETS ${PROJECT_NAME} ${MAYA_TARGET_TYPE} DESTINATION ${INSTALL_DIR}) \ No newline at end of file diff --git a/uvChecker/README.md b/uvChecker/README.md new file mode 100644 index 0000000..657df0c --- /dev/null +++ b/uvChecker/README.md @@ -0,0 +1,50 @@ +# UVChecker +Find general uv errors + +## Check Numbers + +### 0. Udim border intersections + +![](../images/udimIntersections.png) + +### 1. Unmapped polygon faces + +![](../images/unMappedFaces.png) + +### 2. Zero-area UV faces + +![](../images/zeroAreaUVFaces.png) + +### 3. Unassigned UVs + +![img]() + +### 4. UVs in negative space + +![](../images/UVsInNegative.png) + +### 5. Concave UV faces + +![](../images/concaveUVs.png) + +### 6. Reversed UVs + +![](../images/reversedUVs.png) + +## Flags +| Longname | Shortname | Argument types | Default | Properties | Description | +|:---------|----------:|:--------------:|:-------:|:----------:|:-----------:| +|check|c|integer||C|| +|uvArea|uva|double|0.000001|C|| +|uvSet|us|string|current uv set|C|Set what uv set you want to us| +|maxUvBorderDistance|muvd|double|0.0|C|Ignore UVs close to udims borders for "Udim border intersections" check| +|verbose|v|bool|False|C|| + + +## Example +```python +from maya import cmds +errors = cmds.checkUV("|pSphere1", c=0) +print errors +>>> [u'|pSphere1|pSphereShape1.map[19]', u'|pSphere1|pSphereShape1.map[20]', ...] +``` diff --git a/uvChecker/python/removeUnassginedUVs.py b/uvChecker/python/removeUnassginedUVs.py new file mode 100644 index 0000000..56a6901 --- /dev/null +++ b/uvChecker/python/removeUnassginedUVs.py @@ -0,0 +1,109 @@ +""" +Remove unassigned UVs +""" + +from maya import OpenMaya +from maya import cmds + + +def checkUnassignedUVs(): + + bads = [] + + sel = cmds.ls(sl=True, fl=True, long=True) + + if len(sel) == 0: + cmds.error("Nothing is selected") + return + + root = sel[0] + children = cmds.listRelatives(root, ad=True, type="mesh", fullPath=True) + + sel = OpenMaya.MSelectionList() + for i in children: + sel.add(i) + + # OpenMaya.MGlobal.getActiveSelectionList(sel) + dagPath = OpenMaya.MDagPath() + + for i in range(sel.length()): + + sel.getDagPath(i, dagPath) + + fnMesh = OpenMaya.MFnMesh(dagPath) + numAllUVs = fnMesh.numUVs() + + uvCounts = OpenMaya.MIntArray() + uvIds = OpenMaya.MIntArray() + fnMesh.getAssignedUVs(uvCounts, uvIds) + numAssignedUVs = len(set(uvIds)) + if numAllUVs != numAssignedUVs: + bads.append(dagPath.fullPathName()) + + return bads + + +def removeUnassignedUVs(): + sel = OpenMaya.MSelectionList() + OpenMaya.MGlobal.getActiveSelectionList(sel) + + if sel.length() == 0: + cmds.error('Nothing is selected') + return + + dagPath = OpenMaya.MDagPath() + sel.getDagPath(0, dagPath) + + fnMesh = OpenMaya.MFnMesh(dagPath) + uArray = OpenMaya.MFloatArray() + vArray = OpenMaya.MFloatArray() + fnMesh.getUVs(uArray, vArray) + + uvCounts = OpenMaya.MIntArray() + uvIds = OpenMaya.MIntArray() + fnMesh.getAssignedUVs(uvCounts, uvIds) + + # This is UVs that are actually assgined to the geometry + # So you have to keep UVs of those indices. + # Then you have to remove all non-assgined UVs(what we call ghost UVs) + oldUVIndicesSorted = sorted(list(set(uvIds))) + + # Remap old indices to new clean indices + # eg. [x, x, x, 3, x, x, 6, x, x, 9, x, ....] (x means unassigned UVs to be removed) + # | + # [3, 6, 9, ...] <- Remove Unassgined UVs and pack left UVs + # | + # [0, 1, 2, ...] <- Remap to clean order + + # Create new dict which key is old uv indices and value is new uv indices + # In the above example, { 3:0, 6:1, 9:2, .... } + uvMap = {} + for num, oldUVIndex in enumerate(oldUVIndicesSorted): + uvMap[oldUVIndex] = num + + # Replace old UV indices of each face to new UV indices + newUvIds = OpenMaya.MIntArray() + for i in uvIds: + newUvIds.append(uvMap[i]) + + # Construct u and v arrays using only assigned UVs + newUs = [uArray[i] for i in oldUVIndicesSorted] + newVs = [vArray[i] for i in oldUVIndicesSorted] + + # Convert python new uvArrays from python list to MFloatArray + newUArray = OpenMaya.MFloatArray() + newVArray = OpenMaya.MFloatArray() + for i in newUs: + newUArray.append(i) + for i in newVs: + newVArray.append(i) + + # Clear current uvSet and re-assgin new UV information + fnMesh.clearUVs() + fnMesh.setUVs(newUArray, newVArray) + fnMesh.assignUVs(uvCounts, newUvIds) + fnMesh.updateSurface() + + +if __name__ == "__main__": + removeUnassignedUVs() diff --git a/uvChecker/src/uvChecker.cpp b/uvChecker/src/uvChecker.cpp new file mode 100644 index 0000000..83cff00 --- /dev/null +++ b/uvChecker/src/uvChecker.cpp @@ -0,0 +1,545 @@ +#include "uvChecker.hpp" +#include "../../include/ThreadPool.hpp" +#include "../../include/utils.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static const char* const pluginCommandName = "checkUV"; +static const char* const pluginVersion = "2.1.3"; +static const char* const pluginAuthor = "Michi Inoue"; + +namespace { + +std::vector findUdimIntersections(std::vector* paths, const MString uvSet, const double maxUvBorderDistance) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + unsigned int length = list.length(); + + MDagPath dagPath; + MFnMesh mesh; + + std::vector result2; + std::string errorPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + mesh.setObject(dagPath); + std::vector indices; + + for (MItMeshPolygon mItPoly(dagPath); !mItPoly.isDone(); mItPoly.next()) { + int vCount = static_cast(mItPoly.polygonVertexCount()); + int currentUVindex; + int nextUVindex; + float u1, v1, u2, v2; + + for (int j = 0; j < vCount; j++) { + mItPoly.getUVIndex(j, currentUVindex, &uvSet); + + if (j == vCount - 1) { + mItPoly.getUVIndex(0, nextUVindex, &uvSet); + } else { + mItPoly.getUVIndex(j + 1, nextUVindex, &uvSet); + } + + mesh.getUV(currentUVindex, u1, v1, &uvSet); + mesh.getUV(nextUVindex, u2, v2, &uvSet); + + if (floor(u1) == floor(u2) && floor(v1) == floor(v2)) { + } else if ((maxUvBorderDistance == 0.0) + || ((fabs(rint(u1) - fabs(u1)) > maxUvBorderDistance) + && (fabs(rint(v1) - fabs(v1)) > maxUvBorderDistance) + && (fabs(rint(u2) - fabs(u2)) > maxUvBorderDistance) + && (fabs(rint(v2) - fabs(v2)) > maxUvBorderDistance))) { + indices.push_back(currentUVindex); + indices.push_back(nextUVindex); + } + } + } + // Remove duplicate elements + std::sort(indices.begin(), indices.end()); + indices.erase(std::unique(indices.begin(), indices.end()), indices.end()); + + for (auto& index : indices) { + createResultString(dagPath, ResultType::UV, index, errorPath); + result2.push_back(errorPath); + } + } + + return result2; +} + +std::vector findNoUvFaces(std::vector* paths, const MString uvSet) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + unsigned int length = list.length(); + MDagPath dagPath; + bool hasUVs; + std::vector result2; + std::string errorPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + for (MItMeshPolygon itPoly(dagPath); !itPoly.isDone(); itPoly.next()) { + hasUVs = itPoly.hasUVs(uvSet); + if (!hasUVs) { + createResultString(dagPath, ResultType::Face, static_cast(itPoly.index()), errorPath); + result2.push_back(errorPath); + } + } + } + return result2; +} + +std::vector findZeroUvFaces(std::vector* paths, const MString uvSet, const double minUVArea) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + unsigned int length = list.length(); + + MDagPath dagPath; + MFnMesh mesh; + + std::vector result2; + std::string errorPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + mesh.setObject(dagPath); + double area; + bool hasUVs; + for (MItMeshPolygon itPoly(dagPath); !itPoly.isDone(); itPoly.next()) { + hasUVs = itPoly.hasUVs(uvSet); + if (hasUVs) { + itPoly.getUVArea(area, &uvSet); + if (area < minUVArea) { + createResultString(dagPath, ResultType::Face, static_cast(itPoly.index()), errorPath); + result2.push_back(errorPath); + } + } + } + } + return result2; +} + +std::vector hasUnassignedUVs(std::vector* paths, const MString uvSet) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + unsigned int length = list.length(); + + MDagPath dagPath; + MFnMesh mesh; + + std::vector result2; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + mesh.setObject(dagPath); + + int numUVs = mesh.numUVs(uvSet); + MIntArray uvCounts; + MIntArray uvIds; + mesh.getAssignedUVs(uvCounts, uvIds, &uvSet); + unsigned int numUvIds = uvIds.length(); + + std::unordered_set uvIdSet; + for (unsigned int i = 0; i < numUvIds; i++) { + uvIdSet.insert(uvIds[i]); + } + + int numAssignedUVs = static_cast(uvIdSet.size()); + + if (numUVs != numAssignedUVs) { + result2.push_back(dagPath.fullPathName().asChar()); + } + } + return result2; +} + +std::vector findNegativeSpaceUVs(std::vector* paths, const MString uvSet) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + unsigned int length = list.length(); + + MDagPath dagPath; + MFnMesh mesh; + + std::vector result2; + std::string errorPath; + + MFloatArray uArray, vArray; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + mesh.setObject(dagPath); + mesh.getUVs(uArray, vArray, &uvSet); + + int numUVs = mesh.numUVs(uvSet); + + for (int j = 0; j < numUVs; j++) { + float& u = uArray[static_cast(j)]; + if (u < 0.0) { + createResultString(dagPath, ResultType::UV, j, errorPath); + result2.push_back(errorPath); + continue; + } + float& v = vArray[static_cast(j)]; + if (v < 0.0) { + createResultString(dagPath, ResultType::UV, j, errorPath); + result2.push_back(errorPath); + continue; + } + } + } + return result2; +} + +std::vector findConcaveUVs(std::vector* paths, const MString uvSet) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + unsigned int length = list.length(); + + MDagPath dagPath; + + std::vector result2; + std::string errorPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + std::vector indices; + + MPointArray points; + MIntArray vertexList; + + for (MItMeshPolygon itPoly(dagPath); !itPoly.isDone(); itPoly.next()) { + unsigned int polygonIndex = itPoly.index(); + itPoly.getTriangles(points, vertexList); + int numVerts = static_cast(itPoly.polygonVertexCount()); + int p1, p2, p3; + bool isReversed = itPoly.isUVReversed(); + + for (int i = 0; i < numVerts; i++) { + p1 = i; + p2 = i + 1; + p3 = i + 2; + + if (p2 > numVerts - 1) { + p2 -= numVerts; + } + if (p3 > numVerts - 1) { + p3 -= numVerts; + } + + float2 uv1; + float2 uv2; + float2 uv3; + + itPoly.getUV(p1, uv1, &uvSet); + itPoly.getUV(p2, uv2, &uvSet); + itPoly.getUV(p3, uv3, &uvSet); + + float S = getTriangleArea(uv1[0], uv1[1], uv2[0], uv2[1], uv3[0], uv3[1]); + + if (!isReversed) { + if (S <= 0.00000000001) { + indices.push_back(static_cast(polygonIndex)); + } + } else { + if (S >= -0.00000000001) { + indices.push_back(static_cast(polygonIndex)); + } + } + } + } + + for (auto& index : indices) { + createResultString(dagPath, ResultType::Face, index, errorPath); + result2.push_back(errorPath); + } + } + return result2; +} + +std::vector findReversedUVs(std::vector* paths, const MString uvSet) +{ + MSelectionList list; + + for (auto& p : *paths) { + MString mPath(p.c_str()); + list.add(mPath); + } + + unsigned int length = list.length(); + + MDagPath dagPath; + MFnMesh mesh; + + std::vector result2; + std::string errorPath; + + for (unsigned int i = 0; i < length; i++) { + list.getDagPath(i, dagPath); + mesh.setObject(dagPath); + + for (MItMeshPolygon itPoly(dagPath); !itPoly.isDone(); itPoly.next()) { + if (itPoly.isUVReversed(&uvSet)) { + createResultString(dagPath, ResultType::Face, static_cast(itPoly.index()), errorPath); + result2.push_back(errorPath); + } + } + } + return result2; +} + +} // unnamed namespace + +UvChecker::UvChecker() + : verbose(false) + , + // uvSet("map1"), + minUVArea(0.000001) + , maxUvBorderDistance(0.0) +{ +} + +UvChecker::~UvChecker() + = default; + +MSyntax UvChecker::newSyntax() +{ + MSyntax syntax; + syntax.addArg(MSyntax::kString); + syntax.addFlag("-v", "-verbose", MSyntax::kBoolean); + syntax.addFlag("-c", "-check", MSyntax::kUnsigned); + syntax.addFlag("-uva", "-uvArea", MSyntax::kDouble); + syntax.addFlag("-us", "-uvSet", MSyntax::kString); + syntax.addFlag("-muv", "-maxUvBorderDistance", MSyntax::kDouble); + return syntax; +} + +MStatus UvChecker::doIt(const MArgList& args) +{ + MStatus status; + + MSelectionList sel; + + MArgDatabase argData(syntax(), args); + + status = argData.getCommandArgument(0, sel); + + if (status != MS::kSuccess) { + MGlobal::displayError("You have to provide an object path"); + return MStatus::kFailure; + } + + MDagPath path; + sel.getDagPath(0, path); + + // argument parsing + UVCheckType check_type; + + if (argData.isFlagSet("-check")) { + unsigned int check_value; + argData.getFlagArgument("-check", 0, check_value); + + check_type = static_cast(check_value); + + // TODO check if exceeds value + } else { + MGlobal::displayError("Check type required."); + return MS::kFailure; + } + + if (argData.isFlagSet("-verbose")) + argData.getFlagArgument("-verbose", 0, verbose); + + if (argData.isFlagSet("-uvArea")) + argData.getFlagArgument("-uvArea", 0, minUVArea); + + if (argData.isFlagSet("-uvSet")) + argData.getFlagArgument("-uvSet", 0, uvSet); + else + // mesh.getCurrentUVSetName(uvSet); + uvSet = "map1"; + + if (argData.isFlagSet("-maxUvBorderDistance")) + argData.getFlagArgument("-maxUvBorderDistance", 0, maxUvBorderDistance); + + if (verbose) { + MString objectPath = "Selected mesh : " + path.fullPathName(); + MGlobal::displayInfo(objectPath); + } + + std::vector hierarchy; + buildHierarchy(path, hierarchy); + + // Number of threads to use + size_t numTasks = 8; + + // Split sub-vectors to pass to each thread + std::vector> splitGroups; + + splitGroups.resize(numTasks); + size_t n = hierarchy.size() / numTasks + 1; + size_t idCounter = 0; + for (size_t groupID = 0; groupID < numTasks; groupID++) { + splitGroups[groupID].reserve(n); + } + + for (size_t a = 0; a < numTasks; a++) { + for (size_t b = 0; b < n; b++) { + if (idCounter == hierarchy.size()) { + break; + } + splitGroups[a].emplace_back(hierarchy[idCounter]); + idCounter++; + } + } + + ThreadPool pool(8); + std::vector>> results; + + for (size_t i = 0; i < numTasks; i++) { + if (check_type == UVCheckType::UDIM) { + results.push_back(pool.enqueue(findUdimIntersections, &splitGroups[i], uvSet, maxUvBorderDistance)); + } else if (check_type == UVCheckType::HAS_UVS) { + results.push_back(pool.enqueue(findNoUvFaces, &splitGroups[i], uvSet)); + } else if (check_type == UVCheckType::ZERO_AREA) { + results.push_back(pool.enqueue(findZeroUvFaces, &splitGroups[i], uvSet, minUVArea)); + } else if (check_type == UVCheckType::UN_ASSIGNED_UVS) { + results.push_back(pool.enqueue(hasUnassignedUVs, &splitGroups[i], uvSet)); + } else if (check_type == UVCheckType::NEGATIVE_SPACE_UVS) { + results.push_back(pool.enqueue(findNegativeSpaceUVs, &splitGroups[i], uvSet)); + } else if (check_type == UVCheckType::CONCAVE_UVS) { + results.push_back(pool.enqueue(findConcaveUVs, &splitGroups[i], uvSet)); + } else if (check_type == UVCheckType::REVERSED_UVS) { + results.push_back(pool.enqueue(findReversedUVs, &splitGroups[i], uvSet)); + } else { + MGlobal::displayError("Invalid check number"); + return MS::kFailure; + } + } + + std::vector intermediateResult; + + for (auto&& result : results) { + std::vector temp = result.get(); + for (auto& r : temp) { + intermediateResult.push_back(r); + } + } + + MStringArray outputResult; + + for (std::string& path : intermediateResult) { + outputResult.append(path.c_str()); + } + + setResult(outputResult); + + return redoIt(); +} + +MStatus UvChecker::redoIt() +{ + return MS::kSuccess; +} + +MStatus UvChecker::undoIt() +{ + return MS::kSuccess; +} + +bool UvChecker::isUndoable() const +{ + return false; +} + +void* UvChecker::creator() +{ + return new UvChecker; +} + +MStatus initializePlugin(MObject mObj) +{ + MStatus status; + + std::string version_str(pluginVersion); + std::string compile_date_str(__DATE__); + std::string compile_time_str(__TIME__); + std::string version(version_str + " / " + compile_date_str + " / " + compile_time_str); + + MFnPlugin fnPlugin(mObj, pluginAuthor, version.c_str(), "Any"); + + status = fnPlugin.registerCommand(pluginCommandName, UvChecker::creator, UvChecker::newSyntax); + if (!status) { + status.perror("registerCommand"); + return status; + } + + return MS::kSuccess; +} + +MStatus uninitializePlugin(MObject mObj) +{ + MStatus status; + + MFnPlugin fnPlugin(mObj); + status = fnPlugin.deregisterCommand(pluginCommandName); + if (!status) { + status.perror("deregisterCommand"); + return status; + } + + return MS::kSuccess; +} diff --git a/uvChecker/src/uvChecker.hpp b/uvChecker/src/uvChecker.hpp new file mode 100644 index 0000000..d057d63 --- /dev/null +++ b/uvChecker/src/uvChecker.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include + +enum class UVCheckType { + UDIM = 0, + HAS_UVS, + ZERO_AREA, + UN_ASSIGNED_UVS, + NEGATIVE_SPACE_UVS, + CONCAVE_UVS, + REVERSED_UVS +}; + +class UvChecker final : public MPxCommand { +public: + UvChecker(); + ~UvChecker() final; + + // command interface + MStatus doIt(const MArgList& argList) final; + MStatus undoIt() final; + MStatus redoIt() final; + bool isUndoable() const final; + + static void* creator(); + static MSyntax newSyntax(); + +private: + bool verbose; + double minUVArea; + MString uvSet; + double maxUvBorderDistance; +}; diff --git a/uvOverlapChecker/CMakeLists.txt b/uvOverlapChecker/CMakeLists.txt new file mode 100644 index 0000000..f12d00f --- /dev/null +++ b/uvOverlapChecker/CMakeLists.txt @@ -0,0 +1,34 @@ +project(findUvOverlaps CXX) + +add_maya_library(NAME ${PROJECT_NAME} + PRIVATE_SOURCE + src/findUvOverlaps.cpp + src/findUvOverlaps.hpp + src/bentleyOttmann/bentleyOttmann.cpp + src/bentleyOttmann/bentleyOttmann.hpp + src/bentleyOttmann/event.hpp + src/bentleyOttmann/event.cpp + src/bentleyOttmann/lineSegment.hpp + src/bentleyOttmann/lineSegment.cpp + src/bentleyOttmann/point2D.hpp + src/bentleyOttmann/point2D.cpp + src/bentleyOttmann/vector2D.hpp + src/bentleyOttmann/vector2D.cpp + ) + +if (NOT APPLE) + find_package(OpenMP REQUIRED) + target_link_libraries( + ${PROJECT_NAME} + PRIVATE + OpenMP::OpenMP_CXX + ) +endif() + +if (WIN32) + set(MAYA_TARGET_TYPE RUNTIME) +else () + set(MAYA_TARGET_TYPE LIBRARY) +endif() +set(INSTALL_DIR ../plug-ins/${MAYA_VERSION}) +install(TARGETS ${PROJECT_NAME} ${MAYA_TARGET_TYPE} DESTINATION ${INSTALL_DIR}) \ No newline at end of file diff --git a/uvOverlapChecker/README.md b/uvOverlapChecker/README.md new file mode 100644 index 0000000..094aa5d --- /dev/null +++ b/uvOverlapChecker/README.md @@ -0,0 +1,30 @@ +## FindUvOverlaps +Find overlapped UVs. + +### Flags +| Longname | Shortname | Argument types | Default | Properties | +|:---------|----------:|:--------------:|:-------:|:----------:| +|verbose|v|bool|False|C| + +### Example + +```python +from maya import cmds +r = cmds.findUvOverlaps("|pSphere1") +print r +>>> [u'|pPlane1|pPlaneShape1.map[38]', u'|pPlane1|pPlaneShape1.map[39]', ....] +``` + +For multiple object check, select multiple objects and just run the command without path argument. + +```python +cmds.findUvOverlaps() +``` + +* Single object selected or object path specified as command argment + + Image + +* Multiple object selected + + Image diff --git a/uvOverlapChecker/src/bentleyOttmann/bentleyOttmann.cpp b/uvOverlapChecker/src/bentleyOttmann/bentleyOttmann.cpp new file mode 100644 index 0000000..93f7b7f --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/bentleyOttmann.cpp @@ -0,0 +1,263 @@ +// +// bentleyOttmann.cpp +// bentleyOttmann +// + +#include "bentleyOttmann.hpp" +#include +#include + +BentleyOttmann::BentleyOttmann(std::vector& edgeVector) : edges(edgeVector) +{ +} + +BentleyOttmann::~BentleyOttmann() += default; + +BentleyOttmann BentleyOttmann::operator+(const BentleyOttmann& rhs) const +{ + // Create new BentleyOttmann object + size_t newSize = this->edges.size() + rhs.edges.size(); + std::vector AB; + AB.reserve(newSize); + AB.insert(AB.end(), this->edges.begin(), this->edges.end()); + AB.insert(AB.end(), rhs.edges.begin(), rhs.edges.end()); + + BentleyOttmann newBO(AB); + + return newBO; +} + +void BentleyOttmann::createNewEvent(LineSegment* lineA, LineSegment* lineB) +{ + float x, y; + lineUtils::getIntersectionPoint(*lineA, *lineB, x, y); + Point2D p(x, y, 0); + Event crossEvent(2, lineA, lineB, p); + eventQueue.insert(crossEvent); +} + +void BentleyOttmann::check(std::vector &result) +{ + resultPtr = &result; + + for (auto & edge : edges) { + Event ev1(0, &edge, edge.begin); + Event ev2(1, &edge, edge.end); + eventQueue.insert(ev1); + eventQueue.insert(ev2); + } + + statusPtrQueue.reserve(edges.size()); + + while (true) { + if (eventQueue.empty()) { + break; + } + + Event firstEvent = *eventQueue.begin(); + eventQueue.erase(eventQueue.begin()); + + switch (firstEvent.eventType) { + case Event::BEGIN: + doBegin(firstEvent); + break; + case Event::END: + doEnd(firstEvent); + break; + case Event::CROSS: + doCross(firstEvent); + break; + default: + break; + } + } +} + +bool BentleyOttmann::doBegin(Event& ev) +{ + LineSegment* currentEdgePtr = ev.edgePtrA; + statusPtrQueue.emplace_back(currentEdgePtr); + + if (statusPtrQueue.size() <= 1) { + return false; + } + + // Set crossing point of Y for all edges in the statusQueue and the sweepline + for (auto ePtr : statusPtrQueue) { + if (ePtr->isHorizontal) { + // If the edge is horizontal, y of corrsing point is always y + // as sweepline moves from left to right + ePtr->crossingPointY = ePtr->begin.y; + } else if (ePtr->isVertical) { + // if the edge is vertical, the edge and sweepline are collinear, so + // use y of a mid point instread + float mid = (ePtr->begin.y + ePtr->end.y) * 0.5F; + ePtr->crossingPointY = mid; + } else { + // otherwise, find y value of crossing point of the edge and sweepline + float slope2 = (ePtr->end.y - ePtr->begin.y) / (ePtr->end.x - ePtr->begin.x); + float b2 = ePtr->begin.y - slope2 * ePtr->begin.x; + float y2 = slope2 * ev.sweepline + b2; + ePtr->crossingPointY = y2; + } + } + std::sort(statusPtrQueue.begin(), statusPtrQueue.end(), EdgeCrossingComparator()); + + // StatusQueue was sorted so you have to find the edge added to the queue above and find its index + auto foundIter = std::find(statusPtrQueue.begin(), statusPtrQueue.end(), + currentEdgePtr); + if (foundIter == statusPtrQueue.end()) { + return false; + } + + // Get currentEdge object from the statusQueue after sorted + size_t index = static_cast(std::distance(statusPtrQueue.begin(), foundIter)); + + if (foundIter == statusPtrQueue.begin()) { + LineSegment* targetEdge = statusPtrQueue[index + 1]; + if (*(*foundIter) * *(targetEdge)) { + resultPtr->emplace_back(*(*foundIter)); + resultPtr->emplace_back(*targetEdge); + createNewEvent(currentEdgePtr, targetEdge); + } + } + else if (foundIter == statusPtrQueue.end() - 1) { + LineSegment* targetEdge = statusPtrQueue[index - 1]; + if (*(*foundIter) * *(targetEdge)) { + resultPtr->emplace_back(*(*foundIter)); + resultPtr->emplace_back(*targetEdge); + createNewEvent(currentEdgePtr, targetEdge); + } + } + else { + LineSegment* nextEdgePtr = statusPtrQueue[index + 1]; + LineSegment* previousEdgePtr = statusPtrQueue[index - 1]; + if (*(*foundIter) * *(nextEdgePtr)) { + resultPtr->emplace_back(*(*foundIter)); + resultPtr->emplace_back(*nextEdgePtr); + createNewEvent(currentEdgePtr, nextEdgePtr); + } + if (*(*foundIter) * *(previousEdgePtr)) { + resultPtr->emplace_back(*(*foundIter)); + resultPtr->emplace_back(*previousEdgePtr); + createNewEvent(currentEdgePtr, previousEdgePtr); + } + } + return true; +} + +bool BentleyOttmann::doEnd(Event& ev) +{ + LineSegment* currentEdgePtr = ev.edgePtrA; + auto foundIter = std::find(statusPtrQueue.begin(), statusPtrQueue.end(), currentEdgePtr); + + if (foundIter == statusPtrQueue.end()) { + // if iter not found + std::cout << "Not found" << std::endl; + return false; + } + + if (foundIter == statusPtrQueue.begin() || foundIter == statusPtrQueue.end() - 1) { + + } + else { + size_t index = static_cast(std::distance(statusPtrQueue.begin(), foundIter)); + LineSegment* nextEdgePtr = statusPtrQueue[index + 1]; + LineSegment* previousEdgePtr = statusPtrQueue[index - 1]; + bool isCrossing = (*nextEdgePtr) * (*previousEdgePtr); + if (isCrossing) { + resultPtr->emplace_back(*previousEdgePtr); + resultPtr->emplace_back(*nextEdgePtr); + createNewEvent(nextEdgePtr, previousEdgePtr); + } + } + + // Remove current edge from the statusQueue + statusPtrQueue.erase(foundIter); + + return true; +} + +bool BentleyOttmann::doCross(Event& ev) +{ + if (statusPtrQueue.size() <= 2) { + return false; + } + + LineSegment* edgePtr = ev.edgePtrA; + LineSegment* otherEdgePtr = ev.edgePtrB; + + auto lineAPtrIter = std::find(statusPtrQueue.begin(), statusPtrQueue.end(), + edgePtr); + auto lineBPtrIter = std::find(statusPtrQueue.begin(), statusPtrQueue.end(), + otherEdgePtr); + if (lineAPtrIter == statusPtrQueue.end() || lineBPtrIter == statusPtrQueue.end()) { + return false; + } + + size_t lineAIndex = static_cast(std::distance(statusPtrQueue.begin(), lineAPtrIter)); + size_t lineBIndex = static_cast(std::distance(statusPtrQueue.begin(), lineBPtrIter)); + size_t small, big; + + if (lineAIndex > lineBIndex) { + small = lineBIndex; + big = lineAIndex; + } + else { + small = lineAIndex; + big = lineBIndex; + } + + if (small == 0) { + // Check the first edge and the one after next edge + + // If If the second edge is the last element of the statusQueue, then there is + // no edge to be checked with the first edge + if (statusPtrQueue.size() == static_cast(big) + 1) { + return false; + } + + LineSegment* lineAPtr = statusPtrQueue[small]; + LineSegment* lineBPtr = statusPtrQueue[big + 1]; + bool isCrossing = (*lineAPtr) * (*lineBPtr); + if (isCrossing) { + resultPtr->emplace_back(*lineAPtr); + resultPtr->emplace_back(*lineBPtr); + createNewEvent(lineAPtr, lineBPtr); + } + } + else if (big == statusPtrQueue.size() - 1) { + // Check the last edge and the one before the previous edge + + LineSegment* lineAPtr = statusPtrQueue[small - 1]; + LineSegment* lineBPtr = statusPtrQueue[big]; + bool isCrossing = (*lineAPtr) * (*lineBPtr); + if (isCrossing) { + resultPtr->emplace_back(*lineAPtr); + resultPtr->emplace_back(*lineBPtr); + createNewEvent(lineAPtr, lineBPtr); + } + } + else { + // Check the first edge and the one after next(third) + LineSegment* lineAPtr = statusPtrQueue[small - 1]; + LineSegment* lineBPtr = statusPtrQueue[big]; + bool isCrossing = (*lineAPtr) * (*lineBPtr); + if (isCrossing) { + resultPtr->emplace_back(*lineAPtr); + resultPtr->emplace_back(*lineBPtr); + createNewEvent(lineAPtr, lineBPtr); + } + // Check the second edge and the one after next(forth) + LineSegment* lineCPtr = statusPtrQueue[small]; + LineSegment* lineDPtr = statusPtrQueue[big + 1]; + isCrossing = (*lineCPtr) * (*lineDPtr); + if (isCrossing) { + resultPtr->emplace_back(*lineCPtr); + resultPtr->emplace_back(*lineDPtr); + createNewEvent(lineCPtr, lineDPtr); + } + } + return false; +} diff --git a/uvOverlapChecker/src/bentleyOttmann/bentleyOttmann.hpp b/uvOverlapChecker/src/bentleyOttmann/bentleyOttmann.hpp new file mode 100644 index 0000000..c760e4d --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/bentleyOttmann.hpp @@ -0,0 +1,34 @@ +// +// bentleyOttmann.hpp +// bentleyOttmann +// + +#pragma once + +#include "event.hpp" +#include "lineSegment.hpp" + +#include +#include +#include + +class BentleyOttmann { +public: + explicit BentleyOttmann(std::vector& edgeVector); + ~BentleyOttmann(); + + void check(std::vector &result); + std::vector edges; + + BentleyOttmann operator+(const BentleyOttmann& rhs) const; + +private: + std::vector *resultPtr{}; + bool doBegin(Event& ev); + bool doEnd(Event& ev); + bool doCross(Event& ev); + void createNewEvent(LineSegment* lineA, LineSegment* lineB); + + std::vector statusPtrQueue; + std::multiset eventQueue; +}; diff --git a/uvOverlapChecker/src/bentleyOttmann/event.cpp b/uvOverlapChecker/src/bentleyOttmann/event.cpp new file mode 100644 index 0000000..1441385 --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/event.cpp @@ -0,0 +1,32 @@ +// +// event.cpp +// bentleyOttmann +// + +#include "event.hpp" + +Event::Event() = default; + +Event::Event(int eventType, LineSegment* edgePtrA, const Point2D& point) + : eventType(eventType) + , edgePtrA(edgePtrA) + , eventPoint(point) + , sweepline(point.x) +{ +} + +Event::Event(int eventType, LineSegment* edgePtrA, LineSegment* edgePtrB, const Point2D& point) + : eventType(eventType) + , edgePtrA(edgePtrA) + , edgePtrB(edgePtrB) + , eventPoint(point) + , sweepline(point.x) +{ +} + +Event::~Event() = default; + +bool Event::operator<(const Event& rhs) const +{ + return this->eventPoint < rhs.eventPoint; +} diff --git a/uvOverlapChecker/src/bentleyOttmann/event.hpp b/uvOverlapChecker/src/bentleyOttmann/event.hpp new file mode 100644 index 0000000..c7e8252 --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/event.hpp @@ -0,0 +1,34 @@ +// +// event.hptp +// bentleyOttmann +// + +#pragma once + +#include "lineSegment.hpp" +#include "point2D.hpp" +#include + +class Event { +public: + Event(); + Event(int eventType, LineSegment* edgePtrA, const Point2D& point); + Event(int eventType, LineSegment* edgePtrA, LineSegment* edgePtrB, const Point2D& point); + ~Event(); + + int eventType{}; + LineSegment *edgePtrA{}, *edgePtrB{}; + Point2D eventPoint; + int index{}; + float sweepline{}; + + bool operator<(const Event& rhs) const; + + enum EVENT_TYPE { + BEGIN, + END, + CROSS + }; + +private: +}; diff --git a/uvOverlapChecker/src/bentleyOttmann/lineSegment.cpp b/uvOverlapChecker/src/bentleyOttmann/lineSegment.cpp new file mode 100644 index 0000000..8aa6b2e --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/lineSegment.cpp @@ -0,0 +1,124 @@ +// +// lineSegment.cpp +// bentleyOttmann +// + +#include "lineSegment.hpp" +#include +#include + +LineSegment::LineSegment() +{ +} + +LineSegment::LineSegment(Point2D p1, Point2D p2, const char* groupId) : groupId(groupId) +{ + if (p1 < p2) { + this->begin = p1; + this->end = p2; + this->index = std::make_pair(p1.index, p2.index); + } else { + this->begin = p2; + this->end = p1; + this->index = std::make_pair(p2.index, p1.index); + } + if (p1.x == p2.x) { + this->isVertical = true; + this->isHorizontal = false; + } else if (p1.y == p2.y) { + this->isVertical = false; + this->isHorizontal = true; + } + else { + this->isVertical = false; + this->isHorizontal = false; + } + +} + +LineSegment::~LineSegment() +{ +} + +bool LineSegment::operator==(const LineSegment& rhs) const +{ + return (this->begin == rhs.begin && this->end == rhs.end); +} + +float LineSegment::getTriangleArea(float Ax, float Ay, float Bx, float By, float Cx, float Cy) const +{ + return ((Ax * (By - Cy)) + (Bx * (Cy - Ay)) + (Cx * (Ay - By))) * 0.5F; +} + +bool LineSegment::sameSigns(const float x, const float y) const +{ + return (x >= 0) ^ (y < 0); +} + +bool LineSegment::operator*(const LineSegment& rhs) const +{ + // Check if two edges are on a same line + float t1 = getTriangleArea(this->begin.x, this->begin.y, rhs.begin.x, rhs.begin.y, this->end.x, this->end.y); + float t2 = getTriangleArea(this->begin.x, this->begin.y, rhs.end.x, rhs.end.y, this->end.x, this->end.y); + float t3 = getTriangleArea(rhs.begin.x, rhs.begin.y, this->begin.x, this->begin.y, rhs.end.x, rhs.end.y); + float t4 = getTriangleArea(rhs.begin.x, rhs.begin.y, this->end.x, this->end.y, rhs.end.x, rhs.end.y); + + if (t1 == 0 && t2 == 0 && t3 == 0 && t4 == 0) { + // Two lines are on a same line + Vector2D v1 = rhs.end - this->begin; + Vector2D v2 = rhs.begin - this->end; + v1.normalize(); + v2.normalize(); + float dot = v1 * v2; + if (dot >= 0) { + return false; + } else { + return true; + } + } + + if (t1 * t2 == 0 || t3 * t4 == 0) + return false; + + bool ccw1 = sameSigns(t1, t2); + bool ccw2 = sameSigns(t3, t4); + + if (ccw1 == false && ccw2 == false) { + return true; + } else { + return false; + } +} + +namespace lineUtils { +void getIntersectionPoint(const LineSegment& lineA, const LineSegment& lineB, float& x, float& y) +{ + + // Y = AX + B + float a1 = (lineA.end.y - lineA.begin.y) / (lineA.end.x - lineA.begin.x); + float a2 = (lineB.end.y - lineB.begin.y) / (lineB.end.x - lineB.begin.x); + float b1 = lineA.begin.y - (a1 * lineA.begin.x); + float b2 = lineB.begin.y - (a2 * lineB.begin.x); + + a1 = -1.0F * a1; + a2 = -1.0F * a2; + + // Matrix + // | (-a1) 1 || X | = | b1 | + // | (-a2) 1 || Y | = | b2 | + + float adbc = a1 - a2; + + // Get inverse matrix + + float a = 1.0F * (1.0F / adbc); + float b = -a2 * (1.0F / adbc); + float c = -1.0F * (1.0F / adbc); + float d = a1 * (1.0F / adbc); + + // [u] = [ a c ] [y_interceptA] + // [v] [ b d ] [y_interceptB] + x = (a * b1) + (c * b2); + y = (b * b1) + (d * b2); +} +} diff --git a/uvOverlapChecker/src/bentleyOttmann/lineSegment.hpp b/uvOverlapChecker/src/bentleyOttmann/lineSegment.hpp new file mode 100644 index 0000000..5e8bec9 --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/lineSegment.hpp @@ -0,0 +1,54 @@ +// +// lineSegment.hpp +// bentleyOttmann +// + +#pragma once + + +#include "point2D.hpp" +#include +#include + +class LineSegment { +public: + LineSegment(); + LineSegment(Point2D p1, Point2D p2, const char* groupId); + ~LineSegment(); + Point2D begin; + Point2D end; + float crossingPointY; + std::pair index; + const char* groupId; + + bool operator==(const LineSegment& rhs) const; + inline bool operator!=(const LineSegment& rhs) const + { + return !(*this == rhs); + } + + bool operator*(const LineSegment& rhs) const; + + bool isHorizontal; + bool isVertical; + +private: + float getTriangleArea(float Ax, float Ay, float Bx, float By, float Cx, float Cy) const; + bool sameSigns(float x, float y) const; +}; + +class EdgeCrossingComparator { +public: + bool operator()(const LineSegment* left, const LineSegment* right) const + { + if (left->crossingPointY == right->crossingPointY) { + return left->end.y < right->end.y; + } else { + return left->crossingPointY < right->crossingPointY; + } + } +}; + +namespace lineUtils { +void getIntersectionPoint(const LineSegment& lineA, const LineSegment& lineB, float& x, float& y); +} diff --git a/uvOverlapChecker/src/bentleyOttmann/main.cpp b/uvOverlapChecker/src/bentleyOttmann/main.cpp new file mode 100644 index 0000000..d9821c5 --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/main.cpp @@ -0,0 +1,88 @@ +// +// main.cpp +// bentleyOttman +// + +#include +#include +#include + +#include "bentleyOttmann.hpp" +#include "lineSegment.hpp" +#include "point2D.hpp" +#include "testData/dataSet.hpp" + + +int test() { + + std::vector edgeVec; + std::vector edgeVec2; + + std::string dataPathA = "./testData/DataA-Table_1.csv"; + std::string dataPathB = "./testData/DataB-Table_1.csv"; + std::vector > v1 = TestDataSet::getDataSet(dataPathA); + std::vector > v2 = TestDataSet::getDataSet(dataPathB); + + for (size_t i = 0; i < v1.size(); i++) { + int indexA = std::stoi(v1[i][0]); + float x1 = std::stof(v1[i][1]); + float y1 = std::stof(v1[i][2]); + + int indexB = std::stoi(v1[i][3]); + float x2 = std::stof(v1[i][4]); + float y2 = std::stof(v1[i][5]); + + Point2D p1(x1, y1, indexA); + Point2D p2(x2, y2, indexB); + + LineSegment edge(p1, p2); + edgeVec.push_back(edge); + } + + for (size_t i = 0; i < v2.size(); i++) { + int indexA = std::stoi(v2[i][0]); + float x1 = std::stof(v2[i][1]); + float y1 = std::stof(v2[i][2]); + + int indexB = std::stoi(v2[i][3]); + float x2 = std::stof(v2[i][4]); + float y2 = std::stof(v2[i][5]); + + Point2D p1(x1, y1, indexA); + Point2D p2(x2, y2, indexB); + + LineSegment edge(p1, p2); + edgeVec2.push_back(edge); + } + + // Remove duplicated line segments + std::sort(edgeVec.begin(), edgeVec.end(), EdgeIndexComparator()); + edgeVec.erase(std::unique(edgeVec.begin(), edgeVec.end()), edgeVec.end()); + + std::sort(edgeVec2.begin(), edgeVec2.end(), EdgeIndexComparator()); + edgeVec.erase(std::unique(edgeVec2.begin(), edgeVec2.end()), edgeVec2.end()); + + // Name line group name if necessary + std::string groupNameA = "lineGroupA"; + std::string groupNameB = "lineGroupB"; + BentleyOttman checker(edgeVec, groupNameA); + BentleyOttman checker2(edgeVec2, groupNameB); + + BentleyOttman checker3 = checker + checker2; + checker3.check(); + + std::vector::iterator resultIter; + for (resultIter = checker3.resultPtr.begin(); resultIter != checker3.resultPtr.end(); ++resultIter) { + const LineSegment& line = *(*resultIter); + std::cout << line.begin.index << ":" << line.end.index << " :: " << std::endl; + std::cout << line.groupId << std::endl; + } + return 0; +} + +int main(int argc, const char* argv[]) +{ + test(); + std::cout << "end" << std::endl; + return 0; +} diff --git a/uvOverlapChecker/src/bentleyOttmann/point2D.cpp b/uvOverlapChecker/src/bentleyOttmann/point2D.cpp new file mode 100644 index 0000000..2eff73c --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/point2D.cpp @@ -0,0 +1,43 @@ +// +// point2D.cpp +// bentleyOttmann +// + +#include "point2D.hpp" + +Point2D::Point2D() += default; + +Point2D::Point2D(float x, float y, int index) + : x(x) + , y(y) + , index(index) + , xy(std::make_pair(x, y)) +{ +} + +Point2D::~Point2D() += default; + +bool Point2D::operator==(const Point2D& rhs) const +{ + return this->index == rhs.index; +} + +bool Point2D::operator<(const Point2D& rhs) const +{ + return this->xy < rhs.xy; +} + +Vector2D Point2D::operator-(const Point2D& rhs) const +{ + if (this->index == rhs.index) { + Vector2D v(0, 0); + return v; + } + + float value_x = rhs.x - this->x; + float value_y = rhs.y - this->y; + Vector2D v(value_x, value_y); + return v; +} diff --git a/uvOverlapChecker/src/bentleyOttmann/point2D.hpp b/uvOverlapChecker/src/bentleyOttmann/point2D.hpp new file mode 100644 index 0000000..add0877 --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/point2D.hpp @@ -0,0 +1,28 @@ +// +// point2D.hpp +// bentleyOttmann +// + +#pragma once + +#include "vector2D.hpp" +#include + +class Point2D { +public: + Point2D(); + Point2D(float x, float y, int index); + ~Point2D(); + float x{}, y{}; + int index{}; + std::pair xy; + + bool operator==(const Point2D& rhs) const; + inline bool operator!=(const Point2D& rhs) const + { + return !(*this == rhs); + } + + bool operator<(const Point2D& rhs) const; + Vector2D operator-(const Point2D& rhs) const; +}; diff --git a/uvOverlapChecker/src/bentleyOttmann/testData/DataA-Table_1.csv b/uvOverlapChecker/src/bentleyOttmann/testData/DataA-Table_1.csv new file mode 100644 index 0000000..62d7691 --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/testData/DataA-Table_1.csv @@ -0,0 +1,22 @@ +0,0.0660550594329834,0.0660550594329834,1,0.2830275297164917,0.0660550594329834 +1,0.2830275297164917,0.0660550594329834,6,0.2830275297164917,0.2830275297164917 +6,0.2830275297164917,0.2830275297164917,5,0.0660550594329834,0.2830275297164917 +5,0.0660550594329834,0.2830275297164917,0,0.0660550594329834,0.0660550594329834 +1,0.2830275297164917,0.0660550594329834,2,0.50,0.0660550594329834 +2,0.50,0.0660550594329834,7,0.770054817199707,0.36120128631591797 +7,0.770054817199707,0.36120128631591797,6,0.2830275297164917,0.2830275297164917 +2,0.50,0.0660550594329834,3,0.7169724702835083,0.0660550594329834 +3,0.7169724702835083,0.0660550594329834,8,0.7596127390861511,0.23564951121807098 +8,0.7596127390861511,0.23564951121807098,7,0.770054817199707,0.36120128631591797 +3,0.7169724702835083,0.0660550594329834,4,0.9292071461677551,0.11106419563293457 +4,0.9292071461677551,0.11106419563293457,9,0.9339449405670166,0.2830275297164917 +9,0.9339449405670166,0.2830275297164917,8,0.7596127390861511,0.23564951121807098 +6,0.2830275297164917,0.2830275297164917,28,0.2830275297164917,0.5 +28,0.2830275297164917,0.5,29,0.0660550594329834,0.5 +29,0.0660550594329834,0.5,5,0.0660550594329834,0.2830275297164917 +7,0.770054817199707,0.36120128631591797,27,0.5,0.5 +27,0.5,0.5,28,0.2830275297164917,0.5 +8,0.7596127390861511,0.23564951121807098,25,0.7169724702835083,0.5 +25,0.7169724702835083,0.5,27,0.5,0.5 +9,0.9339449405670166,0.2830275297164917,14,0.9339449405670166,0.5 +14,0.9339449405670166,0.5,25,0.7169724702835083,0.5 \ No newline at end of file diff --git a/uvOverlapChecker/src/bentleyOttmann/testData/DataB-Table_1.csv b/uvOverlapChecker/src/bentleyOttmann/testData/DataB-Table_1.csv new file mode 100644 index 0000000..12c1b92 --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/testData/DataB-Table_1.csv @@ -0,0 +1,21 @@ +10,-0.5314721465110779,0.6870385408401489,11,-0.5849046111106873,0.8497003316879272 +11,-0.5849046111106873,0.8497003316879272,16,-0.29304349422454834,0.8890276551246643 +15,-0.47460252046585083,0.8964254856109619,10,-0.5314721465110779,0.6870385408401489 +11,-0.5849046111106873,0.8497003316879272,12,-0.1126982569694519,0.5732992887496948 +12,-0.1126982569694519,0.5732992887496948,17,-0.055828630924224854,0.782686173915863 +17,-0.055828630924224854,0.782686173915863,16,-0.29304349422454834,0.8890276551246643 +12,-0.1126982569694519,0.5732992887496948,13,0.09668868780136108,0.5164296627044678 +13,0.09668868780136108,0.5164296627044678,18,0.19084149599075317,0.6371393203735352 +18,0.19084149599075317,0.6371393203735352,17,-0.055828630924224854,0.782686173915863 +13,0.09668868780136108,0.5164296627044678,26,0.3060756325721741,0.45955994725227356 +26,0.3060756325721741,0.45955994725227356,19,0.3629452586174011,0.6689468026161194 +19,0.3629452586174011,0.6689468026161194,18,0.19084149599075317,0.6371393203735352 +16,-0.29304349422454834,0.8890276551246643,21,-0.2083459496498108,1.0489426851272583 +21,-0.2083459496498108,1.0489426851272583,20,-0.4177328944206238,1.105812430381775 +20,-0.4177328944206238,1.105812430381775,15,-0.47460252046585083,0.8964254856109619 +17,-0.055828630924224854,0.782686173915863,22,0.004851400852203369,0.9247608184814453 +22,0.004851400852203369,0.9247608184814453,21,-0.2083459496498108,1.0489426851272583 +18,0.19084149599075317,0.6371393203735352,23,0.21042793989181519,0.935203492641449 +23,0.21042793989181519,0.935203492641449,22,0.004851400852203369,0.9247608184814453 +19,0.3629452586174011,0.6689468026161194,24,0.4198148846626282,0.8783338665962219 +24,0.4198148846626282,0.8783338665962219,23,0.21042793989181519,0.935203492641449 \ No newline at end of file diff --git a/uvOverlapChecker/src/bentleyOttmann/testData/dataSet.cpp b/uvOverlapChecker/src/bentleyOttmann/testData/dataSet.cpp new file mode 100644 index 0000000..b259017 --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/testData/dataSet.cpp @@ -0,0 +1,30 @@ +// +// dataSet.cpp +// bentleyOttman +// + +#include "dataSet.hpp" +#include +#include +#include + +std::vector > TestDataSet::getDataSet(std::string path) +{ + std::ifstream ifs(path.c_str()); + if (!ifs) { + std::cout << "Failed to open file" << std::endl; + } + std::string str; + std::vector > v; + + while (std::getline(ifs, str)) { + std::istringstream stream(str); + std::string field; + std::vector result; + while (std::getline(stream, field, ',')) { + result.push_back(field); + } + v.push_back(result); + } + return v; +} diff --git a/uvOverlapChecker/src/bentleyOttmann/testData/dataSet.hpp b/uvOverlapChecker/src/bentleyOttmann/testData/dataSet.hpp new file mode 100644 index 0000000..a4a0a2a --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/testData/dataSet.hpp @@ -0,0 +1,17 @@ +// +// dataSet.hpp +// bentleyOttman +// + +#ifndef dataSet_hpp +#define dataSet_hpp + +#include +#include + +class TestDataSet { +public: + static std::vector > getDataSet(std::string path); +}; + +#endif /* dataSet_hpp */ diff --git a/uvOverlapChecker/src/bentleyOttmann/vector2D.cpp b/uvOverlapChecker/src/bentleyOttmann/vector2D.cpp new file mode 100644 index 0000000..d0a8751 --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/vector2D.cpp @@ -0,0 +1,41 @@ +// +// vector2D.cpp +// bentleyOttmann +// + +#include "vector2D.hpp" +#include + +Vector2D::Vector2D() += default; + +Vector2D::Vector2D(float x, float y) + : x(x) + , y(y) +{ +} + +Vector2D::~Vector2D() += default; + +void Vector2D::normalize() +{ + float m = getLength(); + if (m != 0) { + this->x = this->x / m; + this->y = this->y / m; + } +} + +float Vector2D::getLength() +{ + float& value_x = this->x; + float& value_y = this->y; + return std::sqrt(value_x * value_x + value_y * value_y); +} + +float Vector2D::operator*(const Vector2D& rhs) const +{ + float dot = (this->x * rhs.x) + (this->y * rhs.y); + return dot; +} diff --git a/uvOverlapChecker/src/bentleyOttmann/vector2D.hpp b/uvOverlapChecker/src/bentleyOttmann/vector2D.hpp new file mode 100644 index 0000000..0cb102e --- /dev/null +++ b/uvOverlapChecker/src/bentleyOttmann/vector2D.hpp @@ -0,0 +1,19 @@ +// +// vector2D.hpp +// bentleyOttmann +// + +#pragma once + +class Vector2D { +public: + Vector2D(); + Vector2D(float x, float y); + ~Vector2D(); + float x{}, y{}; + + void normalize(); + float getLength(); + + float operator*(const Vector2D& rhs) const; +}; diff --git a/uvOverlapChecker/src/findUvOverlaps.cpp b/uvOverlapChecker/src/findUvOverlaps.cpp new file mode 100644 index 0000000..c2ec545 --- /dev/null +++ b/uvOverlapChecker/src/findUvOverlaps.cpp @@ -0,0 +1,392 @@ +#include +#include +#include +#include +#include +#include +#include "findUvOverlaps.hpp" +#include +#include +#include +#include +#include +#include +#include + +static const char* const pluginCommandName = "findUvOverlaps"; +static const char* const pluginVersion = "1.8.20"; +static const char* const pluginAuthor = "Michitaka Inoue"; + +void UVShell::initAABB() +{ + std::vector uVector; + std::vector vVector; + for (auto & line : this->lines) { + uVector.emplace_back(line.begin.x); + uVector.emplace_back(line.end.x); + vVector.emplace_back(line.begin.y); + vVector.emplace_back(line.end.y); + } + this->left = *std::min_element(uVector.begin(), uVector.end()); + this->right = *std::max_element(uVector.begin(), uVector.end()); + this->bottom = *std::min_element(vVector.begin(), vVector.end()); + this->top = *std::max_element(vVector.begin(), vVector.end()); +} + +bool UVShell::operator*(const UVShell& other) const +{ + if (this->right < other.left) + return false; + + if (this->left > other.right) + return false; + + if (this->top < other.bottom) + return false; + + if (this->bottom > other.top) + return false; + + return true; +} + +UVShell UVShell::operator&&(const UVShell& other) const +{ + std::vector lineVector = this->lines; + lineVector.insert(lineVector.end(), other.lines.begin(), other.lines.end()); + UVShell shell; + shell.lines = lineVector; + return shell; +} + +FindUvOverlaps::FindUvOverlaps() + : verbose(false) {} + +FindUvOverlaps::~FindUvOverlaps() = default; + +void* FindUvOverlaps::creator() +{ + return new FindUvOverlaps(); +} + +MSyntax FindUvOverlaps::newSyntax() +{ + MSyntax syntax; + syntax.addFlag("-v", "-verbose", MSyntax::kBoolean); + syntax.addFlag("-set", "-uvSet", MSyntax::kString); + return syntax; +} + +void FindUvOverlaps::btoCheck(UVShell& shell) +{ + std::vector result; + BentleyOttmann b(shell.lines); + b.check(result); + pushToLineVector(result); +} + +void FindUvOverlaps::pushToLineVector(std::vector& v) +{ + try { + locker.lock(); + finalResult.push_back(v); + locker.unlock(); + } catch (std::exception& e) { + std::cerr << e.what() << std::endl; + } +} + +void FindUvOverlaps::pushToShellVector(UVShell& shell) +{ + try { + locker.lock(); + shellVector.push_back(shell); + locker.unlock(); + } catch (std::exception& e) { + std::cerr << e.what() << std::endl; + } +} + +MStatus FindUvOverlaps::doIt(const MArgList& args) +{ + MStatus stat; + MTimer timer; + double elapsedTime; + + MArgDatabase argData(syntax(), args); + + if (argData.isFlagSet("-verbose")) + argData.getFlagArgument("-verbose", 0, verbose); + else + verbose = false; + + if (argData.isFlagSet("-uvSet")) + argData.getFlagArgument("-uvSet", 0, uvSet); + else + uvSet = "None"; + + MGlobal::getActiveSelectionList(mSel); + + timer.beginTimer(); + // Multithrad obj initialization + // std::thread* threadArray = new std::thread[mSel.length()]; + // for (size_t i = 0; i < mSel.length(); i++) { + // threadArray[i] = std::thread(&FindUvOverlaps::init, this, i); + // } + // for (size_t i = 0; i < mSel.length(); i++) { + // threadArray[i].join(); + // } + // delete[] threadArray; + + int numSelected = static_cast(mSel.length()); +#pragma omp parallel for + for (int i = 0; i < numSelected; i++) { + init(i); + } + + timer.endTimer(); + elapsedTime = timer.elapsedTime(); + if (verbose) + timeIt("Init time : ", elapsedTime); + timer.clear(); + + size_t numAllShells = shellVector.size(); + + for (size_t i = 0; i < numAllShells; i++) { + UVShell& s = shellVector[i]; + s.initAABB(); + } + + std::vector shells; // temp countainer to store both original and combined shells + + for (size_t i = 0; i < numAllShells; i++) { + UVShell& shellA = shellVector[i]; + shells.push_back(shellA); + + for (size_t j = i + 1; j < numAllShells; j++) { + UVShell& shellB = shellVector[j]; + + if (shellA * shellB) { + UVShell intersectedShell = shellA && shellB; + shells.push_back(intersectedShell); + } + } + } + + timer.beginTimer(); + + if (verbose) { + MString numShellsStr; + numShellsStr.set(static_cast(shells.size())); + MGlobal::displayInfo("Number of UvShells : " + numShellsStr); + } + + // Multithread bentleyOttman check + size_t numAllShells2 = shells.size(); + auto* btoThreadArray = new std::thread[numAllShells2]; + for (size_t i = 0; i < numAllShells2; i++) { + UVShell& s = shells[i]; + btoThreadArray[i] = std::thread(&FindUvOverlaps::btoCheck, this, std::ref(s)); + } + for (size_t i = 0; i < numAllShells2; i++) { + btoThreadArray[i].join(); + } + delete[] btoThreadArray; + + timer.endTimer(); + elapsedTime = timer.elapsedTime(); + if (verbose) + timeIt("Check time : ", elapsedTime); + timer.clear(); + + timer.beginTimer(); + // Re-insert to set to remove duplicates + std::string temp_path; + std::unordered_set temp; + for (auto&& lines : finalResult) { + for (auto&& line : lines) { + std::string groupName(line.groupId); + temp_path = groupName + ".map[" + std::to_string(line.index.first) + "]"; + temp.insert(temp_path); + temp_path = groupName + ".map[" + std::to_string(line.index.second) + "]"; + temp.insert(temp_path); + } + } + + // Remove duplicates + timer.endTimer(); + elapsedTime = timer.elapsedTime(); + if (verbose) + timeIt("Removed duplicates : ", elapsedTime); + timer.clear(); + + // Insert all results to MStringArray for return + MString s; + MStringArray resultStringArray; + + for (const auto& fullpath : temp) { + s.set(fullpath.c_str()); + resultStringArray.append(s); + } + + setResult(resultStringArray); + + return MS::kSuccess; +} + +MStatus FindUvOverlaps::init(int i) +{ + MStatus status; + + MDagPath dagPath; + mSel.getDagPath(static_cast(i), dagPath); + + // Check if specified object is geometry or not + status = dagPath.extendToShape(); + if (status != MS::kSuccess) { + if (verbose) + MGlobal::displayInfo("Failed to extend to shape node."); + return MS::kFailure; + } + + if (dagPath.apiType() != MFn::kMesh) { + if (verbose) + MGlobal::displayInfo("Selected node : " + dagPath.fullPathName() + " is not mesh. Skipped"); + return MS::kFailure; + } + + MFnMesh fnMesh(dagPath); + + // Send to path vector and get pointer to that + const char* dagPathChar = paths.emplace_back(dagPath.fullPathName()); + + MIntArray uvShellIds; + unsigned int nbUvShells; + fnMesh.getUvShellsIds(uvShellIds, nbUvShells); + + MIntArray uvCounts; // Num of UVs per face eg. [4, 4, 4, 4, ...] + MIntArray uvIds; + fnMesh.getAssignedUVs(uvCounts, uvIds); + + unsigned int uvCountSize = uvCounts.length(); // is same as number of faces + std::vector> idPairs; + idPairs.reserve(uvCountSize * 4); + unsigned int uvCounter = 0; + unsigned int nextCounter; + // Loop over each face and its edges, then create a pair of indices + for (unsigned int j = 0; j < uvCountSize; j++) { + auto numFaceUVs = static_cast(uvCounts[j]); + for (unsigned int localIndex = 0; localIndex < numFaceUVs; localIndex++) { + if (localIndex == numFaceUVs - 1) { + // Set the nextCounter to the localIndex of zero of the face + nextCounter = uvCounter - numFaceUVs + 1; + } else { + nextCounter = uvCounter + 1; + } + + int idA = uvIds[uvCounter]; + int idB = uvIds[nextCounter]; + + std::pair idPair; + + if (idA < idB) + idPair = std::make_pair(idA, idB); + else + idPair = std::make_pair(idB, idA); + + idPairs.emplace_back(idPair); + uvCounter++; + } + } + + // Remove duplicate elements + std::sort(idPairs.begin(), idPairs.end()); + idPairs.erase(std::unique(idPairs.begin(), idPairs.end()), idPairs.end()); + + // Temp countainer for lineSegments for each UVShell + std::vector> edgeVector; + edgeVector.resize(nbUvShells); + + MFloatArray uArray; + MFloatArray vArray; + fnMesh.getUVs(uArray, vArray); + + // Setup uv shell objects + std::vector shells(nbUvShells); + + // Loop over all id pairs and create lineSegment objects + for (auto & idPair : idPairs) { + + unsigned int idA = idPair.first; + unsigned int idB = idPair.second; + Point2D p1(uArray[idA], vArray[idA], static_cast(idA)); + Point2D p2(uArray[idB], vArray[idB], static_cast(idB)); + + // Create new lineSegment object + LineSegment line(p1, p2, dagPathChar); + + auto shellIndex = static_cast(uvShellIds[idA]); + shells[shellIndex].lines.emplace_back(line); + } + + for (auto & shell : shells) { + pushToShellVector(shell); + } + + return MS::kSuccess; +} + +void FindUvOverlaps::timeIt(const std::string& text, double t) +{ + MString message, time; + message.set(text.c_str()); + time.set(t); + MGlobal::displayInfo(message + " : " + time + " seconds."); +} + +// +// The following routines are used to register/unregister +// the command we are creating within Maya +// + +MStatus initializePlugin(MObject obj) +{ + MStatus status; + + std::string version_str(pluginVersion); + std::string compile_date_str(__DATE__); + std::string compile_time_str(__TIME__); + std::string version(version_str + " / " + compile_date_str + " / " + compile_time_str); + + MFnPlugin plugin(obj, pluginAuthor, version.c_str(), "Any"); + + status = plugin.registerCommand(pluginCommandName, FindUvOverlaps::creator, FindUvOverlaps::newSyntax); + if (!status) { + status.perror("registerCommand"); + return status; + } + + return status; +} + +MStatus uninitializePlugin(MObject obj) +{ + MStatus status; + MFnPlugin plugin(obj); + + status = plugin.deregisterCommand(pluginCommandName); + if (!status) { + status.perror("deregisterCommand"); + return status; + } + + return status; +} + +const char *MStringVector::emplace_back(const MString& path) { + std::lock_guard lock(mtx); + elements.emplace_back(path); + MString &tempMstring = elements.back(); + const char* tempChar = tempMstring.asChar(); + return tempChar; +} diff --git a/uvOverlapChecker/src/findUvOverlaps.hpp b/uvOverlapChecker/src/findUvOverlaps.hpp new file mode 100644 index 0000000..cd846c6 --- /dev/null +++ b/uvOverlapChecker/src/findUvOverlaps.hpp @@ -0,0 +1,57 @@ +#pragma once + + +#include "bentleyOttmann/bentleyOttmann.hpp" +#include "bentleyOttmann/lineSegment.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +class UVShell { + float left, right, top, bottom; +public: + std::vector lines; + void initAABB(); + bool operator*(const UVShell& other) const; + UVShell operator&&(const UVShell& other) const; +}; + +class MStringVector { +private: + std::mutex mtx; + std::vector elements; +public: + const char* emplace_back(const MString& path); +}; + +class FindUvOverlaps : public MPxCommand { +public: + FindUvOverlaps(); + ~FindUvOverlaps() override; + + MStatus doIt(const MArgList& args) override; + + static void* creator(); + static MSyntax newSyntax(); + +private: + std::mutex locker; + MString uvSet; + bool verbose; + MSelectionList mSel; + MStringVector paths; + + std::vector > finalResult; + std::vector shellVector; + + MStatus init(int i); + void btoCheck(UVShell &shell); + void pushToLineVector(std::vector &v); + void pushToShellVector(UVShell &shell); + static void timeIt(const std::string& text, double t); +};