Maya API: как решить эти нерешенные проблемы с внешними символами? - PullRequest
0 голосов
/ 01 августа 2020

Я пытаюсь изучить Maya C ++ API, и с помощью этого руководства мне удалось скомпилировать несколько простых плагинов типа «Hello World»: https://nccastaff.bournemouth.ac.uk/jmacey/MayaAPI/Windows/index.md.html

Затем я попытался скомпилировать этот плагин, очевидно, из книги "Complete Maya Programming", опубликованной в 2003 году:

https://github.com/animformed/complete-maya-programming-book-files/tree/master/Volume-1/Plugins/BasicLocator

Я взял файлы. cpp и .h и попытался собрать только что созданный проект Visual Studio 2019, но я получил следующие ошибки:

Severity    Code    Description Project File    Line    Suppression State
Warning C26495  Variable 'MArrayDataHandle::data' is uninitialized. Always initialize a member variable (type.6).   BasicLocator    C:\Program Files\Autodesk\Maya2016.5\include\maya\MArrayDataHandle.h    113 
Warning C26495  Variable 'MArrayDataHandle::fIsNull' is uninitialized. Always initialize a member variable (type.6).    BasicLocator    C:\Program Files\Autodesk\Maya2016.5\include\maya\MArrayDataHandle.h    113 
Warning C26812  The enum type 'MDAGDrawOverrideInfo::DrawOverrideDisplayType' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).    BasicLocator    C:\Program Files\Autodesk\Maya2016.5\include\maya\MDagPath.h    79  
Warning C26812  The enum type 'MDAGDrawOverrideInfo::DrawOverrideLOD' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).    BasicLocator    C:\Program Files\Autodesk\Maya2016.5\include\maya\MDagPath.h    81  
Warning C26495  Variable 'MDataHandle::f_data' is uninitialized. Always initialize a member variable (type.6).  BasicLocator    C:\Program Files\Autodesk\Maya2016.5\include\maya\MDataHandle.h 274 
Warning C26495  Variable 'MFnAttribute::ca' is uninitialized. Always initialize a member variable (type.6). BasicLocator    C:\Program Files\Autodesk\Maya2016.5\include\maya\MFnAttribute.h    72  
Warning C26812  The enum type 'MStatus::MStatusCode' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). BasicLocator    C:\Program Files\Autodesk\Maya2016.5\include\maya\MStatus.h 103 
Error   LNK2019 unresolved external symbol __imp_glBegin referenced in function "public: virtual void __cdecl BasicLocator::draw(class M3dView &,class MDagPath const &,enum M3dView::DisplayStyle,enum M3dView::DisplayStatus)" (?draw@BasicLocator@@UEAAXAEAVM3dView@@AEBVMDagPath@@W4DisplayStyle@2@W4DisplayStatus@2@@Z)    BasicLocator    C:\Users\Desktop02\Documents\Visual Studio 2019\maya_dev\complete_maya_programming_volume1\BasicLocator\BasicLocator.obj    1   
Error   LNK2019 unresolved external symbol __imp_glEnd referenced in function "public: virtual void __cdecl BasicLocator::draw(class M3dView &,class MDagPath const &,enum M3dView::DisplayStyle,enum M3dView::DisplayStatus)" (?draw@BasicLocator@@UEAAXAEAVM3dView@@AEBVMDagPath@@W4DisplayStyle@2@W4DisplayStatus@2@@Z)  BasicLocator    C:\Users\Desktop02\Documents\Visual Studio 2019\maya_dev\complete_maya_programming_volume1\BasicLocator\BasicLocator.obj    1   
Error   LNK2019 unresolved external symbol __imp_glPopAttrib referenced in function "public: virtual void __cdecl BasicLocator::draw(class M3dView &,class MDagPath const &,enum M3dView::DisplayStyle,enum M3dView::DisplayStatus)" (?draw@BasicLocator@@UEAAXAEAVM3dView@@AEBVMDagPath@@W4DisplayStyle@2@W4DisplayStatus@2@@Z)    BasicLocator    C:\Users\Desktop02\Documents\Visual Studio 2019\maya_dev\complete_maya_programming_volume1\BasicLocator\BasicLocator.obj    1   
Error   LNK2019 unresolved external symbol __imp_glPushAttrib referenced in function "public: virtual void __cdecl BasicLocator::draw(class M3dView &,class MDagPath const &,enum M3dView::DisplayStyle,enum M3dView::DisplayStatus)" (?draw@BasicLocator@@UEAAXAEAVM3dView@@AEBVMDagPath@@W4DisplayStyle@2@W4DisplayStatus@2@@Z)   BasicLocator    C:\Users\Desktop02\Documents\Visual Studio 2019\maya_dev\complete_maya_programming_volume1\BasicLocator\BasicLocator.obj    1   
Error   LNK2019 unresolved external symbol __imp_glVertex3f referenced in function "public: virtual void __cdecl BasicLocator::draw(class M3dView &,class MDagPath const &,enum M3dView::DisplayStyle,enum M3dView::DisplayStatus)" (?draw@BasicLocator@@UEAAXAEAVM3dView@@AEBVMDagPath@@W4DisplayStyle@2@W4DisplayStatus@2@@Z) BasicLocator    C:\Users\Desktop02\Documents\Visual Studio 2019\maya_dev\complete_maya_programming_volume1\BasicLocator\BasicLocator.obj    1   
Error   LNK1120 5 unresolved externals  BasicLocator    C:\Users\Desktop02\Documents\Visual Studio 2019\maya_dev\complete_maya_programming_volume1\BasicLocator\BasicLocator.mll    1   

