Function ReadFile() been virtual - ing, I'm puzzled

Hi there, every one, it's me again! I am reading some source code about read\load\transfer the STEP file, and I found a puzzling truth.

Typical Process of Reading a STEP file

initiate the STEPControl_Reader, then call the ReadFile() func which STEPControl_Reader public inherited from its supertype XSControl_Reader.

STEPControl_Reader reader;
IFSelect_ReturnStatus stat = reader.ReadFile(filename);

This seems easy. So look inside the inner func.

Inner View of XSControl_Reader ReadFile()

The ReadFile() func of the XSControl_Reader calls another ReadFile() which belongs to XSControl_Reader's data member Handle(XSControl_WorkSession) thesession.

IFSelect_ReturnStatus  XSControl_Reader::ReadFile (const Standard_CString filename)
{
  IFSelect_ReturnStatus stat = thesession->ReadFile(filename);//calls another ReadFile()
  thesession->InitTransferReader(4);
  return stat;
}

So, jump to the XSControl_WorkSession

Inner View of XSControl_WorkSession\IFSelect_WorkSession ReadFile()

The same situation as above, the XSControl_WorkSession public inherited the func ReadFile() from its supertype IFSelect_WorkSession.

So, jump to the cxx file: IFSelect_WorkSession.cxx Find the func ReadFile(), there is only one.

IFSelect_ReturnStatus  IFSelect_WorkSession::ReadFile(const Standard_CString filename)
{
  if (thelibrary.IsNull()) return IFSelect_RetVoid;
  if (theprotocol.IsNull()) return IFSelect_RetVoid;
  Handle(Interface_InterfaceModel) model;
  IFSelect_ReturnStatus status = IFSelect_RetVoid;
  try {
    OCC_CATCH_SIGNALS
//*********************************************************************************2 highlight this line
    Standard_Integer stat = thelibrary->ReadFile(filename, model, theprotocol);//calls another ReadFile()
//*********************************************************************************2 highlight this line

    if (stat == 0) status = IFSelect_RetDone;
    else if (stat < 0) status = IFSelect_RetError;
    else status = IFSelect_RetFail;
  }
  catch(Standard_Failure const& anException) {
    Message_Messenger::StreamBuffer sout = Message::SendInfo();
    sout<<"    ****    Interruption ReadFile par Exception :   ****\n";
    sout << anException.GetMessageString();
    sout<<"\n    Abandon"<<std::endl;
    status = IFSelect_RetFail;
  }
  if (status != IFSelect_RetDone) return status;
  if (model.IsNull()) return IFSelect_RetVoid;
  SetModel (model);
  SetLoadedFile (filename);
  return status;
}

We'll see this func calls another ReadFile() which belongs to IFSelect_WorkSession's data member Handle(IFSelect_WorkLibrary) thelibrary.

Finally, we make it to the end, like the edge of the flat earth (doge just kidding.

Jump to the hxx file : IFSelect_WorkLibrary.hxx Look for the func ReadFile(), it's a virtual func.

  Standard_EXPORT virtual Standard_Integer ReadFile (const Standard_CString name, Handle(Interface_InterfaceModel)& model, const Handle(Interface_Protocol)& protocol) const = 0;

To this, I am really confused and puzzled.

Could some one tell me, where the actual codes are? in the codes the OCC opens the step file like using fopen, and do some pre-work for the load and transfer.

Nathaniel Essenberg's picture

The IFSelect_WorkLibrary class has subclasses StepSelect_WorkLibrary and IGESSelect_WorkLibrary. So even though the *pointer* might be of the base type, the actual *object* is probably a StepSelect_WorkLibrary, which does have an implementation for the function ReadFile().
The code would not compile if a function was missing ;)

Lewis Alexander's picture

So this is the way how it works? I see...

I checked it again. What u said is true.

The func ReadFile() is completed inside the class StepSelect_WorkLibrary , and the core func is the StepFile_Read() as an external function called by the StepSelect_WorkLibrary's function member ReadFile(). So technically, some one can read the STEP file with this external function and some other necessary objects, only if the guy is able to comprehend and use this func and directly related class.

And I try to track that what happened when I define a STEPControl_Reader, to figure out how the StepSelect_WorkLibrary is initialized during the process. However it's so complex and so many jump-to-operation and handle-initialization (I use the VS2019 to track the process), which exhaust all my patience.

So I already could read STEP files with the help of OCC and STEPControl_Reader, I've done the code several days ago and it works well, but I don't know exactly how the process process the data.LOL

Anyway, Muchas gracias! Best regards!

Nathaniel Essenberg's picture

Well, it is not so strange when using inheritance in C++ to use a pointer to a base type. It's actually very convenient in cases like this.

I guess the question is: what are you actually trying to achieve? Because you mention that you can read STEP files using OCC, but not "process the data".
If you want to access the shapes and geometry and everything that was read from the STEP file, you don't need to dive into the ReadFile() functions. STEP file format is pretty involved. So unless you want to write your own STEP parser, you don't need to know exactly how OCC reads the STEP file. OCC will import the file, and then you can use OCC functions to access the data that you just imported.
So, for example, you will probably "transfer" the root(s), and then start iterating through the shapes in the model. And you can get all the information in this way. The documentation has quite a bit of information about reading and writing STEP files:
https://dev.opencascade.org/doc/overview/html/occt_user_guides__step.html
(You might also want to check other pages, such as XDE and OCAF)

Lewis Alexander's picture

Thanks for ur hints!

Actually, I am just about to satisfy my curiosity. LOL.