user3696118
user3696118

Reputation: 353

Maya API: How to resolve these unresolved external symbol issues?

I am trying to learn Maya C++ API, and was able to compile a few simple "Hello World" type plugins using this tutorial: https://nccastaff.bournemouth.ac.uk/jmacey/MayaAPI/Windows/index.md.html

I then tried to compile this plugin that was apparently from the "Complete Maya Programming" book published in 2003:

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

I took the .cpp and .h files and attempted to build the newly created Visual Studio 2019 project, but I got the following errors:

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   

I then heard that technically speaking for Maya API builds, it is far safer to use VS 2017, and that apparently creating solution files are safer to do via something like CMake, i attempted to create a new project via these cmake files:

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})

This seems to create a Visual Studio project solution just fine, but when i compile i got similar looking errors (minus the warnings):

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   

I have a feeling this has something to do with these .cpp files being out of date some where since they were written in 2003, but I cannot decipher where exactly those "outdated" sections lies as trying to search up M3dView doesn't really seem to come up with much.

Can any one point me to the the right direction as to how to resolve these sort of conflicts...?

Edit#1: Forgot to mention, but i am using Maya 2016.5

Upvotes: 0

Views: 1079

Answers (1)

user3696118
user3696118

Reputation: 353

From further research i've found that in recent versions of Maya to draw on the Legacy viewport properly you need to specify a pointer to a render object from MHardwareRenderer(?). Here is the code for the header and cpp files of this plugin now working

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;
}

now like what haggi krey stated since Maya uses Viewport 2.0, these methods of drawing is no longer relevant, so will update this ticket once i find the Viewport 2.0 equivalent of this plugin...

Upvotes: 0

Related Questions