Затем я услышал, что технически говоря, для сборок Maya API гораздо безопаснее использовать VS 2017, и это очевидно создание файлов решений безопаснее делать с помощью чего-то вроде CMake, я попытался создать новый проект с помощью этих файлов cmake:

FindMaya.cmake:

if(NOT DEFINED MAYA_VERSION)
    set(MAYA_VERSION 2015 CACHE STRING "Maya version")
endif()

set(MAYA_COMPILED_DEFINITIONS "REQUIRE_IOSTREAM;_BOOL")

set(MAYA_INSTALL_BASE_SUFFIX "")
set(MAYA_LIB_SUFFIX "lib")
set(MAYA_INC_SUFFIX "include")
if(WIN32)
    # Windows
    set(MAYA_INSTALL_BASE_DEFAULT "C:/Program Files/Autodesk")
    set(OPENMAYA OpenMaya.lib)
    set(MAYA_COMPILED_DEFINITIONS "${MAYA_COMPILED_DEFINITIONS};NT_PLUGIN")
    set(MAYA_PLUGIN_EXTENSION ".mll")
elseif(APPLE)
    # Mac
    set(MAYA_INSTALL_BASE_DEFAULT "/Applications/Autodesk")
    set(OPENMAYA libOpenMaya.dylib)
    set(MAYA_LIB_SUFFIX "Maya.app/Contents/MacOS")
    set(MAYA_INC_SUFFIX "devkit/include")
    set(MAYA_COMPILED_DEFINITIONS "${MAYA_COMPILED_DEFINITIONS};OSMac_")
    set(MAYA_PLUGIN_EXTENSION ".bundle")
else(WIN32)
    # Linux
    # this is OLD CMake syntax where the last else statement must match the first if statement
    set(MAYA_INSTALL_BASE_DEFAULT "/usr/autodesk")
    set(MAYA_INSTALL_BASE_SUFFIX -x64)
    set(OPENMAYA libOpenMaya.so)
    set(MAYA_PLUGIN_EXTENSION ".so")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif()

set(MAYA_INSTALL_BASE_PATH ${MAYA_INSTALL_BASE_DEFAULT} CACHE STRING "Root Maya installation path")
set(MAYA_LOCATION ${MAYA_INSTALL_BASE_PATH}/MAYA${MAYA_VERSION}${MAYA_INSTALL_BASE_SUFFIX})

find_path(MAYA_LIBRARY_DIR ${OPENMAYA}
    PATHS
        ${MAYA_LOCATION}
        $ENV{MAYA_LOCATION}
    PATH_SUFFIXES
        "${MAYA_LIB_SUFFIX}/"
    DOC "Maya Library Path"
)

find_path(MAYA_INCLUDE_DIR maya/MFn.h
    PATHS
        ${MAYA_LOCATION}
        $ENV{MAYA_LOCATION}
    PATH_SUFFIXES
        "${MAYA_INC_SUFFIX}/"
    DOC "Maya Include Path"
)

