Thomas,
Here is code that reproduces the problem. I think I have found the reason for the issue. My CAD component is producing some bezier curves segments that have pole points like this (where the first, second and third are all the same):
aPoles(1) = gp_Pnt(284,83,0);
aPoles(2) = gp_Pnt(284,83,0);
aPoles(3) = gp_Pnt(284,83,0);
aPoles(4) = gp_Pnt(285,83,0);
aCurve = new Geom_BezierCurve(aPoles);
Shape_Wire.Add(BRepBuilderAPI_MakeEdge(aCurve));
This is clearly not optimum and if you remove these curves (by adjusting the preceeding or following segment intersection points) the cut problem goes away.
As I understand Bezier curves this construction is valid but unusual and can be replaced with a simple line segment.
Obviously this is a problem I can check for and fix on the CAD side and never feed OCC a curve of this form. The sample code snippet below shows how the error can be duplicated. I don't know if OCC should check for and handle this kind of curve input so I'm not sure if this can be considered a bug in OCC. It is clearly one more of many found in the CAD component I'm using.
//Component: Part1
gp_Ax2 Part1Pin_Ax2 = gp_Ax2(gp_Pnt(78,559,0),gp::DZ(),gp_Dir(gp_Vec(gp_Pnt(78,559,0),gp_Pnt(78,503,0))));
gp_Trsf Part1_Trsf;
TopoDS_Shape Part1_Shape;
{
BRepBuilderAPI_MakeWire Shape_Wire;
Handle(Geom_BezierCurve) aCurve = NULL;
//Segment 1
TColgp_Array1OfPnt aPoles(1,4);
aPoles(1) = gp_Pnt(188,481,0);
aPoles(2) = gp_Pnt(247,481,0);
aPoles(3) = gp_Pnt(297,481,0);
aPoles(4) = gp_Pnt(378,468,0);
aCurve = new Geom_BezierCurve(aPoles);
Shape_Wire.Add(BRepBuilderAPI_MakeEdge(aCurve));
//Segment 2
Shape_Wire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(378,468,0),gp_Pnt(388,741,0)));
//Segment 3
aPoles(1) = gp_Pnt(388,741,0);
aPoles(2) = gp_Pnt(249,723,0);
aPoles(3) = gp_Pnt(168,723,0);
aPoles(4) = gp_Pnt(72,664,0);
aCurve = new Geom_BezierCurve(aPoles);
Shape_Wire.Add(BRepBuilderAPI_MakeEdge(aCurve));
//Segment 4
Shape_Wire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(72,664,0),gp_Pnt(72,494,0)));
//Segment 5
Shape_Wire.Add(BRepBuilderAPI_MakeEdge(gp_Pnt(72,494,0),gp_Pnt(188,481,0)));
//Make Part1 solid
Part1_Shape = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(Shape_Wire),gp_Vec(0,0,10));
//Position Part1 in scene
gp_Ax2 Part1ParentPin_Ax2 = gp_Ax2(gp_Pnt(0,0,0),gp::DZ(),gp::DY()); //Root in scene
gp_Trsf T1; //Transformation required to move child part to parent part connection
T1.SetDisplacement(gp_Ax3(Part1Pin_Ax2),gp_Ax3(Part1ParentPin_Ax2)); //Move shape to root
gp_Trsf T2; //Transformation required to rotate child part around child pin
T2.SetRotation(gp_Ax1(Part1Pin_Ax2.Location(),Part1Pin_Ax2.XDirection()),0.0);
Part1_Trsf = T1*T2;
Part1_Shape.Location(TopLoc_Location(Part1_Trsf));
}
//Component: Part2 -- aproximate circle -- With screwy segments that cause the problem
gp_Ax2 Part2ParentPin_Ax2 = Part1Pin_Ax2;
Part2ParentPin_Ax2.Transform(Part1_Trsf); //Find final location of parent pin in positioned parent part
gp_Ax2 Part2Pin_Ax2 = gp_Ax2(gp_Pnt(284,188,10),gp::DZ(),gp_Dir(gp_Vec(gp_Pnt(284,188,10),gp_Pnt(284,113,0))));
gp_Trsf Part2_Trsf;
TopoDS_Shape Part2_Shape;
{
BRepBuilderAPI_MakeWire Shape_Wire;
Handle(Geom_BezierCurve) aCurve = NULL;
TColgp_Array1OfPnt aPoles(1,4);
//Segment 1
aPoles(1) = gp_Pnt(284,295,0);
aPoles(2) = gp_Pnt(225,295,0);
aPoles(3) = gp_Pnt(176,247,0);
aPoles(4) = gp_Pnt(176,189,0);
aCurve = new Geom_BezierCurve(aPoles);
Shape_Wire.Add(BRepBuilderAPI_MakeEdge(aCurve));
//Segment 2
aPoles(1) = gp_Pnt(176,189,0);
aPoles(2) = gp_Pnt(176,131,0);
aPoles(3) = gp_Pnt(225,83,0);
aPoles(4) = gp_Pnt(284,83,0);
aCurve = new Geom_BezierCurve(aPoles);
Shape_Wire.Add(BRepBuilderAPI_MakeEdge(aCurve));
//Segment 3
aPoles(1) = gp_Pnt(284,83,0);
aPoles(2) = gp_Pnt(284,83,0);
aPoles(3) = gp_Pnt(284,83,0);
aPoles(4) = gp_Pnt(285,83,0);
aCurve = new Geom_BezierCurve(aPoles);
Shape_Wire.Add(BRepBuilderAPI_MakeEdge(aCurve));
//Segment 4
aPoles(1) = gp_Pnt(285,83,0);
//aPoles(1) = gp_Pnt(284,83,0);
aPoles(2) = gp_Pnt(344,83,0);
aPoles(3) = gp_Pnt(393,131,0);
aPoles(4) = gp_Pnt(393,189,0);
aCurve = new Geom_BezierCurve(aPoles);
Shape_Wire.Add(BRepBuilderAPI_MakeEdge(aCurve));
//Segment 5
aPoles(1) = gp_Pnt(393,189,0);
aPoles(2) = gp_Pnt(393,247,0);
aPoles(3) = gp_Pnt(344,295,0);
aPoles(4) = gp_Pnt(285,295,0);
//aPoles(4) = gp_Pnt(284,295,0);
aCurve = new Geom_BezierCurve(aPoles);
Shape_Wire.Add(BRepBuilderAPI_MakeEdge(aCurve));
//Segment 6
aPoles(1) = gp_Pnt(285,295,0);
aPoles(2) = gp_Pnt(285,295,0);
aPoles(3) = gp_Pnt(285,295,0);
aPoles(4) = gp_Pnt(284,295,0);
aCurve = new Geom_BezierCurve(aPoles);
Shape_Wire.Add(BRepBuilderAPI_MakeEdge(aCurve));
//Make part2 solid
Part2_Shape = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(Shape_Wire),gp_Vec(0,0,10));
//Position Part2 in scene
gp_Trsf T1; //Transformation required to move child part to parent part connection
T1.SetDisplacement(gp_Ax3(Part2Pin_Ax2),gp_Ax3(Part2ParentPin_Ax2)); //Move shape to parent part pin
gp_Trsf T2; //Transformation required to rotate child part around child pin
T2.SetRotation(gp_Ax1(Part2Pin_Ax2.Location(),Part2Pin_Ax2.XDirection()),PI/2.0);
Part2_Trsf = T1*T2;
Part2_Shape.Location(TopLoc_Location(Part2_Trsf));
}
//Perform Cut
if(!Part1_Shape.IsNull() && !Part2_Shape.IsNull())
{
BRepAlgoAPI_Cut CutOp(Part2_Shape,Part1_Shape);
if(CutOp.IsDone())
Part2_Shape = CutOp.Shape();
}
//Display Parts
{//Part1
Handle(AIS_Shape) My_AIS_Shape = new AIS_Shape(Part1_Shape);
myAISContext->SetColor(My_AIS_Shape,Quantity_NOC_AZURE);
myAISContext->SetMaterial(My_AIS_Shape,Graphic3d_NOM_PLASTIC);
myAISContext->SetTransparency(My_AIS_Shape,0.8); //Make transparent so we can see cut
myAISContext->SetDisplayMode(My_AIS_Shape,1);
myAISContext->Display(My_AIS_Shape);
}
{//Part2
Handle(AIS_Shape) My2_AIS_Shape = new AIS_Shape(Part2_Shape);
myAISContext->SetColor(My2_AIS_Shape,Quantity_NOC_AZURE);
myAISContext->SetMaterial(My2_AIS_Shape,Graphic3d_NOM_PLASTIC);
myAISContext->SetTransparency(My2_AIS_Shape,0.0);
myAISContext->SetDisplayMode(My2_AIS_Shape,1);
myAISContext->Display(My2_AIS_Shape);
}
myView->SetComputedMode (Standard_False);
myView->FitAll();
myView->Update();
Thanks,
Tim