Community Tip - Learn all about the Community Ranking System, a fun gamification element of the PTC Community. X
I'm trying to use the Surface Tessellation api's.
Surface Tessellation has the following functions
What I want to do is for a given surface, tesselate it with defined quality metrices, and then find information about the facets and vertices.
I would expect that I can write code that looks like this.
ProError err1 = ProSurfaceInit(m_pro_mdl, (int) SourceSequence, &pro_surface);
if(err1 == PRO_TK_NO_ERROR)
{
ProSurfaceTessellationInput *tessellationInput = new ProSurfaceTessellationInput();
err1 = ProSurfacetessellationinputAlloc(tessellationInput);
if (err1 != PRO_TK_NO_ERROR) return;
err1 = ProSurfacetessellationinputStepsizeSet(*tessellationInput, 1000);
if (err1 != PRO_TK_NO_ERROR) return;
err1 = ProSurfacetessellationinputChordheightSet(*tessellationInput, 0.0);
if (err1 != PRO_TK_NO_ERROR) return;
err1 = ProSurfacetessellationinputAnglecontrolSet(*tessellationInput, 0.0);
ProTessellation* tessellation = new ProTessellation();
err1 = ProSurfaceTessellationGet(pro_surface, *tessellationInput, tessellation);
}
I should then be able to use the ProTessellationFacetsGet and ProTessellationVerticesGet methods with the tessellation variable to get information about the tessellated facets and vertices. Like the following.
Pro3dPnt **vertices = NULL;
err1 = ProTessellationVerticesGet(*tessellation, vertices);
The problem I am having is that I get crashes about non existant memory problems whenever I try to call the any of the these functions
ProSurfacetessellationinputStepsizeSet
ProSurfacetessellationChordheightSet
ProSurfacetessellationinputAnglecontrolSet.
I can't figure out how to use this section of the API.
Wendell Duncan
Hi Wendell -
I haven't used any of the Creo Parametric Toolkit functions you mention here, but I did notice something that in your code that could be a problem:
ProSurfaceTessellationInput *tessellationInput = new ProSurfaceTessellationInput();
[ ... ]
ProTessellation* tessellation = new ProTessellation();
The new operator is not part of the C language; it's used to create objects in C++. C++ programmers use new to allocate and initialize objects using a class constructor, something that Creo Parametric Toolkit data structures do not have. Even though your compiler may accept what you're doing here, that doesn't mean the code will execute correctly.
If you don't need to use your ProSurfaceTessellationInput and ProTessellation variables after the current function exits, then the easiest way to write this code is to declare them as local variables:
ProSurfaceTessellationInput tessellationInput ;
err1 = ProSurfacetessellationinputAlloc( &tessellationInput ) ;
err1 = ProSurfacetessellationinputStepsizeSet( tessellationInput, 1000 ) ;
In this version, tesselationInput is a variable of type ProSurfaceTessalationInput instead of a pointer to that type. That's why you need the "&" to pass that variable's address to ProSurfacetessellationinputAlloc and you no longer need the "*" to dereference the pointer for ProSurfacetessellationinputStepsizeSet.
I don't know whether these changes will fix your problems, but it should make your code more manageable. Your code, as it's currently written, will cause memory leaks because you allocated memory using new but did not deallocate that memory with a corresponding delete.
|+| M a r k |+|
Looks like the outline of steps I had is correct. I found a bug in the function just above this one.
My issue is resolved.
Hi all,
The only reason for this reply is to prevent somebody copying the original code and using it.
Wendell,
Mark is correct. One should not be using C++ 'new' keyword in Pro/Toolkit. Although, it is not documented or even mentioned anywhere one could see PIMPL design pattern in quite a number of Pro/Toolkit functions. Please take a look at ProSrf.h header:
typedef struct pro_surface_tessellation_input* ProSurfaceTessellationInput;
typedef struct pro_tessellation* ProTessellation;
What is happening there is Pro/Toolkit developers are telling us that they are going to manage memory for tessellation task in their code and API users should not concern themselves with the stack/heap management...
What Mark is showing you :
ProSurfaceTessellationInput tessellationInput ;
err1 = ProSurfacetessellationinputAlloc( &tessellationInput ) ;
is the tessellationInput is a variable allocated on the stack which is going to hold a future address of an instance of structure pro_surface_tesselation_input which is going to be allocated on the heap with ProSurfacetessellationinputAlloc - and when the API user would subsequently call ProSurfacetessellationinputFree there would be no memory leak. Since the pointer of tessellationInput variable was passed by value to the ProSurfacetessellationinputAlloc function the value of the variable would be holding the correct heap address after the function run.
What your code was doing:
- allocate on the heap the variable which in the future would be storing the address of heap allocated pro_surface_tessellation_input structure:
ProSurfaceTessellationInput *tessellationInput = new ProSurfaceTessellationInput();
the compiler will see simply as sizeof( void*) on the heap and a pointer to the heap address is stored in stack allocated tessellationInput variable.
- the next statement makes it really dangerous you are passing the address of heap allocated void* by the value of stack variable and Pro/Toolkit allocates the proper pro_surface_tessellation_input structure on the heap and sets *tessellationInput which is undetermined because variable was passed as value ( most likely it would be the previously heap allocated address but I would not bet on it).
err1 = ProSurfacetessellationinputAlloc(tessellationInput);
if (err1 != PRO_TK_NO_ERROR) return;
This is the repeat of the same C++ approach, which should be avoided:
ProTessellation* tessellation = new ProTessellation();
err1 = ProSurfaceTessellationGet(pro_surface, *tessellationInput, tessellation);
HIH.
Feliks.