set(_MAYA_LIBRARIES OpenMaya OpenMayaAnim OpenMayaFX OpenMayaRender OpenMayaUI Foundation)
foreach(MAYA_LIB ${_MAYA_LIBRARIES})
    find_library(MAYA_${MAYA_LIB}_LIBRARY NAMES ${MAYA_LIB} PATHS ${MAYA_LIBRARY_DIR} NO_DEFAULT_PATH)
    set(MAYA_LIBRARIES ${MAYA_LIBRARIES} ${MAYA_${MAYA_LIB}_LIBRARY})
endforeach()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Maya DEFAULT_MSG MAYA_INCLUDE_DIR MAYA_LIBRARIES)

function(MAYA_PLUGIN _target)
    if(WIN32)
        set_target_properties(${_target} PROPERTIES
            LINK_FLAGS "/export:initializePlugin /export:uninitializePlugin")
    endif()
    set_target_properties(${_target} PROPERTIES
        COMPILE_DEFINITIONS "${MAYA_COMPILED_DEFINITIONS}"
        PREFIX ""
        SUFFIX ${MAYA_PLUGIN_EXTENSION}
    )
endfunction()

BasicLocator / CMakeLists.txt:

cmake_minimum_required(VERSION 2.6)
project(basicLocatorCmake)

set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/modules)

add_subdirectory(src)

BasicLocator / src / CMakeLists.txt:

set(SOURCE_FILES
    "PluginMain.cpp"
    "BasicLocator.cpp"
    "BasicLocator.h"
)

find_package(Maya REQUIRED)

include_directories(${MAYA_INCLUDE_DIR})
link_directories(${MAYA_LIBRARY_DIR})

add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${MAYA_LIBRARIES})

MAYA_PLUGIN(${PROJECT_NAME})

Похоже, это прекрасно создает решение проекта Visual Studio, но при компиляции я получил похожие ошибки (за вычетом предупреждений ):

Severity    Code    Description Project File    Line    Suppression State
Error   LNK1120 5 unresolved externals  basicLocatorCmake   C:\Users\Desktop02\Documents\Visual Studio 2017\maya_dev\complete_maya_programming_volume1\BasicLocator_cmake\build\src\Debug\basicLocatorCmake.mll 1   
Error   LNK2019 unresolved external symbol __imp_glBegin referenced in function "public: virtual void __cdecl BasicLocator::draw(class M3dView &,class MDagPath const &,enum M3dView::DisplayStyle,enum M3dView::DisplayStatus)" (?draw@BasicLocator@@UEAAXAEAVM3dView@@AEBVMDagPath@@W4DisplayStyle@2@W4DisplayStatus@2@@Z)    basicLocatorCmake   C:\Users\Desktop02\Documents\Visual Studio 2017\maya_dev\complete_maya_programming_volume1\BasicLocator_cmake\build\src\BasicLocator.obj    1   
Error   LNK2019 unresolved external symbol __imp_glEnd referenced in function "public: virtual void __cdecl BasicLocator::draw(class M3dView &,class MDagPath const &,enum M3dView::DisplayStyle,enum M3dView::DisplayStatus)" (?draw@BasicLocator@@UEAAXAEAVM3dView@@AEBVMDagPath@@W4DisplayStyle@2@W4DisplayStatus@2@@Z)  basicLocatorCmake   C:\Users\Desktop02\Documents\Visual Studio 2017\maya_dev\complete_maya_programming_volume1\BasicLocator_cmake\build\src\BasicLocator.obj    1   
Error   LNK2019 unresolved external symbol __imp_glPopAttrib referenced in function "public: virtual void __cdecl BasicLocator::draw(class M3dView &,class MDagPath const &,enum M3dView::DisplayStyle,enum M3dView::DisplayStatus)" (?draw@BasicLocator@@UEAAXAEAVM3dView@@AEBVMDagPath@@W4DisplayStyle@2@W4DisplayStatus@2@@Z)    basicLocatorCmake   C:\Users\Desktop02\Documents\Visual Studio 2017\maya_dev\complete_maya_programming_volume1\BasicLocator_cmake\build\src\BasicLocator.obj    1   
Error   LNK2019 unresolved external symbol __imp_glPushAttrib referenced in function "public: virtual void __cdecl BasicLocator::draw(class M3dView &,class MDagPath const &,enum M3dView::DisplayStyle,enum M3dView::DisplayStatus)" (?draw@BasicLocator@@UEAAXAEAVM3dView@@AEBVMDagPath@@W4DisplayStyle@2@W4DisplayStatus@2@@Z)   basicLocatorCmake   C:\Users\Desktop02\Documents\Visual Studio 2017\maya_dev\complete_maya_programming_volume1\BasicLocator_cmake\build\src\BasicLocator.obj    1   
Error   LNK2019 unresolved external symbol __imp_glVertex3f referenced in function "public: virtual void __cdecl BasicLocator::draw(class M3dView &,class MDagPath const &,enum M3dView::DisplayStyle,enum M3dView::DisplayStatus)" (?draw@BasicLocator@@UEAAXAEAVM3dView@@AEBVMDagPath@@W4DisplayStyle@2@W4DisplayStatus@2@@Z) basicLocatorCmake   C:\Users\Desktop02\Documents\Visual Studio 2017\maya_dev\complete_maya_programming_volume1\BasicLocator_cmake\build\src\BasicLocator.obj    1   
· 1029 на самом деле, кажется, не так много.

