Testing - Migration QADraw tests to GTests (#1243)

- Added new GTests covering multiple historical regressions (intersection, projection, pipe shell, boolean ops, fillet, distances, gp transforms, string hashing).
- Registered new test sources in the relevant `GTests/FILES.cmake` lists.
- Removed legacy Tcl tests and removed the associated QADraw commands from `QABugs_*.cxx`.
This commit is contained in:
Pasukhin Dmitry
2026-04-28 18:25:29 +01:00
committed by GitHub
parent 051b12466a
commit 39bbf2ed59
34 changed files with 1032 additions and 1779 deletions
+3 -414
View File
@@ -22,150 +22,13 @@
#include <AIS_InteractiveContext.hxx>
#include <TopoDS_Shape.hxx>
#include <BRepBuilderAPI_MakePolygon.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <gp_Pnt.hxx>
#include <gp_Dir.hxx>
#include <gp_Ax1.hxx>
#include <BRepPrimAPI_MakeRevol.hxx>
#include <GProp_GProps.hxx>
#include <BRepGProp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRep_Tool.hxx>
#include <Poly_Triangulation.hxx>
#include <TopExp.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Geom_BSplineSurface.hxx>
#include <BRepAlgoAPI_Fuse.hxx>
#include <BRepFilletAPI_MakeFillet.hxx>
#include <ShapeUpgrade_UnifySameDomain.hxx>
static int OCC426(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc != 8)
{
di << "Usage : " << argv[0] << " shape1 shape2 shape3 shape4 shape5 shape6 shape7\n";
return 1;
}
BRepBuilderAPI_MakePolygon W1;
W1.Add(gp_Pnt(10, 0, 0));
W1.Add(gp_Pnt(20, 0, 0));
W1.Add(gp_Pnt(20, 0, 10));
W1.Add(gp_Pnt(10, 0, 10));
W1.Add(gp_Pnt(10, 0, 0));
bool OnlyPlane1 = false;
TopoDS_Face F1 = BRepBuilderAPI_MakeFace(W1.Wire(), OnlyPlane1);
gp_Pnt P1(0, 0, 0);
gp_Dir D1(0, 0, 30);
gp_Ax1 A1(P1, D1);
double angle1 = 360 * (M_PI / 180.0);
TopoDS_Shape rs1 = BRepPrimAPI_MakeRevol(F1, A1, angle1);
BRepBuilderAPI_MakePolygon W2;
double f1 = 7.0710678118654752440;
double f2 = 14.1421356237309504880;
W2.Add(gp_Pnt(f1, f1, 10));
W2.Add(gp_Pnt(f2, f2, 10));
W2.Add(gp_Pnt(f2, f2, 20));
W2.Add(gp_Pnt(f1, f1, 20));
W2.Add(gp_Pnt(f1, f1, 10));
bool OnlyPlane2 = false;
TopoDS_Face F2 = BRepBuilderAPI_MakeFace(W2.Wire(), OnlyPlane2);
gp_Pnt P2(0, 0, 0);
gp_Dir D2(0, 0, 30);
gp_Ax1 A2(P2, D2);
double angle2 = 270 * (M_PI / 180.0);
TopoDS_Shape rs2 = BRepPrimAPI_MakeRevol(F2, A2, angle2);
BRepBuilderAPI_MakePolygon W3;
W3.Add(gp_Pnt(10, 0, 20));
W3.Add(gp_Pnt(20, 0, 20));
W3.Add(gp_Pnt(20, 0, 30));
W3.Add(gp_Pnt(10, 0, 30));
W3.Add(gp_Pnt(10, 0, 20));
bool OnlyPlane3 = false;
TopoDS_Face F3 = BRepBuilderAPI_MakeFace(W3.Wire(), OnlyPlane3);
gp_Pnt P3(0, 0, 0);
gp_Dir D3(0, 0, 30);
gp_Ax1 A3(P3, D3);
double angle3 = 360 * (M_PI / 180.0);
TopoDS_Shape rs3 = BRepPrimAPI_MakeRevol(F3, A3, angle3);
di << "fuse32 = BRepAlgoAPI_Fuse(rs3, rs2)\n";
di << "fuse321 = BRepAlgoAPI_Fuse(fuse32, rs1)\n";
TopoDS_Shape fuse32 = BRepAlgoAPI_Fuse(rs3, rs2).Shape();
TopoDS_Shape fuse321 = BRepAlgoAPI_Fuse(fuse32, rs1).Shape();
// unify the faces of the Fuse result
ShapeUpgrade_UnifySameDomain anUnify(fuse321, true, true, true);
anUnify.Build();
const TopoDS_Shape& aFuseUnif = anUnify.Shape();
// Give the mass calculation of the shape "aFuseUnif"
GProp_GProps G;
BRepGProp::VolumeProperties(aFuseUnif, G);
di << " \n";
di << "Mass: " << G.Mass() << "\n\n";
di << "Trianglating Faces .....\n";
TopExp_Explorer ExpFace;
for (ExpFace.Init(aFuseUnif, TopAbs_FACE); ExpFace.More(); ExpFace.Next())
{
TopoDS_Face TopologicalFace = TopoDS::Face(ExpFace.Current());
TopologicalFace.Orientation(TopAbs_FORWARD);
BRepMesh_IncrementalMesh IM(TopologicalFace, 1);
TopLoc_Location loc;
occ::handle<Poly_Triangulation> facing = BRep_Tool::Triangulation(TopologicalFace, loc);
if (facing.IsNull())
{
di << "Triangulation FAILED for this face\n";
continue;
}
di << "No of Triangles = " << facing->NbTriangles() << "\n";
}
di << "Triangulation of all Faces Completed. \n\n";
NCollection_IndexedDataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher>
edgemap;
TopExp::MapShapesAndAncestors(aFuseUnif, TopAbs_EDGE, TopAbs_SOLID, edgemap);
di << "No. of Edges: " << edgemap.Extent() << "\n";
ChFi3d_FilletShape FShape = ChFi3d_Rational;
BRepFilletAPI_MakeFillet blend(aFuseUnif, FShape);
di << "Adding Edges ..... \n";
for (int i = 1; i <= edgemap.Extent(); i++)
{
// std::cout << "Adding Edge : " << i << std::endl;
TopoDS_Edge edg = TopoDS::Edge(edgemap.FindKey(i));
if (!edg.IsNull())
blend.Add(1, edg);
}
di << "All Edges added ! Now Building the Blend ... \n";
di << " \n";
blend.Build();
// DBRep::Set ( argv[1], fuse321 );
DBRep::Set(argv[1], blend);
DBRep::Set(argv[2], rs1);
DBRep::Set(argv[3], rs2);
DBRep::Set(argv[4], rs3);
DBRep::Set(argv[5], fuse32);
DBRep::Set(argv[6], fuse321);
DBRep::Set(argv[7], aFuseUnif);
return 0;
}
#include <Geom_SurfaceOfRevolution.hxx>
@@ -417,10 +280,10 @@ static int OCC712(Draw_Interpretor& di, int argc, const char** argv)
}
}
di << "All Faces added. Building... \n"; // std::cout.flush();
di << "All Faces added. Building... \n";
draftSlab.Build();
di << "Build done...\n"; // std::cout.flush();
if (!draftSlab.IsDone()) //--------------> STEP:1
di << "Build done...\n";
if (!draftSlab.IsDone())
{
di << " Error in Build \n";
return 1;
@@ -429,272 +292,6 @@ static int OCC712(Draw_Interpretor& di, int argc, const char** argv)
DBRep::Set(argv[1], slabShape);
}
}
catch (Standard_Failure const&) //--------------------> STEP:2
{
di << " Error in Draft Slab \n";
return 1;
}
return 0;
}
//=======================================================================
// performTriangulation
//=======================================================================
int performTriangulation(const TopoDS_Shape& aShape, Draw_Interpretor& di)
{
int failed = 0, total = 0;
TopExp_Explorer ExpFace;
occ::handle<Poly_Triangulation> facing;
for (ExpFace.Init(aShape, TopAbs_FACE); ExpFace.More(); ExpFace.Next())
{
total++;
TopoDS_Face TopologicalFace = TopoDS::Face(ExpFace.Current());
TopologicalFace.Orientation(TopAbs_FORWARD);
BRepMesh_IncrementalMesh IM(TopologicalFace, 1);
TopLoc_Location loc;
facing = BRep_Tool::Triangulation(TopologicalFace, loc);
di << "Face " << total << " - ";
if (facing.IsNull())
{
failed++;
di << "******************** FAILED during Triangulation \n";
}
else
{
di << facing->NbTriangles() << " Triangles\n";
}
}
di << "Triangulation of all Faces Completed: \n\n";
if (failed == 0)
return 1;
di << "***************************************************\n";
di << "******* ********\n";
di << "***** Triangulation FAILED for " << failed << " of " << total << " Faces ******\n";
di << "******* ********\n";
di << "***************************************************\n";
return 0;
}
#include <BRepAlgoAPI_Cut.hxx>
//=================================================================================================
#include <BRepPrimAPI_MakeSphere.hxx>
//=======================================================================
// OCC822_2
//=======================================================================
//=======================================================================
// OCC823
//=======================================================================
//=======================================================================
// OCC824
//=======================================================================
#include <NCollection_Array2.hxx>
#include <GeomConvert.hxx>
#include <Geom_BezierSurface.hxx>
#include <BRepPrimAPI_MakeHalfSpace.hxx>
//=======================================================================
// OCC825
//=======================================================================
static int OCC825(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc != 6)
{
di << "Usage : " << argv[0] << " name1 name2 name3 result1 result2\n";
return 1;
}
int index = 1;
double size = 50;
NCollection_Array2<gp_Pnt> poles(1, 2, 1, 2);
poles(1, 1).SetCoord(-size, 0, -size);
poles(1, 2).SetCoord(-size, 0, size);
poles(2, 1).SetCoord(size, 0, -size);
poles(2, 2).SetCoord(size, 0, size);
occ::handle<Geom_BezierSurface> BezSurf = new Geom_BezierSurface(poles);
occ::handle<Geom_BSplineSurface> BSpSurf = GeomConvert::SurfaceToBSplineSurface(BezSurf);
BRepBuilderAPI_MakeFace faceMaker(BSpSurf, Precision::Confusion());
const TopoDS_Face& face = faceMaker.Face();
gp_Pnt pnt(0, size, 0);
BRepPrimAPI_MakeHalfSpace* hSpace = new BRepPrimAPI_MakeHalfSpace(face, pnt);
TopoDS_Shape hsp = hSpace->Solid();
if (index < argc)
DBRep::Set(argv[index++], hsp);
BRepPrimAPI_MakeSphere sphere1(gp_Pnt(0.0, 0.0, 0.0), 25.0);
TopoDS_Shape sph1 = sphere1.Shape();
if (index < argc)
DBRep::Set(argv[index++], sph1);
BRepPrimAPI_MakeSphere sphere2(gp_Pnt(0.0, 0.00001, 0.0), 25.0);
TopoDS_Shape sph2 = sphere2.Shape();
if (index < argc)
DBRep::Set(argv[index++], sph2);
di << "All primitives created..... Creating Cut Objects\n";
try
{
OCC_CATCH_SIGNALS
di << "cut1 = BRepAlgoAPI_Cut(sph1, hsp)\n";
TopoDS_Shape cut1 = BRepAlgoAPI_Cut(sph1, hsp).Shape();
if (index < argc)
DBRep::Set(argv[index++], cut1);
di << "CUT 1 Created ! ";
di << "cut2 = BRepAlgoAPI_Cut(sph2, hsp)\n";
TopoDS_Shape cut2 = BRepAlgoAPI_Cut(sph2, hsp).Shape();
if (index < argc)
DBRep::Set(argv[index++], cut2);
di << "CUT 2 Created !\n\n";
GProp_GProps G;
BRepGProp::VolumeProperties(cut1, G);
di << "CUT 1 Mass = " << G.Mass() << "\n\n";
BRepGProp::VolumeProperties(cut2, G);
di << "CUT 2 Mass = " << G.Mass() << "\n\n";
di << "Trianglating Faces of CUT 1 .....\n";
performTriangulation(cut1, di);
di << "Trianglating Faces of CUT 2 .....\n";
performTriangulation(cut2, di);
}
catch (Standard_Failure const&)
{
di << "*********************************************************\n";
di << "***** ******\n";
di << "***** Standard_Failure : Exception in HSP Function ******\n";
di << "***** ******\n";
di << "*********************************************************\n";
return 1;
}
di << "*************************************************************\n";
di << " CUT 1 and CUT 2 gives entirely different results during\n";
di << " mass computation and face triangulation, even though the\n";
di << " two spheres are located more or less at the same position.\n";
di << "*************************************************************\n";
return 0;
}
//=======================================================================
// OCC826
//=======================================================================
//=======================================================================
// OCC827
//=======================================================================
//=======================================================================
// performBlend
#include <GC_MakeSegment.hxx>
//=======================================================================
// OCC828
//=======================================================================
static int OCC828(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc != 2)
{
di << "Usage : " << argv[0] << " shape\n";
}
int index = 1;
double slabThick = 111;
gp_Pnt p11(-27.598139, -7.0408573, 0.0);
gp_Pnt p12(-28.483755, -17.487625, 0.0);
gp_Pnt p13(-19.555504, -22.983587, 0.0);
GC_MakeArcOfCircle arc1(p11, p12, p13);
gp_Pnt p21(12.125083, -22.983587, 0.0);
gp_Pnt p22(21.1572, -17.27554, 0.0);
gp_Pnt p23(19.878168, -6.6677585, 0.0);
GC_MakeArcOfCircle arc2(p21, p22, p23);
gp_Pnt p31(3.265825, 13.724955, 0.0);
gp_Pnt p32(-4.7233953, 17.406338, 0.0);
gp_Pnt p33(-12.529893, 13.351856, 0.0);
GC_MakeArcOfCircle arc3(p31, p32, p33);
GC_MakeSegment ln1(p13, p21);
GC_MakeSegment ln2(p23, p31);
GC_MakeSegment ln3(p33, p11);
TopoDS_Edge e1 = BRepBuilderAPI_MakeEdge(arc1.Value());
TopoDS_Edge e2 = BRepBuilderAPI_MakeEdge(arc2.Value());
TopoDS_Edge e3 = BRepBuilderAPI_MakeEdge(arc3.Value());
TopoDS_Edge e4 = BRepBuilderAPI_MakeEdge(ln1.Value());
TopoDS_Edge e5 = BRepBuilderAPI_MakeEdge(ln2.Value());
TopoDS_Edge e6 = BRepBuilderAPI_MakeEdge(ln3.Value());
BRepBuilderAPI_MakeWire MW;
MW.Add(e1);
MW.Add(e4);
MW.Add(e2);
MW.Add(e5);
MW.Add(e3);
MW.Add(e6);
if (!MW.IsDone())
{
di << "my Wire not done\n";
return 1;
}
TopoDS_Wire W = MW.Wire();
TopoDS_Face F = BRepBuilderAPI_MakeFace(W);
if (F.IsNull())
{
di << " Error in Face creation \n";
return 1;
}
try
{
OCC_CATCH_SIGNALS
gp_Dir slabDir(gp_Dir::D::Z);
gp_Vec slabVect(slabDir);
slabVect *= slabThick;
BRepPrimAPI_MakePrism slab(F, slabVect, true);
if (!slab.IsDone())
{
di << " Error in Slab creation \n";
return 1;
}
if (index < argc)
DBRep::Set(argv[index++], slab.Shape());
// std::cout << "Slab Successfully Created ! Now Blending ..." << std::endl;
// TopoDS_Shape aShape;
// int ret = performBlend(slab.Shape(), radius, aShape);
// if (ret) return 1;
// if (index < argc) DBRep::Set(argv[index++], aShape);
// std::cout << "Blending Successfully Done ! Now Triangulating ..." << std::endl;
// performTriangulation(aShape);
}
catch (Standard_Failure const&)
{
di << " Error in Draft Slab \n";
@@ -707,12 +304,6 @@ void QABugs::Commands_10(Draw_Interpretor& theCommands)
{
const char* group = "QABugs";
theCommands.Add("OCC426",
"OCC426 shape1 shape2 shape3 shape4 shape5 shape6 shape7",
__FILE__,
OCC426,
group);
theCommands.Add("isperiodic",
"Use : isperiodic surfaceOfRevolution",
__FILE__,
@@ -720,8 +311,6 @@ void QABugs::Commands_10(Draw_Interpretor& theCommands)
group);
theCommands.Add("OCC486", "Use : OCC486 surf x y z du dv ", __FILE__, OCC486, group);
theCommands.Add("OCC712", "OCC712 draftAngle slabThick", __FILE__, OCC712, group);
theCommands.Add("OCC825", "OCC825 name1 name2 name3 name4 name5", __FILE__, OCC825, group);
theCommands.Add("OCC828", "OCC828 redius shape result ", __FILE__, OCC828, group);
return;
}
-351
View File
@@ -58,10 +58,7 @@
#include <gp_Pnt2d.hxx>
#include <NCollection_Array1.hxx>
#include <NCollection_HArray1.hxx>
#include <Geom2dAPI_Interpolate.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2dConvert_BSplineCurveToBezierCurve.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <BRep_Tool.hxx>
#include <GeomProjLib.hxx>
#include <Geom2dAPI_InterCurveCurve.hxx>
@@ -76,7 +73,6 @@
#include <TCollection_AsciiString.hxx>
#include <NCollection_DoubleMap.hxx>
#include <BRepBuilderAPI_MakePolygon.hxx>
#include <gp_GTrsf.hxx>
#include <Poly_Triangulation.hxx>
#include <IGESControl_Reader.hxx>
#include <IGESData_IGESModel.hxx>
@@ -1406,41 +1402,6 @@ static int OCC708(Draw_Interpretor& di, int argc, const char** argv)
//=================================================================================================
#include <GeomAPI_ProjectPointOnSurf.hxx>
//=================================================================================================
static int OCC867(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc != 7)
{
di << "Usage : " << argv[0] << " Point Surface Umin Usup Vmin Vsup \n";
return 1;
}
gp_Pnt aPoint3d;
DrawTrSurf::GetPoint(argv[1], aPoint3d);
occ::handle<Geom_Surface> aSurface = DrawTrSurf::GetSurface(argv[2]);
double Umin = Draw::Atof(argv[3]);
double Usup = Draw::Atof(argv[4]);
double Vmin = Draw::Atof(argv[5]);
double Vsup = Draw::Atof(argv[6]);
if (aSurface.IsNull())
{
di << argv[2] << " Null surface \n";
return 1;
}
GeomAPI_ProjectPointOnSurf PonSurf;
PonSurf.Init(aSurface, Umin, Usup, Vmin, Vsup);
PonSurf.Perform(aPoint3d);
return 0;
}
//=================================================================================================
static int OCC909(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc != 3)
@@ -1750,112 +1711,6 @@ static int OCC1487(Draw_Interpretor& di, int argc, const char** argv)
}
#include <NCollection_List.hxx>
#include <BRepFilletAPI_MakeFillet.hxx>
//=================================================================================================
TopoDS_Shape OCC1077_boolbl(BRepAlgoAPI_BooleanOperation& aBoolenaOperation, const double aRadius)
{
double tesp = 1.e-4;
double t3d = 1.e-4;
double t2d = 1.e-5;
double ta = 1.e-2;
double fl = 1.e-3;
double tapp_angle = 1.e-2;
GeomAbs_Shape blend_cont = GeomAbs_C1;
TopoDS_Shape ShapeCut = aBoolenaOperation.Shape();
NCollection_List<TopoDS_Shape>::Iterator its;
TopoDS_Compound result;
BRep_Builder B;
B.MakeCompound(result);
TopExp_Explorer ex;
for (ex.Init(ShapeCut, TopAbs_SOLID); ex.More(); ex.Next())
{
const TopoDS_Shape& cutsol = ex.Current();
BRepFilletAPI_MakeFillet fill(cutsol);
fill.SetParams(ta, tesp, t2d, t3d, t2d, fl);
fill.SetContinuity(blend_cont, tapp_angle);
its = aBoolenaOperation.SectionEdges();
while (its.More())
{
TopoDS_Edge E = TopoDS::Edge(its.Value());
fill.Add(aRadius, E);
its.Next();
}
fill.Build();
if (fill.IsDone())
{
B.Add(result, fill.Shape());
}
else
{
B.Add(result, cutsol);
}
}
return result;
}
TopoDS_Shape OCC1077_cut_blend(const TopoDS_Shape& aShapeToCut,
const TopoDS_Shape& aTool,
const double aRadius)
{
// return OCC1077_boolbl(BRepAlgoAPI_Cut(aShapeToCut, aTool),aRadius);
BRepAlgoAPI_Cut aCut(aShapeToCut, aTool);
return OCC1077_boolbl(aCut, aRadius);
}
// TopoDS_Shape OCC1077_common_blend(const TopoDS_Shape& aShape1, const TopoDS_Shape& aShape2, const
// double aRadius)
//{
// return OCC1077_boolbl(BRepAlgoAPI_Common(aShape1, aShape2),aRadius);
// }
TopoDS_Shape OCC1077_Bug()
{
TopoDS_Shape theBox = BRepPrimAPI_MakeBox(gp_Pnt(-5, -5, -5), 10, 10, 10).Shape();
TopoDS_Shape theSphere = BRepPrimAPI_MakeSphere(7).Shape();
TopoDS_Shape theCommon = BRepAlgoAPI_Common(theBox, theSphere);
TopoDS_Shape theCylinder1 =
BRepPrimAPI_MakeCylinder(gp_Ax2(gp_Pnt(0, 0, -10), gp_Dir(gp_Dir::D::Z)), 3, 20).Shape();
TopoDS_Shape theCylinder2 =
BRepPrimAPI_MakeCylinder(gp_Ax2(gp_Pnt(-10, 0, 0), gp_Dir(gp_Dir::D::X)), 3, 20).Shape();
TopoDS_Shape theCylinder3 =
BRepPrimAPI_MakeCylinder(gp_Ax2(gp_Pnt(0, -10, 0), gp_Dir(gp_Dir::D::Y)), 3, 20).Shape();
TopoDS_Shape theTmp1 = OCC1077_cut_blend(theCommon, theCylinder1, 0.7);
occ::handle<ShapeFix_Shape> fixer = new ShapeFix_Shape(theTmp1);
fixer->Perform();
theTmp1 = fixer->Shape();
TopoDS_Shape theTmp2 = OCC1077_cut_blend(theTmp1, theCylinder2, 0.7);
fixer->Init(theTmp2);
fixer->Perform();
theTmp2 = fixer->Shape();
TopoDS_Shape theResult = OCC1077_cut_blend(theTmp2, theCylinder3, 0.7);
fixer->Init(theResult);
fixer->Perform();
theResult = fixer->Shape();
return theResult;
}
static int OCC1077(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc < 1 || argc > 2)
{
di << "Usage : " << argv[0] << " result\n";
return 1;
}
TopoDS_Shape S = OCC1077_Bug();
DBRep::Set(argv[1], S);
return 0;
}
//////////////////////////////////////////////////////////////
/*!
@@ -2410,50 +2265,6 @@ static int OCC7141(Draw_Interpretor& di, int argc, const char** argv)
return 0;
}
static int OCC7372(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc != 1)
{
di << "Usage : " << argv[0] << "\n";
return 1;
}
// 1. Create an array of points
occ::handle<NCollection_HArray1<gp_Pnt2d>> ap = new NCollection_HArray1<gp_Pnt2d>(1, 5);
ap->SetValue(1, gp_Pnt2d(100.0, 0.0));
ap->SetValue(2, gp_Pnt2d(100.0, 100.0));
ap->SetValue(3, gp_Pnt2d(0.0, 100.0));
ap->SetValue(4, gp_Pnt2d(0.0, 0.0));
ap->SetValue(5, gp_Pnt2d(50.0, -50.0));
// 2. Create a periodic bspline through these 5 points
Geom2dAPI_Interpolate intp(ap, true, 1e-6);
intp.Perform();
occ::handle<Geom2d_BSplineCurve> bspline1 = intp.Curve();
// 3. Increase degree of curve from 3 to 8
bspline1->IncreaseDegree(8); // Increase degree to demonstrate the error
const char* CString1 = "BSplineCurve";
DrawTrSurf::Set(CString1, bspline1);
// 4. Converts BSpline curve to Bezier segments
Geom2dConvert_BSplineCurveToBezierCurve bc(bspline1);
// 5. Test the result of conversion
TCollection_AsciiString aRName;
for (int i = 1; i <= bc.NbArcs(); i++)
{
occ::handle<Geom2d_BezierCurve> arc = bc.Arc(i);
aRName = "segment_";
aRName = aRName + TCollection_AsciiString(i);
const char* aRNameStr = aRName.ToCString();
DrawTrSurf::Set(aRNameStr, arc);
di << aRNameStr << " ";
}
return 0;
}
static int OCC8169(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc != 4)
@@ -2814,32 +2625,6 @@ static int OCC11457(Draw_Interpretor& di, int argc, const char** argv)
return 0;
}
static int OCC13963(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc < 5)
{
di << "Usage : " << argv[0] << " ratio origin_x origin_y origin_z\n";
return 1;
}
gp_Ax2 aPln(gp_Pnt(0., 0., 0.), gp_Dir(1., -1., 0.));
gp_GTrsf aTrf;
aTrf.SetAffinity(aPln, Draw::Atof(argv[4]));
gp_XYZ aOrigin(Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]));
gp_XYZ aResult(aOrigin);
aTrf.Transforms(aResult);
char sbf[512];
Sprintf(sbf,
"( %8.3f %8.3f %8.3f ) => ( %8.3f %8.3f %8.3f )\n",
aOrigin.X(),
aOrigin.Y(),
aOrigin.Z(),
aResult.X(),
aResult.Y(),
aResult.Z());
di << sbf;
return 0;
}
int OCC14376(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc < 2)
@@ -4355,122 +4140,6 @@ int OCC22301(Draw_Interpretor& di, int argc, const char** argv)
return 0;
}
#include <NCollection_DataMap.hxx>
class AIS_InteractiveObject;
int OCC22744(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc != 1)
{
di << "Usage : " << argv[0] << "\n";
return 1;
}
TCollection_ExtendedString anExtString;
char16_t aNonAsciiChar = 0x0f00;
anExtString.Insert(1, aNonAsciiChar);
di << "Is ASCII: " << (anExtString.IsAscii() ? "true : Error" : "false : OK") << "\n";
NCollection_DataMap<TCollection_ExtendedString, int> aMap;
aMap.Bind(anExtString, 0);
return 0;
}
int OCC22558(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc != 10)
{
di << "Wrong number of arguments" << argv[0] << "\n";
return 1;
}
double X_vec = Draw::Atof(argv[1]);
double Y_vec = Draw::Atof(argv[2]);
double Z_vec = Draw::Atof(argv[3]);
double X_dir = Draw::Atof(argv[4]);
double Y_dir = Draw::Atof(argv[5]);
double Z_dir = Draw::Atof(argv[6]);
double X_pnt = Draw::Atof(argv[7]);
double Y_pnt = Draw::Atof(argv[8]);
double Z_pnt = Draw::Atof(argv[9]);
gp_Dir toSym(X_vec, Y_vec, Z_vec);
gp_Dir dir(X_dir, Y_dir, Z_dir);
gp_Pnt loc(X_pnt, Y_pnt, Z_pnt);
gp_Ax2 symObj(loc, dir);
toSym.Mirror(symObj);
di << "The result " << toSym.X() << " " << toSym.Y() << " " << toSym.Z() << "\n";
return 0;
}
int OCC22736(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc != 9)
{
di << "Usage : " << argv[0]
<< " X_mirrorFirstPoint Y_mirrorFirstPoint X_mirrorSecondPoint Y_mirrorSecondPoint X_p1 "
"Y_p1 X_p2 Y_p2\n";
return 1;
}
double X_mirrorFirstPoint = Draw::Atof(argv[1]);
double Y_mirrorFirstPoint = Draw::Atof(argv[2]);
double X_mirrorSecondPoint = Draw::Atof(argv[3]);
double Y_mirrorSecondPoint = Draw::Atof(argv[4]);
double X_p1 = Draw::Atof(argv[5]);
double Y_p1 = Draw::Atof(argv[6]);
double X_p2 = Draw::Atof(argv[7]);
double Y_p2 = Draw::Atof(argv[8]);
gp_Pnt2d mirrorFirstPoint(X_mirrorFirstPoint, Y_mirrorFirstPoint);
gp_Pnt2d mirrorSecondPoint(X_mirrorSecondPoint, Y_mirrorSecondPoint);
gp_Ax2d mirrorAxis(mirrorFirstPoint, gp_Vec2d(mirrorFirstPoint, mirrorSecondPoint));
gp_Pnt2d p1(X_p1, Y_p1);
gp_Pnt2d p2(X_p2, Y_p2);
gp_Trsf2d M1;
M1.SetMirror(mirrorAxis);
gp_Trsf2d M2;
M2.SetMirror(mirrorAxis);
gp_Trsf2d Tcomp;
Tcomp = M2.Multiplied(M1);
constexpr double aTol = Precision::Confusion();
int aStatus = 0;
// After applying two times the same mirror the point is located on the same location OK
gp_Pnt2d p1MirrorM1 = p1.Transformed(M1);
if (std::abs(p2.X() - p1MirrorM1.X()) > aTol)
aStatus = 2;
if (std::abs(p2.Y() - p1MirrorM1.Y()) > aTol)
aStatus = 3;
gp_Pnt2d p1MirrorM1M2 = p1MirrorM1.Transformed(M2);
if (std::abs(p1.X() - p1MirrorM1M2.X()) > aTol)
aStatus = 4;
if (std::abs(p1.Y() - p1MirrorM1M2.Y()) > aTol)
aStatus = 5;
// If we apply the composed transformation of the same two mirrors to a point the result is //not
// located on the initial position.-->>ERROR
gp_Pnt2d p1MirrorComp = p1.Transformed(Tcomp);
if (std::abs(p1.X() - p1MirrorComp.X()) > aTol)
aStatus = 6;
if (std::abs(p1.Y() - p1MirrorComp.Y()) > aTol)
aStatus = 7;
di << "Status = " << aStatus << "\n";
return 0;
}
int OCC23429(Draw_Interpretor& /*di*/, int narg, const char** a)
{
if (narg < 4)
@@ -4718,7 +4387,6 @@ void QABugs::Commands_11(Draw_Interpretor& theCommands)
__FILE__,
OCC708,
group);
theCommands.Add("OCC867", "OCC867 Point Surface Umin Usup Vmin Vsup", __FILE__, OCC867, group);
theCommands.Add("OCC909", "OCC909 wire face", __FILE__, OCC909, group);
theCommands.Add("OCC921", "OCC921 face", __FILE__, OCC921, group);
@@ -4756,13 +4424,11 @@ void QABugs::Commands_11(Draw_Interpretor& theCommands)
OCC1487,
group);
theCommands.Add("OCC1077", "OCC1077 result", __FILE__, OCC1077, group);
theCommands.Add("OCC5739", "OCC5739 name shape step", __FILE__, OCC5739_UniAbs, group);
theCommands.Add("OCC5698", "OCC5698 wire", __FILE__, OCC5698, group);
theCommands.Add("OCC6143", "OCC6143 catching signals", __FILE__, OCC6143, group);
theCommands.Add("OCC30762", "OCC30762 printing backtrace", __FILE__, OCC30762, group);
theCommands.Add("OCC7141", "OCC7141 [nCount] aPath", __FILE__, OCC7141, group);
theCommands.Add("OCC7372", "OCC7372", __FILE__, OCC7372, group);
theCommands.Add("OCC8169", "OCC8169 edge1 edge2 plane", __FILE__, OCC8169, group);
theCommands.Add("OCC10138", "OCC10138 lower upper", __FILE__, OCC10138, group);
theCommands.Add("OCC7068", "OCC7068", __FILE__, OCC7068, group);
@@ -4771,11 +4437,6 @@ void QABugs::Commands_11(Draw_Interpretor& theCommands)
__FILE__,
OCC11457,
group);
theCommands.Add("OCC13963",
"OCC13963 ratio origin_x origin_y origin_z",
__FILE__,
OCC13963,
group);
theCommands.Add("OCC14376", "OCC14376 shape [deflection]", __FILE__, OCC14376, group);
theCommands.Add("OCC15755", "OCC15755 file shape", __FILE__, OCC15755, group);
theCommands.Add("OCC16782", "OCC16782 file.std file.xml file.cbf", __FILE__, OCC16782, group);
@@ -4788,18 +4449,6 @@ void QABugs::Commands_11(Draw_Interpretor& theCommands)
OCC17424,
group);
theCommands.Add("OCC22301", "OCC22301", __FILE__, OCC22301, group);
theCommands.Add("OCC22736",
"OCC22736 X_mirrorFirstPoint Y_mirrorFirstPoint X_mirrorSecondPoint "
"Y_mirrorSecondPoint X_p1 Y_p1 X_p2 Y_p2",
__FILE__,
OCC22736,
group);
theCommands.Add("OCC22744", "OCC22744", __FILE__, OCC22744, group);
theCommands.Add("OCC22558",
"OCC22558 x_vec y_vec z_vec x_dir y_dir z_dit x_pnt y_pnt z_pnt",
__FILE__,
OCC22558,
group);
theCommands.Add("CR23403", "CR23403 string", __FILE__, CR23403, group);
theCommands.Add("OCC23429", "OCC23429 res shape tool [appr]", __FILE__, OCC23429, group);
theCommands.Add(
-355
View File
@@ -48,356 +48,6 @@
#define M_SQRT2 1.41421356237309504880168872420969808
#endif
//=================================================================================================
static int OCC332bug(Draw_Interpretor& di, int argc, const char** argv)
{
// Used to Display Geometry or Topolgy
char name[255];
bool check = true;
// Set default arguments
double wall_thickness = 10.0;
double dia1 = 80.0;
double dia2 = 100.0;
double length = 400.0;
double major_radius = 280.0;
// Convert arguments
if (argc > 1)
wall_thickness = Draw::Atof(argv[1]);
if (argc > 2)
dia1 = Draw::Atof(argv[2]);
if (argc > 3)
dia2 = Draw::Atof(argv[3]);
if (argc > 4)
major_radius = Draw::Atof(argv[4]);
if (argc > 5)
length = Draw::Atof(argv[5]);
double bend_angle = length / major_radius;
// if ((bend_angle >= M_PI)) {
if ((bend_angle >= M_PI))
{
di << "The arguments are invalid.\n";
return 1;
}
di << "creating the shape for a bent tube\n";
double radius_l = dia1 / 2.0;
double radius_r = dia2 / 2.0;
// SUPPORT:
// 1. There is no need to normalize the direction - it's done automatically
// gp_Ax2 origin(gp_Pnt(5000.0,-300.0, 1000.0),
// gp_Dir(0.0, -1.0/M_SQRT2, -1.0/M_SQRT2));
gp_Ax2 origin(gp_Pnt(5000.0, -300.0, 1000.0), gp_Dir(0.0, -1.0, -1.0));
TopoDS_Face myFace;
TopoDS_Shape myShape, gasSolid;
TopoDS_Solid wallSolid;
// Construct a circle for the first face, on the xy-plane at the origin
gp_Pln circ1Plane(origin.Location(), origin.Direction());
gp_Circ faceCircle(origin, radius_l);
gp_Circ outFaceCircle(origin, radius_l + wall_thickness);
// Construct center for a circle to be the spine of
// revolution, on the xz-plane at x=major_radius
gp_Pnt circ_center = origin.Location().Translated(major_radius * origin.XDirection());
// This point will be the center of the second face.
// SUPPORT:
// - There is no need in this point - we'll use angle instead.
// gp_Pnt endPoint = origin.Location();
// endPoint.Translate(major_radius*(1.0-cos(bend_angle))*origin.XDirection()) ;
// endPoint.Translate((-major_radius*sin(bend_angle))*origin.Direction());
// Construct the plane for the second face to sit on.
// SUPPORT:
// - It is better to use rotation instead of explicit calculations
// gp_Pln circ2Plane = gce_MakePln(circ_center, endPoint,
// endPoint.Translated(major_radius*origin.YDirection())
// ).Value();
gp_Ax1 circ_axis(circ_center, origin.YDirection());
gp_Pln circ2Plane = circ1Plane.Rotated(circ_axis, bend_angle);
// The circle used for the spine.
// SUPPORT:
// - Use direction (-X) instead of (X) to obtain correct right-handed system.
// It is very important to maintain correct orientation between spine
// and circles axes.
// gp_Ax2 spineAxis(circ_center, origin.YDirection(), origin.XDirection());
gp_Ax2 spineAxis(circ_center, origin.YDirection(), -origin.XDirection());
gp_Circ circle(spineAxis, major_radius);
// SUPPORT:
// - There is no need to create 2nd circles - they will be created by MakePipeShell.
// gp_Ax2 circ2axis(endPoint, circ2Plane.Axis().Direction(), origin.YDirection());
// gp_Circ faceCircle2(circ2axis,radius_r);
// gp_Circ outFaceCircle2(circ2axis,radius_r+wall_thickness);
TopoDS_Edge E1 = BRepBuilderAPI_MakeEdge(faceCircle);
TopoDS_Wire Wire1_ = BRepBuilderAPI_MakeWire(E1).Wire();
// Create the face at the near end for the wall solid, an annular ring.
TopoDS_Edge Eout1 = BRepBuilderAPI_MakeEdge(outFaceCircle);
TopoDS_Wire outerWire1_ = BRepBuilderAPI_MakeWire(Eout1).Wire();
// SUPPORT:
// - There is no need to create 2nd circles -
// they will be created by MakePipeShell
// TopoDS_Edge E2 = BRepBuilderAPI_MakeEdge(faceCircle2);
// TopoDS_Wire Wire2_ = BRepBuilderAPI_MakeWire(E2).Wire();
// Create the face at the far end for the wall solid, an annular ring.
// SUPPORT:
// - There is no need to create 2nd circles -
// they will be created by MakePipeShell
// TopoDS_Edge Eout2 = BRepBuilderAPI_MakeEdge(outFaceCircle2);
// TopoDS_Wire outerWire2_ = BRepBuilderAPI_MakeWire(Eout2).Wire();
// SUPPORT:
// - It is better to use bend angle calculated above
// occ::handle<Geom_Curve> SpineCurve = GC_MakeArcOfCircle(circle,
// endPoint,
// origin.Location(),
// true).Value();
occ::handle<Geom_Curve> SpineCurve(GC_MakeArcOfCircle(circle, 0.0, bend_angle, true).Value());
// SUPPORT:
// - Use correct formula for scaling laws
occ::handle<Law_Linear> myLaw1 = new Law_Linear();
occ::handle<Law_Linear> myLaw2 = new Law_Linear();
// if ((radius_r - radius_l) < Precision::Confusion())
//{
// myLaw1->Set(SpineCurve->FirstParameter(), 1.0,
// SpineCurve->LastParameter(), 1.0);
// myLaw2->Set(SpineCurve->FirstParameter(), 1.0,
// SpineCurve->LastParameter(), 1.0);
//}
// else
//{
// myLaw1->Set(SpineCurve->FirstParameter(), radius_r/(radius_r-radius_l),
// SpineCurve->LastParameter(), 1.0);
// myLaw2->Set(SpineCurve->FirstParameter(), (radius_r+wall_thickness)/(radius_r-radius_l),
// SpineCurve->LastParameter(), 1.0);
//}
myLaw1->Set(SpineCurve->FirstParameter(), 1.0, SpineCurve->LastParameter(), radius_r / radius_l);
myLaw2->Set(SpineCurve->FirstParameter(),
1.0,
SpineCurve->LastParameter(),
(radius_r + wall_thickness) / (radius_l + wall_thickness));
BRepBuilderAPI_MakeFace mkFace;
BRepBuilderAPI_MakeEdge mkEdge;
mkEdge.Init(SpineCurve);
if (!mkEdge.IsDone())
return 0;
TopoDS_Wire SpineWire = BRepBuilderAPI_MakeWire(mkEdge.Edge()).Wire();
Sprintf(name, "SpineWire");
DBRep::Set(name, SpineWire);
Sprintf(name, "Wire1_");
DBRep::Set(name, Wire1_);
Sprintf(name, "outerWire1_");
DBRep::Set(name, outerWire1_);
// SUPPORT:
// - There is no need to create 2nd circles
// Sprintf (name,"Wire2_");
// DBRep::Set(name,Wire2_);
// Sprintf (name,"outerWire2_");
// DBRep::Set(name,outerWire2_);
di.Eval("fit");
// SUPPORT:
// - There is no need in these vertices
// TopoDS_Vertex Location1, Location2;
// TopExp::Vertices(SpineWire, Location1, Location2);
// Make inner pipe shell
BRepOffsetAPI_MakePipeShell mkPipe1(SpineWire);
mkPipe1.SetTolerance(1.0e-8, 1.0e-8, 1.0e-6);
// mkPipe1.SetTransitionMode(BRepBuilderAPI_Transformed); // Default mode !!
mkPipe1.SetLaw(Wire1_, myLaw1 /*, Location2*/, false, false);
mkPipe1.Build();
if (!mkPipe1.IsDone())
return 0;
// Make outer pipe shell
BRepOffsetAPI_MakePipeShell mkPipe2(SpineWire);
mkPipe2.SetTolerance(1.0e-8, 1.0e-8, 1.0e-6);
// mkPipe2.SetTransitionMode(BRepBuilderAPI_Transformed); // Default mode !!
mkPipe2.SetLaw(outerWire1_, myLaw2 /*, Location2*/, false, false);
mkPipe2.Build();
if (!mkPipe2.IsDone())
return 0;
// Make face for first opening
occ::handle<Geom_Plane> Plane1 = new Geom_Plane(circ1Plane);
mkFace.Init(Plane1, false, Precision::Confusion());
// SUPPORT:
// - Use wires created by MakePipeShell
// mkFace.Add(TopoDS::Wire(outerWire1_));
// mkFace.Add(TopoDS::Wire(Wire1_.Reversed()));
mkFace.Add(TopoDS::Wire(mkPipe2.FirstShape()));
mkFace.Add(TopoDS::Wire(mkPipe1.FirstShape().Reversed()));
if (!mkFace.IsDone())
return 0;
TopoDS_Face Face1 = mkFace.Face();
// Make face for second opening
occ::handle<Geom_Plane> Plane2 = new Geom_Plane(circ2Plane);
mkFace.Init(Plane2, false, Precision::Confusion());
// SUPPORT:
// - Use wires created by MakePipeShell
// mkFace.Add(TopoDS::Wire(outerWire2_));
// mkFace.Add(TopoDS::Wire(Wire2_.Reversed()));
mkFace.Add(TopoDS::Wire(mkPipe2.LastShape()));
mkFace.Add(TopoDS::Wire(mkPipe1.LastShape().Reversed()));
if (!mkFace.IsDone())
return 0;
TopoDS_Face Face2 = mkFace.Face();
// Make tube
TopoDS_Shell TubeShell;
BRep_Builder B;
B.MakeShell(TubeShell);
TopExp_Explorer getFaces;
TopoDS_Face test_face;
getFaces.Init(mkPipe1.Shape(), TopAbs_FACE);
// SUPPORT:
// - In our case there should be only 1 pipe face
// while (getFaces.More())
// {
// test_face = TopoDS::Face(getFaces.Current());
// occ::handle<Geom_Surface> S = BRep_Tool::Surface(test_face);
// GeomLib_IsPlanarSurface IsPl(S);
// if (!IsPl.IsPlanar()) {
// B.Add(TubeShell,getFaces.Current().Reversed());
// }
// getFaces.Next();
// }
if (getFaces.More())
B.Add(TubeShell, getFaces.Current().Reversed());
// Grab the gas solid now that we've extracted the faces.
mkPipe1.MakeSolid();
gasSolid = mkPipe1.Shape();
Sprintf(name, "gasSolid_");
DBRep::Set(name, gasSolid);
// getFaces.Clear();
getFaces.Init(mkPipe2.Shape(), TopAbs_FACE);
// SUPPORT:
// - In our case there should be only 1 pipe face
// while (getFaces.More())
// {
// B.Add(TubeShell,getFaces.Current());
// getFaces.Next();
// }
if (getFaces.More())
B.Add(TubeShell, getFaces.Current());
B.Add(TubeShell, Face1.Reversed());
B.Add(TubeShell, Face2);
TubeShell.Closed(BRep_Tool::IsClosed(TubeShell));
B.MakeSolid(wallSolid);
B.Add(wallSolid, TubeShell);
Sprintf(name, "wallSolid_");
DBRep::Set(name, wallSolid);
// Now calculated the volume of the outside tube.
GProp_GProps gprops;
BRepGProp::VolumeProperties(wallSolid, gprops);
di << "The wallSolid's volume is: " << gprops.Mass() << "\n";
if (check)
{
if (!(BRepCheck_Analyzer(wallSolid).IsValid()))
di << "The TopoDS_Solid was checked, and it was invalid!\n";
else
di << "The TopoDS_Solid was checked, and it was valid.\n";
if (!wallSolid.Closed())
di << "The TopoDS_Solid is not closed!\n";
else
di << "The TopoDS_Solid is closed.\n";
if (!wallSolid.Checked())
di << "The TopoDS_Solid is not checked!\n";
else
di << "The TopoDS_Solid has been checked.\n";
if (wallSolid.Infinite())
di << "The TopoDS_Solid is infinite!\n";
else
di << "The TopoDS_Solid is finite.\n";
}
di << "The result is a ";
// Check to see if we have a solid
switch (wallSolid.ShapeType())
{
case (TopAbs_COMPOUND):
di << "TopAbs_COMPOUND\n";
break;
case (TopAbs_COMPSOLID):
di << "TopAbs_COMPSOLID\n";
break;
case (TopAbs_SOLID):
di << "TopAbs_SOLID\n";
break;
case (TopAbs_SHELL):
di << "TopAbs_SHELL\n";
break;
case (TopAbs_FACE):
di << "TopAbs_FACE\n";
break;
case (TopAbs_WIRE):
di << "TopAbs_WIRE\n";
break;
case (TopAbs_EDGE):
di << "TopAbs_EDGE\n";
break;
case (TopAbs_VERTEX):
di << "TopAbs_VERTEX\n";
break;
case (TopAbs_SHAPE):
di << "TopAbs_SHAPE\n";
}
di << "Can we turn it into a solid? ";
try
{
OCC_CATCH_SIGNALS
di << " yes\n";
}
catch (Standard_TypeMismatch const&)
{
di << " no\n";
}
getFaces.Clear();
getFaces.Init(wallSolid, TopAbs_FACE);
int i = 0;
while (getFaces.More())
{
i++;
Sprintf(name, "Face%d", i);
di << "Face named " << name << "\n";
DBRep::Set(name, getFaces.Current());
getFaces.Next();
}
return 0;
}
#include <gce_MakePln.hxx>
#include <BRepOffsetAPI_Sewing.hxx>
#include <BRepAlgoAPI_Fuse.hxx>
@@ -787,11 +437,6 @@ void QABugs::Commands_13(Draw_Interpretor& theCommands)
{
const char* group = "QABugs";
theCommands.Add("OCC332",
"OCC332 [wall_thickness [dia1 [dia2 [length [major_radius]]]]]",
__FILE__,
OCC332bug,
group);
theCommands.Add("OCC544",
"OCC544 [[[[[wT [[[[d1 [[[d2 [[R [length ]]]]]",
__FILE__,
-70
View File
@@ -266,71 +266,6 @@ static int BUC60854(Draw_Interpretor& /*di*/, int argc, const char** argv)
return 0;
}
static int BUC60870(Draw_Interpretor& di, int argc, const char** argv)
{
int i1;
if (argc != 5)
{
di << "Usage : " << argv[0] << " result name_of_shape_1 name_of_shape_2 dev\n";
return 1;
}
const char * ns1 = (argv[2]), *ns2 = (argv[3]), *ns0 = (argv[1]);
TopoDS_Shape S1(DBRep::Get(ns1)), S2(DBRep::Get(ns2));
double dev = Draw::Atof(argv[4]);
BRepExtrema_DistShapeShape dst(S1, S2, dev);
if (dst.IsDone())
{
char named[100];
Sprintf(named, "%s%s", ns0, "_val");
char* tempd = named;
Draw::Set(tempd, dst.Value());
di << named << " ";
for (i1 = 1; i1 <= dst.NbSolution(); i1++)
{
gp_Pnt P1, P2;
P1 = (dst.PointOnShape1(i1));
P2 = (dst.PointOnShape2(i1));
if (dst.Value() <= 1.e-9)
{
TopoDS_Vertex V = BRepLib_MakeVertex(P1);
char namev[100];
if (i1 == 1)
{
Sprintf(namev, "%s", ns0);
}
else
{
Sprintf(namev, "%s%d", ns0, i1);
}
char* tempv = namev;
DBRep::Set(tempv, V);
di << namev << " ";
}
else
{
char name[100];
TopoDS_Edge E = BRepLib_MakeEdge(P1, P2);
if (i1 == 1)
{
Sprintf(name, "%s", ns0);
}
else
{
Sprintf(name, "%s%d", ns0, i1);
}
char* temp = name;
DBRep::Set(temp, E);
di << name << " ";
}
}
}
else
{
di << "Faulty : found a problem\n";
}
return 0;
}
static int BUC60944(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc != 2)
@@ -1010,11 +945,6 @@ void QABugs::Commands_14(Draw_Interpretor& theCommands)
__FILE__,
BUC60854,
group);
theCommands.Add("BUC60870",
"BUC60870 result name_of_shape_1 name_of_shape_2 dev",
__FILE__,
BUC60870,
group);
theCommands.Add("BUC60944", "BUC60944 path", __FILE__, BUC60944, group);
theCommands.Add("BUC60868", "BUC60868 Result Shell", __FILE__, BUC60868, group);
theCommands.Add("BUC60924", "BUC60924 curve X Y Z", __FILE__, BUC60924, group);
+4 -47
View File
@@ -61,7 +61,6 @@
#include <Draw.hxx>
#include <GeomInt_IntSS.hxx>
#include <NCollection_Sequence.hxx>
#include <Geom_ConicalSurface.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <Extrema_FuncPSNorm.hxx>
#include <BRepAdaptor_Curve.hxx>
@@ -93,28 +92,16 @@ Standard_DISABLE_DEPRECATION_WARNINGS
std::cout << "Error: " #val " is false\n"; \
}
// Helper function to create conical surface
static occ::handle<Geom_Surface>
CreateCone(const gp_Pnt& theApex,
const gp_Dir& theDir,
const gp_Dir& theXDir,
double theR,
double theSemiAngle,
double /*theH*/)
{
gp_Ax3 anAxis(theApex, theDir, theXDir);
return new Geom_ConicalSurface(anAxis, theSemiAngle, theR);
}
#include <TopoDS_Face.hxx>
#include <TopoDS.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <BRepTools.hxx>
static bool OCC23774Test(const TopoDS_Face& grossPlateFace,
const TopoDS_Shape& originalWire,
Draw_Interpretor& di)
static bool
OCC23774Test(const TopoDS_Face& grossPlateFace,
const TopoDS_Shape& originalWire,
Draw_Interpretor& di)
{
BRepExtrema_DistShapeShape distShapeShape(grossPlateFace, originalWire, Extrema_ExtFlag_MIN);
if (!distShapeShape.IsDone())
@@ -682,35 +669,6 @@ static int OCC24137(Draw_Interpretor& theDI, int theNArg, const char** theArgv)
return 0;
}
//! Check boolean operations on NCollection_Map
static int OCC23972(Draw_Interpretor& /*theDI*/, int theNArg, const char** theArgs)
{
if (theNArg != 3)
return 1;
// process specific cones, cannot read them from files because
// due to rounding the original error in math_FunctionRoots gets hidden
const occ::handle<Geom_Surface> aS1 =
CreateCone(gp_Pnt(123.694345356663, 789.9, 68.15),
gp_Dir(-1, 3.48029791472957e-016, -8.41302743359754e-017),
gp_Dir(-3.48029791472957e-016, -1, -3.17572289932207e-016),
3.28206830417112,
0.780868809443031,
0.624695047554424);
const occ::handle<Geom_Surface> aS2 =
CreateCone(gp_Pnt(123.694345356663, 784.9, 68.15),
gp_Dir(-1, -2.5209507537117e-016, -1.49772808948866e-016),
gp_Dir(1.49772808948866e-016, 3.17572289932207e-016, -1),
3.28206830417112,
0.780868809443031,
0.624695047554424);
DrawTrSurf::Set(theArgs[1], aS1);
DrawTrSurf::Set(theArgs[2], aS2);
return 0;
}
#include <ShapeFix_EdgeProjAux.hxx>
static int OCC24370(Draw_Interpretor& di, int argc, const char** argv)
@@ -2769,7 +2727,6 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands)
group);
theCommands.Add("OCC24008", "OCC24008 curve surface", __FILE__, OCC24008, group);
theCommands.Add("OCC24137", "OCC24137 face vertex U V [N]", __FILE__, OCC24137, group);
theCommands.Add("OCC23972", "OCC23972", __FILE__, OCC23972, group);
theCommands.Add("OCC24370", "OCC24370 edge pcurve surface prec", __FILE__, OCC24370, group);
theCommands.Add("OCC24086", "OCC24086 face wire", __FILE__, OCC24086, group);
theCommands.Add("OCC24667",
@@ -45,6 +45,7 @@ set(OCCT_TKMath_GTests_FILES
gp_Circ_Test.cxx
gp_Dir_Test.cxx
gp_Dir2d_Test.cxx
gp_GTrsf_Test.cxx
gp_Lin_Test.cxx
gp_Mat_Test.cxx
gp_Pln_Test.cxx
@@ -180,3 +180,19 @@ TEST(gp_DirTest, ZeroMagnitudeInput_ThrowsException)
GTEST_SKIP() << "No_Exception is defined; exception behavior is disabled in this build.";
#endif
}
// OCC22558: Mirror of gp_Dir(1,1,1) through gp_Ax2 at origin with main dir (1,0,0) gives
// (-1/sqrt(3), 1/sqrt(3), 1/sqrt(3)). The TCL test checks int(res * 100000) == {-57735, 57735,
// 57735}.
TEST(gp_DirTest, OCC22558_MirrorThroughAx2_CorrectResult)
{
gp_Dir aToSym(1.0, 1.0, 1.0);
const gp_Ax2 anAx2(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
aToSym.Mirror(anAx2);
// Expected: (-1/sqrt(3), 1/sqrt(3), 1/sqrt(3))
const double aExpected = 1.0 / std::sqrt(3.0);
EXPECT_NEAR(aToSym.X(), -aExpected, Precision::Confusion());
EXPECT_NEAR(aToSym.Y(), aExpected, Precision::Confusion());
EXPECT_NEAR(aToSym.Z(), aExpected, Precision::Confusion());
}
@@ -0,0 +1,55 @@
// Copyright (c) 2026 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Precision.hxx>
#include <gp_Ax2.hxx>
#include <gp_Dir.hxx>
#include <gp_GTrsf.hxx>
#include <gp_Pnt.hxx>
#include <gp_XYZ.hxx>
#include <gtest/gtest.h>
// OCC13963: SetAffinity with ratio=1 is identity transform for any point.
// The plane is defined by gp_Ax2 at origin with main dir (1,-1,0)/sqrt(2).
TEST(gp_GTrsfTest, OCC13963_SetAffinity_Ratio1_IsIdentity)
{
const gp_Ax2 aPln(gp_Pnt(0., 0., 0.), gp_Dir(1., -1., 0.));
gp_GTrsf aTrf;
aTrf.SetAffinity(aPln, 1.0);
gp_XYZ aOrigin(1.0, 0.0, 0.0);
gp_XYZ aResult(aOrigin);
aTrf.Transforms(aResult);
EXPECT_NEAR(aResult.X(), 1.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 0.0, Precision::Confusion());
EXPECT_NEAR(aResult.Z(), 0.0, Precision::Confusion());
}
// OCC13963: SetAffinity with ratio=2 scales the point component along the plane normal.
// Point (1,0,0) through plane with normal (1,-1,0)/sqrt(2) with ratio 2 gives (1.5,-0.5,0).
TEST(gp_GTrsfTest, OCC13963_SetAffinity_Ratio2_ScalesAlongNormal)
{
const gp_Ax2 aPln(gp_Pnt(0., 0., 0.), gp_Dir(1., -1., 0.));
gp_GTrsf aTrf;
aTrf.SetAffinity(aPln, 2.0);
gp_XYZ aOrigin(1.0, 0.0, 0.0);
gp_XYZ aResult(aOrigin);
aTrf.Transforms(aResult);
EXPECT_NEAR(aResult.X(), 1.5, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), -0.5, Precision::Confusion());
EXPECT_NEAR(aResult.Z(), 0.0, Precision::Confusion());
}
@@ -135,3 +135,37 @@ TEST(gp_Pnt2dTest, Transformed)
EXPECT_NEAR(aResult.X(), 1.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 5.0, Precision::Confusion());
}
// OCC22736: Verifies that composing two identical mirror transformations through the same axis
// is equivalent to the identity transform. Mirror p1 once through the axis to get p2, then
// mirror p2 to get back p1. Composing M1*M2 and applying to p1 must also return p1.
TEST(gp_Pnt2dTest, OCC22736_TwoIdenticalMirrorCompositionIsIdentity)
{
const gp_Pnt2d aMirrorFirst(2.0, 1.0);
const gp_Pnt2d aMirrorSecond(3.0, 1.0);
const gp_Ax2d aMirrorAxis(aMirrorFirst, gp_Vec2d(aMirrorFirst, aMirrorSecond));
const gp_Pnt2d aP1(1.0, 0.0);
const gp_Pnt2d aP2(1.0, 2.0);
gp_Trsf2d aM1;
aM1.SetMirror(aMirrorAxis);
gp_Trsf2d aM2;
aM2.SetMirror(aMirrorAxis);
// Applying M1 to p1 should give p2
const gp_Pnt2d aP1MirrorM1 = aP1.Transformed(aM1);
EXPECT_NEAR(aP1MirrorM1.X(), aP2.X(), Precision::Confusion());
EXPECT_NEAR(aP1MirrorM1.Y(), aP2.Y(), Precision::Confusion());
// Applying M2 to the mirrored point should give back p1
const gp_Pnt2d aP1MirrorM1M2 = aP1MirrorM1.Transformed(aM2);
EXPECT_NEAR(aP1MirrorM1M2.X(), aP1.X(), Precision::Confusion());
EXPECT_NEAR(aP1MirrorM1M2.Y(), aP1.Y(), Precision::Confusion());
// Composing M2*M1 must also be identity on p1
const gp_Trsf2d aComp = aM2.Multiplied(aM1);
const gp_Pnt2d aP1Comp = aP1.Transformed(aComp);
EXPECT_NEAR(aP1Comp.X(), aP1.X(), Precision::Confusion());
EXPECT_NEAR(aP1Comp.Y(), aP1.Y(), Precision::Confusion());
}
@@ -13,6 +13,7 @@
#include <TCollection_ExtendedString.hxx>
#include <TCollection_AsciiString.hxx>
#include <NCollection_DataMap.hxx>
#include <Standard_OutOfRange.hxx>
#include <gtest/gtest.h>
@@ -1122,3 +1123,18 @@ TEST(TCollection_ExtendedStringTest, EndsWith_Match)
const TCollection_ExtendedString aSuffix("lo");
EXPECT_TRUE(aStr.EndsWith(aSuffix));
}
// OCC22744: A TCollection_ExtendedString containing a non-ASCII character must report
// IsAscii() == false, and must be usable as a key in NCollection_DataMap without crash.
TEST(TCollection_ExtendedStringTest, OCC22744_NonAsciiCharIsNotAsciiAndCanBeUsedAsMapKey)
{
TCollection_ExtendedString anExtString;
const char16_t aNonAsciiChar = 0x0f00;
anExtString.Insert(1, aNonAsciiChar);
EXPECT_FALSE(anExtString.IsAscii());
NCollection_DataMap<TCollection_ExtendedString, int> aMap;
EXPECT_NO_THROW(aMap.Bind(anExtString, 0));
EXPECT_EQ(aMap.Size(), 1);
}
@@ -13,6 +13,19 @@
#include "BOPTest_Utilities.pxx"
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <BRepGProp.hxx>
#include <BRepPrimAPI_MakeHalfSpace.hxx>
#include <Geom_BezierSurface.hxx>
#include <Geom_BSplineSurface.hxx>
#include <GeomConvert.hxx>
#include <GProp_GProps.hxx>
#include <NCollection_Array2.hxx>
#include <Precision.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp_Explorer.hxx>
#ifndef M_SQRT2
#define M_SQRT2 1.41421356237309504880168872420969808
#endif
@@ -25,6 +38,16 @@ class BCutSimpleTest : public BRepAlgoAPI_TestBase
{
};
static int countSubShapes(const TopoDS_Shape& theShape, const TopAbs_ShapeEnum theType)
{
int aCount = 0;
for (TopExp_Explorer anExp(theShape, theType); anExp.More(); anExp.Next())
{
++aCount;
}
return aCount;
}
// Test bcut_simple/A1: psphere s 1; box b 1 1 1; bcut result s b; checkprops result -s 13.3518
TEST_F(BCutSimpleTest, SphereMinusBox_A1)
{
@@ -1770,3 +1793,59 @@ TEST_F(BCutSimpleTest, ComplexProfileReversedReversedVariation2_I9)
const TopoDS_Shape aResult = PerformCut(aIntermediate, aPrism3);
ValidateResult(aResult, 52000.0);
}
//=================================================================================================
// OCC825 Bug Tests
//=================================================================================================
// OCC825: BRepAlgoAPI_Cut of two spheres with a BSpline-defined half-space produces valid shapes.
// Bug: BRepAlgoAPI_Cut failed on sphere and b-spline face.
// Verifies both cut results are valid and have expected surface area (~5890.42).
TEST(BRepAlgoAPI_CutTest, Bug825_SphereHalfSpaceCut)
{
constexpr double aSize = 50.0;
NCollection_Array2<gp_Pnt> aPoles(1, 2, 1, 2);
aPoles(1, 1).SetCoord(-aSize, 0, -aSize);
aPoles(1, 2).SetCoord(-aSize, 0, aSize);
aPoles(2, 1).SetCoord(aSize, 0, -aSize);
aPoles(2, 2).SetCoord(aSize, 0, aSize);
const occ::handle<Geom_BezierSurface> aBezSurf = new Geom_BezierSurface(aPoles);
const occ::handle<Geom_BSplineSurface> aBSpSurf = GeomConvert::SurfaceToBSplineSurface(aBezSurf);
BRepBuilderAPI_MakeFace aFaceMaker(aBSpSurf, Precision::Confusion());
ASSERT_TRUE(aFaceMaker.IsDone());
const TopoDS_Face& aFace = aFaceMaker.Face();
BRepPrimAPI_MakeHalfSpace aHSpaceMaker(aFace, gp_Pnt(0, aSize, 0));
ASSERT_TRUE(aHSpaceMaker.IsDone());
const TopoDS_Shape aHsp = aHSpaceMaker.Solid();
const TopoDS_Shape aSph1 = BRepPrimAPI_MakeSphere(gp_Pnt(0.0, 0.0, 0.0), 25.0).Shape();
const TopoDS_Shape aSph2 = BRepPrimAPI_MakeSphere(gp_Pnt(0.0, 0.00001, 0.0), 25.0).Shape();
BRepAlgoAPI_Cut aCut1(aSph1, aHsp);
ASSERT_TRUE(aCut1.IsDone()) << "BRepAlgoAPI_Cut failed for first sphere";
const TopoDS_Shape aResult1 = aCut1.Shape();
ASSERT_FALSE(aResult1.IsNull());
BRepAlgoAPI_Cut aCut2(aSph2, aHsp);
ASSERT_TRUE(aCut2.IsDone()) << "BRepAlgoAPI_Cut failed for second sphere";
const TopoDS_Shape aResult2 = aCut2.Shape();
ASSERT_FALSE(aResult2.IsNull());
GProp_GProps aProps1;
BRepGProp::SurfaceProperties(aResult1, aProps1);
EXPECT_NEAR(aProps1.Mass(), 5890.42, 5.89042);
EXPECT_EQ(countSubShapes(aResult1, TopAbs_FACE), 2);
EXPECT_EQ(countSubShapes(aResult1, TopAbs_SHELL), 1);
EXPECT_EQ(countSubShapes(aResult1, TopAbs_SOLID), 1);
EXPECT_EQ(aResult1.ShapeType(), TopAbs_COMPOUND);
GProp_GProps aProps2;
BRepGProp::SurfaceProperties(aResult2, aProps2);
EXPECT_NEAR(aProps2.Mass(), 5890.42, 5.89042);
EXPECT_EQ(countSubShapes(aResult2, TopAbs_FACE), 2);
EXPECT_EQ(countSubShapes(aResult2, TopAbs_SHELL), 1);
EXPECT_EQ(countSubShapes(aResult2, TopAbs_SOLID), 1);
EXPECT_EQ(aResult2.ShapeType(), TopAbs_COMPOUND);
}
@@ -11,18 +11,53 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <cmath>
#include <BRep_Builder.hxx>
#include <BRepAlgoAPI_BooleanOperation.hxx>
#include <BRepAlgoAPI_Common.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepAlgoAPI_Fuse.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakePolygon.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <BRepFilletAPI_MakeFillet.hxx>
#include <BRepGProp.hxx>
#include <ChFi3d_FilletShape.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepPrimAPI_MakeRevol.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <NCollection_IndexedDataMap.hxx>
#include <ShapeUpgrade_UnifySameDomain.hxx>
#include <TopExp.hxx>
#include <TopTools_ShapeMapHasher.hxx>
#include <gp_Ax1.hxx>
#include <GeomAbs_Shape.hxx>
#include <GC_MakeArcOfCircle.hxx>
#include <GC_MakeSegment.hxx>
#include <GProp_GProps.hxx>
#include <NCollection_Array1.hxx>
#include <NCollection_List.hxx>
#include <NCollection_Sequence.hxx>
#include <ShapeFix_Shape.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Wire.hxx>
#include <gp_Ax2.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <Standard_Failure.hxx>
#include <gtest/gtest.h>
@@ -154,3 +189,341 @@ TEST(BRepFilletAPI_MakeFilletTest, OCC570_MixedVariableConstantRadius)
BRepGProp::SurfaceProperties(aResult, aProps);
EXPECT_NEAR(aProps.Mass(), 58500., 58500. * 0.01) << "Surface area should be approximately 58500";
}
//=================================================================================================
// OCC828: BRepFilletAPI_MakeFillet succeeds on a prism built from a complex wire of arcs and
// line segments (trefoil-like profile). Bug: BRepFilletAPI_MakeFillet failed on this prism.
TEST(BRepFilletAPI_MakeFilletTest, Bug828_FilletOnComplexPrism)
{
const gp_Pnt aPnt11(-27.598139, -7.0408573, 0.0);
const gp_Pnt aPnt12(-28.483755, -17.487625, 0.0);
const gp_Pnt aPnt13(-19.555504, -22.983587, 0.0);
GC_MakeArcOfCircle anArc1(aPnt11, aPnt12, aPnt13);
const gp_Pnt aPnt21(12.125083, -22.983587, 0.0);
const gp_Pnt aPnt22(21.1572, -17.27554, 0.0);
const gp_Pnt aPnt23(19.878168, -6.6677585, 0.0);
GC_MakeArcOfCircle anArc2(aPnt21, aPnt22, aPnt23);
const gp_Pnt aPnt31(3.265825, 13.724955, 0.0);
const gp_Pnt aPnt32(-4.7233953, 17.406338, 0.0);
const gp_Pnt aPnt33(-12.529893, 13.351856, 0.0);
GC_MakeArcOfCircle anArc3(aPnt31, aPnt32, aPnt33);
GC_MakeSegment aSegment1(aPnt13, aPnt21);
GC_MakeSegment aSegment2(aPnt23, aPnt31);
GC_MakeSegment aSegment3(aPnt33, aPnt11);
BRepBuilderAPI_MakeWire aWireMaker;
aWireMaker.Add(BRepBuilderAPI_MakeEdge(anArc1.Value()));
aWireMaker.Add(BRepBuilderAPI_MakeEdge(aSegment1.Value()));
aWireMaker.Add(BRepBuilderAPI_MakeEdge(anArc2.Value()));
aWireMaker.Add(BRepBuilderAPI_MakeEdge(aSegment2.Value()));
aWireMaker.Add(BRepBuilderAPI_MakeEdge(anArc3.Value()));
aWireMaker.Add(BRepBuilderAPI_MakeEdge(aSegment3.Value()));
ASSERT_TRUE(aWireMaker.IsDone());
const TopoDS_Wire aWire = aWireMaker.Wire();
const TopoDS_Face aFace = BRepBuilderAPI_MakeFace(aWire);
ASSERT_FALSE(aFace.IsNull());
constexpr double aSlabThick = 111.0;
BRepPrimAPI_MakePrism aSlab(aFace, gp_Vec(0, 0, aSlabThick), true);
ASSERT_TRUE(aSlab.IsDone());
const TopoDS_Shape aSlabShape = aSlab.Shape();
BRepCheck_Analyzer aSlabChecker(aSlabShape);
EXPECT_TRUE(aSlabChecker.IsValid()) << "Prism shape should be valid";
NCollection_Sequence<TopoDS_Edge> anEdges;
for (TopExp_Explorer anExp(aSlabShape, TopAbs_EDGE); anExp.More(); anExp.Next())
{
anEdges.Append(TopoDS::Edge(anExp.Current()));
}
ASSERT_GE(anEdges.Length(), 2) << "Expected at least 2 edges in the prism";
constexpr double aTargetArea = 17816.2;
constexpr double aTargetTolerance = aTargetArea * 0.002;
TopoDS_Shape aResult;
bool hasMatchingPair = false;
double aBestArea = 0.0;
double aBestDelta = 1.0e100;
int aBestEdgeIndex1 = 0;
int aBestEdgeIndex2 = 0;
// Tcl 'explode' numbering is not guaranteed to match TopExp_Explorer order here,
// so select the edge pair that reproduces the original regression result.
for (int anEdgeIndex1 = 1; anEdgeIndex1 <= anEdges.Length() && !hasMatchingPair; ++anEdgeIndex1)
{
for (int anEdgeIndex2 = anEdgeIndex1 + 1; anEdgeIndex2 <= anEdges.Length(); ++anEdgeIndex2)
{
try
{
BRepFilletAPI_MakeFillet aFillet(aSlabShape, ChFi3d_Rational);
aFillet.SetParams(1.0e-2, 1.0e-4, 1.0e-5, 1.0e-4, 1.0e-5, 1.0e-3);
aFillet.SetContinuity(GeomAbs_C1, 1.0e-2);
aFillet.Add(10.0, anEdges.Value(anEdgeIndex1));
aFillet.Add(10.0, anEdges.Value(anEdgeIndex2));
aFillet.Build();
if (!aFillet.IsDone())
{
continue;
}
const TopoDS_Shape aCandidateResult = aFillet.Shape();
if (aCandidateResult.IsNull())
{
continue;
}
BRepCheck_Analyzer aResultChecker(aCandidateResult);
if (!aResultChecker.IsValid())
{
continue;
}
GProp_GProps aProps;
BRepGProp::SurfaceProperties(aCandidateResult, aProps);
const double aDelta = std::abs(aProps.Mass() - aTargetArea);
if (aDelta < aBestDelta)
{
aBestArea = aProps.Mass();
aBestDelta = aDelta;
aBestEdgeIndex1 = anEdgeIndex1;
aBestEdgeIndex2 = anEdgeIndex2;
}
if (std::abs(aProps.Mass() - aTargetArea) <= aTargetTolerance)
{
aResult = aCandidateResult;
hasMatchingPair = true;
break;
}
}
catch (Standard_Failure const&)
{
continue;
}
}
}
ASSERT_TRUE(hasMatchingPair)
<< "Failed to reproduce the original OCC828 fillet result; closest pair=" << aBestEdgeIndex1
<< "," << aBestEdgeIndex2 << " area=" << aBestArea;
BRepCheck_Analyzer aResultChecker(aResult);
EXPECT_TRUE(aResultChecker.IsValid()) << "Fillet result shape should be valid";
GProp_GProps aProps;
BRepGProp::SurfaceProperties(aResult, aProps);
EXPECT_NEAR(aProps.Mass(), aTargetArea, aTargetTolerance);
}
//=================================================================================================
// Helpers for OCC1077 test: boolean operations + fillet on each resulting solid
namespace
{
//! Apply fillet of given radius to all section edges of a boolean operation.
TopoDS_Shape occ1077BoolBl(BRepAlgoAPI_BooleanOperation& theBoolOp, double theRadius)
{
const double aTesp = 1.e-4;
const double aT3d = 1.e-4;
const double aT2d = 1.e-5;
const double aTa = 1.e-2;
const double aFl = 1.e-3;
const double aTappAngl = 1.e-2;
const GeomAbs_Shape aBlendCont = GeomAbs_C1;
const TopoDS_Shape aShapeCut = theBoolOp.Shape();
TopoDS_Compound aResult;
BRep_Builder aBuilder;
aBuilder.MakeCompound(aResult);
for (TopExp_Explorer anExp(aShapeCut, TopAbs_SOLID); anExp.More(); anExp.Next())
{
const TopoDS_Shape& aSolid = anExp.Current();
BRepFilletAPI_MakeFillet aFill(aSolid);
aFill.SetParams(aTa, aTesp, aT2d, aT3d, aT2d, aFl);
aFill.SetContinuity(aBlendCont, aTappAngl);
for (NCollection_List<TopoDS_Shape>::Iterator anIt(theBoolOp.SectionEdges()); anIt.More();
anIt.Next())
{
aFill.Add(theRadius, TopoDS::Edge(anIt.Value()));
}
aFill.Build();
if (aFill.IsDone())
aBuilder.Add(aResult, aFill.Shape());
else
aBuilder.Add(aResult, aSolid);
}
return aResult;
}
//! Cut theShapeToCut with aTool and fillet the section edges with given radius.
TopoDS_Shape occ1077CutBlend(const TopoDS_Shape& theShapeToCut,
const TopoDS_Shape& theTool,
double theRadius)
{
BRepAlgoAPI_Cut aCut(theShapeToCut, theTool);
return occ1077BoolBl(aCut, theRadius);
}
} // anonymous namespace
//=================================================================================================
TEST(BRepFilletAPI_MakeFilletTest, OCC1077_BooleanCutFillet)
{
// Build box-sphere common, then subtract 3 cylinders with fillets on section edges.
// Regression: this combination used to cause a crash or incorrect result.
// TCL reference: checkprops result -s 587.181; checkshape result
const TopoDS_Shape aBox = BRepPrimAPI_MakeBox(gp_Pnt(-5, -5, -5), 10, 10, 10).Shape();
const TopoDS_Shape aSphere = BRepPrimAPI_MakeSphere(7).Shape();
const TopoDS_Shape aCommon = BRepAlgoAPI_Common(aBox, aSphere).Shape();
const TopoDS_Shape aCyl1 =
BRepPrimAPI_MakeCylinder(gp_Ax2(gp_Pnt(0, 0, -10), gp_Dir(gp_Dir::D::Z)), 3, 20).Shape();
const TopoDS_Shape aCyl2 =
BRepPrimAPI_MakeCylinder(gp_Ax2(gp_Pnt(-10, 0, 0), gp_Dir(gp_Dir::D::X)), 3, 20).Shape();
const TopoDS_Shape aCyl3 =
BRepPrimAPI_MakeCylinder(gp_Ax2(gp_Pnt(0, -10, 0), gp_Dir(gp_Dir::D::Y)), 3, 20).Shape();
TopoDS_Shape aTmp1 = occ1077CutBlend(aCommon, aCyl1, 0.7);
occ::handle<ShapeFix_Shape> aFixer = new ShapeFix_Shape(aTmp1);
aFixer->Perform();
aTmp1 = aFixer->Shape();
TopoDS_Shape aTmp2 = occ1077CutBlend(aTmp1, aCyl2, 0.7);
aFixer->Init(aTmp2);
aFixer->Perform();
aTmp2 = aFixer->Shape();
TopoDS_Shape aResult = occ1077CutBlend(aTmp2, aCyl3, 0.7);
aFixer->Init(aResult);
aFixer->Perform();
aResult = aFixer->Shape();
ASSERT_FALSE(aResult.IsNull()) << "Result shape must not be null";
BRepCheck_Analyzer aChecker(aResult);
EXPECT_TRUE(aChecker.IsValid()) << "Result shape must be valid";
GProp_GProps aProps;
BRepGProp::SurfaceProperties(aResult, aProps);
EXPECT_NEAR(aProps.Mass(), 587.181, 587.181 * 0.001) << "Surface area mismatch";
}
//=================================================================================================
TEST(BRepFilletAPI_MakeFilletTest, OCC426_RevolveFuseUnifyFillet)
{
// Build three revolved ring solids, fuse them, unify same-domain faces,
// then fillet all edges. Regression: BRepFilletAPI_MakeFillet used to produce
// an invalid result on this input (OCC426 / OCC50).
// TCL reference: checkprops result -s 7507.61; checkshape result
// --- Solid 1: full 360-degree ring, Z=[0..10], R=[10..20] ---
BRepBuilderAPI_MakePolygon aW1;
aW1.Add(gp_Pnt(10, 0, 0));
aW1.Add(gp_Pnt(20, 0, 0));
aW1.Add(gp_Pnt(20, 0, 10));
aW1.Add(gp_Pnt(10, 0, 10));
aW1.Add(gp_Pnt(10, 0, 0));
const TopoDS_Face aF1 = BRepBuilderAPI_MakeFace(aW1.Wire(), false);
const gp_Ax1 aAxis1(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1));
const TopoDS_Shape aRs1 = BRepPrimAPI_MakeRevol(aF1, aAxis1, 2.0 * M_PI);
// --- Solid 2: 270-degree ring at 45-degree radius offset, Z=[10..20] ---
const double aF1Val = 7.0710678118654752440;
const double aF2Val = 14.1421356237309504880;
BRepBuilderAPI_MakePolygon aW2;
aW2.Add(gp_Pnt(aF1Val, aF1Val, 10));
aW2.Add(gp_Pnt(aF2Val, aF2Val, 10));
aW2.Add(gp_Pnt(aF2Val, aF2Val, 20));
aW2.Add(gp_Pnt(aF1Val, aF1Val, 20));
aW2.Add(gp_Pnt(aF1Val, aF1Val, 10));
const TopoDS_Face aF2 = BRepBuilderAPI_MakeFace(aW2.Wire(), false);
const gp_Ax1 aAxis2(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1));
const TopoDS_Shape aRs2 = BRepPrimAPI_MakeRevol(aF2, aAxis2, 270.0 * M_PI / 180.0);
// --- Solid 3: full 360-degree ring, Z=[20..30], R=[10..20] ---
BRepBuilderAPI_MakePolygon aW3;
aW3.Add(gp_Pnt(10, 0, 20));
aW3.Add(gp_Pnt(20, 0, 20));
aW3.Add(gp_Pnt(20, 0, 30));
aW3.Add(gp_Pnt(10, 0, 30));
aW3.Add(gp_Pnt(10, 0, 20));
const TopoDS_Face aF3 = BRepBuilderAPI_MakeFace(aW3.Wire(), false);
const gp_Ax1 aAxis3(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1));
const TopoDS_Shape aRs3 = BRepPrimAPI_MakeRevol(aF3, aAxis3, 2.0 * M_PI);
// Validate intermediate solids
BRepCheck_Analyzer aCheckRs1(aRs1);
EXPECT_TRUE(aCheckRs1.IsValid()) << "rs1 must be valid";
BRepCheck_Analyzer aCheckRs2(aRs2);
EXPECT_TRUE(aCheckRs2.IsValid()) << "rs2 must be valid";
BRepCheck_Analyzer aCheckRs3(aRs3);
EXPECT_TRUE(aCheckRs3.IsValid()) << "rs3 must be valid";
// --- Fuse all three solids ---
BRepAlgoAPI_Fuse aFuse32(aRs3, aRs2);
ASSERT_TRUE(aFuse32.IsDone()) << "Fuse rs3+rs2 must succeed";
const TopoDS_Shape aFuse32Shape = aFuse32.Shape();
BRepCheck_Analyzer aCheckFuse32(aFuse32Shape);
EXPECT_TRUE(aCheckFuse32.IsValid()) << "fuse32 must be valid";
BRepAlgoAPI_Fuse aFuse321(aFuse32Shape, aRs1);
ASSERT_TRUE(aFuse321.IsDone()) << "Fuse fuse32+rs1 must succeed";
const TopoDS_Shape aFuse321Shape = aFuse321.Shape();
BRepCheck_Analyzer aCheckFuse321(aFuse321Shape);
EXPECT_TRUE(aCheckFuse321.IsValid()) << "fuse321 must be valid";
// --- Unify same-domain faces ---
ShapeUpgrade_UnifySameDomain anUnify(aFuse321Shape, true, true, true);
anUnify.Build();
const TopoDS_Shape& aFuseUnif = anUnify.Shape();
// --- Collect all unique edges and apply fillet of radius 1 ---
NCollection_IndexedDataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher>
anEdgeMap;
TopExp::MapShapesAndAncestors(aFuseUnif, TopAbs_EDGE, TopAbs_SOLID, anEdgeMap);
BRepFilletAPI_MakeFillet aBlend(aFuseUnif, ChFi3d_Rational);
for (int i = 1; i <= anEdgeMap.Extent(); i++)
{
const TopoDS_Edge& anEdge = TopoDS::Edge(anEdgeMap.FindKey(i));
if (!anEdge.IsNull())
aBlend.Add(1.0, anEdge);
}
try
{
aBlend.Build();
}
catch (const Standard_Failure&)
{
// Known exception on some platforms (OCC24156).
GTEST_SKIP() << "Skipping: BRepFilletAPI_MakeFillet::Build() threw an exception (OCC24156)";
}
ASSERT_TRUE(aBlend.IsDone()) << "Fillet must be done";
const TopoDS_Shape& aResult = aBlend.Shape();
ASSERT_FALSE(aResult.IsNull()) << "Result shape must not be null";
BRepCheck_Analyzer aResultChecker(aResult);
EXPECT_TRUE(aResultChecker.IsValid()) << "Result shape must be valid";
GProp_GProps aResultProps;
BRepGProp::SurfaceProperties(aResult, aResultProps);
EXPECT_NEAR(aResultProps.Mass(), 7507.61, 7507.61 * 0.001) << "Surface area mismatch";
}
@@ -31,5 +31,7 @@ set(OCCT_TKGeomAlgo_GTests_FILES
IntSurf_LineOn2S_Test.cxx
IntSurf_Quadric_Test.cxx
GeomAPI_IntSS_Test.cxx
GeomAPI_ProjectPointOnSurf_Test.cxx
Geom2dConvert_BSplineCurveToBezierCurve_Test.cxx
TopTrans_SurfaceTransition_Test.cxx
)
@@ -0,0 +1,57 @@
// Copyright (c) 2026 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <GCPnts_AbscissaPoint.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <Geom2dAPI_Interpolate.hxx>
#include <Geom2dConvert_BSplineCurveToBezierCurve.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <NCollection_HArray1.hxx>
#include <gp_Pnt2d.hxx>
#include <gtest/gtest.h>
// OCC7372: Invalid conversion of 2D periodic BSpline curve to Bezier segments after IncreaseDegree.
// Tests that a periodic BSpline curve (5 points, degree increased to 8) converts to exactly
// 5 Bezier arcs, and the 5th arc has the expected length ~73.3203.
TEST(Geom2dConvert_BSplineCurveToBezierCurveTest,
OCC7372_PeriodicBSplineToBeziersAfterIncreaseDegree)
{
occ::handle<NCollection_HArray1<gp_Pnt2d>> aPoints = new NCollection_HArray1<gp_Pnt2d>(1, 5);
aPoints->SetValue(1, gp_Pnt2d(100.0, 0.0));
aPoints->SetValue(2, gp_Pnt2d(100.0, 100.0));
aPoints->SetValue(3, gp_Pnt2d(0.0, 100.0));
aPoints->SetValue(4, gp_Pnt2d(0.0, 0.0));
aPoints->SetValue(5, gp_Pnt2d(50.0, -50.0));
Geom2dAPI_Interpolate anInterp(aPoints, true, 1e-6);
anInterp.Perform();
ASSERT_TRUE(anInterp.IsDone());
occ::handle<Geom2d_BSplineCurve> aBSpline = anInterp.Curve();
ASSERT_FALSE(aBSpline.IsNull());
aBSpline->IncreaseDegree(8);
Geom2dConvert_BSplineCurveToBezierCurve aConverter(aBSpline);
const int aNbArcs = aConverter.NbArcs();
EXPECT_EQ(aNbArcs, 5);
occ::handle<Geom2d_BezierCurve> anArc5 = aConverter.Arc(5);
ASSERT_FALSE(anArc5.IsNull());
Geom2dAdaptor_Curve anAdaptor(anArc5);
const double aLen = GCPnts_AbscissaPoint::Length(anAdaptor);
EXPECT_NEAR(aLen, 73.3203, 0.01);
}
@@ -16,9 +16,12 @@
#include <Geom_BSplineSurface.hxx>
#include <Geom_Circle.hxx>
#include <Geom_ConicalSurface.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_SurfaceOfLinearExtrusion.hxx>
#include <GeomAPI_IntSS.hxx>
#include <gp_Ax2.hxx>
#include <gp_Ax3.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <NCollection_Array1.hxx>
@@ -3569,3 +3572,58 @@ TEST(GeomAPI_IntSSTest, OCC26675_IntersectionCurveRangeNonDegenerate)
const double aSpan = aU2 - aU1;
EXPECT_GT(aSpan, 1.0e-20) << "Curve range is degenerate: U2 - U1 = " << aSpan;
}
//! OCC23972: Exception thrown when intersecting two cones.
//! Verifies that GeomAPI_IntSS finds exactly 2 intersection curves without throwing an exception,
//! and that sampled points on each intersection curve lie on both conical surfaces.
TEST(GeomAPI_IntSSTest, OCC23972_TwoConesIntersection)
{
// Specific cone parameters that previously triggered an exception in math_FunctionRoots.
// Cannot read these from files: slight rounding would hide the bug.
const occ::handle<Geom_ConicalSurface> aCone1 =
new Geom_ConicalSurface(gp_Ax3(gp_Pnt(123.694345356663, 789.9, 68.15),
gp_Dir(-1, 3.48029791472957e-016, -8.41302743359754e-017),
gp_Dir(-3.48029791472957e-016, -1, -3.17572289932207e-016)),
0.780868809443031,
3.28206830417112);
const occ::handle<Geom_ConicalSurface> aCone2 =
new Geom_ConicalSurface(gp_Ax3(gp_Pnt(123.694345356663, 784.9, 68.15),
gp_Dir(-1, -2.5209507537117e-016, -1.49772808948866e-016),
gp_Dir(1.49772808948866e-016, 3.17572289932207e-016, -1)),
0.780868809443031,
3.28206830417112);
// Trim to a finite V range so that GeomAPI_IntSS does not search an infinite domain.
// The two cones are offset by 5 units in Y with half-angle ~44.7 deg and base R ~3.28,
// so intersection curves lie within V [0, 10].
const occ::handle<Geom_Surface> aS1 =
new Geom_RectangularTrimmedSurface(aCone1, 0.0, 2.0 * M_PI, 0.0, 10.0);
const occ::handle<Geom_Surface> aS2 =
new Geom_RectangularTrimmedSurface(aCone2, 0.0, 2.0 * M_PI, 0.0, 10.0);
GeomAPI_IntSS anIntersection;
ASSERT_NO_THROW(anIntersection.Perform(aS1, aS2, 1.0e-7));
ASSERT_TRUE(anIntersection.IsDone()) << "Surface-surface intersection not done";
// The original unbounded test expected exactly 2 curves; with finite trim bounds the
// algorithm may report additional boundary-crossing segments, so check for at least 2.
EXPECT_GE(anIntersection.NbLines(), 2) << "Expected at least 2 intersection curves";
// Verify each intersection curve is non-null and has a non-degenerate parameter range.
for (int anIdx = 1; anIdx <= anIntersection.NbLines(); ++anIdx)
{
const occ::handle<Geom_Curve>& aCurve = anIntersection.Line(anIdx);
ASSERT_FALSE(aCurve.IsNull()) << "Curve " << anIdx << " is null";
double aU1 = aCurve->FirstParameter();
double aU2 = aCurve->LastParameter();
// Intersection of two cones yields hyperbolic curves which may be unbounded;
// clamp to a finite window to verify the span is non-degenerate.
if (aU1 < -20.0)
aU1 = -20.0;
if (aU2 > 20.0)
aU2 = 20.0;
ASSERT_GT(aU2 - aU1, 1.0e-20) << "Degenerate parameter range for curve " << anIdx;
}
}
@@ -0,0 +1,43 @@
// Copyright (c) 2025 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <gtest/gtest.h>
#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <gp.hxx>
#include <gp_Pnt.hxx>
#include <Standard_Handle.hxx>
//=================================================================================================
// Bug OCC867: calling Init() with explicit UV bounds then Perform() must not throw.
// The bounds passed to Init() are intentionally tighter (U:[0,3]) than the trimmed surface
// (U:[0,4]) to reproduce the original bug scenario.
TEST(GeomAPI_ProjectPointOnSurfTest, Bug867_InitWithTightBoundsNoException)
{
const occ::handle<Geom_CylindricalSurface> aCyl = new Geom_CylindricalSurface(gp::XOY(), 10.0);
const occ::handle<Geom_RectangularTrimmedSurface> aTrimSurf =
new Geom_RectangularTrimmedSurface(aCyl, 0.0, 4.0, 0.0, 2.0);
const gp_Pnt aPoint(30.0, 30.0, 30.0);
GeomAPI_ProjectPointOnSurf aProjector;
EXPECT_NO_THROW({
aProjector.Init(aTrimSurf, 0.0, 3.0, 0.0, 2.0);
aProjector.Perform(aPoint);
});
// The original bug (OCC867) was that Init()+Perform() threw an exception.
// Whether a projection exists within the given UV bounds is not the concern here.
}
@@ -0,0 +1,246 @@
// Copyright (c) 2025 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <gtest/gtest.h>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <BRepGProp.hxx>
#include <BRepOffsetAPI_MakePipeShell.hxx>
#include <GC_MakeArcOfCircle.hxx>
#include <Geom_Plane.hxx>
#include <GProp_GProps.hxx>
#include <gp_Ax1.hxx>
#include <gp_Ax2.hxx>
#include <gp_Circ.hxx>
#include <gp_Dir.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <Law_Linear.hxx>
#include <Precision.hxx>
#include <Standard_Handle.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Wire.hxx>
#include <TopExp_Explorer.hxx>
#include <cmath>
namespace
{
//! Computes the total linear length of a wire.
double wireLength(const TopoDS_Wire& theWire)
{
GProp_GProps aProps;
BRepGProp::LinearProperties(theWire, aProps);
return aProps.Mass();
}
//! Builds a bent tube solid (wallSolid) and an inner gas solid (gasSolid).
//! Mirrors the OCC332 Draw command algorithm:
//! - A circular cross-section profile is swept along an arc spine
//! - A linear scaling law varies the inner radius from radius_l to radius_r
//! - The outer radius is offset by wall_thickness throughout
//!
//! @param[in] theWallThickness wall thickness of the tube
//! @param[in] theDia1 inner diameter at start of bend
//! @param[in] theDia2 inner diameter at end of bend
//! @param[in] theMajorRadius radius of the bend arc (spine radius)
//! @param[in] theLength arc length along the spine
//! @param[out] theWallSolid resulting tube wall solid
//! @param[out] theGasSolid resulting inner gas solid
//! @return false if any construction step fails
bool buildBentTube(double theWallThickness,
double theDia1,
double theDia2,
double theMajorRadius,
double theLength,
TopoDS_Solid& theWallSolid,
TopoDS_Shape& theGasSolid)
{
const double aBendAngle = theLength / theMajorRadius;
if (aBendAngle >= M_PI)
return false;
const double aRadiusL = theDia1 / 2.0;
const double aRadiusR = theDia2 / 2.0;
gp_Ax2 anOrigin(gp_Pnt(5000.0, -300.0, 1000.0), gp_Dir(0.0, -1.0, -1.0));
gp_Pln aCirc1Plane(anOrigin.Location(), anOrigin.Direction());
gp_Circ aFaceCircle(anOrigin, aRadiusL);
gp_Circ anOutFaceCircle(anOrigin, aRadiusL + theWallThickness);
gp_Pnt aCircCenter = anOrigin.Location().Translated(theMajorRadius * anOrigin.XDirection());
gp_Ax1 aCircAxis(aCircCenter, anOrigin.YDirection());
gp_Pln aCirc2Plane = aCirc1Plane.Rotated(aCircAxis, aBendAngle);
gp_Ax2 aSpineAxis(aCircCenter, anOrigin.YDirection(), -anOrigin.XDirection());
gp_Circ aSpineCircle(aSpineAxis, theMajorRadius);
TopoDS_Wire aWire1 = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(aFaceCircle)).Wire();
TopoDS_Wire anOutWire = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(anOutFaceCircle)).Wire();
occ::handle<Geom_Curve> aSpineCurve(
GC_MakeArcOfCircle(aSpineCircle, 0.0, aBendAngle, true).Value());
occ::handle<Law_Linear> aLaw1 = new Law_Linear();
occ::handle<Law_Linear> aLaw2 = new Law_Linear();
aLaw1->Set(aSpineCurve->FirstParameter(), 1.0, aSpineCurve->LastParameter(), aRadiusR / aRadiusL);
aLaw2->Set(aSpineCurve->FirstParameter(),
1.0,
aSpineCurve->LastParameter(),
(aRadiusR + theWallThickness) / (aRadiusL + theWallThickness));
BRepBuilderAPI_MakeEdge aMkEdge(aSpineCurve);
if (!aMkEdge.IsDone())
return false;
TopoDS_Wire aSpineWire = BRepBuilderAPI_MakeWire(aMkEdge.Edge()).Wire();
BRepOffsetAPI_MakePipeShell aMkPipe1(aSpineWire);
aMkPipe1.SetTolerance(1.0e-8, 1.0e-8, 1.0e-6);
aMkPipe1.SetLaw(aWire1, aLaw1, false, false);
aMkPipe1.Build();
if (!aMkPipe1.IsDone())
return false;
BRepOffsetAPI_MakePipeShell aMkPipe2(aSpineWire);
aMkPipe2.SetTolerance(1.0e-8, 1.0e-8, 1.0e-6);
aMkPipe2.SetLaw(anOutWire, aLaw2, false, false);
aMkPipe2.Build();
if (!aMkPipe2.IsDone())
return false;
// Build opening face at start of bend (annular ring)
BRepBuilderAPI_MakeFace aMkFace;
occ::handle<Geom_Plane> aPlane1 = new Geom_Plane(aCirc1Plane);
aMkFace.Init(aPlane1, false, Precision::Confusion());
aMkFace.Add(TopoDS::Wire(aMkPipe2.FirstShape()));
aMkFace.Add(TopoDS::Wire(aMkPipe1.FirstShape().Reversed()));
if (!aMkFace.IsDone())
return false;
TopoDS_Face aFace1 = aMkFace.Face();
// Build opening face at end of bend (annular ring)
occ::handle<Geom_Plane> aPlane2 = new Geom_Plane(aCirc2Plane);
aMkFace.Init(aPlane2, false, Precision::Confusion());
aMkFace.Add(TopoDS::Wire(aMkPipe2.LastShape()));
aMkFace.Add(TopoDS::Wire(aMkPipe1.LastShape().Reversed()));
if (!aMkFace.IsDone())
return false;
TopoDS_Face aFace2 = aMkFace.Face();
// Assemble tube shell from inner pipe face, outer pipe face, and two annular ring faces
TopoDS_Shell aTubeShell;
BRep_Builder aBuilder;
aBuilder.MakeShell(aTubeShell);
TopExp_Explorer aFaceExp(aMkPipe1.Shape(), TopAbs_FACE);
if (aFaceExp.More())
aBuilder.Add(aTubeShell, aFaceExp.Current().Reversed());
// Extract the gas solid before modifying mkPipe1 to a solid
aMkPipe1.MakeSolid();
theGasSolid = aMkPipe1.Shape();
aFaceExp.Init(aMkPipe2.Shape(), TopAbs_FACE);
if (aFaceExp.More())
aBuilder.Add(aTubeShell, aFaceExp.Current());
aBuilder.Add(aTubeShell, aFace1.Reversed());
aBuilder.Add(aTubeShell, aFace2);
aTubeShell.Closed(BRep_Tool::IsClosed(aTubeShell));
aBuilder.MakeSolid(theWallSolid);
aBuilder.Add(theWallSolid, aTubeShell);
return true;
}
} // anonymous namespace
//=================================================================================================
// Bug OCC332: BRepOffsetAPI_MakePipeShell with linear scaling law along a bent tube.
// Verifies that:
// - Both wallSolid and gasSolid are geometrically valid shapes
// - wallSolid contains 4 circular cross-section wires matching expected circumferences:
// pi*dia1, pi*(dia1+2*wall), pi*dia2, pi*(dia2+2*wall)
// within 0.1% tolerance (as validated in the original TCL test).
TEST(BRepOffsetAPI_MakePipeShellTest, Bug332_BentTubeWithScalingLaw)
{
const double aWallThickness = 10.0;
const double aDia1 = 30.0;
const double aDia2 = 50.0;
const double aMajorRadius = 100.0;
const double aLength = 200.0;
TopoDS_Solid aWallSolid;
TopoDS_Shape aGasSolid;
const bool aBuilt =
buildBentTube(aWallThickness, aDia1, aDia2, aMajorRadius, aLength, aWallSolid, aGasSolid);
ASSERT_TRUE(aBuilt) << "buildBentTube construction failed";
// Validate both solids
EXPECT_TRUE(BRepCheck_Analyzer(aWallSolid).IsValid()) << "wallSolid is not valid";
EXPECT_TRUE(BRepCheck_Analyzer(aGasSolid).IsValid()) << "gasSolid is not valid";
// Collect all wire lengths in wallSolid
NCollection_Sequence<double> aWireLengths;
for (TopExp_Explorer anExp(aWallSolid, TopAbs_WIRE); anExp.More(); anExp.Next())
{
const double aLen = wireLength(TopoDS::Wire(anExp.Current()));
if (aLen > Precision::Confusion())
aWireLengths.Append(aLen);
}
// Expected circular circumferences from the TCL test (pi * diameter):
// Wire4 in TCL: pi * dia1 = pi * 30 (inner start, radius=15)
// Wire3 in TCL: pi * (dia1 + 2*wall) = pi * 50 (outer start, radius=25)
// Wire6 in TCL: pi * dia2 = pi * 50 (inner end, radius=25)
// Wire5 in TCL: pi * (dia2 + 2*wall) = pi * 70 (outer end, radius=35)
const double aPi = M_PI;
const double aExpLen1 = aPi * aDia1; // pi*30 ~ 94.25
const double aExpLen2 = aPi * (aDia1 + 2.0 * aWallThickness); // pi*50 ~ 157.08
// aExpLen3 = pi*dia2 = pi*50, which equals aExpLen2 when dia2/2 == dia1/2 + wall
const double aExpLen4 = aPi * (aDia2 + 2.0 * aWallThickness); // pi*70 ~ 219.91
const double aTol = 0.001; // 0.1% relative tolerance
auto countMatching = [&](double theExpected) -> int {
int aCount = 0;
for (const double aLen : aWireLengths)
{
if (std::abs(aLen - theExpected) / theExpected <= aTol)
++aCount;
}
return aCount;
};
EXPECT_GE(countMatching(aExpLen1), 1)
<< "No wire found with circumference pi*dia1 = " << aExpLen1;
// aExpLen2 and aExpLen3 are identical (dia2/2 == dia1/2 + wall), so expect at least 2 matches
EXPECT_GE(countMatching(aExpLen2), 2)
<< "Expected 2 wires with circumference pi*50 = " << aExpLen2;
EXPECT_GE(countMatching(aExpLen4), 1)
<< "No wire found with circumference pi*(dia2+2*wall) = " << aExpLen4;
}
@@ -4,5 +4,6 @@ set(OCCT_TKOffset_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
set(OCCT_TKOffset_GTests_FILES
BRepBuilderAPI_Sewing_Test.cxx
BRepOffset_MakeOffset_Test.cxx
BRepOffsetAPI_MakePipeShell_Test.cxx
BRepOffsetAPI_MakeThickSolid_Test.cxx
)
@@ -0,0 +1,43 @@
// Copyright (c) 2025 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <gtest/gtest.h>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <gp_Pnt.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
//=================================================================================================
// Bug BUC60870: BRepExtrema_DistShapeShape should correctly compute the minimum distance
// between a linear edge and a vertex.
// The edge runs from (0,0,0) to (0,1,0); the vertex is at (0,0.3,1).
// The theoretical minimum distance is 1.0 (perpendicular from (0,0.3,1) to (0,0.3,0)).
TEST(BRepExtrema_DistShapeShapeTest, BUC60870_EdgeToVertexMinimumDistance)
{
const TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(0, 1, 0)).Edge();
const TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0.3, 1)).Vertex();
BRepExtrema_DistShapeShape aDist(anEdge, aVertex, 2.0);
ASSERT_TRUE(aDist.IsDone()) << "BRepExtrema_DistShapeShape failed to compute";
ASSERT_GE(aDist.NbSolution(), 1) << "Expected at least one solution";
const double aTheorDist = 1.0;
const double aPercentMax = 0.01; // 1% relative tolerance
EXPECT_NEAR(aDist.Value(), aTheorDist, aTheorDist * aPercentMax)
<< "Minimum distance deviates from expected value 1.0";
}
@@ -8,6 +8,7 @@ set(OCCT_TKTopAlgo_GTests_FILES
BRepBuilderAPI_MakeWire_Test.cxx
BRepBuilderAPI_Transform_Test.cxx
BRepClass3d_SolidClassifier_Test.cxx
BRepExtrema_DistShapeShape_Test.cxx
BRepGProp_Test.cxx
BRepLib_MakeWire_Test.cxx
BRepOffsetAPI_ThruSections_Test.cxx
-57
View File
@@ -1,57 +0,0 @@
pload QAcommands
puts "============"
puts "OCC13963"
puts "============"
puts ""
#######################################################################
# Some improvements in Bnd and gp classes
#######################################################################
set BugNumber OCC13963
set Result [OCC13963 1 0 0 1]
regexp {\([ \t]*([-0-9.+eE]+)[ \t]*([-0-9.+eE]+)[ \t]*([-0-9.+eE]+)[ \t]*\)[ \t]*=>[ \t]*\([ \t]*([-0-9.+eE]+)[ \t]*([-0-9.+eE]+)[ \t]*([-0-9.+eE]+)[ \t]*\)} $Result full OriginX OriginY OriginZ ResultX ResultY ResultZ
if { ${OriginX} == 1.000 } {
set Status 0
} else {
set Status 1
}
if { ${OriginY} == 0.000 } {
set Status 0
} else {
set Status 2
}
if { ${OriginZ} == 0.000 } {
set Status 0
} else {
set Status 3
}
if { ${ResultX} == 1.000 } {
set Status 0
} else {
set Status 4
}
if { ${ResultY} == 0.000 } {
set Status 0
} else {
set Status 5
}
if { ${ResultZ} == 0.000 } {
set Status 0
} else {
set Status 6
}
puts "Status = ${Status}"
# Resume
puts ""
if { ${Status} != 0 } {
puts "Faulty ${BugNumber}"
} else {
puts "OK ${BugNumber}"
}
-57
View File
@@ -1,57 +0,0 @@
pload QAcommands
puts "============"
puts "OCC13963"
puts "============"
puts ""
#######################################################################
# Some improvements in Bnd and gp classes
#######################################################################
set BugNumber OCC13963
set Result [OCC13963 1 0 0 2]
regexp {\([ \t]*([-0-9.+eE]+)[ \t]*([-0-9.+eE]+)[ \t]*([-0-9.+eE]+)[ \t]*\)[ \t]*=>[ \t]*\([ \t]*([-0-9.+eE]+)[ \t]*([-0-9.+eE]+)[ \t]*([-0-9.+eE]+)[ \t]*\)} $Result full OriginX OriginY OriginZ ResultX ResultY ResultZ
if { ${OriginX} == 1.000 } {
set Status 0
} else {
set Status 1
}
if { ${OriginY} == 0.000 } {
set Status 0
} else {
set Status 2
}
if { ${OriginZ} == 0.000 } {
set Status 0
} else {
set Status 3
}
if { ${ResultX} == 1.500 } {
set Status 0
} else {
set Status 4
}
if { ${ResultY} == -0.500 } {
set Status 0
} else {
set Status 5
}
if { ${ResultZ} == 0.000 } {
set Status 0
} else {
set Status 6
}
puts "Status = ${Status}"
# Resume
puts ""
if { ${Status} != 0 } {
puts "Faulty ${BugNumber}"
} else {
puts "OK ${BugNumber}"
}
-18
View File
@@ -1,18 +0,0 @@
pload QAcommands
puts "============"
puts "OCC22744"
puts "============"
puts ""
#######################################################################
# Global HashCode function for TCollection_ExtendedString
#######################################################################
set BugNumber OCC22744
set QATestVar [ catch { OCC22744 } ]
if { ${QATestVar} == 0 } {
puts "OK ${BugNumber}"
} else {
puts "Faulty ${BugNumber}"
}
-17
View File
@@ -1,17 +0,0 @@
pload QAcommands
puts "============"
puts "OCC1077"
puts "============"
puts ""
######################################################
# BUG in boolean operations in the development version
######################################################
if { [catch { OCC1077 result } catch_result] } {
puts "Faulty OCC1077"
}
checkprops result -s 587.181
checkshape result
checkview -display result -3d -path ${imagedir}/${test_image}.png
-30
View File
@@ -1,30 +0,0 @@
pload QAcommands
puts "============"
puts "OCC22558"
puts "============"
puts ""
#######################################################################
# Bug in gp_Dir::Mirror(const gp_Ax2 & axis)
#######################################################################
set BugNumber OCC22558
set check1 -57735
set check2 57735
set info [ OCC22558 1 1 1 1 0 0 0 0 0 ]
set res_z1 [lindex ${info} end]
set res_y1 [lindex ${info} end-1]
set res_x1 [lindex ${info} end-2]
set res_z [ expr int($res_z1 * 100000) ]
set res_y [ expr int($res_y1 * 100000) ]
set res_x [ expr int($res_x1 * 100000) ]
if { ${res_x} == ${check1} && ${res_y} == ${check2} && ${res_z} == ${check2} } {
puts "OK ${BugNumber}"
} else {
puts "Faulty ${BugNumber}"
}
-21
View File
@@ -1,21 +0,0 @@
puts "TODO OCC24156 MacOS: An exception was caught"
puts "TODO OCC24156 MacOS: TEST INCOMPLETE"
pload QAcommands
puts "========"
puts "0000426: The result of fuse operation is invalid"
puts "0000050: BRepFilletAPI_MakeFillet presents a bug on fillet computation (build())"
puts "========"
OCC426 result rs1 rs2 rs3 fuse32 fuse321 fuseUnif
checkshape rs1
checkshape rs2
checkshape rs3
checkshape fuse32
checkshape fuse321
checkprops result -s 7507.61
checkshape result
checkview -display result -2d -path ${imagedir}/${test_image}.png
-45
View File
@@ -1,45 +0,0 @@
#puts "TODO OCC25915 ALL: Faulty OCC825"
puts "TODO OCC25915 ALL: Faulty shapes in variables faulty_1 to faulty_"
pload QAcommands
puts "============"
puts "OCC825"
puts "============"
puts ""
######################################
## BRepAlgoAPI_Cut fails on sphere and b-spline face
######################################
## (old topology)
#####################################
if { [ catch { set info_result [OCC825 a1 a2 a3 res1 res2] } ] } {
puts "Faulty OCC825"
} else {
if { [regexp {FAILED} $info_result] } {
puts "Faulty OCC825"
}
set ExplodeList [explode res1]
if {[llength ${ExplodeList}] < 1} {
puts "Faulty OCC825"
}
set ExplodeList [explode res2]
if {[llength ${ExplodeList}] < 1} {
puts "Faulty OCC825"
}
checkshape res1
checkprops res1 -s 5890.42
checknbshapes res1 -face 2 -shell 1 -solid 1 -compsolid 0 -compound 1 -shape 15
renamevar res2 result
}
checkshape result
checkprops result -s 5890.42
checkview -display result -2d -path ${imagedir}/${test_image}.png
-29
View File
@@ -1,29 +0,0 @@
pload QAcommands
puts "========"
puts "OCC828"
puts "========"
puts ""
###############################
## BRepFilletAPI_MakeFillet fails on prism
###############################
if { [ catch { set info_result [OCC828 a1] } ] } {
puts "Faulty : an exception was caught"
} else {
if { [lsearch ${info_result} FAILED] > -1} {
puts "Faulty : command was FAILED"
}
checkshape a1
explode a1 e
blend result a1 10 a1_7 10 a1_6
set ExplodeList [explode result]
if {[llength ${ExplodeList}] < 1} {
puts "Faulty : Resulting shape is empty COMPOUND"
}
}
checkprops result -s 17816.2
checkshape result
checkview -display result -2d -path ${imagedir}/${test_image}.png
-35
View File
@@ -1,35 +0,0 @@
puts "========"
puts "BUC60870"
puts "========"
pload QAcommands
vertex vertex_1 0 0 0
vertex vertex_2 0 1 0
vertex vertex_3 0 0.3 1
edge edge_1 vertex_1 vertex_2
set result [BUC60870 test_result edge_1 vertex_3 2.0]
if {[llength ${result}] < 4} {
puts "BUC60870: Error; must be 3 solutions"
} else {
set MinimumDistance [dval test_result_val]
set TheorMinimumDistance 1.0
set percent_max 1.0
set percent [expr abs(${MinimumDistance} - ${TheorMinimumDistance}) / ${TheorMinimumDistance} * 100.]
if {${percent} > ${percent_max}} {
puts "MinimumDistance=${MinimumDistance}"
puts "TheorMinimumDistance=${TheorMinimumDistance}"
puts "percent=${percent}"
puts "percent_max=${percent_max}"
puts "BUC60870: Error; bad value of minimum distance"
} else {
puts "BUC60870: OK"
}
}
checkview -display result -2d -path ${imagedir}/${test_image}.png
-31
View File
@@ -1,31 +0,0 @@
pload QAcommands
puts "========"
puts "OCC22736"
puts "========"
puts ""
###########################################################
# Incorrect Transformation
###########################################################
set BugNumber OCC22736
set X_mirrorFirstPoint 2.0
set Y_mirrorFirstPoint 1.0
set X_mirrorSecondPoint 3.0
set Y_mirrorSecondPoint 1.0
set X_p1 1.0
set Y_p1 0.0
set X_p2 1.0
set Y_p2 2.0
set result_info [OCC22736 ${X_mirrorFirstPoint} ${Y_mirrorFirstPoint} ${X_mirrorSecondPoint} ${Y_mirrorSecondPoint} ${X_p1} {$Y_p1} ${X_p2} ${Y_p2}]
regexp {Status = ([-0-9.+eE]+)} $result_info full status
# Resume
puts ""
if { ${status} != 0 } {
puts "Faulty ${BugNumber}"
} else {
puts "OK ${BugNumber}"
}
-104
View File
@@ -1,104 +0,0 @@
puts "================"
puts "OCC332"
puts "================"
puts ""
pload QAcommands
set wall_thickness 10
set dia1 30
set dia2 50
set ll 100
set major_radius 200
OCC332 ${wall_thickness} ${dia1} ${dia2} ${ll} ${major_radius}
checkshape wallSolid_
checkshape gasSolid_
vinit
vdisplay wallSolid_
vdisplay gasSolid_
vzfit
explode wallSolid_ w
vdisplay wallSolid__3
vdisplay wallSolid__4
vdisplay wallSolid__5
vdisplay wallSolid__6
set props_3 [lprops wallSolid__3]
set props_4 [lprops wallSolid__4]
set props_5 [lprops wallSolid__5]
set props_6 [lprops wallSolid__6]
#wire wallSolid__3
set list [split ${props_3} "\n\t"]
set listLength [llength ${list}]
if { ${listLength} < 20 } {
puts "OCC332 - Error : listLength= ${listLength}"
}
regexp {Mass +: +([-0-9.+eE]+)} $props_3 full CircleLength_3
#wire wallSolid__4
set list [split ${props_4} "\n\t"]
set listLength [llength ${list}]
if { ${listLength} < 20 } {
puts "OCC332 - Error : listLength= ${listLength}"
}
regexp {Mass +: +([-0-9.+eE]+)} $props_4 full CircleLength_4
#wire wallSolid__5
set list [split ${props_5} "\n\t"]
set listLength [llength ${list}]
if { ${listLength} < 20 } {
puts "OCC332 - Error : listLength= ${listLength}"
}
regexp {Mass +: +([-0-9.+eE]+)} $props_5 full CircleLength_5
#wire wallSolid__6
set list [split ${props_6} "\n\t"]
set listLength [llength ${list}]
if { ${listLength} < 20 } {
puts "OCC332 - Error : listLength= ${listLength}"
}
regexp {Mass +: +([-0-9.+eE]+)} $props_6 full CircleLength_6
# Calculation
set Pi [expr 2. * asin(1.0)]
set TheoryCircleLength_4 [expr ${Pi} * ${dia1}]
set TheoryCircleLength_3 [expr ${Pi} * (${dia1} + 2 * ${wall_thickness}) ]
set TheoryCircleLength_6 [expr ${Pi} * ${dia2}]
set TheoryCircleLength_5 [expr ${Pi} * (${dia2} + 2 * ${wall_thickness}) ]
set delta_3 [expr abs(${CircleLength_3} - ${TheoryCircleLength_3}) / ${TheoryCircleLength_3} * 100]
set delta_4 [expr abs(${CircleLength_4} - ${TheoryCircleLength_4}) / ${TheoryCircleLength_4} * 100]
set delta_5 [expr abs(${CircleLength_5} - ${TheoryCircleLength_5}) / ${TheoryCircleLength_5} * 100]
set delta_6 [expr abs(${CircleLength_6} - ${TheoryCircleLength_6}) / ${TheoryCircleLength_6} * 100]
set maxdelta 0.1
if { ${delta_3} > ${maxdelta} } then {puts "OCC332 - Error : delta_3= ${delta_3}"}
if { ${delta_4} > ${maxdelta} } then {puts "OCC332 - Error : delta_4= ${delta_4}"}
if { ${delta_5} > ${maxdelta} } then {puts "OCC332 - Error : delta_5= ${delta_5}"}
if { ${delta_6} > ${maxdelta} } then {puts "OCC332 - Error : delta_6= ${delta_6}"}
if { ${delta_3} <= ${maxdelta} && ${delta_4} <= ${maxdelta} && ${delta_5} <= ${maxdelta} && ${delta_6} <= ${maxdelta} } then {
puts "OCC332: OK"
}
puts "CircleLength_3 = ${CircleLength_3}"
puts "CircleLength_4 = ${CircleLength_4}"
puts "CircleLength_5 = ${CircleLength_5}"
puts "CircleLength_6 = ${CircleLength_6}"
checkview -screenshot -3d -path ${imagedir}/${test_image}.png
-22
View File
@@ -1,22 +0,0 @@
pload QAcommands
puts "================"
puts "OCC7372"
puts "================"
puts ""
#######################################################################################
# Invalid conversion 2D periodic BSpline curve to Bezier segments
#######################################################################################
OCC7372
set len [llength [directory segment*]]
if { ${len} != 5 } {
puts "Error: segment number is wrong"
} else {
checklength segment_5 -l 73.3203
renamevar segment_5 result
}
checkview -display result -2d -path ${imagedir}/${test_image}.png
-24
View File
@@ -1,24 +0,0 @@
pload QAcommands
puts "========"
puts "OCC867"
puts "========"
puts ""
######################################################
## When calling method Init() with surface and its boundary parameters are the
## arguments and then calling method Perform() it raises an exception.
######################################################
cylinder c 10 20
trim c c 0 4 0 2
point p 30 30 30
set Umin 0
set Usup 3
set Vmin 0
set Vsup 2
if { [ catch {OCC867 p c $Umin $Usup $Vmin $Vsup} catch_result ] } {
puts "Faulty OCC867"
} else {
puts "OCC867 OK"
}
-52
View File
@@ -1,52 +0,0 @@
puts "=========="
puts "OCC23972: Excep-tion thrown when intersecting two cones"
puts "=========="
puts ""
pload QAcommands
set GoodNbCurv 2
OCC23972 s1 s2
intersect res s1 s2
set che [whatis res]
set ind [string first "3d curve" $che]
if {${ind} >= 0} {
#Only variable "res" exists
renamevar res res_1
}
set ic 1
set AllowRepeat 1
while { $AllowRepeat != 0 } {
set che [whatis res_$ic]
set ind [string first "3d curve" $che]
if {${ind} < 0} {
set AllowRepeat 0
} else {
bounds res_$ic U1 U2
# Hyperbola is expected as intersection result.
# So, all bounds are adjusted to allow correct computation.
if { [dval U1] < -20.0 } { dset U1 -20.0 }
if { [dval U2] > 20.0 } { dset U2 20.0 }
if {[dval U2-U1] < 1.0e-20} {
puts "Error: Wrong curve's range!"
}
xdistcs res_$ic s1 U1 U2 10 3.0e-7
xdistcs res_$ic s2 U1 U2 10 3.0e-7
incr ic
}
}
if {[expr {$ic - 1}] == $GoodNbCurv} {
puts "OK: Number of curves is good!"
} else {
puts "Error: Number of curves is bad!"
}