Opencascade read step file surface information

Background

I am using Opencascade to read the curve and surface geometric information in the step file, such as the following code:

bool HighOrder::FileIO_3D::read_step(std::string & stepFile)
{
    STEPControl_Controller::Init();
    STEPControl_Reader reader;

    Standard_Integer status = reader.ReadFile(stepFile.c_str());

    if (status != IFSelect_RetDone) {
        return false;
    }

    reader.TransferRoots();
    //int n = reader.NbShapes();
    //cout << n << endl;
    int idx = 0;

    //TopoDS_Shape shapes = reader.OneShape();
    TopoDS_Shape shapes = reader.Shape(1);
    TopExp_Explorer explorer/*(shapes, TopAbs_FACE)*/;

    // read surfaces
    for (explorer.Init(shapes, TopAbs_FACE); explorer.More(); explorer.Next()) {
        TopoDS_Shape shape = explorer.Current();
        TopoDS_Face face = TopoDS::Face(shape); 
        TopLoc_Location location;
        Handle_Geom_Surface surface = BRep_Tool::Surface(face, location);
        GeomAdaptor_Surface adapter(surface);
    }

    // read curves
    for (explorer.Init(shapes, TopAbs_EDGE); explorer.More(); explorer.Next()) {
        TopoDS_Shape shape = explorer.Current();
        TopoDS_Edge edge = TopoDS::Edge(shape);
        TopLoc_Location location;
        double para1, para2;
        Handle_Geom_Curve curve = BRep_Tool::Curve(edge, para1, para2);
        if (curve.IsNull()) continue;
        GeomAdaptor_Curve adapter0(curve, para1, para2);

        bool flag = true;
        gp_Pnt node0, node1;
        for (int i = 0; i < curves.size(); ++i) {
            GeomAdaptor_Curve adapter1(curves[i]->h());
            double para1_ = curves[i]->para().first, para2_ = curves[i]->para().second;
            int intervals_num = 10;
            double step0 = (para2 - para1) / intervals_num;
            double step1 = (para2_ - para1_) / intervals_num;

            bool isEqual = true;
            for (int i = 0; i <= intervals_num; ++i) {
                adapter0.D0(para1 + i * step0, node0);
                adapter1.D0(para1_ + i * step1, node1);

                if (!node0.IsEqual(node1, 1e-10)) {
                    isEqual = false; break;
                }
            }
            if (isEqual) {
                flag = false; break;
            }
        }

        if (flag) {
            //Curve *c = new Curve(curve, std::make_pair(para1, para2));
            curves.push_back(new Curve(curve, { para1, para2 }));
        }
    }

    cout << "Curves' num: " << curves.size() << endl;

    return true;
}

Regardless of the curve information, I now want to get the three-dimensional physical coordinates xyz on the corresponding surface through a two-dimensional parameter coordinate uv.

but I found that the two-dimensional parameter domain of some surfaces is not the same as the shape of the surface

For example, for a strip-shaped surface, its parameter domain range is a square. Here are some examples (I projected the grid points to the corresponding parameter coordinates).

Green represents parameter coordinates, red represents physical coordinates

have the same shape

ppxuHtP.png

ppxubff.png

ppxu7kt.png

ppxuLp8.png

have the different shape

ppxu5md.png

ppxuoTI.png

ppxuI0A.png

ppxuO1S.png

Question

How can I control the range of the parameter domain to be consistent with the three-dimensional shape, or how to change the range of the parameter domain to be consistent with the three-dimensional shape?

Thanks in advance for any help or suggestions!