+ Init Repo

This commit is contained in:
indigo 2023-09-24 21:17:24 +08:00
commit 1992234adf
9 changed files with 26073 additions and 0 deletions

3
.hgignore Normal file
View File

@ -0,0 +1,3 @@
syntax: glob
build/*
CMakeFiles/*

6
CMakeLists.txt Normal file
View File

@ -0,0 +1,6 @@
project(CgMeshInfo)
cmake_minimum_required(VERSION 3.12)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
add_subdirectory(src)

79
cmake/FindMaya.cmake Normal file
View File

@ -0,0 +1,79 @@
if(NOT DEFINED MAYA_VERSION)
set(MAYA_VERSION 2013.5 CACHE STRING "Maya version")
endif()
set(MAYA_COMPILE_DEFINITIONS "REQUIRE_IOSTREAM;_BOOL;_CRT_SECURE_NO_WARNINGS;NOMINMAX")
set(MAYA_INSTALL_BASE_SUFFIX "")
set(MAYA_LIB_SUFFIX "lib")
set(MAYA_INC_SUFFIX "include")
set(MAYA_TARGET_TYPE LIBRARY)
if(WIN32)
# Windows
set(MAYA_INSTALL_BASE "C:/Program Files/Autodesk")
set(OPENMAYA OpenMaya.lib)
set(MAYA_COMPILE_DEFINITIONS "${MAYA_COMPILE_DEFINITIONS};NT_PLUGIN")
set(MAYA_PLUGIN_EXTENSION ".mll")
set(MAYA_TARGET_TYPE RUNTIME)
elseif(APPLE)
# Mac
set(MAYA_INSTALL_BASE "/Applications/Autodesk")
set(OPENMAYA libOpenMaya.dylib)
set(MAYA_LIB_SUFFIX "Maya.app/Contents/MacOS")
set(MAYA_INC_SUFFIX "devkit/include")
set(MAYA_COMPILE_DEFINITIONS "${MAYA_COMPILE_DEFINITIONS};OSMac")
set(MAYA_PLUGIN_EXTENSION ".dylib")
else()
# Linux
set(MAYA_INSTALL_BASE "/usr/autodesk")
set(MAYA_INSTALL_BASE_SUFFIX -x64)
set(OPENMAYA libOpenMaya.so)
set(MAYA_COMPILE_DEFINITIONS "${MAYA_COMPILE_DEFINITIONS};LINUX")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set(MAYA_PLUGIN_EXTENSION ".so")
endif()
set(MAYA_INSTALL_BASE_PATH ${MAYA_INSTALL_BASE} CACHE STRING "Maya Root Installation Path")
set(MAYA_LOCATION ${MAYA_INSTALL_BASE_PATH}/maya${MAYA_VERSION}${MAYA_INSTALL_BASE_SUFFIX})
message(STATUS "MAYA_INSTALL_BASE_PATH : ${MAYA_INSTALL_BASE_PATH}")
find_path(MAYA_LIBRARY_DIR ${OPENMAYA}
PATHS
${MAYA_LOCATION}
$ENV{MAYA_LOCATION}
PATH_SUFFIXES
"${MAYA_LIB_SUFFIX}/"
DOC "Maya library path"
)
find_path(MAYA_INCLUDE_DIR maya/MFn.h
PATHS
${MAYA_LOCATION}
$ENV{MAYA_LOCATION}
PATH_SUFFIXES
"${MAYA_INC_SUFFIX}/"
DOC "Maya include path"
)
set(_MAYA_LIBRARIES OpenMaya OpenMayaAnim OpenMayaFx OpenMayaRender OpenMayaUI Foundation)
foreach(MAYA_LIB ${_MAYA_LIBRARIES})
find_library(MAYA_${MAYA_LIB}_LIBRARY NAMES ${MAYA_LIB} PATHS ${MAYA_LIBRARY_DIR} NO_DEFAULT_PATH)
set(MAYA_LIBRARIES ${MAYA_LIBRARIES} ${MAYA_${MAYA_LIB}_LIBRARY})
endforeach()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Maya DEFAULT_MSG MAYA_INCLUDE_DIR MAYA_LIBRARIES)
function(MAYA_PLUGIN _target)
if(WIN32)
set_target_properties(${_target} PROPERTIES
LINK_FLAGS "/export:initializePlugin /export:uninitializePlugin")
endif()
set_target_properties(${_target} PROPERTIES
COMPILE_DEFINITIONS "${MAYA_COMPILE_DEFINITIONS}"
PREFIX ""
SUFFIX ${MAYA_PLUGIN_EXTENSION}
)
endfunction()

22
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,22 @@
set(SRC_FILES
"MeshInfoCmd.h"
"MeshInfoCmd.cpp"
"PluginMain.cpp"
"sha1.hpp"
"json.hpp")
# find_package(Maya REQUIRED)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
include_directories(
"C:/aw/Maya2020/include"
)
link_directories(
"C:/aw/Maya2020/lib"
)
link_libraries(Foundation OpenMaya OpenMayaAnim OpenMayaUI OpenMayaFX OpenMayaRender)
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".mll") # Suffix

203
src/MeshInfoCmd.cpp Normal file
View File

@ -0,0 +1,203 @@
#include "MeshInfoCmd.h"
#include "sha1.hpp"
#include "json.hpp"
#include <maya/MSelectionList.h>
#include <maya/MArgDatabase.h>
#include <maya/MGlobal.h>
#include <maya/MDagPath.h>
#include <maya/MFnMesh.h>
#include <maya/MFloatArray.h>
#include <maya/MItDag.h>
#include <algorithm>
#include <functional>
#include <vector>
#include <iostream>
#include <sstream>
#include <chrono>
#include <Windows.h>
#include <shlwapi.h>
using json = nlohmann::json;
MeshInfoCmd::MeshInfoCmd()
{
}
MeshInfoCmd::~MeshInfoCmd()
{
}
MSyntax MeshInfoCmd::newSyntex()
{
MSyntax syntax;
syntax.useSelectionAsDefault(true);
syntax.setObjectType(MSyntax::kSelectionList);
syntax.setMinObjects(1);
syntax.addFlag(kVtxHashFlag, kVtxHashFlagLong, MSyntax::kNoArg);
syntax.addFlag(kUvHashFlag, kUvHashFlagLong, MSyntax::kNoArg);
syntax.addFlag(kExtendToShapeFlag, kExtendToShapeFlagLong, MSyntax::kNoArg);
syntax.addFlag(kNoIntermediaFlag, kNoIntermediaFlagLong, MSyntax::kNoArg);
syntax.addFlag(kFileFlag, kFileFlagLong, MSyntax::kString);
return syntax;
}
void * MeshInfoCmd::creator()
{
return new MeshInfoCmd();
}
MString MeshInfoCmd::getHash(MIntArray & arrayData1, MIntArray &arrayData2)
{
auto SHA1 = sha1();
SHA1.add(&arrayData1[0], sizeof(int) * arrayData1.length());
SHA1.add(&arrayData2[0], sizeof(int) * arrayData2.length());
char hex[SHA1_HEX_SIZE];
SHA1.finalize().print_hex(hex);
return MString(hex);
}
MString MeshInfoCmd::getHash(MFloatArray & arrayData1, MFloatArray & arrayData2)
{
auto SHA1 = sha1();
SHA1.add(&arrayData1[0], sizeof(float) * arrayData1.length());
SHA1.add(&arrayData2[0], sizeof(float) * arrayData2.length());
char hex[SHA1_HEX_SIZE];
SHA1.finalize().print_hex(hex);
return MString(hex);
}
MStatus MeshInfoCmd::extendToShape(MSelectionList & list)
{
MStatus status;
MSelectionList current_list = list;
unsigned nObj = current_list.length();
if (current_list.isEmpty())
return MS::kInvalidParameter;
list.clear();
for (unsigned int i = 0; i < nObj; i++)
{
MObject node;
current_list.getDependNode(0, node);
if (!node.hasFn(MFn::kMesh))
{
MItDag itDag;
itDag.reset(node);
while (!itDag.isDone())
{
MObject currentItem = itDag.currentItem();
if (!currentItem.hasFn(MFn::kMesh))
continue;
MDagPath dagPath;
MFnMesh fnMesh(dagPath);
itDag.getPath(dagPath);
list.add(dagPath);
itDag.next();
}
}
else {
MDagPath nodePath;
current_list.getDagPath(0, nodePath);
list.add(nodePath);
}
}
return MS::kSuccess;
}
MStatus MeshInfoCmd::doIt(const MArgList & args)
{
MStatus status;
MSelectionList list;
MArgDatabase argData(syntax(), args);
status = argData.getObjects(list);
if (MS::kSuccess != status) {
MGlobal::displayError("Error to get objects");
return status;
}
bool vtxHashGen = argData.isFlagSet(kVtxHashFlag);
bool uvHashGen = argData.isFlagSet(kUvHashFlag);
bool ets = argData.isFlagSet(kExtendToShapeFlag);
bool noIntermdia = argData.isFlagSet(kNoIntermediaFlag);
bool fileGen = argData.isFlagSet(kFileFlag);
if (ets) {
extendToShape(list);
}
unsigned nObj = list.length();
MStringArray result;
std::vector<std::string> header = { "name", "vertices_hash", "uv_hash" };
auto meshInfo = json::array();
meshInfo.push_back(header);
if (nObj)
{
for (unsigned int i = 0; i < nObj; i++)
{
MDagPath dagPath;
MObject depNode;
list.getDependNode(i, depNode);
if (!depNode.hasFn(MFn::kMesh)) {
continue;
}
list.getDagPath(i, dagPath);
MFnMesh fnMesh(dagPath);
if (noIntermdia) {
if (fnMesh.isIntermediateObject())
continue;
}
/*std::vector<int> intArray;
intArray.resize(vertexList.length());
vertexList.get(&intArray[0]);*/
//std::copy(intArray.begin(), intArray.end(), std::ostream_iterator<int>(ss_result, ","));
/*auto SHA1 = sha1();
//SHA1.add(&intArray[0], sizeof(int) * intArray.size());
SHA1.add(&vertexList[0], sizeof(int) * vertexList.length());
char hex[SHA1_HEX_SIZE];
SHA1.finalize().print_hex(hex);*/
//char hex[SHA1_HEX_SIZE];
result.append(fnMesh.name());
MString vtx_hash, uv_hash;
if (vtxHashGen || fileGen) {
MIntArray vertexCount, vertexList;
fnMesh.getVertices(vertexCount, vertexList);
vtx_hash = getHash(vertexCount, vertexList);
result.append(vtx_hash);
}
if (uvHashGen || fileGen){
MFloatArray uArray, vArray;
fnMesh.getUVs(uArray, vArray);
uv_hash = getHash(uArray, vArray);
result.append(uv_hash);
}
if (fileGen)
{
std::vector<std::string> hashData = { fnMesh.name().asChar(), vtx_hash.asChar(), uv_hash.asChar() };
meshInfo.push_back(hashData);
}
}
}
std::string meshInfo_s = meshInfo.dump(4);
MGlobal::displayInfo(meshInfo_s.c_str());
setResult(result);
return status;
}

