In a cpp plugin I am developing in Maya API, I register a custom MPxTransform Node in the initializePlugin function:
status=pluginFn.registerTransform("mympxtransform",
myMPxTransformClass::id,
&myMPxTransformClass::creator,
&myMPxTransformClass::initialize,
&myMPxTransformMatrixClass::creator,
myMPxTransformMatrixClass::id);
And then create the node programmatically:
MDagModifier mdagmod;
MObject MyMObject;
MyMObject=mdagmod.createNode("mympxtransform",MObject::kNullObj,&status);
I can see the node properly created in the outliner.
But now, how can I access my custom myMPxTransformClass from the obtained MyMObject ?
Solution To This Problem:
You would just have to do:
myMPxTransformClass* newDerived = (myMPxTransformClass*)&transformedObj; // 1)
// For debugging
MGlobal::displayInfo(newDerived->className());
1) What we do here is basically create a pointer of your class' type and assign to it the type casted pointer to the created MObject. The compiler wouldn't allow type-casting MObject itself, but the pointer to it can be type-casted into your class' pointer (myMPxTransformClass*).
We can then just use the pointer to access the class' methods and so on.
p.s. In the case of the dynamic_cast, attempting to cast MObject directly won't work because MObject is not a polymorphic type (intentionally).
Side Recommendation:
On a side note, I wanted to add this. This is mostly my opinion. Since I don't know what you are trying to do with your code, please take this recommendation with a grain of salt.
According to core Maya's principle,
Thou shall never access member functions of a node/MObject in Maya.
Once it has been created, it is solely under Maya's control. The only way you can (sort of) control it is using Maya's provided function sets (MFn Classes) for that node type (in your case MFnTransform set because your node is a kPluginTransformNode which is a transform node).
In the case you have class data members that you might want to operate with and manipulate programmatically, you will have to make them actual Maya attributes for that node (and thereby expose them to Maya). Then, you will be able to get them as MPlugs and do your thing.
Looking at your code, I feel that there are two components you are majorly aiming to produce, a node(s) (i.e. your custom MPxTransform); and a functor kind of class (i.e. UnitClass) that does something with/to your node(s). I would recommend splitting your plugin then into two separate components: a node and a command. That way there is clear separation of responsibilities. Because, as it stands right now, just loading your plugin creates the node(s) and also operates on them. The user might be confused as to what might be happening. If you separated them into a node and a command that does the thing, they can be used in many different ways as the user sees fit. The command could be the entry point for the user to use your plugin.
Hope this helps!
Here's another way of doing it using the api:
myMPxTransformClass* node= (myMPxTransformClass*)(MFnDependencyNode(myMObject).userNode());
Related
How do I create an object in python from a feature class in a geodatabase? I would think the following code would create a featureclass object?
featureclassobject = "C:/path/to/my/featureclass"
But this creates a string object, right? So I am not able to pass this object into an arcpy function later on.
You are correct that it creates a string object. However, whether it will work with a particular ArcPy function depends on the function -- in most cases, the tool simply needs to know the path to the function as a string (which the featureclassobject is).
The help pages are slightly unhelpful in this regard. Buffer, for example, says that input parameter in_features needs to be data type "Feature Layer" -- however, what it really expects is a string that describes where the feature layer can be found.
One significant exception to this is geometry objects:
In many geoprocessing workflows, you may need to run a specific operation using coordinate and geometry information but don't necessarily want to go through the process of creating a new (temporary) feature class, populating the feature class with cursors, using the feature class, then deleting the temporary feature class. Geometry objects can be used instead for both input and output to make geoprocessing easier.
But if you've already got a feature class (or shapefile) on disk, that's much simpler than creating an in-memory geometry object to work with.
My goal here is to create a unique ID (starting a 0) for each child of a specific class. I'm not sure if it is possible in the way i want, but i figured i'd ask here as a last resort.
Some context:
I'm creating my own 2D game engine and i want it to have an ECS as it's back bone (Before anyone says anything, i'm doing this as a learning experience, i know i could just use an already existing game engine). My idea is that each class that implements the 'EntityComponent' class should have a unique ID applied to it. This needs to be per child, not per object. I want to use this ID as the index for an array to find the component of an entity. The actual ID that each Component gets is unimportant and each component does not need to be assigned the ID every run time.
My hope is there is some way to create something similar to a static variable per class (That implements the Entity Component class). It needs to be quick to get this value so doing an unordered_map lookup is slower than i would like. One thing i do not want to do is setting the ID for every component myself. This could cause problems once many components are made and could cause problems if i forget to set it or set two components to the same ID.
One idea i had was to make a variable in EntityComponent called ID (And a getter to get it). When the entity is constructed it looks up an unordered map (which was made at run time, assigning an ID to each class) for what ID it should have. The price of looking up once at construction is fine. The only problem i see with this is there is a lot of redundant data (Though overall it seems it would account to a pretty small amount). With this, every single transform component would have to store that it its ID is x. This means potentially thousands upon thousands of transform components are storing this ID value, when only 1 really needs to.
Basically i am after an extremely quick way to find an ID for a class TYPE. This can be through a lookup, but it needs to be a quick lookup. I would like something faster than unordered_map if possible. If this can be done through compile time tricks (Maybe enums?) or maybe even templates i would love to hear your ideas. I know premature optimisation is the bad, but being able to get a component fast is a pretty big thing.
What i'm asking might very well be impossible. Just thought i'd ask here to make sure first. I should also note i'm trying to avoid implementation of this in the children classes. I'd like to not have to set up the same code for each child class to create an id.
Thank you.
In order to get something corresponding to the actual type of an object, it either needs to be in the object itself or accessed via a virtual function. Otherwise the type will be determined by the type of the variable it is associated with.
A common option when speed and size are both important is to have an integer identifier associated with each type (when the full type list is known at compile time) and use that integer value in a specific way when you want to do something based on the type.
The integer mechanism usually uses an enum for generating the corresponding value for each type and has that field in every object.
The virtual method variety, I've used boost::uuid and a static data member in each class and a virtual method get'er for it.
Declare a virtual function newId() in EntityComponent.
Implement this function to get and increment a static variable in each class, which children you want to have a unique Id.
Assign Id in the constructor:
mId = newId();
don't know this if this is what you meant and i know this is an old post however this is how im currently dealing with a similar issue, maybe it will help someone else.
(Im also doing this as a learning experience for uni :) )
in the controlling class or its own utility class:
enum class EntityType{ TYPE_ONE = 0, TYPE_TWO =1};
in class header:
#include "EntityType.h"
class Whatever{
public:
inline void getType(){return _type;}
OR
inline void getType(){return EntityType::TYPE_ONE;}
private:
EntityType _type = EntityType::TYPE_ONE;
};
Hope this is helpful to anyone :)
I'm a little new to writing in C so I hope I'm not to far off base here.
I'm working on a library to handle the control of multiple types of LED ICs. There are a ton of different types of RGB Pixel libraries each with their own unique naming, but all really perform the same basic actions. A "strip" or "strand" object is created, each pixel gets a color value set, and the strip then gets updated.
My library handles getting pixel color values from software in the back ground and providing the user with the most recent values from an array belonging to the object.
What I would like is to allow the user to initiate their LED strip object and pass a reference to that object to my library, and then allow them to pass their objects "setPixelColor()" function and "UpdateStrip()" function to the library as well. If this is achievable then I believe my library could then handle all of light control operations for any given PixelLibrary.
I believe what I'm looking for is the proper way to pass a functions pointer between objects? Not looking for someone to do this for me, but just looking for directed guidance. Been searching google for while this morning, but I don't know that I'm even using the proper terms. Any advice or guidance would be a big help. Thanks!
Sounds like what you need is a base class or virtual base/interface. You define a class with common data and methods which work across all your LEDs. This common or abstract class defines the common functions. Each of your LED strand types will then inherit the base class/interface and implement the specific functions to set an LED for example.
Using this approach the application code works using the Base class/interface methods treating all the strands the same way.
If you use this approach, I also recommend you create a static factory method which returns a base class/interface pointer after creating the specifically required object.
abstractController=CreateLEDStrandController("Strand Type");//Creates the right object, returns an abstracted base class pointer.
abstractController.SetLEDColor("RED"); //Actually calls the specific object SetLEDColor
I'm creating a C++ object serialization library. This is more towards self-learning and enhancements & I don't want to use off-the-shelf library like boost or google protocol buf.
Please share your experience or comments on good ways to go about it (like creating some encoding with tag-value etc).
I would like to start by supporting PODs followed by support to non-linear DSs.
Thanks
PS: HNY2012
If you need serialization for inter process communication, then I suggest to use some interface language (IDL or ASN.1) for defining interfaces.
So it will be easier to make support for other languages (than C++) too. And also, it will be easier to implement code/stub generator.
I have been working on something similar for the last few months. I couldn't use Boost because the task was to serialize a bunch of existing classes (huge existing codebase) and it was inappropriate to have the classes inherit from the interface which had the serialize() virtual function (we did not want multiple inheritance).
The approach taken had the following salient features:
Create a helper class for each existing class, designated with the task of serializing that particular class, and make the helper class a friend of the class being serialized. This avoids introduction of inheritance in the class being serialized, and also allows the helper class access to private variables.
Have each of the helper classes (let's call them 'serializers') register themselves into a global map. Each serializer class implements a clone() virtual function ('prototype' pattern), which allows one to retrieve a pointer to a serializer, given the name of the class, from this map. The name is obtained by using compiler-specific RTTI information. The registration into the global map is taken care of by instantiating static pointers and 'new'ing them, since static variables get created before the program starts.
A special stream object was created (derived from std::fstream), that contained template functions to serialize non-pointer, pointer, and STL data types. The stream object could only be opened in read-only or write-only modes (by design), so the same serialize() function could be used to either read from the file or write into the file, depending on the mode in which the stream was opened. Thus, there is no chance of any mismatch in the order of reading versus writing of the class members.
For every object being saved or restored, a unique tag (integer) was created based on the address of the variable and stored in a map. If the same address occurred again, only the tag was saved, not the deep-copied object itself. Thus, each object was deep copied only once into the file.
A page on the web captures some of these ideas shared above: http://www.cs.sjsu.edu/~pearce/modules/lectures/cpp/Serialization.htm. Hope that helps.
I wrote an article some years ago. Code and tools can be obsolete, but concepts can remain the same.
May be this can help you.
I'm very bad with recursion, never used it before. I know the theory of it .. not that that helps :)) For my problem i have a structure of TCollection that contains TCollection and TCollectionItem etc .. I have to write a recursion function that will read all my TCollectionItems.
Here is graphical view:
TCollection->TCollectionItem(s)->TCollection->TCollectionItem(s)
TCollection can have 1 or even 2,3 TCollection's under him OR none.
Here are few more examples:
TCollection->TCollectionItem
TCollection->TCollectionItem->TCollection->TCollectionItem->TCollection->TCollectionItem
etc ..
Please tell me if i described the problem badly, i probably did .. please ask if something is unclear :)
Thanks for the support!
You haven't indicated the prototypes of the TCollection methods so as to enumerate and to read your TCollectionItems, and other needed details.
However, this is definitely solved by: The Composite Design Pattern.
The aim of this pattern is to traverse a recursive form, and to forward a call on a composite onto its composants and so on, until that reaches the leaves ( TCollectionItems with an empty TCollection in your case)
The only way to recursively access child TCollection objects, without knowing the class types of the owning TCollectionItem objects so you can type-cast them, is to use the VCL's RTTI information.
In C++Builder versions prior to XE, VCL-based RTTI is only available for __published properties. Given a TCollectionItem (or any general TObject) object pointer, you can use the GetPropList() function declared in TypInfo.hpp to retreive a list of that object's published property information. You can then loop through that list, checking for any properties that report a TypeKind value of tkClass. When you find one, use the GetObjectProp() function to retreive that property's TObject pointer value, and then use dynamic_cast to make sure it is really a TCollection object before you access its child TCollectionItem objects.
In C++Builder 2010, a new Enhanced RTTI system was introduced, declared in Rtti.hpp, that provides information for all members of a class, including non-published properties and fields. With this enhanded RTTI, a child TCollection does not need to be declared as a __published property anymore. Under this system, you would use the TRttiContext class to access a TRttiType object for your recursion's starting TCollectionItem object, then use the TRttiType::GetFields() and TRttiType::GetProperties() methods to look for child TRttiField and TRttiProperty items that report a TypeKind of tkClass, then use the TRttiField::GetValue() and TRttiProperty::GetValue() methods to get the TObject object pointer that can be type-casted to a TCollection pointer with dynamic_cast.