Running executable: strange behavior

I've been developing a DLL in C++ that uses OpenCascade. The application that makes use of it is developed in Delphi. The "hooking" mechanism is achieved by exporting classes and functions in the DLL and writing Delphi code that will understand them. So far, so good.

I don't recall having any problems like this before, but today I found something really bizarre.

One of the methods implemented in the DLL allows the user to cut a solid with a face thus dividing the solid in two (or more, depending on the shape). To do that, I use the Fuse operation plus a few extra tricks. If I run the Delphi executable from Windows Explorer or from Visual Studio (with or without the debugger attached to it), everything works as expected. However, if I run the executable from Delphi, either with or without the debugger attached, the operation misses a few faces. It's the same program and the same test case, still the results differ.

I have no clue how the launching application can affect the behavior of the same executable in OCC's internals. If anyone has an idea, please tell me.

Here's the wrong result: http://ceniza666.googlepages.com/fusebad.png

Here's the right result:
http://ceniza666.googlepages.com/fusegood.png

The tree nodes named "Element" represent Faces. In 'wrong' you can see that each Subspace has only 5 faces, instead of 6. In 'right' the number of faces is correct, and even one of them "Element 4" belonged to the shape before the fuse operation.

Paul Jimenez's picture

After a whole week, the problem is still there. The only findings so far are that it's indeed caused by BRepAlgoAPI_Fuse, and that the faces that disappear are those not modified by the boolean operation. Not long ago I was having another strange problem which I nailed down to an uninitialized attribute in AIS_InteractiveObject (which I reported here). That's the only thing I can think of: another uninitialized attribute somewhere. It may be worth mentioning that I'm using Roman's patches plus some other patches found here in the forum.

Another finding is that it only happens when using the debug DLLs. I just tested it with the release ones, and it works as it should. Trying to run it with unpatched DLLs crashed the application, and I don't have the old .lib and .hxx files to try recompiling the DLL. That makes it harder for me to check if it's caused by one of the patches, which would point to Roman's.

I'll leave it like that by now.

Roman Lygin's picture

Hi Paul,

Often this happens due to uninitialized variable use and/or mismatched PATH variables (e.g. pointing to different libraries when invoking from MSVS/Explorer and Delphi).

Could you send a small code snippet and a test case to my email ? I'd try Parallel Inspector on it.

Thanks.
Roman

---
opencascade.blogspot.com - blog on Open CASCADE
Join the Open CASCADE Group at LinkedIn

Paul Jimenez's picture

Hi Roman,

I've been trying to create a simple test case in the form of a code snippet. I'm even calling this code from the same place, but the test case works every time.

I also recall trying to modify that piece of code, and fuse was behaving strange. I had to convert the original code to the new one one step at a time, and then it worked. The only thing that I removed was a call to check the status of the fuse operation using ErrorStatus. Everything else was the same as the code that didn't want to work. The strange behavior was that it was not reporting any modified shapes at all. I explored all faces of the shell, but fuse said none was modified. That one even happened when running it from Visual Studio.

A simple test code that achieves the same operation is:

TopoDS_Shell aShell = BRepPrimAPI_MakeBox(1000, 1000, 3000);
TopoDS_Face aFace = BRepBuilderAPI_MakeFace(BRepBuilderAPI_MakePolygon(gp_Pnt(-500, 500, 0), gp_Pnt(1500, 500, 0), gp_Pnt(1500, 500, 3000), gp_Pnt(-500, 500, 3000), Standard_True), Standard_True);
BRepAlgoAPI_Fuse aFuser(aShell, aFace);
anAISContext->Display(new AIS_Shape(aFuser));

That small piece of code works everytime, but maybe you have some luck finding a problem somewhere that may pop up in very rare situations... like running it form Delphi.

Thanks,

Paul.

Roman Lygin's picture

Paul, are you certain it's a computational problem (inside BRepAlgoAPI_Fuse), and not a visualization one ? I just ran the commands in DRAW and the shape displayed in the OpenGL window had artifacts (though slightly different than yours). They seem to be connected with the shape size (3000) and default clipping settings. The model itself is just fine. Look at these screenshots:
http://myphoto.nnov.ru/img/c5a62380cf4567e0de9c5cde3260aeb6.png
http://myphoto.nnov.ru/img/b64fff47f462108dbcd76e12ce79eabc.png

Could you add dumping of the resulting model (BRepTools::Write()) into your code to see if it really differs when displayed fine and bad ? Another test is to work with scaled parameters (e.g. 1000 times smaller) and see if the problem still persists.

Hope this will be helpful somehow.
Roman

P.S. Didn't run the Inspector yet, can't download the recent build being at home :-(.

---
opencascade.blogspot.com - blog on Open CASCADE
Join the Open CASCADE Group at LinkedIn

Paul Jimenez's picture

Hi Roman,

The missing faces are not an illusion created by clipping. I've dumped the shape, and it indeed doesn't have the faces that are not being displayed. If you check the tree in the application's screenshot, you can notice that faces are missing from it (faces that should exist, but don't).

Thanks again for trying the code.

P.S.: If you have the chance to run the Inspector, and find something, please let me know.

Fotis Sioutis's picture

Hello Paul

There is a small chance that the FPU control word is not set correctly by Delphi RTL for OCC.Try to set it using the equivalent Delphi api in the executable.

In Borland Deveveloper Studio that i am using (c++ personallity) i have to set it otherwise very strange behavior can be seen, like loss of precision and strange exceptions.My control word looks like :

unsigned int A_NEW_EXC_FL_MASK = MCW_EM;

A_NEW_EXC_FL_MASK |= EM_INVALID;
A_NEW_EXC_FL_MASK |= EM_OVERFLOW;

*default87Ptr = RC_NEAR+PC_64+IC_AFFINE+A_NEW_EXC_FL_MASK;

where *default87Ptr is the FPU control word.

I am not sure if this is the case , but it never harms to give it a try

Fotis

Paul Jimenez's picture

Hello Fotis,

I tried using

Set8087CW($133f)

as suggested in Borland's documentation, but it didn't help to my problem. Still, I'll leave it there as it's suggested when dealing with OpenGL.

Thanks for the hint. Too bad it didn't solve my problem.

Svetlozar Kostadinov's picture

Hi folks, I can confirm the "missing face" problem. It happened a couple of months ago and I regret to say I didn't save the model. The diffence from the Paul's case is that the face is result of a cut operation, not a fuse.

http://img147.imageshack.us/my.php?image=missingfacehd6.png

Dima's picture

Please show an example of use OpenCascade in Delphi. Very much I want to work with OpenCascade.

Paul Jimenez's picture

Although I said that I am using OpenCASCADE with Delphi, what I am really doing is creating a C++ DLL that I call from Delphi code. All the Delphi application does is to send a Handle to initialize the visualization, send all mouse events and retrieve some information to show it in a nice GUI. No single OpenCASCADE method is being called directly from Delphi.
I am not aware of any wrapper for Delphi. I am not sure if being able to compile OpenCASCADE with C++ Builder may help the process either.
If you want to interface Delphi with C++ code, take a look at:

http://rvelthuis.de/articles/articles-cppobjs.html
http://rvelthuis.de/articles/articles-cobjs.html
http://rvelthuis.de/articles/articles-convert.html