31
src/MeshInfoCmd.h Normal file
View File

@ -0,0 +1,31 @@
#include <maya/MPxCommand.h>
#include <maya/MSyntax.h>
#include <maya/MArgList.h>
#define kCommandName "meshInfo"
#define kVtxHashFlag "-vh"
#define kVtxHashFlagLong "-vtxHash"
#define kUvHashFlag "-uvh"
#define kUvHashFlagLong "-uvHash"
#define kExtendToShapeFlag "-ets"
#define kExtendToShapeFlagLong "-extendToShape"
#define kNoIntermediaFlag "-ni"
#define kNoIntermediaFlagLong "-noIntermediate"
#define kFileFlag "-f"
#define kFileFlagLong "-file"
class MeshInfoCmd : public MPxCommand
{
public:
MeshInfoCmd();
~MeshInfoCmd();
virtual MStatus doIt(const MArgList&);
static MSyntax newSyntex();
static void* creator();
MString getHash(MIntArray& arrayData1, MIntArray& arrayData2);
MString getHash(MFloatArray& arrayData1, MFloatArray& arrayData2);
MStatus extendToShape(MSelectionList &list);
};

27
src/PluginMain.cpp Normal file
View File

@ -0,0 +1,27 @@
#include <maya/MFnPlugin.h>
#include "MeshInfoCmd.h"
MStatus initializePlugin(MObject obj)
{
MStatus status = MStatus::kSuccess;
MFnPlugin plugin(obj, "CGCG Inc.2021", "1.0");
status = plugin.registerCommand(kCommandName, MeshInfoCmd::creator, MeshInfoCmd::newSyntex);
if (!status) {
printf("Failed to register plugin (%s)", kCommandName);
}
return status;
}
MStatus uninitializePlugin(MObject obj)
{
MStatus status = MStatus::kSuccess;
MFnPlugin plugin(obj);
status = plugin.deregisterCommand(kCommandName);
if (!status) {
printf("Failed to deregister plugin (%s)", kCommandName);
}
return status;
}