Может ли кто-нибудь указать мне правильное направление относительно того, как разрешить такого рода конфликты ...?

Редактировать # 1: Забыл упомянуть, но я использую Maya 2016.5

1 Ответ

0 голосов
/ 07 августа 2020

В результате дальнейшего исследования я обнаружил, что в последних версиях Maya для правильного рисования в окне просмотра Legacy вам необходимо указать указатель на объект визуализации из MHardwareRenderer (?). Вот код заголовка и cpp файлов этого плагина, которые теперь работают

basicLocator.h:

//
// Copyright (C) 2001 David Gould 
//
#ifndef BASICLOCATOR_H
#define BASICLOCATOR_H

#include <maya/MPxLocatorNode.h> 
#include <maya/MString.h> 
#include <maya/MTypeId.h> 
#include <maya/MVector.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/M3dView.h>
#include <maya/MDistance.h>
#include <maya/MFnUnitAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnMessageAttribute.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MPxManipContainer.h>
#include <maya/MPointArray.h>
#include <maya/MPlug.h>
#include <maya/MGlobal.h>
#include <math.h>

// legacy viewport includes
#include <maya/MHardwareRenderer.h>
#include <maya/MGLFunctionTable.h>

class BasicLocator : public MPxLocatorNode
{
public:
    virtual void draw( M3dView & view, const MDagPath & path, M3dView::DisplayStyle style, M3dView::DisplayStatus status );
    
    virtual bool isBounded() const;
    virtual MBoundingBox boundingBox() const; 

    static void *creator();
    static MStatus initialize();

    static const MTypeId typeId;
    static const MString typeName;

    // Attributes
    static MObject xWidth;
    static MObject zWidth;
    static MObject dispType;

private:
    bool getCirclePoints( MPointArray &pts ) const;
};


#endif

basicLocator. cpp

//
// Copyright (C) 2001 David Gould 
// 

#include "BasicLocator.h"
#include <maya/MGlobal.h>
#include <maya/MPointArray.h>
#include <maya/MFnDagNode.h>

const MTypeId BasicLocator::typeId( 0x00336 );
const MString BasicLocator::typeName( "basicLocator" );

MObject BasicLocator::xWidth;
MObject BasicLocator::zWidth;
MObject BasicLocator::dispType;

const double M_2PI = M_PI * 2.0;

