Crash in TKBRep.dll using BRepOffsetAPI_MakePipe

Dear all,

I am writing you because I am having a problem with the OCC DLLs. I have prepared a small example which shows the problem.

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.
1. Download the OCC 6.8.0 Windows Installer and install the library. This will result in the installed Win32 libraries and DLLs.
2. 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 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

}

int _tmain(int argc, _TCHAR* argv[])
{
std::cout

testCrash();
std::cout 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

Paolo Tricerri's picture

Just a small update. In the function buildSolid, it does not matter how the TopoDS_Wire and TopoDS_Face are given to the function (i.e. by value or reference). Indeed, even if I create local variables to have copies of the passed arguments, the application still crashes. However, if a wire and a face are created entirely within the buildSolid function, the application does not crash.

If the function buildSolid is changed as follows:

void buildSolid(TopoDS_Wire& circ, TopoDS_Wire straight, TopoDS_Solid& solid, TopoDS_Face faceToSweep)
{
gp_Pnt zero(0.0, 0.0, 0.0);
gp_Pnt one(100.0, 0.0, 0.0);

BRepBuilderAPI_MakeEdge edge(zero, one);
edge.Build(); edge.Check();

BRepBuilderAPI_MakeWire wireStraight(edge.Edge());
wireStraight.Build(); wireStraight.Check();
gp_Pnt pOne(0.0, 75.0, 100.0);
gp_Pnt pTwo(0.0, -75.0, 100.0);

gp_Pnt pThree(0.0, -75.0, -100.0);
gp_Pnt pFour(0.0, 75.0, -100.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();
BRepTools::Write(sqFace.Face(), "sqFace.brep");

BRepOffsetAPI_MakePipe shell(wireStraight, sqFace.Face());

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");
}
The application runs smoothly.

Is there any advice (on some file in the documentation) on how to build OCC with 64 bits?

Paolo Tricerri's picture

Dear all,

a small update: if the same TopoDS_Wire and TopoDS_Face are built within the function, the crash disappears. On the other hand, if the TopoDS_Wire and TopoDS_Face are wrapped within two classes (which contain a TopoDS_Wire and TopoDS_Face as private members) and the classes are passed by value (or reference) the crash comes back.

Benjamin Bihler's picture

Hi!

In such cases I compile OCC and my code in debug mode and run the application in a debugger. The debugger should reveal the code line where a segmentation fault happens and you can start doing research on the reasons for that.

If for some reasons the segmentation fault does not happen when running the application in debug mode (unfortunately this can be the case), then consider running your application with Valgrind. As far as I know Valgrind is only available on Linux, but it is IMHO the best tool ever made for finding memory problems and segmentation faults.

Good luck,
Benjamin

Paolo Tricerri's picture

Hi Benjamin,

thanks for your advice. Actually, I have compiled and installed OCC on an Ubuntu machine and I will give a go to your suggestion. I hope the same problem appears on Ubuntu as well.

Thanks again,

Paolo

Paolo Tricerri's picture

Dear all,

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.

Is there any document which explains the build settings that have to be considered when building OCC by hand and not just relying on the installed libraries?

Kind regards

Paolo

Paolo Tricerri's picture

Dear all,

the problem is my Visual Studio 2010. As correctly stated in the release notes, SP1 for VS2010 is needed in order to correctly compile the library. That's what I was missing in my VS2010. I have now installed SP1 for VS2010 and tested my application and it works fine.

Kind regards,

Paolo