7 Replies Latest reply on Mar 18, 2016 6:07 AM by Artem Taturevych

    Why does IFace2::GetTessTriStrips sometimes return System.DBNull

    Brad Phelan

      I'm trying to render some IBody2 objects using opengl in the BufferSwap callback. I do this by iterating the faces and calling

       

         face.GetTessTriStrips

       

      For some of my bodies this works and I can render the triangle strips successfully with opengl using OpenTK. With other bodies the call just returns System.DBNull. It's like the tessellation of the face has not been performed. I would then expect to find an API call to force tessellation but I can't find it.  Is there an API to force tessellation on a face when in the context of the BufferSwap callback.

       

      Maybe the bufferswap callback is the wrong place to get the tessellation data.

       

      My scene is pretty simple. I have a concurrent dictionary to store my bodies to render

       

              public static ConcurrentDictionary<IBody2, Tuple<IBody2, Color>> BodiesToRender = new ConcurrentDictionary<IBody2, Tuple<IBody2,Color>>();

       

      and a static method to display them. This returns a disposable that when disposed removes the body from the scene.

       

              public static IDisposable DisplayUndoable(IBody2 body, Color? color)

              {

                  BodiesToRender[body]=Tuple.Create(body,(color ?? Color.Yellow));

                  return Disposable.Create(() =>

                  {

                      Tuple<IBody2, Color> dummy;

                      BodiesToRender.TryRemove(body, out dummy);

                  });

              }

       

       

      and in BufferSwap I have

       

              private int OnBufferSwapNotify()

              {

                  foreach (var o in BodiesToRender.Values)

                  {

                      var b = o.Item1;

                      MeshRender.Render(b.GetFaces().CastArray<IFace2>(), _ISwApp, o.Item2, 2.0f);

                  }

            }

       

      The MeshRender.Render method is the one that calls GetTessTriStrips.

        • Re: Why does IFace2::GetTessTriStrips sometimes return System.DBNull
          Artem Taturevych

          If you are using temp body it must be displayed in order to get the tesselation from it. if you are using regular bodies make sure they are not hidden.

            • Re: Why does IFace2::GetTessTriStrips sometimes return System.DBNull
              Brad Phelan

              Hi Artem,

               

              This doesn't make any sense. The API call generates a tristrips object that is specifically suitable for the opengl tristrips primitive.

               

              2016 SOLIDWORKS API Help - GetTessTriStrips Method (IFace2)

               

              What would be the purpose of displaying the object first with Display3, then to get the tristrips and render it with opengl? Note that you have previously told me that I should not be using Display3 to do any kind of animation and I should use opengl. Now we have gone and learned how to use opengl and you are telling me that I should be using Display3 again because it is not possible to get the tessellation data. This seems like I am going around in circles here.

               

              My use case is that I am designing a custom tool path generator. I have a model of a part and I want to perform some operations with a tool that has been generated with IModeler. I have a property manager page which aligns the tool with the part and I want to render the tool position as I change the properties in the page. If I use display3 to do this then it is very slow to update the screeen as the user quickly adjusts the position. If I use opengl it is very fast but I can't get the tessellation data for the tool.

               

              What do you suggest here?

                • Re: Why does IFace2::GetTessTriStrips sometimes return System.DBNull
                  Artem Taturevych

                  Hi Brad,

                   

                  Note that you have previously told me that I should not be using Display3

                  I think you are really missing the point of the public forum vs paid consultancy. Any answers here should only be considered as a reference resource. I gave you my suggestions based on my experience.

                   

                  Finally I believe you misunderstood my suggestion. This is the quote you are talking about

                  The temp bodies are not meant to be used for dynamic animations. Use OpenGL to render your moving graphics instead.

                  I told that the temp bodies should not be used for animation rather OpenGL animation. So in other words you can use temp body to get the 'snapshot' of BREP data and transform it purely via OpenGL rather than ApplyTransform.

                   

                  I do not know what your project is about and how you build the models (you could be using your own 3d kernel and do not need the modeler thus you have your tessellation data ready). But if you still want to use temp bodies produced from modeler you can display them, get tessellation, and destroy. Now you can use OpenGL transformation to animate your OGL data (so you will get the maximum performance).

                   

                  Thanks,

                  Artem

                    • Re: Why does IFace2::GetTessTriStrips sometimes return System.DBNull
                      Brad Phelan

                      Hi Artem,

                       

                      I have a solution that works for us at the moment. The ITesselation interface works all the time but it is slow because of the number of COM calls. I've written a wrapper for IBody2 that uses ITesselation to create an initial tessellation but also has an ApplyTransform method that works on the tessellated data as well as the IBody2 so I don't have to again tessellate if I'm only doing an affine transform.

                       

                      I'm not well versed enough with opengl to do the transform at hardware level but transforming the mesh seems to be performant enough at the moment.

                       

                      With regards to your feeling that we are using the forums inappropriately, I can only say that most of what we learn about the solidworks API we are giving back to the community via this library.

                       

                      GitHub - Weingartner/SolidworksAddinFramework

                       

                      which is a continual work in progress and will contain our work with regards to opengl rendering of IBody2 primitives. For example our work with opengl can be found here.

                       

                      SolidworksAddinFramework/SolidworksAddinFramework/OpenGl at master · Weingartner/SolidworksAddinFramework · GitHub

                        • Re: Why does IFace2::GetTessTriStrips sometimes return System.DBNull
                          Artem Taturevych

                          Hi Brad,

                           

                          I didn't meant that you are using the forum inappropriately. What I meant that you should not expect the completely correct/'bullet proof' answer on the forum and still should rely on your own research to make a decision towards the ways to resolve the problem.

                           

                          The GitHub source code you are publishing is definitely the valuable contribution to the SolidWorks community.

                           

                          I glad you get it resolved. I think the reason why it works for the invisible body is that ITesselation is completely recalculates the mesh (the same reason why it is slower) while GetTessTiStrips is trying to get the already generated mesh (and if the body was never displayed mesh was never generated).

                           

                          Thanks,

                          Artem

                    • Re: Why does IFace2::GetTessTriStrips sometimes return System.DBNull
                      Brad Phelan

                      The other alternative that I have tried is to use

                      2016 SOLIDWORKS API Help - ITessellation Interface Members

                      This does always work. However. It is very very slow because you need to make a COM call for every vertex. There is no way to dump the entire triangle data as a single array.