I am writing you because I am having a problem with the DLLs of a library I am using for my code. I have looked for similar threads which are related to crashes in Release mode but not in Debug mode but they do not seem to fit exactly the issue I am facing. I have prepared a small example which shows the problem. I am using Visual Studio 2010 to compile my example as well as the Open CasCade library.
The problem is that when I compile and run my example in Release x64 configuration, the creation of a BRepOffsetAPI_MakePipe object makes the application crash because of a crash in the TKBRep.dll due to access reading location 0xFFFFFFFFFFFF. What is a bit puzzling as well is that if the code is compiled in Release Win32, everything works fine and the result is correct. Hereafter I describe the process I am following to compile the library and the code I have written. Please, note that the objects I create (i.e. cylinder, faces) are created using the classes of OCC. I am currently using the version 6.8.0 but I have observed the same problem with version 6.9.0. For this reason, I am prone to think the problem is in the code I am writing.
Process to install OCC for Win32 and x64 configuration.
- Download the OCC 6.8.0 Windows Installer and install the library. This will result in the installed Win32 libraries and DLLs.
- Open the OCC.sln in Visual Studio 2013 and compile the packages needed for the example in the Release x64 configuration. This will create libraries and DLLs in the win64 folder within the installation folder.
Example code:
void constructWires(gp_Pnt pointZero, gp_Pnt pointOne,
TopoDS_Wire& circular, TopoDS_Wire& straight,
TopoDS_Face& faceCircular)
{
BRepBuilderAPI_MakeEdge edgeS(pointZero, pointOne);
edgeS.Build(); edgeS.Check();
BRepBuilderAPI_MakeWire wireS(edgeS.Edge());
wireS.Build(); wireS.Check();
straight = wireS.Wire();
gp_Vec vec(pointZero.X() - pointOne.X(), pointZero.Y() - pointOne.Y(), pointZero.Z() - pointOne.Z());
gp_Dir dir = vec.Normalized();
gp_Ax2 ax(pointZero, dir);
Handle(Geom_Circle) circle = new Geom_Circle(ax, 50.0);
BRepBuilderAPI_MakeEdge edgeC(circle);
edgeC.Build(); edgeC.Check();
BRepBuilderAPI_MakeWire wireC(edgeC.Edge());
wireC.Build(); wireC.Check();
circular = wireC.Wire();
// Face One creation
gp_Pln plane(pointZero, dir);
BRepBuilderAPI_MakeFace faceCreated(plane, circular, Standard_True);
faceCreated.Build(); faceCreated.Check();
faceCircular = faceCreated.Face();
}
void buildSolid(TopoDS_Wire& circ, TopoDS_Wire& straight, TopoDS_Solid& solid, TopoDS_Face faceToSweep)
{
//BRepTools::Write(straight, "straight.brep");
//BRepTools::Write(circ, "circ.brep");
// In this example, the shape is a cylinder but the class
// BRepOffsetAPI_MakePipe because the wire representing the
// axis of the cylinder might be composed of different edges
// properly alinged.
// This line generates the TKBRep.dll failure trying to access
// 0xFFFFFFFFFF location.
BRepOffsetAPI_MakePipe shell(straight, faceToSweep);
shell.Build();
shell.Check();
//shell.MakeSolid();
TopExp_Explorer solidInS(shell.Shape(), TopAbs_SOLID);
if (!solidInS.More())
{
std::cout << "Error when creating solid!" << std::endl;
return;
}
solid = TopoDS::Solid( solidInS.Current() ) ;
BRepTools::Write(solid, "solid.brep");
}
void cutFace(TopoDS_Shape solid, TopoDS_Shape face, TopoDS_Shape& shape)
{
BRepTools::Write(face, "faceInCut.brep");
BRepTools::Write(solid, "solidInCut.brep");
TopoDS_Shape faceToCut(face);
TopoDS_Shape solidToCut(solid);
BRepAlgoAPI_Cut cut(faceToCut, solidToCut);
cut.Build(); cut.Check();
shape = cut.Shape();
}
TopoDS_Face constructSquareFace()
{
gp_Pnt pOne(-100.0, 75.0, 0.0);
gp_Pnt pTwo(-100.0, -75.0, 0.0);
gp_Pnt pThree(200.0, -75.0, 0.0);
gp_Pnt pFour(200.0, 75.0, 0.0);
BRepBuilderAPI_MakeEdge edgeOne(pOne, pTwo);
BRepBuilderAPI_MakeEdge edgeTwo(pTwo, pThree);
BRepBuilderAPI_MakeEdge edgeThree(pThree, pFour);
BRepBuilderAPI_MakeEdge edgeFour(pFour, pOne);
BRepBuilderAPI_MakeWire wire(edgeOne.Edge(), edgeTwo.Edge(), edgeThree.Edge(), edgeFour.Edge());
wire.Build(); wire.Check();
BRepBuilderAPI_MakeFace sqFace(wire.Wire(), Standard_True);
sqFace.Build(); sqFace.Check();
return sqFace.Face();
}
void testCrash(void)
{
gp_Pnt pointZero(0.0, 0.0, 0.0);
gp_Pnt pointOne(100.0, 0.0, 0.0);
TopoDS_Wire circular;
TopoDS_Wire straight;
TopoDS_Face faceCircular;
// This method creates a circular face which then will be swept
// along the straight wire which represents the axis of the cylinder.
constructWires(pointZero, pointOne, circular, straight, faceCircular);
TopoDS_Solid solid;
// This method constructs the solid, i.e. cylinder, used to cut.
buildSolid(circular, straight, solid, faceCircular);
BRepTools::Write(solid, "solid.brep");
// This is the face which will be cut.
TopoDS_Face faceToCut = constructSquareFace();
BRepTools::Write(faceToCut, "sqFace.brep");
// Perform cut operation.
TopoDS_Shape shape;
cutFace(solid, faceToCut, shape);
BRepTools::Write(shape, "shape.brep");
std::cout << "Done!!" << std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "Started" << std::endl;
testCrash();
std::cout << "Finished" << std::endl;
return 0;
}
It seems to me that the code is correct and there is not any ambiguous parameters declarations in the definitions of the functions.
Could anyone point me to the right direction, please?
Any help is very much appreciated. Kind regards,
Paolo
I have understood what triggers the crash of my small application. It's related to how I compile the OpenCasCade library. Since I am developing my OCC code for a 64bits application, I will now refer to the latest release of OCC, i.e. OCC 6.9.0, which (for Windows at least) whose results are tested and certified for the Release x64 configuration. However, as I said, I saw the same problem with version 6.8.0 x64. There might be a unique fix then.
When OCC 6.9.0 is installed, the win64 folders bin and lib are created containing the dlls and libraries complied in Release mode. If my example is linked against these files, it does not crash and the results are correct.
Let's now suppose that a user wants to build the library by himself. What I do is the following: - Open a command prompt window and go to the C:\OpenCASCADE6.9.0\opencascade-6.9.0\ folder. - Execute custom.bat and msvc.bat vc10 Debug win64
This will open VC2010 and a build configuration can be chosen. In the solution explorer some projects can be selected built. For instance, in my project I am interested in building all the projects but the ones in the Draw folder. I build the projects in Debug mode and execute my example linking it against the new DLLs and Libs file (now grouped in win64\vc10\bind and \libd, respectively). In Debug mode, as I previously said, it works fine. On the other hand, when the same projects are built in Release mode and the application is executed it CRASHES.
The cause of my error is that the build settings are different when I compile the code in Release mode by hand and when I get the Release dlls and libs from the installation.
For the moment, I will rely on the installed DLLs and Libs. In case I will have more details I will post them here.
Kind regards
P.s. Sorry for giving all the details. I know most of them are obvious to many of you.