2 Replies Latest reply on Feb 18, 2016 3:18 PM by Yc Lim

    Custom OpenGL Rendering of SW MacroFeature objects

    Yc Lim


      I'm a C++/C# developer but completely new to Solidworks and just started learning the API.   My goal is to create a solidworks addin that can import in STL meshes and Point clouds and render them in OpenGL similar to the ScanToCAD addin.


      So by downloading the examples online I am able to create a working C# addin and implemented some basic OpenGL rendering to make sure everything works however, the Solidworks object model is very confusing to me so I'm unsure how to best solve my problem.


      1) I want to use InsertMacroFeature3 as my standin object to represent the mesh that I will import in the Solidworks tree. This appears to work but how do i track the Transform of my objects and render it in the right position by OGL?  Right now my test object is unrotated and resting at 0,0,0 so my OGL rendering is of course correct. If i move or rotate the object inside of solidworks, I need to be able to track and update my rendering.


      Simply put, i need to track down the 3D world position of my object in Solidworks space and be able to apply that transform when i render in openGL, but I'm very confused the functionality in objects between ModelDoc, Features, Bodies, and Component2 objects.  It looks like the Commponent2 object is able to get me a transform but I have no ideal how to get there the Feature / Body that I have.  I tried using the Feature.GetSpecificFeature2 and casting it as recommended but it always returns null.


      2) Best way to add custom data to a Feature / object in the world?

      I'm able to create a  custom objects in to the feature tree using InsertMacroFeature3, it appears this is the best way to approach things, however I wish to tag my feature with additional variable data.  I thought i could setup a separate lookup table using Feature.GetID but i'm unsure what would happen on document save / open. I'm guessing i need to save out my data separately somewhere? Alternatively i can use DefineAttribute / and then the solidworks Attribute function to get back the data. However, iFeature.GetSpecificFeature2  when cast back to an IAttribute always returns back null.  So i'm able to store the feature, but I can't seem to read the feature back.  I followed this example here, but instead of attaching the attribute to the face, i just attached it straight to the feature.




      This is all new to me so i'm unsure if I'm approaching the problem correctly.


      Thanks for any help

        • Re: Custom OpenGL Rendering of SW MacroFeature objects
          Artem Taturevych



          Let me firstly answer your second question. You can store custom attributes from within your macro feature definitions. To get the definition from the pointer to feature call IFeature::GetDefinition this will return you the IMacroFeatureData interface. You may find several methods there to work with parameters such as MacroFeatureData::GetParameters. You can define the parameters and types within the FeatureManager::InsertMacroFeature3 method.


          Regarding the transformation. There is a number of properties within the macro feature definition for handling the transformation. Please see below:






          However all of those methods are not suitable for you. They are intended to be used when macro feature rebuilds. While in your case you do not generate any bodies within the macro feature and most likely won't assign any references to your feature.


          In addition, OpenGL can only be rendered in the active view. So if you have a part with the macro feature inserting and two instances of this part in the assembly you need to handle this entirely on the assembly level. What I would suggest you to do is the following


          • When assembly activated/opened (you have notification for that) traverse all components to find your macro features by type and definitions (IAssemblyDoc::GetComponents)
          • Having the pointer to IFeature you can find the corresponding component via Entity::GetComponent (or just store the association while traversing the components). Having the pointer to IComponent2 you can find its transformation via Component2::Transform2.
          • Now you can render your instances considering the transformations.




          • You may have problems with performance because traversing of components will require some time
          • You need to listen for the events when components moved/added/deleted to update your previews
          • Take a look at SolidWorks 3rd party storage (2012 SOLIDWORKS API Help - IGet3rdPartyStorage Method (IModelDoc2)) as an alternative for storing the mesh data inside the file (if you do not want to link to the input STL file).




            • Re: Custom OpenGL Rendering of SW MacroFeature objects
              Yc Lim

              Hi Artem,


              Thank you for the detailed reply.  I looked in to MacroFeatureData::FeatureTransform yesterday and discovered what you told me. The transforms were not suitable for me. Or more importantly all the transforms returned Identity no matter what changes I made in my object. 


              After posting the message yesterday, I realized that there is a difference between a part document and an assembly document in that the part document, even if you use the Copy/Move feature, it really just generates a new feature versus doing any changes to the root feature, it never actually moves your part in respect to the root co-ordinate space.


              I will try your suggestion for searching for the part when inside an Assembly document.


              Thanks for the tip regarding Get3rdPartyStorage method, I was looking at it and I think doing what you suggested will work.  I can use MacroFeatureData to store small lightweight variable data and I can use the 3rdPartyStorage to start large mesh data that gets imported in to the document.


              Thanks again for the help.