BRep_Tool::CurveOnSurface for Bspline Surface issue

I want to implement a surface expand function and have some trouble

I attempted to use the function BRep_Tool::CurveOnSurface to acquire the Geom2d_Curve from a TopoDS_Edge and it's corresponding Geom_Surface; indeed, I successfully get the desired outcome in general cases, they work well with plane, cylindrical surface, spherical surface...etc. However, this fails for a specific TopoDS_Edge which is located on the BSpline Surfce, one kind in Geom_Surfce.

The following is my code and figure:

void AIS_Face::Expand()
{
//return;

Handle(AIS_InteractiveContext) pAISContext = GetContext();
pAISContext->Remove(this, Standard_False);

Standard_Boolean bAll = Standard_True;
int iIndex = 1;
Standard_Real rDist = 3.;

TopoDS_Face faceCur = TopoDS::Face(Shape());
Handle(Geom_Surface) pSurface = BRep_Tool::Surface(faceCur);

Standard_Integer iCount = 1;
BRepBuilderAPI_MakeFace mkFace;
TopTools_ListOfShape listWireAdd;
TopoDS_Wire wireOuter = BRepTools::OuterWire(faceCur);
for (TopExp_Explorer expWire(faceCur, TopAbs_WIRE); expWire.More(); expWire.Next())
{
TopoDS_Wire wireCur = TopoDS::Wire(expWire.Value());

BRepBuilderAPI_MakeWire mkWire;
for (TopExp_Explorer expEdge(wireCur, TopAbs_EDGE); expEdge.More(); expEdge.Next())
{
TopoDS_Edge edgeCur = TopoDS::Edge(expEdge.Value());
TopLoc_Location locEdge = edgeCur.Location();
Standard_Real rFirst, rLast;
Handle(Geom_Curve) pCurve = BRep_Tool::Curve(edgeCur, rFirst, rLast);
Handle(Geom2d_Curve) pPCurve = BRep_Tool::CurveOnSurface(edgeCur, pSurface, locEdge, rFirst, rLast);

if ((bAll || iCount++ == iIndex) && !pPCurve.IsNull())
{
Standard_Real rStart = rFirst + (rLast - rFirst) / 3.;
Standard_Real rEnd = rFirst + 2 * (rLast - rFirst) / 3.;
Standard_Real rMid = (rStart + rEnd) / 2.;

gp_Pnt2d pnt2dFirst;
pPCurve->D0(rFirst, pnt2dFirst);
gp_Pnt2d pnt2dLast;
pPCurve->D0(rLast, pnt2dLast);
gp_Pnt2d pnt2dMid;
gp_Vec2d vec2dMid;
pPCurve->D1(rMid, pnt2dMid, vec2dMid);
gp_Dir2d dir2dNorm(vec2dMid.Y(), -vec2dMid.X());
if ((faceCur.Orientation() == TopAbs_REVERSED) != (edgeCur.Orientation() == TopAbs_REVERSED))
dir2dNorm.Reverse();

Standard_Real rUVDist = ComputeUVDist(pSurface, pnt2dMid, dir2dNorm, rDist);

TopoDS_Edge edge1 = BRepBuilderAPI_MakeEdge(pPCurve, pSurface, rFirst, rStart).Edge();
BRepLib::BuildCurve3d(edge1);

gp_Pnt2d pnt2dStart;
pPCurve->D0(rStart, pnt2dStart);
BRepBuilderAPI_MakeVertex mkVertexStart1(gp_Pnt(pnt2dStart.X(), pnt2dStart.Y(), 0.));
BRepBuilderAPI_MakeVertex mkVertexStart2(gp_Pnt(pnt2dStart.X() + rUVDist * dir2dNorm.X(), pnt2dStart.Y() + rUVDist * dir2dNorm.Y(), 0.));
TopoDS_Edge edge2 = Edge2DTo3D(BRepBuilderAPI_MakeEdge(mkVertexStart1.Vertex(), mkVertexStart2.Vertex()).Edge(), pSurface);
BRepLib::BuildCurve3d(edge2);

gp_Trsf2d trsf2dTran;
trsf2dTran.SetTranslation(gp_Vec2d(rUVDist * dir2dNorm.X(), rUVDist * dir2dNorm.Y()));
Handle(Geom2d_Curve) pPCurveTrsf = Handle(Geom2d_Curve)::DownCast(pPCurve->Transformed(trsf2dTran));
TopoDS_Edge edge3 = BRepBuilderAPI_MakeEdge(pPCurveTrsf, pSurface, rStart, rEnd).Edge();
BRepLib::BuildCurve3d(edge3);

gp_Pnt2d pnt2dEnd;
pPCurve->D0(rEnd, pnt2dEnd);
BRepBuilderAPI_MakeVertex mkVertexEnd1(gp_Pnt(pnt2dEnd.X() + rUVDist * dir2dNorm.X(), pnt2dEnd.Y() + rUVDist * dir2dNorm.Y(), 0.));
BRepBuilderAPI_MakeVertex mkVertexEnd2(gp_Pnt(pnt2dEnd.X(), pnt2dEnd.Y(), 0.));
TopoDS_Edge edge4 = Edge2DTo3D(BRepBuilderAPI_MakeEdge(mkVertexEnd1.Vertex(), mkVertexEnd2.Vertex()).Edge(), pSurface);
BRepLib::BuildCurve3d(edge4);

TopoDS_Edge edge5 = BRepBuilderAPI_MakeEdge(pPCurve, pSurface, rEnd, rLast).Edge();
BRepLib::BuildCurve3d(edge5);

if ((wireCur.Orientation() == TopAbs_REVERSED) != (edgeCur.Orientation() == TopAbs_REVERSED))
{
edge1.Reverse();
edge2.Reverse();
edge3.Reverse();
edge4.Reverse();
edge5.Reverse();

mkWire.Add(edge5);
mkWire.Add(edge4);
mkWire.Add(edge3);
mkWire.Add(edge2);
mkWire.Add(edge1);

pAISContext->Display(new AIS_Shape(edge5), Standard_True);
pAISContext->Display(new AIS_Shape(edge4), Standard_True);
pAISContext->Display(new AIS_Shape(edge3), Standard_True);
pAISContext->Display(new AIS_Shape(edge2), Standard_True);
pAISContext->Display(new AIS_Shape(edge1), Standard_True);
}
else
{
mkWire.Add(edge1);
mkWire.Add(edge2);
mkWire.Add(edge3);
mkWire.Add(edge4);
mkWire.Add(edge5);

pAISContext->Display(new AIS_Shape(edge1), Standard_True);
pAISContext->Display(new AIS_Shape(edge2), Standard_True);
pAISContext->Display(new AIS_Shape(edge3), Standard_True);
pAISContext->Display(new AIS_Shape(edge4), Standard_True);
pAISContext->Display(new AIS_Shape(edge5), Standard_True);
}
}
else
{
mkWire.Add(edgeCur);

pAISContext->Display(new AIS_Shape(edgeCur), Standard_True);
}
}

if (mkWire.IsDone())
{
TopoDS_Wire wireAdd = mkWire.Wire();
if ((faceCur.Orientation() == TopAbs_REVERSED) != (wireCur.Orientation() == TopAbs_REVERSED))
wireAdd.Reverse();

if (wireCur == wireOuter)
mkFace = BRepBuilderAPI_MakeFace(pSurface, wireAdd);
else
listWireAdd.Append(wireAdd);
}
else
ASSERT(0);
}
for (TopTools_ListIteratorOfListOfShape iter(listWireAdd); iter.More(); iter.Next())
mkFace.Add(TopoDS::Wire(iter.Value()));
listWireAdd.Clear();

if (mkFace.IsDone())
{
TopoDS_Face faceRes = mkFace.Face();
if (faceCur.Orientation() == TopAbs_REVERSED)
faceRes.Reverse();

SetShape(faceRes);
IncrementalMesh(0.1);
}
else
ASSERT(0);
}

Attachments: