diff --git a/CHANGELOG.md b/CHANGELOG.md index 073eead3..f52a853f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,99 @@ +## v0.28.5 (2018-07-10) + +### Added + +* New open-source ALFrameRange schema and translator, which sets up Maya time range and current frame during the translation. +* Tests for ALFrameRange translator. +* Tests for the fix for the over-decref issue in transform chain. + +### Fixed + +* Over-decref in transform chain during some prim tear-down. + +## v0.28.4 (2018-07-05) + +### Added + +* New events to prevent USDGlimpse from rebuilding the scene when mapping meta data is inserted into the prims during selection. + +### Changed + +* Transform values that have not changed no longer get written back to USD. +* Only hook up the proxy shape time attribute to the transform nodes that are actually transforms (i.e. ignore prims that are effectively just organisational containers) +* Allowed named events to be able to have callbacks registered against them prior to the events being registered + +### Removed + +* Some export macros from inline methods + +### Fixed + +* Regression where transform values were no longer being correctly displayed when translating prims into maya. +* A number of build warnings in the OSS build +* Final two build warnings in the repo. The generated schema code needs to have a flag set in the build C4099 to hide the 'class defined as struct' warning (pixar issue, not ours) +* When you duplicate a proxy shape, you wont see anything in the viewport and it wont be fully initialize until you reopen maya or find a hack (like changing the usd path) to trigger a load stage. (#98 - @nxkb) +* Add missing newlines to some TF_DEBUG statements in ProxyShapeUI (#92 - @elrond79) + +## v0.28.3 (2018-06-18) + +### Added ++ AL_usdmaya_CreateUsdPrim command added to insert a new prim into the UsdStage of a proxy shape. + +### Changed ++ The proxyShape outStageData is now connectable, and now longer hidden. Allows for manual DG node connections to be made. + +### Fixed ++ The internal mapping between a maya object and a prim now works correctly when specifying the -name flag of AL_usdmaya_ProxyShapeImport. + +## v0.28.2 (2018-06-14) + +### Added ++ Viewport will continue to refresh to show updated progressive renderers (like embree) until converged (#91 - @elrond79) + +### Changed ++ make getRenderAttris update showRender, as well as showGuides (#87 - @elrond79) + +### Fixed ++ Tweaks to allow builds to work with just rpath. (#88 - @elrond79) ++ When importing left handed geometry that has no normals, compute the correct set of inverted normals. + +## v0.28.1 (2018-06-06) + +### Added +* Documentation for mesh export, interpolation modes, and diffing. +* "-fd" flag added to the import command and the translate command +* Support for prim var interpolation modes in the import/export code paths (currently UV sets only, colour sets & normals will be in a later PR). +* Support for diffing all variations of the interpolation modes on prim vars. +* Routines to determine the interpolation modes on vec2/vec3/vec4 types. +- AL_usdmaya_LayerManagerCommands to retrieve layers that have been modified and that have been the EditTarget. + +### Changed ++ Built using USD-0.8.5 ++ ProxyShapePostLoadProcess::createTranformChainsForSchemaPrims now checks all the prims' parents' metadata for their unmerged status. If found, the transform chain creation skips the current prim in place of its parent. ++ ProxyShapePostLoadProcess::createSchemaPrims now checks all the prims' parents' metadata for their unmerged status. If found, the schema prim import will instead take place under the parent node. ++ Mesh::import now checks the prim's parents' metadata for its unmerged status. If found, the created shape node will not have the appended "Shape" string. +* Mesh attributes queries use EarliestTime timecode +* Functions in DgNodeTranslator are moved to DgNodeHelper in AL_USDMayaUtils +* AttributeType.h/.cpp are moved to AL_USDMayaUtils +- LayerManager API has been updated so you can now inspect all layers that have been set as an EditTarget and are Dirty. ++ Updated endToEndMaya tutorial to work with latest USD API changes. +* All hard coded /tmp paths in the unit tests, in favour of a linux/win32 solution. + +### Fixed + +- Fix for when tearing down a shape, that it's sibling shapes are left alone in Maya. +* time1.outTime is now connected to proxy shape nodes when transforms are selected during creation. +* Selected transforms are no longer renamed when importing a proxy shape. +* Tests build restored. +- Fix for Issue "meshTransform cannot execute twice" #82 +* Bug in the import/export of mesh normals +* Normals export now correctly listen to the exporter options. +* AL_usdmaya_plugin can be unloaded correctly. +* Passing the time value into the nurbs, camera, and transform translators on export. + +### Removed +* Removed the code that reversed polygon windings if the 'leftHanded' meta data flag was encountered. Instead, the 'opposite' flag is set on the maya mesh. + ## v0.27.10 (2018-05-07) ### Added diff --git a/CMakeLists.txt b/CMakeLists.txt index 027982a8..cb84d0da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,8 +18,7 @@ include(${USD_CONFIG_FILE}) # to get PYTHON_EXECUTABLE find_package(PythonInterp) -include(ProjectDefaults) -include(Public) +set(CMAKE_INCLUDE_CURRENT_DIR ON) include(CXXDefaults) add_definitions(${_PXR_CXX_DEFINITIONS}) @@ -64,6 +63,7 @@ set(NEED_BOOST_FILESYSTEM ON) if(WIN32) set(CMAKE_CXX_FLAGS -std=c++11 + /WX "${_PXR_CXX_FLAGS}" ) else() @@ -80,6 +80,11 @@ set(CMAKE_VERBOSE_MAKEFILE OFF) option(BUILD_USDMAYA_SCHEMAS "Build optional schemas." ON) option(BUILD_USDMAYA_TRANSLATORS "Build optional translators." ON) option(VALIDATE_GENERATED_SCHEMAS "Generate schemas code and compare." OFF) +option(SKIP_USDMAYA_TESTS "Build tests" OFF) + +if(NOT SKIP_USDMAYA_TESTS) + enable_testing() +endif() set(AL_USDMAYA_LOCATION_NAME "AL_USDMAYA_LOCATION" diff --git a/README.md b/README.md index 8a6e1330..ae7eeb34 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,17 @@ Pixar's [USDMaya plugin](https://graphics.pixar.com/usd/docs/Maya-USD-Plugins.ht ## Contact We have a google group for discussion and technical assistance: https://groups.google.com/forum/#!forum/al_usdmaya-discussion. For CLAs or to contact us directly, use email **usdmaya@al.com.au**. +## Videos +We have some videos explaining some of the workflows we support. We are hoping to add to this as we go: ++ [Animation & Layout](https://youtu.be/wcC71Yu2gjA) ++ [Modelling & Surfacing](https://youtu.be/DaxLk6pHijw) + ## Detailed Documentation + [Building it](docs/build.md) + [FAQ](docs/faq.md) ++ [Python](docs/python.md) + [Contributing](docs/contributing.md) + [Translation](docs/translation.md) + [Basic Usage](docs/basicUsage.md) diff --git a/cmake/defaults/CXXDefaults.cmake b/cmake/defaults/CXXDefaults.cmake index 16f87e24..4b56546c 100644 --- a/cmake/defaults/CXXDefaults.cmake +++ b/cmake/defaults/CXXDefaults.cmake @@ -48,6 +48,11 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") _add_define(BUILD_OPTLEVEL_DEV) endif() +# Set plugin path environment variable name +if (PXR_OVERRIDE_PLUGINPATH_NAME) + _add_define("PXR_PLUGINPATH_NAME=${PXR_OVERRIDE_PLUGINPATH_NAME}") +endif() + set(_PXR_CXX_FLAGS ${_PXR_CXX_FLAGS} ${_PXR_CXX_WARNING_FLAGS}) # CMake list to string. diff --git a/cmake/defaults/Options.cmake b/cmake/defaults/Options.cmake index aedd9989..9fe8466c 100644 --- a/cmake/defaults/Options.cmake +++ b/cmake/defaults/Options.cmake @@ -58,6 +58,12 @@ set(PXR_INSTALL_LOCATION "" "Intended final location for plugin resource files." ) +set(PXR_OVERRIDE_PLUGINPATH_NAME "" + CACHE + STRING + "Name of the environment variable that will be used to get plugin paths." +) + set(PXR_ALL_LIBS "" CACHE INTERNAL diff --git a/cmake/defaults/ProjectDefaults.cmake b/cmake/defaults/ProjectDefaults.cmake deleted file mode 100644 index 8ff64321..00000000 --- a/cmake/defaults/ProjectDefaults.cmake +++ /dev/null @@ -1,51 +0,0 @@ -# -# Copyright 2016 Pixar -# -# Licensed under the Apache License, Version 2.0 (the "Apache License") -# with the following modification; you may not use this file except in -# compliance with the Apache License and the following modification to it: -# Section 6. Trademarks. is deleted and replaced with: -# -# 6. Trademarks. This License does not grant permission to use the trade -# names, trademarks, service marks, or product names of the Licensor -# and its affiliates, except as required to comply with Section 4(c) of -# the License and to reproduce the content of the NOTICE file. -# -# You may obtain a copy of the Apache License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the Apache License with the above modification is -# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the Apache License for the specific -# language governing permissions and limitations under the Apache License. -# -if(APPLE) - set(OSX_ARCHITECTURES "x86_64" CACHE STRING "Build architectures for OSX") - set(CMAKE_MACOSX_RPATH ON) - set(CMAKE_SKIP_BUILD_RPATH FALSE) - set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) - set(CMAKE_DYLIB_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE STRING "install_name path for dylib.") - list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) - message(WARNING "Building USD on Mac OSX is currently experimental.") -elseif(WIN32) - # Windows specific set up - message(WARNING "Building USD on Windows is currently experimental.") -endif() - -# Allow local includes from source directory. -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -# Turn on folder usage -set_property(GLOBAL PROPERTY USE_FOLDERS ON) - -# Default build type -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release") -endif() - -if (PXR_BUILD_TESTS) - # Enable CTest - enable_testing() -endif() diff --git a/cmake/defaults/Version.cmake b/cmake/defaults/Version.cmake index 914b9745..93488f9d 100644 --- a/cmake/defaults/Version.cmake +++ b/cmake/defaults/Version.cmake @@ -24,4 +24,4 @@ # Versioning information set(PXR_MAJOR_VERSION "0") set(PXR_MINOR_VERSION "8") -set(PXR_PATCH_VERSION "3") +set(PXR_PATCH_VERSION "5") diff --git a/cmake/defaults/msvcdefaults.cmake b/cmake/defaults/msvcdefaults.cmake index db585ebe..1b6fe47e 100644 --- a/cmake/defaults/msvcdefaults.cmake +++ b/cmake/defaults/msvcdefaults.cmake @@ -26,8 +26,8 @@ set(_PXR_CXX_FLAGS "${_PXR_CXX_FLAGS} /EHsc") # Standards compliant. -set(_PXR_CXX_FLAGS "${_PXR_CXX_FLAGS} /Zc:rvalueCast \ - /Zc:strictStrings \ +set(_PXR_CXX_FLAGS "${_PXR_CXX_FLAGS} /Zc:rvalueCast + /Zc:strictStrings /Zc:inline") # Turn on all but informational warnings. diff --git a/cmake/macros/Private.cmake b/cmake/macros/Private.cmake deleted file mode 100644 index e76f6f1b..00000000 --- a/cmake/macros/Private.cmake +++ /dev/null @@ -1,270 +0,0 @@ -# -# Copyright 2016 Pixar -# -# Licensed under the Apache License, Version 2.0 (the "Apache License") -# with the following modification; you may not use this file except in -# compliance with the Apache License and the following modification to it: -# Section 6. Trademarks. is deleted and replaced with: -# -# 6. Trademarks. This License does not grant permission to use the trade -# names, trademarks, service marks, or product names of the Licensor -# and its affiliates, except as required to comply with Section 4(c) of -# the License and to reproduce the content of the NOTICE file. -# -# You may obtain a copy of the Apache License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the Apache License with the above modification is -# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the Apache License for the specific -# language governing permissions and limitations under the Apache License. -# -include(Version) - -function(_install_headers LIBRARY_NAME) - set(options "") - set(oneValueArgs PREFIX) - set(multiValueArgs FILES) - cmake_parse_arguments(_install_headers - "${options}" - "${oneValueArgs}" - "${multiValueArgs}" - ${ARGN} - ) - - if (PXR_INSTALL_SUBDIR) - set(installPrefix "${CMAKE_BINARY_DIR}/${PXR_INSTALL_SUBDIR}") - else() - set(installPrefix "${CMAKE_BINARY_DIR}") - endif() - - set(hpath "${_install_headers_PREFIX}/${LIBRARY_NAME}") - set(header_dest_dir "${installPrefix}/include/${hpath}") - if( NOT "${_install_headers_FILES}" STREQUAL "") - set(files_copied "") - foreach (f ${_install_headers_FILES}) - set(infile "${CMAKE_CURRENT_SOURCE_DIR}/${f}") - set(outfile "${header_dest_dir}/${f}") - list(APPEND files_copied ${outfile}) - add_custom_command( - OUTPUT ${outfile} - COMMAND "${CMAKE_COMMAND}" - ARGS -E copy "${infile}" "${outfile}" - MAIN_DEPENDENCY "${infile}" - COMMENT "Copying ${f} ..." - VERBATIM - ) - endforeach() - endif() -endfunction() # _install_headers - -# Converts a library name, such as _tf.so to the internal module name given -# our naming conventions, e.g. Tf -function(_get_python_module_name LIBRARY_FILENAME MODULE_NAME) - # Library names are either something like tf.so for shared libraries - # or _tf.so for Python module libraries. We want to strip the leading - # "_" off. - string(REPLACE "_" "" LIBNAME ${LIBRARY_FILENAME}) - string(SUBSTRING ${LIBNAME} 0 1 LIBNAME_FL) - string(TOUPPER ${LIBNAME_FL} LIBNAME_FL) - string(SUBSTRING ${LIBNAME} 1 -1 LIBNAME_SUFFIX) - set(${MODULE_NAME} - "${LIBNAME_FL}${LIBNAME_SUFFIX}" - PARENT_SCOPE - ) -endfunction() # _get_python_module_name - -function(_plugInfo_subst libName plugInfoPath) - # Generate plugInfo.json files from a template. Note that we can't use - # the $ generator expression here because - # configure_file will run at configure time while the generators will only - # run after. - set(libFile ${CMAKE_SHARED_LIBRARY_PREFIX}${libName}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set(pluginFile ${libName}${CMAKE_SHARED_LIBRARY_SUFFIX}) - - # The root resource directory is in $PREFIX/share/usd/$LIB/resource but the - # libs are actually in $PREFIX/lib. The lib path can then be specified - # relatively as below. - set(PLUG_INFO_LIBRARY_PATH "../../../../lib/${libFile}") - set(PLUG_INFO_PLUGIN_PATH "../${pluginFile}") - set(PLUG_INFO_RESOURCE_PATH "resources") - set(PLUG_INFO_PLUGIN_NAME "pxr.${libName}") - set(PLUG_INFO_ROOT "..") - - configure_file( - ${plugInfoPath} - ${CMAKE_CURRENT_BINARY_DIR}/${plugInfoPath} - ) -endfunction() # _plugInfo_subst - -# Install compiled python files alongside the python object, -# e.g. lib/python/pxr/Ar/__init__.pyc -function(_install_python LIBRARY_NAME) - set(options "") - set(oneValueArgs "") - set(multiValueArgs FILES) - cmake_parse_arguments(ip - "${options}" - "${oneValueArgs}" - "${multiValueArgs}" - ${ARGN} - ) - - set(libPythonPrefix lib/python) - - string(SUBSTRING ${LIBRARY_NAME} 0 1 LIBNAME_FL) - string(TOUPPER ${LIBNAME_FL} LIBNAME_FL) - string(SUBSTRING ${LIBRARY_NAME} 1 -1 LIBNAME_SUFFIX) - set(LIBRARY_INSTALLNAME "${LIBNAME_FL}${LIBNAME_SUFFIX}") - - foreach(file ${ip_FILES}) - set(filesToInstall "") - set(installDest - "${libPythonPrefix}/pxr/${LIBRARY_INSTALLNAME}") - - # Only attempt to compile .py files. Files like plugInfo.json may also - # be in this list - if (${file} MATCHES ".py$") - get_filename_component(file_we ${file} NAME_WE) - - # Preserve any directory prefix, just strip the extension. This - # directory needs to exist in the binary dir for the COMMAND below - # to work. - get_filename_component(dir ${file} PATH) - if (dir) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${dir}) - set(file_we ${dir}/${file_we}) - set(installDest ${installDest}/${dir}) - endif() - - set(outfile ${CMAKE_CURRENT_BINARY_DIR}/${file_we}.pyc) - list(APPEND files_copied ${outfile}) - add_custom_command(OUTPUT ${outfile} - COMMAND - ${PYTHON_EXECUTABLE} - ${PROJECT_SOURCE_DIR}/cmake/macros/compilePython.py - ${CMAKE_CURRENT_SOURCE_DIR}/${file} - ${CMAKE_CURRENT_SOURCE_DIR}/${file} - ${CMAKE_CURRENT_BINARY_DIR}/${file_we}.pyc - ) - list(APPEND filesToInstall ${CMAKE_CURRENT_SOURCE_DIR}/${file}) - list(APPEND filesToInstall ${CMAKE_CURRENT_BINARY_DIR}/${file_we}.pyc) - elseif (${file} STREQUAL "plugInfo.json") - _plugInfo_subst(${LIBRARY_NAME} ${file}) - list(APPEND filesToInstall ${CMAKE_CURRENT_BINARY_DIR}/${file}) - else() - list(APPEND filesToInstall ${CMAKE_CURRENT_SOURCE_DIR}/${file}) - endif() - - # Note that we always install under lib/python/pxr, even if we are in - # the third_party project. This means the import will always look like - # 'from pxr import X'. We need to do this per-loop iteration because - # the installDest may be different due to the presence of subdirs. - INSTALL( - FILES - ${filesToInstall} - DESTINATION - "${installDest}" - ) - endforeach() - - add_custom_target(${LIBRARY_NAME}_pythonfiles ALL - DEPENDS - ${files_copied} - ) - - set_target_properties(${LIBRARY_NAME}_pythonfiles - PROPERTIES - FOLDER "${PXR_PREFIX}/_python" - ) -endfunction() #_install_python - -function(_install_resource_files) - set(resourceFiles "") - foreach(resourceFile ${ARGN}) - # plugInfo.json go through an initial template substitution step files - # install it from the binary (gen) directory specified by the full - # path. Otherwise, use the original relative path which is relative to - # the source directory. - if (${resourceFile} STREQUAL "plugInfo.json") - _plugInfo_subst(${LIBRARY_NAME} ${resourceFile}) - list(APPEND resourceFiles "${CMAKE_CURRENT_BINARY_DIR}/${resourceFile}") - else() - list(APPEND resourceFiles ${resourceFile}) - endif() - endforeach() - - # Resource files install into a structure that looks like: - # share/ - # usd/ - # ${LIBRARY_NAME}/ - # resources/ - # resourceFileA - # subdir/ - # resourceFileB - # resourceFileC - # ... - # - foreach(f ${resourceFiles}) - # Don't install subdirs for absolute paths, there's no way to tell - # what the intended subdir structure is. In practice, any absolute paths - # should only come from the plugInfo.json processing above, which - # install at the top-level anyway. - if (NOT IS_ABSOLUTE ${f}) - get_filename_component(dirPath ${f} PATH) - endif() - - install( - FILES ${f} - DESTINATION ${PLUGINS_PREFIX}/${LIBRARY_NAME}/resources/${dirPath} - ) - endforeach() -endfunction() # _install_resource_files - -function(_classes LIBRARY_NAME) - # Install headers to build or install prefix - set(options PUBLIC PRIVATE) - cmake_parse_arguments(classes - "${options}" - "${oneValueArgs}" - "${multiValueArgs}" - ${ARGN} - ) - # If both get set, fall back to public. - if(${classes_PUBLIC}) - set(VISIBILITY "PUBLIC") - elseif(${classes_PRIVATE}) - set(VISIBILITY "PRIVATE") - else() - message(FATAL_ERROR - "Library ${LIBRARY_NAME} has implicit visibility. " - "Provide PUBLIC or PRIVATE to classes() call.") - endif() - - # Should the classes have an argument name? - foreach(cls ${classes_UNPARSED_ARGUMENTS}) - list(APPEND ${LIBRARY_NAME}_${VISIBILITY}_HEADERS ${cls}.h) - list(APPEND ${LIBRARY_NAME}_CPPFILES ${cls}.cpp) - endforeach() - set(${LIBRARY_NAME}_${VISIBILITY}_HEADERS - ${${LIBRARY_NAME}_${VISIBILITY}_HEADERS} - PARENT_SCOPE - ) - set(${LIBRARY_NAME}_CPPFILES ${${LIBRARY_NAME}_CPPFILES} PARENT_SCOPE) -endfunction() # _classes - - -function(_get_install_dir path out) - if (PXR_INSTALL_SUBDIR) - set(${out} ${PXR_INSTALL_SUBDIR}/${path} PARENT_SCOPE) - else() - set(${out} ${path} PARENT_SCOPE) - endif() -endfunction() # get_install_dir - -macro(_get_share_install_dir RESULT) - _get_install_dir(share/usd ${RESULT}) -endmacro() # _get_share_install_dir - diff --git a/cmake/macros/Public.cmake b/cmake/macros/Public.cmake deleted file mode 100644 index e4844dc2..00000000 --- a/cmake/macros/Public.cmake +++ /dev/null @@ -1,854 +0,0 @@ -# -# Copyright 2016 Pixar -# -# Licensed under the Apache License, Version 2.0 (the "Apache License") -# with the following modification; you may not use this file except in -# compliance with the Apache License and the following modification to it: -# Section 6. Trademarks. is deleted and replaced with: -# -# 6. Trademarks. This License does not grant permission to use the trade -# names, trademarks, service marks, or product names of the Licensor -# and its affiliates, except as required to comply with Section 4(c) of -# the License and to reproduce the content of the NOTICE file. -# -# You may obtain a copy of the Apache License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the Apache License with the above modification is -# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the Apache License for the specific -# language governing permissions and limitations under the Apache License. -# -include(Private) - -function(pxr_python_bins) - _get_install_dir(bin installDir) - foreach(file ${ARGN}) - set(pyFile ${file}.py) - - # /pxrpythonsubst will be replaced with the full path to the configured - # python executable. This doesn't use the CMake ${...} or @...@ syntax - # for backwards compatibility with other build systems. - file(READ ${pyFile} contents) - string(REGEX REPLACE "/pxrpythonsubst" ${PXR_PYTHON_SHEBANG} - contents "${contents}") - file(WRITE ${CMAKE_BINARY_DIR}/${pyFile} ${contents}) - - install(PROGRAMS - ${CMAKE_BINARY_DIR}/${pyFile} - DESTINATION ${installDir} - RENAME ${file} - ) - endforeach() -endfunction() # pxr_install_python_bins - -function(pxr_cpp_bin BIN_NAME) - _get_install_dir(bin installDir) - - set(multiValueArgs - LIBRARIES - INCLUDE_DIRS - ) - - cmake_parse_arguments(cb - "" - "" - "${multiValueArgs}" - ${ARGN} - ) - - add_executable(${BIN_NAME} ${BIN_NAME}.cpp) - add_dependencies(${BIN_NAME} ${cb_LIBRARIES}) - - # Install and include headers from the build directory. - get_filename_component( - PRIVATE_INC_DIR - "${CMAKE_BINARY_DIR}/include" - ABSOLUTE - ) - - target_include_directories(${BIN_NAME} - PRIVATE - ${cb_INCLUDE_DIRS} - ${PRIVATE_INC_DIR} - ) - - set_target_properties(${BIN_NAME} - PROPERTIES - INSTALL_RPATH_USE_LINK_PATH TRUE - ) - - if (PXR_MALLOC_LIBRARY) - target_link_libraries(${BIN_NAME} ${cb_LIBRARIES}) - else() - target_link_libraries(${BIN_NAME} - ${cb_LIBRARIES} - ${PXR_MALLOC_LIBRARY} - ) - endif() - - install(TARGETS - ${BIN_NAME} - DESTINATION ${installDir} - ) - -endfunction() - -function(pxr_shared_library LIBRARY_NAME) - set(options PYTHON_LIBRARY) - set(multiValueArgs - PUBLIC_CLASSES - PUBLIC_HEADERS - PRIVATE_CLASSES - PRIVATE_HEADERS - CPPFILES - PYMODULE_CPPFILES - PYTHON_FILES - LIBRARIES - INCLUDE_DIRS - RESOURCE_FILES - ) - - cmake_parse_arguments(sl - "${options}" - "" - "${multiValueArgs}" - ${ARGN} - ) - - _classes(${LIBRARY_NAME} ${sl_PRIVATE_CLASSES} PRIVATE) - _classes(${LIBRARY_NAME} ${sl_PUBLIC_CLASSES} PUBLIC) - - set(PXR_ALL_LIBS - "${PXR_ALL_LIBS} ${LIBRARY_NAME}" - CACHE - INTERNAL - "Aggregation of all internal libraries." - ) - - add_library(${LIBRARY_NAME} - SHARED - ${sl_CPPFILES} ${${LIBRARY_NAME}_CPPFILES} - ${sl_PUBLIC_HEADERS} ${${LIBRARY_NAME}_PUBLIC_HEADERS} - ${sl_PRIVATE_HEADERS} ${${LIBRARY_NAME}_PRIVATE_HEADERS} - ) - - if(sl_PYTHON_FILES) - _install_python(${LIBRARY_NAME} - FILES ${sl_PYTHON_FILES} - ) - endif() - - # Convert the name of the library into the python module name - # , e.g. _tf.so -> Tf. This is later used to determine the eventual - # install location as well as for inclusion into the __init__.py's - # __all__ list. - _get_python_module_name(${LIBRARY_NAME} pyModuleName) - - # If we are building a python library, we want it to have the name - # _foo.so and install to ${project}/lib/python/${project}/${libname} - if(sl_PYTHON_LIBRARY) - # Always install under the 'pxr' module, rather than base on the - # project name. This makes importing consistent, e.g. - # 'from pxr import X'. Additionally, python libraries always install - # into the default lib install, not into the third_party subdirectory - # or similar. - set(LIB_INSTALL_PREFIX "lib/python/pxr/${pyModuleName}") - - set_property(GLOBAL - APPEND PROPERTY PXR_PYTHON_MODULES ${pyModuleName} - ) - - # Python modules for third_party libs are installed into the root - # pxr/lib/python but need to be able to access their corresponding - # library which lives in third_party/${pkg}/lib - set(rpath ${CMAKE_INSTALL_RPATH}) - if (PXR_INSTALL_SUBDIR) - set(rpath "$ORIGIN/../../../../${PXR_INSTALL_SUBDIR}/lib:${rpath}") - endif() - - set_target_properties(${LIBRARY_NAME} - PROPERTIES - PREFIX "" - FOLDER "${PXR_PREFIX}/_python" - INSTALL_RPATH ${rpath} - ) - else() - _get_install_dir(lib LIB_INSTALL_PREFIX) - _get_share_install_dir(SHARE_INSTALL_PREFIX) - - set(PLUGINS_PREFIX ${SHARE_INSTALL_PREFIX}/plugins) - - set_target_properties(${LIBRARY_NAME} - PROPERTIES - FOLDER "${PXR_PREFIX}" - ) - endif() - - if(PXR_INSTALL_SUBDIR) - set(HEADER_INSTALL_PREFIX - "${CMAKE_INSTALL_PREFIX}/${PXR_INSTALL_SUBDIR}/include/${PXR_PREFIX}/${LIBRARY_NAME}") - else() - set(HEADER_INSTALL_PREFIX - "${CMAKE_INSTALL_PREFIX}/include/${PXR_PREFIX}/${LIBRARY_NAME}") - endif() - - if(PXR_INSTALL_LOCATION) - set(installLocation ${PXR_INSTALL_LOCATION}) - else() - set(installLocation ${CMAKE_INSTALL_PREFIX}/${PLUGINS_PREFIX}) - endif() - - set_target_properties(${LIBRARY_NAME} - PROPERTIES COMPILE_DEFINITIONS - "MFB_PACKAGE_NAME=${PXR_PACKAGE};MFB_ALT_PACKAGE_NAME=${PXR_PACKAGE};MFB_PACKAGE_MODULE=${pyModuleName};PXR_USER_LOCATION=/usr/local/share/usd/plugins;PXR_BUILD_LOCATION=${CMAKE_INSTALL_PREFIX}/${PLUGINS_PREFIX};PXR_INSTALL_LOCATION=${installLocation}" - ) - - _install_headers(${LIBRARY_NAME} - FILES - ${sl_PUBLIC_HEADERS} - ${sl_PRIVATE_HEADERS} - ${${LIBRARY_NAME}_PUBLIC_HEADERS} - ${${LIBRARY_NAME}_PRIVATE_HEADERS} - PREFIX ${PXR_PREFIX} - ) - - string(TOUPPER ${LIBRARY_NAME} ucLibName) - - set_target_properties(${LIBRARY_NAME} - PROPERTIES - PUBLIC_HEADER - "${sl_PUBLIC_HEADERS};${${LIBRARY_NAME}_PUBLIC_HEADERS}" - INTERFACE_INCLUDE_DIRECTORIES - "" - DEFINE_SYMBOL - "${ucLibName}_EXPORTS" - ) - - # Install and include headers from the build directory. - get_filename_component( - PRIVATE_INC_DIR - "${CMAKE_BINARY_DIR}/include" - ABSOLUTE - ) - target_include_directories(${LIBRARY_NAME} - PRIVATE ${PRIVATE_INC_DIR} - ) - - # Allow #include'ing of headers within the same install subdir. - if (PXR_INSTALL_SUBDIR) - get_filename_component( - SUBDIR_INC_DIR - "${CMAKE_BINARY_DIR}/${PXR_INSTALL_SUBDIR}/include" - ABSOLUTE - ) - - target_include_directories(${LIBRARY_NAME} - PRIVATE ${SUBDIR_INC_DIR} - ) - endif() - - install(TARGETS ${LIBRARY_NAME} - EXPORT pxrTargets - LIBRARY DESTINATION ${LIB_INSTALL_PREFIX} - ARCHIVE DESTINATION ${LIB_INSTALL_PREFIX} - PUBLIC_HEADER DESTINATION ${HEADER_INSTALL_PREFIX} - ) - - export(TARGETS ${LIBRARY_NAME} - APPEND - FILE "${PROJECT_BINARY_DIR}/pxrTargets.cmake" - ) - - if (PXR_MALLOC_LIBRARY) - target_link_libraries(${LIBRARY_NAME} - ${sl_LIBRARIES} - ${PXR_MALLOC_LIBRARY} - ) - else() - target_link_libraries(${LIBRARY_NAME} - ${sl_LIBRARIES} - ) - endif() - - # Include system headers before our own. We define several headers - # that conflict; for example, half.h in EXR versus gf - if (sl_INCLUDE_DIRS) - target_include_directories(${LIBRARY_NAME} - BEFORE - PUBLIC - ${sl_INCLUDE_DIRS} - ) - endif() - - # Build python module. - if(DEFINED sl_PYMODULE_CPPFILES) - pxr_shared_library( - "_${LIBRARY_NAME}" - PYTHON_LIBRARY - CPPFILES ${sl_PYMODULE_CPPFILES} - LIBRARIES ${LIBRARY_NAME} - ) - endif() - - if (sl_RESOURCE_FILES) - _install_resource_files(${sl_RESOURCE_FILES}) - endif() -endfunction() # pxr_shared_library - -function(pxr_static_library LIBRARY_NAME) - set(multiValueArgs - PUBLIC_CLASSES - PUBLIC_HEADERS - PRIVATE_CLASSES - PRIVATE_HEADERS - CPPFILES - LIBRARIES - INCLUDE_DIRS - ) - - cmake_parse_arguments(sl - "${options}" - "" - "${multiValueArgs}" - ${ARGN} - ) - - _classes(${LIBRARY_NAME} ${sl_PRIVATE_CLASSES} PRIVATE) - _classes(${LIBRARY_NAME} ${sl_PUBLIC_CLASSES} PUBLIC) - - set(PXR_ALL_LIBS - "${PXR_ALL_LIBS} ${LIBRARY_NAME}" - CACHE - INTERNAL - "Aggregation of all internal libraries." - ) - - add_library(${LIBRARY_NAME} - STATIC - ${sl_CPPFILES} ${${LIBRARY_NAME}_CPPFILES} - ${sl_PUBLIC_HEADERS} ${${LIBRARY_NAME}_PUBLIC_HEADERS} - ${sl_PRIVATE_HEADERS} ${${LIBRARY_NAME}_PRIVATE_HEADERS} - ) - - # Even though this library is static, still want to build with -fPIC - set_target_properties(${LIBRARY_NAME} - PROPERTIES POSITION_INDEPENDENT_CODE ON - ) - - if(PXR_INSTALL_SUBDIR) - set(HEADER_INSTALL_PREFIX - "${CMAKE_INSTALL_PREFIX}/${PXR_INSTALL_SUBDIR}/include/${PXR_PREFIX}/${LIBRARY_NAME}") - else() - set(HEADER_INSTALL_PREFIX - "${CMAKE_INSTALL_PREFIX}/include/${PXR_PREFIX}/${LIBRARY_NAME}") - endif() - - set_target_properties(${LIBRARY_NAME} - PROPERTIES COMPILE_DEFINITIONS - "MFB_PACKAGE_NAME=${PXR_PACKAGE};MFB_ALT_PACKAGE_NAME=${PXR_PACKAGE}" - ) - - # Always bake the rpath. - set_target_properties(${LIBRARY_NAME} - PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE - ) - - _install_headers(${LIBRARY_NAME} - FILES - ${sl_PUBLIC_HEADERS} - ${sl_PRIVATE_HEADERS} - ${${LIBRARY_NAME}_PUBLIC_HEADERS} - ${${LIBRARY_NAME}_PRIVATE_HEADERS} - PREFIX ${PXR_PREFIX} - ) - - set_target_properties(${LIBRARY_NAME} - PROPERTIES - PUBLIC_HEADER - "${sl_PUBLIC_HEADERS};${${LIBRARY_NAME}_PUBLIC_HEADERS}" - INTERFACE_INCLUDE_DIRECTORIES "" - ) -# Install and include headers from the build directory. - get_filename_component( - PRIVATE_INC_DIR - "${CMAKE_BINARY_DIR}/include" - ABSOLUTE - ) - target_include_directories(${LIBRARY_NAME} - PRIVATE ${PRIVATE_INC_DIR} - ) - - _get_install_dir(lib LIB_INSTALL_PREFIX) - - # Allow #include'ing of headers within the same install subdir. - if (PXR_INSTALL_SUBDIR) - get_filename_component( - SUBDIR_INC_DIR - "${CMAKE_BINARY_DIR}/${PXR_INSTALL_SUBDIR}/include" - ABSOLUTE - ) - - target_include_directories(${LIBRARY_NAME} - PRIVATE ${SUBDIR_INC_DIR} - ) - endif() - - install(TARGETS ${LIBRARY_NAME} - EXPORT pxrTargets - ARCHIVE DESTINATION ${LIB_INSTALL_PREFIX} - PUBLIC_HEADER DESTINATION ${HEADER_INSTALL_PREFIX} - ) - - export(TARGETS ${LIBRARY_NAME} - APPEND - FILE "${PROJECT_BINARY_DIR}/pxrTargets.cmake" - ) - - if (PXR_MALLOC_LIBRARY) - target_link_libraries(${LIBRARY_NAME} - ${sl_LIBRARIES} - ) - else() - target_link_libraries(${LIBRARY_NAME} - ${sl_LIBRARIES} - ${PXR_MALLOC_LIBRARY} - ) - endif() - - # Include system headers before our own. We define several headers - # that conflict; for example, half.h in EXR versus gf - if (sl_INCLUDE_DIRS) - target_include_directories(${LIBRARY_NAME} - BEFORE - PUBLIC - ${sl_INCLUDE_DIRS} - ) - endif() -endfunction() # pxr_static_library - -function(pxr_plugin PLUGIN_NAME) - set(options - KATANA_PLUGIN - ) - set(oneValueArgs - PREFIX - ) - set(multiValueArgs - PUBLIC_CLASSES - PUBLIC_HEADERS - PRIVATE_CLASSES - PRIVATE_HEADERS - CPPFILES - PYMODULE_CPPFILES - PYTHON_FILES - LIBRARIES - INCLUDE_DIRS - RESOURCE_FILES - ) - - cmake_parse_arguments(sl - "${options}" - "${oneValueArgs}" - "${multiValueArgs}" - ${ARGN} - ) - - _classes(${PLUGIN_NAME} ${sl_PRIVATE_CLASSES} PRIVATE) - _classes(${PLUGIN_NAME} ${sl_PUBLIC_CLASSES} PUBLIC) - - add_library(${PLUGIN_NAME} - SHARED - ${sl_CPPFILES} ${${PLUGIN_NAME}_CPPFILES} - ${sl_PUBLIC_HEADERS} ${${PLUGIN_NAME}_PUBLIC_HEADERS} - ${sl_PRIVATE_HEADERS} ${${PLUGIN_NAME}_PRIVATE_HEADERS} - ) - - if(sl_PYTHON_FILES) - _install_python(${PLUGIN_NAME} - FILES ${sl_PYTHON_FILES} - ) - endif() - - # Plugins do not have a lib* prefix like usual shared libraries - set_target_properties(${PLUGIN_NAME} PROPERTIES PREFIX "") - - if (PXR_INSTALL_SUBDIR) - set(PLUGIN_INSTALL_PREFIX "${PXR_INSTALL_SUBDIR}/plugin") - set(HEADER_INSTALL_PREFIX - "${CMAKE_INSTALL_PREFIX}/${PXR_INSTALL_SUBDIR}/include/${PXR_PREFIX}/${PLUGIN_NAME}") - else() - set(PLUGIN_INSTALL_PREFIX "plugin") - set(HEADER_INSTALL_PREFIX - "${CMAKE_INSTALL_PREFIX}/include/${PXR_PREFIX}/${PLUGIN_NAME}") - endif() - - # Katana plugins install into a specific sub directory structure. Shared - # objects, for example, install into plugin/Libs - if (sl_KATANA_PLUGIN) - set(PLUGIN_INSTALL_PREFIX ${PLUGIN_INSTALL_PREFIX}/Libs) - - # Ensure the katana plugin can pick up the top-level libs and the - # top-level katana/libs - set(rpath ${CMAKE_INSTALL_RPATH}) - set(rpath "$ORIGIN/../../lib:$ORIGIN/../../../../lib:${rpath}") - - set_target_properties(${PLUGIN_NAME} - PROPERTIES - INSTALL_RPATH ${rpath} - ) - else() - # Ensure this plugin can find the libs for its matching component, e.g. - # maya/plugin/px_usdIO.so can find maya/lib/*.so - set_target_properties(${PLUGIN_NAME} - PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_RPATH}:$ORIGIN/../lib" - ) - endif() - - set_target_properties(${PLUGIN_NAME} - PROPERTIES COMPILE_DEFINITIONS - "MFB_PACKAGE_NAME=${PXR_PACKAGE};MFB_ALT_PACKAGE_NAME=${PXR_PACKAGE}" - ) - - _install_headers(${PLUGIN_NAME} - FILES - ${sl_PUBLIC_HEADERS} - ${sl_PRIVATE_HEADERS} - ${${PLUGIN_NAME}_PUBLIC_HEADERS} - ${${PLUGIN_NAME}_PRIVATE_HEADERS} - PREFIX ${PXR_PREFIX} - ) - - set_target_properties(${PLUGIN_NAME} - PROPERTIES - PUBLIC_HEADER - "${sl_PUBLIC_HEADERS};${${PLUGIN_NAME}_PUBLIC_HEADERS}" - INTERFACE_INCLUDE_DIRECTORIES "" - ) - - # Install and include headers from the build directory. - get_filename_component( - PRIVATE_INC_DIR - "${CMAKE_BINARY_DIR}/include" - ABSOLUTE - ) - target_include_directories(${PLUGIN_NAME} - PRIVATE ${PRIVATE_INC_DIR} - ) - - # Allow #include'ing of headers within the same install subdir. - if (PXR_INSTALL_SUBDIR) - get_filename_component( - SUBDIR_INC_DIR - "${CMAKE_BINARY_DIR}/${PXR_INSTALL_SUBDIR}/include" - ABSOLUTE - ) - - target_include_directories(${PLUGIN_NAME} - PRIVATE ${SUBDIR_INC_DIR} - ) - endif() - - install(TARGETS ${PLUGIN_NAME} - EXPORT pxrTargets - LIBRARY DESTINATION ${PLUGIN_INSTALL_PREFIX} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_PREFIX} - PUBLIC_HEADER DESTINATION ${HEADER_INSTALL_PREFIX} - ) - - export(TARGETS ${PLUGIN_NAME} - APPEND - FILE "${PROJECT_BINARY_DIR}/pxrTargets.cmake" - ) - - if (PXR_MALLOC_LIBRARY) - target_link_libraries(${PLUGIN_NAME} - ${sl_LIBRARIES} - ) - else() - target_link_libraries(${PLUGIN_NAME} - ${sl_LIBRARIES} - ${PXR_MALLOC_LIBRARY} - ) - endif() - - # Include system headers before our own. We define several headers - # that conflict; for example, half.h in EXR versus gf - if (sl_INCLUDE_DIRS) - target_include_directories(${PLUGIN_NAME} - BEFORE - PUBLIC - ${sl_INCLUDE_DIRS} - ) - endif() - - if (sl_RESOURCE_FILES) - _get_install_dir(plugin PLUGINS_PREFIX) - set(LIBRARY_NAME ${PLUGIN_NAME}) - - _install_resource_files(${sl_RESOURCE_FILES}) - endif() - - # Build python module. - if(DEFINED sl_PYMODULE_CPPFILES) - pxr_shared_library( - "_${PLUGIN_NAME}" - PYTHON_LIBRARY - CPPFILES ${sl_PYMODULE_CPPFILES} - LIBRARIES ${PLUGIN_NAME} - ) - endif() -endfunction() # pxr_plugin - -function(pxr_setup_python) - get_property(pxrPythonModules GLOBAL PROPERTY PXR_PYTHON_MODULES) - - # A new list where each python module is quoted - set(converted "") - foreach(module ${pxrPythonModules}) - list(APPEND converted "'${module}'") - endforeach() - - # Join these with a ', ' - string(REPLACE ";" ", " pyModulesStr "${converted}") - - # Install a pxr __init__.py with an appropriate __all__ - _get_install_dir(lib/python/pxr installPrefix) - install(CODE - "file(WRITE \"${CMAKE_INSTALL_PREFIX}/${installPrefix}/__init__.py\" \"__all__ = [${pyModulesStr}]\n\")" - ) -endfunction() # pxr_setup_python - -function (pxr_create_test_module MODULE_NAME) - cmake_parse_arguments(tm "" "INSTALL_PREFIX;SOURCE_DIR" "" ${ARGN}) - - if (NOT tm_SOURCE_DIR) - set(tm_SOURCE_DIR testenv) - endif() - - # Look specifically for an __init__.py and a plugInfo.json prefixed by the - # module name. These will be installed without the module prefix. - set(initPyFile ${tm_SOURCE_DIR}/${MODULE_NAME}__init__.py) - set(plugInfoFile ${tm_SOURCE_DIR}/${MODULE_NAME}_plugInfo.json) - - if (EXISTS ${initPyFile}) - install( - FILES - ${initPyFile} - RENAME - __init__.py - DESTINATION - tests/${tm_INSTALL_PREFIX}/lib/python/${MODULE_NAME} - ) - endif() - - if (EXISTS ${plugInfoFile}) - install( - FILES - ${plugInfoFile} - RENAME - plugInfo.json - DESTINATION - tests/${tm_INSTALL_PREFIX}/lib/python/${MODULE_NAME} - ) - endif() -endfunction() # pxr_create_test_module - -function(pxr_build_test_shared_lib LIBRARY_NAME) - cmake_parse_arguments(bt - "" "" - "LIBRARIES;CPPFILES" - ${ARGN} - ) - - add_library(${LIBRARY_NAME} - SHARED - ${bt_CPPFILES} - ) - target_link_libraries(${LIBRARY_NAME} - ${bt_LIBRARIES} - ) - set_target_properties(${LIBRARY_NAME} - PROPERTIES - INSTALL_RPATH_USE_LINK_PATH TRUE - FOLDER "${PXR_PREFIX}/tests/lib" - ) - - # We always want this test to build after the package it's under, even if - # it doesn't link directly. This ensures that this test is able to include - # headers from its parent package. - add_dependencies(${LIBRARY_NAME} ${PXR_PACKAGE}) - - # Test libraries can include the private headers of their parent PXR_PACKAGE - # library - target_include_directories(${LIBRARY_NAME} - PRIVATE $ - ) - - install(TARGETS ${LIBRARY_NAME} - LIBRARY DESTINATION "tests/lib" - ARCHIVE DESTINATION "tests/lib" - ) -endfunction() # pxr_build_test_shared_lib - -function(pxr_build_test TEST_NAME) - cmake_parse_arguments(bt - "" "" - "LIBRARIES;CPPFILES" - ${ARGN} - ) - - add_executable(${TEST_NAME} - ${bt_CPPFILES} - ) - target_link_libraries(${TEST_NAME} - ${bt_LIBRARIES} - ) - target_include_directories(${TEST_NAME} - PRIVATE $ - ) - set_target_properties(${TEST_NAME} - PROPERTIES - INSTALL_RPATH_USE_LINK_PATH TRUE - POSITION_INDEPENDENT_CODE ON - FOLDER "${PXR_PREFIX}/tests/bin" - ) - - install(TARGETS ${TEST_NAME} - RUNTIME DESTINATION "tests" - ) -endfunction() # pxr_build_test - -function(pxr_test_scripts) - foreach(file ${ARGN}) - get_filename_component(destFile ${file} NAME_WE) - install( - PROGRAMS ${file} - DESTINATION tests - RENAME ${destFile} - ) - endforeach() -endfunction() # pxr_test_scripts - -function(pxr_install_test_dir) - cmake_parse_arguments(bt - "" - "SRC;DEST" - "" - ${ARGN} - ) - - install( - DIRECTORY ${bt_SRC}/ - DESTINATION tests/ctest/${bt_DEST} - ) -endfunction() # pxr_install_test_dir - -function(pxr_register_test TEST_NAME) - cmake_parse_arguments(bt - "PYTHON" - "COMMAND;STDOUT_REDIRECT;STDERR_REDIRECT;DIFF_COMPARE;EXPECTED_RETURN_CODE;TESTENV" - "ENV" - ${ARGN} - ) - - # This harness is a filter which allows us to manipulate the test run, - # e.g. by changing the environment, changing the expected return code, etc. - set(testWrapperCmd ${PROJECT_SOURCE_DIR}/cmake/macros/testWrapper.py --verbose) - - if (bt_STDOUT_REDIRECT) - set(testWrapperCmd ${testWrapperCmd} --stdout-redirect=${bt_STDOUT_REDIRECT}) - endif() - - if (bt_STDERR_REDIRECT) - set(testWrapperCmd ${testWrapperCmd} --stderr-redirect=${bt_STDERR_REDIRECT}) - endif() - - # Not all tests will have testenvs, but if they do let the wrapper know so - # it can copy the testenv contents into the run directory. By default, - # assume the testenv has the same name as the test but allow it to be - # overridden by specifying TESTENV. - if (bt_TESTENV) - set(testenvDir ${CMAKE_INSTALL_PREFIX}/tests/ctest/${bt_TESTENV}) - else() - set(testenvDir ${CMAKE_INSTALL_PREFIX}/tests/ctest/${TEST_NAME}) - endif() - - set(testWrapperCmd ${testWrapperCmd} --testenv-dir=${testenvDir}) - - if (bt_DIFF_COMPARE) - set(testWrapperCmd ${testWrapperCmd} --diff-compare=${bt_DIFF_COMPARE}) - - # For now the baseline directory is assumed by convention from the test - # name. There may eventually be cases where we'd want to specify it by - # an argument though. - set(baselineDir ${testenvDir}/baseline) - set(testWrapperCmd ${testWrapperCmd} --baseline-dir=${baselineDir}) - endif() - - if (bt_EXPECTED_RETURN_CODE) - set(testWrapperCmd ${testWrapperCmd} - --expected-return-code=${bt_EXPECTED_RETURN_CODE}) - endif() - - if (bt_ENV) - foreach(env ${bt_ENV}) - set(testWrapperCmd ${testWrapperCmd} --env-var=${env}) - endforeach() - endif() - - # Ensure that Python imports the Python files built by this build - set(testWrapperCmd ${testWrapperCmd} - --env-var=PYTHONPATH=${CMAKE_INSTALL_PREFIX}/lib/python:${PYTHON_PATH}) - - # Ensure we run with the python executable known to the build - if (bt_PYTHON) - set(testCmd "${PYTHON_EXECUTABLE} ${bt_COMMAND}") - else() - set(testCmd "${bt_COMMAND}") - endif() - - add_test( - NAME ${TEST_NAME} - COMMAND ${PYTHON_EXECUTABLE} ${testWrapperCmd} ${testCmd} - ) -endfunction() # pxr_register_test - -function(pxr_setup_plugins) - _get_share_install_dir(SHARE_INSTALL_PREFIX) - - # Install a top-level plugInfo.json in the shared area - install(CODE - "file(WRITE \"${CMAKE_INSTALL_PREFIX}/${SHARE_INSTALL_PREFIX}/plugins/plugInfo.json\" \"{\n \\\"Includes\\\": [ \\\"*/resources/\\\" ]\n}\")" - - # Install a top-level plugInfo.json in the external plugins area - install(CODE - "file(WRITE \"${CMAKE_INSTALL_PREFIX}/plugin/plugInfo.json\" \"{\n \\\"Includes\\\": [ \\\"*/resources/\\\" ]\n}\")" - ) - ) -endfunction() # pxr_setup_plugins - -function(pxr_katana_nodetypes NODE_TYPES) - set(installDir ${PXR_INSTALL_SUBDIR}/plugin/Plugins/NodeTypes) - - set(pyFiles "") - set(importLines "") - - foreach (nodeType ${NODE_TYPES}) - list(APPEND pyFiles ${nodeType}.py) - set(importLines "import ${nodeType}\n") - endforeach() - - install(PROGRAMS - ${pyFiles} - DESTINATION ${installDir} - ) - - # Install a __init__.py that imports all the known node types - install(CODE - "file(WRITE \"${CMAKE_INSTALL_PREFIX}/${installDir}/__init__.py\" \"${importLines}\")" - ) -endfunction() # pxr_katana_nodetypes - diff --git a/cmake/macros/compilePython.py b/cmake/macros/compilePython.py deleted file mode 100755 index 58ab77ca..00000000 --- a/cmake/macros/compilePython.py +++ /dev/null @@ -1,66 +0,0 @@ -# -# Copyright 2016 Pixar -# -# Licensed under the Apache License, Version 2.0 (the "Apache License") -# with the following modification; you may not use this file except in -# compliance with the Apache License and the following modification to it: -# Section 6. Trademarks. is deleted and replaced with: -# -# 6. Trademarks. This License does not grant permission to use the trade -# names, trademarks, service marks, or product names of the Licensor -# and its affiliates, except as required to comply with Section 4(c) of -# the License and to reproduce the content of the NOTICE file. -# -# You may obtain a copy of the Apache License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the Apache License with the above modification is -# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the Apache License for the specific -# language governing permissions and limitations under the Apache License. -# -# -# Usage: compilePython source.py dest.pyc -# -# This program compiles python code, providing a reasonable -# gcc-esque error message if errors occur. -# -# parameters: -# src.py - the source file to report errors for -# file.py - the installed location of the file -# file.pyc - the precompiled python file - -import sys -import py_compile - -if len(sys.argv) < 4: - print "Usage: %s src.py file.py file.pyc" % sys.argv[0] - sys.exit(1) - -try: - py_compile.compile(sys.argv[2], sys.argv[3], sys.argv[1], doraise=True) -except py_compile.PyCompileError as compileError: - exc_value = compileError.exc_value - if compileError.exc_type_name == SyntaxError.__name__: - # py_compile.compile stashes the type name and args of the exception - # in the raised PyCompileError rather than the exception itself. This - # is especially annoying because the args member of some SyntaxError - # instances are lacking the source information tuple, but do have a - # usable lineno. - error = exc_value[0] - try: - linenumber = exc_value[1][1] - line = exc_value[1][3] - print '%s:%s: %s: "%s"' % (sys.argv[1], linenumber, error, line) - except IndexError: - print '%s: Syntax error: "%s"' % (sys.argv[1], error) - else: - print "%s: Unhandled compile error: (%s) %s" % ( - sys.argv[1], compileError.exc_type_name, exc_value) - sys.exit(1) -except: - exc_type, exc_value, exc_traceback = sys.exc_info() - print "%s: Unhandled exception: %s" % (sys.argv[1], exc_value) - sys.exit(1) diff --git a/cmake/macros/testWrapper.py b/cmake/macros/testWrapper.py deleted file mode 100644 index 43d29656..00000000 --- a/cmake/macros/testWrapper.py +++ /dev/null @@ -1,163 +0,0 @@ -# -# Copyright 2016 Pixar -# -# Licensed under the Apache License, Version 2.0 (the "Apache License") -# with the following modification; you may not use this file except in -# compliance with the Apache License and the following modification to it: -# Section 6. Trademarks. is deleted and replaced with: -# -# 6. Trademarks. This License does not grant permission to use the trade -# names, trademarks, service marks, or product names of the Licensor -# and its affiliates, except as required to comply with Section 4(c) of -# the License and to reproduce the content of the NOTICE file. -# -# You may obtain a copy of the Apache License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the Apache License with the above modification is -# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the Apache License for the specific -# language governing permissions and limitations under the Apache License. -# -# -# Usage: testWrapper.py -# -# Wrapper for test commands which allows us to control the test environment -# and provide additional conditions for passing. -# -# CTest only cares about the eventual return code of the test command it runs -# with 0 being success and anything else indicating failure. This script allows -# us to wrap a test command and provide additional conditions which must be met -# for that test to pass. -# -# Current features include: -# - specifying non-zero return codes -# - comparing output files against a baseline -# -import argparse -import os -import shutil -import subprocess -import sys -import tempfile - -def _parseArgs(): - parser = argparse.ArgumentParser(description='USD test wrapper') - parser.add_argument('--stdout-redirect', type=str, - help='File to redirect stdout to') - parser.add_argument('--stderr-redirect', type=str, - help='File to redirect stderr to') - parser.add_argument('--diff-compare', type=str, - help=('Compare output file with a file in the baseline-dir of the ' - 'same name')) - parser.add_argument('--testenv-dir', type=str, - help='Testenv directory to copy into test run directory') - parser.add_argument('--baseline-dir', - help='Baseline directory to use with --diff-compare') - parser.add_argument('--expected-return-code', type=int, default=0, - help='Expected return code of this test.') - parser.add_argument('--env-var', dest='envVars', default=[], type=str, - action='append', help='Variable to set in the test environment.') - parser.add_argument('--verbose', '-v', action='store_true', - help='Verbose output.') - parser.add_argument('cmd', metavar='CMD', type=str, nargs='+', - help='Test command to run') - return parser.parse_args() - -def _diff(fileName, baselineDir, verbose): - # Some test envs are contained within a non-specific subdirectory, if that - # exists then use it for the baselines - nonSpecific = os.path.join(baselineDir, 'non-specific') - if os.path.isdir(nonSpecific): - baselineDir = nonSpecific - - # Use the diff program, rather than filecmp or similar because it's - # possible we might want to specify other diff programs in the future. - cmd = ['/usr/bin/diff', os.path.join(baselineDir, fileName), fileName] - if verbose: - print "cmd: {0}".format(cmd) - - # This will print any diffs to stdout which is a nice side-effect - return subprocess.call(cmd) == 0 - -def _copyTree(src, dest): - ''' Copies the contents of src into dest.''' - if not os.path.exists(dest): - os.makedirs(dest) - for item in os.listdir(src): - s = os.path.join(src, item) - d = os.path.join(dest, item) - if os.path.isdir(s): - shutil.copytree(s, d) - else: - shutil.copy2(s, d) - -if __name__ == '__main__': - args = _parseArgs() - - if args.diff_compare and not args.baseline_dir: - print sys.stderr, "Error: --baseline-dir must be specified with " \ - "--diff-compare" - sys.exit(1) - - testDir = tempfile.mkdtemp() - os.chdir(testDir) - if args.verbose: - print "chdir: {0}".format(testDir) - - # Copy the contents of the testenv directory into our test run directory so - # the test has it's own copy that it can reference and possibly modify. - if args.testenv_dir and os.path.isdir(args.testenv_dir): - if args.verbose: - print "copying testenv dir: {0}".format(args.testenv_dir) - try: - _copyTree(args.testenv_dir, os.getcwd()) - except Exception as e: - print sys.stderr, "Error: copying testenv directory: {0}".format(e) - sys.exit(1) - - # Add any envvars specified with --env-var options into the environment - env = os.environ.copy() - for varStr in args.envVars: - try: - k, v = varStr.split('=') - env[k] = v - except IndexError: - print sys.stderr, "Error: envvar '{0}' not of the form key=value" \ - .format(varStr) - sys.exit(1) - - fout = open(args.stdout_redirect, 'w') if args.stdout_redirect else None - ferr = open(args.stderr_redirect, 'w') if args.stderr_redirect else None - try: - retcode = subprocess.call(args.cmd, shell=True, env=env, - stdout=(fout or sys.stdout), stderr=(ferr or sys.stderr)) - finally: - if fout: - fout.close() - if ferr: - ferr.close() - - # subprocess.call returns -N if the process raised signal N. Convert this - # to the standard positive error code matching that signal. e.g. if the - # process encounters an SIGABRT signal it will return -6, but we really - # want the exit code 134 as that is what the script would return when run - # from the shell. This is well defined to be 128 + (signal number). - if retcode < 0: - retcode = 128 + abs(retcode) - - # The return code didn't match our expected error code, even if it returned - # 0 -- this is a failure. - if retcode != args.expected_return_code: - sys.exit(1) - - # If desired, diff the provided file (must be generated by the test somehow) - # with a file of the same name in the baseline directory - if (args.diff_compare and - not _diff(args.diff_compare, args.baseline_dir, args.verbose)): - sys.exit(1) - - sys.exit(0) - diff --git a/cmake/modules/FindGLEW.cmake b/cmake/modules/FindGLEW.cmake deleted file mode 100644 index 60d715b0..00000000 --- a/cmake/modules/FindGLEW.cmake +++ /dev/null @@ -1,128 +0,0 @@ -# -# Copyright 2016 Pixar -# -# Licensed under the Apache License, Version 2.0 (the "Apache License") -# with the following modification; you may not use this file except in -# compliance with the Apache License and the following modification to it: -# Section 6. Trademarks. is deleted and replaced with: -# -# 6. Trademarks. This License does not grant permission to use the trade -# names, trademarks, service marks, or product names of the Licensor -# and its affiliates, except as required to comply with Section 4(c) of -# the License and to reproduce the content of the NOTICE file. -# -# You may obtain a copy of the Apache License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the Apache License with the above modification is -# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the Apache License for the specific -# language governing permissions and limitations under the Apache License. -# -# Try to find GLEW library and include path. -# Once done this will define -# -# GLEW_FOUND -# GLEW_INCLUDE_DIR -# GLEW_LIBRARY -# - -include(FindPackageHandleStandardArgs) - -if (WIN32) - find_path(GLEW_INCLUDE_DIR - NAMES - GL/glew.h - HINTS - "${GLEW_LOCATION}/include" - "$ENV{GLEW_LOCATION}/include" - PATHS - "$ENV{PROGRAMFILES}/GLEW/include" - "${PROJECT_SOURCE_DIR}/extern/glew/include" - DOC "The directory where GL/glew.h resides" ) - - if ("${CMAKE_GENERATOR}" MATCHES "[Ww]in64") - set(ARCH x64) - else() - set(ARCH x86) - endif() - - find_library(GLEW_LIBRARY - NAMES - glew GLEW glew32s glew32 - HINTS - "${GLEW_LOCATION}/lib" - "$ENV{GLEW_LOCATION}/lib" - PATHS - "$ENV{PROGRAMFILES}/GLEW/lib" - "${PROJECT_SOURCE_DIR}/extern/glew/bin" - "${PROJECT_SOURCE_DIR}/extern/glew/lib" - PATH_SUFFIXES - Release/${ARCH} - DOC "The GLEW library") -endif () - -if (${CMAKE_HOST_UNIX}) - find_path( GLEW_INCLUDE_DIR - NAMES - GL/glew.h - HINTS - "${GLEW_LOCATION}/include" - "$ENV{GLEW_LOCATION}/include" - PATHS - /usr/include - /usr/local/include - /sw/include - /opt/local/include - NO_DEFAULT_PATH - DOC "The directory where GL/glew.h resides" - ) - find_library( GLEW_LIBRARY - NAMES - GLEW glew - HINTS - "${GLEW_LOCATION}/lib" - "$ENV{GLEW_LOCATION}/lib" - PATHS - "${GLEW_LOCATION}/lib" - /usr/lib64 - /usr/lib - /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} - /usr/local/lib64 - /usr/local/lib - /sw/lib - /opt/local/lib - NO_DEFAULT_PATH - DOC "The GLEW library") -endif () - - -if (GLEW_INCLUDE_DIR AND EXISTS "${GLEW_INCLUDE_DIR}/GL/glew.h") - - file(STRINGS "${GLEW_INCLUDE_DIR}/GL/glew.h" GLEW_4_2 REGEX "^#define GL_VERSION_4_2.*$") - if (GLEW_4_2) - set(OPENGL_4_2_FOUND TRUE) - else () - message(WARNING - "glew-1.7.0 or newer needed for supporting OpenGL 4.2 dependent features" - ) - endif () - - file(STRINGS "${GLEW_INCLUDE_DIR}/GL/glew.h" GLEW_4_3 REGEX "^#define GL_VERSION_4_3.*$") - if (GLEW_4_3) - SET(OPENGL_4_3_FOUND TRUE) - else () - message(WARNING - "glew-1.9.0 or newer needed for supporting OpenGL 4.3 dependent features" - ) - endif () - -endif () - -find_package_handle_standard_args(GLEW - REQUIRED_VARS - GLEW_INCLUDE_DIR - GLEW_LIBRARY -) diff --git a/docs/basicUsage.md b/docs/basicUsage.md index 6b12f44b..93c0c201 100644 --- a/docs/basicUsage.md +++ b/docs/basicUsage.md @@ -28,19 +28,3 @@ Now: - If you want to make these transforms permanent, from the menu, select "USD->Proxy Shape->Import Transforms as Transforms" (at the moment, you can only choose to create transforms for all of the objects in the scene, not just some of them.. it's a @todo). These transforms will be animated if the underlying USD data is animated - -##Python bindings -There aren't many python bindings in AL_USDMaya - at the moment just the "StageCache" Singleton class which allows python access to the set of in-memory stages - - -getting the USD stage (once you've created a proxy shape) -```python -from AL import usdmaya -stageCache = usdmaya.StageCache.Get() -stages = stageCache.GetAllStages() -if stages: - print stages[0] -``` -Note at the moment there's no way of easily knowing which stage corresponds to which proxy Shape. -You could probably work it out by looking at something like the identifier/rootLayer of each stage and matching to something in the proxy shape..? - diff --git a/docs/build.md b/docs/build.md index 505334d6..0e322fd1 100644 --- a/docs/build.md +++ b/docs/build.md @@ -1,9 +1,8 @@ # Building ## Build Requirements -- This project is buildable on a variety of Linux platforms (It has been tested extensively on CentOS 6.6) -- Experimental Windows build support. -- USD-0.8.4 built with ptex-2.0.40 (<2.0.41) +- This project is buildable on a variety of Linux platforms (It has been tested extensively on CentOS 6.6) and on Windows 7 (it's probably buildable on more recent versions also) +- USD-0.8.5 built with ptex-2.0.40 (<2.0.41) - [google test framework](https://github.com/google/googletest) (>1.8.0) to build and run the tests - GLEW: Maya (certainly up to 2018) uses a very old build of GLEW. We've found that both to use the latest OpenGL 4x features that Hydra exploits, and for stability reasons, you should use a newer version (e.g GLEW 2.0). We've had to LD_PRELOAD GLEW 2.0 to make this happen. diff --git a/docs/developer.md b/docs/developer.md index 4168735b..639053d7 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -458,6 +458,43 @@ Existing TF_DEBUG flags are: * ALUSDMAYA_LAYERS * ALUSDMAYA_DRAW * ALUSDMAYA_SELECTION +* ALUSDMAYA_RENDERER + +Within Maya itself, the MEL command AL_usdmaya_UsdDebugCommand allows you to list, disable, enable, and query the debug notices throughout USD and AL_USDMaya. +To query the list of available notices, simply execute: + +```c++ +print `AL_usdmaya_UsdDebugCommand -ls`; +``` +To enable a particular notice: + +```c++ +AL_usdmaya_UseDebugCommand -en "ALUSDMAYA_TRANSLATORS"; +``` + +To query the state of a particular notice, use the -st flag: + +```c++ +if(`AL_usdmaya_UseDebugCommand -st "ALUSDMAYA_TRANSLATORS"`) + print "ALUSDMAYA_TRANSLATORS is enabled\n"; +else + print "ALUSDMAYA_TRANSLATORS is disabled\n"; +``` +To disable a particular notice: + +```c++ +AL_usdmaya_UseDebugCommand -ds "ALUSDMAYA_TRANSLATORS"; +``` + +It should also be noted that the ```USD->Debug->TfDebug Options``` menu item will bring up a GUI that allows you to enable/disable all registered notices. + +If you wish to add additional notices for debugging C++, add the new entry within the DebugCodes.h and DebugCodes.cpp. It is then possible to format messages +targeting that new flag using the standard printf formatting: + +```c++ +TF_DEBUG(ALUSDMAYA_MY_CUSTOM_FLAG).Msg("Hello world, this is an int %d, and this is a string \"$s\"\n", 42, "hellllllo!"); +``` + ## running in batch mode @todo add doc diff --git a/docs/faq.md b/docs/faq.md index 8cd92fa0..033556dd 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -18,5 +18,5 @@ Ideally, ongoing - but we can't provide any guarantees about our response time ## How often do you do a release and/or push to the github repository Ideally, quite often - but again, we can't provide any guarantees. -## Does it build for Windows or Mac? -At the moment the plugin only builds on Linux. As USD support for Windows and MacOS stabilises, others can contribute this functionality if they wish. We only use Linux internally at Animal Logic. +## Does it build for Windows or Mac? +At the moment the plugin builds on both Linux and Windows. As USD support for MacOS stabilises, others can contribute this functionality if they wish. We only use Linux internally at Animal Logic so that is the most tested path. Tests should also run on Windows diff --git a/docs/geometry.md b/docs/geometry.md new file mode 100644 index 00000000..6b73dc69 --- /dev/null +++ b/docs/geometry.md @@ -0,0 +1,197 @@ + +# Mesh Geometry: Overview + +The following document details the way in which Maya mesh data is imported and exported from USD. + +# Mesh Geometry: Polygons & Vertices + +When importing/exporting data from Maya, the mesh data is defined using an array of vertex positions, an array of vertex counts +_(one entry per face, defining how many vertices are contained in that face)_, and an array of vertex indices _(a flattened list +of all vertex indices)_. + +The following table describes the Maya and USD API calls that should be used to access mesh data. + +| Data | Maya API | UsdGeomMesh | +|--------------|---------------|-------------| +| Vertex Positions | MFnMesh::getRawPoints or MFnMesh::getPoints | +| Vertex Counts | First argument of MFnMesh::getVertices | +| Face Vertex Indices | Second argument of MFnMesh::getVertices | + + +# Mesh Geometry: Polygon Holes + +Within Maya, there are two methods of defining holes on mesh geometry, however only one method is supported for import/export +via AL_USDMaya _(and the second method will likely cause errors in the exported geometry)_. + +Within Maya the *performPolyHoleFace* command will tag a face as invisible _(You can also access this command via the +```Edit Mesh -> Assign Invisible Faces``` menu item)_. This information can be queried from USD via +```UsdGeomMesh::GetHoleIndicesAttr()```. The data stored is merely an array of indices that indicate which faces are tagged +as invisible. + +Maya also supports holes using the ```Mesh Tools -> Make Hole``` tool. Polygon holes created via this tool will not be exported +by AL_USDMaya _(and infact, are liable to lead to errors within the exported geometry data)_. + + +# Mesh Geometry: Vertex/Corner Creases + +Vertex creases assigned to mesh geometry will be exported into a pair of arrays, one to store the vertex indices the crease +has been applied to _(which maps into the Vertex Positions array)_, and an array of sharpness params that will match up with the +crease indices. + +The following table describes the Maya and USD API calls that should be used to access the vertex crease information: + + +| Data | Maya API | UsdGeomMesh | +|--------------|---------------|-------------| +| Vertex Crease Indices | The vertexIds param of MFnMesh::getCreaseVertices | UsdGeomMesh::GetCornerIndicesAttr | +| Vertex Crease Sharpness | The creaseData param of MFnMesh::getCreaseVertices | UsdGeomMesh::GetCornerSharpnessesAttr | + + +# Mesh Geometry: Edge Creases + +Edge creases on mesh geometry are defined using pairs of vertex indices that describe the edges that have crease weights assigned. +This implies that the edge crease indices array will always be twice the length of the crease weights array. + +The following table describes the Maya and USD API calls that should be used to access the edge crease information: + + +| Data | Maya API | UsdGeomMesh | +|--------------|---------------|-------------| +| Edge Crease Indices | The edgeIds param of MFnMesh::getCreaseEdges | UsdGeomMesh::GetCreaseIndicesAttr | +| Edge Crease Sharpness | The creaseData param of MFnMesh::getCreaseEdges | UsdGeomMesh::GetCornerSharpnessesAttr | +| Edge Crease Lengths | _unsupported_ | UsdGeomMesh::GetCreaseLengthsAttr | + + +# Mesh Geometry: Vertex Normals + +Vertex Normals are exported using interpolation modes of either faceVarying, UsdGeomTokens->vertex, UsdGeomTokens->uniform, +or UsdGeomTokens->constant. + +| Data | Maya API | UsdGeomMesh | +|--------------|---------------|-------------| +| Vertex Normals | MFnMesh::getRawNormals | UsdGeomPointBased::GetNormalsAttr | + + +# Mesh Geometry: Prim Vars (UV coords) + +UV coordinates stored within UsdGeomPrimvar objects, are exported as arrays of GfVec2f's with an optional set of indices. +The AL_USDMaya export has the ability to specify a compaction mode that at the lowest level, will simply copy the data +directly from Maya into USD _(i.e. an interpolation UsdGeomTokens->faceVarying, with indices)_. Additional modes exist +that add varying degrees of testing of the UV sets to decide whether they can be described using constant, uniform, +or vertex interpolation modes. It should be noted that higher compaction levels may result in smaller USD files on disk, +but at the expense of an additional computational overhead at export time. + +The following tables indicate the supported combinations of interpolation mode and primvar indices : + +| Interpolation Mode | Indexed | Export | Import | +|-----------------------------|---------|--------|--------| +| UsdGeomTokens->constant | No | Yes | Yes | +| UsdGeomTokens->vertex | No | Yes | Yes | +| UsdGeomTokens->vertex | Yes | No | Yes | +| UsdGeomTokens->uniform | No | Yes | Yes | +| UsdGeomTokens->uniform | Yes | No | Yes | +| UsdGeomTokens->faceVarying | No | Yes | Yes | +| UsdGeomTokens->faceVarying | Yes | Yes | Yes | + + +A summary of the compaction level, and the processing performed are detailed in this table: + + +| Compaction Mode | Description | +|----------------------------|-----------------------------------------| +| None | No tests performed, UV coordinates will be exported as faceVarying with indices | +| Basic | If all UV coords are the same, the mode will be constant; If the UV indices match the vertex indices, the interpolation mode will be vertex; otherwise the mode will be faceVarying with indices. | +| Medium | If there is a single UV assignment per face, the interpolation mode will be uniform. Otherwise, this mode performs the same tests as Basic. | +| Extensive | Where as the Medium and Basic levels perform tests based on the indices, the Extensive mode tests the actual UV coordinate data directly. This is far more likely to find cases of uniform/vertex interpolation, and will remap the data accordingly. As a result of comparisons with the UV coordinate data, the worst case processing time at export is greater. | + + +The following table indicates the interpolation modes that may result from a specific compaction mode. The asterix indicates +that a simplified index check is used rather than a full data check, so this may miss a number of cases in practice. It should +be noted that from a simplicity point of view, that always using a compaction mode of 'none' implies that code further down the +pipeline only needs to worry about UV data in a single format. If however you wish to ensure the smallest assets possible for +disk / network reasons, then the Extensive mode will give you that option _(although you will have to implement more complex +processing at render time)_ + + +| Interpolation Mode | None | Basic | Medium | Extensive | +|-----------------------------|---------|--------|--------|-----------| +| UsdGeomTokens->constant | No | Yes | Yes | Yes | +| UsdGeomTokens->vertex | No | Yes* | Yes* | Yes | +| UsdGeomTokens->uniform | No | No | Yes | Yes | +| UsdGeomTokens->faceVarying | No | No | No | Yes | +| UsdGeomTokens->faceVarying with Indices | Yes | Yes | Yes | Yes | + + +# Mesh Geometry: Prim Vars (colour sets) + +If a UsdGeomPrimvar contains arrays of 4D or 3D floating point values, then they will be treated as a colour set. +The behaviour when importing/exporting colour sets is mostly the same as for UV sets, however given that Maya does +not provide any indices for colour sets, the behaviour differs slightly for export data. + + +The following tables indicate the supported combinations of interpolation mode and primvar indices are supported for import and export: + +| Interpolation Mode | Indexed | Export | Import | +|-----------------------------|---------|--------|--------| +| UsdGeomTokens->constant | No | Yes | Yes | +| UsdGeomTokens->vertex | No | Yes | Yes | +| UsdGeomTokens->vertex | Yes | No | Yes | +| UsdGeomTokens->uniform | No | Yes | Yes | +| UsdGeomTokens->uniform | Yes | No | Yes | +| UsdGeomTokens->faceVarying | No | Yes | Yes | +| UsdGeomTokens->faceVarying | Yes | No | Yes | + +This implies that only the following interpolation modes will be exported from AL_USDMaya at present. +No attempt to generate indices will be made during export. + +| Interpolation Mode | None | Basic | Medium | Extensive | +|-----------------------------|---------|--------|--------|-----------| +| UsdGeomTokens->constant | No | Yes | Yes | Yes | +| UsdGeomTokens->vertex | No | Yes | Yes | Yes | +| UsdGeomTokens->uniform | No | No | Yes | Yes | +| UsdGeomTokens->faceVarying | Yes | Yes | Yes | Yes | + + +# Mesh Translation & Diffing + +When using the AL_usdmaya_TranslatePrim command to make modifications to Mesh data within Maya; when +converting the geometry from Maya back into USD, a diff process is run in order to determine which +_(if any)_ of the geometry components _(e.g. vertices, normals, uv sets, etc)_ have changed. If a +given component type has changed _(or has been added)_, then those geometry components will be +written back to the prim into the layer set as the current edit target. + +This is designed to minimise the amount of data accumulated when making simple tweaks on existing +geometry. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/importExport.md b/docs/importExport.md index 37751810..53b300c2 100644 --- a/docs/importExport.md +++ b/docs/importExport.md @@ -249,17 +249,6 @@ For meshes normally we export: An option "meshUV" indicates AL_usdmaya_ExportCommand to only export Indexed UVs and leave other part of USD hierarchy as empty "over" prims. Under this mode, "leftHandedUV" is used to adjust UV indices orientation. -**Use Animal Schema** -The "Use_Animal_Schema" option when exporting was originally intended to export mesh data in a way which was easier for our inhouse Renderer to consume. -The salient differences are: -+ Export Indexed Subdiv Crease Data -+ Imports/Exports Subdivision-related Flags used by our Renderer as attributes -+ When exporting Colour Sets, names them prefixed with "alusd_colour_" to avoid clashes with Pixar Schemas, and force to RGBA and per Face - -**Note: This special schema needs to be revisited, possibly removed/made more generic (@todo Reference Github issue)** -**The colour handling in particular is a bit of a mess at the moment, and is hardcoded to support some very specific use cases. Until we fix all this, might be worth using the Pixar Plugin for mesh import/export** - - # Tech Note: Colours on Geometry USD has an convention enforced in a Schema related to having a Colour Set on your mesh called "primvars:displayColor" [see here](https://github.com/PixarAnimationStudios/USD/blob/4a3f61e50fd862bfaa57b9a06b5f3d3c05c3bb09/pxr/usd/lib/usdGeom/gprim.h#L131). This will be used as a fallback by Hydra and other viewers if there is no other shading information (There is also a matching displayOpacity) @@ -275,7 +264,6 @@ The exporter will export the data as it is stored in Maya - non-indexed ### How do we export in AL_USDMaya so we have colours? 1. Make sure that one of the colour sets in your mesh is called "displayColor" (there is an example maya file [here](../samples/colours/faceColours.ma)) -2. If we don't use the "Animal_Schema" when exporting the names of Colour Sets will be preserved (but exported as faceVarying) ### A note on Alembic+Maya+USD diff --git a/docs/layers.md b/docs/layers.md index 89e25b51..163a9ce7 100644 --- a/docs/layers.md +++ b/docs/layers.md @@ -1,15 +1,20 @@ # Layers -AL_USDMaya allows you to edit any of the layers used in a USD Stage as well as creating and modfiying them. -Layers can be modified using the USD API +AL_USDMaya has limited support via Maya commands for editing or retrieving layer contents. It does know which layers have been modified in memory by tracking which layers have been set as an EditTarget and that are dirtied via the LayerManager node. -#### Serialising Modified Layers -Any layer changes you make will be serialised to the maya scene when the scene is saved, and reapplied when the scene is opened. +Typically a user of AL_USDMaya will do modifications directly via the USD API and AL_USDMaya will react accordingly. + +#### LayerManager +The LayerManager is a singleton that tracks all layers that have been set as an EditTarget and that are classified as "Dirty" by USD. The LayerManager can be retrieved via it's Python bindings or directly in C++, you can also retrieve it's tracked layer contents via the AL_usdmaya_LayerManager command. +The tracked layers will be serialised to the Maya scene when the scene is saved, and reapplied when the scene is re-opened. To record edits to a layer, you need to set it as the current [Edit Target](https://graphics.pixar.com/usd/docs/USD-Glossary.html#USDGlossary-EditTarget). AL_USDMaya will record which layers have been set as the edit target during a session, and when the scene is saved (via an OnSceneSaved callback) will serialise their content into the maya scene. Those layers will be deserialised into the live USD model after the scene has been opened again via an equivalent OnSceneOpened callback). Normally, the default Edit Target in USD will be the Root Layer of the scene, although using the [Session Layer](https://graphics.pixar.com/usd/docs/USD-Glossary.html#USDGlossary-SessionLayer) is something we should consider. +##### Uses at AL +###### Modifications for exisiting layers +After doing in-memory edits to our USD scene changes(typically via Maya) we then translate our USD scene, which is a filepath to the root layer and the serialised content of all the modified in-memory layers that are tracked by the LayerManager, into our renderers scene description for rendering. #### Commands There are a number of layer-related commands available, all are available via MEL, and some from the USD->Layers dropdow in the UI. @@ -51,27 +56,8 @@ You can see that this will be serialised in the maya scene if you find the appro print cmds.getAttr("Ball_usd.szd") ``` +#### Hydra Renderer Plugin +Layer manager defines Hydra renderer plugin that is used by all Proxy shapes for rendering. It can be set directly (`AL_usdmaya_LayerManger.rendererPluginName`) or with command (`AL_usdmaya_ManageRenderer -setPlugin "Glimpse"`). +List of available renderers is based on plugins discovered by USD. If there is more than one renderer plugin available a new menu entry USD > Renderer is added. - -#### Session Layer - -+ Session Layer support -+ Layer Creation Commands -+ Serialisation etc? Storing Layer Contents on the proxy shape -+ Animation - -At Animal Logic we use this set of tools for our Shot Set Editing workflow - -@todo Baz! - - -We currently create a layer DG node for each layer in the root layerstack. -How do we know if this has changed? -We serialise this into the relevant DG node when we save the maya scene -A layer is either owned by USDMaya or not - if it’s owned by USDMaya we allow you to make any changes to that layer you want, and that layer is serialised on scene save, and deserialised on scene open - -Creating temporary layer, checking in etc .. how does it work? -Working from an existing layer vs creating one from scratch - -We use this system to implement our Shotbased-Set Overrides workflow - we import a shot which contains a set (sublayer or reference?). We want to be able to override transforms and visibility in that set and save the changes as an override layer which is passed down our pipeline diff --git a/docs/proxyShape.md b/docs/proxyShape.md index f810e766..f0dfc0da 100644 --- a/docs/proxyShape.md +++ b/docs/proxyShape.md @@ -23,8 +23,8 @@ see [code docs](https://animallogic.github.io/AL_USDMaya/classAL_1_1usdmaya_1_1n + loads the USD stage into memory + Creates an AL_usdmaya_ProxyShape node in Maya which points to the stage + Traverse the USD Stage, and for each prim, do one of: -1. Ignore it (excludeFromProxyShape Metadata) -2. Translate it into Maya data (importAsNative Metadata) +1. Ignore it _(excludeFromProxyShape Metadata)_ +2. Translate it into Maya data _(importAsNative Metadata)_ 3. If the Prim is of a type for which there is a SchemaTranslator registered, run the translator. See [here](schemaTranslatorPlugins.md) 4. If none of the above... display it in the Maya Viewport, using Pixar's [Hydra](https://graphics.pixar.com/usd/docs/USD-Glossary.html#USDGlossary-HydraRenderer) to render it as OpenGL. (This data is not (initially at least) bridged into maya). @@ -32,7 +32,8 @@ see [code docs](https://animallogic.github.io/AL_USDMaya/classAL_1_1usdmaya_1_1n **Some additional facts:** + When additional things are imported, the proxyShape is the root node in maya under which other things will be parented. + You can create as many proxy shapes as you like in the maya scene. -+ A proxyShape contains a handle to a live USD Stage. This stage, and the handle - are recreated on scene open/load ++ A proxyShape contains a handle to a live USD Stage. This stage, and the handle - are recreated on scene open/load ++ You can define Hydra renderer plugin with AL_usdmaya_LayerManager.rendererPlugin. It affects rendering of all proxy shapes in the scene. **Prim Metadata** There is some metadata defined in (@todo add doxygen link)Metadata.h which if found on a prim, causes a specific behaviour for that prim: @@ -41,25 +42,25 @@ There is some metadata defined in (@todo add doxygen link)Metadata.h which if fo **Selecting Prims in the Proxy Shape** -We can select any USD prim being displayed in the proxy shape, and it's transform hierarchy (the entire chain of transforms up to the root) will be immediately mirrored into maya. +We can select any USD prim being displayed in the proxy shape, and it's transform hierarchy _(the entire chain of transforms up to the root)_ will be immediately mirrored into maya. These transforms will be removed once the USD object is unselected. -These can be transformed using maya's transform tools and maintain a live connection to their master usd objects, so you will see the selected portion of the USD hierarchy move (via the proxy shape) +These can be transformed using maya's transform tools and maintain a live connection to their master usd objects, so you will see the selected portion of the USD hierarchy move _(via the proxy shape)_ We can choose which layer to affect when we move these objects, so any modifications we make will be recorded as overrides in the relevant layer, which we can then export ## Commands -The Proxy Shape has a number of commands associated with it. (This documentation below is culled from the maya help strings of the commands) +The Proxy Shape has a number of commands associated with it. _(This documentation below is gleaned from the maya help strings of the commands)_ ### AL_usdmaya_ProxyShapeImport Overview This command allows you to import a USD file as a proxy shape node. In the simplest case, you can do this: -``` +```c++ AL_usdmaya_ProxyShapeImport -file "/scratch/dev/myaweomescene.usda" -name "MyAwesomeScene"; ``` which will load the usda file specified, and create an ProxyShape of the specified name. If you wish to instance that scene into maya a bunch of times, you can do this: -``` +```c++ AL_usdmaya_ProxyShapeImport -file "/scratch/dev/myaweomescene.usda" -name "MyAwesomeScene" "transform1" "transform2"; ``` This will load the file, create the proxy shape, and then add them as instances underneath transform1 and transform2. @@ -67,20 +68,35 @@ This will load the file, create the proxy shape, and then add them as instances Some other flags and stuff: To load only a subset of the USD file, you can specify a root prim path with the -pp/-primPath flag: -``` +```c++ -primPath "/myScene/foo/bar" ``` This will ignore everything in the USD file apart from the UsdPrim's underneath /myScene/foo/bar. By default the imported proxy node will be connected to the time1.outTime attribute. The -ctt/-connectToTime flag controls this behaviour, so adding this flag will mean the usd proxy is not driven by time at all: -``` +```c++ -connectToTime false ``` If you wish to prevent certain prims from being displayed in the proxy, you can specify the -excludePrimPath/-epp flag, e.g. -``` +```c++ -excludePrimPath "/do/not/show/this/prim" ``` +If you want to exclude some prims from being read when stage is opened, use the -pmi/-populationMaskInclude flag, e.g. +```c++ +-populationMaskInclude "/only/show/this/prim1,/only/show/this/prim2" +``` +It is possible to import the USD stage with an overloaded session layer _(which can be useful if you wish to import +the scene with a specific set of variants set)_. To specify the session layer contents, use the -session flag: +```c++ +-session "#usda 1.0" +``` +It is also possible to prevent all loadable prims from being loaded when importing the USD stage by specifying the unloaded +flag _(the default is false)_ +```c++ +-unloaded true //< don't load any loadable prims +-unloaded false //< load all loadable prims +``` The command will return a string array containing the names of all instances of the created node. (There will be more than one instance if more than one transform was selected or passed into the command). By default, this will be the shortest-unique names; if -fp/-fullpaths is given, then they will be full path names. @@ -101,7 +117,7 @@ If you have an ProxyShape node selected, then: You can also specify a prim path root, which in theory should end up restricting the returned results to just those under the specified path. -``` +```c++ AL_usdmaya_ProxyShapeFindLoadable -pp "/only/assets/under/here"; AL_usdmaya_ProxyShapeFindLoadable -pp -loaded "/only/assets/under/here"; AL_usdmaya_ProxyShapeFindLoadable -pp -unloaded "/only/assets/under/here"; @@ -116,7 +132,7 @@ Assuming you have selected an ProxyShape node, this command will traverse the pr The -pushToPrim/-p2p option controls whether the generated Transforms have their pushToPrim attribute set to true. If it's enabled, then the generated transforms will drive the USD prims. If however it is disabled, then the transform nodes will only be observing the UsdPrims -``` +```c++ AL_usdmaya_ProxyShapeImportAllTransforms "ProxyShape1" -p2p true; // drive the USD prims AL_usdmaya_ProxyShapeImportAllTransforms "ProxyShape1" -p2p false ; // observe the USD prims ``` @@ -125,7 +141,7 @@ This command is undoable. ### AL_usdmaya_ProxyShapeRemoveAllTransforms Overview: If you have previously generated a tonne of Transforms to drive the prims in a usd proxy shape, via a call to 'ProxyShapeImportAllTransforms', then this command will go and delete all of those transform nodes again. -``` +```c++ AL_usdmaya_ProxyShapeRemoveAllTransforms "ProxyShape1"; // drive the USD prims ``` This command is undoable. @@ -133,23 +149,33 @@ This command is undoable. ### AL_usdmaya_ProxyShapeImportPrimPathAsMaya Overview: -This command is a little bit interesting, and probably bug ridden. The following command: -``` + +The following call will import the path "/some/prim/path", and all of it's parent transforms as AL_usdmaya_Transform +nodes into maya. +```c++ AL_usdmaya_ProxyShapeImportPrimPathAsMaya "ProxyShape1" -pp "/some/prim/path"; ``` -..Will disable the rendering of the prim path "/some/prim/path" on the "ProxyShape1" node,and will run an import process to bring in all of the transforms/geometry/etc found under "/some/prim/path", as native maya transform and mesh nodes. -Adding in the -ap/-asProxy flag will build a transform hierarchy of Transform nodes to the specified prim, and then create a new ProxyShape to represent all of that geometry underneath that prim path. -e.g -``` +The custom Maya transforms generated will now act as thin wrapper over the transforms within USD. Any modifications +you make within Maya will be directly translated into USD _(and stored within the currect edit target)_. + +Adding in the -ap/-asProxy flag will build a transform hierarchy of Transform nodes to the +specified prim, and then create a new ProxyShape to represent all of that geometry underneath +that prim path. +```c++ AL_usdmaya_ProxyShapeImportPrimPathAsMaya "ProxyShape1" -ap -pp "/some/prim/path"; ``` -I'm not sure why anyone would want that, but you've got it, so there. - ### AL_usdmaya_ProxyShapePrintRefCountState Overview: -Command used for debugging the internal transform reference counts. +The AL_usdmaya_ProxyShape node maintains an internal set of reference counts that determine the life span of an +AL_usdmaya_Transform node (i.e. a transform may have been created because it has been selected, or because the +transform is required for a particular plugin translator node). For the average user of AL_USDMaya, these ref +counts are nothing more than an implementation detail that can be ignored. For some developers working on the +core of AL_USDMaya, being able to inspect these ref counts may be of use, which you can do so like this: +```c++ +AL_usdmaya_ProxyShapePrintRefCountState -p "ProxyShapeName"; +``` ### AL_usdmaya_ProxyShapeResync Overview Used to inform AL_USDMaya that at the provided prim path and it's descendants, that the Maya scene at that point may be affected by some upcoming changes. @@ -159,7 +185,7 @@ After calling this command, clients are expected to make modifications to the st The provided prim path and it's descendants of known schema type will have the AL::usdmaya::fileio::translators::TranslatorAbstract::preTearDown method called on each schema's translator It's then up to the user to perform updates to the USD scene at or below that point in the hierarchy On calling stage.Reload(),the relevant USDNotice will be triggered and and apply any changes and updates to the Maya scene. -``` +```c++ AL_usdmaya_ProxyShapeResync -p "ProxyShape1" -pp "/some/prim/path" ``` ## Selection @@ -169,25 +195,32 @@ Selection-related commands are described [here](selection.md) TranslatePrim Overview: -Used to manually execute a translator for a prim at the specified path typically so you can force an import or a tearDown of a prim: -``` +The AL_usdmaya_TranslatePrim command is used to manually execute a translator plugin for a specific prim type. The main use for this functionality +is to import a prim into Maya for editing, and then push the changes back into the current edit target within USD. + +Assuming a plugin translator exists for a given prim type, you can import that prim into Maya by using the *ip* flag with one of more prim paths: + + +```c++ AL_usdmaya_TranslatePrim -ip "/MyPrim"; //< Run the Prim's translator's import ``` -``` -AL_usdmaya_TranslatePrim -tp "/MyPrim"; //< Run the Prim's translator's tearDown -``` -``` +```c++ AL_usdmaya_TranslatePrim -ip "/MyPrim,/YourPrim"; //< Run the Prim's translator's import on multiple Prims ``` + +To avoid overloading Maya with data that could be retained in a USD proxy shape for performance reasons, some prims _(such as the Mesh)_ are not imported by default. +In those cases, you will need to use the *-fi* flag to force import of that prim type, e.g. + +```c++ +AL_usdmaya_TranslatePrim -fi -ip "/MyMesh"; //< Run the Prim's translator's import ``` -AL_usdmaya_TranslatePrim -tp "/MyPrim,/YourPrim"; //< Run the Prim's translator's tearDown on multiple Prims -``` +Once you have made any modifications to the prim, you can push those changes back into the current edit target by using the *-tp* flag with one of more prim paths that you wish to tear down. e.g. -Some prims such as the Mesh typed prims are not imported by default, so you will need to pass in a flag that forces the import: +```c++ +AL_usdmaya_TranslatePrim -tp "/MyPrim"; //< Run the Prim's translator's tearDown ``` -AL_usdmaya_TranslatePrim -fi -ip "/MyMesh"; //< Run the Prim's translator's import +```c++ +AL_usdmaya_TranslatePrim -tp "/MyPrim,/YourPrim"; //< Run the Prim's translator's tearDown on multiple Prims ``` -The ForceImport(-fi) flag will forces the import of the available translator. Used for translators who don't import when -their corresponding prim type is brought into the scene. diff --git a/docs/python.md b/docs/python.md new file mode 100644 index 00000000..681fa106 --- /dev/null +++ b/docs/python.md @@ -0,0 +1,73 @@ + +# Python bindings +Python bindings are currently limited to what we or Luma Pictures have implemented internally based on our needs, and are by no means comprehensive + +Currently all bindings are under the AL.usdmaya module +```python +from AL import usdmaya +``` + +## StageCache +the "StageCache" Singleton class allows python access to the set of in-memory stages + + +Example: getting the USD stage (once you've created a proxy shape) +```python +from AL import usdmaya +stageCache = usdmaya.StageCache.Get() +stages = stageCache.GetAllStages() +if stages: + print stages[0] +``` + + +Method list is: ++ Get() ++ Clear() + + +## ProxyShape + +The ProxyShape class wraps an instance of a maya proxy shape + +You can get a specific shape in the scene with: ++ getByName + +example: +```python +from AL import usdmaya +myShape = usdmaya.ProxyShape.getByName('name_of_my_Proxy_Shape') +theStage = myShape.getUsdStage() +``` + +As well as a number of methods to manipulate a shape instance: ++ boundingBox ++ destroyTransformReferences ++ findRequiredPath ++ getUsdStage ++ isRequiredPath ++ makeUsdTransformChain ++ makeUsdTransforms ++ removeUsdTransformChain ++ removeUsdTransforms ++ resync + + +## LayerManager +Is a singleton which reflects the Layer Manager node in the maya scene. Once you've created or referenced the node via: ++ find ++ findOrCreate + +there are number of methods for manipulating the manager: ++ addLayer ++ findLayer ++ getLayerIdentifiers ++ removeLayer + + +Example: +```python +from AL import usdmaya +theLayerMan = usdmaya.LayerManager.findOrCreate() +print theLayerMan.getLayerIdentifiers() +``` diff --git a/lib/AL_USDMaya/AL/docpages/docs_mainpage.h b/lib/AL_USDMaya/AL/docpages/docs_mainpage.h deleted file mode 100644 index 806d2845..00000000 --- a/lib/AL_USDMaya/AL/docpages/docs_mainpage.h +++ /dev/null @@ -1,10 +0,0 @@ - -/** - -\mainpage Animal Logic - USD Maya Bridge - - - - -*/ - diff --git a/lib/AL_USDMaya/AL/docpages/docs_translator_plugins.h b/lib/AL_USDMaya/AL/docpages/docs_translator_plugins.h index 3e1fbb33..4400956b 100644 --- a/lib/AL_USDMaya/AL/docpages/docs_translator_plugins.h +++ b/lib/AL_USDMaya/AL/docpages/docs_translator_plugins.h @@ -34,6 +34,7 @@ class PolyCubeNodeTranslator MStatus update(const UsdPrim& prim) override; MStatus tearDown(const SdfPath& primPath) override; bool supportsUpdate() const override; + bool importableByDefault() const override; private: @@ -377,4 +378,24 @@ are deleted in a specific order, or you have some other book keeping exercise to It should be noted that whilst preTearDown and update are optional, tearDown is NOT. You must implement this method in order to support variant switching! +\b Importable \b by \b Default + +When a USD file is imported into a proxy shape node, if you \a always want that node to be imported immediately, +then you should return true from the importableByDefault method (which is the default). This will cause the +translator to be run as soon as the matching prim type has been encountered. In some cases, you might not want +those prims to be immediately imported. One example of this is with mesh data. + +If you are importing a very geometry heavy scene with a large number of dense meshes, you would want to keep +those meshes within USD/Hydra for as long as possible for performance reasons. If you return false from +importableByDefault, then that particular node type can only be manually imported by calling the AL_usdmaya_TranslatePrim +command. This means that importing and displaying the data will be quick by default, however if you need to make +modifications to that particular prim, you'll be able to selectively import the data when needed. + +\code +bool PolyCubeNodeTranslator::importableByDefault() const +{ + return false; +} +\endcode + */ diff --git a/lib/AL_USDMaya/AL/usdmaya/Api.h b/lib/AL_USDMaya/AL/usdmaya/Api.h index 39d3aee4..c35d98e4 100644 --- a/lib/AL_USDMaya/AL/usdmaya/Api.h +++ b/lib/AL_USDMaya/AL/usdmaya/Api.h @@ -37,4 +37,4 @@ #define AL_USDMAYA_PUBLIC #define AL_USDMAYA_LOCAL #endif -#endif \ No newline at end of file +#endif diff --git a/lib/AL_USDMaya/AL/usdmaya/DebugCodes.cpp b/lib/AL_USDMaya/AL/usdmaya/DebugCodes.cpp index b99446e9..eb4cf193 100644 --- a/lib/AL_USDMaya/AL/usdmaya/DebugCodes.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/DebugCodes.cpp @@ -30,6 +30,7 @@ TF_REGISTRY_FUNCTION(TfDebug) TF_DEBUG_ENVIRONMENT_SYMBOL(ALUSDMAYA_DRAW, "UsdMaya draw"); TF_DEBUG_ENVIRONMENT_SYMBOL(ALUSDMAYA_SELECTION, "UsdMaya selection"); TF_DEBUG_ENVIRONMENT_SYMBOL(ALUSDMAYA_GUIHELPER, "UsdMaya CommandGuiHelper"); + TF_DEBUG_ENVIRONMENT_SYMBOL(ALUSDMAYA_RENDERER, "UsdMaya renderer"); } PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/AL_USDMaya/AL/usdmaya/DebugCodes.h b/lib/AL_USDMaya/AL/usdmaya/DebugCodes.h index a6bee640..8901d88a 100644 --- a/lib/AL_USDMaya/AL/usdmaya/DebugCodes.h +++ b/lib/AL_USDMaya/AL/usdmaya/DebugCodes.h @@ -29,7 +29,8 @@ TF_DEBUG_CODES( ALUSDMAYA_LAYERS, ALUSDMAYA_DRAW, ALUSDMAYA_SELECTION, - ALUSDMAYA_GUIHELPER + ALUSDMAYA_GUIHELPER, + ALUSDMAYA_RENDERER ); diff --git a/lib/AL_USDMaya/AL/usdmaya/PluginRegister.h b/lib/AL_USDMaya/AL/usdmaya/PluginRegister.h index e8e383db..ed58a78b 100644 --- a/lib/AL_USDMaya/AL/usdmaya/PluginRegister.h +++ b/lib/AL_USDMaya/AL/usdmaya/PluginRegister.h @@ -21,11 +21,13 @@ #include "AL/usdmaya/Global.h" #include "AL/usdmaya/StageData.h" #include "AL/usdmaya/DrivenTransformsData.h" +#include "AL/usdmaya/cmds/CreateUsdPrim.h" #include "AL/usdmaya/cmds/DebugCommands.h" #include "AL/usdmaya/cmds/EventCommand.h" #include "AL/usdmaya/cmds/LayerCommands.h" #include "AL/usdmaya/cmds/ProxyShapeCommands.h" #include "AL/usdmaya/cmds/ProxyShapeSelectCommands.h" +#include "AL/usdmaya/cmds/RendererCommands.h" #include "AL/usdmaya/cmds/UnloadPrim.h" #include "AL/usdmaya/fileio/Export.h" #include "AL/usdmaya/fileio/ExportTranslator.h" @@ -36,6 +38,7 @@ #include "AL/usdmaya/nodes/ProxyDrawOverride.h" #include "AL/usdmaya/nodes/ProxyShape.h" #include "AL/usdmaya/nodes/ProxyShapeUI.h" +#include "AL/usdmaya/nodes/RendererManager.h" #include "AL/usdmaya/nodes/Transform.h" #include "AL/usdmaya/nodes/TransformationMatrix.h" @@ -96,11 +99,13 @@ MStatus registerPlugin(AFnPlugin& plugin) AL_REGISTER_DATA(plugin, AL::usdmaya::StageData); AL_REGISTER_DATA(plugin, AL::usdmaya::DrivenTransformsData); AL_REGISTER_COMMAND(plugin, AL::maya::utils::CommandGuiListGen); + AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::CreateUsdPrim); AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::LayerCreateLayer); AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::LayerGetLayers); AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::LayerCurrentEditTarget); AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::LayerSave); AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::LayerSetMuted); + AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::ManageRenderer); AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::ProxyShapeImport); AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::ProxyShapeFindLoadable); AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::ProxyShapeImportAllTransforms); @@ -124,6 +129,7 @@ MStatus registerPlugin(AFnPlugin& plugin) AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::EventQuery); AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::EventLookup); AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::TranslatePrim); + AL_REGISTER_COMMAND(plugin, AL::usdmaya::cmds::LayerManager); AL_REGISTER_COMMAND(plugin, AL::usdmaya::fileio::ImportCommand); AL_REGISTER_COMMAND(plugin, AL::usdmaya::fileio::ExportCommand); AL_REGISTER_TRANSLATOR(plugin, AL::usdmaya::fileio::ImportTranslator); @@ -131,6 +137,7 @@ MStatus registerPlugin(AFnPlugin& plugin) AL_REGISTER_DRAW_OVERRIDE(plugin, AL::usdmaya::nodes::ProxyDrawOverride); AL_REGISTER_SHAPE_NODE(plugin, AL::usdmaya::nodes::ProxyShape, AL::usdmaya::nodes::ProxyShapeUI, AL::usdmaya::nodes::ProxyDrawOverride); AL_REGISTER_TRANSFORM_NODE(plugin, AL::usdmaya::nodes::Transform, AL::usdmaya::nodes::TransformationMatrix); + AL_REGISTER_DEPEND_NODE(plugin, AL::usdmaya::nodes::RendererManager); AL_REGISTER_DEPEND_NODE(plugin, AL::usdmaya::nodes::Layer); // Since AL_MAYA_DECLARE_NODE / AL_MAYA_DEFINE_NODE declare/define "creator" // method, and AL_REGISTER_DEPEND_NODE registers "creator", in order to @@ -153,6 +160,7 @@ MStatus registerPlugin(AFnPlugin& plugin) AL::usdmaya::cmds::constructLayerCommandGuis(); AL::usdmaya::cmds::constructProxyShapeCommandGuis(); AL::usdmaya::cmds::constructDebugCommandGuis(); + AL::usdmaya::cmds::constructRendererCommandGuis(); CHECK_MSTATUS(AL::maya::utils::MenuBuilder::generatePluginUI(plugin, "AL_usdmaya")); AL::usdmaya::Global::onPluginLoad(); @@ -200,6 +208,7 @@ MStatus unregisterPlugin(AFnPlugin& plugin) AL_UNREGISTER_COMMAND(plugin, AL::usdmaya::cmds::LayerGetLayers); AL_UNREGISTER_COMMAND(plugin, AL::usdmaya::cmds::LayerSave); AL_UNREGISTER_COMMAND(plugin, AL::usdmaya::cmds::LayerSetMuted); + AL_UNREGISTER_COMMAND(plugin, AL::usdmaya::cmds::ManageRenderer); AL_UNREGISTER_COMMAND(plugin, AL::usdmaya::cmds::ProxyShapeImport); AL_UNREGISTER_COMMAND(plugin, AL::usdmaya::cmds::ProxyShapeFindLoadable); AL_UNREGISTER_COMMAND(plugin, AL::usdmaya::cmds::ProxyShapeImportAllTransforms); @@ -220,11 +229,14 @@ MStatus unregisterPlugin(AFnPlugin& plugin) AL_UNREGISTER_COMMAND(plugin, AL::usdmaya::fileio::ImportCommand); AL_UNREGISTER_COMMAND(plugin, AL::usdmaya::fileio::ExportCommand); AL_UNREGISTER_COMMAND(plugin, AL::usdmaya::cmds::TranslatePrim); + AL_UNREGISTER_COMMAND(plugin, AL::usdmaya::cmds::LayerManager); + AL_UNREGISTER_COMMAND(plugin, AL::usdmaya::cmds::CreateUsdPrim); AL_UNREGISTER_TRANSLATOR(plugin, AL::usdmaya::fileio::ImportTranslator); AL_UNREGISTER_TRANSLATOR(plugin, AL::usdmaya::fileio::ExportTranslator); AL_UNREGISTER_DRAW_OVERRIDE(plugin, AL::usdmaya::nodes::ProxyDrawOverride); AL_UNREGISTER_NODE(plugin, AL::usdmaya::nodes::ProxyShape); AL_UNREGISTER_NODE(plugin, AL::usdmaya::nodes::Transform); + AL_UNREGISTER_NODE(plugin, AL::usdmaya::nodes::RendererManager); AL_UNREGISTER_NODE(plugin, AL::usdmaya::nodes::Layer); AL_UNREGISTER_NODE(plugin, AL::usdmaya::nodes::LayerManager); AL_UNREGISTER_DATA(plugin, AL::usdmaya::DrivenTransformsData); diff --git a/lib/AL_USDMaya/AL/usdmaya/TypeIDs.h b/lib/AL_USDMaya/AL/usdmaya/TypeIDs.h index 1ed030be..38cdc68f 100644 --- a/lib/AL_USDMaya/AL/usdmaya/TypeIDs.h +++ b/lib/AL_USDMaya/AL/usdmaya/TypeIDs.h @@ -28,6 +28,7 @@ const MTypeId AL_USDMAYA_STAGEDATA (0x00112A24); const MTypeId AL_USDMAYA_DRIVENTRANSFORMS (0x00112A25); const MTypeId AL_USDMAYA_DRIVENTRANSFORMS_DATA (0x00112A26); const MTypeId AL_USDMAYA_LAYERMANAGER (0x00112A27); +const MTypeId AL_USDMAYA_RENDERERMANAGER (0x00112A28); #if defined(WANT_UFE_BUILD) const int MAYA_UFE_RUNTIME_ID(1); diff --git a/lib/AL_USDMaya/AL/usdmaya/Version.h b/lib/AL_USDMaya/AL/usdmaya/Version.h index 85e02160..eba08774 100644 --- a/lib/AL_USDMaya/AL/usdmaya/Version.h +++ b/lib/AL_USDMaya/AL/usdmaya/Version.h @@ -21,8 +21,8 @@ #define stringify(a) #a #define AL_USDMAYA_VERSION_MAJOR 0 -#define AL_USDMAYA_VERSION_MINOR 27 -#define AL_USDMAYA_VERSION_PATCH 10 +#define AL_USDMAYA_VERSION_MINOR 28 +#define AL_USDMAYA_VERSION_PATCH 5 #define AL_USDMAYA_VERSION_STR xstr(AL_USDMAYA_VERSION_MAJOR) "." \ xstr(AL_USDMAYA_VERSION_MINOR) "." \ diff --git a/lib/AL_USDMaya/AL/usdmaya/cmds/CreateUsdPrim.cpp b/lib/AL_USDMaya/AL/usdmaya/cmds/CreateUsdPrim.cpp new file mode 100644 index 00000000..0ae1193b --- /dev/null +++ b/lib/AL_USDMaya/AL/usdmaya/cmds/CreateUsdPrim.cpp @@ -0,0 +1,148 @@ + +#include "AL/usdmaya/cmds/CreateUsdPrim.h" +#include "AL/usdmaya/DebugCodes.h" +#include "AL/usdmaya/nodes/ProxyShape.h" +#include "AL/maya/utils/MenuBuilder.h" + +#include "pxr/base/tf/debug.h" + +#include "pxr/usd/usd/modelAPI.h" + +#include "maya/MSyntax.h" +#include "maya/MGlobal.h" +#include "maya/MArgDatabase.h" +#include "maya/MArgList.h" +#include "maya/MStringArray.h" +#include "maya/MFnDagNode.h" + +namespace AL { +namespace usdmaya { +namespace cmds { + +//---------------------------------------------------------------------------------------------------------------------- +nodes::ProxyShape* getShapeNode(const MArgDatabase& args) +{ + MSelectionList sl; + args.getObjects(sl); + MDagPath path; + MStatus status = sl.getDagPath(0, path); + if(!status) + { + MGlobal::displayError("Argument is not a proxy shape"); + throw status; + } + + if(path.node().hasFn(MFn::kTransform)) + { + path.extendToShape(); + } + + if(path.node().hasFn(MFn::kPluginShape)) + { + MFnDagNode fn(path); + if(fn.typeId() == nodes::ProxyShape::kTypeId) + { + return (nodes::ProxyShape*)fn.userNode(); + } + else + { + MGlobal::displayError("No usd proxy shape selected"); + } + } + else + { + MGlobal::displayError("No usd proxy shape selected"); + } + return 0; +} + +//---------------------------------------------------------------------------------------------------------------------- +AL_MAYA_DEFINE_COMMAND(CreateUsdPrim, AL_usdmaya); + +//---------------------------------------------------------------------------------------------------------------------- +MSyntax CreateUsdPrim::createSyntax() +{ + MSyntax syn; + syn.addFlag("-k", "-kind", MSyntax::kString); + syn.addFlag("-h", "-help"); + syn.addArg(MSyntax::kString); + syn.addArg(MSyntax::kString); + syn.useSelectionAsDefault(false); + syn.setObjectType(MSyntax::kSelectionList, 0, 1); + return syn; +} + +//---------------------------------------------------------------------------------------------------------------------- +MStatus CreateUsdPrim::doIt(const MArgList& args) +{ + try + { + MStatus status; + MArgDatabase db(syntax(), args, &status); + if(!status) + throw status; + AL_MAYA_COMMAND_HELP(db, g_helpText); + + nodes::ProxyShape* node = getShapeNode(db); + if(!node) + throw MS::kFailure; + + MString primPath, primType, kind; + db.getCommandArgument(0, primPath); + db.getCommandArgument(1, primType); + + if(db.isFlagSet("-k")) + { + db.getFlagArgument("-k", 0, kind); + } + + auto stage = node->usdStage(); + + SdfPath path(primPath.asChar()); + TfToken type(primType.asChar()); + + UsdPrim prim = stage->DefinePrim(path, type); + if(prim) + { + if(kind.length()) + { + UsdModelAPI modelAPI(prim); + modelAPI.SetKind(TfToken(kind.asChar())); + } + setResult(true); + } + else + { + setResult(false); + } + + return MS::kSuccess; + } + catch(MStatus status) + { + return status; + } + return redoIt(); +} + +//---------------------------------------------------------------------------------------------------------------------- +const char* const CreateUsdPrim::g_helpText = R"( + AL_usdmaya_CreateUsdPrim Overview: + + This command allows you to create a new prim of a specific point at a path within the stage represented by a proxy + shape. So for example, to create a UsdLuxDiskLight prim, specify the prim path, the type, and the proxy shape to + create the prim within. + + AL_usdmaya_CreateUsdPrim "/path/to/create" "UsdLuxDiskLight" "AL_usdmaya_ProxyShape1"; + + It is also possible to use the -k/-kind flag to specify a 'Kind' which can be queried by the UsdModelAPI. + + AL_usdmaya_CreateUsdPrim -k "MyCustomKind" "/path/to/create" "UsdLuxDiskLight" "AL_usdmaya_ProxyShape1"; +)"; + +//---------------------------------------------------------------------------------------------------------------------- +} +} +} +//---------------------------------------------------------------------------------------------------------------------- + diff --git a/lib/AL_USDMaya/AL/usdmaya/cmds/CreateUsdPrim.h b/lib/AL_USDMaya/AL/usdmaya/cmds/CreateUsdPrim.h new file mode 100644 index 00000000..9dfbb8b7 --- /dev/null +++ b/lib/AL_USDMaya/AL/usdmaya/cmds/CreateUsdPrim.h @@ -0,0 +1,45 @@ +// +// Copyright 2017 Animal Logic +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License.// +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#pragma once + +#include "maya/MPxCommand.h" +#include "pxr/pxr.h" +#include "AL/event/EventHandler.h" +#include "AL/maya/utils/Api.h" +#include "AL/maya/utils/MayaHelperMacros.h" + +PXR_NAMESPACE_USING_DIRECTIVE + +namespace AL { +namespace usdmaya { +namespace cmds { + +//---------------------------------------------------------------------------------------------------------------------- +/// \brief A command that allows you to register and unregister new Event types from script. +/// \ingroup commands +//---------------------------------------------------------------------------------------------------------------------- +class CreateUsdPrim + : public MPxCommand +{ +public: + AL_MAYA_DECLARE_COMMAND(); +private: + MStatus doIt(const MArgList& args) override; +}; + +} // cmds +} // usdmaya +} // AL diff --git a/lib/AL_USDMaya/AL/usdmaya/cmds/DebugCommands.cpp b/lib/AL_USDMaya/AL/usdmaya/cmds/DebugCommands.cpp index 8328d6d5..260d25c6 100644 --- a/lib/AL_USDMaya/AL/usdmaya/cmds/DebugCommands.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/cmds/DebugCommands.cpp @@ -101,7 +101,7 @@ MStatus UsdDebugCommand::doIt(const MArgList& argList) setResult(state); } } - catch(const MStatus& s) + catch(const MStatus&) { } diff --git a/lib/AL_USDMaya/AL/usdmaya/cmds/LayerCommands.cpp b/lib/AL_USDMaya/AL/usdmaya/cmds/LayerCommands.cpp index a734f1c1..53892d4b 100644 --- a/lib/AL_USDMaya/AL/usdmaya/cmds/LayerCommands.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/cmds/LayerCommands.cpp @@ -60,10 +60,11 @@ namespace { AL::usdmaya::nodes::ProxyShape* foundShape = nullptr; MDagPath path; - for(uint32_t i = 0; i < sl.length(); ++i) + const uint32_t selLength = sl.length(); + for(uint32_t i = 0; i < selLength ; ++i) { MStatus status = sl.getDagPath(i, path); - if(!status) continue; + if(status != MS::kSuccess) continue; MFnDagNode fn(path); @@ -136,12 +137,31 @@ MArgDatabase LayerCommandBase::makeDatabase(const MArgList& args) //---------------------------------------------------------------------------------------------------------------------- nodes::ProxyShape* LayerCommandBase::getShapeNode(const MArgDatabase& args) { + TF_DEBUG(ALUSDMAYA_COMMANDS).Msg("LayerCommandBase::getShapeNode\n"); MDagPath path; MSelectionList sl; args.getObjects(sl); - nodes::ProxyShape* foundShape = getProxyShapeFromSel(sl); - if(foundShape) return foundShape; + const uint32_t selLength = sl.length(); + for(uint32_t i = 0; i < selLength; ++i) + { + MStatus status = sl.getDagPath(i, path); + if(status != MS::kSuccess) continue; + + if(path.node().hasFn(MFn::kTransform)) + { + path.extendToShape(); + } + + if(path.node().hasFn(MFn::kPluginShape)) + { + MFnDagNode fn(path); + if(fn.typeId() == nodes::ProxyShape::kTypeId) + { + return (nodes::ProxyShape*)fn.userNode(); + } + } + } sl.clear(); @@ -152,8 +172,26 @@ nodes::ProxyShape* LayerCommandBase::getShapeNode(const MArgDatabase& args) if(args.getFlagArgument("-p", 0, proxyName)) { sl.add(proxyName); - foundShape = getProxyShapeFromSel(sl); - if(foundShape) return foundShape; + if(sl.length()) + { + MStatus status = sl.getDagPath(0, path); + if(status == MS::kSuccess) + { + if(path.node().hasFn(MFn::kTransform)) + { + path.extendToShape(); + } + + if(path.node().hasFn(MFn::kPluginShape)) + { + MFnDagNode fn(path); + if(fn.typeId() == nodes::ProxyShape::kTypeId) + { + return (nodes::ProxyShape*)fn.userNode(); + } + } + } + } } MGlobal::displayError("Invalid ProxyShape specified/selected with -p flag"); } @@ -213,15 +251,6 @@ MStatus LayerGetLayers::doIt(const MArgList& argList) UsdStageRefPtr stage = proxyShape->usdStage(); MStringArray results; - auto push = [](MStringArray& results, const MString& newLayer) - { - for(uint32_t i = 0; i < results.length(); ++i) - { - if(results[i] == newLayer) return; - } - results.append(newLayer); - }; - const bool useIdentifiers = args.isFlagSet("-id"); if(args.isFlagSet("-rl")) { @@ -901,7 +930,7 @@ MStatus LayerSetMuted::doIt(const MArgList& argList) } else { - MGlobal::displayError("LayerSave: no layer manager in scene (so no layers)"); + MGlobal::displayError("LayerSetMuted: no layer manager in scene (so no layers)"); throw MS::kFailure; } LAYER_HANDLE_CHECK(m_layer); @@ -936,6 +965,100 @@ MStatus LayerSetMuted::redoIt() return MS::kSuccess; } +//---------------------------------------------------------------------------------------------------------------------- +/// \brief Retrieves all the layers that have been set as the EditTarget from any Stage during this session. +//---------------------------------------------------------------------------------------------------------------------- +AL_MAYA_DEFINE_COMMAND(LayerManager, AL_usdmaya); + +//---------------------------------------------------------------------------------------------------------------------- +bool LayerManager::isUndoable() const +{ + return false; +} + +//---------------------------------------------------------------------------------------------------------------------- +MSyntax LayerManager::createSyntax() +{ + MSyntax syn = setUpCommonSyntax(); + syn.useSelectionAsDefault(true); + syn.setObjectType(MSyntax::kSelectionList, 0); + syn.addFlag("-dal", "-dirtyallLayers", MSyntax::kNoArg); + syn.addFlag("-dso", "-dirtysessiononly", MSyntax::kNoArg); + syn.addFlag("-dlo", "-dirtyedittargetlayersonly", MSyntax::kNoArg); + return syn; +} + +//---------------------------------------------------------------------------------------------------------------------- +MStatus LayerManager::doIt(const MArgList& argList) +{ + try + { + MArgDatabase args = makeDatabase(argList); + AL_MAYA_COMMAND_HELP(args, g_helpText); + + nodes::LayerManager* layerManager = nodes::LayerManager::findManager(); + + auto shouldRecord = [&](const MString& currId) + { + if(args.isFlagSet("-dso")) + { + UsdStageRefPtr stage = getShapeNodeStage(args); + std::string shapesSessionId = stage->GetSessionLayer()->GetIdentifier(); + if(std::strcmp(currId.asChar(), shapesSessionId.c_str()) != 0) + { + // only return the dirty session layer for the selected stage + return false; + } + } + else if(args.isFlagSet("-dlo")) + { + std::string displayName = SdfLayer::GetDisplayNameFromIdentifier(currId.asChar()); + std::size_t found = displayName.find("session"); + if(found != std::string::npos) + { + return false; + } + } + return true; + }; + + MStringArray results; + if(layerManager) + { + MStringArray identifiers; + layerManager->getLayerIdentifiers(identifiers); + + for(uint32_t x = 0, n = identifiers.length(); x < n; ++x) + { + MString currId = identifiers[x]; + + if(!shouldRecord(currId)) + { + continue; + } + + SdfLayerHandle l = layerManager->findLayer(currId.asChar()); + if(l) + { + std::string str; + l->ExportToString(&str); + + // Write the results in adjacent pairs(id,contents, id,contents) + results.append(currId); + results.append(AL::maya::utils::convert(str)); + } + } + } + setResult(results); + } + catch(const MStatus& status) + { + return status; + } + + return MS::kSuccess; +} + //---------------------------------------------------------------------------------------------------------------------- MStringArray buildEditedLayersList(const MString&) { @@ -1169,6 +1292,23 @@ LayerSetMuted Overview: This command is undoable, but it will probably crash right now. )"; +//---------------------------------------------------------------------------------------------------------------------- +const char* const LayerManager::g_helpText = R"( +LayerManager Command Overview: + This command retrieves all the layers that have been set as the EditTarget from any Stage during this session. + + Returns a StringArray in the format of [LayerIdentifier_A,LayerContents_A, LayerIdentifier_B,LayerContents_B] + + Retrieves all Layers that have been set as the EditTarget and have been modified: + LayerManager -dall "ProxyShape1" + + Retrieves the SessionLayer that has been modified for the passed in ProxyShape's stage: + LayerManager -dso "ProxyShape1" + + Retrieves all Layers, except SessionLayers, that have been set as the EditTarget and have been modified: + LayerManager -dlo "ProxyShape1" +)"; + //---------------------------------------------------------------------------------------------------------------------- } // cmds } // usdmaya diff --git a/lib/AL_USDMaya/AL/usdmaya/cmds/LayerCommands.h b/lib/AL_USDMaya/AL/usdmaya/cmds/LayerCommands.h index 49e18d37..2edc07fd 100644 --- a/lib/AL_USDMaya/AL/usdmaya/cmds/LayerCommands.h +++ b/lib/AL_USDMaya/AL/usdmaya/cmds/LayerCommands.h @@ -179,6 +179,22 @@ class LayerSetMuted MStatus redoIt() override; }; +//---------------------------------------------------------------------------------------------------------------------- +/// \brief Command to introspect and pull out data from the layer manager +/// \ingroup commands +//---------------------------------------------------------------------------------------------------------------------- +class LayerManager + : public LayerCommandBase +{ +public: + AL_MAYA_DECLARE_COMMAND(); +private: + bool isUndoable() const override; + MStatus doIt(const MArgList& args) override; + MStatus captureLayerContents(const MString& id, MStringArray& results); +}; + + /// \brief function called on startup to generate the menu & option boxes for the layer commands /// \ingroup commands diff --git a/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapeCommands.cpp b/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapeCommands.cpp index f6309609..f452c488 100644 --- a/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapeCommands.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapeCommands.cpp @@ -119,18 +119,20 @@ nodes::ProxyShape* ProxyShapeCommandBase::getShapeNode(const MArgDatabase& args) for(uint32_t i = 0; i < sl.length(); ++i) { MStatus status = sl.getDagPath(i, path); - - if(path.node().hasFn(MFn::kTransform)) + if(status) { - path.extendToShape(); - } + if(path.node().hasFn(MFn::kTransform)) + { + path.extendToShape(); + } - if(path.node().hasFn(MFn::kPluginShape)) - { - MFnDagNode fn(path); - if(fn.typeId() == nodes::ProxyShape::kTypeId) + if(path.node().hasFn(MFn::kPluginShape)) { - return (nodes::ProxyShape*)fn.userNode(); + MFnDagNode fn(path); + if(fn.typeId() == nodes::ProxyShape::kTypeId) + { + return (nodes::ProxyShape*)fn.userNode(); + } } } } @@ -146,18 +148,20 @@ nodes::ProxyShape* ProxyShapeCommandBase::getShapeNode(const MArgDatabase& args) if(sl.length()) { MStatus status = sl.getDagPath(0, path); - - if(path.node().hasFn(MFn::kTransform)) + if(status) { - path.extendToShape(); - } + if(path.node().hasFn(MFn::kTransform)) + { + path.extendToShape(); + } - if(path.node().hasFn(MFn::kPluginShape)) - { - MFnDagNode fn(path); - if(fn.typeId() == nodes::ProxyShape::kTypeId) + if(path.node().hasFn(MFn::kPluginShape)) { - return (nodes::ProxyShape*)fn.userNode(); + MFnDagNode fn(path); + if(fn.typeId() == nodes::ProxyShape::kTypeId) + { + return (nodes::ProxyShape*)fn.userNode(); + } } } } @@ -234,6 +238,34 @@ MStatus ProxyShapeImport::redoIt() MStatus status = m_modifier.doIt(); if(status) { + // set the name of the node + MFnDagNode fnShape(m_shape); + + if(m_createdParent) + { + // if lots of TM's have been specified as parents, just name the shape explicitly + if(m_parentTransforms.length()) + { + if(m_proxy_name.length()) + { + fnShape.setName(m_proxy_name + "Shape"); + } + } + else + { + MFnDependencyNode fnTransform(fnShape.parent(0)); + fnShape.setName(fnTransform.name() + "Shape"); + if(m_proxy_name.length()) + { + fnTransform.setName(m_proxy_name); + } + else + { + fnTransform.setName("AL_usdmaya_Proxy"); + } + } + } + status = m_modifier2.doIt(); if(status) { @@ -247,31 +279,6 @@ MStatus ProxyShapeImport::redoIt() } } - // set the name of the node - MFnDagNode fnShape(m_shape); - - // if lots of TM's have been specified as parents, just name the shape explicitly - if(m_parentTransforms.length()) - { - if(m_proxy_name.length()) - { - fnShape.setName(m_proxy_name + "Shape"); - } - } - else - { - MFnDependencyNode fnTransform(fnShape.parent(0)); - fnShape.setName(fnTransform.name() + "Shape"); - if(m_proxy_name.length()) - { - fnTransform.setName(m_proxy_name); - } - else - { - fnTransform.setName("AL_usdmaya_Proxy"); - } - } - return status; } @@ -296,6 +303,7 @@ MStatus ProxyShapeImport::doIt(const MArgList& args) items.getDependNode(i, node); if(node.hasFn(MFn::kTransform)) { + m_createdParent = false; m_parentTransforms.append(node); } } @@ -406,17 +414,13 @@ MStatus ProxyShapeImport::doIt(const MArgList& args) if(connectToTime) { - MSelectionList temp; MSelectionList sl; - MGlobal::getActiveSelectionList(temp, true); - MGlobal::selectByName("time1"); - MGlobal::getActiveSelectionList(sl); - MGlobal::setActiveSelectionList(temp); + sl.add("time1"); MObject time1; sl.getDependNode(0, time1); MFnDependencyNode fnTime(time1); MPlug outTime = fnTime.findPlug("outTime"); - m_modifier.connect(outTime, MPlug(m_shape, nodes::ProxyShape::time())); + m_modifier2.connect(outTime, MPlug(m_shape, nodes::ProxyShape::time())); } status = redoIt(); CHECK_MSTATUS_AND_RETURN_IT(status); @@ -710,7 +714,7 @@ MStatus ProxyShapeImportAllTransforms::doIt(const MArgList& args) } } } - catch(const MStatus& status) + catch(const MStatus&) { return MS::kFailure; } @@ -807,7 +811,7 @@ MStatus ProxyShapeRemoveAllTransforms::doIt(const MArgList& args) } } } - catch(const MStatus& status) + catch(const MStatus&) { return MS::kFailure; } @@ -889,6 +893,7 @@ AL_MAYA_DEFINE_COMMAND(InternalProxyShapeSelect, AL_usdmaya); MSyntax InternalProxyShapeSelect::createSyntax() { MSyntax syntax = setUpCommonSyntax(); + syntax.useSelectionAsDefault(false); syntax.addFlag("-pp", "-primPath", MSyntax::kString); syntax.addFlag("-h", "-help", MSyntax::kNoArg); syntax.addFlag("-cl", "-clear", MSyntax::kNoArg); @@ -1310,6 +1315,7 @@ MSyntax TranslatePrim::createSyntax() syntax.addFlag("-ip", "-importPaths", MSyntax::kString); syntax.addFlag("-tp", "-teardownPaths", MSyntax::kString); syntax.addFlag("-fi", "-forceImport", MSyntax::kNoArg); + syntax.addFlag("-fd", "-forceDefault", MSyntax::kNoArg); return syntax; } @@ -1342,6 +1348,12 @@ MStatus TranslatePrim::doIt(const MArgList& args) { tp.setForcePrimImport(true); } + + // change the translator context to read default value + if(db.isFlagSet("-fd")) + { + m_proxy->context()->setForceDefaultRead(true); + } } catch(const MStatus& status) { @@ -1490,6 +1502,17 @@ AL_usdmaya_ProxyShapeImport Overview: -populationMaskInclude "/only/show/this/prim1,/only/show/this/prim2" + It is possible to import the USD stage with an overloaded session layer _(which can be useful if you wish to import + the scene with a specific set of variants set)_. To specify the session layer contents, use the -session flag: + + -session "#usda 1.0" + + It is also possible to prevent all loadable prims from being loaded when importing the USD stage by specifying the unloaded + flag _(the default is false)_ + + -unloaded true //< don't load any loadable prims + -unloaded false //< load all loadable prims + The command will return a string array containing the names of all instances of the created node. (There will be more than one instance if more than one transform was selected or passed into the command.) By default, the will be the shortest-unique names; if -fp/-fullpaths is given, then they will be full path names. @@ -1558,23 +1581,33 @@ AL_usdmaya_ProxyShapeRemoveAllTransforms Overview: const char* const ProxyShapeImportPrimPathAsMaya::g_helpText = R"( AL_usdmaya_ProxyShapeImportPrimPathAsMaya Overview: - Imports the following path as a hierarchy of transforms: + The following call will import the path "/some/prim/path", and all of it's parent transforms as AL_usdmaya_Transform + nodes into maya. + AL_usdmaya_ProxyShapeImportPrimPathAsMaya "ProxyShape1" -pp "/some/prim/path"; + The custom Maya transforms generated will now act as thin wrapper over the transforms within USD. Any modifications + you make within Maya will be directly translated into USD _(and stored within the currect edit target)_. + Adding in the -ap/-asProxy flag will build a transform hierarchy of Transform nodes to the specified prim, and then create a new ProxyShape to represent all of that geometry underneath that prim path. AL_usdmaya_ProxyShapeImportPrimPathAsMaya "ProxyShape1" -ap -pp "/some/prim/path"; - I'm not sure why anyone would want that, but you've got it, so there. )"; //---------------------------------------------------------------------------------------------------------------------- const char* const ProxyShapePrintRefCountState::g_helpText = R"( AL_usdmaya_ProxyShapePrintRefCountState Overview: - Command used for debugging the internal transform reference counts. + The AL_usdmaya_ProxyShape node maintains an internal set of reference counts that determine the life span of an + AL_usdmaya_Transform node (i.e. a transform may have been created because it has been selected, or because the + transform is required for a particular plugin translator node). For the average user of AL_USDMaya, these ref + counts are nothing more than an implementation detail that can be ignored. For some developers working on the + core of AL_USDMaya, being able to inspect these ref counts may be of use, which you can do so like this: + + AL_usdmaya_ProxyShapePrintRefCountState -p "ProxyShapeName"; )"; diff --git a/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapeCommands.h b/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapeCommands.h index 0d1d5138..93657083 100644 --- a/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapeCommands.h +++ b/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapeCommands.h @@ -84,6 +84,7 @@ class ProxyShapeImport MObjectArray m_parentTransforms; MObject m_shape; MString m_proxy_name; + bool m_createdParent = true; public: AL_MAYA_DECLARE_COMMAND(); private: diff --git a/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapePostLoadProcess.cpp b/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapePostLoadProcess.cpp index 4dd94600..d5513d2a 100644 --- a/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapePostLoadProcess.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapePostLoadProcess.cpp @@ -186,6 +186,18 @@ void huntForNativeNodes( } // anon +//---------------------------------------------------------------------------------------------------------------------- +static bool parentNodeIsUnmerged(const UsdPrim & prim) +{ + bool parentUnmerged = false; + TfToken val; + if(prim.GetParent().IsValid() && prim.GetParent().GetMetadata(AL::usdmaya::Metadata::mergedTransform, &val)) + { + parentUnmerged = (val == AL::usdmaya::Metadata::unmerged); + } + return parentUnmerged; +} + //---------------------------------------------------------------------------------------------------------------------- fileio::ImporterParams ProxyShapePostLoadProcess::m_params; @@ -215,9 +227,17 @@ void ProxyShapePostLoadProcess::createTranformChainsForSchemaPrims( SdfPath path = usdPrim.GetPath(); TF_DEBUG(ALUSDMAYA_TRANSLATORS).Msg("ProxyShapePostLoadProcess::createTranformChainsForSchemaPrims checking %s\n", path.GetText()); MObject newpath = MObject::kNullObj; + bool parentUnmerged = parentNodeIsUnmerged(usdPrim); if(schemaPrimUtils.needsTransformParent(usdPrim)) { - newpath = ptrNode->makeUsdTransformChain(usdPrim, modifier, nodes::ProxyShape::kRequired, &modifier2); + if(!parentUnmerged) + { + newpath = ptrNode->makeUsdTransformChain(usdPrim, modifier, nodes::ProxyShape::kRequired, &modifier2); + } + else + { + newpath = ptrNode->makeUsdTransformChain(usdPrim.GetParent(), modifier, nodes::ProxyShape::kRequired, &modifier2); + } } objsToCreate.push_back(std::make_pair(newpath, usdPrim)); } @@ -252,13 +272,27 @@ void ProxyShapePostLoadProcess::createSchemaPrims( fileio::translators::TranslatorContextPtr context = proxy->context(); fileio::translators::TranslatorManufacture& translatorManufacture = proxy->translatorManufacture(); + if(context->getForceDefaultRead()) + { + TF_DEBUG(ALUSDMAYA_TRANSLATORS).Msg("ProxyShapePostLoadProcess::createSchemaPrims," + " will read default values\n"); + } + auto it = objsToCreate.begin(); const auto end = objsToCreate.end(); for(; it != end; ++it) { UsdPrim prim = *it; - - MObject object = proxy->findRequiredPath(prim.GetPath()); + bool parentUnmerged = parentNodeIsUnmerged(prim); + MObject object; + if (parentUnmerged) + { + object = proxy->findRequiredPath(prim.GetParent().GetPath()); + } + else + { + object = proxy->findRequiredPath(prim.GetPath()); + } fileio::translators::TranslatorRefPtr translator = translatorManufacture.get(prim.GetTypeName()); TF_DEBUG(ALUSDMAYA_TRANSLATORS).Msg("ProxyShapePostLoadProcess::createSchemaPrims prim=%s\n", prim.GetPath().GetText()); diff --git a/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapePostLoadProcess.h b/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapePostLoadProcess.h index a34917fb..43e51d4f 100644 --- a/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapePostLoadProcess.h +++ b/lib/AL_USDMaya/AL/usdmaya/cmds/ProxyShapePostLoadProcess.h @@ -75,6 +75,7 @@ class ProxyShapePostLoadProcess /// those nodes that should be imported into the Maya Scene. /// \param proxy the proxy shape to create the schema prims on /// \param objsToCreate the mapping returned from createTranformChainsForSchemaPrims + /// \param param the translator plugin options static void createSchemaPrims( nodes::ProxyShape* proxy, const std::vector& objsToCreate, diff --git a/lib/AL_USDMaya/AL/usdmaya/cmds/RendererCommands.cpp b/lib/AL_USDMaya/AL/usdmaya/cmds/RendererCommands.cpp new file mode 100644 index 00000000..596a0839 --- /dev/null +++ b/lib/AL_USDMaya/AL/usdmaya/cmds/RendererCommands.cpp @@ -0,0 +1,145 @@ +// +// Copyright 2017 Animal Logic +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License.// +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "AL/maya/utils/CommandGuiHelper.h" +#include "AL/usdmaya/utils/Utils.h" +#include "AL/maya/utils/MayaHelperMacros.h" +#include "AL/usdmaya/DebugCodes.h" +#include "AL/usdmaya/cmds/RendererCommands.h" +#include "AL/usdmaya/nodes/RendererManager.h" + +#include "maya/MArgDatabase.h" +#include "maya/MDagPath.h" +#include "maya/MFnDagNode.h" +#include "maya/MGlobal.h" +#include "maya/MItDependencyGraph.h" +#include "maya/MItDependencyNodes.h" +#include "maya/MSelectionList.h" +#include "maya/MStringArray.h" +#include "maya/MSyntax.h" + +#include +#include "AL/usdmaya/utils/Utils.h" + +namespace AL { +namespace usdmaya { +namespace cmds { + +//---------------------------------------------------------------------------------------------------------------------- +/// \brief Get / Set renderer plugin settings +//---------------------------------------------------------------------------------------------------------------------- +AL_MAYA_DEFINE_COMMAND(ManageRenderer, AL_usdmaya); + +//---------------------------------------------------------------------------------------------------------------------- +MArgDatabase ManageRenderer::makeDatabase(const MArgList& args) +{ + MStatus status; + MArgDatabase database(createSyntax(), args, &status); + if(!status) + throw status; + return database; +} + +//---------------------------------------------------------------------------------------------------------------------- +MSyntax ManageRenderer::createSyntax() +{ + MSyntax syn; + syn.addFlag("-h", "-help", MSyntax::kNoArg); + syn.addFlag("-sp", "-setPlugin", MSyntax::kString); + return syn; +} + +//---------------------------------------------------------------------------------------------------------------------- +bool ManageRenderer::isUndoable() const +{ + return false; +} + +//---------------------------------------------------------------------------------------------------------------------- +MStatus ManageRenderer::doIt(const MArgList& argList) +{ + try + { + MArgDatabase args = makeDatabase(argList); + AL_MAYA_COMMAND_HELP(args, g_helpText); + + if(args.isFlagSet("-sp")) + { + MString name; + args.getFlagArgument("-sp", 0, name); + bool result = nodes::RendererManager::findOrCreateManager()->setRendererPlugin(name); + setResult(result); + } + } + catch(const MStatus& status) + { + return status; + } + return MS::kSuccess; +} + +//---------------------------------------------------------------------------------------------------------------------- +MStringArray buildRendererPluginsList(const MString&) +{ + nodes::RendererManager* RendererManager = nodes::RendererManager::findManager(); + if(RendererManager) + { + int index = RendererManager->getRendererPluginIndex(); + if (index > 0) + { + // swap items so current plugin is first and active in the list + MStringArray result = AL::usdmaya::nodes::RendererManager::getRendererPluginList(); + MString temp = result[0]; + result[0] = result[index]; + result[index] = temp; + return result; + } + } + return AL::usdmaya::nodes::RendererManager::getRendererPluginList(); +} + +//---------------------------------------------------------------------------------------------------------------------- +void constructRendererCommandGuis() +{ + /// It makes little sense to add this menu when there's just one option + if (AL::usdmaya::nodes::RendererManager::getRendererPluginList().length() > 1) + { + { + AL::maya::utils::CommandGuiHelper manageRenderer("AL_usdmaya_ManageRenderer", "Hydra Renderer Plugin", "Set", "USD/Renderer", false); + manageRenderer.addListOption("sp", "Plugin Name", (AL::maya::utils::GenerateListFn)buildRendererPluginsList); + } + } +} + + +//---------------------------------------------------------------------------------------------------------------------- +// Documentation strings. +//---------------------------------------------------------------------------------------------------------------------- + +const char* const ManageRenderer::g_helpText = R"( +ManageRenderer Overview: + + This command allows you to manage global renderer settings: + + ManageRenderer -sp "Embree"; //< sets current renderer to Intel Embree + ManageRenderer -sp "Glimpse"; //< sets current renderer to glimpse + ManageRenderer -sp "GL"; //< sets current renderer to Hydra GL +)"; + +//---------------------------------------------------------------------------------------------------------------------- +} // cmds +} // usdmaya +} // AL +//---------------------------------------------------------------------------------------------------------------------- diff --git a/lib/AL_USDMaya/AL/usdmaya/cmds/RendererCommands.h b/lib/AL_USDMaya/AL/usdmaya/cmds/RendererCommands.h new file mode 100644 index 00000000..363c4da6 --- /dev/null +++ b/lib/AL_USDMaya/AL/usdmaya/cmds/RendererCommands.h @@ -0,0 +1,60 @@ +// +// Copyright 2017 Animal Logic +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License.// +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#pragma once + +#include "../Api.h" + +#include "AL/usdmaya/ForwardDeclares.h" +#include "AL/maya/utils/Api.h" +#include "AL/maya/utils/MayaHelperMacros.h" +#include "maya/MDGModifier.h" +#include "maya/MObject.h" +#include "maya/MPxCommand.h" + +#include "pxr/pxr.h" +#include "pxr/usd/usd/stage.h" +#include + +namespace AL { +namespace usdmaya { +namespace cmds { + +//---------------------------------------------------------------------------------------------------------------------- +/// \brief Get / Set renderer plugin settings +/// \ingroup commands +//---------------------------------------------------------------------------------------------------------------------- +class ManageRenderer + : public MPxCommand +{ + MArgDatabase makeDatabase(const MArgList& args); +public: + AL_MAYA_DECLARE_COMMAND(); +private: + bool isUndoable() const override; + MStatus doIt(const MArgList& args) override; +}; + + +/// \brief function called on startup to generate the menu & option boxes for the layer commands +/// \ingroup commands +AL_USDMAYA_PUBLIC +void constructRendererCommandGuis(); + +//---------------------------------------------------------------------------------------------------------------------- +} // cmds +} // usdmaya +} // AL +//---------------------------------------------------------------------------------------------------------------------- diff --git a/lib/AL_USDMaya/AL/usdmaya/cmds/UnloadPrim.cpp b/lib/AL_USDMaya/AL/usdmaya/cmds/UnloadPrim.cpp index d0adf36d..221d25d2 100644 --- a/lib/AL_USDMaya/AL/usdmaya/cmds/UnloadPrim.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/cmds/UnloadPrim.cpp @@ -111,7 +111,7 @@ MStatus ChangeVariant::doIt(const MArgList& args) } } } - catch(MStatus& status) + catch(MStatus&) { std::cout << "Error" << std::endl; } @@ -182,7 +182,7 @@ MStatus ActivatePrim::doIt(const MArgList& args) } } } - catch(MStatus status) + catch(MStatus) { std::cout << "Error" << std::endl; } diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/AnimationTranslator.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/AnimationTranslator.cpp index e4a4ead1..75eba268 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/AnimationTranslator.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/AnimationTranslator.cpp @@ -295,7 +295,9 @@ void AnimationTranslator::exportAnimation(const ExporterParams& params) } for(auto it = startMesh; it != endMesh; ++it) { - AL::usdmaya::utils::copyVertexData(MFnMesh(it->first), it->second, timeCode); + UsdGeomMesh mesh(it->second.GetPrim()); + AL::usdmaya::utils::MeshExportContext context(it->first, mesh, timeCode); + context.copyVertexData(timeCode); } } } diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/AnimationTranslator.h b/lib/AL_USDMaya/AL/usdmaya/fileio/AnimationTranslator.h index a4c51a86..157f4b91 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/AnimationTranslator.h +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/AnimationTranslator.h @@ -72,8 +72,10 @@ typedef std::map PlugAttrScaledVector; /// \brief A utility class to help with exporting animated plugs from maya /// \ingroup fileio //---------------------------------------------------------------------------------------------------------------------- -struct AnimationTranslator +class AnimationTranslator { +public: + /// \brief returns true if the attribute is animated /// \param node the node which contains the attribute to test /// \param attr the attribute handle diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/Export.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/Export.cpp index 8d3bafe4..310b106d 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/Export.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/Export.cpp @@ -615,6 +615,7 @@ SdfPath Export::makeMeshReferencePath(MDagPath path, const SdfPath& usdPath, Ref } break; } + return SdfPath(); } //---------------------------------------------------------------------------------------------------------------------- @@ -639,17 +640,20 @@ void Export::addReferences(MDagPath shapePath, MFnTransform& fnTransform, SdfPat // usd only allows instanceable on transform prim switch (refType) { - case kTransformReference: + case kTransformReference: { usdPrim.SetInstanceable(true); } break; - case kMeshReference: + case kMeshReference: { copyTransformParams(usdPrim, fnTransform); } break; + + default: + break; } usdPrim.GetReferences().AddReference(SdfReference("", instancePath)); } @@ -1002,11 +1006,7 @@ MStatus ExportCommand::doIt(const MArgList& args) } if(argData.isFlagSet("luv", &status)) { - AL_MAYA_CHECK_ERROR(argData.getFlagArgument("luv", 0, m_params.m_leftHandedUV), "ALUSDExport: Unable to fetch \"m_leftHanded\" argument"); - } - if(argData.isFlagSet("as", &status)) - { - AL_MAYA_CHECK_ERROR(argData.getFlagArgument("uas", 0, m_params.m_useAnimalSchema), "ALUSDExport: Unable to fetch \"use animal schema\" argument"); + MGlobal::displayWarning("-luv flag is deprecated in AL_usdmaya_ExportCommand\n"); } if(argData.isFlagSet("mt", &status)) { @@ -1114,8 +1114,6 @@ MSyntax ExportCommand::createSyntax() AL_MAYA_CHECK_ERROR2(status, errorString); status = syntax.addFlag("-di" , "-duplicateInstances", MSyntax::kBoolean); AL_MAYA_CHECK_ERROR2(status, errorString); - status = syntax.addFlag("-uas", "-useAnimalSchema", MSyntax::kBoolean); - AL_MAYA_CHECK_ERROR2(status, errorString); status = syntax.addFlag("-mt", "-mergeTransforms", MSyntax::kBoolean); AL_MAYA_CHECK_ERROR2(status, errorString); status = syntax.addFlag("-ani", "-animation", MSyntax::kNoArg); diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/ExportParams.h b/lib/AL_USDMaya/AL/usdmaya/fileio/ExportParams.h index ddc5399b..d910d9ed 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/ExportParams.h +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/ExportParams.h @@ -18,15 +18,14 @@ #include "maya/MSelectionList.h" #include "maya/MString.h" #include "AL/usd/utils/ForwardDeclares.h" +#include "pxr/usd/usd/timeCode.h" + +PXR_NAMESPACE_USING_DIRECTIVE namespace AL { namespace usdmaya { namespace fileio { -#ifndef USE_AL_DEFAULT - #define USE_AL_DEFAULT 0 -#endif - //---------------------------------------------------------------------------------------------------------------------- /// \brief parameters for the exporter. These parameters are constructed by any command or file translator that wishes /// to export data from maya, which are then passed to the AL::usdmaya::fileio::Export class to perform the @@ -41,9 +40,15 @@ struct ExporterParams double m_maxFrame=1.0; ///< the end frame of the animation export bool m_selected = false; ///< are we exporting selected objects (true) or all objects (false) bool m_meshes = true; ///< if true, export meshes + bool m_meshPoints = true; ///< if true mesh vertices will be exported + bool m_meshConnects = true; ///< if true face connects and counts will be exported + bool m_meshNormals = true; ///< if true normal vectors will be exported + bool m_meshVertexCreases = true; ///< if true vertex creases will be exported + bool m_meshEdgeCreases = true; ///< if true edge creases will be exported + bool m_meshUvs = true; ///< if true UV coordinates will be exported + bool m_meshColours = true; ///< if true colour sets will be exported + bool m_meshHoles = true; ///< if true polygonal holes will be exported bool m_meshUV = false; ///< if true, export a scene hierarchy with all empty prims marked "over", only meshes UV will be filled in. - bool m_meshNormals = false; ///< if true normal vectors will be exported - bool m_leftHandedUV = false; ///< if true, UV indices retrieved from Maya will be adjusted to left-handed orientation, it only works with m_meshUV. bool m_nurbsCurves = true; ///< if true export nurbs curves bool m_dynamicAttributes = true; ///< if true export any dynamic attributes found on the nodes we are exporting bool m_duplicateInstances = true; ///< if true, instances will be exported as duplicates. As of 23/01/17, nothing will be exported if set to false. @@ -51,9 +56,11 @@ struct ExporterParams bool m_animation = false; ///< if true, animation will be exported. bool m_useTimelineRange = false; ///< if true, then the export uses Maya's timeline range. bool m_filterSample = false; ///< if true, duplicate sample of attribute will be filtered out - bool m_useAnimalSchema = (USE_AL_DEFAULT) ? true : false; ///< if true, the data exported will be designed to fit with Animal Logics internal needs. If false, the original pxr schema will be used. + int m_compactionLevel = 3; ///< by default apply the strongest level of data compaction AnimationTranslator* m_animTranslator = 0; ///< the animation translator to help exporting the animation data bool m_extensiveAnimationCheck = true; ///< if true, extensive animation check will be performed on transform nodes. + int m_exportAtWhichTime = 0; ///< controls where the data will be written to: 0 = default time, 1 = earliest time, 2 = current time + UsdTimeCode m_timeCode = UsdTimeCode::Default(); }; //---------------------------------------------------------------------------------------------------------------------- diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/ExportTranslator.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/ExportTranslator.cpp index 4c7c0604..39ab3005 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/ExportTranslator.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/ExportTranslator.cpp @@ -29,6 +29,25 @@ namespace AL { namespace usdmaya { namespace fileio { +//---------------------------------------------------------------------------------------------------------------------- +const char* const ExportTranslator::compactionLevels[] = { + "None", + "Basic", + "Medium", + "Extensive", + 0 +}; + +//---------------------------------------------------------------------------------------------------------------------- +const char* const ExportTranslator::timelineLevel[] = { + "Default Time", + "Earliest Time", + "Current Time", + "Min Timeline Range", + 0 +}; + + //---------------------------------------------------------------------------------------------------------------------- MStatus ExportTranslator::writer(const MFileObject& file, const AL::maya::utils::OptionsParser& options, FileAccessMode mode) { @@ -44,13 +63,23 @@ MStatus ExportTranslator::writer(const MFileObject& file, const AL::maya::utils: params.m_dynamicAttributes = options.getBool(kDynamicAttributes); params.m_duplicateInstances = options.getBool(kDuplicateInstances); params.m_meshes = options.getBool(kMeshes); + params.m_meshConnects = options.getBool(kMeshConnects); + params.m_meshPoints = options.getBool(kMeshPoints); params.m_meshNormals = options.getBool(kMeshNormals); + params.m_meshVertexCreases = options.getBool(kMeshVertexCreases); + params.m_meshEdgeCreases = options.getBool(kMeshEdgeCreases); + params.m_meshUvs = options.getBool(kMeshUvs); + params.m_meshColours = options.getBool(kMeshColours); + params.m_meshHoles = options.getBool(kMeshHoles); + params.m_compactionLevel = options.getInt(kCompactionLevel); params.m_nurbsCurves = options.getBool(kNurbsCurves); - params.m_useAnimalSchema = options.getBool(kUseAnimalSchema); params.m_mergeTransforms = options.getBool(kMergeTransforms); params.m_fileName = file.fullName(); params.m_selected = mode == MPxFileTranslator::kExportActiveAccessMode; params.m_animation = options.getBool(kAnimation); + params.m_exportAtWhichTime = options.getInt(kExportAtWhichTime); + + if(params.m_animation) { if(options.getBool(kUseTimelineRange)) @@ -87,6 +116,22 @@ MStatus ExportTranslator::writer(const MFileObject& file, const AL::maya::utils: it.next(); } } + + switch(params.m_exportAtWhichTime) + { + case 0: + params.m_timeCode = UsdTimeCode::Default(); + break; + case 1: + params.m_timeCode = UsdTimeCode::EarliestTime(); + break; + case 2: + params.m_timeCode = UsdTimeCode(MAnimControl::currentTime().value()); + break; + case 3: + params.m_timeCode = UsdTimeCode(params.m_minFrame); + break; + } Export exporter(params); diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/ExportTranslator.h b/lib/AL_USDMaya/AL/usdmaya/fileio/ExportTranslator.h index f2ae61ff..ff4d0fb2 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/ExportTranslator.h +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/ExportTranslator.h @@ -43,16 +43,30 @@ AL_MAYA_TRANSLATOR_BEGIN(ExportTranslator, "AL usdmaya export", false, true, "us // specify the option names (These will uniquely identify the exporter options) static constexpr const char* const kDynamicAttributes = "Dynamic Attributes"; ///< export dynamic attributes option name static constexpr const char* const kMeshes = "Meshes"; ///< export mesh geometry option name - static constexpr const char* const kMeshNormals = "Mesh Normals"; ///< export mesh mesh normals + static constexpr const char* const kMeshConnects = "Mesh Face Connects"; ///< export mesh face connects + static constexpr const char* const kMeshPoints = "Mesh Points"; ///< export mesh points + static constexpr const char* const kMeshNormals = "Mesh Normals"; ///< export mesh normals + static constexpr const char* const kMeshVertexCreases = "Mesh Vertex Creases"; ///< export mesh vertex creases + static constexpr const char* const kMeshEdgeCreases = "Mesh Edge Creases"; ///< export mesh edge creases + static constexpr const char* const kMeshUvs = "Mesh UVs"; ///< export mesh UV coordinates + static constexpr const char* const kMeshColours = "Mesh Colours"; ///< export mesh Colour Sets + static constexpr const char* const kMeshHoles = "Mesh Holes"; ///< export mesh face holes + static constexpr const char* const kCompactionLevel = "Compaction Level"; ///< export mesh face holes static constexpr const char* const kNurbsCurves = "Nurbs Curves"; ///< export nurbs curves option name static constexpr const char* const kDuplicateInstances = "Duplicate Instances"; ///< export instances option name - static constexpr const char* const kUseAnimalSchema = "Use Animal Schema"; ///< export using animal schema option name static constexpr const char* const kMergeTransforms = "Merge Transforms"; ///< export by merging transforms and shapes option name static constexpr const char* const kAnimation = "Animation"; ///< export animation data option name static constexpr const char* const kUseTimelineRange = "Use Timeline Range"; ///< export using the timeline range option name static constexpr const char* const kFrameMin = "Frame Min"; ///< specify min time frame option name static constexpr const char* const kFrameMax = "Frame Max"; ///< specify max time frame option name static constexpr const char* const kFilterSample = "Filter Sample"; ///< export filter sample option name + static constexpr const char* const kExportAtWhichTime = "Export At Which Time"; + + AL_USDMAYA_PUBLIC + static const char* const compactionLevels[]; + + AL_USDMAYA_PUBLIC + static const char* const timelineLevel[]; /// \brief provide a method to specify the export options /// \param options a set of options that are constructed and later used for option parsing @@ -63,16 +77,25 @@ AL_MAYA_TRANSLATOR_BEGIN(ExportTranslator, "AL usdmaya export", false, true, "us if(!options.addFrame("AL USD Exporter Options")) return MS::kFailure; if(!options.addBool(kDynamicAttributes, defaultValues.m_dynamicAttributes)) return MS::kFailure; if(!options.addBool(kMeshes, defaultValues.m_meshes)) return MS::kFailure; - if(!options.addBool(kMeshNormals, defaultValues.m_meshes)) return MS::kFailure; + if(!options.addBool(kMeshConnects, defaultValues.m_meshConnects)) return MS::kFailure; + if(!options.addBool(kMeshPoints, defaultValues.m_meshPoints)) return MS::kFailure; + if(!options.addBool(kMeshNormals, defaultValues.m_meshNormals)) return MS::kFailure; + if(!options.addBool(kMeshVertexCreases, defaultValues.m_meshVertexCreases)) return MS::kFailure; + if(!options.addBool(kMeshEdgeCreases, defaultValues.m_meshEdgeCreases)) return MS::kFailure; + if(!options.addBool(kMeshUvs, defaultValues.m_meshUvs)) return MS::kFailure; + if(!options.addBool(kMeshColours, defaultValues.m_meshColours)) return MS::kFailure; + if(!options.addBool(kMeshHoles, defaultValues.m_meshHoles)) return MS::kFailure; + if(!options.addEnum(kCompactionLevel, compactionLevels, defaultValues.m_compactionLevel)) return MS::kFailure; if(!options.addBool(kNurbsCurves, defaultValues.m_nurbsCurves)) return MS::kFailure; if(!options.addBool(kDuplicateInstances, defaultValues.m_duplicateInstances)) return MS::kFailure; - if(!options.addBool(kUseAnimalSchema, defaultValues.m_useAnimalSchema)) return MS::kFailure; if(!options.addBool(kMergeTransforms, defaultValues.m_mergeTransforms)) return MS::kFailure; if(!options.addBool(kAnimation, defaultValues.m_animation)) return MS::kFailure; if(!options.addBool(kUseTimelineRange, defaultValues.m_useTimelineRange)) return MS::kFailure; if(!options.addFloat(kFrameMin, defaultValues.m_minFrame)) return MS::kFailure; if(!options.addFloat(kFrameMax, defaultValues.m_maxFrame)) return MS::kFailure; if(!options.addBool(kFilterSample, defaultValues.m_filterSample)) return MS::kFailure; + if(!options.addEnum(kExportAtWhichTime, timelineLevel, defaultValues.m_exportAtWhichTime)) return MS::kFailure; + return MS::kSuccess; } diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/Import.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/Import.cpp index ac46ba03..eb860849 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/Import.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/Import.cpp @@ -310,6 +310,11 @@ MStatus ImportCommand::doIt(const MArgList& args) AL_MAYA_CHECK_ERROR(argData.getFlagArgument("-nc", 0, m_params.m_nurbsCurves), "ImportCommand: Unable to fetch \"nurbs curves\" argument"); } + if(argData.isFlagSet("-fd", &status)) + { + m_params.m_forceDefaultRead = true; + } + return redoIt(); } @@ -339,6 +344,7 @@ MSyntax ImportCommand::createSyntax() AL_MAYA_CHECK_ERROR2(syntax.addFlag("-da", "-dynamicAttribute", MSyntax::kBoolean), errorString); AL_MAYA_CHECK_ERROR2(syntax.addFlag("-m", "-meshes", MSyntax::kBoolean), errorString); AL_MAYA_CHECK_ERROR2(syntax.addFlag("-nc", "-nurbsCurves", MSyntax::kBoolean), errorString); + AL_MAYA_CHECK_ERROR2(syntax.addFlag("-fd", "-forceDefaultRead", MSyntax::kNoArg), errorString); syntax.makeFlagMultiUse("-arp"); syntax.enableQuery(false); syntax.enableEdit(false); diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/ImportParams.h b/lib/AL_USDMaya/AL/usdmaya/fileio/ImportParams.h index b05ed62e..4e5d16aa 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/ImportParams.h +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/ImportParams.h @@ -46,7 +46,7 @@ struct ImporterParams bool m_nurbsCurves = true; ///< true to import nurbs curves, false to ignore nurbs curves on import bool m_dynamicAttributes = true; ///< if true, attributes in the USD file marked as 'custom' will be imported as dynamic attributes. bool m_stageUnloaded = true; ///< if true, the USD stage will be opened with the UsdStage::LoadNone flag. If false the stage will be loaded with the UsdStage::LoadAll flag - bool m_useAnimalSchema = (USE_AL_DEFAULT) ? true : false; ///< if true, the data exported will be designed to fit with Animal Logics internal needs. If false, the original pxr schema will be used. + bool m_forceDefaultRead = false; ///< true to explicit read default values SdfLayerRefPtr m_rootLayer; ///< \todo Remove? SdfLayerRefPtr m_sessionLayer; ///< \todo Remove? }; diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/ImportTranslator.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/ImportTranslator.cpp index 6445d1ea..1b6529b8 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/ImportTranslator.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/ImportTranslator.cpp @@ -45,8 +45,9 @@ MStatus ImportTranslator::reader(const MFileObject& file, const AL::maya::utils: m_params.m_meshes = options.getBool(kMeshes); m_params.m_nurbsCurves = options.getBool(kNurbsCurves); m_params.m_animations = options.getBool(kAnimations); - m_params.m_animations = options.getBool(kAnimations); - + m_params.m_stageUnloaded = options.getBool(kStageUnload); + m_params.m_forceDefaultRead = options.getBool(kReadDefaultValues); + Import importer(m_params); return importer ? MS::kSuccess : MS::kFailure; // done! diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/ImportTranslator.h b/lib/AL_USDMaya/AL/usdmaya/fileio/ImportTranslator.h index f9d3d045..740c9de1 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/ImportTranslator.h +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/ImportTranslator.h @@ -46,7 +46,9 @@ AL_MAYA_TRANSLATOR_BEGIN(ImportTranslator, "AL usdmaya import", true, false, "*. static constexpr const char* const kNurbsCurves = "Import Curves"; ///< the import curves option name static constexpr const char* const kAnimations = "Import Animations"; ///< the import animation option name static constexpr const char* const kDynamicAttributes = "Import Dynamic Attributes"; ///< the import dynamic attributes option name - + static constexpr const char* const kStageUnload = "Load None"; ///< the import animation option name + static constexpr const char* const kReadDefaultValues = "Read Default Values"; ///< the import animation option name + /// \brief provide a method to specify the import options /// \param options a set of options that are constructed and later used for option parsing /// \return MS::kSuccess if ok @@ -58,6 +60,8 @@ AL_MAYA_TRANSLATOR_BEGIN(ImportTranslator, "AL usdmaya import", true, false, "*. if(!options.addBool(kNurbsCurves, true)) return MS::kFailure; if(!options.addBool(kAnimations, true)) return MS::kFailure; if(!options.addBool(kDynamicAttributes, true)) return MS::kFailure; + if(!options.addBool(kStageUnload, false)) return MS::kFailure; + if(!options.addBool(kReadDefaultValues, true)) return MS::kFailure; return MS::kSuccess; } diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/NodeFactory.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/NodeFactory.cpp index 159e4f94..fc3ce5cb 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/NodeFactory.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/NodeFactory.cpp @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -#include "AL/usdmaya/AttributeType.h" +#include "AL/usdmaya/utils/AttributeType.h" #include "AL/usdmaya/fileio/Import.h" #include "AL/usdmaya/fileio/ImportParams.h" #include "AL/usdmaya/fileio/NodeFactory.h" diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/NodeFactory.h b/lib/AL_USDMaya/AL/usdmaya/fileio/NodeFactory.h index c1951708..258d0f83 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/NodeFactory.h +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/NodeFactory.h @@ -43,6 +43,8 @@ struct NodeFactory /// \param from the prim we are copying the data from /// \param nodeType can be one of "transform", "mesh", "nurbsCurve", or "camera". /// \param parent the parent transform for the Maya data + /// \param parentUnmerged if false, the parent transform will be merged with a shape. If true, the nodes will remain + /// separate MObject createNode(const UsdPrim& from, const char* const nodeType, MObject parent, bool parentUnmerged = false); /// \brief Some of the translators rely on import settings specified in the import params. Prior to use of this factory, diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/SchemaPrims.h b/lib/AL_USDMaya/AL/usdmaya/fileio/SchemaPrims.h index f4f8f6cd..f283f10b 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/SchemaPrims.h +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/SchemaPrims.h @@ -42,7 +42,7 @@ extern const TfToken ALExcludedPrimSchema; /// \param created the returned MObject of the created node (can be null) /// \param context a custom context to use when importing the prim /// \param translator the custom translator to use to import the prim -/// \param forceImport overrides the default import state of the translator and forces and import. +/// \param param params controlling the import of the plugin translator nodes /// \return true if the import succeeded, false otherwise /// \ingroup fileio //---------------------------------------------------------------------------------------------------------------------- diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/CameraTranslator.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/CameraTranslator.cpp index 5cc6c1f6..5dbb4f61 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/CameraTranslator.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/CameraTranslator.cpp @@ -196,15 +196,15 @@ MStatus CameraTranslator::copyAttributes(const MObject& from, UsdPrim& prim, con AL_MAYA_CHECK_ERROR(getDistance(from, m_focusDistance, focusDistance), errorString); AL_MAYA_CHECK_ERROR(getDouble(from, m_lensSqueezeRatio, squeezeRatio), errorString); - usdCamera.GetProjectionAttr().Set(isOrthographic ? UsdGeomTokens->orthographic : UsdGeomTokens->perspective); - usdCamera.GetHorizontalApertureAttr().Set(float(horizontalAperture * squeezeRatio * inches_to_mm)); - usdCamera.GetVerticalApertureAttr().Set(float(verticalAperture * squeezeRatio * inches_to_mm)); - usdCamera.GetHorizontalApertureOffsetAttr().Set(float(horizontalApertureOffset * squeezeRatio * inches_to_mm)); - usdCamera.GetVerticalApertureOffsetAttr().Set(float(verticalApertureOffset * squeezeRatio * inches_to_mm)); - usdCamera.GetFocalLengthAttr().Set(float(focalLength)); - usdCamera.GetClippingRangeAttr().Set(GfVec2f(nearDistance.as(MDistance::kCentimeters), farDistance.as(MDistance::kCentimeters))); - usdCamera.GetFStopAttr().Set(float(fstop)); - usdCamera.GetFocusDistanceAttr().Set(float(focusDistance.as(MDistance::kCentimeters))); + usdCamera.GetProjectionAttr().Set(isOrthographic ? UsdGeomTokens->orthographic : UsdGeomTokens->perspective, params.m_timeCode); + usdCamera.GetHorizontalApertureAttr().Set(float(horizontalAperture * squeezeRatio * inches_to_mm), params.m_timeCode); + usdCamera.GetVerticalApertureAttr().Set(float(verticalAperture * squeezeRatio * inches_to_mm), params.m_timeCode); + usdCamera.GetHorizontalApertureOffsetAttr().Set(float(horizontalApertureOffset * squeezeRatio * inches_to_mm), params.m_timeCode); + usdCamera.GetVerticalApertureOffsetAttr().Set(float(verticalApertureOffset * squeezeRatio * inches_to_mm), params.m_timeCode); + usdCamera.GetFocalLengthAttr().Set(float(focalLength), params.m_timeCode); + usdCamera.GetClippingRangeAttr().Set(GfVec2f(nearDistance.as(MDistance::kCentimeters), farDistance.as(MDistance::kCentimeters)), params.m_timeCode); + usdCamera.GetFStopAttr().Set(float(fstop), params.m_timeCode); + usdCamera.GetFocusDistanceAttr().Set(float(focusDistance.as(MDistance::kCentimeters)), params.m_timeCode); AnimationTranslator* animTranslator = params.m_animTranslator; if(animTranslator) diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/DagNodeTranslator.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/DagNodeTranslator.cpp index 505ac804..29271689 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/DagNodeTranslator.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/DagNodeTranslator.cpp @@ -53,6 +53,7 @@ MStatus DagNodeTranslator::registerType() return MS::kSuccess; } +//---------------------------------------------------------------------------------------------------------------------- void DagNodeTranslator::initialiseDefaultShadingGroup(MObject& target) { MSelectionList sl; diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/DgNodeTranslator.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/DgNodeTranslator.cpp index b01b9982..565a3198 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/DgNodeTranslator.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/DgNodeTranslator.cpp @@ -24,7 +24,6 @@ #include "maya/MGlobal.h" #include "maya/MPlug.h" #include "maya/MFnDependencyNode.h" -#include "maya/MDGModifier.h" #include "maya/MMatrixArray.h" #include "maya/MFnMatrixData.h" #include "maya/MFnMatrixArrayData.h" @@ -84,2582 +83,12 @@ MStatus DgNodeTranslator::copyAttributes(const MObject& from, UsdPrim& to, const return MS::kSuccess; } -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::setAngleAnim(const MObject node, const MObject attr, const UsdGeomXformOp op) -{ - MStatus status; - const char* const errorString = "DgNodeTranslator::setAngleAnim"; - - MPlug plug(node, attr); - MFnAnimCurve fnCurve; - fnCurve.create(plug, NULL, &status); - AL_MAYA_CHECK_ERROR(status, errorString); - - std::vector times; - op.GetTimeSamples(×); - - const float conversionFactor = 0.0174533f; - - float value = 0; - for(auto const& timeValue: times) - { - const bool retValue = op.GetAs(&value, timeValue); - if (!retValue) continue; - - MTime tm(timeValue, MTime::kFilm); - - switch (fnCurve.animCurveType()) - { - case MFnAnimCurve::kAnimCurveTL: - case MFnAnimCurve::kAnimCurveTA: - case MFnAnimCurve::kAnimCurveTU: - { - fnCurve.addKey(tm, value * conversionFactor, MFnAnimCurve::kTangentGlobal, MFnAnimCurve::kTangentGlobal, NULL, &status); - AL_MAYA_CHECK_ERROR(status, errorString); - break; - } - default: - { - std::cout << "[DgNodeTranslator::setAngleAnim] Unexpected anim curve type: " << fnCurve.animCurveType() << std::endl; - break; - } - } - } - - return MS::kSuccess; -} - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::setFloatAttrAnim(const MObject node, const MObject attr, UsdAttribute usdAttr, double conversionFactor) -{ - if (!usdAttr.GetNumTimeSamples()) - { - return MS::kFailure; - } - - const char* const errorString = "DgNodeTranslator::setFloatAttrAnim"; - MStatus status; - - MPlug plug(node, attr); - MPlug srcPlug; - MFnAnimCurve fnCurve; - MDGModifier dgmod; - - srcPlug = plug.source(&status); - AL_MAYA_CHECK_ERROR(status, errorString); - if(!srcPlug.isNull()) - { - std::cout << "[DgNodeTranslator::setFloatAttrAnim] disconnecting curve! = " << srcPlug.name().asChar() << std::endl; - dgmod.disconnect(srcPlug, plug); - dgmod.doIt(); - } - fnCurve.create(plug, NULL, &status); - AL_MAYA_CHECK_ERROR(status, errorString); - - std::vector times; - usdAttr.GetTimeSamples(×); - - float value; - for(auto const& timeValue: times) - { - const bool retValue = usdAttr.Get(&value, timeValue); - if(!retValue) continue; - - MTime tm(timeValue, MTime::kFilm); - - switch(fnCurve.animCurveType()) - { - case MFnAnimCurve::kAnimCurveTL: - case MFnAnimCurve::kAnimCurveTA: - case MFnAnimCurve::kAnimCurveTU: - { - fnCurve.addKey(tm, value * conversionFactor, MFnAnimCurve::kTangentGlobal, MFnAnimCurve::kTangentGlobal, NULL, &status); - AL_MAYA_CHECK_ERROR(status, errorString); - break; - } - default: - { - std::cout << "[DgNodeTranslator::setFloatAttrAnim] OTHER ANIM CURVE TYPE! = " << fnCurve.animCurveType() << std::endl; - break; - } - } - } - - return MS::kSuccess; -} - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::setVisAttrAnim(const MObject node, const MObject attr, const UsdAttribute &usdAttr) -{ - if (!usdAttr.GetNumTimeSamples()) - { - return MS::kFailure; - } - - const char* const errorString = "DgNodeTranslator::setVisAttrAnim"; - MStatus status; - - MPlug plug(node, attr); - MPlug srcPlug; - MFnAnimCurve fnCurve; - MDGModifier dgmod; - - srcPlug = plug.source(&status); - AL_MAYA_CHECK_ERROR(status, errorString); - if(!srcPlug.isNull()) - { - std::cout << "[DgNodeTranslator::setVisAttrAnim] disconnecting curve! = " << srcPlug.name().asChar() << std::endl; - dgmod.disconnect(srcPlug, plug); - dgmod.doIt(); - } - fnCurve.create(plug, NULL, &status); - AL_MAYA_CHECK_ERROR(status, errorString); - - std::vector times; - usdAttr.GetTimeSamples(×); - - TfToken value; - for(auto const& timeValue: times) - { - const bool retValue = usdAttr.Get(&value, timeValue); - if(!retValue) continue; - - MTime tm(timeValue, MTime::kFilm); - - fnCurve.addKey(tm, (value == UsdGeomTokens->invisible) ? 0 : 1, MFnAnimCurve::kTangentGlobal, MFnAnimCurve::kTangentGlobal, NULL, &status); - AL_MAYA_CHECK_ERROR(status, errorString); - } - - return MS::kSuccess; -} - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::copyBool(MObject node, MObject attr, const UsdAttribute& value) -{ - if(value.IsAuthored() && value.HasValue()) - { - bool data; - value.Get (&data); - return setBool(node, attr, data); - } - return MS::kSuccess; -} - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::copyFloat(MObject node, MObject attr, const UsdAttribute& value) -{ - if(value.IsAuthored() && value.HasValue()) - { - float data; - value.Get (&data); - return setFloat(node, attr, data); - } - return MS::kSuccess; -} - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::copyDouble(MObject node, MObject attr, const UsdAttribute& value) -{ - if(value.IsAuthored() && value.HasValue()) - { - double data; - value.Get (&data); - return setDouble(node, attr, data); - } - return MS::kSuccess; -} - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::copyInt(MObject node, MObject attr, const UsdAttribute& value) -{ - if(value.IsAuthored() && value.HasValue()) - { - int data; - value.Get (&data); - return setBool(node, attr, data); - } - return MS::kSuccess; -} - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::copyVec3(MObject node, MObject attr, const UsdAttribute& value) -{ - if(value.IsAuthored() && value.HasValue()) - { - int data; - value.Get (&data); - return setBool(node, attr, data); - } - return MS::kSuccess; -} - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::setUsdBoolArray(const MObject& node, const MObject& attribute, const VtArray& values) -{ - MPlug plug(node, attribute); - if(!plug || !plug.isArray()) - return MS::kFailure; - - AL_MAYA_CHECK_ERROR(plug.setNumElements(values.size()), "DgNodeTranslator: attribute array could not be resized"); - - for(size_t i = 0, n = values.size(); i != n; ++i) - { - plug.elementByLogicalIndex(i).setBool(values[i]); - } - - return MS::kSuccess; -} - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::getUsdBoolArray(const MObject& node, const MObject& attr, VtArray& values) -{ - // - // Handle the oddity that is std::vector - // - - MPlug plug(node, attr); - if(!plug || !plug.isArray()) - return MS::kFailure; - - uint32_t num = plug.numElements(); - values.resize(num); - for(uint32_t i = 0; i < num; ++i) - { - values[i] = plug.elementByLogicalIndex(i).asBool(); - } - return MS::kSuccess; -} - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::addDynamicAttribute(MObject node, const UsdAttribute& usdAttr) -{ - const SdfValueTypeName typeName = usdAttr.GetTypeName(); - const bool isArray = typeName.IsArray(); - const UsdDataType dataType = getAttributeType(usdAttr); - MObject attribute = MObject::kNullObj; - const char* attrName = usdAttr.GetName().GetString().c_str(); - const uint32_t flags = (isArray ? AL::maya::utils::NodeHelper::kArray : 0) | AL::maya::utils::NodeHelper::kReadable | AL::maya::utils::NodeHelper::kWritable | AL::maya::utils::NodeHelper::kStorable | AL::maya::utils::NodeHelper::kConnectable; - switch(dataType) - { - case UsdDataType::kAsset: - { - return MS::kSuccess; - } - break; - - case UsdDataType::kBool: - { - AL::maya::utils::NodeHelper::addBoolAttr(node, attrName, attrName, false, flags, &attribute); - } - break; - - case UsdDataType::kUChar: - { - AL::maya::utils::NodeHelper::addInt8Attr(node, attrName, attrName, 0, flags, &attribute); - } - break; - - case UsdDataType::kInt: - case UsdDataType::kUInt: - { - AL::maya::utils::NodeHelper::addInt32Attr(node, attrName, attrName, 0, flags, &attribute); - } - break; - - case UsdDataType::kInt64: - case UsdDataType::kUInt64: - { - AL::maya::utils::NodeHelper::addInt64Attr(node, attrName, attrName, 0, flags, &attribute); - } - break; - - case UsdDataType::kHalf: - case UsdDataType::kFloat: - { - AL::maya::utils::NodeHelper::addFloatAttr(node, attrName, attrName, 0, flags, &attribute); - } - break; - - case UsdDataType::kDouble: - { - AL::maya::utils::NodeHelper::addDoubleAttr(node, attrName, attrName, 0, flags, &attribute); - } - break; - - case UsdDataType::kString: - { - AL::maya::utils::NodeHelper::addStringAttr(node, attrName, attrName, flags, true, &attribute); - } - break; - - case UsdDataType::kMatrix2d: - { - const float defValue[2][2] = {{0, 0}, {0, 0}}; - AL::maya::utils::NodeHelper::addMatrix2x2Attr(node, attrName, attrName, defValue, flags, &attribute); - } - break; - - case UsdDataType::kMatrix3d: - { - const float defValue[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; - AL::maya::utils::NodeHelper::addMatrix3x3Attr(node, attrName, attrName, defValue, flags, &attribute); - } - break; - - case UsdDataType::kMatrix4d: - { - AL::maya::utils::NodeHelper::addMatrixAttr(node, attrName, attrName, MMatrix(), flags, &attribute); - } - break; - - case UsdDataType::kQuatd: - { - AL::maya::utils::NodeHelper::addVec4dAttr(node, attrName, attrName, flags, &attribute); - } - break; - - case UsdDataType::kQuatf: - case UsdDataType::kQuath: - { - AL::maya::utils::NodeHelper::addVec4fAttr(node, attrName, attrName, flags, &attribute); - } - break; - - case UsdDataType::kVec2d: - { - AL::maya::utils::NodeHelper::addVec2dAttr(node, attrName, attrName, flags, &attribute); - } - break; - - case UsdDataType::kVec2f: - case UsdDataType::kVec2h: - { - AL::maya::utils::NodeHelper::addVec2fAttr(node, attrName, attrName, flags, &attribute); - } - break; - - case UsdDataType::kVec2i: - { - AL::maya::utils::NodeHelper::addVec2iAttr(node, attrName, attrName, flags, &attribute); - } - break; - - case UsdDataType::kVec3d: - { - AL::maya::utils::NodeHelper::addVec3dAttr(node, attrName, attrName, flags, &attribute); - } - break; - - case UsdDataType::kVec3f: - case UsdDataType::kVec3h: - { - AL::maya::utils::NodeHelper::addVec3fAttr(node, attrName, attrName, flags, &attribute); - } - break; - - case UsdDataType::kVec3i: - { - AL::maya::utils::NodeHelper::addVec3iAttr(node, attrName, attrName, flags, &attribute); - } - break; - - case UsdDataType::kVec4d: - { - AL::maya::utils::NodeHelper::addVec4dAttr(node, attrName, attrName, flags, &attribute); - } - break; - - case UsdDataType::kVec4f: - case UsdDataType::kVec4h: - { - AL::maya::utils::NodeHelper::addVec4fAttr(node, attrName, attrName, flags, &attribute); - } - break; - - case UsdDataType::kVec4i: - { - AL::maya::utils::NodeHelper::addVec4iAttr(node, attrName, attrName, flags, &attribute); - } - break; - - default: - MGlobal::displayError("DgNodeTranslator::addDynamicAttribute - unsupported USD data type"); - return MS::kFailure; - } - - if(isArray) - { - return setArrayMayaValue(node, attribute, usdAttr, dataType); - } - return setSingleMayaValue(node, attribute, usdAttr, dataType); -} - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::setMayaValue(MObject node, MObject attr, const UsdAttribute& usdAttr) -{ - const SdfValueTypeName typeName = usdAttr.GetTypeName(); - UsdDataType dataType = getAttributeType(usdAttr); - - if(typeName.IsArray()) - { - return setArrayMayaValue(node, attr, usdAttr, dataType); - } - return setSingleMayaValue(node, attr, usdAttr, dataType); -} - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::setArrayMayaValue(MObject node, MObject attr, const UsdAttribute& usdAttr, const UsdDataType type) -{ - switch(type) - { - case UsdDataType::kBool: - { - VtArray value; - usdAttr.Get(&value); - return setUsdBoolArray(node, attr, value); - } - - case UsdDataType::kUChar: - { - VtArray value; - usdAttr.Get(&value); - return setInt8Array(node, attr, (const int8_t*)value.cdata(), value.size()); - } - - case UsdDataType::kInt: - { - VtArray value; - usdAttr.Get(&value); - return setInt32Array(node, attr, (const int32_t*)value.cdata(), value.size()); - } - - case UsdDataType::kUInt: - { - VtArray value; - usdAttr.Get(&value); - return setInt32Array(node, attr, (const int32_t*)value.cdata(), value.size()); - } - - case UsdDataType::kInt64: - { - VtArray value; - usdAttr.Get(&value); - return setInt64Array(node, attr, (const int64_t*)value.cdata(), value.size()); - } - - case UsdDataType::kUInt64: - { - VtArray value; - usdAttr.Get(&value); - return setInt64Array(node, attr, (const int64_t*)value.cdata(), value.size()); - } - - case UsdDataType::kHalf: - { - VtArray value; - usdAttr.Get(&value); - return setHalfArray(node, attr, (const GfHalf*)value.cdata(), value.size()); - } - - case UsdDataType::kFloat: - { - VtArray value; - usdAttr.Get(&value); - return setFloatArray(node, attr, (const float*)value.cdata(), value.size()); - } - - case UsdDataType::kDouble: - { - VtArray value; - usdAttr.Get(&value); - return setDoubleArray(node, attr, (const double*)value.cdata(), value.size()); - } - - case UsdDataType::kString: - { - VtArray value; - usdAttr.Get(&value); - return setStringArray(node, attr, (const std::string*)value.cdata(), value.size()); - } - - case UsdDataType::kMatrix2d: - { - VtArray value; - usdAttr.Get(&value); - return setMatrix2x2Array(node, attr, (const double*)value.cdata(), value.size()); - } - - case UsdDataType::kMatrix3d: - { - VtArray value; - usdAttr.Get(&value); - return setMatrix3x3Array(node, attr, (const double*)value.cdata(), value.size()); - } - - case UsdDataType::kMatrix4d: - { - VtArray value; - usdAttr.Get(&value); - return setMatrix4x4Array(node, attr, (const double*)value.cdata(), value.size()); - } - - case UsdDataType::kQuatd: - { - VtArray value; - usdAttr.Get(&value); - return setQuatArray(node, attr, (const double*)value.cdata(), value.size()); - } - - case UsdDataType::kQuatf: - { - VtArray value; - usdAttr.Get(&value); - return setQuatArray(node, attr, (const float*)value.cdata(), value.size()); - } - - case UsdDataType::kQuath: - { - VtArray value; - usdAttr.Get(&value); - return setQuatArray(node, attr, (const GfHalf*)value.cdata(), value.size()); - } - - case UsdDataType::kVec2d: - { - VtArray value; - usdAttr.Get(&value); - return setVec2Array(node, attr, (const double*)value.cdata(), value.size()); - } - - case UsdDataType::kVec2f: - { - VtArray value; - usdAttr.Get(&value); - return setVec2Array(node, attr, (const float*)value.cdata(), value.size()); - } - - case UsdDataType::kVec2h: - { - VtArray value; - usdAttr.Get(&value); - return setVec2Array(node, attr, (const GfHalf*)value.cdata(), value.size()); - } - - case UsdDataType::kVec2i: - { - VtArray value; - usdAttr.Get(&value); - return setVec2Array(node, attr, (const int32_t*)value.cdata(), value.size()); - } - - case UsdDataType::kVec3d: - { - VtArray value; - usdAttr.Get(&value); - return setVec3Array(node, attr, (const double*)value.cdata(), value.size()); - } - - case UsdDataType::kVec3f: - { - VtArray value; - usdAttr.Get(&value); - return setVec3Array(node, attr, (const float*)value.cdata(), value.size()); - } - - case UsdDataType::kVec3h: - { - VtArray value; - usdAttr.Get(&value); - return setVec3Array(node, attr, (const GfHalf*)value.cdata(), value.size()); - } - - case UsdDataType::kVec3i: - { - VtArray value; - usdAttr.Get(&value); - return setVec3Array(node, attr, (const int32_t*)value.cdata(), value.size()); - } - - case UsdDataType::kVec4d: - { - VtArray value; - usdAttr.Get(&value); - return setVec4Array(node, attr, (const double*)value.cdata(), value.size()); - } - - case UsdDataType::kVec4f: - { - VtArray value; - usdAttr.Get(&value); - return setVec4Array(node, attr, (const float*)value.cdata(), value.size()); - } - - case UsdDataType::kVec4h: - { - VtArray value; - usdAttr.Get(&value); - return setVec4Array(node, attr, (const GfHalf*)value.cdata(), value.size()); - } - - case UsdDataType::kVec4i: - { - VtArray value; - usdAttr.Get(&value); - return setVec4Array(node, attr, (const int32_t*)value.cdata(), value.size()); - } - - default: - MGlobal::displayError("DgNodeTranslator::setArrayMayaValue - unsupported USD data type"); - break; - } - return MS::kFailure; -} - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::setSingleMayaValue(MObject node, MObject attr, const UsdAttribute& usdAttr, const UsdDataType type) -{ - switch(type) - { - case UsdDataType::kBool: - { - bool value; - usdAttr.Get(&value); - return setBool(node, attr, value); - } - - case UsdDataType::kUChar: - { - unsigned char value; - usdAttr.Get(&value); - return setInt8(node, attr, value); - } - - case UsdDataType::kInt: - { - int32_t value; - usdAttr.Get(&value); - return setInt32(node, attr, value); - } - - case UsdDataType::kUInt: - { - uint32_t value; - usdAttr.Get(&value); - return setInt32(node, attr, value); - } - - case UsdDataType::kInt64: - { - int64_t value; - usdAttr.Get(&value); - return setInt64(node, attr, value); - } - - case UsdDataType::kUInt64: - { - uint64_t value; - usdAttr.Get(&value); - return setInt64(node, attr, value); - } - - case UsdDataType::kHalf: - { - GfHalf value; - usdAttr.Get(&value); - return setFloat(node, attr, value); - } - - case UsdDataType::kFloat: - { - float value; - usdAttr.Get(&value); - return setFloat(node, attr, value); - } - - case UsdDataType::kDouble: - { - double value; - usdAttr.Get(&value); - return setDouble(node, attr, value); - } - - case UsdDataType::kString: - { - std::string value; - usdAttr.Get(&value); - return setString(node, attr, value.c_str()); - } - - case UsdDataType::kMatrix2d: - { - GfMatrix2d value; - usdAttr.Get(&value); - return setMatrix2x2(node, attr, value.GetArray()); - } - - case UsdDataType::kMatrix3d: - { - GfMatrix3d value; - usdAttr.Get(&value); - return setMatrix3x3(node, attr, value.GetArray()); - } - - case UsdDataType::kMatrix4d: - { - GfMatrix4d value; - usdAttr.Get(&value); - return setMatrix4x4(node, attr, value.GetArray()); - } - - case UsdDataType::kQuatd: - { - GfQuatd value; - usdAttr.Get(&value); - return setQuat(node, attr, reinterpret_cast(&value)); - } - - case UsdDataType::kQuatf: - { - GfQuatf value; - usdAttr.Get(&value); - return setQuat(node, attr, reinterpret_cast(&value)); - } - - case UsdDataType::kQuath: - { - GfQuath value; - usdAttr.Get(&value); - float xyzw[4]; - xyzw[0] = value.GetImaginary()[0]; - xyzw[1] = value.GetImaginary()[1]; - xyzw[2] = value.GetImaginary()[2]; - xyzw[3] = value.GetReal(); - return setQuat(node, attr, xyzw); - } - - case UsdDataType::kVec2d: - { - GfVec2d value; - usdAttr.Get(&value); - return setVec2(node, attr, reinterpret_cast(&value)); - } - - case UsdDataType::kVec2f: - { - GfVec2f value; - usdAttr.Get(&value); - return setVec2(node, attr, reinterpret_cast(&value)); - } - - case UsdDataType::kVec2h: - { - GfVec2h value; - usdAttr.Get(&value); - float data[2]; - data[0] = value[0]; - data[1] = value[1]; - return setVec2(node, attr, data); - } - - case UsdDataType::kVec2i: - { - GfVec2i value; - usdAttr.Get(&value); - return setVec2(node, attr, reinterpret_cast(&value)); - } - - case UsdDataType::kVec3d: - { - GfVec3d value; - usdAttr.Get(&value); - return setVec3(node, attr, reinterpret_cast(&value)); - } - - case UsdDataType::kVec3f: - { - GfVec3f value; - usdAttr.Get(&value); - return setVec3(node, attr, reinterpret_cast(&value)); - } - - case UsdDataType::kVec3h: - { - GfVec3h value; - usdAttr.Get(&value); - return setVec3(node, attr, value[0], value[1], value[2]); - } - - case UsdDataType::kVec3i: - { - GfVec3i value; - usdAttr.Get(&value); - return setVec3(node, attr, reinterpret_cast(&value)); - } - - case UsdDataType::kVec4d: - { - GfVec4d value; - usdAttr.Get(&value); - return setVec4(node, attr, reinterpret_cast(&value)); - } - - case UsdDataType::kVec4f: - { - GfVec4f value; - usdAttr.Get(&value); - return setVec4(node, attr, reinterpret_cast(&value)); - } - - case UsdDataType::kVec4h: - { - GfVec4h value; - usdAttr.Get(&value); - float xyzw[4]; - xyzw[0] = value[0]; - xyzw[1] = value[1]; - xyzw[2] = value[2]; - xyzw[3] = value[3]; - return setVec4(node, attr, xyzw); - } - - case UsdDataType::kVec4i: - { - GfVec4i value; - usdAttr.Get(&value); - return setVec4(node, attr, reinterpret_cast(&value)); - } - - default: - MGlobal::displayError("DgNodeTranslator::setArrayMayaValue - unsupported USD data type"); - break; - } - return MS::kFailure; -} - //---------------------------------------------------------------------------------------------------------------------- bool DgNodeTranslator::attributeHandled(const UsdAttribute& usdAttr) { return false; } - - -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::convertSpecialValueToUSDAttribute(const MPlug& plug, UsdAttribute& usdAttr) -{ - // now we start some hard-coded special attribute value type conversion, no better way found: - // interpolateBoundary: This property comes from alembic, in maya it is boolean type: - if(usdAttr.GetName() == UsdGeomTokens->interpolateBoundary) - { - if(plug.asBool()) - usdAttr.Set(UsdGeomTokens->edgeAndCorner); - else - usdAttr.Set(UsdGeomTokens->edgeOnly); - - return MS::kSuccess; - } - // more special type conversion rules might come here.. - return MS::kFailure; -} -//---------------------------------------------------------------------------------------------------------------------- -MStatus DgNodeTranslator::copyDynamicAttributes(MObject node, UsdPrim& prim) -{ - MFnDependencyNode fn(node); - uint32_t numAttributes = fn.attributeCount(); - for(uint32_t i = 0; i < numAttributes; ++i) - { - MObject attribute = fn.attribute(i); - MPlug plug(node, attribute); - - // skip child attributes (only export from highest level) - if(plug.isChild()) - continue; - - bool isDynamic = plug.isDynamic(); - if(isDynamic) - { - TfToken attributeName = TfToken(plug.partialName(false, false, false, false, false, true).asChar()); - - // first test if the attribute happen to come with the prim by nature and we have a mapping rule for it: - if(prim.HasAttribute(attributeName)) - { - UsdAttribute usdAttr = prim.GetAttribute(attributeName); - // if the conversion works, we are done: - if(convertSpecialValueToUSDAttribute(plug, usdAttr)) - { - continue; - } - // if not, then we count on CreateAttribute codes below since that will return the USDAttribute if - // already exists and hopefully the type conversions below will work. - } - - bool isArray = plug.isArray(); - switch(attribute.apiType()) - { - case MFn::kAttribute2Double: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Double2); - GfVec2d m; - getVec2(node, attribute, (double*)&m); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Double2Array); - VtArray m; - m.resize(plug.numElements()); - getVec2Array(node, attribute, (double*)m.data(), m.size()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - case MFn::kAttribute2Float: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Float2); - GfVec2f m; - getVec2(node, attribute, (float*)&m); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Float2Array); - VtArray m; - m.resize(plug.numElements()); - getVec2Array(node, attribute, (float*)m.data(), m.size()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - case MFn::kAttribute2Int: - case MFn::kAttribute2Short: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Int2); - GfVec2i m; - getVec2(node, attribute, (int32_t*)&m); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Int2Array); - VtArray m; - m.resize(plug.numElements()); - getVec2Array(node, attribute, (int32_t*)m.data(), m.size()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - case MFn::kAttribute3Double: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Double3); - GfVec3d m; - getVec3(node, attribute, (double*)&m); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Double3Array); - VtArray m; - m.resize(plug.numElements()); - getVec3Array(node, attribute, (double*)m.data(), m.size()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - case MFn::kAttribute3Float: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Float3); - GfVec3f m; - getVec3(node, attribute, (float*)&m); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Float3Array); - VtArray m; - m.resize(plug.numElements()); - getVec3Array(node, attribute, (float*)m.data(), m.size()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - case MFn::kAttribute3Long: - case MFn::kAttribute3Short: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Int3); - GfVec3i m; - getVec3(node, attribute, (int32_t*)&m); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Int3Array); - VtArray m; - m.resize(plug.numElements()); - getVec3Array(node, attribute, (int32_t*)m.data(), m.size()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - case MFn::kAttribute4Double: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Double4); - GfVec4d m; - getVec4(node, attribute, (double*)&m); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Double4Array); - VtArray m; - m.resize(plug.numElements()); - getVec4Array(node, attribute, (double*)m.data(), m.size()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - case MFn::kNumericAttribute: - { - MFnNumericAttribute fn(attribute); - switch(fn.unitType()) - { - case MFnNumericData::kBoolean: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Bool); - bool value; - getBool(node, attribute, value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->BoolArray); - VtArray m; - m.resize(plug.numElements()); - getUsdBoolArray(node, attribute, m); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - case MFnNumericData::kFloat: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Float); - float value; - getFloat(node, attribute, value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->FloatArray); - VtArray m; - m.resize(plug.numElements()); - getFloatArray(node, attribute, (float*)m.data(), m.size()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - case MFnNumericData::kDouble: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Double); - double value; - getDouble(node, attribute, value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->DoubleArray); - VtArray m; - m.resize(plug.numElements()); - getDoubleArray(node, attribute, (double*)m.data(), m.size()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - case MFnNumericData::kInt: - case MFnNumericData::kShort: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Int); - int32_t value; - getInt32(node, attribute, value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->IntArray); - VtArray m; - m.resize(plug.numElements()); - getInt32Array(node, attribute, (int32_t*)m.data(), m.size()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - case MFnNumericData::kInt64: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Int64); - int64_t value; - getInt64(node, attribute, value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Int64Array); - VtArray m; - m.resize(plug.numElements()); - getInt64Array(node, attribute, (int64_t*)m.data(), m.size()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - case MFnNumericData::kByte: - case MFnNumericData::kChar: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->UChar); - int16_t value; - getInt16(node, attribute, value); - usdAttr.Set(uint8_t(value)); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->UCharArray); - VtArray m; - m.resize(plug.numElements()); - getInt8Array(node, attribute, (int8_t*)m.data(), m.size()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - default: - { - std::cout << "Unhandled numeric attribute: " << fn.name().asChar() << " " << fn.unitType() << std::endl; - } - break; - } - } - break; - - case MFn::kDoubleAngleAttribute: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Double); - double value; - getDouble(node, attribute, value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->DoubleArray); - VtArray value; - value.resize(plug.numElements()); - getDoubleArray(node, attribute, (double*)value.data(), value.size()); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - } - break; - - case MFn::kFloatAngleAttribute: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Float); - float value; - getFloat(node, attribute, value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->FloatArray); - VtArray value; - value.resize(plug.numElements()); - getFloatArray(node, attribute, (float*)value.data(), value.size()); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - } - break; - - case MFn::kDoubleLinearAttribute: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Double); - double value; - getDouble(node, attribute, value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->DoubleArray); - VtArray value; - value.resize(plug.numElements()); - getDoubleArray(node, attribute, (double*)value.data(), value.size()); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - } - break; - - case MFn::kFloatLinearAttribute: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Float); - float value; - getFloat(node, attribute, value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->FloatArray); - VtArray value; - value.resize(plug.numElements()); - getFloatArray(node, attribute, (float*)value.data(), value.size()); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - } - break; - - case MFn::kTimeAttribute: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Double); - double value; - getDouble(node, attribute, value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->DoubleArray); - VtArray value; - value.resize(plug.numElements()); - getDoubleArray(node, attribute, (double*)value.data(), value.size()); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - } - break; - - case MFn::kEnumAttribute: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Int); - int32_t value; - getInt32(node, attribute, value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->IntArray); - VtArray m; - m.resize(plug.numElements()); - getInt32Array(node, attribute, (int32_t*)m.data(), m.size()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - } - break; - - case MFn::kTypedAttribute: - { - MFnTypedAttribute fnTyped(plug.attribute()); - MFnData::Type type = fnTyped.attrType(); - - switch(type) - { - case MFnData::kString: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->String); - std::string value; - getString(node, attribute, value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->StringArray); - VtArray value; - value.resize(plug.numElements()); - getStringArray(node, attribute, (std::string*)value.data(), value.size()); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - } - break; - - case MFnData::kMatrixArray: - { - MFnMatrixArrayData fnData(plug.asMObject()); - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Matrix4dArray); - VtArray m; - m.assign((const GfMatrix4d*)&fnData.array()[0], ((const GfMatrix4d*)&fnData.array()[0]) + fnData.array().length()); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - break; - - default: - { - std::cout << "Unhandled typed attribute: " << fn.name().asChar() << " " << fn.typeName().asChar() << std::endl; - } - break; - } - } - break; - - case MFn::kCompoundAttribute: - { - MFnCompoundAttribute fnCompound(plug.attribute()); - { - if(fnCompound.numChildren() == 2) - { - MObject x = fnCompound.child(0); - MObject y = fnCompound.child(1); - if(x.apiType() == MFn::kCompoundAttribute && - y.apiType() == MFn::kCompoundAttribute) - { - MFnCompoundAttribute fnCompoundX(x); - MFnCompoundAttribute fnCompoundY(y); - - if(fnCompoundX.numChildren() == 2 && fnCompoundY.numChildren() == 2) - { - MObject xx = fnCompoundX.child(0); - MObject xy = fnCompoundX.child(1); - MObject yx = fnCompoundY.child(0); - MObject yy = fnCompoundY.child(1); - if(xx.apiType() == MFn::kNumericAttribute && - xy.apiType() == MFn::kNumericAttribute && - yx.apiType() == MFn::kNumericAttribute && - yy.apiType() == MFn::kNumericAttribute) - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Matrix2d); - GfMatrix2d value; - getMatrix2x2(node, attribute, (double*)&value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Matrix2dArray); - VtArray value; - value.resize(plug.numElements()); - getMatrix2x2Array(node, attribute, (double*)value.data(), plug.numElements()); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - } - } - } - } - else - if(fnCompound.numChildren() == 3) - { - MObject x = fnCompound.child(0); - MObject y = fnCompound.child(1); - MObject z = fnCompound.child(2); - if(x.apiType() == MFn::kCompoundAttribute && - y.apiType() == MFn::kCompoundAttribute && - z.apiType() == MFn::kCompoundAttribute) - { - MFnCompoundAttribute fnCompoundX(x); - MFnCompoundAttribute fnCompoundY(y); - MFnCompoundAttribute fnCompoundZ(z); - - if(fnCompoundX.numChildren() == 3 && fnCompoundY.numChildren() == 3 && fnCompoundZ.numChildren() == 3) - { - MObject xx = fnCompoundX.child(0); - MObject xy = fnCompoundX.child(1); - MObject xz = fnCompoundX.child(2); - MObject yx = fnCompoundY.child(0); - MObject yy = fnCompoundY.child(1); - MObject yz = fnCompoundY.child(2); - MObject zx = fnCompoundZ.child(0); - MObject zy = fnCompoundZ.child(1); - MObject zz = fnCompoundZ.child(2); - if(xx.apiType() == MFn::kNumericAttribute && - xy.apiType() == MFn::kNumericAttribute && - xz.apiType() == MFn::kNumericAttribute && - yx.apiType() == MFn::kNumericAttribute && - yy.apiType() == MFn::kNumericAttribute && - yz.apiType() == MFn::kNumericAttribute && - zx.apiType() == MFn::kNumericAttribute && - zy.apiType() == MFn::kNumericAttribute && - zz.apiType() == MFn::kNumericAttribute) - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Matrix3d); - GfMatrix3d value; - getMatrix3x3(node, attribute, (double*)&value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Matrix3dArray); - VtArray value; - value.resize(plug.numElements()); - getMatrix3x3Array(node, attribute, (double*)value.data(), plug.numElements()); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - } - } - } - } - else - if(fnCompound.numChildren() == 4) - { - MObject x = fnCompound.child(0); - MObject y = fnCompound.child(1); - MObject z = fnCompound.child(2); - MObject w = fnCompound.child(3); - if(x.apiType() == MFn::kNumericAttribute && - y.apiType() == MFn::kNumericAttribute && - z.apiType() == MFn::kNumericAttribute && - w.apiType() == MFn::kNumericAttribute) - { - MFnNumericAttribute fnx(x); - MFnNumericAttribute fny(y); - MFnNumericAttribute fnz(z); - MFnNumericAttribute fnw(w); - MFnNumericData::Type typex = fnx.unitType(); - MFnNumericData::Type typey = fny.unitType(); - MFnNumericData::Type typez = fnz.unitType(); - MFnNumericData::Type typew = fnw.unitType(); - if(typex == typey && typex == typez && typex == typew) - { - switch(typex) - { - case MFnNumericData::kInt: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Int4); - GfVec4i value; - getVec4(node, attribute, (int32_t*)&value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Int4Array); - VtArray value; - value.resize(plug.numElements()); - getVec4Array(node, attribute, (int32_t*)value.data(), value.size()); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - } - break; - - case MFnNumericData::kFloat: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Float4); - GfVec4f value; - getVec4(node, attribute, (float*)&value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Float4Array); - VtArray value; - value.resize(plug.numElements()); - getVec4Array(node, attribute, (float*)value.data(), value.size()); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - } - break; - - case MFnNumericData::kDouble: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Double4); - GfVec4d value; - getVec4(node, attribute, (double*)&value); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Double4Array); - VtArray value; - value.resize(plug.numElements()); - getVec4Array(node, attribute, (double*)value.data(), value.size()); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - } - break; - - default: break; - } - } - } - } - } - } - break; - - case MFn::kFloatMatrixAttribute: - case MFn::kMatrixAttribute: - { - if(!isArray) - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Matrix4d); - GfMatrix4d m; - getMatrix4x4(node, attribute, (double*)&m); - usdAttr.Set(m); - usdAttr.SetCustom(true); - } - else - { - UsdAttribute usdAttr = prim.CreateAttribute(attributeName, SdfValueTypeNames->Matrix4dArray); - VtArray value; - value.resize(plug.numElements()); - getMatrix4x4Array(node, attribute, (double*)value.data(), value.size()); - usdAttr.Set(value); - usdAttr.SetCustom(true); - } - } - break; - - default: break; - } - } - } - return MS::kSuccess; -} - -//---------------------------------------------------------------------------------------------------------------------- -void DgNodeTranslator::copySimpleValue(const MPlug& plug, UsdAttribute& usdAttr, const UsdTimeCode& timeCode) -{ - MObject node = plug.node(); - MObject attribute = plug.attribute(); - bool isArray = plug.isArray(); - switch(getAttributeType(usdAttr)) - { - case UsdDataType::kUChar: - if(!isArray) - { - int8_t value; - getInt8(node, attribute, value); - usdAttr.Set(uint8_t(value), timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getInt8Array(node, attribute, (int8_t*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kInt: - if(!isArray) - { - int32_t value; - getInt32(node, attribute, value); - usdAttr.Set(value, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getInt32Array(node, attribute, (int32_t*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kUInt: - if(!isArray) - { - int32_t value; - getInt32(node, attribute, value); - usdAttr.Set(uint32_t(value), timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getInt32Array(node, attribute, (int32_t*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kInt64: - if(!isArray) - { - int64_t value; - getInt64(node, attribute, value); - usdAttr.Set(value, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getInt64Array(node, attribute, (int64_t*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kUInt64: - if(!isArray) - { - int64_t value; - getInt64(node, attribute, value); - usdAttr.Set(value, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getInt64Array(node, attribute, (int64_t*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kFloat: - if(!isArray) - { - float value; - getFloat(node, attribute, value); - usdAttr.Set(value, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getFloatArray(node, attribute, (float*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kDouble: - if(!isArray) - { - double value; - getDouble(node, attribute, value); - usdAttr.Set(value, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getDoubleArray(node, attribute, (double*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kHalf: - if(!isArray) - { - GfHalf value; - getHalf(node, attribute, value); - usdAttr.Set(value, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getHalfArray(node, attribute, (GfHalf*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - default: - break; - } -} - -//---------------------------------------------------------------------------------------------------------------------- -void DgNodeTranslator::copyAttributeValue(const MPlug& plug, UsdAttribute& usdAttr, const UsdTimeCode& timeCode) -{ - MObject node = plug.node(); - MObject attribute = plug.attribute(); - bool isArray = plug.isArray(); - switch(attribute.apiType()) - { - case MFn::kAttribute2Double: - case MFn::kAttribute2Float: - case MFn::kAttribute2Int: - case MFn::kAttribute2Short: - { - switch(getAttributeType(usdAttr)) - { - case UsdDataType::kVec2d: - if(!isArray) - { - GfVec2d m; - getVec2(node, attribute, (double*)&m); - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec2Array(node, attribute, (double*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kVec2f: - if(!isArray) - { - GfVec2f m; - getVec2(node, attribute, (float*)&m); - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec2Array(node, attribute, (float*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kVec2i: - if(!isArray) - { - GfVec2i m; - getVec2(node, attribute, (int*)&m); - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec2Array(node, attribute, (int*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kVec2h: - if(!isArray) - { - GfVec2h m; - getVec2(node, attribute, (GfHalf*)&m); - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec2Array(node, attribute, (GfHalf*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - default: - break; - } - } - break; - - case MFn::kAttribute3Double: - case MFn::kAttribute3Float: - case MFn::kAttribute3Long: - case MFn::kAttribute3Short: - { - switch(getAttributeType(usdAttr)) - { - case UsdDataType::kVec3d: - if(!isArray) - { - GfVec3d m; - getVec3(node, attribute, (double*)&m); - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec3Array(node, attribute, (double*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kVec3f: - if(!isArray) - { - GfVec3f m; - getVec3(node, attribute, (float*)&m); - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec3Array(node, attribute, (float*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kVec3i: - if(!isArray) - { - GfVec3i m; - getVec3(node, attribute, (int*)&m); - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec3Array(node, attribute, (int*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kVec3h: - if(!isArray) - { - GfVec3h m; - getVec3(node, attribute, (GfHalf*)&m); - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec3Array(node, attribute, (GfHalf*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - default: - break; - } - } - break; - - case MFn::kAttribute4Double: - { - switch(getAttributeType(usdAttr)) - { - case UsdDataType::kVec4d: - if(!isArray) - { - GfVec4d m; - getVec4(node, attribute, (double*)&m); - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec4Array(node, attribute, (double*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kVec4f: - if(!isArray) - { - GfVec4f m; - getVec4(node, attribute, (float*)&m); - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec4Array(node, attribute, (float*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kVec4i: - if(!isArray) - { - GfVec4i m; - getVec4(node, attribute, (int*)&m); - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec4Array(node, attribute, (int*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kVec4h: - if(!isArray) - { - GfVec4h m; - getVec4(node, attribute, (GfHalf*)&m); - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec4Array(node, attribute, (GfHalf*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - break; - - default: - break; - } - } - break; - - case MFn::kNumericAttribute: - { - MFnNumericAttribute fn(attribute); - switch(fn.unitType()) - { - case MFnNumericData::kBoolean: - { - if(!isArray) - { - bool value; - getBool(node, attribute, value); - usdAttr.Set(value, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getUsdBoolArray(node, attribute, m); - usdAttr.Set(m, timeCode); - } - } - break; - - case MFnNumericData::kFloat: - case MFnNumericData::kDouble: - case MFnNumericData::kInt: - case MFnNumericData::kShort: - case MFnNumericData::kInt64: - case MFnNumericData::kByte: - case MFnNumericData::kChar: - { - copySimpleValue(plug, usdAttr, timeCode); - } - break; - - default: - { - } - break; - } - } - break; - - case MFn::kTimeAttribute: - case MFn::kFloatAngleAttribute: - case MFn::kDoubleAngleAttribute: - case MFn::kDoubleLinearAttribute: - case MFn::kFloatLinearAttribute: - { - copySimpleValue(plug, usdAttr, timeCode); - } - break; - - case MFn::kEnumAttribute: - { - if(!isArray) - { - int32_t value; - getInt32(node, attribute, value); - usdAttr.Set(value, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getInt32Array(node, attribute, (int32_t*)m.data(), m.size()); - usdAttr.Set(m, timeCode); - } - } - break; - - case MFn::kTypedAttribute: - { - MFnTypedAttribute fnTyped(plug.attribute()); - MFnData::Type type = fnTyped.attrType(); - - switch(type) - { - case MFnData::kString: - { - // don't animate strings - } - break; - - case MFnData::kMatrixArray: - { - MFnMatrixArrayData fnData(plug.asMObject()); - VtArray m; - m.assign((const GfMatrix4d*)&fnData.array()[0], ((const GfMatrix4d*)&fnData.array()[0]) + fnData.array().length()); - usdAttr.Set(m, timeCode); - } - break; - - default: - { - } - break; - } - } - break; - - case MFn::kCompoundAttribute: - { - MFnCompoundAttribute fnCompound(plug.attribute()); - { - if(fnCompound.numChildren() == 2) - { - MObject x = fnCompound.child(0); - MObject y = fnCompound.child(1); - if(x.apiType() == MFn::kCompoundAttribute && - y.apiType() == MFn::kCompoundAttribute) - { - MFnCompoundAttribute fnCompoundX(x); - MFnCompoundAttribute fnCompoundY(y); - - if(fnCompoundX.numChildren() == 2 && fnCompoundY.numChildren() == 2) - { - MObject xx = fnCompoundX.child(0); - MObject xy = fnCompoundX.child(1); - MObject yx = fnCompoundY.child(0); - MObject yy = fnCompoundY.child(1); - if(xx.apiType() == MFn::kNumericAttribute && - xy.apiType() == MFn::kNumericAttribute && - yx.apiType() == MFn::kNumericAttribute && - yy.apiType() == MFn::kNumericAttribute) - { - if(!isArray) - { - GfMatrix2d value; - getMatrix2x2(node, attribute, (double*)&value); - usdAttr.Set(value, timeCode); - } - else - { - VtArray value; - value.resize(plug.numElements()); - getMatrix2x2Array(node, attribute, (double*)value.data(), plug.numElements()); - usdAttr.Set(value, timeCode); - } - } - } - } - } - else - if(fnCompound.numChildren() == 3) - { - MObject x = fnCompound.child(0); - MObject y = fnCompound.child(1); - MObject z = fnCompound.child(2); - if(x.apiType() == MFn::kCompoundAttribute && - y.apiType() == MFn::kCompoundAttribute && - z.apiType() == MFn::kCompoundAttribute) - { - MFnCompoundAttribute fnCompoundX(x); - MFnCompoundAttribute fnCompoundY(y); - MFnCompoundAttribute fnCompoundZ(z); - - if(fnCompoundX.numChildren() == 3 && fnCompoundY.numChildren() == 3 && fnCompoundZ.numChildren() == 3) - { - MObject xx = fnCompoundX.child(0); - MObject xy = fnCompoundX.child(1); - MObject xz = fnCompoundX.child(2); - MObject yx = fnCompoundY.child(0); - MObject yy = fnCompoundY.child(1); - MObject yz = fnCompoundY.child(2); - MObject zx = fnCompoundZ.child(0); - MObject zy = fnCompoundZ.child(1); - MObject zz = fnCompoundZ.child(2); - if(xx.apiType() == MFn::kNumericAttribute && - xy.apiType() == MFn::kNumericAttribute && - xz.apiType() == MFn::kNumericAttribute && - yx.apiType() == MFn::kNumericAttribute && - yy.apiType() == MFn::kNumericAttribute && - yz.apiType() == MFn::kNumericAttribute && - zx.apiType() == MFn::kNumericAttribute && - zy.apiType() == MFn::kNumericAttribute && - zz.apiType() == MFn::kNumericAttribute) - { - if(!isArray) - { - GfMatrix3d value; - getMatrix3x3(node, attribute, (double*)&value); - usdAttr.Set(value, timeCode); - } - else - { - VtArray value; - value.resize(plug.numElements()); - getMatrix3x3Array(node, attribute, (double*)value.data(), plug.numElements()); - usdAttr.Set(value, timeCode); - } - } - } - } - } - else - if(fnCompound.numChildren() == 4) - { - MObject x = fnCompound.child(0); - MObject y = fnCompound.child(1); - MObject z = fnCompound.child(2); - MObject w = fnCompound.child(3); - if(x.apiType() == MFn::kNumericAttribute && - y.apiType() == MFn::kNumericAttribute && - z.apiType() == MFn::kNumericAttribute && - w.apiType() == MFn::kNumericAttribute) - { - MFnNumericAttribute fnx(x); - MFnNumericAttribute fny(y); - MFnNumericAttribute fnz(z); - MFnNumericAttribute fnw(w); - MFnNumericData::Type typex = fnx.unitType(); - MFnNumericData::Type typey = fny.unitType(); - MFnNumericData::Type typez = fnz.unitType(); - MFnNumericData::Type typew = fnw.unitType(); - if(typex == typey && typex == typez && typex == typew) - { - switch(typex) - { - case MFnNumericData::kInt: - { - if(!isArray) - { - GfVec4i value; - getVec4(node, attribute, (int32_t*)&value); - usdAttr.Set(value, timeCode); - } - else - { - VtArray value; - value.resize(plug.numElements()); - getVec4Array(node, attribute, (int32_t*)value.data(), value.size()); - usdAttr.Set(value, timeCode); - } - } - break; - - case MFnNumericData::kFloat: - { - if(!isArray) - { - GfVec4f value; - getVec4(node, attribute, (float*)&value); - usdAttr.Set(value, timeCode); - } - else - { - VtArray value; - value.resize(plug.numElements()); - getVec4Array(node, attribute, (float*)value.data(), value.size()); - usdAttr.Set(value, timeCode); - } - } - break; - - case MFnNumericData::kDouble: - { - if(!isArray) - { - GfVec4d value; - getVec4(node, attribute, (double*)&value); - usdAttr.Set(value, timeCode); - } - else - { - VtArray value; - value.resize(plug.numElements()); - getVec4Array(node, attribute, (double*)value.data(), value.size()); - usdAttr.Set(value, timeCode); - } - } - break; - - default: break; - } - } - } - } - } - } - break; - - case MFn::kFloatMatrixAttribute: - case MFn::kMatrixAttribute: - { - if(!isArray) - { - GfMatrix4d m; - getMatrix4x4(node, attribute, (double*)&m); - usdAttr.Set(m, timeCode); - } - else - { - VtArray value; - value.resize(plug.numElements()); - getMatrix4x4Array(node, attribute, (double*)value.data(), value.size()); - usdAttr.Set(value, timeCode); - } - } - break; - - default: break; - } -} - -//---------------------------------------------------------------------------------------------------------------------- -void DgNodeTranslator::copySimpleValue(const MPlug& plug, UsdAttribute& usdAttr, const float scale, const UsdTimeCode& timeCode) -{ - MObject node = plug.node(); - MObject attribute = plug.attribute(); - bool isArray = plug.isArray(); - switch(getAttributeType(usdAttr)) - { - case UsdDataType::kFloat: - if(!isArray) - { - float value; - getFloat(node, attribute, value); - usdAttr.Set(value * scale, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getFloatArray(node, attribute, (float*)m.data(), m.size()); - for(auto it = m.begin(), e = m.end(); it != e; ++it) - { - *it *= scale; - } - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kDouble: - if(!isArray) - { - double value; - getDouble(node, attribute, value); - usdAttr.Set(value * scale, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getDoubleArray(node, attribute, (double*)m.data(), m.size()); - double temp = scale; - for(auto it = m.begin(), e = m.end(); it != e; ++it) - { - *it *= temp; - } - usdAttr.Set(m, timeCode); - } - break; - - default: - break; - } -} - -//---------------------------------------------------------------------------------------------------------------------- -void DgNodeTranslator::copyAttributeValue(const MPlug& plug, UsdAttribute& usdAttr, const float scale, const UsdTimeCode& timeCode) -{ - MObject node = plug.node(); - MObject attribute = plug.attribute(); - bool isArray = plug.isArray(); - switch(attribute.apiType()) - { - case MFn::kAttribute2Double: - case MFn::kAttribute2Float: - case MFn::kAttribute2Int: - case MFn::kAttribute2Short: - { - switch(getAttributeType(usdAttr)) - { - case UsdDataType::kVec2d: - if(!isArray) - { - GfVec2d m; - getVec2(node, attribute, (double*)&m); - m *= scale; - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec2Array(node, attribute, (double*)m.data(), m.size()); - double temp = scale; - for(auto it = m.begin(), e = m.end(); it != e; ++it) - { - *it *= temp; - } - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kVec2f: - if(!isArray) - { - GfVec2f m; - getVec2(node, attribute, (float*)&m); - m *= scale; - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec2Array(node, attribute, (float*)m.data(), m.size()); - for(auto it = m.begin(), e = m.end(); it != e; ++it) - { - *it *= scale; - } - usdAttr.Set(m, timeCode); - } - break; - - default: - break; - } - } - break; - - case MFn::kAttribute3Double: - case MFn::kAttribute3Float: - case MFn::kAttribute3Long: - case MFn::kAttribute3Short: - { - switch(getAttributeType(usdAttr)) - { - case UsdDataType::kVec3d: - if(!isArray) - { - GfVec3d m; - getVec3(node, attribute, (double*)&m); - m *= scale; - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec3Array(node, attribute, (double*)m.data(), m.size()); - double temp = scale; - for(auto it = m.begin(), e = m.end(); it != e; ++it) - { - *it *= temp; - } - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kVec3f: - if(!isArray) - { - GfVec3f m; - getVec3(node, attribute, (float*)&m); - m *= scale; - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec3Array(node, attribute, (float*)m.data(), m.size()); - for(auto it = m.begin(), e = m.end(); it != e; ++it) - { - *it *= scale; - } - usdAttr.Set(m, timeCode); - } - break; - - default: - break; - } - } - break; - - case MFn::kAttribute4Double: - { - switch(getAttributeType(usdAttr)) - { - case UsdDataType::kVec4d: - if(!isArray) - { - GfVec4d m; - getVec4(node, attribute, (double*)&m); - m *= scale; - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec4Array(node, attribute, (double*)m.data(), m.size()); - double temp = scale; - for(auto it = m.begin(), e = m.end(); it != e; ++it) - { - *it *= temp; - } - usdAttr.Set(m, timeCode); - } - break; - - case UsdDataType::kVec4f: - if(!isArray) - { - GfVec4f m; - getVec4(node, attribute, (float*)&m); - m *= scale; - usdAttr.Set(m, timeCode); - } - else - { - VtArray m; - m.resize(plug.numElements()); - getVec4Array(node, attribute, (float*)m.data(), m.size()); - for(auto it = m.begin(), e = m.end(); it != e; ++it) - { - *it *= scale; - } - usdAttr.Set(m, timeCode); - } - break; - - default: - break; - } - } - break; - - case MFn::kNumericAttribute: - { - MFnNumericAttribute fn(attribute); - switch(fn.unitType()) - { - case MFnNumericData::kFloat: - case MFnNumericData::kDouble: - case MFnNumericData::kInt: - case MFnNumericData::kShort: - case MFnNumericData::kInt64: - case MFnNumericData::kByte: - case MFnNumericData::kChar: - { - copySimpleValue(plug, usdAttr, scale, timeCode); - } - break; - - default: - { - } - break; - } - } - break; - - case MFn::kTimeAttribute: - case MFn::kFloatAngleAttribute: - case MFn::kDoubleAngleAttribute: - case MFn::kDoubleLinearAttribute: - case MFn::kFloatLinearAttribute: - { - copySimpleValue(plug, usdAttr, scale, timeCode); - } - break; - - default: break; - } -} - //---------------------------------------------------------------------------------------------------------------------- } // translators } // fileio diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/DgNodeTranslator.h b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/DgNodeTranslator.h index bca095ab..48c75d21 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/DgNodeTranslator.h +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/DgNodeTranslator.h @@ -18,7 +18,7 @@ #include "../../Api.h" #include -#include "AL/usdmaya/AttributeType.h" +#include "AL/usdmaya/utils/AttributeType.h" #include "AL/usdmaya/utils/DgNodeHelper.h" #include "AL/usdmaya/utils/ForwardDeclares.h" #include "AL/maya/utils/MayaHelperMacros.h" @@ -27,14 +27,12 @@ #include "maya/MAngle.h" #include "maya/MDistance.h" #include "maya/MTime.h" -#include "maya/MFnAnimCurve.h" #include "maya/MGlobal.h" #include "maya/MStatus.h" #include "pxr/base/gf/half.h" #include "pxr/usd/usd/attribute.h" -#include "pxr/usd/usdGeom/xformOp.h" #include #include @@ -90,479 +88,8 @@ class DgNodeTranslator /// \return true if your translator is handling this attr AL_USDMAYA_PUBLIC virtual bool attributeHandled(const UsdAttribute& usdAttr); - - //-------------------------------------------------------------------------------------------------------------------- - /// \name animation - //-------------------------------------------------------------------------------------------------------------------- - - /// \brief creates animation curves in maya for the specified attribute - /// \param node the node instance the animated attribute belongs to - /// \param attr the attribute handle - /// \param op the USD geometry operation that contains the animation data - /// \param conversionFactor a scaling factor to apply to the source key frames on import. - /// \return MS::kSuccess on success, error code otherwise - template - static MStatus setVec3Anim(MObject node, MObject attr, const UsdGeomXformOp op, double conversionFactor = 1.0); - - /// \brief creates animation curves to animate the specified angle attribute - /// \param node the node instance the animated attribute belongs to - /// \param attr the attribute handle - /// \param op the USD transform op that contains the keyframe data - /// \return MS::kSuccess on success, error code otherwise - AL_USDMAYA_PUBLIC - static MStatus setAngleAnim(MObject node, MObject attr, const UsdGeomXformOp op); - - /// \brief creates animation curves in maya for the specified attribute - /// \param node the node instance the animated attribute belongs to - /// \param attr the attribute handle - /// \param usdAttr the USD attribute that contains the keyframe data - /// \param conversionFactor a scaling to apply to the key frames on import - /// \return MS::kSuccess on success, error code otherwise - AL_USDMAYA_PUBLIC - static MStatus setFloatAttrAnim(MObject node, MObject attr, UsdAttribute usdAttr, double conversionFactor = 1.0); - - /// \brief creates animation curves in maya for the visibility attribute - /// \param node the node instance the animated attribute belongs to - /// \param attr the visibility attribute handle - /// \param usdAttr the USD attribute that contains the keyframe data - /// \return MS::kSuccess on success, error code otherwise - AL_USDMAYA_PUBLIC - static MStatus setVisAttrAnim(const MObject node, const MObject attr, const UsdAttribute & usdAttr); - - //-------------------------------------------------------------------------------------------------------------------- - /// \name Get array values from Maya - //-------------------------------------------------------------------------------------------------------------------- - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus getUsdBoolArray(const MObject& node, const MObject& attr, VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus getUsdInt8Array(const MObject& node, const MObject& attr, VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus getUsdInt16Array(const MObject& node, const MObject& attr, VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus getUsdInt32Array(const MObject& node, const MObject& attr, VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus getUsdInt64Array(const MObject& node, const MObject& attr, VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus getUsdHalfArray(const MObject& node, const MObject& attr, VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus getUsdFloatArray(const MObject& node, const MObject& attr, VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus getUsdDoubleArray(const MObject& node, const MObject& attr, VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus setUsdBoolArray(const MObject& node, const MObject& attr, const VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus setUsdInt8Array(const MObject& node, const MObject& attr, const VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus setUsdInt16Array(const MObject& node, const MObject& attr, const VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus setUsdInt32Array(const MObject& node, const MObject& attr, const VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus setUsdInt64Array(const MObject& node, const MObject& attr, const VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus setUsdHalfArray(const MObject& node, const MObject& attr, const VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus setUsdFloatArray(const MObject& node, const MObject& attr, const VtArray& values); - - /// \name get data from maya attribute, and store in the USD values array - /// \param node the node to get the attribute data from - /// \param attr the attribute to get the data from - /// \param values the returned array data - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus setUsdDoubleArray(const MObject& node, const MObject& attr, const VtArray& values); - - //-------------------------------------------------------------------------------------------------------------------- - /// \name Copy single values from USD to Maya - //-------------------------------------------------------------------------------------------------------------------- - - /// \brief copy a boolean value from USD and apply to Maya attribute - /// \param node the node to copy the attribute data to - /// \param attr the attribute to copy the data to - /// \param value the USD attribute to copy the data from - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus copyBool(MObject node, MObject attr, const UsdAttribute& value); - - /// \brief copy a boolean value from USD and apply to Maya attribute - /// \param node the node to copy the attribute data to - /// \param attr the attribute to copy the data to - /// \param value the USD attribute to copy the data from - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus copyFloat(MObject node, MObject attr, const UsdAttribute& value); - - /// \brief copy a boolean value from USD and apply to Maya attribute - /// \param node the node to copy the attribute data to - /// \param attr the attribute to copy the data to - /// \param value the USD attribute to copy the data from - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus copyDouble(MObject node, MObject attr, const UsdAttribute& value); - - /// \brief copy a boolean value from USD and apply to Maya attribute - /// \param node the node to copy the attribute data to - /// \param attr the attribute to copy the data to - /// \param value the USD attribute to copy the data from - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus copyInt(MObject node, MObject attr, const UsdAttribute& value); - - /// \brief copy a boolean value from USD and apply to Maya attribute - /// \param node the node to copy the attribute data to - /// \param attr the attribute to copy the data to - /// \param value the USD attribute to copy the data from - /// \return MS::kSuccess if succeeded - AL_USDMAYA_PUBLIC - static MStatus copyVec3(MObject node, MObject attr, const UsdAttribute& value); - - //-------------------------------------------------------------------------------------------------------------------- - /// \name Internal import/export utils - //-------------------------------------------------------------------------------------------------------------------- - - /// \brief copy a non array value from a usd attribute into the maya attribute specified - /// \param node the node to copy the attribute data to - /// \param attr the attribute to copy the data to - /// \param usdAttr the attribute to copy the from - /// \param type the attribute type - /// \return MS::kSuccess if succeeded, error code otherwise - AL_USDMAYA_PUBLIC - static MStatus setSingleMayaValue(MObject node, MObject attr, const UsdAttribute& usdAttr, const UsdDataType type); - - /// \brief copy an array value from a usd attribute into the maya attribute specified - /// \param node the node to copy the attribute data to - /// \param attr the attribute to copy the data to - /// \param usdAttr the attribute to copy the from - /// \param type the attribute type of the array elements - /// \return MS::kSuccess if succeeded, error code otherwise - AL_USDMAYA_PUBLIC - static MStatus setArrayMayaValue(MObject node, MObject attr, const UsdAttribute& usdAttr, const UsdDataType type); - - /// \brief copy the value from the usdAttribute onto the maya attribute value - /// \param node the node to copy the attribute data to - /// \param attr the attribute to copy the data to - /// \param usdAttr the attribute to copy the from - /// \return MS::kSuccess if succeeded, error code otherwise - AL_USDMAYA_PUBLIC - static MStatus setMayaValue(MObject node, MObject attr, const UsdAttribute& usdAttr); - - /// \brief creates a new dynamic attribute on the Maya node specified which will be initialized from the usdAttr. - /// \param node the node to copy the attribute data to - /// \param usdAttr the attribute to copy the from - /// \return MS::kSuccess if succeeded, error code otherwise - AL_USDMAYA_PUBLIC - static MStatus addDynamicAttribute(MObject node, const UsdAttribute& usdAttr); - - /// \brief copy all custom attributes from the usd primitive onto the maya node. - /// \param node the node to copy the attributes to - /// \param prim the USD prim to copy the attributes from - /// \return MS::kSuccess if succeeded, error code otherwise - AL_USDMAYA_PUBLIC - static MStatus copyDynamicAttributes(MObject node, UsdPrim& prim); - - /// \brief copy the attribute value from the plug specified, at the given time, and store the data on the usdAttr. - /// \param attr the attribute to be copied - /// \param usdAttr the attribute to copy the data to - /// \param timeCode the timecode to use when setting the data - AL_USDMAYA_PUBLIC - static void copyAttributeValue(const MPlug& attr, UsdAttribute& usdAttr, const UsdTimeCode& timeCode); - - /// \brief copy the attribute value from the plug specified, at the given time, and store the data on the usdAttr. - /// \param plug the attribute to be copied - /// \param usdAttr the attribute to copy the data to - /// \param timeCode the timecode to use when setting the data - AL_USDMAYA_PUBLIC - static void copySimpleValue(const MPlug& plug, UsdAttribute& usdAttr, const UsdTimeCode& timeCode); - - /// \brief copy the attribute value from the plug specified, at the given time, and store the data on the usdAttr. - /// \param attr the attribute to be copied - /// \param usdAttr the attribute to copy the data to - /// \param scale a scaling factor to apply to provide support for - /// \param timeCode the timecode to use when setting the data - AL_USDMAYA_PUBLIC - static void copyAttributeValue(const MPlug& attr, UsdAttribute& usdAttr, float scale, const UsdTimeCode& timeCode); - - /// \brief copy the attribute value from the plug specified, at the given time, and store the data on the usdAttr. - /// \param plug the attribute to be copied - /// \param usdAttr the attribute to copy the data to - /// \param scale a scaling factor to apply to provide support for - /// \param timeCode the timecode to use when setting the data - AL_USDMAYA_PUBLIC - static void copySimpleValue(const MPlug& plug, UsdAttribute& usdAttr, float scale, const UsdTimeCode& timeCode); - - /// \brief convert value from the plug specified and set it to usd attribute. - /// \param plug the plug to copy the attributes value from - /// \param usdAttr the USDAttribute to set the attribute value to - /// \return MS::kSuccess if the conversion success based on certain rules. - AL_USDMAYA_PUBLIC - static MStatus convertSpecialValueToUSDAttribute(const MPlug& plug, UsdAttribute& usdAttr); }; -//---------------------------------------------------------------------------------------------------------------------- -template -MStatus DgNodeTranslator::setVec3Anim(MObject node, MObject attr, const UsdGeomXformOp op, double conversionFactor) -{ - MPlug plug(node, attr); - MStatus status; - const char* const xformErrorCreate = "DgNodeTranslator:setVec3Anim error creating animation curve"; - - MFnAnimCurve acFnSetX; - acFnSetX.create(plug.child(0), NULL, &status); - AL_MAYA_CHECK_ERROR(status, xformErrorCreate); - - MFnAnimCurve acFnSetY; - acFnSetY.create(plug.child(1), NULL, &status); - AL_MAYA_CHECK_ERROR(status, xformErrorCreate); - - MFnAnimCurve acFnSetZ; - acFnSetZ.create(plug.child(2), NULL, &status); - AL_MAYA_CHECK_ERROR(status, xformErrorCreate); - - std::vector times; - op.GetTimeSamples(×); - - const char* const xformErrorKey = "DgNodeTranslator:setVec3Anim error setting key on animation curve"; - - T value(0); - for(auto const& timeValue: times) - { - const bool retValue = op.GetAs(&value, timeValue); - if (!retValue) continue; - - MTime tm(timeValue, MTime::kFilm); - - switch (acFnSetX.animCurveType()) - { - case MFnAnimCurve::kAnimCurveTL: // time->distance: translation - case MFnAnimCurve::kAnimCurveTA: // time->angle: rotation - case MFnAnimCurve::kAnimCurveTU: // time->double: scale - { - acFnSetX.addKey(tm, value[0] * conversionFactor, MFnAnimCurve::kTangentGlobal, MFnAnimCurve::kTangentGlobal, NULL, &status); - AL_MAYA_CHECK_ERROR(status, xformErrorKey); - acFnSetY.addKey(tm, value[1] * conversionFactor, MFnAnimCurve::kTangentGlobal, MFnAnimCurve::kTangentGlobal, NULL, &status); - AL_MAYA_CHECK_ERROR(status, xformErrorKey); - acFnSetZ.addKey(tm, value[2] * conversionFactor, MFnAnimCurve::kTangentGlobal, MFnAnimCurve::kTangentGlobal, NULL, &status); - AL_MAYA_CHECK_ERROR(status, xformErrorKey); - break; - } - default: - { - break; - } - } - } - - return MS::kSuccess; -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::getUsdInt8Array(const MObject& node, const MObject& attr, VtArray& values) -{ - MPlug plug(node, attr); - if(!plug || !plug.isArray()) - return MS::kFailure; - const uint32_t num = plug.numElements(); - values.resize(num); - return getInt8Array(node, attr, values.data(), num); -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::getUsdInt16Array(const MObject& node, const MObject& attr, VtArray& values) -{ - MPlug plug(node, attr); - if(!plug || !plug.isArray()) - return MS::kFailure; - const uint32_t num = plug.numElements(); - values.resize(num); - return getInt16Array(node, attr, values.data(), num); -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::getUsdInt32Array(const MObject& node, const MObject& attr, VtArray& values) -{ - MPlug plug(node, attr); - if(!plug || !plug.isArray()) - return MS::kFailure; - const uint32_t num = plug.numElements(); - values.resize(num); - return getInt32Array(node, attr, values.data(), num); -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::getUsdInt64Array(const MObject& node, const MObject& attr, VtArray& values) -{ - MPlug plug(node, attr); - if(!plug || !plug.isArray()) - return MS::kFailure; - const uint32_t num = plug.numElements(); - values.resize(num); - return getInt64Array(node, attr, values.data(), num); -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::getUsdHalfArray(const MObject& node, const MObject& attr, VtArray& values) -{ - MPlug plug(node, attr); - if(!plug || !plug.isArray()) - return MS::kFailure; - const uint32_t num = plug.numElements(); - values.resize(num); - return getHalfArray(node, attr, values.data(), num); -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::getUsdFloatArray(const MObject& node, const MObject& attr, VtArray& values) -{ - MPlug plug(node, attr); - if(!plug || !plug.isArray()) - return MS::kFailure; - const uint32_t num = plug.numElements(); - values.resize(num); - return getFloatArray(node, attr, values.data(), num); -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::getUsdDoubleArray(const MObject& node, const MObject& attr, VtArray& values) -{ - MPlug plug(node, attr); - if(!plug || !plug.isArray()) - return MS::kFailure; - const uint32_t num = plug.numElements(); - values.resize(num); - return getDoubleArray(node, attr, values.data(), num); -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::setUsdInt8Array(const MObject& node, const MObject& attr, const VtArray& values) -{ - return setInt8Array(node, attr, values.cdata(), values.size()); -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::setUsdInt16Array(const MObject& node, const MObject& attr, const VtArray& values) -{ - return setInt16Array(node, attr, values.cdata(), values.size()); -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::setUsdInt32Array(const MObject& node, const MObject& attr, const VtArray& values) -{ - return setInt32Array(node, attr, values.cdata(), values.size()); -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::setUsdInt64Array(const MObject& node, const MObject& attr, const VtArray& values) -{ - return setInt64Array(node, attr, values.cdata(), values.size()); -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::setUsdHalfArray(const MObject& node, const MObject& attr, const VtArray& values) -{ - return setHalfArray(node, attr, values.cdata(), values.size()); -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::setUsdFloatArray(const MObject& node, const MObject& attr, const VtArray& values) -{ - return setFloatArray(node, attr, values.cdata(), values.size()); -} - -//---------------------------------------------------------------------------------------------------------------------- -inline MStatus DgNodeTranslator::setUsdDoubleArray(const MObject& node, const MObject& attr, const VtArray& values) -{ - return setDoubleArray(node, attr, values.cdata(), values.size()); -} - //---------------------------------------------------------------------------------------------------------------------- } // translators } // fileio diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/MeshTranslator.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/MeshTranslator.cpp index a0a5d4f6..a5fd9b65 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/MeshTranslator.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/MeshTranslator.cpp @@ -14,6 +14,7 @@ // limitations under the License. // #include "AL/usd/utils/SIMD.h" +#include "AL/usdmaya/Metadata.h" #include "AL/usdmaya/utils/Utils.h" #include "AL/usdmaya/utils/MeshUtils.h" #include "AL/usdmaya/fileio/ExportParams.h" @@ -96,27 +97,49 @@ UsdPrim MeshTranslator::exportObject(UsdStageRefPtr stage, MDagPath path, const return UsdPrim(); UsdGeomMesh mesh = UsdGeomMesh::Define(stage, usdPath); - - MStatus status; - MFnMesh fnMesh(path, &status); - AL_MAYA_CHECK_ERROR2(status, MString("unable to attach function set to mesh") + path.fullPathName()); - if(status) + + AL::usdmaya::utils::MeshExportContext context(path, mesh, params.m_timeCode, false, (AL::usdmaya::utils::MeshExportContext::CompactionLevel)params.m_compactionLevel); + if(context) { UsdAttribute pointsAttr = mesh.GetPointsAttr(); if (params.m_animTranslator && AnimationTranslator::isAnimatedMesh(path)) { params.m_animTranslator->addMesh(path, pointsAttr); } - - AL::usdmaya::utils::copyVertexData(fnMesh, pointsAttr); - AL::usdmaya::utils::copyFaceConnectsAndPolyCounts(mesh, fnMesh); - AL::usdmaya::utils::copyInvisibleHoles(mesh, fnMesh); - AL::usdmaya::utils::copyUvSetData(mesh, fnMesh, params.m_leftHandedUV); - AL::usdmaya::utils::copyNormalData(fnMesh, mesh.GetNormalsAttr()); - AL::usdmaya::utils::copyGlimpseTesselationAttributes(mesh, fnMesh); - AL::usdmaya::utils::copyColourSetData(mesh, fnMesh); - AL::usdmaya::utils::copyCreaseVertices(mesh, fnMesh); - AL::usdmaya::utils::copyCreaseEdges(mesh, fnMesh); + + if(params.m_meshPoints) + { + context.copyVertexData(context.timeCode()); + } + if(params.m_meshConnects) + { + context.copyFaceConnectsAndPolyCounts(); + } + if(params.m_meshHoles) + { + context.copyInvisibleHoles(); + } + if(params.m_meshUvs) + { + context.copyUvSetData(); + } + if(params.m_meshNormals) + { + context.copyNormalData(context.timeCode()); + } + context.copyGlimpseTesselationAttributes(); + if(params.m_meshColours) + { + context.copyColourSetData(); + } + if(params.m_meshVertexCreases) + { + context.copyCreaseVertices(); + } + if(params.m_meshEdgeCreases) + { + context.copyCreaseEdges(); + } // pick up any additional attributes attached to the mesh node (these will be added alongside the transform attributes) if(params.m_dynamicAttributes) @@ -132,13 +155,11 @@ UsdPrim MeshTranslator::exportObject(UsdStageRefPtr stage, MDagPath path, const UsdPrim MeshTranslator::exportUV(UsdStageRefPtr stage, MDagPath path, const SdfPath& usdPath, const ExporterParams& params) { UsdPrim overPrim = stage->OverridePrim(usdPath); - MStatus status; - MFnMesh fnMesh(path, &status); - AL_MAYA_CHECK_ERROR2(status, MString("unable to attach function set to mesh") + path.fullPathName()); - if (status) + UsdGeomMesh mesh(overPrim); + AL::usdmaya::utils::MeshExportContext context(path, mesh, params.m_timeCode); + if (context) { - UsdGeomMesh mesh(overPrim); - AL::usdmaya::utils::copyUvSetData(mesh, fnMesh, params.m_leftHandedUV); + context.copyUvSetData(); } return overPrim; } @@ -156,52 +177,31 @@ MObject MeshTranslator::createNode(const UsdPrim& from, MObject parent, const ch return MObject::kNullObj; const UsdGeomMesh mesh(from); - - TfToken orientation; - bool leftHanded = (mesh.GetOrientationAttr().Get(&orientation) && orientation == UsdGeomTokens->leftHanded); - - MFnMesh fnMesh; - MFloatPointArray points; - MVectorArray normals; - MIntArray counts, connects; - - AL::usdmaya::utils::gatherFaceConnectsAndVertices(mesh, points, normals, counts, connects, leftHanded); - - MObject polyShape = fnMesh.create(points.length(), counts.length(), points, counts, connects, parent); - - MIntArray normalsFaceIds; - normalsFaceIds.setLength(connects.length()); - int32_t* normalsFaceIdsPtr = &normalsFaceIds[0]; - if(normals.length()) + + bool parentUnmerged = false; + TfToken val; + if(from.GetParent().GetMetadata(AL::usdmaya::Metadata::mergedTransform, &val)) { - MIntArray normalsFaceIds; - normalsFaceIds.setLength(connects.length()); - int32_t* normalsFaceIdsPtr = &normalsFaceIds[0]; - if (normals.length() == fnMesh.numFaceVertices()) - { - for (uint32_t i = 0, k = 0, n = counts.length(); i < n; i++) - { - for (uint32_t j = 0, m = counts[i]; j < m; j++, ++k) - { - normalsFaceIdsPtr[k] = i; - } - } - } - fnMesh.setFaceVertexNormals(normals, normalsFaceIds, connects); + parentUnmerged = (val == AL::usdmaya::Metadata::unmerged); } - - MFnDagNode fnDag(polyShape); - fnDag.setName(std::string(from.GetName().GetString() + std::string("Shape")).c_str()); - - AL::usdmaya::utils::applyHoleFaces(mesh, fnMesh); - AL::usdmaya::utils::applyVertexCreases(mesh, fnMesh); - AL::usdmaya::utils::applyEdgeCreases(mesh, fnMesh); - AL::usdmaya::utils::applyGlimpseSubdivParams(from, fnMesh); - AL::usdmaya::utils::applyGlimpseUserDataParams(from, fnMesh); - applyDefaultMaterialOnShape(polyShape); - AL::usdmaya::utils::applyPrimVars(mesh, fnMesh, counts, connects); - - return polyShape; + MString dagName = from.GetName().GetString().c_str(); + if(!parentUnmerged) + { + dagName += "Shape"; + } + + UsdTimeCode timeCode = params.m_forceDefaultRead ? UsdTimeCode::Default() : UsdTimeCode::EarliestTime(); + + AL::usdmaya::utils::MeshImportContext context(mesh, parent, dagName, timeCode); + context.applyVertexNormals(); + context.applyHoleFaces(); + context.applyVertexCreases(); + context.applyEdgeCreases(); + context.applyGlimpseSubdivParams(); + context.applyGlimpseUserDataParams(); + applyDefaultMaterialOnShape(context.getPolyShape()); + context.applyPrimVars(); + return context.getPolyShape(); } //---------------------------------------------------------------------------------------------------------------------- diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/NurbsCurveTranslator.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/NurbsCurveTranslator.cpp index 14e63831..c8253e90 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/NurbsCurveTranslator.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/NurbsCurveTranslator.cpp @@ -61,7 +61,7 @@ MObject NurbsCurveTranslator::createNode(const UsdPrim& from, MObject parent, co parentUnmerged = (mtVal == AL::usdmaya::Metadata::unmerged); } - if (!AL::usdmaya::utils::createMayaCurves(fnCurve, parent, usdCurves, params.m_useAnimalSchema, parentUnmerged)) + if (!AL::usdmaya::utils::createMayaCurves(fnCurve, parent, usdCurves, parentUnmerged)) { return MObject::kNullObj; } @@ -83,11 +83,11 @@ UsdPrim NurbsCurveTranslator::exportObject(UsdStageRefPtr stage, MDagPath path, UsdGeomNurbsCurves nurbs = UsdGeomNurbsCurves::Define(stage, usdPath); MFnNurbsCurve fnCurve(path); - AL::usdmaya::utils::copyPoints(fnCurve, nurbs.GetPointsAttr()); - AL::usdmaya::utils::copyCurveVertexCounts(fnCurve, nurbs.GetCurveVertexCountsAttr()); - AL::usdmaya::utils::copyKnots(fnCurve, nurbs.GetKnotsAttr()); - AL::usdmaya::utils::copyRanges(fnCurve, nurbs.GetRangesAttr()); - AL::usdmaya::utils::copyOrder(fnCurve, nurbs.GetOrderAttr()); + AL::usdmaya::utils::copyPoints(fnCurve, nurbs.GetPointsAttr(), params.m_timeCode); + AL::usdmaya::utils::copyCurveVertexCounts(fnCurve, nurbs.GetCurveVertexCountsAttr(), params.m_timeCode); + AL::usdmaya::utils::copyKnots(fnCurve, nurbs.GetKnotsAttr(), params.m_timeCode); + AL::usdmaya::utils::copyRanges(fnCurve, nurbs.GetRangesAttr(), params.m_timeCode); + AL::usdmaya::utils::copyOrder(fnCurve, nurbs.GetOrderAttr(), params.m_timeCode); MObject widthObj; MPlug widthPlug; diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TransformTranslator.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TransformTranslator.cpp index 0774c585..ca920153 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TransformTranslator.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TransformTranslator.cpp @@ -14,8 +14,8 @@ // limitations under the License. // #include "AL/usdmaya/fileio/translators/TransformTranslator.h" -#include "AL/usdmaya/AttributeType.h" #include "AL/usdmaya/fileio/ExportParams.h" +#include "AL/usdmaya/fileio/ImportParams.h" #include "AL/usdmaya/fileio/AnimationTranslator.h" #include "AL/usdmaya/nodes/Transform.h" @@ -38,12 +38,16 @@ #include "pxr/usd/usd/attribute.h" #include "pxr/usd/usdGeom/xform.h" #include "pxr/usd/usdGeom/xformCommonAPI.h" +#include "AL/usdmaya/utils/AttributeType.h" +#include "AL/usdmaya/utils/DgNodeHelper.h" #include "AL/usdmaya/utils/Utils.h" namespace AL { namespace usdmaya { namespace fileio { namespace translators { + + //---------------------------------------------------------------------------------------------------------------------- MObject TransformTranslator::m_inheritsTransform = MObject::kNullObj; MObject TransformTranslator::m_scale = MObject::kNullObj; @@ -239,7 +243,8 @@ bool TransformTranslator::getAnimationVariables(TransformOperation opIt, MObject //---------------------------------------------------------------------------------------------------------------------- MStatus TransformTranslator::copyAttributes(const UsdPrim& from, MObject to, const ImporterParams& params) { - static const UsdTimeCode usdTime = UsdTimeCode::EarliestTime(); + static const UsdTimeCode usdTime = params.m_forceDefaultRead ? + UsdTimeCode::Default() : UsdTimeCode::EarliestTime(); const char* const xformError = "ALUSDImport: error creating transform node"; AL_MAYA_CHECK_ERROR2(DagNodeTranslator::copyAttributes(from, to, params), xformError); @@ -256,12 +261,12 @@ MStatus TransformTranslator::copyAttributes(const UsdPrim& from, MObject to, con const UsdGeomXformOp& op = *it; const SdfValueTypeName vtn = op.GetTypeName(); - UsdDataType attr_type = getAttributeType(vtn); + utils::UsdDataType attr_type = AL::usdmaya::utils::getAttributeType(vtn); // Import animation (if we have time samples) if (op.GetNumTimeSamples()) { - if(attr_type == UsdDataType::kVec3f || attr_type == UsdDataType::kVec3d) + if(attr_type == utils::UsdDataType::kVec3f || attr_type == utils::UsdDataType::kVec3d) { MObject obj; double conversionFactor = 1.0; @@ -278,7 +283,7 @@ MStatus TransformTranslator::copyAttributes(const UsdPrim& from, MObject to, con AL_MAYA_CHECK_ERROR2(setInt32(to, m_rotateOrder, uint32_t(convertRotationOrder(op.GetOpType()))), xformError); } - if (attr_type == UsdDataType::kVec3f) + if (attr_type == utils::UsdDataType::kVec3f) { AL_MAYA_CHECK_ERROR2(setVec3Anim(to, obj, op, conversionFactor), xformError); } @@ -287,7 +292,7 @@ MStatus TransformTranslator::copyAttributes(const UsdPrim& from, MObject to, con AL_MAYA_CHECK_ERROR2(setVec3Anim(to, obj, op, conversionFactor), xformError); } } - else if(attr_type == UsdDataType::kFloat) + else if(attr_type == utils::UsdDataType::kFloat) { MObject attr; @@ -323,7 +328,7 @@ MStatus TransformTranslator::copyAttributes(const UsdPrim& from, MObject to, con setAngleAnim(to, attr, op); } } - else if(attr_type == UsdDataType::kMatrix4d) + else if(attr_type == utils::UsdDataType::kMatrix4d) { if(*opIt == kShear) { @@ -338,7 +343,7 @@ MStatus TransformTranslator::copyAttributes(const UsdPrim& from, MObject to, con // Else if static const float degToRad = 3.141592654f / 180.0f; - if(attr_type == UsdDataType::kVec3f) + if(attr_type == utils::UsdDataType::kVec3f) { GfVec3f value(0); @@ -374,7 +379,7 @@ MStatus TransformTranslator::copyAttributes(const UsdPrim& from, MObject to, con } } else - if(attr_type == UsdDataType::kVec3d) + if(attr_type == utils::UsdDataType::kVec3d) { GfVec3d value(0); @@ -409,7 +414,7 @@ MStatus TransformTranslator::copyAttributes(const UsdPrim& from, MObject to, con } } else - if(attr_type == UsdDataType::kFloat) + if(attr_type == utils::UsdDataType::kFloat) { float value = 0; @@ -470,7 +475,7 @@ MStatus TransformTranslator::copyAttributes(const UsdPrim& from, MObject to, con } } else - if(attr_type == UsdDataType::kMatrix4d) + if(attr_type == utils::UsdDataType::kMatrix4d) { if(*opIt == kShear) { @@ -497,8 +502,8 @@ MStatus TransformTranslator::copyAttributes(const UsdPrim& from, MObject to, con { const UsdGeomXformOp& op = *it; const SdfValueTypeName vtn = op.GetTypeName(); - UsdDataType attr_type = getAttributeType(vtn); - if(attr_type == UsdDataType::kMatrix4d) + utils::UsdDataType attr_type = AL::usdmaya::utils::getAttributeType(vtn); + if(attr_type == utils::UsdDataType::kMatrix4d) { switch(op.GetOpType()) { @@ -535,7 +540,7 @@ MStatus TransformTranslator::copyAttributes(const UsdPrim& from, MObject to, con processMetaData(from, to, params); if (UsdAttribute myAttr = from.GetAttribute(UsdGeomTokens->visibility)) { - setVisAttrAnim(to, m_visibility, myAttr); + DgNodeHelper::setVisAttrAnim(to, m_visibility, myAttr); } return MS::kSuccess; @@ -564,18 +569,24 @@ bool animationCheck(AnimationTranslator* animTranslator, MPlug plug) } //---------------------------------------------------------------------------------------------------------------------- -UsdAttribute addTranslateOp(const UsdGeomXform &xformSchema, const char *attrName, const GfVec3f ¤tValue) +UsdAttribute addTranslateOp( + const UsdGeomXform& xformSchema, + const char* attrName, + const GfVec3f& currentValue, + const UsdTimeCode& time) { UsdGeomXformOp op = xformSchema.AddTranslateOp(UsdGeomXformOp::PrecisionFloat, TfToken(attrName)); - op.Set(currentValue); + op.Set(currentValue, time); return op.GetAttr(); } //---------------------------------------------------------------------------------------------------------------------- -UsdAttribute addRotateOp(const UsdGeomXform &xformSchema, - const char *attrName, - const int32_t &rotateOrder, - const GfVec3f &rotation) +UsdAttribute addRotateOp( + const UsdGeomXform &xformSchema, + const char *attrName, + const int32_t& rotateOrder, + const GfVec3f& rotation, + const UsdTimeCode& time) { TfToken rotateToken(attrName); UsdGeomXformOp op; @@ -608,14 +619,13 @@ UsdAttribute addRotateOp(const UsdGeomXform &xformSchema, default: break; } - op.Set(rotation); + op.Set(rotation, time); return op.GetAttr(); } //---------------------------------------------------------------------------------------------------------------------- MStatus TransformTranslator::copyAttributes(const MObject& from, UsdPrim& to, const ExporterParams& params) { - static const UsdTimeCode usdTime = UsdTimeCode::EarliestTime(); UsdGeomXform xformSchema(to); GfVec3f scale; GfVec3f shear; @@ -686,21 +696,21 @@ MStatus TransformTranslator::copyAttributes(const MObject& from, UsdPrim& to, co plugAnimated = transformAnimated || animationCheck(animTranslator, MPlug(from, m_translation)); if(plugAnimated || translation != defaultTranslation) { - UsdAttribute translateAttr = addTranslateOp(xformSchema, "translate", translation); + UsdAttribute translateAttr = addTranslateOp(xformSchema, "translate", translation, params.m_timeCode); if(plugAnimated && animTranslator) animTranslator->forceAddPlug(MPlug(from, m_translation), translateAttr); } plugAnimated = animationCheck(animTranslator, MPlug(from, m_rotatePivotTranslate)); if(plugAnimated || rotatePivotTranslate != defaultRotatePivotTranslate) { - UsdAttribute rotatePivotTranslateAttr = addTranslateOp(xformSchema, "rotatePivotTranslate", rotatePivotTranslate); + UsdAttribute rotatePivotTranslateAttr = addTranslateOp(xformSchema, "rotatePivotTranslate", rotatePivotTranslate, params.m_timeCode); if(plugAnimated && animTranslator) animTranslator->forceAddPlug(MPlug(from, m_rotatePivotTranslate), rotatePivotTranslateAttr); } plugAnimated = animationCheck(animTranslator, MPlug(from, m_rotatePivot)); if(plugAnimated || rotatePivot != defaultRotatePivot) { - UsdAttribute rotatePivotAttr = addTranslateOp(xformSchema, "rotatePivot", rotatePivot); + UsdAttribute rotatePivotAttr = addTranslateOp(xformSchema, "rotatePivot", rotatePivot, params.m_timeCode); if(plugAnimated && animTranslator) animTranslator->forceAddPlug(MPlug(from, m_rotatePivot), rotatePivotAttr); } @@ -708,7 +718,7 @@ MStatus TransformTranslator::copyAttributes(const MObject& from, UsdPrim& to, co if(plugAnimated || rotation != defaultRotation) { rotation *= radToDeg; - UsdAttribute rotateAttr = addRotateOp(xformSchema, "rotate", rotateOrder, rotation); + UsdAttribute rotateAttr = addRotateOp(xformSchema, "rotate", rotateOrder, rotation, params.m_timeCode); if(plugAnimated && animTranslator) animTranslator->forceAddPlug(MPlug(from, m_rotation), rotateAttr, radToDeg); } @@ -716,28 +726,28 @@ MStatus TransformTranslator::copyAttributes(const MObject& from, UsdPrim& to, co if(plugAnimated || rotateAxis != defaultRotateAxis) { rotateAxis *= radToDeg; - UsdAttribute rotateAxisAttr = addRotateOp(xformSchema, "rotateAxis", MEulerRotation::kXYZ, rotateAxis); + UsdAttribute rotateAxisAttr = addRotateOp(xformSchema, "rotateAxis", MEulerRotation::kXYZ, rotateAxis, params.m_timeCode); if(plugAnimated && animTranslator) animTranslator->forceAddPlug(MPlug(from, m_rotateAxis), rotateAxisAttr, radToDeg); } plugAnimated = animationCheck(animTranslator, MPlug(from, m_rotatePivot)); if(plugAnimated || rotatePivot != defaultRotatePivot) { - UsdAttribute rotatePivotINVAttr = addTranslateOp(xformSchema, "rotatePivotINV", -rotatePivot); + UsdAttribute rotatePivotINVAttr = addTranslateOp(xformSchema, "rotatePivotINV", -rotatePivot, params.m_timeCode); if(plugAnimated && animTranslator) animTranslator->forceAddPlug(MPlug(from, m_rotatePivot), rotatePivotINVAttr); } plugAnimated = animationCheck(animTranslator, MPlug(from, m_scalePivotTranslate)); if(plugAnimated || scalePivotTranslate != defaultScalePivotTranslate) { - UsdAttribute scalePivotTranslateAttr = addTranslateOp(xformSchema, "scalePivotTranslate", scalePivotTranslate); + UsdAttribute scalePivotTranslateAttr = addTranslateOp(xformSchema, "scalePivotTranslate", scalePivotTranslate, params.m_timeCode); if(plugAnimated && animTranslator) animTranslator->forceAddPlug(MPlug(from, m_scalePivotTranslate), scalePivotTranslateAttr); } plugAnimated = animationCheck(animTranslator, MPlug(from, m_scalePivot)); if(plugAnimated || scalePivot != defaultScalePivot) { - UsdAttribute scalePivotAttr = addTranslateOp(xformSchema, "scalePivot", scalePivot); + UsdAttribute scalePivotAttr = addTranslateOp(xformSchema, "scalePivot", scalePivot, params.m_timeCode); if(plugAnimated && animTranslator) animTranslator->forceAddPlug(MPlug(from, m_scalePivot), scalePivotAttr); } @@ -749,21 +759,21 @@ MStatus TransformTranslator::copyAttributes(const MObject& from, UsdPrim& to, co shear[1], shear[2], 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); UsdGeomXformOp op = xformSchema.AddTransformOp(UsdGeomXformOp::PrecisionDouble, TfToken("shear")); - op.Set(shearMatrix); + op.Set(shearMatrix, params.m_timeCode); } plugAnimated = transformAnimated || animationCheck(animTranslator, MPlug(from, m_scale)); if(plugAnimated || scale != defaultScale) { UsdGeomXformOp op = xformSchema.AddScaleOp(UsdGeomXformOp::PrecisionFloat, TfToken("scale")); - op.Set(scale); + op.Set(scale, params.m_timeCode); if(plugAnimated && animTranslator) animTranslator->forceAddPlug(MPlug(from, m_scale), op.GetAttr()); } plugAnimated = animationCheck(animTranslator, MPlug(from, m_scalePivot)); if(plugAnimated || scalePivot != defaultScalePivot) { - UsdAttribute scalePivotINVAttr = addTranslateOp(xformSchema, "scalePivotINV", -scalePivot); + UsdAttribute scalePivotINVAttr = addTranslateOp(xformSchema, "scalePivotINV", -scalePivot, params.m_timeCode); if(plugAnimated && animTranslator) animTranslator->forceAddPlug(MPlug(from, m_scalePivot), scalePivotINVAttr); } diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorBase.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorBase.cpp index 736bcd56..758adf6e 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorBase.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorBase.cpp @@ -29,7 +29,6 @@ namespace translators { //---------------------------------------------------------------------------------------------------------------------- TranslatorManufacture::TranslatorManufacture(TranslatorContextPtr context) { - unsigned int translatorCount = 0; std::set loadedTypes; std::set derivedTypes; diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorBase.h b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorBase.h index 2874d8bc..9508e65f 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorBase.h +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorBase.h @@ -170,13 +170,13 @@ class TranslatorBase /// \brief returns the translated prim type AL_USDMAYA_PUBLIC - virtual TfType getTranslatedType() const override + TfType getTranslatedType() const override { return m_translatedType; } /// \brief returns the context currently being used to translate the USD prims. The context can be used to add /// references to prims you have created in your translator plugins (see: AL_USDMAYA_PUBLIC - virtual TranslatorContextPtr context() const + TranslatorContextPtr context() const { return m_context; } /// \brief Internal method used to create a new instance of a plugin translator @@ -186,16 +186,13 @@ class TranslatorBase AL_USDMAYA_PUBLIC static RefPtr manufacture(const std::string& primType, TranslatorContextPtr context) = delete; - /// \brief Internal method used to create a new instance of a plugin translator - /// \param primType the type of translator to manufacture - /// \param context the translation context - /// \return a handle to the newly created plugin translator + /// \brief This method will be called prior to the tear down process taking place. This is the last chance you have + /// to do any serialisation whilst all of the existing nodes are available to query. + /// \param prim the prim that may be modified or deleted as a result of a variant switch + /// \return MS::kSuccess if all ok AL_USDMAYA_PUBLIC - virtual MStatus preTearDown(UsdPrim& prim) - { - m_isTearingDown = true; - return MS::kSuccess; - } + MStatus preTearDown(UsdPrim& prim) override + { return MS::kSuccess; } /// \brief return the usd stage associated with this context /// \return the usd stage @@ -203,12 +200,6 @@ class TranslatorBase UsdStageRefPtr getUsdStage() const { return context()->getUsdStage(); } - /// \brief If the translator has had pretearDown called on it then this will return true. - /// \return true if this prim has had the pretearDown called on it. - AL_USDMAYA_PUBLIC - bool isTearingDown() const - { return m_isTearingDown; } - protected: /// \brief internal method. Used within AL_USDMAYA_DEFINE_TRANSLATOR macro to set the schema type of the node we @@ -223,8 +214,6 @@ class TranslatorBase { m_context = context; } private: - bool m_isTearingDown = false; - TfType m_translatedType; TranslatorContextPtr m_context; }; @@ -282,7 +271,7 @@ class TranslatorFactory : public TranslatorFactoryBase /// \brief creates a new translator for a given type T /// \param ctx the current translator context /// \return the plugin translator associated with type T - virtual TfRefPtr create(TranslatorContextPtr ctx) const + TfRefPtr create(TranslatorContextPtr ctx) const override { return T::create(ctx); } }; diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorContext.cpp b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorContext.cpp index 4a0f9125..74821df1 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorContext.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorContext.cpp @@ -77,7 +77,7 @@ void TranslatorContext::updatePrimTypes() UsdPrim prim = stage->GetPrimAtPath(path); if(!prim) { - m_primMapping.erase(it++); + it = m_primMapping.erase(it); } else if(it->type() != prim.GetTypeName()) @@ -233,6 +233,7 @@ void TranslatorContext::insertItem(const UsdPrim& prim, MObjectHandle object) } } + //---------------------------------------------------------------------------------------------------------------------- void TranslatorContext::removeItems(const SdfPath& path) { @@ -297,7 +298,7 @@ void TranslatorContext::removeItems(const SdfPath& path) } if(hasDagNodes) { - for (int i = 0; i < tempXforms.size(); ++i) + for (size_t i = 0, n = tempXforms.size(); i < n; ++i) { // Check if these xforms have already been deleted automatically when we deleted their child shape. if(tempXforms[i].isAlive() && tempXforms[i].isValid()) @@ -409,7 +410,7 @@ void TranslatorContext::preRemoveEntry(const SdfPath& primPath, SdfPathVector& i // we are no longer in the same prim root const SdfPath& childPath = range_end->path(); - if(!range_end->path().HasPrefix(primPath)) + if(!childPath.HasPrefix(primPath)) { break; } @@ -461,9 +462,13 @@ void TranslatorContext::removeEntries(const SdfPathVector& itemsToRemove) { auto path = *iter; auto node = std::lower_bound(m_primMapping.begin(), m_primMapping.end(), path, value_compare()); + bool isInTransformChain = isPrimInTransformChain(path); TF_DEBUG(ALUSDMAYA_TRANSLATORS).Msg("TranslatorContext::removeEntries removing: %s\n", iter->GetText()); - unloadPrim(path, node->object()); + if(node->objectHandle().isValid() && node->objectHandle().isAlive()) + { + unloadPrim(path, node->object()); + } // The item might already have been removed by a translator... if(node != m_primMapping.end() && node->path() == path) @@ -472,7 +477,10 @@ void TranslatorContext::removeEntries(const SdfPathVector& itemsToRemove) m_primMapping.erase(node); } - m_proxyShape->removeUsdTransformChain(path, modifier, nodes::ProxyShape::kRequired); + if(isInTransformChain) + { + m_proxyShape->removeUsdTransformChain(path, modifier, nodes::ProxyShape::kRequired); + } ++iter; } @@ -493,12 +501,7 @@ void TranslatorContext::preUnloadPrim(UsdPrim& prim, const MObject& primObj) if(translator) { TF_DEBUG(ALUSDMAYA_TRANSLATORS).Msg("TranslatorContext::preUnloadPrim [preTearDown] prim=%s\n", prim.GetPath().GetText()); - - // call pretearDown if it hasn't been called before - if(!translator->isTearingDown()) - { - translator->preTearDown(prim); - } + translator->preTearDown(prim); } else { @@ -528,18 +531,14 @@ void TranslatorContext::unloadPrim(const SdfPath& path, const MObject& primObj) { TF_DEBUG(ALUSDMAYA_TRANSLATORS).Msg("TranslatorContext::unloadPrim [tearDown] prim=%s\n", path.GetText()); - // call pretearDown if it hasn't been called before - if(!translator->isTearingDown()) + UsdPrim prim = stage->GetPrimAtPath(path); + if(prim) { - UsdPrim prim = stage->GetPrimAtPath(path); - if(prim) - { - translator->preTearDown(prim); - } - else - { - TF_DEBUG(ALUSDMAYA_TRANSLATORS).Msg("TranslatorContext::preTearDown was skipped because the path '%s' was invalid\n", path.GetText()); - } + translator->preTearDown(prim); + } + else + { + TF_DEBUG(ALUSDMAYA_TRANSLATORS).Msg("TranslatorContext::preTearDown was skipped because the path '%s' was invalid\n", path.GetText()); } MStatus status = translator->tearDown(path); @@ -575,6 +574,105 @@ void TranslatorContext::unloadPrim(const SdfPath& path, const MObject& primObj) } } +//---------------------------------------------------------------------------------------------------------------------- +bool TranslatorContext::isNodeAncestorOf(MObjectHandle ancestorHandle, MObjectHandle objectHandleToTest) +{ + if(!ancestorHandle.isValid() || !ancestorHandle.isAlive()) + { + return false; + } + + if(!objectHandleToTest.isValid() || !objectHandleToTest.isAlive()) + { + return false; + } + + MObject ancestorNode = ancestorHandle.object(); + MObject nodeToTest = objectHandleToTest.object(); + if(ancestorNode == nodeToTest) + { + return false; + } + + MStatus parentStatus = MS::kSuccess; + MFnDagNode dagFn(nodeToTest, &parentStatus); + + // If it is not a DAG node: + if(!parentStatus) + { + return false; + } + + bool isParent = dagFn.isChildOf(ancestorNode, &parentStatus); + if(isParent) + { + return true; + } + + unsigned int parentC = dagFn.parentCount(&parentStatus); + if(!parentStatus) + { + return false; + } + + for(unsigned int i=0; iparentTransform(); + MObject proxyTransformNode = proxyShapeTransformDagPath.node(); + MObjectHandle proxyTransformNodeHandle(proxyTransformNode); + + + // First test the Maya node that prim is for, this is for MayaReference.. + MObjectHandle parentHandle; + if(getTransform(path, parentHandle)) + { + if(isNodeAncestorOf(proxyTransformNodeHandle, parentHandle)) + { + return true; + } + } + + // Now test the Maya node that translator created, this is for DAG hierarchy transform|shape.. + MObjectHandleArray mayaNodes; + bool everCreatedNodes = getMObjects(path, mayaNodes); + if(!everCreatedNodes) + { + return false; + } + + size_t nodeCount = mayaNodes.size(); + for(size_t i=0; isetForceDefaultRead(false); + return res; + } /// \brief return the proxy shape associated with this context /// \return the proxy shape @@ -301,7 +305,7 @@ struct TranslatorContext /// \brief get the maya object of the node /// \return the maya node for this reference MObject object() const - { return objectHandle().object(); } + { return m_object.object(); } /// \brief get the prim type /// \return the type stored for this prim @@ -412,6 +416,12 @@ struct TranslatorContext UsdPrim& primPath, const MObject& primObj); + bool isNodeAncestorOf(MObjectHandle ancestorHandle, MObjectHandle objectHandleToTest); + + /// \brief test if the prim was translated into any MObject(s), that sits underneath the parent MObject. + /// \return true if the prim maps to a MObject inside the Maya Dag tree. + bool isPrimInTransformChain(const SdfPath& path); + inline PrimLookups::iterator find(const SdfPath& path) { PrimLookups::iterator end = m_primMapping.end(); @@ -457,10 +467,21 @@ struct TranslatorContext // true to make all translators that default to not importing Prims to always import Prims via the translators bool m_forcePrimImport; - // list of geometry that has been request to be excluded during the translation SdfPathSet m_excludedGeometry; bool m_isExcludedGeometryDirty; + +public: + void setForceDefaultRead(bool forceDefaultRead) + { m_forceDefaultRead = forceDefaultRead; } + + bool getForceDefaultRead() + { return m_forceDefaultRead; } + +private: + // If true, will explicitly read default attribute values. + bool m_forceDefaultRead; + }; typedef TfRefPtr TranslatorContextPtr; diff --git a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorTestPlugin.h b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorTestPlugin.h index 0c6e067a..a75ebace 100644 --- a/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorTestPlugin.h +++ b/lib/AL_USDMaya/AL/usdmaya/fileio/translators/TranslatorTestPlugin.h @@ -40,6 +40,7 @@ class TranslatorTestPlugin AL_USDMAYA_DECLARE_TRANSLATOR(TranslatorTestPlugin); +private: MStatus initialize() override; MStatus import(const UsdPrim& prim, MObject& parent) override; MStatus postImport(const UsdPrim& prim) override; diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/LayerManager.cpp b/lib/AL_USDMaya/AL/usdmaya/nodes/LayerManager.cpp index 7fcf1bd9..6ecd25d9 100644 --- a/lib/AL_USDMaya/AL/usdmaya/nodes/LayerManager.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/LayerManager.cpp @@ -23,6 +23,14 @@ #include "pxr/usd/sdf/fileFormat.h" #include "pxr/usd/sdf/textFileFormat.h" #include "pxr/usd/usd/usdaFileFormat.h" +#include "pxr/usdImaging/usdImaging/version.h" +#if (USD_IMAGING_API_VERSION >= 7) + #include "pxr/usdImaging/usdImagingGL/gl.h" + #include "pxr/usdImaging/usdImagingGL/hdEngine.h" +#else + #include "pxr/usdImaging/usdImaging/gl.h" + #include "pxr/usdImaging/usdImaging/hdEngine.h" +#endif #include "maya/MBoundingBox.h" #include "maya/MGlobal.h" @@ -112,6 +120,10 @@ namespace AL { namespace usdmaya { namespace nodes { +LayerManager::~LayerManager() +{ +} + //---------------------------------------------------------------------------------------------------------------------- bool LayerDatabase::addLayer(SdfLayerRefPtr layer, const std::string& identifier) { @@ -156,19 +168,24 @@ bool LayerDatabase::removeLayer(SdfLayerRefPtr layer) return true; } -//---------------------------------------------------------------------------------------------------------------------- SdfLayerHandle LayerDatabase::findLayer(std::string identifier) const { auto foundIdAndLayer = m_idToLayer.find(identifier); if(foundIdAndLayer != m_idToLayer.end()) { - return foundIdAndLayer->second; + // Non-dirty layers may be placed in the database "temporarily" - + // ie, current edit targets for proxyShape stages, that have not + // yet been edited. Filter those out. + if(foundIdAndLayer->second->IsDirty()) + { + return foundIdAndLayer->second; + } } - return SdfLayerHandle(); } + //---------------------------------------------------------------------------------------------------------------------- void LayerDatabase::_addLayer(SdfLayerRefPtr layer, const std::string& identifier, std::vector& idsForLayer) @@ -270,6 +287,7 @@ MStatus LayerManager::initialise() try { setNodeType(kTypeName); + addFrame("USD Layer Manager Node"); addFrame("Serialization infos"); @@ -423,7 +441,7 @@ MStatus LayerManager::populateSerialisationAttributes() AL_MAYA_CHECK_ERROR(status, errorString); { boost::shared_lock_guard lock(m_layersMutex); - MArrayDataBuilder builder(&dataBlock, layers(), m_layerDatabase.size(), &status); + MArrayDataBuilder builder(&dataBlock, layers(), m_layerDatabase.max_size(), &status); AL_MAYA_CHECK_ERROR(status, errorString); std::string temp; for (const auto& layerAndIds : m_layerDatabase) diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/LayerManager.h b/lib/AL_USDMaya/AL/usdmaya/nodes/LayerManager.h index d52d6c55..ae8fa5a8 100644 --- a/lib/AL_USDMaya/AL/usdmaya/nodes/LayerManager.h +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/LayerManager.h @@ -22,8 +22,10 @@ #include "pxr/usd/usd/stage.h" #include "maya/MPxLocatorNode.h" +#include "maya/MNodeMessage.h" #include "AL/maya/utils/MayaHelperMacros.h" +#include #include #include #include @@ -34,12 +36,106 @@ namespace AL { namespace usdmaya { namespace nodes { +class ProxyShape; + +//---------------------------------------------------------------------------------------------------------------------- +/// \brief Iterator wrapper for LayerToIdsMap that hides non-dirty items +/// Implemented as a template to define const / non-const iterator at same time +/// \ingroup nodes +//---------------------------------------------------------------------------------------------------------------------- +template +class DirtyOnlyIterator +// : public std::iterator +{ +public: + typedef typename WrappedIterator::value_type value_type; + + /// \brief ctor + /// \param it the start of the iteration range + /// \param end the end of the iteration range + DirtyOnlyIterator(WrappedIterator it, WrappedIterator end): + m_iter(it), + m_end(end) + { + SetToNextDirty(); + } + + /// \brief copy ctor + /// \param other the iterator to copy + DirtyOnlyIterator(const DirtyOnlyIterator& other): + m_iter(other.m_iter), + m_end(other.m_end) + { + SetToNextDirty(); + } + + /// \brief pre-increment operator + /// \return a reference to this + DirtyOnlyIterator& operator++() + { + ++m_iter; + SetToNextDirty(); + return *this; + } + + /// \brief post-increment operator + /// \return a copy of the original iterator value + DirtyOnlyIterator operator++(int) + { + WrappedIterator tmp(*this); + operator++(); + return tmp; + } + + /// \brief equivalence operator + /// \param rhs the iterator to compare against + /// \return true if equivalent + bool operator == (const DirtyOnlyIterator& rhs) const + { + // You could argue we should check m_end too, + // but all we really care about is whether we're pointed + // at the same place, and it's faster... + return m_iter == rhs.m_iter; + } + + /// \brief non equivalence operator + /// \param rhs the iterator to compare against + /// \return false if equivalent, true otherwise + bool operator != (const DirtyOnlyIterator& rhs) const + { + return m_iter != rhs.m_iter; + } + + /// \brief dereference operator + value_type& operator * () + { return *m_iter; } + +private: + void SetToNextDirty() + { + while (m_iter != m_end && !m_iter->first->IsDirty()) + { + ++m_iter; + } + } + + WrappedIterator m_iter; + WrappedIterator m_end; +}; + //---------------------------------------------------------------------------------------------------------------------- /// \brief Stores layers, in a way that they may be looked up by the layer ref ptr, or by identifier /// Also, unlike boost::multi_index, we can have multiple identifiers per layer +/// You can add non-dirty layers to the database, but the query operations will "hide" them - +/// ie, iteration will skip by them, and findLayer will return an invalid ptr if it's not dirty +/// We allow adding non-dirty items because if we want to guarantee we always have all the latest +/// items, we need to deal with the situation where the current edit target starts out not +/// dirty... and it's easiest to just add it then filter it if it's not dirty /// \ingroup nodes //---------------------------------------------------------------------------------------------------------------------- -class LayerDatabase { +class LayerDatabase +{ public: typedef std::map> LayerToIdsMap; typedef std::map IdToLayerMap; @@ -47,7 +143,7 @@ class LayerDatabase { /// \brief Add the given layer to the set of layers in this LayerDatabase, if not already present, /// and optionally add an extra identifier as a key to it /// \param layer What layer to add to this database - /// \param identifer Extra identifier to add as a key to this layer; note that the "canonical" identifier, + /// \param identifier Extra identifier to add as a key to this layer; note that the "canonical" identifier, /// as returned by layer.GetIdentifier(), is ALWAYS added as an identifier key for this layer so this /// is intended as a way to provide a second identifier for the same layer (or third or more, if you /// call it repeatedly). This is useful both because multiple identifiers may resolve to the same @@ -57,7 +153,7 @@ class LayerDatabase { /// an empty string, it is ignored. /// \return bool which is true if the layer was actually added to the set of layers managed by this node /// (ie, if it wasn't already managed) - bool addLayer(SdfLayerRefPtr layer, const std::string& identifier=std::string("")); + bool addLayer(SdfLayerRefPtr layer, const std::string& identifier = std::string()); /// \brief Remove the given layer to the list of layers managed by this node, if present. /// \return bool which is true if the layer was actually removed from the set of layers managed by this node @@ -65,20 +161,60 @@ class LayerDatabase { bool removeLayer(SdfLayerRefPtr layer); /// \brief Find the layer in the set of layers managed by this node, by identifier - /// \return The found layer handle in the layer list managed by this node (invalid if not found) + /// \param identifier the identifier the full identifier of the layer to locate + /// \return The found layer handle in the layer list managed by this node (invalid if not found or not dirty) SdfLayerHandle findLayer(std::string identifier) const; - LayerToIdsMap::size_type size() const { return m_layerToIds.size(); } - - // Iterator interface - typedef LayerToIdsMap::iterator iterator; - typedef LayerToIdsMap::const_iterator const_iterator; - iterator begin() { return m_layerToIds.begin(); } - const_iterator begin() const { return m_layerToIds.cbegin(); } - const_iterator cbegin() const { return m_layerToIds.cbegin(); } - iterator end() { return m_layerToIds.end(); } - const_iterator end() const { return m_layerToIds.cend(); } - const_iterator cend() const { return m_layerToIds.cend(); } + /// Because we may have an unknown number of non-dirty member layers which we're treating + /// as not-existing, we can't get a size without iterating over all the layers; we can, + /// however, do an empty/non-empty boolean check by seeing if begin() == end(); in the + /// worst case, when the LayerDatabase consists of nothing but non-dirty layers, begin() + /// will will still end up iterating through all the layers attempting to find a + /// non-dirty layer to start at, but the average case should be pretty fast + /// + /// We use the safe-bool idiom to avoid nasty automatic conversions, etc +private: + typedef const LayerToIdsMap LayerDatabase::*_UnspecifiedBoolType; +public: + operator _UnspecifiedBoolType() const + { return begin() == end() ? &LayerDatabase::m_layerToIds : nullptr; } + + /// \brief Upper bound for the number of non-dirty layers in this object + /// This is the count of all tracked layers, dirty-and-non-dirty; + /// If it is zero, it can be guaranteed that there are no dirty + /// layers, but if it is non-zero, we cannot guarantee that there + /// are any non-dirty layers. Use boolean conversion above to test + /// that. + size_t max_size() const + { return m_layerToIds.size(); } + + // Iterator interface - skips past non-dirty items + typedef DirtyOnlyIterator iterator; + typedef DirtyOnlyIterator const_iterator; + + /// \brief returns start of layer range + iterator begin() + { return iterator(m_layerToIds.begin(), m_layerToIds.end()); } + + /// \brief returns start of layer range + const_iterator begin() const + { return const_iterator(m_layerToIds.cbegin(), m_layerToIds.cend()); } + + /// \brief returns start of layer range + const_iterator cbegin() const + { return const_iterator(m_layerToIds.cbegin(), m_layerToIds.cend()); } + + /// \brief returns end of layer range + iterator end() + { return iterator(m_layerToIds.end(), m_layerToIds.end()); } + + /// \brief returns end of layer range + const_iterator end() const + { return const_iterator(m_layerToIds.cend(), m_layerToIds.cend()); } + + /// \brief returns end of layer range + const_iterator cend() const + { return const_iterator(m_layerToIds.cend(), m_layerToIds.cend()); } private: void _addLayer(SdfLayerRefPtr layer, const std::string& identifier, @@ -90,6 +226,7 @@ class LayerDatabase { //---------------------------------------------------------------------------------------------------------------------- /// \brief The layer manager node handles serialization and deserialization of all layers used by all ProxyShapes +/// It may temporarily contain non-dirty layers, but those will be filtered out by query operations. /// \ingroup nodes //---------------------------------------------------------------------------------------------------------------------- class LayerManager @@ -103,6 +240,8 @@ class LayerManager inline LayerManager() : MPxNode(), NodeHelper() {} + ~LayerManager(); + /// \brief Find the already-existing non-referenced LayerManager node in the scene, or return a null MObject /// \return the found LayerManager node, or a null MObject AL_USDMAYA_PUBLIC @@ -115,7 +254,7 @@ class LayerManager /// \param wasCreated If given, whether a new layer manager had to be created is stored here. /// \return the found-or-created LayerManager node AL_USDMAYA_PUBLIC - static MObject findOrCreateNode(MDGModifier* dgmod=nullptr, bool* wasCreated=nullptr); + static MObject findOrCreateNode(MDGModifier* dgmod = nullptr, bool* wasCreated = nullptr); /// \brief Find the already-existing non-referenced LayerManager node in the scene, or return a nullptr /// \return the found LayerManager, or a nullptr @@ -129,7 +268,7 @@ class LayerManager /// \param wasCreated If given, whether a new layer manager had to be created is stored here. /// \return the found-or-created LayerManager AL_USDMAYA_PUBLIC - static LayerManager* findOrCreateManager(MDGModifier* dgmod=nullptr, bool* wasCreated=nullptr); + static LayerManager* findOrCreateManager(MDGModifier* dgmod = nullptr, bool* wasCreated = nullptr); //-------------------------------------------------------------------------------------------------------------------- /// Methods to handle the saving and restoring of layer data @@ -137,7 +276,7 @@ class LayerManager /// \brief Add the given layer to the list of layers managed by this node, if not already present. /// \param layer What layer to add to this LayerManager - /// \param identifer Extra identifier to add as a key to this layer; note that the "canonical" identifier, + /// \param identifier Extra identifier to add as a key to this layer; note that the "canonical" identifier, /// as returned by layer.GetIdentifier(), is ALWAYS added as an identifier key for this layer so this /// is intended as a way to provide a second identifier for the same layer (or third or more, if you /// call it repeatedly). This is useful both because multiple identifiers may resolve to the same @@ -148,7 +287,7 @@ class LayerManager /// \return bool which is true if the layer was actually added to the list of layers managed by this node /// (ie, if it wasn't already managed, and the given layer handle was valid) AL_USDMAYA_PUBLIC - bool addLayer(SdfLayerHandle layer, const std::string& identifier=std::string("")); + bool addLayer(SdfLayerHandle layer, const std::string& identifier = std::string()); /// \brief Remove the given layer to the list of layers managed by this node, if present. /// \return bool which is true if the layer was actually removed from the list of layers managed by this node diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyDrawOverride.cpp b/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyDrawOverride.cpp index cf5b87b4..8cb87604 100644 --- a/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyDrawOverride.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyDrawOverride.cpp @@ -59,6 +59,7 @@ class RenderUserData //---------------------------------------------------------------------------------------------------------------------- MString ProxyDrawOverride::kDrawDbClassification("drawdb/geometry/AL_usdmaya"); MString ProxyDrawOverride::kDrawRegistrantId("pxrUsd"); +MUint64 ProxyDrawOverride::s_lastRefreshFrameStamp = 0; //---------------------------------------------------------------------------------------------------------------------- ProxyDrawOverride::ProxyDrawOverride(const MObject& obj) @@ -135,8 +136,6 @@ MUserData* ProxyDrawOverride::prepareForDraw( return NULL; } - data->m_params.showGuides = data->m_shape->displayGuidesPlug().asBool(); - data->m_params.showRender = data->m_shape->displayRenderGuidesPlug().asBool(); data->m_rootPrim = data->m_shape->getRootPrim(); data->m_engine = engine; @@ -190,7 +189,7 @@ void ProxyDrawOverride::draw(const MHWRender::MDrawContext& context, const MUser else { MFloatPoint fp(0,0,0); - for(int j = 0; j < positions.length(); ++j) + for(uint32_t j = 0; j < positions.length(); ++j) { fp += positions[j]; } @@ -383,6 +382,16 @@ void ProxyDrawOverride::draw(const MHWRender::MDrawContext& context, const MUser stateManager->setDepthStencilState(previousDepthState); MHWRender::MStateManager::releaseDepthStencilState(depthState); + + // Check framestamp b/c we don't want to put multiple refresh commands + // on the idle queue for a single frame-render... especially if we have + // multiple ProxyShapes... + if (!ptr->m_engine->IsConverged() && context.getFrameStamp() != s_lastRefreshFrameStamp) + { + s_lastRefreshFrameStamp = context.getFrameStamp(); + // Force another refresh of the current viewport + MGlobal::executeCommandOnIdle("refresh -cv -f"); + } } glClearColor(clearCol[0], clearCol[1], clearCol[2], clearCol[3]); } diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyDrawOverride.h b/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyDrawOverride.h index 5acaa306..b0b1bbdb 100644 --- a/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyDrawOverride.h +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyDrawOverride.h @@ -118,6 +118,9 @@ class ProxyDrawOverride bool excludedFromPostEffects() const override { return false; } #endif + +private: + static MUint64 s_lastRefreshFrameStamp; }; //---------------------------------------------------------------------------------------------------------------------- diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShape.cpp b/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShape.cpp index 277a97a7..27b4bfeb 100644 --- a/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShape.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShape.cpp @@ -16,10 +16,8 @@ #include "pxr/usdImaging/usdImaging/version.h" #if (USD_IMAGING_API_VERSION >= 7) #include "pxr/usdImaging/usdImagingGL/hdEngine.h" - #include "pxr/usdImaging/usdImagingGL/gl.h" #else #include "pxr/usdImaging/usdImaging/hdEngine.h" - #include "pxr/usdImaging/usdImaging/gl.h" #endif #if (__cplusplus >= 201703L) @@ -52,6 +50,7 @@ typedef boost::filesystem::path path; #include "AL/usdmaya/fileio/SchemaPrims.h" #include "AL/usdmaya/fileio/TransformIterator.h" #include "AL/usdmaya/nodes/LayerManager.h" +#include "AL/usdmaya/nodes/RendererManager.h" #include "AL/usdmaya/nodes/ProxyShape.h" #include "AL/usdmaya/nodes/Transform.h" #include "AL/usdmaya/nodes/TransformationMatrix.h" @@ -233,13 +232,11 @@ MObject ProxyShape::m_transformTranslate = MObject::kNullObj; MObject ProxyShape::m_transformRotate = MObject::kNullObj; MObject ProxyShape::m_transformScale = MObject::kNullObj; MObject ProxyShape::m_stageDataDirty = MObject::kNullObj; -MObject ProxyShape::m_rendererPlugin = MObject::kNullObj; MObject ProxyShape::m_stageCacheId = MObject::kNullObj; MObject ProxyShape::m_assetResolverConfig = MObject::kNullObj; //---------------------------------------------------------------------------------------------------------------------- std::vector ProxyShape::m_unloadedProxyShapes; -TfTokenVector ProxyShape::m_rendererPlugins; int m_stageCacheId; //---------------------------------------------------------------------------------------------------------------------- UsdPrim ProxyShape::getUsdPrim(MDataBlock& dataBlock) const @@ -264,8 +261,11 @@ SdfPathVector ProxyShape::getExcludePrimPaths() const { TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("ProxyShape::getExcludePrimPaths\n"); - MString paths = excludePrimPathsPlug().asString(); - return getPrimPathsFromCommaJoinedString(paths); + SdfPathVector paths = getPrimPathsFromCommaJoinedString(excludePrimPathsPlug().asString()); + SdfPathVector temp = getPrimPathsFromCommaJoinedString(excludedTranslatedGeometryPlug().asString()); + paths.insert(paths.end(), temp.begin(), temp.end()); + + return paths; } //---------------------------------------------------------------------------------------------------------------------- @@ -293,7 +293,7 @@ void ProxyShape::translatePrimPathsIntoMaya( const SdfPathVector& teardownPaths, const fileio::translators::TranslatorParameters& param) { - TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("ProxyShape:translatePrimPathsIntoMaya ImportSize='%d' TearDownSize='%d' \n", + TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("ProxyShape:translatePrimPathsIntoMaya ImportSize='%zd' TearDownSize='%zd' \n", importPaths.size(), teardownPaths.size()); @@ -320,7 +320,7 @@ void ProxyShape::translatePrimsIntoMaya( const SdfPathVector& teardownPrims, const fileio::translators::TranslatorParameters& param) { - TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("ProxyShape:translatePrimsIntoMaya ImportSize='%d' TearDownSize='%d' \n", importPrims.size(), teardownPrims.size()); + TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("ProxyShape:translatePrimsIntoMaya ImportSize='%zd' TearDownSize='%zd' \n", importPrims.size(), teardownPrims.size()); proxy::PrimFilter filter(teardownPrims, importPrims, this); if(TfDebug::IsEnabled(ALUSDMAYA_TRANSLATORS)) @@ -441,6 +441,12 @@ void ProxyShape::constructGLImagingEngine() translatedGeo.end()); m_engine = new UsdImagingGLHdEngine(m_path, excludedGeometryPaths); + // set renderer plugin based on RendererManager setting + RendererManager* manager = RendererManager::findManager(); + if(manager && m_engine) + { + manager->changeRendererPlugin(this, true); + } triggerEvent("ConstructGLEngine"); } @@ -545,6 +551,7 @@ bool ProxyShape::getRenderAttris(void* pattribs, const MHWRender::MFrameContext& const float complexities[] = {1.05f, 1.15f, 1.25f, 1.35f, 1.45f, 1.55f, 1.65f, 1.75f, 1.9f}; attribs.complexity = complexities[complexityPlug().asInt()]; attribs.showGuides = displayGuidesPlug().asBool(); + attribs.showRender = displayRenderGuidesPlug().asBool(); return true; } @@ -726,7 +733,7 @@ MStatus ProxyShape::initialise() m_complexity = addInt32Attr("complexity", "cplx", 0, kCached | kConnectable | kReadable | kWritable | kAffectsAppearance | kKeyable | kStorable); setMinMax(m_complexity, 0, 8, 0, 4); - m_outStageData = addDataAttr("outStageData", "od", StageData::kTypeId, kInternal | kReadable | kWritable | kAffectsAppearance); + m_outStageData = addDataAttr("outStageData", "od", StageData::kTypeId, kConnectable | kReadable | kWritable | kAffectsAppearance); m_displayGuides = addBoolAttr("displayGuides", "dg", false, kCached | kKeyable | kWritable | kAffectsAppearance | kStorable); m_displayRenderGuides = addBoolAttr("displayRenderGuides", "drg", false, kCached | kKeyable | kWritable | kAffectsAppearance | kStorable); m_unloaded = addBoolAttr("unloaded", "ul", false, kCached | kKeyable | kWritable | kAffectsAppearance | kStorable); @@ -763,20 +770,6 @@ MStatus ProxyShape::initialise() m_stageDataDirty = addBoolAttr("stageDataDirty", "sdd", false, kWritable | kAffectsAppearance | kInternal); - // Create dummy imaging engine to get renderer names - UsdImagingGL imagingEngine(SdfPath(), {}); - m_rendererPlugins = imagingEngine.GetRendererPlugins(); - std::vector pluginDesc(m_rendererPlugins.size()); - std::vector pluginNames(m_rendererPlugins.size() + 1, nullptr); - std::vector pluginIds(m_rendererPlugins.size() + 1, -1); - for (size_t i = 0; i < m_rendererPlugins.size(); ++i) - { - pluginDesc[i] = imagingEngine.GetRendererPluginDesc(m_rendererPlugins[i]); - pluginNames[i] = pluginDesc[i].data(); - pluginIds[i] = i; - } - m_rendererPlugin = addEnumAttr("rendererPlugin", "rp", kCached | kReadable | kWritable | kAffectsAppearance, pluginNames.data(), pluginIds.data()); - m_stageCacheId = addInt32Attr("stageCacheId", "stcid", -1, kCached | kConnectable | kReadable ); m_assetResolverConfig = addStringAttr("assetResolverConfig", "arc", kReadable | kWritable | kConnectable | kStorable | kAffectsAppearance); @@ -815,26 +808,20 @@ void ProxyShape::onEditTargetChanged(UsdNotice::StageEditTargetChanged const& no //---------------------------------------------------------------------------------------------------------------------- void ProxyShape::trackEditTargetLayer(LayerManager* layerManager) { - TF_DEBUG(ALUSDMAYA_LAYERS).Msg("ProxyShape::trackEditTargetLayer"); + TF_DEBUG(ALUSDMAYA_LAYERS).Msg("ProxyShape::trackEditTargetLayer\n"); auto stage = getUsdStage(); + if(!stage) { TF_DEBUG(ALUSDMAYA_LAYERS).Msg(" - no stage\n"); return; } - auto prevTargetLayer = m_prevTargetLayer; - m_prevTargetLayer = stage->GetEditTarget().GetLayer(); + auto currTargetLayer = stage->GetEditTarget().GetLayer(); - if(!prevTargetLayer) - { - TF_DEBUG(ALUSDMAYA_LAYERS).Msg(" - no prev target layer\n"); - return; - } + TF_DEBUG(ALUSDMAYA_LAYERS).Msg(" - curr target layer: %s\n", currTargetLayer->GetIdentifier().c_str()); - TF_DEBUG(ALUSDMAYA_LAYERS).Msg(" - prev target layer: %s\n", - prevTargetLayer->GetIdentifier().c_str()); - if(prevTargetLayer->IsDirty()) + if (m_prevEditTarget != currTargetLayer) { if(!layerManager) { @@ -847,9 +834,19 @@ void ProxyShape::trackEditTargetLayer(LayerManager* layerManager) return; } } - layerManager->addLayer(prevTargetLayer); + + if (m_prevEditTarget && !m_prevEditTarget->IsDirty()) + { + // If the old edit target still isn't dirty, and we're switching to a new + // edit target, we can remove it from the layer manager + layerManager->removeLayer(m_prevEditTarget); + } + + layerManager->addLayer(currTargetLayer); + m_prevEditTarget = currTargetLayer; + + triggerEvent("EditTargetChanged"); } - triggerEvent("EditTargetChanged"); } //---------------------------------------------------------------------------------------------------------------------- @@ -1132,7 +1129,7 @@ void ProxyShape::validateTransforms() newPrim.GetMetadata(Metadata::transformType, &transformType); if(newPrim && transformType.empty()) { - tm->transform()->setPrim(newPrim); + tm->transform()->setPrim(newPrim, tm); } } else @@ -1235,7 +1232,10 @@ void ProxyShape::loadStage() AL_BEGIN_PROFILE_SECTION(LoadStage); MDataBlock dataBlock = forceCache(); // in case there was already a stage in m_stage, check to see if it's edit target has been altered - trackEditTargetLayer(); + if (m_stage) + { + trackEditTargetLayer(); + } m_stage = UsdStageRefPtr(); // Get input attr values @@ -1438,23 +1438,23 @@ bool ProxyShape::updateLockPrims(const SdfPathSet& lockTransformPrims, const Sdf for (auto lock : lockTransformPrims) { auto inserted = m_lockTransformPrims.insert(lock); - lockChanged |= inserted.second; + lockChanged = lockChanged || inserted.second; auto erased = m_lockInheritedPrims.erase(lock); - lockChanged |= erased; + lockChanged = lockChanged || erased; } for (auto inherited : lockInheritedPrims) { auto erased = m_lockTransformPrims.erase(inherited); - lockChanged |= erased; + lockChanged = lockChanged || erased; auto inserted = m_lockInheritedPrims.insert(inherited); - lockChanged |= inserted.second; + lockChanged = lockChanged || inserted.second; } for (auto unlocked : unlockedPrims) { auto erased = m_lockTransformPrims.erase(unlocked); - lockChanged |= erased; + lockChanged = lockChanged || erased; erased = m_lockInheritedPrims.erase(unlocked); - lockChanged |= erased; + lockChanged = lockChanged || erased; } return lockChanged; } @@ -1620,35 +1620,13 @@ void ProxyShape::onAttributeChanged(MNodeMessage::AttributeMessage msg, MPlug& p } } else - if(plug == m_excludePrimPaths) + if(plug == m_excludePrimPaths || plug == m_excludedTranslatedGeometry) { if(proxy->m_stage) { proxy->constructExcludedPrims(); } } - else - if(plug == m_rendererPlugin) - { - short rendererId = plug.asShort(); - if (rendererId < m_rendererPlugins.size() && proxy->m_engine) - { - TfToken plugin = m_rendererPlugins[rendererId]; - if (!proxy->m_engine->SetRendererPlugin(plugin)) - { - MString message("failed to set renderer plugin: "); - MString data(plugin.data()); - MGlobal::displayError(message + data); - } - } - else - { - MString message("failed to set renderer plugin: "); - MString data; - data.set(rendererId); - MGlobal::displayError(message + data); - } - } } } @@ -1656,10 +1634,10 @@ void ProxyShape::onAttributeChanged(MNodeMessage::AttributeMessage msg, MPlug& p void ProxyShape::removeAttributeChangedCallback() { TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("ProxyShape::removeAttributeChangedCallback\n"); - if(m_attributeChanged != -1) + if(m_attributeChanged != 0) { MMessage::removeCallback(m_attributeChanged); - m_attributeChanged = -1; + m_attributeChanged = 0; } } @@ -1667,7 +1645,7 @@ void ProxyShape::removeAttributeChangedCallback() void ProxyShape::addAttributeChangedCallback() { TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("ProxyShape::addAttributeChangedCallback\n"); - if(m_attributeChanged == -1) + if(m_attributeChanged == 0) { MObject obj = thisMObject(); m_attributeChanged = MNodeMessage::addAttributeChangedCallback(obj, onAttributeChanged, (void*)this); @@ -1793,6 +1771,11 @@ MStatus ProxyShape::computeOutStageData(const MPlug& plug, MDataBlock& dataBlock return MS::kFailure; } + // make sure a stage is loaded + if (!m_stage) + { + loadStage(); + } // Set the output stage data params usdStageData->stage = m_stage; usdStageData->primPath = m_path; @@ -1884,6 +1867,7 @@ MBoundingBox ProxyShape::boundingBox() const // This would seem to be superfluous? unless it is actually forcing a DG pull? MDataHandle outDataHandle = dataBlock.inputValue(m_outStageData, &status); + (void)outDataHandle; CHECK_MSTATUS_AND_RETURN(status, MBoundingBox() ); // XXX:aluk @@ -2108,7 +2092,7 @@ void ProxyShape::deserialiseTransformRefs() //---------------------------------------------------------------------------------------------------------------------- ProxyShape::TransformReference::TransformReference(MObject mayaNode, Transform* node, uint32_t r, uint32_t s, uint32_t rc) - : m_node(mayaNode), m_transform(node) + : m_transform(node), m_node(mayaNode) { m_required = r; m_selected = s; @@ -2151,6 +2135,8 @@ void ProxyShape::registerEvents() registerEvent("PreDeserialiseTransformRefs", AL::event::kUSDMayaEventType, Global::postRead()); registerEvent("PostDeserialiseTransformRefs", AL::event::kUSDMayaEventType, Global::postRead()); registerEvent("EditTargetChanged", AL::event::kUSDMayaEventType); + registerEvent("SelectionStarted", AL::event::kUSDMayaEventType); + registerEvent("SelectionEnded", AL::event::kUSDMayaEventType); } #if defined(WANT_UFE_BUILD) diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShape.h b/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShape.h index 08b7496e..c987d84a 100644 --- a/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShape.h +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShape.h @@ -316,7 +316,7 @@ class ProxyShape /// display guide - sets shape to display geometry of purpose "guide". See imageable.h AL_DECL_ATTRIBUTE(displayGuides); - /// display render guide - sets hape to display geometry of purpose "render. See imageable.h + /// display render guide - sets hape to display geometry of purpose "render". See imageable.h AL_DECL_ATTRIBUTE(displayRenderGuides); /// Connection to any layer DG nodes @@ -371,9 +371,6 @@ class ProxyShape /// Excluded geometry that has been explicitly translated AL_DECL_ATTRIBUTE(excludedTranslatedGeometry); - /// Hydra renderer plugin used for rendering (not storable) - AL_DECL_ATTRIBUTE(rendererPlugin); - /// Cache ID of the currently loaded stage) AL_DECL_ATTRIBUTE(stageCacheId); @@ -823,19 +820,18 @@ class ProxyShape /// \brief Translates prims at the specified paths, the operation conducted by the translator depends on /// which list you populate. - /// \param importPaths paths you wish to import + /// \param importPrims array of prims you wish to import /// \param teardownPaths paths you wish to teardown /// \param param are flags which direct the translation of the prims AL_USDMAYA_PUBLIC void translatePrimsIntoMaya( const AL::usd::utils::UsdPrimVector& importPrims, - const SdfPathVector& teardownPrims, + const SdfPathVector& teardownPaths, const fileio::translators::TranslatorParameters& param = fileio::translators::TranslatorParameters()); - /// \brief Breaks a comma separated string up into a SdfPath Vector - /// \param importPaths paths you wish to import - /// \param teardownPaths paths you wish to teardown - /// \param param are flags which direct the translation of the prims + /// \brief Breaks a comma separated string up into a SdfPath Vector + /// \param paths the comma separated list of paths + /// \return the separated list of paths AL_USDMAYA_PUBLIC SdfPathVector getPrimPathsFromCommaJoinedString(const MString &paths) const; @@ -1030,8 +1026,8 @@ class ProxyShape mutable std::map m_boundingBoxCache; AL::event::CallbackId m_beforeSaveSceneId = -1; - MCallbackId m_attributeChanged = -1; - MCallbackId m_onSelectionChanged = -1; + MCallbackId m_attributeChanged = 0; + MCallbackId m_onSelectionChanged = 0; SdfPathVector m_excludedGeometry; SdfPathVector m_excludedTaggedGeometry; SdfPathSet m_lockTransformPrims; @@ -1046,7 +1042,7 @@ class ProxyShape fileio::translators::TranslatorManufacture m_translatorManufacture; SdfPath m_changedPath; SdfPathVector m_variantSwitchedPrims; - SdfLayerHandle m_prevTargetLayer; + SdfLayerHandle m_prevEditTarget; UsdImagingGLHdEngine* m_engine = 0; uint32_t m_engineRefCount = 0; @@ -1054,7 +1050,6 @@ class ProxyShape bool m_drivenTransformsDirty = false; bool m_pleaseIgnoreSelection = false; bool m_hasChangedSelection = false; - static TfTokenVector m_rendererPlugins; }; //---------------------------------------------------------------------------------------------------------------------- diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShapeSelection.cpp b/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShapeSelection.cpp index d3fb111b..95384167 100644 --- a/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShapeSelection.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShapeSelection.cpp @@ -578,8 +578,6 @@ MObject ProxyShape::makeUsdTransformChain( MPlug inStageData = ptrNode->inStageDataPlug(); MPlug inTime = ptrNode->timePlug(); - modifier.connect(outStage, inStageData); - modifier.connect(outTime, inTime); if(modifier2) { @@ -601,6 +599,12 @@ MObject ProxyShape::makeUsdTransformChain( MPlug(node, MPxTransform::shearXZ).setLocked(true); MPlug(node, MPxTransform::shearYZ).setLocked(true); } + else + { + // only connect time and stage if transform can change + modifier.connect(outTime, inTime); + modifier.connect(outStage, inStageData); + } // set the primitive path modifier.newPlugValueString(ptrNode->primPathPlug(), path.GetText()); @@ -726,9 +730,9 @@ void ProxyShape::removeUsdTransformChain( auto it = m_requiredPaths.find(parentPrim); if(it == m_requiredPaths.end()) { - return; + TF_DEBUG(ALUSDMAYA_SELECTION).Msg("ProxyShape -- %s path has not been found\n", path.GetText()); } - + else if(it->second.decRef(reason)) { MObject object = it->second.node(); @@ -1010,6 +1014,7 @@ bool ProxyShape::doSelect(SelectionUndoHelper& helper, const SdfPathVector& orde auto stage = m_stage; if(!stage) return false; + triggerEvent("SelectionStarted"); m_pleaseIgnoreSelection = true; prepSelect(); @@ -1054,6 +1059,7 @@ bool ProxyShape::doSelect(SelectionUndoHelper& helper, const SdfPathVector& orde if(keepPrims.empty() && insertPrims.empty()) { m_pleaseIgnoreSelection = false; + triggerEvent("SelectionEnded"); return false; } @@ -1154,6 +1160,7 @@ bool ProxyShape::doSelect(SelectionUndoHelper& helper, const SdfPathVector& orde if(prims.empty()) { m_pleaseIgnoreSelection = false; + triggerEvent("SelectionEnded"); return false; } @@ -1167,7 +1174,7 @@ bool ProxyShape::doSelect(SelectionUndoHelper& helper, const SdfPathVector& orde m_selectedPaths.erase(prim.GetPath()); removeUsdTransformChain_internal(prim, helper.m_modifier1, ProxyShape::kSelection); - for(int i = 0; i < helper.m_newSelection.length(); ++i) + for(uint32_t i = 0; i < helper.m_newSelection.length(); ++i) { MObject obj; helper.m_newSelection.getDependNode(i, object); @@ -1223,7 +1230,7 @@ bool ProxyShape::doSelect(SelectionUndoHelper& helper, const SdfPathVector& orde m_selectedPaths.erase(prim.GetPath()); removeUsdTransformChain_internal(prim, helper.m_modifier1, ProxyShape::kSelection); - for(int i = 0; i < helper.m_newSelection.length(); ++i) + for(uint32_t i = 0; i < helper.m_newSelection.length(); ++i) { MObject obj; helper.m_newSelection.getDependNode(i, object); @@ -1262,6 +1269,7 @@ bool ProxyShape::doSelect(SelectionUndoHelper& helper, const SdfPathVector& orde } m_pleaseIgnoreSelection = false; + triggerEvent("SelectionEnded"); return true; } diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShapeUI.cpp b/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShapeUI.cpp index 48489125..bfa9c7f8 100644 --- a/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShapeUI.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShapeUI.cpp @@ -49,13 +49,13 @@ namespace nodes { //---------------------------------------------------------------------------------------------------------------------- ProxyShapeUI::ProxyShapeUI() { - TF_DEBUG(ALUSDMAYA_DRAW).Msg("ProxyShapeUI::ProxyShapeUI"); + TF_DEBUG(ALUSDMAYA_DRAW).Msg("ProxyShapeUI::ProxyShapeUI\n"); } //---------------------------------------------------------------------------------------------------------------------- ProxyShapeUI::~ProxyShapeUI() { - TF_DEBUG(ALUSDMAYA_DRAW).Msg("ProxyShapeUI::~ProxyShapeUI"); + TF_DEBUG(ALUSDMAYA_DRAW).Msg("ProxyShapeUI::~ProxyShapeUI\n"); } //---------------------------------------------------------------------------------------------------------------------- @@ -67,7 +67,7 @@ void* ProxyShapeUI::creator() //---------------------------------------------------------------------------------------------------------------------- void ProxyShapeUI::getDrawRequests(const MDrawInfo& drawInfo, bool isObjectAndActiveOnly, MDrawRequestQueue& requests) { - TF_DEBUG(ALUSDMAYA_DRAW).Msg("ProxyShapeUI::getDrawRequests"); + TF_DEBUG(ALUSDMAYA_DRAW).Msg("ProxyShapeUI::getDrawRequests\n"); MDrawRequest request = drawInfo.getPrototype(*this); @@ -88,7 +88,7 @@ void ProxyShapeUI::getDrawRequests(const MDrawInfo& drawInfo, bool isObjectAndAc //---------------------------------------------------------------------------------------------------------------------- void ProxyShapeUI::draw(const MDrawRequest& request, M3dView& view) const { - TF_DEBUG(ALUSDMAYA_DRAW).Msg("ProxyShapeUI::draw"); + TF_DEBUG(ALUSDMAYA_DRAW).Msg("ProxyShapeUI::draw\n"); // view.beginGL(); @@ -272,134 +272,139 @@ SdfPathVector ProxyShapeSelectionHelper::m_paths; //---------------------------------------------------------------------------------------------------------------------- bool ProxyShapeUI::select(MSelectInfo& selectInfo, MSelectionList& selectionList, MPointArray& worldSpaceSelectPoints) const { - TF_DEBUG(ALUSDMAYA_DRAW).Msg("ProxyShapeUI::select"); + TF_DEBUG(ALUSDMAYA_DRAW).Msg("ProxyShapeUI::select"); - float clearCol[4]; - glGetFloatv(GL_COLOR_CLEAR_VALUE, clearCol); - - M3dView view = selectInfo.view(); - - MSelectionMask objectsMask(ProxyShape::s_selectionMaskName); - - // selectable() takes MSelectionMask&, not const MSelectionMask. :(. - if (!selectInfo.selectable(objectsMask)) - return false; - - MDagPath selectPath = selectInfo.selectPath(); - MMatrix invMatrix = selectPath.inclusiveMatrixInverse(); - - UsdImagingGLEngine::RenderParams params; - MMatrix viewMatrix, projectionMatrix; - GfMatrix4d worldToLocalSpace(invMatrix.matrix); - - GLuint glHitRecord; - view.beginSelect(&glHitRecord, 1); - glGetDoublev(GL_MODELVIEW_MATRIX, viewMatrix[0]); - glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix[0]); - view.endSelect(); - - auto* proxyShape = static_cast(surfaceShape()); - auto engine = proxyShape->engine(); - proxyShape->m_pleaseIgnoreSelection = true; + float clearCol[4]; + glGetFloatv(GL_COLOR_CLEAR_VALUE, clearCol); - UsdPrim root = proxyShape->getUsdStage()->GetPseudoRoot(); + M3dView view = selectInfo.view(); - UsdImagingGLEngine::HitBatch hitBatch; - SdfPathVector rootPath; - rootPath.push_back(root.GetPath()); + MSelectionMask objectsMask(ProxyShape::s_selectionMaskName); - int resolution = 10; - MGlobal::getOptionVarValue("AL_usdmaya_selectResolution", resolution); - if (resolution < 10) { resolution = 10; } - if (resolution > 1024) { resolution = 1024; } + // selectable() takes MSelectionMask&, not const MSelectionMask. :(. + if(!selectInfo.selectable(objectsMask)) + return false; - bool hitSelected = engine->TestIntersectionBatch( - GfMatrix4d(viewMatrix.matrix), - GfMatrix4d(projectionMatrix.matrix), - worldToLocalSpace, - rootPath, - params, - resolution, - ProxyShapeSelectionHelper::path_ting, - &hitBatch); + MDagPath selectPath = selectInfo.selectPath(); + MMatrix invMatrix = selectPath.inclusiveMatrixInverse(); - auto selected = false; + UsdImagingGLEngine::RenderParams params; + MMatrix viewMatrix, projectionMatrix; + GfMatrix4d worldToLocalSpace(invMatrix.matrix); + + GLuint glHitRecord; + view.beginSelect(&glHitRecord, 1); + glGetDoublev(GL_MODELVIEW_MATRIX, viewMatrix[0]); + glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix[0]); + view.endSelect(); + + auto* proxyShape = static_cast(surfaceShape()); + auto engine = proxyShape->engine(); + proxyShape->m_pleaseIgnoreSelection = true; + + UsdPrim root = proxyShape->getUsdStage()->GetPseudoRoot(); + + UsdImagingGLEngine::HitBatch hitBatch; + SdfPathVector rootPath; + rootPath.push_back(root.GetPath()); + + int resolution = 10; + MGlobal::getOptionVarValue("AL_usdmaya_selectResolution", resolution); + if (resolution < 10) { resolution = 10; } + if (resolution > 1024) { resolution = 1024; } + + bool hitSelected = engine->TestIntersectionBatch( + GfMatrix4d(viewMatrix.matrix), + GfMatrix4d(projectionMatrix.matrix), + worldToLocalSpace, + rootPath, + params, + resolution, + ProxyShapeSelectionHelper::path_ting, + &hitBatch); + + auto selected = false; #if defined(WANT_UFE_BUILD) - auto pickUfePathPrim = [proxyShape](const SdfPath& path) -> SdfPath { - if (ArchHasEnv("MAYA_WANT_UFE_SELECTION")) { - // Get only Xform types for ufe selection - UsdPrim prim = proxyShape->getUsdStage()->GetPrimAtPath(path); - while (prim && prim.GetTypeName() != "Xform") - prim = prim.GetParent(); - return prim.GetPath(); - } - return path; + auto pickUfePathPrim = [proxyShape](const SdfPath& path) -> SdfPath { + if (ArchHasEnv("MAYA_WANT_UFE_SELECTION")) { + // Get only Xform types for ufe selection + UsdPrim prim = proxyShape->getUsdStage()->GetPrimAtPath(path); + while (prim && prim.GetTypeName() != "Xform") + prim = prim.GetParent(); + return prim.GetPath(); + } + return path; }; #else - // Do nothing if WANT_UFE_BUILD is disabled - auto pickUfePathPrim = false; + // Do nothing if WANT_UFE_BUILD is disabled + auto pickUfePathPrim = false; #endif - auto removeVariantFromPath = [&pickUfePathPrim] (const SdfPath& path) -> SdfPath { - std::string pathStr = path.GetText(); - - // I'm not entirely sure about this, but it would appear that the returned string here has the variant name - // tacked onto the end? - size_t dot_location = pathStr.find_last_of('.'); - if(dot_location != std::string::npos) { - pathStr = pathStr.substr(0, dot_location); - } - SdfPath resultPath(pathStr); + auto removeVariantFromPath = [&pickUfePathPrim] (const SdfPath& path) -> SdfPath + { + std::string pathStr = path.GetText(); + // I'm not entirely sure about this, but it would appear that the returned string here has the variant name + // tacked onto the end? + size_t dot_location = pathStr.find_last_of('.'); + if(dot_location != std::string::npos) + { + pathStr = pathStr.substr(0, dot_location); + } + #if defined(WANT_UFE_BUILD) - return pickUfePathPrim(resultPath); + SdfPath resultPath(pathStr); + return pickUfePathPrim(resultPath); #else - return resultPath; + return SdfPath(pathStr); #endif }; - auto getHitPath = [&engine, &removeVariantFromPath, &pickUfePathPrim] (const UsdImagingGLEngine::HitBatch::const_reference& it) -> SdfPath { - const UsdImagingGLEngine::HitInfo& hit = it.second; - auto path = engine->GetPrimPathFromInstanceIndex(it.first, hit.hitInstanceIndex); - if (!path.IsEmpty()) - { + auto getHitPath = [&engine, &removeVariantFromPath, &pickUfePathPrim] (const UsdImagingGLEngine::HitBatch::const_reference& it) -> SdfPath + { + const UsdImagingGLEngine::HitInfo& hit = it.second; + auto path = engine->GetPrimPathFromInstanceIndex(it.first, hit.hitInstanceIndex); + if (!path.IsEmpty()) + { #if defined(WANT_UFE_BUILD) - return pickUfePathPrim(path); + return pickUfePathPrim(path); #else - return path; + return path; #endif - } - return removeVariantFromPath(it.first); + } + return removeVariantFromPath(it.first); }; auto addSelection = [&hitBatch, &selectInfo, &selectionList, &worldSpaceSelectPoints, &objectsMask, &selected, proxyShape, - &removeVariantFromPath] (const MString& command) { - selected = true; - MStringArray nodes; - MGlobal::executeCommand(command, nodes, false, true); - - // If the selection is in a single selection mode, we don't know if your mesh - // will be the actual final selection, because we can't make sure this is going to - // be called the last. So we are returning a deferred command here, that'll run last. - // That'll check if the mesh is still selected, and run an internal deselect command on that. - const auto singleSelection = selectInfo.singleSelection(); - - uint32_t i = 0; - for(auto it = hitBatch.begin(), e = hitBatch.end(); it != e; ++it, ++i) + &removeVariantFromPath, &getHitPath] (const MString& command) + { + selected = true; + MStringArray nodes; + MGlobal::executeCommand(command, nodes, false, true); + + // If the selection is in a single selection mode, we don't know if your mesh + // will be the actual final selection, because we can't make sure this is going to + // be called the last. So we are returning a deferred command here, that'll run last. + // That'll check if the mesh is still selected, and run an internal deselect command on that. + // const auto singleSelection = selectInfo.singleSelection(); + + uint32_t i = 0; + for(auto it = hitBatch.begin(), e = hitBatch.end(); it != e; ++it, ++i) + { + auto obj = proxyShape->findRequiredPath(removeVariantFromPath(getHitPath(*it))); + if (obj != MObject::kNullObj) { - auto obj = proxyShape->findRequiredPath(removeVariantFromPath(it->first)); - if (obj != MObject::kNullObj) { - MSelectionList sl; - MFnDagNode dagNode(obj); - MDagPath dg; - dagNode.getPath(dg); - sl.add(dg); - const double* d = it->second.worldSpaceHitPoint.GetArray(); - selectInfo.addSelection(sl, MPoint(d[0], d[1], d[2], 1.0), selectionList, worldSpaceSelectPoints, objectsMask, false); - } + MSelectionList sl; + MFnDagNode dagNode(obj); + MDagPath dg; + dagNode.getPath(dg); + sl.add(dg); + const double* d = it->second.worldSpaceHitPoint.GetArray(); + selectInfo.addSelection(sl, MPoint(d[0], d[1], d[2], 1.0), selectionList, worldSpaceSelectPoints, objectsMask, false); } + } }; // Currently we have two approaches to selection. One method works with undo (but does not @@ -479,42 +484,52 @@ bool ProxyShapeUI::select(MSelectInfo& selectInfo, MSelectionList& selectionList mode = MGlobal::kXORWithList; SdfPathVector paths; - if (!hitBatch.empty()) { + if (!hitBatch.empty()) + { paths.reserve(hitBatch.size()); - auto addHit = [&engine, &paths, &getHitPath](const UsdImagingGLEngine::HitBatch::const_reference& it) { + auto addHit = [&engine, &paths, &getHitPath](UsdImagingGLEngine::HitBatch::const_reference& it) + { paths.push_back(getHitPath(it)); }; // Do to the inaccuracies in the selection method in gl engine // we still need to find the closest selection. // Around the edges it often selects two or more prims. - if (selectInfo.singleSelection()) { + if (selectInfo.singleSelection()) + { auto closestHit = hitBatch.cbegin(); - if (hitBatch.size() > 1) { + if (hitBatch.size() > 1) + { MDagPath cameraPath; selectInfo.view().getCamera(cameraPath); const auto cameraPoint = cameraPath.inclusiveMatrix() * MPoint(0.0, 0.0, 0.0, 1.0); - auto distanceToCameraSq = [&cameraPoint] (const UsdImagingGLEngine::HitBatch::const_reference& it) -> double { - const auto dx = cameraPoint.x - it.second.worldSpaceHitPoint[0]; - const auto dy = cameraPoint.y - it.second.worldSpaceHitPoint[1]; - const auto dz = cameraPoint.z - it.second.worldSpaceHitPoint[2]; - return dx * dx + dy * dy + dz * dz; + auto distanceToCameraSq = [&cameraPoint] (UsdImagingGLEngine::HitBatch::const_reference& it) -> double + { + const auto dx = cameraPoint.x - it.second.worldSpaceHitPoint[0]; + const auto dy = cameraPoint.y - it.second.worldSpaceHitPoint[1]; + const auto dz = cameraPoint.z - it.second.worldSpaceHitPoint[2]; + return dx * dx + dy * dy + dz * dz; }; auto closestDistance = distanceToCameraSq(*closestHit); - for (auto it = ++hitBatch.cbegin(), itEnd = hitBatch.cend(); it != itEnd; ++it) { + for (auto it = ++hitBatch.cbegin(), itEnd = hitBatch.cend(); it != itEnd; ++it) + { const auto currentDistance = distanceToCameraSq(*it); - if (currentDistance < closestDistance) { + if (currentDistance < closestDistance) + { closestDistance = currentDistance; closestHit = it; } } } addHit(*closestHit); - } else { - for (const auto& it : hitBatch) { + } + else + { + for (const auto& it : hitBatch) + { addHit(it); } } @@ -579,149 +594,153 @@ bool ProxyShapeUI::select(MSelectInfo& selectInfo, MSelectionList& selectionList } else { #endif - switch (mode) - { - case MGlobal::kReplaceList: + switch(mode) + { + case MGlobal::kReplaceList: + { + MString command; + if(!proxyShape->selectedPaths().empty()) { - MString command; - if (!proxyShape->selectedPaths().empty()) - { - command = "AL_usdmaya_ProxyShapeSelect -i -cl "; - MFnDependencyNode fn(proxyShape->thisMObject()); - command += " \""; - command += fn.name(); - command += "\";"; - } - - if (!paths.empty()) - { - command += "AL_usdmaya_ProxyShapeSelect -i -a "; - for (const auto& it : paths) - { - command += " -pp \""; - command += it.GetText(); - command += "\""; - } - MFnDependencyNode fn(proxyShape->thisMObject()); - command += " \""; - command += fn.name(); - command += "\""; + command = "AL_usdmaya_ProxyShapeSelect -i -cl "; + MFnDependencyNode fn(proxyShape->thisMObject()); + command += " \""; + command += fn.name(); + command += "\";"; + } - } + if(!paths.empty()) + { + command += "AL_usdmaya_ProxyShapeSelect -i -a "; + for(const auto& it : paths) + { + command += " -pp \""; + command += it.GetText(); + command += "\""; + } + MFnDependencyNode fn(proxyShape->thisMObject()); + command += " \""; + command += fn.name(); + command += "\""; - if (command.length() > 0) { - addSelection(command); - } } - break; - case MGlobal::kAddToHeadOfList: - case MGlobal::kAddToList: + if(command.length() > 0) { - MString command; - if (paths.size()) - { - command = "AL_usdmaya_ProxyShapeSelect -i -a "; - for (auto it : paths) - { - command += " -pp \""; - command += it.GetText(); - command += "\""; - } - MFnDependencyNode fn(proxyShape->thisMObject()); - command += " \""; - command += fn.name(); - command += "\""; - } + addSelection(command); + } + } + break; - if (command.length() > 0) { - selected = true; - addSelection(command); - } + case MGlobal::kAddToHeadOfList: + case MGlobal::kAddToList: + { + MString command; + if(paths.size()) + { + command = "AL_usdmaya_ProxyShapeSelect -i -a "; + for(auto it : paths) + { + command += " -pp \""; + command += it.GetText(); + command += "\""; + } + MFnDependencyNode fn(proxyShape->thisMObject()); + command += " \""; + command += fn.name(); + command += "\""; } - break; - case MGlobal::kRemoveFromList: + if(command.length() > 0) { - if (!proxyShape->selectedPaths().empty() && paths.size()) - { - MString command = "AL_usdmaya_ProxyShapeSelect -d "; - for (auto it : paths) - { - command += " -pp \""; - command += it.GetText(); - command += "\""; - } - MFnDependencyNode fn(proxyShape->thisMObject()); - command += " \""; - command += fn.name(); - command += "\""; - MGlobal::executeCommandOnIdle(command, false); - } + selected = true; + addSelection(command); } - break; + } + break; - case MGlobal::kXORWithList: + case MGlobal::kRemoveFromList: + { + if(!proxyShape->selectedPaths().empty() && paths.size()) { - auto& slpaths = proxyShape->selectedPaths(); - bool hasSelectedItems = false; - bool hasDeletedItems = false; + MString command = "AL_usdmaya_ProxyShapeSelect -d "; + for(auto it : paths) + { + command += " -pp \""; + command += it.GetText(); + command += "\""; + } + MFnDependencyNode fn(proxyShape->thisMObject()); + command += " \""; + command += fn.name(); + command += "\""; + MGlobal::executeCommandOnIdle(command, false); + } + } + break; - MString selectcommand = "AL_usdmaya_ProxyShapeSelect -i -a "; - MString deselectcommand = "AL_usdmaya_ProxyShapeSelect -d "; - for (auto it : paths) + case MGlobal::kXORWithList: + { + auto& slpaths = proxyShape->selectedPaths(); + bool hasSelectedItems = false; + bool hasDeletedItems = false; + + MString selectcommand = "AL_usdmaya_ProxyShapeSelect -i -a "; + MString deselectcommand = "AL_usdmaya_ProxyShapeSelect -d "; + for(auto it : paths) + { + bool flag = false; + for(auto sit : slpaths) + { + if(sit == it) { - bool flag = false; - for (auto sit : slpaths) - { - if (sit == it) - { - flag = true; - break; - } - } - if (flag) - { - deselectcommand += " -pp \""; - deselectcommand += it.GetText(); - deselectcommand += "\""; - hasDeletedItems = true; - } - else - { - selectcommand += " -pp \""; - selectcommand += it.GetText(); - selectcommand += "\""; - hasSelectedItems = true; - } + flag = true; + break; } - MFnDependencyNode fn(proxyShape->thisMObject()); - selectcommand += " \""; - selectcommand += fn.name(); - selectcommand += "\""; - deselectcommand += " \""; - deselectcommand += fn.name(); + } + if(flag) + { + deselectcommand += " -pp \""; + deselectcommand += it.GetText(); deselectcommand += "\""; - - if (hasSelectedItems) { - addSelection(selectcommand); - } - - if (hasDeletedItems) { - MGlobal::executeCommandOnIdle(deselectcommand, false); - } + hasDeletedItems = true; + } + else + { + selectcommand += " -pp \""; + selectcommand += it.GetText(); + selectcommand += "\""; + hasSelectedItems = true; + } + } + MFnDependencyNode fn(proxyShape->thisMObject()); + selectcommand += " \""; + selectcommand += fn.name(); + selectcommand += "\""; + deselectcommand += " \""; + deselectcommand += fn.name(); + deselectcommand += "\""; + + if(hasSelectedItems) + { + addSelection(selectcommand); } - break; + + if(hasDeletedItems) + { + MGlobal::executeCommandOnIdle(deselectcommand, false); } + } + break; + } - MString final_command = "AL_usdmaya_ProxyShapePostSelect \""; - MFnDependencyNode fn(proxyShape->thisMObject()); - final_command += fn.name(); - final_command += "\""; - proxyShape->setChangedSelectionState(true); - MGlobal::executeCommandOnIdle(final_command, false); + MString final_command = "AL_usdmaya_ProxyShapePostSelect \""; + MFnDependencyNode fn(proxyShape->thisMObject()); + final_command += fn.name(); + final_command += "\""; + proxyShape->setChangedSelectionState(true); + MGlobal::executeCommandOnIdle(final_command, false); #if defined(WANT_UFE_BUILD) - } // else MAYA_WANT_UFE_SELECTION + } // else MAYA_WANT_UFE_SELECTION #endif } diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/RendererManager.cpp b/lib/AL_USDMaya/AL/usdmaya/nodes/RendererManager.cpp new file mode 100644 index 00000000..e2d91ecf --- /dev/null +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/RendererManager.cpp @@ -0,0 +1,324 @@ +// +// Copyright 2017 Animal Logic +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License.// +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "AL/usdmaya/TypeIDs.h" +#include "AL/usdmaya/DebugCodes.h" +#include "AL/usdmaya/nodes/RendererManager.h" +#include "AL/usdmaya/nodes/ProxyShape.h" + +#include "pxr/usdImaging/usdImaging/version.h" +#if (USD_IMAGING_API_VERSION >= 7) + #include "pxr/usdImaging/usdImagingGL/gl.h" + #include "pxr/usdImaging/usdImagingGL/hdEngine.h" +#else + #include "pxr/usdImaging/usdImaging/gl.h" + #include "pxr/usdImaging/usdImaging/hdEngine.h" +#endif + +#include "maya/MGlobal.h" +#include "maya/MFnDependencyNode.h" +#include "maya/MItDependencyNodes.h" + +namespace { + + static std::mutex s_findNodeMutex; + +} + +namespace AL { +namespace usdmaya { +namespace nodes { + +RendererManager::~RendererManager() +{ + removeAttributeChangedCallback(); +} + +//---------------------------------------------------------------------------------------------------------------------- +AL_MAYA_DEFINE_NODE(RendererManager, AL_USDMAYA_RENDERERMANAGER, AL_usdmaya); + +MObject RendererManager::m_rendererPluginName = MObject::kNullObj; +MObject RendererManager::m_rendererPlugin = MObject::kNullObj; + +TfTokenVector RendererManager::m_rendererPluginsTokens; +MStringArray RendererManager::m_rendererPluginsNames; + +//---------------------------------------------------------------------------------------------------------------------- +MStatus RendererManager::initialise() +{ + TF_DEBUG(ALUSDMAYA_RENDERER).Msg("RendererManager::initialize\n"); + try + { + setNodeType(kTypeName); + addFrame("Renderer plugin"); + + // hydra renderer plugin discovery + // create dummy imaging engine to get renderer names + UsdImagingGL imagingEngine(SdfPath(), {}); + m_rendererPluginsTokens = imagingEngine.GetRendererPlugins(); + const size_t numTokens = m_rendererPluginsTokens.size(); + m_rendererPluginsNames = MStringArray(numTokens, MString()); + + // as it's not clear what is the lifetime of strings returned from HdEngine::GetRendererPluginDesc + // we store them in array to populate options menu items + std::vector pluginNames(numTokens); + std::vector enumNames(numTokens + 1, nullptr); + std::vector enumValues(numTokens, -1); + for (size_t i = 0; i < numTokens; ++i) + { + pluginNames[i] = imagingEngine.GetRendererPluginDesc(m_rendererPluginsTokens[i]); + m_rendererPluginsNames[i] = MString(pluginNames[i].data(), pluginNames[i].size()); + enumNames[i] = pluginNames[i].data(); + enumValues[i] = i; + } + + m_rendererPluginName = addStringAttr( + "rendererPluginName", "rpn", "GL", kCached | kReadable | kWritable | kStorable | kHidden); + m_rendererPlugin = addEnumAttr( + "rendererPlugin", "rp", kInternal | kReadable | kWritable, enumNames.data(), enumValues.data() + ); + + } + catch(const MStatus& status) + { + return status; + } + generateAETemplate(); + return MS::kSuccess; +} + +//---------------------------------------------------------------------------------------------------------------------- +MObject RendererManager::findNode() +{ + std::lock_guard lock(s_findNodeMutex); + return _findNode(); +} + +//---------------------------------------------------------------------------------------------------------------------- +MObject RendererManager::_findNode() +{ + MFnDependencyNode fn; + MItDependencyNodes iter(MFn::kPluginDependNode); + for(; !iter.isDone(); iter.next()) + { + MObject mobj = iter.item(); + fn.setObject(mobj); + if(fn.typeId() == kTypeId && !fn.isFromReferencedFile()) + { + return mobj; + } + } + return MObject::kNullObj; +} + +//---------------------------------------------------------------------------------------------------------------------- +MObject RendererManager::findOrCreateNode(MDGModifier* dgmod, bool* wasCreated) +{ + TF_DEBUG(ALUSDMAYA_RENDERER).Msg("RendererManager::findOrCreateNode\n"); + std::lock_guard lock(s_findNodeMutex); + MObject theManager = _findNode(); + + if (!theManager.isNull()) + { + if (wasCreated) *wasCreated = false; + return theManager; + } + + if (wasCreated) *wasCreated = true; + + if (dgmod) + { + return dgmod->createNode(kTypeId); + } + else + { + MDGModifier modifier; + MObject node = modifier.createNode(kTypeId); + modifier.doIt(); + return node; + } +} + +//---------------------------------------------------------------------------------------------------------------------- +RendererManager* RendererManager::findManager() +{ + MObject manager = findNode(); + if(manager.isNull()) + { + return nullptr; + } + return static_cast(MFnDependencyNode(manager).userNode()); +} + +//---------------------------------------------------------------------------------------------------------------------- +RendererManager* RendererManager::findOrCreateManager(MDGModifier* dgmod, bool* wasCreated) +{ + return static_cast(MFnDependencyNode(findOrCreateNode(dgmod, wasCreated)).userNode()); +} + + +//---------------------------------------------------------------------------------------------------------------------- +void RendererManager::onAttributeChanged(MNodeMessage::AttributeMessage msg, MPlug& plug, MPlug&, void* clientData) +{ + TF_DEBUG(ALUSDMAYA_RENDERER).Msg("RendererManager::onAttributeChanged\n"); + RendererManager* manager = static_cast(clientData); + assert(manager); + if(plug == m_rendererPluginName) + manager->onRendererChanged(); +} + +//---------------------------------------------------------------------------------------------------------------------- +void RendererManager::removeAttributeChangedCallback() +{ + TF_DEBUG(ALUSDMAYA_RENDERER).Msg("RendererManager::removeAttributeChangedCallback\n"); + if(m_attributeChanged != 0) + { + MMessage::removeCallback(m_attributeChanged); + m_attributeChanged = 0; + } +} + +//---------------------------------------------------------------------------------------------------------------------- +void RendererManager::addAttributeChangedCallback() +{ + TF_DEBUG(ALUSDMAYA_RENDERER).Msg("RendererManager::addAttributeChangedCallback\n"); + if(m_attributeChanged == 0) + { + MObject obj = thisMObject(); + m_attributeChanged = MNodeMessage::addAttributeChangedCallback(obj, onAttributeChanged, (void*)this); + } +} + +//---------------------------------------------------------------------------------------------------------------------- +void RendererManager::postConstructor() +{ + TF_DEBUG(ALUSDMAYA_RENDERER).Msg("RendererManager::postConstructor\n"); + addAttributeChangedCallback(); +} + +//---------------------------------------------------------------------------------------------------------------------- +bool RendererManager::setInternalValueInContext(const MPlug& plug, const MDataHandle& dataHandle, MDGContext& ctx) +{ + if (plug == m_rendererPlugin) + { + short index = dataHandle.asShort(); + if (index >= 0 && index < short(m_rendererPluginsNames.length())) + { + MPlug plug(thisMObject(), m_rendererPluginName); + plug.setString(m_rendererPluginsNames[index]); + return true; + } + } + return MPxNode::setInternalValueInContext(plug, dataHandle, ctx); +} + +//---------------------------------------------------------------------------------------------------------------------- +bool RendererManager::getInternalValueInContext(const MPlug& plug, MDataHandle& dataHandle, MDGContext& ctx) +{ + if (plug == m_rendererPlugin) + { + int index = getRendererPluginIndex(); + if (index >= 0) + { + dataHandle.set((short)index); + return true; + } + } + return MPxNode::getInternalValueInContext(plug, dataHandle, ctx); +} + +//---------------------------------------------------------------------------------------------------------------------- +void RendererManager::onRendererChanged() +{ + // Find all proxy shapes and change renderer plugin + MFnDependencyNode fn; + MItDependencyNodes iter(MFn::kPluginShape); + for(; !iter.isDone(); iter.next()) + { + fn.setObject(iter.item()); + if(fn.typeId() == ProxyShape::kTypeId) + { + ProxyShape* proxy = static_cast(fn.userNode()); + changeRendererPlugin(proxy); + } + } + //! We need to refresh viewport to changes take effect + MGlobal::executeCommandOnIdle("refresh -force"); +} + +//---------------------------------------------------------------------------------------------------------------------- +void RendererManager::changeRendererPlugin(ProxyShape* proxy, bool creation) +{ + TF_DEBUG(ALUSDMAYA_RENDERER).Msg("RendererManager::changeRendererPlugin\n"); + assert(proxy); + if (proxy->engine()) + { + int rendererId = getRendererPluginIndex(); + if (rendererId >= 0) + { + // Skip redundant renderer changes on ProxyShape creation + if (rendererId == 0 && creation) + return; + + assert(rendererId < m_rendererPluginsTokens.size()); + TfToken plugin = m_rendererPluginsTokens[rendererId]; + if (!proxy->engine()->SetRendererPlugin(plugin)) + { + MString data(plugin.data()); + MGlobal::displayError(MString("Failed to set renderer plugin: ") + data); + } + } + else + { + MPlug plug(thisMObject(), m_rendererPluginName); + MString pluginName = plug.asString(); + if (pluginName.length()) + MGlobal::displayError(MString("Invalid renderer plugin: ") + pluginName); + } + } +} + +//---------------------------------------------------------------------------------------------------------------------- +int RendererManager::getRendererPluginIndex() const +{ + MPlug plug(thisMObject(), m_rendererPluginName); + MString pluginName = plug.asString(); + return m_rendererPluginsNames.indexOf(pluginName); +} + +//---------------------------------------------------------------------------------------------------------------------- +bool RendererManager::setRendererPlugin(const MString& pluginName) +{ + int index = m_rendererPluginsNames.indexOf(pluginName); + if (index >= 0) + { + TF_DEBUG(ALUSDMAYA_RENDERER).Msg("RendererManager::setRendererPlugin\n"); + MPlug plug(thisMObject(), m_rendererPluginName); + plug.setString(pluginName); + return true; + } + else + { + TF_DEBUG(ALUSDMAYA_RENDERER).Msg("Failed to set renderer plugin!\n"); + MGlobal::displayError(MString("Failed to set renderer plugin: ") + pluginName); + } + return false; +} + +//---------------------------------------------------------------------------------------------------------------------- +} // nodes +} // usdmaya +} // AL +//---------------------------------------------------------------------------------------------------------------------- diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/RendererManager.h b/lib/AL_USDMaya/AL/usdmaya/nodes/RendererManager.h new file mode 100644 index 00000000..0b9549e6 --- /dev/null +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/RendererManager.h @@ -0,0 +1,143 @@ +// +// Copyright 2017 Animal Logic +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License.// +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#pragma once + +#include "../Api.h" + +#include "AL/maya/utils/NodeHelper.h" +#include "pxr/pxr.h" +#include "pxr/usd/usd/stage.h" + +#include "maya/MPxLocatorNode.h" +#include "maya/MNodeMessage.h" +#include "AL/maya/utils/MayaHelperMacros.h" + +#include + +PXR_NAMESPACE_USING_DIRECTIVE + +namespace AL { +namespace usdmaya { +namespace nodes { + +class ProxyShape; + + +//---------------------------------------------------------------------------------------------------------------------- +/// \brief The layer manager node handles serialization and deserialization of all layers used by all ProxyShapes +/// \ingroup nodes +//---------------------------------------------------------------------------------------------------------------------- +class RendererManager + : public MPxNode, + public AL::maya::utils::NodeHelper +{ +public: + + /// \brief ctor + inline RendererManager() + : MPxNode(), NodeHelper() {} + + ~RendererManager(); + + /// \brief Find the already-existing non-referenced RendererManager node in the scene, or return a null MObject + /// \return the found RendererManager node, or a null MObject + static MObject findNode(); + + /// \brief Either find the already-existing non-referenced RendererManager node in the scene, or make one + /// \param dgmod An optional dgmodifier to create the node, if necessary. Note that if one is passed in, + /// createNode might be called on it, but doIt never will be, so the layer manager node + /// may not be added to the scene graph yet + /// \param wasCreated If given, whether a new layer manager had to be created is stored here. + /// \return the found-or-created RendererManager node + static MObject findOrCreateNode(MDGModifier* dgmod=nullptr, bool* wasCreated=nullptr); + + /// \brief Find the already-existing non-referenced RendererManager node in the scene, or return a nullptr + /// \return the found RendererManager, or a nullptr + static RendererManager* findManager(); + + /// \brief Either find the already-existing non-referenced RendererManager in the scene, or make one + /// \param dgmod An optional dgmodifier to create the node, if necessary. Note that if one is passed in, + /// createNode might be called on it, but doIt never will be, so the layer manager node + /// may not be added to the scene graph yet + /// \param wasCreated If given, whether a new layer manager had to be created is stored here. + /// \return the found-or-created RendererManager + static RendererManager* findOrCreateManager(MDGModifier* dgmod=nullptr, bool* wasCreated=nullptr); + + //-------------------------------------------------------------------------------------------------------------------- + /// Methods to handle renderer plugin + //-------------------------------------------------------------------------------------------------------------------- + + /// \brief Set current renderer for all proxy shapes + void onRendererChanged(); + + /// \brief Set current renderer plugin based on provided name + bool setRendererPlugin(const MString& pluginName); + + /// \brief Change current renderer plugin for provided ProxyShape + void changeRendererPlugin(ProxyShape* proxy, bool creation=false); + + /// \brief Get current renderer plugin index + int getRendererPluginIndex() const; + + /// \brief Get list of available Hydra renderer plugin names + static const MStringArray& getRendererPluginList() { return m_rendererPluginsNames; } + + //-------------------------------------------------------------------------------------------------------------------- + /// Type Info & Registration + //-------------------------------------------------------------------------------------------------------------------- + AL_MAYA_DECLARE_NODE(); + + //-------------------------------------------------------------------------------------------------------------------- + /// Type Info & Registration + //-------------------------------------------------------------------------------------------------------------------- + + /// Hydra renderer plugin name used for rendering (storable) + AL_DECL_ATTRIBUTE(rendererPluginName); + /// Hydra renderer plugin index used for UI (internal) + AL_DECL_ATTRIBUTE(rendererPlugin); + +private: + static MObject _findNode(); + static void onAttributeChanged(MNodeMessage::AttributeMessage, MPlug&, MPlug&, void*); + + /// \brief adds the attribute changed callback to manager + void addAttributeChangedCallback(); + + /// \brief removes the attribute changed callback from manager + void removeAttributeChangedCallback(); + + MCallbackId m_attributeChanged = 0; + + static TfTokenVector m_rendererPluginsTokens; + static MStringArray m_rendererPluginsNames; + + //-------------------------------------------------------------------------------------------------------------------- + /// MPxNode overrides + //-------------------------------------------------------------------------------------------------------------------- + + void postConstructor() override; + + bool setInternalValueInContext(const MPlug& plug, const MDataHandle& dataHandle, MDGContext& ctx) override; + + bool getInternalValueInContext(const MPlug& plug, MDataHandle& dataHandle, MDGContext& ctx) override; + +}; + +} // nodes +} // usdmaya +} // AL +//---------------------------------------------------------------------------------------------------------------------- + diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/Transform.cpp b/lib/AL_USDMaya/AL/usdmaya/nodes/Transform.cpp index 0cf00c39..ea0e592a 100644 --- a/lib/AL_USDMaya/AL/usdmaya/nodes/Transform.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/Transform.cpp @@ -281,7 +281,6 @@ MStatus Transform::validateAndSetValue(const MPlug& plug, const MDataHandle& han // If the time values are changed, store the new values, and then update the transform if (plug == m_time || plug == m_timeOffset || plug == m_timeScalar) { - MStatus status = MS::kSuccess; MDataBlock dataBlock = forceCache(*(MDGContext *)&context); if(plug == m_time) { @@ -366,11 +365,11 @@ MStatus Transform::validateAndSetValue(const MPlug& plug, const MDataHandle& han primPath = SdfPath(path.asChar()); usdPrim = data->stage->GetPrimAtPath(primPath); } - transform()->setPrim(usdPrim); + transform()->setPrim(usdPrim, this); } else { - transform()->setPrim(UsdPrim()); + transform()->setPrim(UsdPrim(), this); } return MS::kSuccess; } @@ -391,7 +390,7 @@ MStatus Transform::validateAndSetValue(const MPlug& plug, const MDataHandle& han primPath = SdfPath(path.asChar()); usdPrim = UsdPrim(data->stage->GetPrimAtPath(primPath)); } - transform()->setPrim(usdPrim); + transform()->setPrim(usdPrim, this); if(usdPrim) updateTransform(dataBlock); } @@ -402,7 +401,7 @@ MStatus Transform::validateAndSetValue(const MPlug& plug, const MDataHandle& han TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("Could not set '%s' to '%s' - could not retrieve stage\n", plug.name().asChar(), path.asChar()); } - transform()->setPrim(UsdPrim()); + transform()->setPrim(UsdPrim(), this); } return MS::kSuccess; } diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/TransformationMatrix.cpp b/lib/AL_USDMaya/AL/usdmaya/nodes/TransformationMatrix.cpp index 90d6be1f..5205e47f 100644 --- a/lib/AL_USDMaya/AL/usdmaya/nodes/TransformationMatrix.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/TransformationMatrix.cpp @@ -14,13 +14,13 @@ // limitations under the License. // #include "AL/maya/utils/CommandGuiHelper.h" -#include "AL/usdmaya/AttributeType.h" #include "AL/usdmaya/TypeIDs.h" #include "AL/usdmaya/DebugCodes.h" #include "AL/usdmaya/nodes/Transform.h" #include "AL/usdmaya/nodes/TransformationMatrix.h" #include "maya/MFileIO.h" +#include "AL/usdmaya/utils/AttributeType.h" #include "AL/usdmaya/utils/Utils.h" PXR_NAMESPACE_USING_DIRECTIVE @@ -29,6 +29,8 @@ namespace AL { namespace usdmaya { namespace nodes { +using AL::usdmaya::utils::UsdDataType; + //---------------------------------------------------------------------------------------------------------------------- const MTypeId TransformationMatrix::kTypeId(AL_USDMAYA_TRANSFORMATION_MATRIX); @@ -101,7 +103,7 @@ TransformationMatrix::TransformationMatrix(const UsdPrim& prim) } //---------------------------------------------------------------------------------------------------------------------- -void TransformationMatrix::setPrim(const UsdPrim& prim) +void TransformationMatrix::setPrim(const UsdPrim& prim, Transform* transformNode) { if(prim.IsValid()) { @@ -143,11 +145,7 @@ void TransformationMatrix::setPrim(const UsdPrim& prim) m_rotatePivotFromUsd = MPoint(0, 0, 0); m_rotatePivotTranslationFromUsd = MVector(0, 0, 0); m_rotateOrientationFromUsd = MQuaternion(0, 0, 0, 1.0); - //if(MFileIO::isReadingFile()) - { - initialiseToPrim(!MFileIO::isReadingFile()); - } - + initialiseToPrim(!MFileIO::isReadingFile(), transformNode); MPxTransformationMatrix::scaleValue = m_scaleFromUsd; MPxTransformationMatrix::rotationValue = m_rotationFromUsd; MPxTransformationMatrix::translationValue = m_translationFromUsd; @@ -165,7 +163,7 @@ bool TransformationMatrix::readVector(MVector& result, const UsdGeomXformOp& op, { TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("TransformationMatrix::readVector\n"); const SdfValueTypeName vtn = op.GetTypeName(); - UsdDataType attr_type = getAttributeType(vtn); + UsdDataType attr_type = AL::usdmaya::utils::getAttributeType(vtn); switch(attr_type) { case UsdDataType::kVec3d: @@ -237,35 +235,47 @@ bool TransformationMatrix::pushVector(const MVector& result, UsdGeomXformOp& op, { TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("TransformationMatrix::pushVector %f %f %f\n%s\n", result.x, result.y, result.z, op.GetOpName().GetText()); const SdfValueTypeName vtn = op.GetTypeName(); - UsdDataType attr_type = getAttributeType(vtn); + UsdDataType attr_type = AL::usdmaya::utils::getAttributeType(vtn); switch(attr_type) { case UsdDataType::kVec3d: { GfVec3d value(result.x, result.y, result.z); - op.Set(value, timeCode); + GfVec3d oldValue; + op.Get(&oldValue, timeCode); + if(value != oldValue) + op.Set(value, timeCode); } break; case UsdDataType::kVec3f: { GfVec3f value(result.x, result.y, result.z); - op.Set(value, timeCode); + GfVec3f oldValue; + op.Get(&oldValue, timeCode); + if(value != oldValue) + op.Set(value, timeCode); } break; case UsdDataType::kVec3h: { GfVec3h value(result.x, result.y, result.z); - op.Set(value, timeCode); + GfVec3h oldValue; + op.Get(&oldValue, timeCode); + if(value != oldValue) + op.Set(value, timeCode); } break; case UsdDataType::kVec3i: { GfVec3i value(result.x, result.y, result.z); - op.Set(value, timeCode); + GfVec3i oldValue; + op.Get(&oldValue, timeCode); + if(value != oldValue) + op.Set(value, timeCode); } break; @@ -281,7 +291,7 @@ bool TransformationMatrix::pushShear(const MVector& result, UsdGeomXformOp& op, { TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("TransformationMatrix::pushShear %f %f %f\n%s\n", result.x, result.y, result.z, op.GetOpName().GetText()); const SdfValueTypeName vtn = op.GetTypeName(); - UsdDataType attr_type = getAttributeType(vtn); + UsdDataType attr_type = AL::usdmaya::utils::getAttributeType(vtn); switch(attr_type) { case UsdDataType::kMatrix4d: @@ -291,7 +301,10 @@ bool TransformationMatrix::pushShear(const MVector& result, UsdGeomXformOp& op, result.x, 1.0, 0.0, 0.0, result.y, result.z, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); - op.Set(m, timeCode); + GfMatrix4d oldValue; + op.Get(&oldValue, timeCode); + if(m != oldValue) + op.Set(m, timeCode); } break; @@ -306,7 +319,7 @@ bool TransformationMatrix::readShear(MVector& result, const UsdGeomXformOp& op, { TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("TransformationMatrix::readShear\n"); const SdfValueTypeName vtn = op.GetTypeName(); - UsdDataType attr_type = getAttributeType(vtn); + UsdDataType attr_type = AL::usdmaya::utils::getAttributeType(vtn); switch(attr_type) { case UsdDataType::kMatrix4d: @@ -335,7 +348,7 @@ bool TransformationMatrix::readPoint(MPoint& result, const UsdGeomXformOp& op, U { TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("TransformationMatrix::readPoint\n"); const SdfValueTypeName vtn = op.GetTypeName(); - UsdDataType attr_type = getAttributeType(vtn); + UsdDataType attr_type = AL::usdmaya::utils::getAttributeType(vtn); switch(attr_type) { case UsdDataType::kVec3d: @@ -407,7 +420,7 @@ bool TransformationMatrix::readMatrix(MMatrix& result, const UsdGeomXformOp& op, { TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("TransformationMatrix::readMatrix\n"); const SdfValueTypeName vtn = op.GetTypeName(); - UsdDataType attr_type = getAttributeType(vtn); + UsdDataType attr_type = AL::usdmaya::utils::getAttributeType(vtn); switch(attr_type) { case UsdDataType::kMatrix4d: @@ -418,7 +431,9 @@ bool TransformationMatrix::readMatrix(MMatrix& result, const UsdGeomXformOp& op, { return false; } - result = *(const MMatrix*)(&value); + auto vtemp = (const void*)&value; + auto mtemp = (const MMatrix*)vtemp; + result = *mtemp; } break; @@ -434,16 +449,21 @@ bool TransformationMatrix::pushMatrix(const MMatrix& result, UsdGeomXformOp& op, { TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("TransformationMatrix::pushMatrix\n"); const SdfValueTypeName vtn = op.GetTypeName(); - UsdDataType attr_type = getAttributeType(vtn); + UsdDataType attr_type = AL::usdmaya::utils::getAttributeType(vtn); switch(attr_type) { case UsdDataType::kMatrix4d: { - GfMatrix4d value = *(const GfMatrix4d*)(&result); - const bool retValue = op.Set(value, timeCode); - if (!retValue) + const GfMatrix4d& value = *(const GfMatrix4d*)(&result); + GfMatrix4d oldValue; + op.Get(&oldValue, timeCode); + if(value != oldValue) { - return false; + const bool retValue = op.Set(value, timeCode); + if (!retValue) + { + return false; + } } } break; @@ -460,34 +480,46 @@ bool TransformationMatrix::pushPoint(const MPoint& result, UsdGeomXformOp& op, U { TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("TransformationMatrix::pushPoint %f %f %f\n%s\n", result.x, result.y, result.z, op.GetOpName().GetText()); const SdfValueTypeName vtn = op.GetTypeName(); - UsdDataType attr_type = getAttributeType(vtn); + UsdDataType attr_type = AL::usdmaya::utils::getAttributeType(vtn); switch(attr_type) { case UsdDataType::kVec3d: { GfVec3d value(result.x, result.y, result.z); - op.Set(value, timeCode); + GfVec3d oldValue; + op.Get(&oldValue, timeCode); + if(value != oldValue) + op.Set(value, timeCode); } break; case UsdDataType::kVec3f: { GfVec3f value(result.x, result.y, result.z); - op.Set(value, timeCode); + GfVec3f oldValue; + op.Get(&oldValue, timeCode); + if(value != oldValue) + op.Set(value, timeCode); } break; case UsdDataType::kVec3h: { GfVec3h value(result.x, result.y, result.z); - op.Set(value, timeCode); + GfVec3h oldValue; + op.Get(&oldValue, timeCode); + if(value != oldValue) + op.Set(value, timeCode); } break; case UsdDataType::kVec3i: { GfVec3i value(result.x, result.y, result.z); - op.Set(value, timeCode); + GfVec3i oldValue; + op.Get(&oldValue, timeCode); + if(value != oldValue) + op.Set(value, timeCode); } break; @@ -503,7 +535,7 @@ double TransformationMatrix::readDouble(const UsdGeomXformOp& op, UsdTimeCode ti { TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("TransformationMatrix::readDouble\n"); double result = 0; - UsdDataType attr_type = getAttributeType(op.GetTypeName()); + UsdDataType attr_type = AL::usdmaya::utils::getAttributeType(op.GetTypeName()); switch(attr_type) { case UsdDataType::kHalf: @@ -561,30 +593,42 @@ double TransformationMatrix::readDouble(const UsdGeomXformOp& op, UsdTimeCode ti void TransformationMatrix::pushDouble(const double value, UsdGeomXformOp& op, UsdTimeCode timeCode) { TF_DEBUG(ALUSDMAYA_EVALUATION).Msg("TransformationMatrix::pushDouble %f\n%s\n", value, op.GetOpName().GetText()); - UsdDataType attr_type = getAttributeType(op.GetTypeName()); + UsdDataType attr_type = AL::usdmaya::utils::getAttributeType(op.GetTypeName()); switch(attr_type) { case UsdDataType::kHalf: { - op.Set(GfHalf(value), timeCode); + GfHalf oldValue; + op.Get(&oldValue); + if(oldValue != GfHalf(value)) + op.Set(GfHalf(value), timeCode); } break; case UsdDataType::kFloat: { - op.Set(float(value), timeCode); + float oldValue; + op.Get(&oldValue); + if(oldValue != float(value)) + op.Set(float(value), timeCode); } break; case UsdDataType::kDouble: { - op.Set(double(value), timeCode); + double oldValue; + op.Get(&oldValue); + if(oldValue != double(value)) + op.Set(double(value), timeCode); } break; case UsdDataType::kInt: { - op.Set(int32_t(value), timeCode); + int32_t oldValue; + op.Get(&oldValue); + if(oldValue != int32_t(value)) + op.Set(int32_t(value), timeCode); } break; @@ -804,7 +848,8 @@ void TransformationMatrix::initialiseToPrim(bool readFromPrim, Transform* transf { m_flags |= kAnimatedTranslation; } - if(readFromPrim) { + if(readFromPrim) + { internal_readVector(m_translationFromUsd, op); if(transformNode) { @@ -819,7 +864,8 @@ void TransformationMatrix::initialiseToPrim(bool readFromPrim, Transform* transf case kPivot: { m_flags |= kPrimHasPivot; - if(readFromPrim) { + if(readFromPrim) + { internal_readPoint(m_scalePivotFromUsd, op); m_rotatePivotFromUsd = m_scalePivotFromUsd; if(transformNode) @@ -913,7 +959,8 @@ void TransformationMatrix::initialiseToPrim(bool readFromPrim, Transform* transf case kScalePivotTranslate: { m_flags |= kPrimHasScalePivotTranslate; - if(readFromPrim) { + if(readFromPrim) + { internal_readVector(m_scalePivotTranslationFromUsd, op); if(transformNode) { @@ -928,7 +975,8 @@ void TransformationMatrix::initialiseToPrim(bool readFromPrim, Transform* transf case kScalePivot: { m_flags |= kPrimHasScalePivot; - if(readFromPrim) { + if(readFromPrim) + { internal_readPoint(m_scalePivotFromUsd, op); if(transformNode) { @@ -947,7 +995,8 @@ void TransformationMatrix::initialiseToPrim(bool readFromPrim, Transform* transf { m_flags |= kAnimatedShear; } - if(readFromPrim) { + if(readFromPrim) + { internal_readShear(m_shearFromUsd, op); if(transformNode) { @@ -966,7 +1015,8 @@ void TransformationMatrix::initialiseToPrim(bool readFromPrim, Transform* transf { m_flags |= kAnimatedScale; } - if(readFromPrim) { + if(readFromPrim) + { internal_readVector(m_scaleFromUsd, op); if(transformNode) { @@ -998,7 +1048,8 @@ void TransformationMatrix::initialiseToPrim(bool readFromPrim, Transform* transf m_flags |= kAnimatedMatrix; } - if(readFromPrim) { + if(readFromPrim) + { MMatrix m; internal_readMatrix(m, op); decomposeMatrix(m); @@ -1876,7 +1927,9 @@ void TransformationMatrix::pushToPrim() if(pushPrimToMatrix()) { MMatrix m = MPxTransformationMatrix::asMatrix(); - op.Set(*(const GfMatrix4d*)&m, getTimeCode()); + auto vtemp = (const void*)&m; + auto mtemp = (const GfMatrix4d*)vtemp; + op.Set(*mtemp, getTimeCode()); } } break; @@ -1989,7 +2042,9 @@ void TransformationMatrix::enableReadAnimatedValues(bool enabled) if(m_orderedOps[i] == kTransform) { MMatrix m = MPxTransformationMatrix::asMatrix(); - m_xformops[i].Set(*(const GfMatrix4d*)&m, getTimeCode()); + auto vtemp = (const void*)&m; + auto mtemp = (const GfMatrix4d*)vtemp; + m_xformops[i].Set(*mtemp, getTimeCode()); break; } } @@ -2051,7 +2106,9 @@ void TransformationMatrix::enablePushToPrim(bool enabled) if(m_orderedOps[i] == kTransform) { MMatrix m = MPxTransformationMatrix::asMatrix(); - m_xformops[i].Set(*(const GfMatrix4d*)&m, getTimeCode()); + auto vtemp = (const void*)&m; + auto mtemp = (const GfMatrix4d*)vtemp; + m_xformops[i].Set(*mtemp, getTimeCode()); break; } } diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/TransformationMatrix.h b/lib/AL_USDMaya/AL/usdmaya/nodes/TransformationMatrix.h index 08d2d778..207be1cf 100644 --- a/lib/AL_USDMaya/AL/usdmaya/nodes/TransformationMatrix.h +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/TransformationMatrix.h @@ -184,41 +184,41 @@ class TransformationMatrix /// \param op the transformation op to read from /// \param timeCode the time at which to query the transform value /// return true if read ok - static bool readVector(MVector& result, const UsdGeomXformOp& op, UsdTimeCode timeCode = UsdTimeCode::Default()); + static bool readVector(MVector& result, const UsdGeomXformOp& op, UsdTimeCode timeCode = UsdTimeCode::EarliestTime()); /// \brief helper method. Reads a shear value from the transform op specified at the requested timecode /// \param result the returned result /// \param op the transformation op to read from /// \param timeCode the time at which to query the transform value /// return true if read ok - static bool readShear(MVector& result, const UsdGeomXformOp& op, UsdTimeCode timeCode = UsdTimeCode::Default()); + static bool readShear(MVector& result, const UsdGeomXformOp& op, UsdTimeCode timeCode = UsdTimeCode::EarliestTime()); /// \brief helper method. Reads a point from the transform op specified at the requested timecode /// \param result the returned result /// \param op the transformation op to read from /// \param timeCode the time at which to query the transform value /// return true if read ok - static bool readPoint(MPoint& result, const UsdGeomXformOp& op, UsdTimeCode timeCode = UsdTimeCode::Default()); + static bool readPoint(MPoint& result, const UsdGeomXformOp& op, UsdTimeCode timeCode = UsdTimeCode::EarliestTime()); /// \brief helper method. Reads an euler rotation from the transform op specified at the requested timecode /// \param result the returned result /// \param op the transformation op to read from /// \param timeCode the time at which to query the transform value /// return true if read ok - static bool readRotation(MEulerRotation& result, const UsdGeomXformOp& op, UsdTimeCode timeCode = UsdTimeCode::Default()); + static bool readRotation(MEulerRotation& result, const UsdGeomXformOp& op, UsdTimeCode timeCode = UsdTimeCode::EarliestTime()); /// \brief helper method. Reads a double from the transform op specified at the requested timecode (typically RotateX / rotateY values) /// \param op the transformation op to read from /// \param timeCode the time at which to query the transform value /// return the returned value - static double readDouble(const UsdGeomXformOp& op, UsdTimeCode timeCode = UsdTimeCode::Default()); + static double readDouble(const UsdGeomXformOp& op, UsdTimeCode timeCode = UsdTimeCode::EarliestTime()); /// \brief helper method. Reads a matrix from the transform op specified at the requested timecode /// \param result the returned result /// \param op the transformation op to read from /// \param timeCode the time at which to query the transform value /// return true if read ok - static bool readMatrix(MMatrix& result, const UsdGeomXformOp& op, UsdTimeCode timeCode = UsdTimeCode::Default()); + static bool readMatrix(MMatrix& result, const UsdGeomXformOp& op, UsdTimeCode timeCode = UsdTimeCode::EarliestTime()); /// \brief helper method. Pushes a vector into the transform op specified at the requested timecode /// \param input the new value to insert into the transform operation @@ -280,7 +280,7 @@ class TransformationMatrix /// \brief set the prim that this transformation matrix will read/write to. /// \param prim the prim - void setPrim(const UsdPrim& prim); + void setPrim(const UsdPrim& prim, Transform* transformNode); /// \brief If set to true, modifications to these transform attributes will be pushed back onto the original prim. /// \param enabled true will cause changes to this transform update the values on the USD prim. False will mean that diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/proxy/DrivenTransforms.cpp b/lib/AL_USDMaya/AL/usdmaya/nodes/proxy/DrivenTransforms.cpp index c53a5f7d..3d3c2763 100644 --- a/lib/AL_USDMaya/AL/usdmaya/nodes/proxy/DrivenTransforms.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/proxy/DrivenTransforms.cpp @@ -21,7 +21,7 @@ void DrivenTransforms::updateDrivenTransforms(std::vector& drivenPrims, { for (uint32_t i = 0, cnt = m_dirtyMatrices.size(); i < cnt; ++i) { - int32_t idx = m_dirtyMatrices[i]; + uint32_t idx = uint32_t(m_dirtyMatrices[i]); // [RB] This seems redundant? Why not just prevent invalid data from entering the structure? if (idx >= drivenPrims.size()) { @@ -77,7 +77,7 @@ void DrivenTransforms::updateDrivenVisibility(std::vector& drivenPrims, { for (uint32_t i = 0, cnt = m_dirtyVisibilities.size(); i < cnt; ++i) { - int32_t idx = m_dirtyVisibilities[i]; + uint32_t idx = uint32_t(m_dirtyVisibilities[i]); // [RB] This seems redundant? Why not just prevent invalid data from entering the structure? if (idx >= drivenPrims.size()) { diff --git a/lib/AL_USDMaya/AL/usdmaya/nodes/wrapProxyShape.cpp b/lib/AL_USDMaya/AL/usdmaya/nodes/wrapProxyShape.cpp index 44aa147d..a8865bca 100644 --- a/lib/AL_USDMaya/AL/usdmaya/nodes/wrapProxyShape.cpp +++ b/lib/AL_USDMaya/AL/usdmaya/nodes/wrapProxyShape.cpp @@ -183,7 +183,7 @@ namespace { { return nullptr; } - for (int i = 0; i < numShapes; ++i) + for (uint32_t i = 0; i < numShapes; ++i) { dag.extendToShapeDirectlyBelow(i); if (isProxyShape(dag.node())) diff --git a/lib/AL_USDMaya/CMakeLists.txt b/lib/AL_USDMaya/CMakeLists.txt index 30a57889..c0caa7d2 100644 --- a/lib/AL_USDMaya/CMakeLists.txt +++ b/lib/AL_USDMaya/CMakeLists.txt @@ -4,7 +4,6 @@ set(LIBRARY_NAME AL_USDMaya) list(APPEND AL_usdmaya_headers AL/usdmaya/Api.h - AL/usdmaya/AttributeType.h AL/usdmaya/DebugCodes.h AL/usdmaya/DrivenTransformsData.h AL/usdmaya/Metadata.h @@ -19,7 +18,6 @@ list(APPEND AL_usdmaya_headers ) list(APPEND AL_usdmaya_source - AL/usdmaya/AttributeType.cpp AL/usdmaya/DebugCodes.cpp AL/usdmaya/DrivenTransformsData.cpp AL/usdmaya/Global.cpp @@ -33,21 +31,25 @@ list(APPEND AL_usdmaya_source ) list(APPEND AL_usdmaya_cmds_headers + AL/usdmaya/cmds/CreateUsdPrim.h AL/usdmaya/cmds/DebugCommands.h AL/usdmaya/cmds/EventCommand.h AL/usdmaya/cmds/LayerCommands.h AL/usdmaya/cmds/ProxyShapeCommands.h AL/usdmaya/cmds/ProxyShapeSelectCommands.h AL/usdmaya/cmds/ProxyShapePostLoadProcess.h + AL/usdmaya/cmds/RendererCommands.h AL/usdmaya/cmds/UnloadPrim.h ) list(APPEND AL_usdmaya_cmds_source + AL/usdmaya/cmds/CreateUsdPrim.cpp AL/usdmaya/cmds/DebugCommands.cpp AL/usdmaya/cmds/EventCommand.cpp AL/usdmaya/cmds/LayerCommands.cpp AL/usdmaya/cmds/ProxyShapeCommands.cpp AL/usdmaya/cmds/ProxyShapeSelectCommands.cpp AL/usdmaya/cmds/ProxyShapePostLoadProcess.cpp + AL/usdmaya/cmds/RendererCommands.cpp AL/usdmaya/cmds/UnloadPrim.cpp ) @@ -106,6 +108,7 @@ list(APPEND AL_usdmaya_nodes_headers AL/usdmaya/nodes/ProxyDrawOverride.h AL/usdmaya/nodes/ProxyShape.h AL/usdmaya/nodes/ProxyShapeUI.h + AL/usdmaya/nodes/RendererManager.h AL/usdmaya/nodes/Transform.h AL/usdmaya/nodes/TransformationMatrix.h ) @@ -120,6 +123,7 @@ list(APPEND AL_usdmaya_nodes_source AL/usdmaya/nodes/ProxyShape.cpp AL/usdmaya/nodes/ProxyShapeSelection.cpp AL/usdmaya/nodes/ProxyShapeUI.cpp + AL/usdmaya/nodes/RendererManager.cpp AL/usdmaya/nodes/Transform.cpp AL/usdmaya/nodes/TransformationMatrix.cpp AL/usdmaya/nodes/proxy/DrivenTransforms.cpp @@ -169,6 +173,7 @@ set(Boost_LINK_LIBRARIES if(WIN32) list(APPEND Boost_LINK_LIBRARIES ${Boost_CHRONO_LIBRARY} + ${Boost_DATE_TIME_LIBRARY} ) endif() @@ -246,8 +251,15 @@ target_link_libraries(${PYTHON_LIBRARY_NAME} ${LIBRARY_NAME} ) -# bake plugInfo.json using pxr macro -_plugInfo_subst(${LIBRARY_NAME} plugInfo.json) +set(libFile ${CMAKE_SHARED_LIBRARY_PREFIX}${libName}${CMAKE_SHARED_LIBRARY_SUFFIX}) +set(PLUG_INFO_RESOURCE_PATH "resources") +set(PLUG_INFO_ROOT "..") +set(PLUG_INFO_PLUGIN_NAME "pxr.${LIBRARY_NAME}") +set(PLUG_INFO_LIBRARY_PATH "../../../../lib/${libFile}") +configure_file( + plugInfo.json + ${CMAKE_CURRENT_BINARY_DIR}/plugInfo.json +) install(TARGETS ${PYTHON_LIBRARY_NAME} LIBRARY diff --git a/mayautils/AL/maya/CMakeLists.txt b/mayautils/AL/maya/CMakeLists.txt index 3cdc5bfe..bac6a0b0 100755 --- a/mayautils/AL/maya/CMakeLists.txt +++ b/mayautils/AL/maya/CMakeLists.txt @@ -82,4 +82,6 @@ install(TARGETS ${MAYAUTILS_LIBRARY_NAME} DESTINATION ${MAYAUTILS_LIBRARY_LOCATION} ) -add_subdirectory(tests) +if(NOT SKIP_USDMAYA_TESTS) + add_subdirectory(tests) +endif() diff --git a/mayautils/AL/maya/event/MayaEventManager.cpp b/mayautils/AL/maya/event/MayaEventManager.cpp index 3a5728ed..262de772 100644 --- a/mayautils/AL/maya/event/MayaEventManager.cpp +++ b/mayautils/AL/maya/event/MayaEventManager.cpp @@ -56,12 +56,15 @@ static void bindBasicFunction(void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindElapsedTimeFunction(float elapsed, float last, void* ptr) +static void bindCheckFunction(bool* retCode, void* ptr) { - auto binder = [elapsed, last](void* ud, const void* cb) + bool result = true; + auto binder = [&result](void* ud, const void* cb) { - MMessage::MElapsedTimeFunction cf = (MMessage::MElapsedTimeFunction)cb; - cf(elapsed, last, ud); + MMessage::MCheckFunction cf = (MMessage::MCheckFunction)cb; + bool temp = true; + cf(&temp, ud); + result = result && temp; }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -70,14 +73,14 @@ static void bindElapsedTimeFunction(float elapsed, float last, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindCheckFunction(bool* retCode, void* ptr) +static void bindCheckPlugFunction(bool* retCode, MPlug& plug, void* ptr) { bool result = true; - auto binder = [&result](void* ud, const void* cb) + auto binder = [&result, &plug](void* ud, const void* cb) { - MMessage::MCheckFunction cf = (MMessage::MCheckFunction)cb; + MMessage::MCheckPlugFunction cf = (MMessage::MCheckPlugFunction)cb; bool temp = true; - cf(&temp, ud); + cf(&temp, plug, ud); result = result && temp; }; @@ -87,15 +90,12 @@ static void bindCheckFunction(bool* retCode, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindCheckFileFunction(bool* retCode, MFileObject& obj, void* ptr) +static void bindNodeFunction(MObject& node, void* ptr) { - bool result = true; - auto binder = [&result, &obj](void* ud, const void* cb) + auto binder = [&node](void* ud, const void* cb) { - MMessage::MCheckFileFunction cf = (MMessage::MCheckFileFunction)cb; - bool temp = true; - cf(&temp, obj, ud); - result = result && temp; + MMessage::MNodeFunction cf = (MMessage::MNodeFunction)cb; + cf(node, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -104,15 +104,12 @@ static void bindCheckFileFunction(bool* retCode, MFileObject& obj, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindCheckPlugFunction(bool* retCode, MPlug& plug, void* ptr) +static void bindStringFunction(const MString& str, void* ptr) { - bool result = true; - auto binder = [&result, &plug](void* ud, const void* cb) + auto binder = [str](void* ud, const void* cb) { - MMessage::MCheckPlugFunction cf = (MMessage::MCheckPlugFunction)cb; - bool temp = true; - cf(&temp, plug, ud); - result = result && temp; + MMessage::MStringFunction cf = (MMessage::MStringFunction)cb; + cf(str, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -121,12 +118,12 @@ static void bindCheckPlugFunction(bool* retCode, MPlug& plug, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindComponentFunction(MUintArray componentIds[], unsigned int count, void* ptr) +static void bindStringIntBoolIntFunction(const MString& str, uint32_t index, bool flag, uint32_t type, void* ptr) { - auto binder = [componentIds, count](void* ud, const void* cb) + auto binder = [str, index, flag, type](void* ud, const void* cb) { - MMessage::MComponentFunction cf = (MMessage::MComponentFunction)cb; - cf(componentIds, count, ud); + MMessage::MStringIntBoolIntFunction cf = (MMessage::MStringIntBoolIntFunction)cb; + cf(str, index, flag, type, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -135,12 +132,12 @@ static void bindComponentFunction(MUintArray componentIds[], unsigned int count, } //---------------------------------------------------------------------------------------------------------------------- -static void bindNodeFunction(MObject& node, void* ptr) +static void bindNodeStringBoolFunction(MObject& node, const MString& str, bool flag, void* ptr) { - auto binder = [&node](void* ud, const void* cb) + auto binder = [&node, str, flag](void* ud, const void* cb) { - MMessage::MNodeFunction cf = (MMessage::MNodeFunction)cb; - cf(node, ud); + MMessage::MNodeStringBoolFunction cf = (MMessage::MNodeStringBoolFunction)cb; + cf(node, str, flag, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -149,12 +146,12 @@ static void bindNodeFunction(MObject& node, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindStringFunction(const MString& str, void* ptr) +static void bindTimeFunction(MTime& time, void* ptr) { - auto binder = [str](void* ud, const void* cb) + auto binder = [&time](void* ud, const void* cb) { - MMessage::MStringFunction cf = (MMessage::MStringFunction)cb; - cf(str, ud); + MMessage::MTimeFunction cf = (MMessage::MTimeFunction)cb; + cf(time, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -163,12 +160,12 @@ static void bindStringFunction(const MString& str, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindTwoStringFunction(const MString& str1, const MString& str2, void* ptr) +static void bindPlugFunction(MPlug& src, MPlug& dst, bool made, void* ptr) { - auto binder = [str1, str2](void* ud, const void* cb) + auto binder = [&src, &dst, made](void* ud, const void* cb) { - MMessage::MTwoStringFunction cf = (MMessage::MTwoStringFunction)cb; - cf(str1, str2, ud); + MMessage::MPlugFunction cf = (MMessage::MPlugFunction)cb; + cf(src, dst, made, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -177,12 +174,12 @@ static void bindTwoStringFunction(const MString& str1, const MString& str2, void } //---------------------------------------------------------------------------------------------------------------------- -static void bindThreeStringFunction(const MString& str1, const MString& str2, const MString& str3, void* ptr) +static void bindParentChildFunction(MDagPath& child, MDagPath& parent, void* ptr) { - auto binder = [str1, str2, str3](void* ud, const void* cb) + auto binder = [&child, &parent](void* ud, const void* cb) { - MMessage::MThreeStringFunction cf = (MMessage::MThreeStringFunction)cb; - cf(str1, str2, str3, ud); + MMessage::MParentChildFunction cf = (MMessage::MParentChildFunction)cb; + cf(child, parent, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -191,12 +188,12 @@ static void bindThreeStringFunction(const MString& str1, const MString& str2, co } //---------------------------------------------------------------------------------------------------------------------- -static void bindStringIntBoolIntFunction(const MString& str, uint32_t index, bool flag, uint32_t type, void* ptr) +static void bindStringArrayFunction(const MStringArray& strs, void* ptr) { - auto binder = [str, index, flag, type](void* ud, const void* cb) + auto binder = [strs](void* ud, const void* cb) { - MMessage::MStringIntBoolIntFunction cf = (MMessage::MStringIntBoolIntFunction)cb; - cf(str, index, flag, type, ud); + MMessage::MStringArrayFunction cf = (MMessage::MStringArrayFunction)cb; + cf(strs, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -205,12 +202,12 @@ static void bindStringIntBoolIntFunction(const MString& str, uint32_t index, boo } //---------------------------------------------------------------------------------------------------------------------- -static void bindStringIndexFunction(const MString& str, uint32_t index, void* ptr) +static void bindObjArrayFunction(MObjectArray& objects, void* ptr) { - auto binder = [str, index](void* ud, const void* cb) + auto binder = [&objects](void* ud, const void* cb) { - MMessage::MStringIndexFunction cf = (MMessage::MStringIndexFunction)cb; - cf(str, index, ud); + MMessage::MObjArray cf = (MMessage::MObjArray)cb; + cf(objects, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -219,12 +216,12 @@ static void bindStringIndexFunction(const MString& str, uint32_t index, void* pt } //---------------------------------------------------------------------------------------------------------------------- -static void bindNodeStringBoolFunction(MObject& node, const MString& str, bool flag, void* ptr) +static void bindCameraLayerFunction(MObject& cameraSetNode, uint32_t index, bool added, void* ptr) { - auto binder = [&node, str, flag](void* ud, const void* cb) + auto binder = [&cameraSetNode, index, added](void* ud, const void* cb) { - MMessage::MNodeStringBoolFunction cf = (MMessage::MNodeStringBoolFunction)cb; - cf(node, str, flag, ud); + MMessage::MCameraLayerFunction cf = (MMessage::MCameraLayerFunction)cb; + cf(cameraSetNode, index, added, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -233,12 +230,12 @@ static void bindNodeStringBoolFunction(MObject& node, const MString& str, bool f } //---------------------------------------------------------------------------------------------------------------------- -static void bindStateFunction(bool flag, void* ptr) +static void bindCameraLayerCameraFunction(MObject& cameraSetNode, uint32_t index, MObject& oldCamera, MObject& newCamera, void* ptr) { - auto binder = [flag](void* ud, const void* cb) + auto binder = [&cameraSetNode, index, &oldCamera, &newCamera](void* ud, const void* cb) { - MMessage::MStateFunction cf = (MMessage::MStateFunction)cb; - cf(flag, ud); + MMessage::MCameraLayerCameraFunction cf = (MMessage::MCameraLayerCameraFunction)cb; + cf(cameraSetNode, index, oldCamera, newCamera, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -247,12 +244,12 @@ static void bindStateFunction(bool flag, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindTimeFunction(MTime& time, void* ptr) +static void bindPlugsDGModFunction(MPlugArray& plugs, MDGModifier& modifier, void* ptr) { - auto binder = [&time](void* ud, const void* cb) + auto binder = [&plugs, &modifier](void* ud, const void* cb) { - MMessage::MTimeFunction cf = (MMessage::MTimeFunction)cb; - cf(time, ud); + MMessage::MPlugsDGModFunction cf = (MMessage::MPlugsDGModFunction)cb; + cf(plugs, modifier, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -261,12 +258,12 @@ static void bindTimeFunction(MTime& time, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindPlugFunction(MPlug& src, MPlug& dst, bool made, void* ptr) +static void bindMessageFunction(const MString& message, MCommandMessage::MessageType messageType, void* ptr) { - auto binder = [&src, &dst, made](void* ud, const void* cb) + auto binder = [message, messageType](void* ud, const void* cb) { - MMessage::MPlugFunction cf = (MMessage::MPlugFunction)cb; - cf(src, dst, made, ud); + MCommandMessage::MMessageFunction cf = (MCommandMessage::MMessageFunction)cb; + cf(message, messageType, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -275,12 +272,15 @@ static void bindPlugFunction(MPlug& src, MPlug& dst, bool made, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindNodePlugFunction(MObject& node, MPlug& plug, void* ptr) +static void bindMessageFilterFunction(const MString& message, MCommandMessage::MessageType messageType, bool& filterOutput, void* ptr) { - auto binder = [&node, &plug](void* ud, const void* cb) + filterOutput = false; + auto binder = [&filterOutput, message, messageType](void* ud, const void* cb) { - MMessage::MNodePlugFunction cf = (MMessage::MNodePlugFunction)cb; - cf(node, plug, ud); + bool temp = false; + MCommandMessage::MMessageFilterFunction cf = (MCommandMessage::MMessageFilterFunction)cb; + cf(message, messageType, temp, ud); + filterOutput = filterOutput || temp; }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -289,12 +289,12 @@ static void bindNodePlugFunction(MObject& node, MPlug& plug, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindNodeStringFunction(MObject& node, const MString& str, void* ptr) +static void bindMessageParentChildFunction(MDagMessage::DagMessage msgType, MDagPath& child, MDagPath& parent, void* ptr) { - auto binder = [&node, str](void* ud, const void* cb) + auto binder = [msgType, &child, &parent](void* ud, const void* cb) { - MMessage::MNodeStringFunction cf = (MMessage::MNodeStringFunction)cb; - cf(node, str, ud); + MDagMessage::MMessageParentChildFunction cf = (MDagMessage::MMessageParentChildFunction)cb; + cf(msgType, child, parent, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -303,12 +303,12 @@ static void bindNodeStringFunction(MObject& node, const MString& str, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindParentChildFunction(MDagPath& child, MDagPath& parent, void* ptr) +static void bindPathObjectPlugColoursFunction(MDagPath& path, MObject& object, MPlug& plug, MColorArray& colors, void* ptr) { - auto binder = [&child, &parent](void* ud, const void* cb) + auto binder = [&path, &object, &plug, &colors](void* ud, const void* cb) { - MMessage::MParentChildFunction cf = (MMessage::MParentChildFunction)cb; - cf(child, parent, ud); + MPaintMessage::MPathObjectPlugColorsFunction cf = (MPaintMessage::MPathObjectPlugColorsFunction)cb; + cf(path, object, plug, colors, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -316,13 +316,16 @@ static void bindParentChildFunction(MDagPath& child, MDagPath& parent, void* ptr scheduler.triggerEvent(cbi->eventId, binder); } +// these are functions we will probably want in the long term, however to ensure the OpenSource build does not +// complain about unused symbols, they are hidden behind a #if 0 for now. +#if 0 //---------------------------------------------------------------------------------------------------------------------- -static void bindModifierFunction(MDGModifier& mod, void* ptr) +static void bindElapsedTimeFunction(float elapsed, float last, void* ptr) { - auto binder = [&mod](void* ud, const void* cb) + auto binder = [elapsed, last](void* ud, const void* cb) { - MMessage::MModifierFunction cf = (MMessage::MModifierFunction)cb; - cf(mod, ud); + MMessage::MElapsedTimeFunction cf = (MMessage::MElapsedTimeFunction)cb; + cf(elapsed, last, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -331,12 +334,15 @@ static void bindModifierFunction(MDGModifier& mod, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindStringArrayFunction(const MStringArray& strs, void* ptr) +static void bindCheckFileFunction(bool* retCode, MFileObject& obj, void* ptr) { - auto binder = [strs](void* ud, const void* cb) + bool result = true; + auto binder = [&result, &obj](void* ud, const void* cb) { - MMessage::MStringArrayFunction cf = (MMessage::MStringArrayFunction)cb; - cf(strs, ud); + MMessage::MCheckFileFunction cf = (MMessage::MCheckFileFunction)cb; + bool temp = true; + cf(&temp, obj, ud); + result = result && temp; }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -345,12 +351,12 @@ static void bindStringArrayFunction(const MStringArray& strs, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindNodeModifierFunction(MObject& node, MDGModifier& mod, void* ptr) +static void bindComponentFunction(MUintArray componentIds[], unsigned int count, void* ptr) { - auto binder = [&node, &mod](void* ud, const void* cb) + auto binder = [componentIds, count](void* ud, const void* cb) { - MMessage::MNodeModifierFunction cf = (MMessage::MNodeModifierFunction)cb; - cf(node, mod, ud); + MMessage::MComponentFunction cf = (MMessage::MComponentFunction)cb; + cf(componentIds, count, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -359,12 +365,12 @@ static void bindNodeModifierFunction(MObject& node, MDGModifier& mod, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindObjArrayFunction(MObjectArray& objects, void* ptr) +static void bindTwoStringFunction(const MString& str1, const MString& str2, void* ptr) { - auto binder = [&objects](void* ud, const void* cb) + auto binder = [str1, str2](void* ud, const void* cb) { - MMessage::MObjArray cf = (MMessage::MObjArray)cb; - cf(objects, ud); + MMessage::MTwoStringFunction cf = (MMessage::MTwoStringFunction)cb; + cf(str1, str2, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -373,12 +379,12 @@ static void bindObjArrayFunction(MObjectArray& objects, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindNodeObjArrayFunction(MObject& node, MObjectArray& objects, void* ptr) +static void bindThreeStringFunction(const MString& str1, const MString& str2, const MString& str3, void* ptr) { - auto binder = [&node, &objects](void* ud, const void* cb) + auto binder = [str1, str2, str3](void* ud, const void* cb) { - MMessage::MNodeObjArray cf = (MMessage::MNodeObjArray)cb; - cf(node, objects, ud); + MMessage::MThreeStringFunction cf = (MMessage::MThreeStringFunction)cb; + cf(str1, str2, str3, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -387,12 +393,12 @@ static void bindNodeObjArrayFunction(MObject& node, MObjectArray& objects, void* } //---------------------------------------------------------------------------------------------------------------------- -static void bindStringNodeFunction(const MString& str, MObject& node, void* ptr) +static void bindStringIndexFunction(const MString& str, uint32_t index, void* ptr) { - auto binder = [str, &node](void* ud, const void* cb) + auto binder = [str, index](void* ud, const void* cb) { - MMessage::MStringNode cf = (MMessage::MStringNode)cb; - cf(str, node, ud); + MMessage::MStringIndexFunction cf = (MMessage::MStringIndexFunction)cb; + cf(str, index, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -401,12 +407,12 @@ static void bindStringNodeFunction(const MString& str, MObject& node, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindCameraLayerFunction(MObject& cameraSetNode, uint32_t index, bool added, void* ptr) +static void bindStateFunction(bool flag, void* ptr) { - auto binder = [&cameraSetNode, index, added](void* ud, const void* cb) + auto binder = [flag](void* ud, const void* cb) { - MMessage::MCameraLayerFunction cf = (MMessage::MCameraLayerFunction)cb; - cf(cameraSetNode, index, added, ud); + MMessage::MStateFunction cf = (MMessage::MStateFunction)cb; + cf(flag, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -415,12 +421,12 @@ static void bindCameraLayerFunction(MObject& cameraSetNode, uint32_t index, bool } //---------------------------------------------------------------------------------------------------------------------- -static void bindCameraLayerCameraFunction(MObject& cameraSetNode, uint32_t index, MObject& oldCamera, MObject& newCamera, void* ptr) +static void bindNodePlugFunction(MObject& node, MPlug& plug, void* ptr) { - auto binder = [&cameraSetNode, index, &oldCamera, &newCamera](void* ud, const void* cb) + auto binder = [&node, &plug](void* ud, const void* cb) { - MMessage::MCameraLayerCameraFunction cf = (MMessage::MCameraLayerCameraFunction)cb; - cf(cameraSetNode, index, oldCamera, newCamera, ud); + MMessage::MNodePlugFunction cf = (MMessage::MNodePlugFunction)cb; + cf(node, plug, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -429,12 +435,12 @@ static void bindCameraLayerCameraFunction(MObject& cameraSetNode, uint32_t index } //---------------------------------------------------------------------------------------------------------------------- -static void bindConnFailFunction(MPlug& src, MPlug& dst, const MString& srcName, const MString& dstName, void* ptr) +static void bindNodeStringFunction(MObject& node, const MString& str, void* ptr) { - auto binder = [&src, &dst, srcName, dstName](void* ud, const void* cb) + auto binder = [&node, str](void* ud, const void* cb) { - MMessage::MConnFailFunction cf = (MMessage::MConnFailFunction)cb; - cf(src, dst, srcName, dstName, ud); + MMessage::MNodeStringFunction cf = (MMessage::MNodeStringFunction)cb; + cf(node, str, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -443,12 +449,12 @@ static void bindConnFailFunction(MPlug& src, MPlug& dst, const MString& srcName, } //---------------------------------------------------------------------------------------------------------------------- -static void bindPlugsDGModFunction(MPlugArray& plugs, MDGModifier& modifier, void* ptr) +static void bindModifierFunction(MDGModifier& mod, void* ptr) { - auto binder = [&plugs, &modifier](void* ud, const void* cb) + auto binder = [&mod](void* ud, const void* cb) { - MMessage::MPlugsDGModFunction cf = (MMessage::MPlugsDGModFunction)cb; - cf(plugs, modifier, ud); + MMessage::MModifierFunction cf = (MMessage::MModifierFunction)cb; + cf(mod, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -457,12 +463,12 @@ static void bindPlugsDGModFunction(MPlugArray& plugs, MDGModifier& modifier, voi } //---------------------------------------------------------------------------------------------------------------------- -static void bindNodeUuidFunction(MObject& node, MUuid& uuid, void* ptr) +static void bindNodeModifierFunction(MObject& node, MDGModifier& mod, void* ptr) { - auto binder = [&node, &uuid](void* ud, const void* cb) + auto binder = [&node, &mod](void* ud, const void* cb) { - MMessage::MNodeUuidFunction cf = (MMessage::MNodeUuidFunction)cb; - cf(node, uuid, ud); + MMessage::MNodeModifierFunction cf = (MMessage::MNodeModifierFunction)cb; + cf(node, mod, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -471,12 +477,12 @@ static void bindNodeUuidFunction(MObject& node, MUuid& uuid, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindObjectFileFunction(MObject& node, MFileObject& file, void* ptr) +static void bindNodeObjArrayFunction(MObject& node, MObjectArray& objects, void* ptr) { - auto binder = [&node, &file](void* ud, const void* cb) + auto binder = [&node, &objects](void* ud, const void* cb) { - MMessage::MObjectFileFunction cf = (MMessage::MObjectFileFunction)cb; - cf(node, file, ud); + MMessage::MNodeObjArray cf = (MMessage::MNodeObjArray)cb; + cf(node, objects, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -485,15 +491,12 @@ static void bindObjectFileFunction(MObject& node, MFileObject& file, void* ptr) } //---------------------------------------------------------------------------------------------------------------------- -static void bindCheckObjectFileFunction(bool* retCode, const MObject& referenceNode, MFileObject& fo, void* ptr) +static void bindStringNodeFunction(const MString& str, MObject& node, void* ptr) { - bool result = true; - auto binder = [&result, referenceNode, &fo](void* ud, const void* cb) + auto binder = [str, &node](void* ud, const void* cb) { - MMessage::MCheckObjectFileFunction cf = (MMessage::MCheckObjectFileFunction)cb; - bool temp = true; - cf(&temp, referenceNode, fo, ud); - result = result && temp; + MMessage::MStringNode cf = (MMessage::MStringNode)cb; + cf(str, node, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -502,12 +505,12 @@ static void bindCheckObjectFileFunction(bool* retCode, const MObject& referenceN } //---------------------------------------------------------------------------------------------------------------------- -static void bindMessageFunction(const MString& message, MCommandMessage::MessageType messageType, void* ptr) +static void bindConnFailFunction(MPlug& src, MPlug& dst, const MString& srcName, const MString& dstName, void* ptr) { - auto binder = [message, messageType](void* ud, const void* cb) + auto binder = [&src, &dst, srcName, dstName](void* ud, const void* cb) { - MCommandMessage::MMessageFunction cf = (MCommandMessage::MMessageFunction)cb; - cf(message, messageType, ud); + MMessage::MConnFailFunction cf = (MMessage::MConnFailFunction)cb; + cf(src, dst, srcName, dstName, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -516,15 +519,12 @@ static void bindMessageFunction(const MString& message, MCommandMessage::Message } //---------------------------------------------------------------------------------------------------------------------- -static void bindMessageFilterFunction(const MString& message, MCommandMessage::MessageType messageType, bool& filterOutput, void* ptr) +static void bindNodeUuidFunction(MObject& node, MUuid& uuid, void* ptr) { - filterOutput = false; - auto binder = [&filterOutput, message, messageType](void* ud, const void* cb) + auto binder = [&node, &uuid](void* ud, const void* cb) { - bool temp = false; - MCommandMessage::MMessageFilterFunction cf = (MCommandMessage::MMessageFilterFunction)cb; - cf(message, messageType, temp, ud); - filterOutput = filterOutput || temp; + MMessage::MNodeUuidFunction cf = (MMessage::MNodeUuidFunction)cb; + cf(node, uuid, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -533,12 +533,12 @@ static void bindMessageFilterFunction(const MString& message, MCommandMessage::M } //---------------------------------------------------------------------------------------------------------------------- -static void bindMessageParentChildFunction(MDagMessage::DagMessage msgType, MDagPath& child, MDagPath& parent, void* ptr) +static void bindObjectFileFunction(MObject& node, MFileObject& file, void* ptr) { - auto binder = [msgType, &child, &parent](void* ud, const void* cb) + auto binder = [&node, &file](void* ud, const void* cb) { - MDagMessage::MMessageParentChildFunction cf = (MDagMessage::MMessageParentChildFunction)cb; - cf(msgType, child, parent, ud); + MMessage::MObjectFileFunction cf = (MMessage::MObjectFileFunction)cb; + cf(node, file, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -547,12 +547,15 @@ static void bindMessageParentChildFunction(MDagMessage::DagMessage msgType, MDag } //---------------------------------------------------------------------------------------------------------------------- -static void bindWorldMatrixModifiedFunction(MObject& transform, MDagMessage::MatrixModifiedFlags& modified, void* ptr) +static void bindCheckObjectFileFunction(bool* retCode, const MObject& referenceNode, MFileObject& fo, void* ptr) { - auto binder = [&transform, &modified](void* ud, const void* cb) + bool result = true; + auto binder = [&result, referenceNode, &fo](void* ud, const void* cb) { - MDagMessage::MWorldMatrixModifiedFunction cf = (MDagMessage::MWorldMatrixModifiedFunction)cb; - cf(transform, modified, ud); + MMessage::MCheckObjectFileFunction cf = (MMessage::MCheckObjectFileFunction)cb; + bool temp = true; + cf(&temp, referenceNode, fo, ud); + result = result && temp; }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -561,12 +564,12 @@ static void bindWorldMatrixModifiedFunction(MObject& transform, MDagMessage::Mat } //---------------------------------------------------------------------------------------------------------------------- -static void bindPathObjectPlugColoursFunction(MDagPath& path, MObject& object, MPlug& plug, MColorArray& colors, void* ptr) +static void bindWorldMatrixModifiedFunction(MObject& transform, MDagMessage::MatrixModifiedFlags& modified, void* ptr) { - auto binder = [&path, &object, &plug, &colors](void* ud, const void* cb) + auto binder = [&transform, &modified](void* ud, const void* cb) { - MPaintMessage::MPathObjectPlugColorsFunction cf = (MPaintMessage::MPathObjectPlugColorsFunction)cb; - cf(path, object, plug, colors, ud); + MDagMessage::MWorldMatrixModifiedFunction cf = (MDagMessage::MWorldMatrixModifiedFunction)cb; + cf(transform, modified, ud); }; MayaEventHandler::MayaCallbackInfo* cbi = (MayaEventHandler::MayaCallbackInfo*)ptr; @@ -574,6 +577,8 @@ static void bindPathObjectPlugColoursFunction(MDagPath& path, MObject& object, M scheduler.triggerEvent(cbi->eventId, binder); } +#endif + //---------------------------------------------------------------------------------------------------------------------- MayaEventHandler::MayaEventHandler(AL::event::EventScheduler* scheduler, AL::event::EventType eventType) { @@ -742,10 +747,6 @@ void MayaEventHandler::registerCommandMessages(AL::event::EventScheduler* schedu //---------------------------------------------------------------------------------------------------------------------- void MayaEventHandler::initConditionMessage(MayaCallbackInfo& cbi) { - switch(cbi.mmessageEnum) - { - default: break; - } } //---------------------------------------------------------------------------------------------------------------------- @@ -846,10 +847,6 @@ void MayaEventHandler::registerDGMessages(AL::event::EventScheduler* scheduler, //---------------------------------------------------------------------------------------------------------------------- void MayaEventHandler::initEventMessage(MayaCallbackInfo& cbi) { - switch(cbi.mmessageEnum) - { - default: break; - } } //---------------------------------------------------------------------------------------------------------------------- @@ -861,10 +858,6 @@ void MayaEventHandler::registerEventMessages(AL::event::EventScheduler* schedule //---------------------------------------------------------------------------------------------------------------------- void MayaEventHandler::initLockMessage(MayaCallbackInfo& cbi) { - switch(cbi.mmessageEnum) - { - default: break; - } } //---------------------------------------------------------------------------------------------------------------------- @@ -897,10 +890,6 @@ void MayaEventHandler::registerModelMessages(AL::event::EventScheduler* schedule //---------------------------------------------------------------------------------------------------------------------- void MayaEventHandler::initNodeMessage(MayaCallbackInfo& cbi) { - switch(cbi.mmessageEnum) - { - default: break; - } } //---------------------------------------------------------------------------------------------------------------------- @@ -911,10 +900,6 @@ void MayaEventHandler::registerNodeMessages(AL::event::EventScheduler* scheduler //---------------------------------------------------------------------------------------------------------------------- void MayaEventHandler::initObjectSetMessage(MayaCallbackInfo& cbi) { - switch(cbi.mmessageEnum) - { - default: break; - } } //---------------------------------------------------------------------------------------------------------------------- @@ -941,10 +926,6 @@ void MayaEventHandler::registerPaintMessages(AL::event::EventScheduler* schedule //---------------------------------------------------------------------------------------------------------------------- void MayaEventHandler::initPolyMessage(MayaCallbackInfo& cbi) { - switch(cbi.mmessageEnum) - { - default: break; - } } //---------------------------------------------------------------------------------------------------------------------- @@ -1074,10 +1055,6 @@ void MayaEventHandler::registerSceneMessages(AL::event::EventScheduler* schedule //---------------------------------------------------------------------------------------------------------------------- void MayaEventHandler::initTimerMessage(MayaCallbackInfo& cbi) { - switch(cbi.mmessageEnum) - { - default: break; - } } //---------------------------------------------------------------------------------------------------------------------- @@ -1088,10 +1065,6 @@ void MayaEventHandler::registerTimerMessages(AL::event::EventScheduler* schedule //---------------------------------------------------------------------------------------------------------------------- void MayaEventHandler::initUiMessage(MayaCallbackInfo& cbi) { - switch(cbi.mmessageEnum) - { - default: break; - } } //---------------------------------------------------------------------------------------------------------------------- @@ -1206,6 +1179,7 @@ MayaEventManager* MayaEventManager::g_instance = 0; //---------------------------------------------------------------------------------------------------------------------- static const char* const eventTypeStrings[] = { + "unknown", "custom", "schema", "coremaya", diff --git a/mayautils/AL/maya/event/MayaEventManager.h b/mayautils/AL/maya/event/MayaEventManager.h index bf8ddaee..7b34fe05 100644 --- a/mayautils/AL/maya/event/MayaEventManager.h +++ b/mayautils/AL/maya/event/MayaEventManager.h @@ -513,13 +513,11 @@ class MayaEventManager static MayaEventManager& instance(); /// \brief returns the global maya event manager instance - AL_MAYA_EVENTS_PUBLIC static void freeInstance() { delete g_instance; g_instance = 0; } /// \brief constructor /// \param mayaEvents the custom event handler - AL_MAYA_EVENTS_PUBLIC MayaEventManager(MayaEventHandler* mayaEvents) : m_mayaEvents(mayaEvents) { g_instance = this; } @@ -530,7 +528,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MBasicFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kBasicFunction, eventName, tag, weight, userData); } @@ -541,7 +538,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MElapsedTimeFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kElapsedTimeFunction, eventName, tag, weight, userData); } @@ -552,7 +548,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MCheckFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kCheckFunction, eventName, tag, weight, userData); } @@ -563,7 +558,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MCheckFileFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kCheckFileFunction, eventName, tag, weight, userData); } @@ -574,7 +568,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MCheckPlugFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kCheckPlugFunction, eventName, tag, weight, userData); } @@ -585,7 +578,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MComponentFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kComponentFunction, eventName, tag, weight, userData); } @@ -596,7 +588,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MNodeFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kNodeFunction, eventName, tag, weight, userData); } @@ -607,7 +598,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MStringFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kStringFunction, eventName, tag, weight, userData); } @@ -618,7 +608,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MTwoStringFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kTwoStringFunction, eventName, tag, weight, userData); } @@ -629,7 +618,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MThreeStringFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kThreeStringFunction, eventName, tag, weight, userData); } @@ -640,7 +628,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MStringIntBoolIntFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kStringIntBoolIntFunction, eventName, tag, weight, userData); } @@ -651,7 +638,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MStringIndexFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kStringIndexFunction, eventName, tag, weight, userData); } @@ -662,7 +648,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MNodeStringBoolFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kNodeStringBoolFunction, eventName, tag, weight, userData); } @@ -673,7 +658,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MStateFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kStateFunction, eventName, tag, weight, userData); } @@ -684,7 +668,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MTimeFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kTimeFunction, eventName, tag, weight, userData); } @@ -695,7 +678,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MPlugFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kPlugFunction, eventName, tag, weight, userData); } @@ -706,7 +688,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MNodePlugFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kNodePlugFunction, eventName, tag, weight, userData); } @@ -717,7 +698,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MNodeStringFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kNodeStringFunction, eventName, tag, weight, userData); } @@ -728,7 +708,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MParentChildFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kParentChildFunction, eventName, tag, weight, userData); } @@ -739,7 +718,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MModifierFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kModifierFunction, eventName, tag, weight, userData); } @@ -750,7 +728,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MStringArrayFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kStringArrayFunction, eventName, tag, weight, userData); } @@ -761,7 +738,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MNodeModifierFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kNodeModifierFunction, eventName, tag, weight, userData); } @@ -772,7 +748,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MObjArray func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kObjArrayFunction, eventName, tag, weight, userData); } @@ -783,7 +758,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MNodeObjArray func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kNodeObjArrayFunction, eventName, tag, weight, userData); } @@ -794,7 +768,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MStringNode func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kStringNodeFunction, eventName, tag, weight, userData); } @@ -805,7 +778,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MCameraLayerFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kCameraLayerFunction, eventName, tag, weight, userData); } @@ -816,7 +788,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MCameraLayerCameraFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kCameraLayerCameraFunction, eventName, tag, weight, userData); } @@ -827,7 +798,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MConnFailFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kConnFailFunction, eventName, tag, weight, userData); } @@ -838,7 +808,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MPlugsDGModFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kPlugsDGModFunction, eventName, tag, weight, userData); } @@ -849,7 +818,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MNodeUuidFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kNodeUuidFunction, eventName, tag, weight, userData); } @@ -860,7 +828,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MCheckNodeUuidFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kCheckNodeUuidFunction, eventName, tag, weight, userData); } @@ -871,7 +838,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MObjectFileFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kObjectFileFunction, eventName, tag, weight, userData); } @@ -882,7 +848,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MCheckObjectFileFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kCheckObjectFileFunction, eventName, tag, weight, userData); } @@ -893,7 +858,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MMessage::MRenderTileFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kRenderTileFunction, eventName, tag, weight, userData); } @@ -904,7 +868,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MCommandMessage::MMessageFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kMessageFunction, eventName, tag, weight, userData); } @@ -915,7 +878,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MCommandMessage::MMessageFilterFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kMessageFilterFunction, eventName, tag, weight, userData); } @@ -926,7 +888,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MDagMessage::MMessageParentChildFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kMessageParentChildFunction, eventName, tag, weight, userData); } @@ -937,7 +898,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MDagMessage::MWorldMatrixModifiedFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kWorldMatrixModifiedFunction, eventName, tag, weight, userData); } @@ -948,7 +908,6 @@ class MayaEventManager /// \param weight the weight (lower weights at executed before higher weights) /// \param userData custom user data pointer /// \return the callback id - AL_MAYA_EVENTS_PUBLIC AL::event::CallbackId registerCallback(MPaintMessage::MPathObjectPlugColorsFunction func, const char* const eventName, const char* const tag, uint32_t weight, void* userData = 0) { return registerCallbackInternal((void*)func, MayaCallbackType::kPathObjectPlugColoursFunction, eventName, tag, weight, userData); } diff --git a/mayautils/AL/maya/tests/mayaplugintest/CMakeLists.txt b/mayautils/AL/maya/tests/mayaplugintest/CMakeLists.txt index 7ae35a08..ddfba0e3 100644 --- a/mayautils/AL/maya/tests/mayaplugintest/CMakeLists.txt +++ b/mayautils/AL/maya/tests/mayaplugintest/CMakeLists.txt @@ -1,8 +1,3 @@ -IF(DEFINED NO_TESTS AND NO_TESTS) - message("Skipping building of test plugin.") - return() -ENDIF() - find_package(GTest REQUIRED) set(MAYAUTILS_TEST_LIBRARY_NAME AL_MayaUtilsTests) diff --git a/mayautils/AL/maya/tests/mayaplugintest/UnitTestHarness.cpp b/mayautils/AL/maya/tests/mayaplugintest/UnitTestHarness.cpp index 044231a7..faa4ea9f 100644 --- a/mayautils/AL/maya/tests/mayaplugintest/UnitTestHarness.cpp +++ b/mayautils/AL/maya/tests/mayaplugintest/UnitTestHarness.cpp @@ -20,13 +20,19 @@ #include "maya/MArgDatabase.h" #include "maya/MGlobal.h" +#ifdef _WIN32 +# define RESET_COLOUR +#else +# define RESET_COLOUR "\e[39m" +#endif + const char* happy_cat = "\n" " \\ /\\ \n" " ) ( ^)\n" " ( / )\n" " \\(__)|\n" -"\e[39m"; +RESET_COLOUR; const char* angry_cat = "\n" @@ -34,7 +40,7 @@ const char* angry_cat = " ( >)\n" " /\\ / )\n" " / \\(__)|\n" -"\e[39m"; +RESET_COLOUR; //---------------------------------------------------------------------------------------------------------------------- const MString UnitTestHarness::kName = "MayaUtils_UnitTestHarness"; @@ -150,7 +156,7 @@ MStatus UnitTestHarness::doIt(const MArgList& args) char** argv = new char*[arguments.size()]; int argc(arguments.size()); - for(size_t i = 0; i < argc; ++i) + for(int i = 0; i < argc; ++i) { argv[i] = (char*)arguments[i].c_str(); } @@ -164,37 +170,23 @@ MStatus UnitTestHarness::doIt(const MArgList& args) delete [] argv; setResult(error_code); - cleanTemporaryFiles(); - if(MGlobal::kInteractive == MGlobal::mayaState()) MGlobal::executeCommand("refresh -suspend false"); if(error_code) { + #ifndef _WIN32 if(::testing::GTEST_FLAG(color) != "no") std::cout << "\e[31m"; + #endif std::cout << angry_cat; } else { + #ifndef _WIN32 if(::testing::GTEST_FLAG(color) != "no") std::cout << "\e[32m"; + #endif std::cout << happy_cat; } return MS::kSuccess; } -//------------------------------------------------------------------------------ -void UnitTestHarness::cleanTemporaryFiles() const -{ - MString cmd( - "import glob;" - "import os;" - "[os.remove(x) for x in glob.glob('/tmp/AL_USDMayaTests*.usda')];" - "[os.remove(x) for x in glob.glob('/tmp/AL_USDMayaTests*.ma')]" - ); - - MStatus stat = MGlobal::executePythonCommand(cmd); - - if(stat != MStatus::kSuccess) { - MGlobal::displayWarning("Unable to remove temporary test files"); - } -} diff --git a/mayautils/AL/maya/tests/mayaplugintest/UnitTestHarness.h b/mayautils/AL/maya/tests/mayaplugintest/UnitTestHarness.h index 5a275f4a..d6d35636 100644 --- a/mayautils/AL/maya/tests/mayaplugintest/UnitTestHarness.h +++ b/mayautils/AL/maya/tests/mayaplugintest/UnitTestHarness.h @@ -26,9 +26,5 @@ class UnitTestHarness : public MPxCommand static MSyntax createSyntax(); static const MString kName; MStatus doIt(const MArgList& args) override; - -private: - void cleanTemporaryFiles() const; - }; diff --git a/mayautils/AL/maya/tests/mayaplugintest/utils/CommandGuiHelperTest.cpp b/mayautils/AL/maya/tests/mayaplugintest/utils/CommandGuiHelperTest.cpp index 273eb68e..f2f00dfa 100644 --- a/mayautils/AL/maya/tests/mayaplugintest/utils/CommandGuiHelperTest.cpp +++ b/mayautils/AL/maya/tests/mayaplugintest/utils/CommandGuiHelperTest.cpp @@ -397,7 +397,7 @@ bool test_CommandGuiHelper() result = MGlobal::executeCommand("init_polyCube_optionGUI;") && result; bool exists = false; - if(true == MGlobal::optionVarIntValue(polyCube_constructionHistory, &exists)) + if(MGlobal::optionVarIntValue(polyCube_constructionHistory, &exists)) { result = exists && result; } diff --git a/mayautils/AL/maya/utils/CommandGuiHelper.cpp b/mayautils/AL/maya/utils/CommandGuiHelper.cpp index a92734e0..deffbefb 100644 --- a/mayautils/AL/maya/utils/CommandGuiHelper.cpp +++ b/mayautils/AL/maya/utils/CommandGuiHelper.cpp @@ -69,7 +69,7 @@ MStatus CommandGuiListGen::doIt(const MArgList& args) } // ensure the list id is valid - if(genListId < 0 || genListId >= m_funcs.size()) + if(genListId < 0 || size_t(genListId) >= m_funcs.size()) { MGlobal::displayError("Invalid gen list ID for the GUI"); return MS::kFailure; diff --git a/mayautils/AL/maya/utils/FileTranslatorBase.h b/mayautils/AL/maya/utils/FileTranslatorBase.h index 243da248..a14416c7 100644 --- a/mayautils/AL/maya/utils/FileTranslatorBase.h +++ b/mayautils/AL/maya/utils/FileTranslatorBase.h @@ -178,7 +178,7 @@ class FileTranslatorBase private: - MStatus reader(const MFileObject &file, const MString &optionsString, const FileAccessMode mode) override + MStatus reader(const MFileObject &file, const MString &optionsString, FileAccessMode mode) override { MStatus status = m_optionParser.parse(optionsString); if(MS::kSuccess == status) @@ -189,7 +189,7 @@ class FileTranslatorBase return status; } - MStatus writer(const MFileObject &file, const MString &optionsString, const FileAccessMode mode) override + MStatus writer(const MFileObject &file, const MString &optionsString, FileAccessMode mode) override { MStatus status = m_optionParser.parse(optionsString); if(MS::kSuccess == status) diff --git a/mayautils/AL/maya/utils/FileTranslatorOptions.cpp b/mayautils/AL/maya/utils/FileTranslatorOptions.cpp index dc593a3d..aab3b82f 100644 --- a/mayautils/AL/maya/utils/FileTranslatorOptions.cpp +++ b/mayautils/AL/maya/utils/FileTranslatorOptions.cpp @@ -46,13 +46,14 @@ MStatus OptionsParser::parse(const MString& optionString) { MStatus status = MS::kSuccess; { - auto it = m_optionNameToValue.begin(); - auto end = m_optionNameToValue.begin(); + auto it = m_niceNameToValue.begin(); + auto end = m_niceNameToValue.end(); for(; it != end; ++it) { it->second->init(); } } + if (optionString.length() > 0) { int i, length; @@ -140,6 +141,7 @@ bool FileTranslatorOptions::addBool(const char* niceName, bool defaultValue) option.niceName = niceName; option.type = kBool; option.defaultBool = defaultValue; + option.enumValues = 0; if(hasOption(option.optionName)) { MGlobal::displayError("FileTranslatorOptions: cannot register the same option twice"); @@ -163,6 +165,7 @@ bool FileTranslatorOptions::addInt(const char* niceName, int defaultValue) option.niceName = niceName; option.type = kInt; option.defaultInt = defaultValue; + option.enumValues = 0; if(hasOption(option.optionName)) { MGlobal::displayError("FileTranslatorOptions: cannot register the same option twice"); @@ -185,6 +188,7 @@ bool FileTranslatorOptions::addFloat(const char* niceName, float defaultValue) option.niceName = niceName; option.type = kFloat; option.defaultFloat = defaultValue; + option.enumValues = 0; if(hasOption(option.optionName)) { MGlobal::displayError("FileTranslatorOptions: cannot register the same option twice"); @@ -207,6 +211,31 @@ bool FileTranslatorOptions::addString(const char* niceName, const char* const de option.niceName = niceName; option.type = kString; option.defaultString = defaultValue; + option.enumValues = 0; + if(hasOption(option.optionName)) + { + MGlobal::displayError("FileTranslatorOptions: cannot register the same option twice"); + return false; + } + frame.m_options.push_back(option); + return true; +} + +//---------------------------------------------------------------------------------------------------------------------- +bool FileTranslatorOptions::addEnum(const char* niceName, const char* const enumValues[], const int defaultValue) +{ + if(m_frames.empty()) + return false; + + FrameLayout& frame = lastFrame(); + FrameLayout::Option option; + + option.optionName = niceNameToOptionString(niceName); + option.niceName = niceName; + option.type = kEnum; + option.defaultInt = defaultValue; + option.enumValues = enumValues; + if(hasOption(option.optionName)) { MGlobal::displayError("FileTranslatorOptions: cannot register the same option twice"); @@ -272,6 +301,27 @@ void FileTranslatorOptions::generateStringGlobals(const MString& niceName, const m_code += "\n"; } +//---------------------------------------------------------------------------------------------------------------------- +void FileTranslatorOptions::generateEnumGlobals(const MString& niceName, const MString& optionName, const char* const enumValues[], int defaultValue) +{ + MString controlName = m_translatorName + "_" + optionName; + MString createCommand = MString("global proc create_") + controlName + "() {" + MString("optionMenuGrp -l \"") + niceName + "\" " + controlName + ";"; + + for(int i = 0; enumValues && enumValues[i]; ++i) + { + createCommand += MString("menuItem -l \"") + enumValues[i] + "\";"; + } + + createCommand += "}\n"; + MString postCommand = MString("global proc post_") + controlName + "(string $value){ int $v=$value; eval (\"optionMenuGrp -e -sl \" + ($v + 1) + \" " + controlName + "\");}\n"; + MString buildCommand = MString("global proc string build_") + controlName + "(){ string $str = \"" + optionName + "=\" + (`optionMenuGrp -q -sl " + controlName + "` -1) + \";\"; return $str;}\n"; + + m_code += createCommand; + m_code += postCommand; + m_code += buildCommand; + m_code += "\n"; +} + //---------------------------------------------------------------------------------------------------------------------- bool FileTranslatorOptions::hasOption(const char* const optionName) const { @@ -352,7 +402,7 @@ MStatus FileTranslatorOptions::generateScript(OptionsParser& optionParser, MStri case kInt: { generateIntGlobals(ito->niceName, ito->optionName, ito->defaultInt); - defaultOptionString += ito->optionName + "=" + MString().set(ito->defaultInt) + ";"; + defaultOptionString += ito->optionName + "=" + (MString() + ito->defaultInt) + ";"; OptionsParser::OptionValue* value = new OptionsParser::OptionValue; value->m_type = OptionsParser::kInt; @@ -365,7 +415,7 @@ MStatus FileTranslatorOptions::generateScript(OptionsParser& optionParser, MStri case kFloat: { generateFloatGlobals(ito->niceName, ito->optionName, ito->defaultFloat); - defaultOptionString += ito->optionName + "=" + MString().set(ito->defaultInt) + ";"; + defaultOptionString += ito->optionName + "=" + (MString() + ito->defaultFloat) + ";"; OptionsParser::OptionValue* value = new OptionsParser::OptionValue; value->m_type = OptionsParser::kFloat; @@ -387,6 +437,19 @@ MStatus FileTranslatorOptions::generateScript(OptionsParser& optionParser, MStri optionParser.m_optionNameToValue.insert(std::make_pair(ito->optionName.asChar(), value)); } break; + + case kEnum: + { + generateEnumGlobals(ito->niceName, ito->optionName, ito->enumValues, ito->defaultInt); + defaultOptionString += ito->optionName + "=" + (MString() + ito->defaultInt) + ";"; + + OptionsParser::OptionValue* value = new OptionsParser::OptionValue; + value->m_type = OptionsParser::kEnum; + value->m_defaultInt = ito->defaultInt; + optionParser.m_niceNameToValue.insert(std::make_pair(ito->niceName.asChar(), value)); + optionParser.m_optionNameToValue.insert(std::make_pair(ito->optionName.asChar(), value)); + } + break; } } } diff --git a/mayautils/AL/maya/utils/FileTranslatorOptions.h b/mayautils/AL/maya/utils/FileTranslatorOptions.h index a5ca722c..16f108b8 100644 --- a/mayautils/AL/maya/utils/FileTranslatorOptions.h +++ b/mayautils/AL/maya/utils/FileTranslatorOptions.h @@ -112,7 +112,8 @@ class OptionsParser kBool, kInt, kFloat, - kString + kString, + kEnum }; AL_MAYA_UTILS_PUBLIC @@ -127,6 +128,7 @@ class OptionsParser case kInt: m_int = m_defaultInt; break; case kFloat: m_float = m_defaultFloat; break; case kString: m_string = m_defaultString; break; + case kEnum: m_int = m_defaultInt; break; default: break; } } @@ -138,7 +140,8 @@ class OptionsParser case kBool: m_bool = str.asInt() ? true : false; break; case kInt: m_int = str.asInt(); break; case kFloat: m_float = str.asFloat(); break; - case kString: m_string = str.asChar(); break; ///< More needed here! + case kString: m_string = str.asChar(); break; + case kEnum: m_int = str.asInt(); break; default: break; } } @@ -219,6 +222,14 @@ class FileTranslatorOptions AL_MAYA_UTILS_PUBLIC bool addString(const char* optionName, const char* const defaultValue = ""); + /// \brief Add an integer value to the translator options + /// \param optionName the name of the option + /// \param enumValues a null terminated list of strings for each enum entry + /// \param defaultValue the default value for the option + /// \return true if the option was successfully added. False if the option is a duplicate + AL_MAYA_UTILS_PUBLIC + bool addEnum(const char* optionName, const char* const enumValues[], int defaultValue = 0); + /// \brief For a given boolean option (the controller), if enabled the 'controlled' option will be editable. If /// the checkbox is uncecked, the controlled option will be disabled in the GUI. The invertBehaviour /// param reverses this behaviour (i.e. if controller is true, controlled will be disabled). @@ -253,6 +264,7 @@ class FileTranslatorOptions void generateIntGlobals(const MString& niceName, const MString& optionName, int defaultValue); void generateFloatGlobals(const MString& niceName, const MString& optionName, float defaultValue); void generateStringGlobals(const MString& niceName, const MString& optionName, MString defaultValue); + void generateEnumGlobals(const MString& niceName, const MString& optionName, const char* const enumVals[], int defaultValue); #endif private: #ifndef AL_GENERATING_DOCS @@ -261,7 +273,8 @@ class FileTranslatorOptions kBool, kInt, kFloat, - kString + kString, + kEnum }; struct FrameLayout { @@ -281,6 +294,21 @@ class FileTranslatorOptions float defaultFloat; const char* defaultString; }; + const char* const* enumValues; + + Option() = default; + Option(const Option& opt) + : optionName(opt.optionName), niceName(opt.niceName), type(opt.type), enumValues(opt.enumValues) + { + switch(type) + { + case kBool: defaultBool = opt.defaultBool; break; + case kInt: + case kEnum: defaultInt = opt.defaultInt; break; + case kFloat: defaultFloat = opt.defaultFloat; break; + case kString: defaultString = opt.defaultString; break; + } + } }; std::vector