bool BasicLocator::getCirclePoints( MPointArray &pts ) const
{
MStatus stat;
MObject thisNode = thisMObject();
MFnDagNode dagFn( thisNode  );  

MPlug xWidthPlug = dagFn.findPlug( xWidth, &stat );
float xWidthValue;
xWidthPlug.getValue( xWidthValue );

MPlug zWidthPlug = dagFn.findPlug( zWidth, &stat );
float zWidthValue;
zWidthPlug.getValue( zWidthValue );

MPlug typePlug = dagFn.findPlug( dispType, &stat );
short typeValue;
typePlug.getValue( typeValue );

unsigned int nCirclePts;

switch( typeValue )
   {
   case 0:
       nCirclePts = 4;
       break;
   case 1:
       nCirclePts = 5;
       break;
   default:
       nCirclePts = 20;
       break;
   }

pts.clear();
pts.setSizeIncrement( nCirclePts );
   
MPoint pt;
pt.y = 0.0;
   
const double angleIncr = M_2PI / (nCirclePts - 1);
double angle = 0.0;
unsigned int i=0;
for( ; i < nCirclePts; i++, angle+=angleIncr )
    {
    pt.x = xWidthValue * cos( angle );
    pt.z = zWidthValue * sin( angle );
    pts.append( pt );
    }

return true;
}

void BasicLocator::draw( M3dView & view, const MDagPath & path,
M3dView::DisplayStyle style, M3dView::DisplayStatus status )
{ 

// we need to add this to make sure Maya grabs the OpenGL commands
// we also need to make sure that all OpenGL commands are being used from gGLFT
static MGLFunctionTable *gGLFT = 0;
if (0 == gGLFT)
    gGLFT = MHardwareRenderer::theRenderer()->glFunctionTable();
//

view.beginGL(); 
gGLFT->glPushAttrib( GL_CURRENT_BIT );

MPointArray pts;
getCirclePoints( pts );

gGLFT->glBegin(GL_LINE_STRIP);
for( unsigned int i=0; i < pts.length(); i++ )
    gGLFT->glVertex3f( float(pts[i].x), float(pts[i].y), float(pts[i].z) );
gGLFT->glEnd();

gGLFT->glBegin(GL_LINES);
    gGLFT->glVertex3f( -0.5f, 0.0f, 0.0f );
    gGLFT->glVertex3f( 0.5f, 0.0f, 0.0f );

    gGLFT->glVertex3f( 0.0f, 0.0f, -0.5f );
    gGLFT->glVertex3f( 0.0f, 0.0f, 0.5f );
    gGLFT->glEnd();

gGLFT->glPopAttrib();
view.endGL();       
}

bool BasicLocator::isBounded() const
{ 
return true;
}

MBoundingBox BasicLocator::boundingBox() const
//
// N.B. It is important to have this bounding box function otherwise zoom selected and 
// zoom all won't work correctly.
//
{   
MPointArray pts;
getCirclePoints( pts );

MBoundingBox bbox;
for( unsigned int i=0; i < pts.length(); i++ )
    bbox.expand( pts[i] );
return bbox;
}


void *BasicLocator::creator()
{
return new BasicLocator();
}

MStatus BasicLocator::initialize()
{ 
MFnUnitAttribute unitFn;    
MFnNumericAttribute numFn;
MStatus stat;
    
xWidth = unitFn.create( "xWidth", "xw", MFnUnitAttribute::kDistance );
unitFn.setDefault( MDistance(1.0, MDistance::uiUnit()) );
unitFn.setMin( MDistance(0.0, MDistance::uiUnit()) );
unitFn.setKeyable( true );
stat = addAttribute( xWidth );
if (!stat) 
    {
    stat.perror( "Unable to add \"xWidth\" attribute" );
    return stat;
    } 

zWidth = unitFn.create( "zWidth", "zw", MFnUnitAttribute::kDistance );
unitFn.setDefault( MDistance(1.0, MDistance::uiUnit()) );
unitFn.setMin( MDistance(0.0, MDistance::uiUnit()) );
unitFn.setKeyable( true );
stat = addAttribute( zWidth );
if (!stat) 
    {
    stat.perror( "Unable to add \"zWidth\" attribute" );
    return stat;
    } 

dispType = numFn.create( "dispType", "att", MFnNumericData::kShort );
numFn.setDefault( 0);
numFn.setMin( 0 );
numFn.setMax( 2 );
numFn.setKeyable( true );
stat = addAttribute( dispType );
if (!stat) 
    {
    stat.perror( "Unable to add \"dispType\" attribute" );
    return stat;
    }

return MS::kSuccess;
}

Теперь как то, что haggi krey указано, поскольку Maya использует Viewport 2.0, эти методы рисования больше не актуальны, поэтому обновлю этот билет, как только я найду эквивалент этого плагина Viewport 2.0 ...

...