While developing a .Net application using the OpenCascade wrappers, some issues might appear: like an unexpected crash or a function that returns nothing when it should return some list with processed elements and no clue why it is not working. There could be many causes of the problem, among them there are:
- incorrect usage of the class (forgot to initialize something),
- correct usage of the class but incorrect parameters or not treating the error that the operation returned and moving to next steps (like the operation failed silently and I am trying to access the result shape),
- bug in the wrappers (some parameter not passed correctly to the native layer) - not typical but not excluded,
- bug in OpenCascade - not typical but not excluded.
Because investigating all these problems might take a lot of time I will explain from my experience with wrappers until now how to approach the problem to solve it quickly.
Let's assume that I write some OpenCascade code in C# and it doesn't work. I try one or two constructors for the class, I try the same function with different parameters but still the class/algorithm returns no results and I have no clue what's the problem. The problem can be in the C# layer, in the wrappers or in OpenCascade. Assuming (because of the lack of samples) that I am not sure how to use the class properly or even if this is the algorithm class that solves my problem, also I am not sure if the problem is on my layer or lower layers, I do the following:
1. Because the code is already written the first thing I would do is to use the OpenCascade error handling mechanism to see if there is a problem.
To detail further this sentence: majority of the classes have the IsDone() method that should return true, also many algorithms classes have some function to get the operation status (they return something like OK, could not allocate memory, invalid parameters). Modeling algorithms docs have some hints on these.
If all these look ok we move to the step 2.
2. If the result that I expect is an array of shapes, or some values I look at the class for functions related to the algorithm that might give me a hint what happened. I look at result array length if it is 0, or if the class has some methods that describe the solution like NbPoints() or IsGeneratedNewShape(). If all these are 0/false a possibility would be that I didn't initialize the algorithm properly so it couldn't find a solution. I always look for Intialize() functions.
3. This step could be a step before step 1, before starting to implement the algorithm.
Replicate the functionality with Draw Test Harness. I make quickly a similar shape using tcl, apply the algorithm and see if this works. If it doesn't work it might be an OpenCascade bug, if it works I look at the command source code to see how they implemented the code.
A problem here might be that I can't always find a command close to the functionality that I want to implement. An advantage would be that looking at their code I get the confirmation that I use the right path for my solution.
4. Search on forum for the problem. If some sample code is found in C++ I can always try it with copy paste on one of the mfc sample applications provided together with OCC. Also I look if the class usage is like the one from my code.
5. If none of the above steps to detect the problem worked I try to implement myself the solution in C++ to eliminate the wrapper layer. If it works in C++ we have a wrapper problem, if it doesn't it's an incorrect class usage problem or an OpenCascade bug.
6. The last solution and most time consuming one is to debug the OpenCascade function. I look first at the source codes to try to get a hint on why my code fails (maybe I see a check there if a parameter is a Face type shape). In many cases I find there some code that I don't understand and gives no clue why it doesn't work. An approach for it is to debug it while doing some operation to see where it stops or crashes.
How to debug:
- first we have to build OpenCascade in debug mode. Using VisualStudio this can be made by going to OpenCASCADE6.3.0\ros\adm\win32\vc8\ and build the projects found there. Some projects might fail building because they depend on other projects so we try again after building the others. Some always fail, we can always copy from the release folder the release version of these especially if we are not interested debugging these missing libraries,
- make the CASROOT environment variable point to our debug folder or rename our debug folder with the name of the release folder, make sure we use the debug folder by renaming the release folder and see if sample applications work,
- launch the C#/.Net/C++ application, attach to it with a debugger and put a breakpoint in the OpenCascade function that we want to debug. In the trunk in NaroCad folder there is a file named DebuggingSolution.txt that explains in detail how to configure WinDbg to debug OpenCascade.
From debugging I made until now there is no point to have wrappers in debug mode, you can always check in the native OpenCascade code if the parameters passed are correct or garbled.
After all these debugging preparations if we don't understand the native code a chance would be to be lucky and have the code failing on some "if" check or see some message thrown that can give us a hint.
7. The final step would be always to start again from step 1 (or 3) searching for a completely different solution.
Many variations on the order of these steps can be done I just wanted to make a list of possibilities that can help us find a quick and reliable solution.