25447
src/json.hpp Normal file

File diff suppressed because it is too large Load Diff

255
src/sha1.hpp Normal file
View File

@ -0,0 +1,255 @@
#include <stdint.h>
#include <string.h>
#define SHA1_HEX_SIZE (40 + 1)
#define SHA1_BASE64_SIZE (28 + 1)
class sha1 {
private:
void add_byte_dont_count_bits(uint8_t x) {
buf[i++] = x;
if (i >= sizeof(buf)) {
i = 0;
process_block(buf);
}
}
static uint32_t rol32(uint32_t x, uint32_t n) {
return (x << n) | (x >> (32 - n));
}
static uint32_t make_word(const uint8_t *p) {
return
((uint32_t)p[0] << 3 * 8) |
((uint32_t)p[1] << 2 * 8) |
((uint32_t)p[2] << 1 * 8) |
((uint32_t)p[3] << 0 * 8);
}
void process_block(const uint8_t *ptr) {
const uint32_t c0 = 0x5a827999;
const uint32_t c1 = 0x6ed9eba1;
const uint32_t c2 = 0x8f1bbcdc;
const uint32_t c3 = 0xca62c1d6;
uint32_t a = state[0];
uint32_t b = state[1];
uint32_t c = state[2];
uint32_t d = state[3];
uint32_t e = state[4];
uint32_t w[16];
for (int i = 0; i < 16; i++) w[i] = make_word(ptr + i * 4);
#define SHA1_LOAD(i) w[i&15] = rol32(w[(i+13)&15] ^ w[(i+8)&15] ^ w[(i+2)&15] ^ w[i&15], 1);
#define SHA1_ROUND_0(v,u,x,y,z,i) z += ((u & (x ^ y)) ^ y) + w[i&15] + c0 + rol32(v, 5); u = rol32(u, 30);
#define SHA1_ROUND_1(v,u,x,y,z,i) SHA1_LOAD(i) z += ((u & (x ^ y)) ^ y) + w[i&15] + c0 + rol32(v, 5); u = rol32(u, 30);
#define SHA1_ROUND_2(v,u,x,y,z,i) SHA1_LOAD(i) z += (u ^ x ^ y) + w[i&15] + c1 + rol32(v, 5); u = rol32(u, 30);
#define SHA1_ROUND_3(v,u,x,y,z,i) SHA1_LOAD(i) z += (((u | x) & y) | (u & x)) + w[i&15] + c2 + rol32(v, 5); u = rol32(u, 30);
#define SHA1_ROUND_4(v,u,x,y,z,i) SHA1_LOAD(i) z += (u ^ x ^ y) + w[i&15] + c3 + rol32(v, 5); u = rol32(u, 30);
SHA1_ROUND_0(a, b, c, d, e, 0);
SHA1_ROUND_0(e, a, b, c, d, 1);
SHA1_ROUND_0(d, e, a, b, c, 2);
SHA1_ROUND_0(c, d, e, a, b, 3);
SHA1_ROUND_0(b, c, d, e, a, 4);
SHA1_ROUND_0(a, b, c, d, e, 5);
SHA1_ROUND_0(e, a, b, c, d, 6);
SHA1_ROUND_0(d, e, a, b, c, 7);
SHA1_ROUND_0(c, d, e, a, b, 8);
SHA1_ROUND_0(b, c, d, e, a, 9);
SHA1_ROUND_0(a, b, c, d, e, 10);
SHA1_ROUND_0(e, a, b, c, d, 11);
SHA1_ROUND_0(d, e, a, b, c, 12);
SHA1_ROUND_0(c, d, e, a, b, 13);
SHA1_ROUND_0(b, c, d, e, a, 14);
SHA1_ROUND_0(a, b, c, d, e, 15);
SHA1_ROUND_1(e, a, b, c, d, 16);
SHA1_ROUND_1(d, e, a, b, c, 17);
SHA1_ROUND_1(c, d, e, a, b, 18);
SHA1_ROUND_1(b, c, d, e, a, 19);
SHA1_ROUND_2(a, b, c, d, e, 20);
SHA1_ROUND_2(e, a, b, c, d, 21);
SHA1_ROUND_2(d, e, a, b, c, 22);
SHA1_ROUND_2(c, d, e, a, b, 23);
SHA1_ROUND_2(b, c, d, e, a, 24);
SHA1_ROUND_2(a, b, c, d, e, 25);
SHA1_ROUND_2(e, a, b, c, d, 26);
SHA1_ROUND_2(d, e, a, b, c, 27);
SHA1_ROUND_2(c, d, e, a, b, 28);
SHA1_ROUND_2(b, c, d, e, a, 29);
SHA1_ROUND_2(a, b, c, d, e, 30);
SHA1_ROUND_2(e, a, b, c, d, 31);
SHA1_ROUND_2(d, e, a, b, c, 32);
SHA1_ROUND_2(c, d, e, a, b, 33);
SHA1_ROUND_2(b, c, d, e, a, 34);
SHA1_ROUND_2(a, b, c, d, e, 35);
SHA1_ROUND_2(e, a, b, c, d, 36);
SHA1_ROUND_2(d, e, a, b, c, 37);
SHA1_ROUND_2(c, d, e, a, b, 38);
SHA1_ROUND_2(b, c, d, e, a, 39);
SHA1_ROUND_3(a, b, c, d, e, 40);
SHA1_ROUND_3(e, a, b, c, d, 41);
SHA1_ROUND_3(d, e, a, b, c, 42);
SHA1_ROUND_3(c, d, e, a, b, 43);
SHA1_ROUND_3(b, c, d, e, a, 44);
SHA1_ROUND_3(a, b, c, d, e, 45);
SHA1_ROUND_3(e, a, b, c, d, 46);
SHA1_ROUND_3(d, e, a, b, c, 47);
SHA1_ROUND_3(c, d, e, a, b, 48);
SHA1_ROUND_3(b, c, d, e, a, 49);
SHA1_ROUND_3(a, b, c, d, e, 50);
SHA1_ROUND_3(e, a, b, c, d, 51);
SHA1_ROUND_3(d, e, a, b, c, 52);
SHA1_ROUND_3(c, d, e, a, b, 53);
SHA1_ROUND_3(b, c, d, e, a, 54);
SHA1_ROUND_3(a, b, c, d, e, 55);
SHA1_ROUND_3(e, a, b, c, d, 56);
SHA1_ROUND_3(d, e, a, b, c, 57);
SHA1_ROUND_3(c, d, e, a, b, 58);
SHA1_ROUND_3(b, c, d, e, a, 59);
SHA1_ROUND_4(a, b, c, d, e, 60);
SHA1_ROUND_4(e, a, b, c, d, 61);
SHA1_ROUND_4(d, e, a, b, c, 62);
SHA1_ROUND_4(c, d, e, a, b, 63);
SHA1_ROUND_4(b, c, d, e, a, 64);
SHA1_ROUND_4(a, b, c, d, e, 65);
SHA1_ROUND_4(e, a, b, c, d, 66);
SHA1_ROUND_4(d, e, a, b, c, 67);
SHA1_ROUND_4(c, d, e, a, b, 68);
SHA1_ROUND_4(b, c, d, e, a, 69);
SHA1_ROUND_4(a, b, c, d, e, 70);
SHA1_ROUND_4(e, a, b, c, d, 71);
SHA1_ROUND_4(d, e, a, b, c, 72);
SHA1_ROUND_4(c, d, e, a, b, 73);
SHA1_ROUND_4(b, c, d, e, a, 74);
SHA1_ROUND_4(a, b, c, d, e, 75);
SHA1_ROUND_4(e, a, b, c, d, 76);
SHA1_ROUND_4(d, e, a, b, c, 77);
SHA1_ROUND_4(c, d, e, a, b, 78);
SHA1_ROUND_4(b, c, d, e, a, 79);
#undef SHA1_LOAD
#undef SHA1_ROUND_0
#undef SHA1_ROUND_1
#undef SHA1_ROUND_2
#undef SHA1_ROUND_3
#undef SHA1_ROUND_4
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
}
public:
uint32_t state[5];
uint8_t buf[64];
uint32_t i;
uint64_t n_bits;
sha1(const char *text = NULL) : i(0), n_bits(0) {
state[0] = 0x67452301;
state[1] = 0xEFCDAB89;
state[2] = 0x98BADCFE;
state[3] = 0x10325476;
state[4] = 0xC3D2E1F0;
if (text) add(text);
}
sha1& add(uint8_t x) {
add_byte_dont_count_bits(x);
n_bits += 8;
return *this;
}
sha1& add(char c) {
return add(*(uint8_t*)&c);
}
sha1& add(const void *data, uint32_t n) {
if (!data) return *this;
const uint8_t *ptr = (const uint8_t*)data;
// fill up block if not full
for (; n && i % sizeof(buf); n--) add(*ptr++);
// process full blocks
for (; n >= sizeof(buf); n -= sizeof(buf)) {
process_block(ptr);
ptr += sizeof(buf);
n_bits += sizeof(buf) * 8;
}
// process remaining part of block
for (; n; n--) add(*ptr++);
return *this;
}
sha1& add(const char *text) {
if (!text) return *this;
return add(text, strlen(text));
}
sha1& finalize() {
// hashed text ends with 0x80, some padding 0x00 and the length in bits
add_byte_dont_count_bits(0x80);
while (i % 64 != 56) add_byte_dont_count_bits(0x00);
for (int j = 7; j >= 0; j--) add_byte_dont_count_bits(n_bits >> j * 8);
return *this;
}
const sha1& print_hex(
char *hex,
bool zero_terminate = true,
const char *alphabet = "0123456789abcdef"
) const {
// print hex
int k = 0;
for (int i = 0; i < 5; i++) {
for (int j = 7; j >= 0; j--) {
hex[k++] = alphabet[(state[i] >> j * 4) & 0xf];
}
}
if (zero_terminate) hex[k] = '\0';
return *this;
}
const sha1& print_base64(char *base64, bool zero_terminate = true) const {
static const uint8_t *table = (const uint8_t*)
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"+/";
uint32_t triples[7] = {
((state[0] & 0xffffff00) >> 1 * 8),
((state[0] & 0x000000ff) << 2 * 8) | ((state[1] & 0xffff0000) >> 2 * 8),
((state[1] & 0x0000ffff) << 1 * 8) | ((state[2] & 0xff000000) >> 3 * 8),
((state[2] & 0x00ffffff) << 0 * 8),
((state[3] & 0xffffff00) >> 1 * 8),
((state[3] & 0x000000ff) << 2 * 8) | ((state[4] & 0xffff0000) >> 2 * 8),
((state[4] & 0x0000ffff) << 1 * 8),
};
for (int i = 0; i < 7; i++) {
uint32_t x = triples[i];
base64[i * 4 + 0] = table[(x >> 3 * 6) % 64];
base64[i * 4 + 1] = table[(x >> 2 * 6) % 64];
base64[i * 4 + 2] = table[(x >> 1 * 6) % 64];
base64[i * 4 + 3] = table[(x >> 0 * 6) % 64];
}
base64[SHA1_BASE64_SIZE - 2] = '=';
if (zero_terminate) base64[SHA1_BASE64_SIZE - 1] = '\0';
return *this;
}
};