vb.netapisolidworkssolidworksapi

Adding new members and extending methods in an external API interface


I am building an VB.NET application in Visual Studio using SOLIDWORKS API - my application connects to SOLIDWORKS application via COM, and performs some actions in it using various API calls. The API is accessed by adding project references to SOLIDWORKS .dll files. These files must be embedded to the executable of my application for legal reasons.

This question is not specific to that API, but I will try to explain what I want to do. There is a SOLIDWORKS API interface called Body2 that governs manipulation of model objects (bodies) in 3D space. For example, Body2 interface provides a method ApplyTransform that allows moving or rotating a certain body by applying a MathTransform (a transform matrix) to it:

ModelBody.ApplyTransform(rotationMatrix) 'rotates the body

Now, the Body2 objects do not store these transformation matrices - they are applied and forgotten. However, in my application, I need to persistently store that information, so that at some point, I can reverse all transformations, and return the body to it's original position.

Therefore, I want to extend the Body2 interface by adding a new property to it, called "CombinedTransformMatrix", so that every time I call ApplyTransform, I could also update the value of this property, for example:

ModelBody.ApplyTransform(rotationMatrix)
ModelBody.CombinedTransformMatrix.Multiply(rotationMatrix)
ModelBody.ApplyTransform(translationMatrix)
ModelBody.CombinedTransformMatrix.Multiply(translationMatrix)

And when I finally want to return the body to it's original position, I could call:

ModelBody.ApplyTransform(ModelBody.CombinedTransformMatrix.Inverse)
ModelBody.CombinedTransformMatrix = New MathTransform 'reset matrix

Ideally, it would be really nice to also extend the ApplyTransform method, so that it would update the CombinedTransformMatrix automatically, for example:

Overrides Function ApplyTransform(Xform As MathTransform) As Boolean
   'Do whatever SOLIDWORKS does in this function

   'My additional code:
   Me.CombinedTransformMatrix.Multiply(Xform)
End function

(I know I should do an extension rather than an override, but I don't know how)

If this is possible, then I could simplify the code for the body transformations, as the CombinedTransformMatrix would update automatically:

'Rotate and move
ModelBody.ApplyTransform(rotationMatrix)
ModelBody.ApplyTransform(translationMatrix)

'Return to original position
ModelBody.ApplyTransform(ModelBody.CombinedTransformMatrix.Inverse)
ModelBody.CombinedTransformMatrix = New MathTransform 'reset matrix

I would very much prefer this kind of a solution instead of creating some derived class from Body2, or making some kind of a wrapper class that stores CombinedTransformMatrix outside the Body2 object. I want to store that bit inside the object itself. As for derived class, Visual Studio doesn't even allow me to inherit from Body2 - says "'Body2Class' is not allowed when its assembly is configured to embed interop types.". And I must embed these .dll files because otherwise I would have to ship them along the .exe of my application, which is legally prohibited by SOLIDWORKS.

Is what I want possible? Can I add that CombinedTransformMatrix to the Body2 interface without creating a derived class? And is it possible to extend that ApplyTransform method with my additional code without knowing how that method is implemented?

If not, what is the next best solution to achieve what I want? Like I said, I would very much like to avoid wrappers or additional variables outside of Body2, because there will be lots of these Body2 objects, they will persist throughout the application's lifetime, each will have a different transformation, so having to store their transformation information outside themselves would seriously complicate my code.


Solution

  • There is no universal way of doing this. You can maintain the separate dictionary with your COM object (e.g. IBody2 in this case) to be a key and the additional parameters (tags) to be a value. You will need to manually update the dictionary to remove the data when the pointer is destroyed. There are however some specific SW interfaces that do have some ways to associate custom data (similar to tags). For instance, IBody2 has the IBody2::AddPropertyExtension2 which allows associating custom data with the body itself, IEntity has the IEntity::CreateStringAttributeDefinition (note, this is not documented method) etc.

    But there is no something like universal System::Windows::Forms::Tag property for Windows Controls or Dependency Property for DependencyObjects exists for COM classes.