Unable to call MPxDeformerNode.weightValue in method defined outside class

Unable to call MPxDeformerNode.weightValue in method defined outside class

jmreinhart
Advisor Advisor
1,337 Views
9 Replies
Message 1 of 10

Unable to call MPxDeformerNode.weightValue in method defined outside class

jmreinhart
Advisor
Advisor

So I am making a custom deformer using the MPxDeformerNode class. When I define the "deform" method inside of the class I am able to call weightValue(...) without issue, but when I declare the method inside the class and then define it outside the class calling weightValue causes a linker error. I tested this by removing everything but the weightValue query from the deform method so I know that this is the issue.

 

Error LNK2019 unresolved external symbol "__declspec(dllimport) public: float __cdecl Autodesk::Maya::OpenMaya20180000::MPxDeformerNode::weightValue(class Autodesk::Maya::OpenMaya20180000::MDataBlock &,unsigned int,unsigned int)" (__imp_?weightValue@MPxDeformerNode@OpenMaya20180000@Maya@Autodesk@@QEAAMAEAVMDataBlock@234@II@Z) referenced in function "public: virtual class Autodesk::Maya::OpenMaya20180000::MStatus __cdecl offset::deform(class Autodesk::Maya::OpenMaya20180000::MDataBlock &,class Autodesk::Maya::OpenMaya20180000::MItGeometry &,class Autodesk::Maya::OpenMaya20180000::MMatrix const &,unsigned int)" (?deform@offset@@UEAA?

 

I've looked at some example deformers and they are able to call it in a function defined outside the class. 

I was able to find a forum post that seemed to be related to this same issue but the response to that post was "use cmake".

 

 

 

0 Likes
Accepted solutions (2)
1,338 Views
9 Replies
Replies (9)
Message 2 of 10

olarn
Advocate
Advocate

How about just  rewrite the original in-class weightValue so that it calls your external function.

 

0 Likes
Message 3 of 10

jmreinhart
Advisor
Advisor

Sorry I don't think I did a good job of explaining the problem I'm running into. The below code is what gives me a linker error.

 

class offset : public MPxDeformerNode
{
public:
	offset();
	virtual                         ~offset();

	static  void*           creator() { return new offset(); };
	static  MStatus         initialize() {};

	// deformation function
	virtual MStatus deform(MDataBlock&              block,
		MItGeometry&         iter,
		const MMatrix&       mat,
		unsigned int         multiIndex);

private:
};

MStatus offset::deform(MDataBlock& block, MItGeometry& iter, const MMatrix& mat, unsigned int multiIndex) 
{
	float x = weightValue(block, multiIndex, iter.index());
	return MS::kSuccess;
}

But this code does not give me a linker error

#include <maya/MPxDeformerNode.h> 
#include <maya/MItGeometry.h>

#include <maya/MFnMatrixData.h>

#include <maya/MFnPlugin.h>
#include <maya/MTypeId.h> 
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MMatrix.h>
#include <maya/MDagModifier.h>
#include <maya/MObject.h>


class offset : public MPxDeformerNode
{
public:
	offset();
	virtual                         ~offset();

	static  void*           creator() { return new offset(); };
	static  MStatus         initialize() {};

	static float weightValue(MDataBlock& block, unsigned int multiIndex, unsigned int compIndex);

	// deformation function
	MStatus offset::deform(MDataBlock& block, MItGeometry& iter, const MMatrix& mat, unsigned int multiIndex)
	{
		float x = weightValue(block, multiIndex, iter.index());
		return MS::kSuccess;
	}

private:
};

I think I'm just not understanding something about inheritance, nut I'm quite new to C++ so I may be wrong.

 

0 Likes
Message 4 of 10

olarn
Advocate
Advocate

Looks like the first example actually compiles.

Did you forget to remove this declaration? unless you intent (and forgot) to implement.

static  void*           creator() { return new offset(); };
	static  MStatus         initialize() {};

	static float weightValue(MDataBlock& block, unsigned int multiIndex, unsigned int compIndex);
	// deformation function
	MStatus offset::deform(MDataBlock& block, MItGeometry& iter, const MMatrix& mat, unsigned int multiIndex)
	{

Btw the second example weren't supposed to compile. What compiler were you using?

0 Likes
Message 5 of 10

jmreinhart
Advisor
Advisor

Oops I made a mistake when copying those codes, this is the one that DOES compile:

#include <maya/MPxDeformerNode.h> 
#include <maya/MItGeometry.h>

#include <maya/MFnMatrixData.h>

#include <maya/MFnPlugin.h>
#include <maya/MTypeId.h> 
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MMatrix.h>
#include <maya/MDagModifier.h>
#include <maya/MObject.h>


class offset : public MPxDeformerNode
{
public:
	offset();
	virtual                         ~offset();

	static  void*           creator() { return new offset(); };
	static  MStatus         initialize() {};

	MStatus deform(MDataBlock& block, MItGeometry& iter, const MMatrix& mat, unsigned int multiIndex)
	{
		float x = weightValue(block, multiIndex, iter.index());
		return MS::kSuccess;
	};

private:
};



This one that does NOT:

#include <maya/MPxDeformerNode.h> 
#include <maya/MItGeometry.h>

#include <maya/MFnMatrixData.h>

#include <maya/MFnPlugin.h>
#include <maya/MTypeId.h> 
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MMatrix.h>
#include <maya/MDagModifier.h>
#include <maya/MObject.h>


class offset : public MPxDeformerNode
{
public:
	offset();
	virtual                         ~offset();

	static  void*           creator() { return new offset(); };
	static  MStatus         initialize() {};

	// deformation function
	virtual MStatus deform(MDataBlock&              block,
		MItGeometry&         iter,
		const MMatrix&       mat,
		unsigned int         multiIndex);

private:
};

MStatus offset::deform(MDataBlock& block, MItGeometry& iter, const MMatrix& mat, unsigned int multiIndex)
{
	float x = weightValue(block, multiIndex, iter.index());
	return MS::kSuccess;

}

I am using visual studio 2017 to compile.

0 Likes
Message 6 of 10

jmreinhart
Advisor
Advisor

So I did some testing with reimplimenting weightValue inside and outside the class. Both work.

 

Does this function always need to be re-implimented?

Where in the documentation would I be able to see if it is required to re-impliment a certain method?

 

This is the setup that worked for me:

#include <maya/MPxNode.h>
#include <maya/MPxDeformerNode.h> 
#include <maya/MItGeometry.h>

#include <maya/MFnMatrixData.h>

#include <maya/MFnPlugin.h>
#include <maya/MTypeId.h> 
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MMatrix.h>
#include <maya/MDagModifier.h>
#include <maya/MObject.h>


class offset : public MPxDeformerNode
{
public:
	offset();
	virtual                         ~offset();

	static  void*           creator() { return new offset(); };
	static  MStatus         initialize() {};

	// deformation function
	virtual MStatus deform(MDataBlock&              block,
		MItGeometry&         iter,
		const MMatrix&       mat,
		unsigned int         multiIndex);

	float weightValue(MDataBlock& block, unsigned int multiIndex, unsigned int compIndex);

private:
};

float offset::weightValue(MDataBlock& block, unsigned int multiIndex, unsigned int compIndex)
{
	return 0;
};

MStatus offset::deform(MDataBlock& block, MItGeometry& iter, const MMatrix& mat, unsigned int multiIndex)
{
	float x = weightValue(block, multiIndex, iter.index());
	return MS::kSuccess;


}
0 Likes
Message 7 of 10

olarn
Advocate
Advocate

 

I can't replicate your issue. This is the entirety of one file plugin and it compiles (on vs2019, using vs2017 compiler)

 

#include <maya/MPxDeformerNode.h> 
#include <maya/MItGeometry.h>

#include <maya/MFnMatrixData.h>

#include <maya/MFnPlugin.h>
#include <maya/MTypeId.h> 
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MMatrix.h>
#include <maya/MDagModifier.h>
#include <maya/MObject.h>

const MTypeId TYPE_ID(123456);

class offset : public MPxDeformerNode
{
public:
  offset() {}
  ~offset() override {}

  static  void* creator() { return new offset(); }
  static  MStatus         initialize() { return MStatus::kSuccess; }

  // deformation function
  virtual MStatus deform(MDataBlock& block,
    MItGeometry& iter,
    const MMatrix& mat,
    unsigned int         multiIndex);

private:
};

MStatus offset::deform(MDataBlock& block, MItGeometry& iter, const MMatrix& mat, unsigned int multiIndex)
{
  float x = weightValue(block, multiIndex, iter.index());
  return MS::kSuccess;
}

MStatus initializePlugin(MObject obj) {
 MStatus status = MStatus::kSuccess;
 MFnPlugin plugin(obj, "AAA", "0.0", "Any");

 status = plugin.registerNode("test",
   TYPE_ID,
   offset::creator,
   offset::initialize);

 return status;
}

MStatus uninitializePlugin(MObject obj) {
 MStatus status = MStatus::kSuccess;
 MFnPlugin plugin(obj);

 status = plugin.deregisterNode(TYPE_ID);
 
 return status;
}

 

0 Likes
Message 8 of 10

jmreinhart
Advisor
Advisor

When I run the code you posted I get several linker errors. Below is one of them

 

Error LNK2019 unresolved external symbol "__declspec(dllimport) public: __cdecl Autodesk::Maya::OpenMaya20180000::MPxDeformerNode::MPxDeformerNode(void)" (__imp_??0MPxDeformerNode@OpenMaya20180000@Maya@Autodesk@@QEAA@XZ) referenced in function "public: __cdecl offset::offset(void)" (??0offset@@QEAA@XZ) Project3 C:\Users\Jonah\source\repos\test_node\Project3\test.obj 1

 

I'm going to delete my OpenMaya lib and re-download it and I guess look at my linker settings, because if it runs for you it must be an issue on my end.

0 Likes
Message 9 of 10

olarn
Advocate
Advocate
Accepted solution

Perhaps you forgot to add some necessary maya *.lib or not using a matching version?

grap this or one of the forks for easier project setup.

https://github.com/chadmv/cgcmake

0 Likes
Message 10 of 10

jmreinhart
Advisor
Advisor
Accepted solution

Based on your suggestion I checked the libraries I was bringing in and I had missed OpenMayaAnim.lib. I'm a bit confused as to why MPxNode is in OpenMaya.lib but MPxDefomerNode is an OpenMayaAnim.lib  but oh well.

 

I really appreciate all your patience and your help.