Dagmc loads a file by calling MBInterface::load_file(). For several reasons, dagmc wants to know what type of file is thus loaded, but MBInterface does not provide an obvious way to find out. Here is a roundabout way to test whether a file is handled by a given reader (in this case, the native MOAB reader):
// variables in scope: MBInterface* MBI, char* filename
// cast MBInterface to MBCore and extract reader-writer set MBReaderWriterSet* rwset = (dynamic_cast<MBCore*>(MBI))-
reader_writer_set(); // get the MOAB handler MBReaderWriterSet::iterator moab_reader = rwset->handler_by_name ("MOAB"); // get the read handler for our file MBReaderWriterSet::iterator cfile_reader = rwset- handler_from_extension( rwset->extension_from_filename( filename ), true, false );
if( moab_reader == cfile_reader ){ ... special code for MOAB files ... }
I have three questions: 1) Is the code above the best way for a MOAB client to check file types? Is there a better way? 2) Should we wrap up this functionality into a more convenient function? Perhaps something like MBReaderWriterSet::handler_name_from_filename(), or even MBInterface::detect_file_type(). (I realize the latter would be a substantial interface change, but it does express the operation I am looking for.) Another option would be to provide a new optional argument to load_file, which would return a value indicating the file type that was loaded. 3) Handler names are currently specified by strings given directly in the code (e.g. "MOAB" in the above). A handler name is initially passed to the MBReaderWriterSet::register_factory method; right now all calls to this method are found within MBReaderWriterSet.cpp. However, if we want to use these handler names to distinguish file types outside of the implementation of MBReaderWriterSet, it might make sense to #define the strings somewhere. Would such defines be appropriate, and if so, where should they go? Paul, Tim, and I discussed this earlier today, and we would value the input of Jason and any other interested users. I'm happy to do the necessary implementation work, if we can agree on an approach. Happy weekend to all, ~S
On Wed, 25 Nov 2009 17:42:04 -0600, Steve Jackson <[email protected]> wrote:
Dagmc loads a file by calling MBInterface::load_file(). For several reasons, dagmc wants to know what type of file is thus loaded, but MBInterface does not provide an obvious way to find out.
Why specifically does it need to know? This sort of problem is most frequently a sign of putting logic in the wrong place, leading to brittleness as you add/change implementations. Jed
On Nov 26, 2009, at 5:36 , Jed Brown wrote:
Dagmc loads a file by calling MBInterface::load_file(). For several reasons, dagmc wants to know what type of file is thus loaded, but MBInterface does not provide an obvious way to find out.
Why specifically does it need to know?
There are two reasons, one serious, and one cosmetic. Serious reason: DagMC has a feature that allows ray tracing to be performed directly on a CAD representation of a geometry, rather than on the faceted representation stored in MOAB. This is done by calling CGM functions (specifically GeometryQueryTool::fire_ray). This CGM-level ray casting only works when the relevant geometry is stored in CGM-- which is expected only if ReadCGM was used to import the geometry into MOAB. In contrast, CAD-based ray casting should be disabled if the file was loaded by some other file loader. So DagMC needs some way to find out if CGM was used to load data. DagMC used to do CGM loading internally, rather than calling out to MOAB. The recent abstraction of the CGM loading code into the ReadCGM module has broken DagMC's assumption that it can know if a CAD geometry was loaded. Cosmetic reason: DagMC passes some file loading options to MBInterface::load_file. These options go unhandled by MOAB's native file reader, causing load_file to return the MB_UNHANDLED_OPTION error code. This isn't really an error condition, though; we wouldn't pass the options in the first place if we knew the file was going to be handled by MOAB's native loader. ~S
Steve Jackson wrote:
On Nov 26, 2009, at 5:36 , Jed Brown wrote:
Dagmc loads a file by calling MBInterface::load_file(). For several reasons, dagmc wants to know what type of file is thus loaded, but MBInterface does not provide an obvious way to find out. Why specifically does it need to know?
There are two reasons, one serious, and one cosmetic.
Serious reason: DagMC has a feature that allows ray tracing to be performed directly on a CAD representation of a geometry, rather than on the faceted representation stored in MOAB. This is done by calling CGM functions (specifically GeometryQueryTool::fire_ray). This CGM-level ray casting only works when the relevant geometry is stored in CGM-- which is expected only if ReadCGM was used to import the geometry into MOAB. In contrast, CAD-based ray casting should be disabled if the file was loaded by some other file loader. So DagMC needs some way to find out if CGM was used to load data.
DagMC used to do CGM loading internally, rather than calling out to MOAB. The recent abstraction of the CGM loading code into the ReadCGM module has broken DagMC's assumption that it can know if a CAD geometry was loaded.
So you don't need to know the file type. You need to know whether or not the file contained geometry that was read into CGM. Why not just query CGM to see if it has any geometry?
Cosmetic reason: DagMC passes some file loading options to MBInterface::load_file. These options go unhandled by MOAB's native file reader, causing load_file to return the MB_UNHANDLED_OPTION error code. This isn't really an error condition, though; we wouldn't pass the options in the first place if we knew the file was going to be handled by MOAB's native loader.
Returning the loaded file type after the fact is unlikely to be helpful in this case, and MOAB cannot correctly determine the file type in all cases until it has successfully loaded it. - jason
On Nov 30, 2009, at 15:36 , Jason Kraftcheck wrote:
So you don't need to know the file type. You need to know whether or not the file contained geometry that was read into CGM. Why not just query CGM to see if it has any geometry?
Fair enough. That seemed to me like a roundabout way of coming at the problem, but it sounds like the simplest fix.
Cosmetic reason: DagMC passes some file loading options to MBInterface::load_file. These options go unhandled by MOAB's native file reader, causing load_file to return the MB_UNHANDLED_OPTION error code. This isn't really an error condition, though; we wouldn't pass the options in the first place if we knew the file was going to be handled by MOAB's native loader.
Returning the loaded file type after the fact is unlikely to be helpful in this case,
It might be helpful, even in this case. We expect the options to go unhandled for MOAB native file types. But if the options go unhandled for a different file type, that's unexpected, and it would be polite to issue a warning to the user. It's still a cosmetic issue, though, and probably does not merit an interface change. Thanks for your help. ~S
Steve Jackson wrote:
On Nov 30, 2009, at 15:36 , Jason Kraftcheck wrote:
Cosmetic reason: DagMC passes some file loading options to MBInterface::load_file. These options go unhandled by MOAB's native file reader, causing load_file to return the MB_UNHANDLED_OPTION error code. This isn't really an error condition, though; we wouldn't pass the options in the first place if we knew the file was going to be handled by MOAB's native loader. Returning the loaded file type after the fact is unlikely to be helpful in this case,
It might be helpful, even in this case. We expect the options to go unhandled for MOAB native file types. But if the options go unhandled for a different file type, that's unexpected, and it would be polite to issue a warning to the user. It's still a cosmetic issue, though, and probably does not merit an interface change.
It would be even better to allow the caller to specify options that apply to specific file formats, eliminating the need for the caller and only report an error for unhandled options that apply to the read format or all formats. E.g.: rather than FACTET_TOLERANCE=1e-6, CUBIT:FACET_TOLERANCE=1e-6. - jason
Steve Jackson wrote:
On Nov 30, 2009, at 15:36 , Jason Kraftcheck wrote:
So you don't need to know the file type. You need to know whether or not the file contained geometry that was read into CGM. Why not just query CGM to see if it has any geometry?
Fair enough. That seemed to me like a roundabout way of coming at the problem, but it sounds like the simplest fix.
Well, the direct solution would be to determine whether or not MOAB used the ReadCGM class to read the file. But asking about the file type is equally indirect, as CGM can read a variety of file formats as well. If we do want to proved the string name of the reader, then I think the way to do this is to use a file set. The MOAB load_file function allows an optional EntitySet handle to be passed. If that handle is provided, the contents of the file will be added to the set. MOAB should hang pertinent data in tags on that set (file name, file reader name/file type, etc.) - jason
It would help if we documented the following: - given an extension name or file name, get the name or actual reader/writer which can handle it - get the extensions a given reader/writer handles and possibly all the readers/writers registered After looking again at MBReaderWriterSet and MBCore::query_interface, I think all this is already possible, it's just not always clear how they're used. I'll put in a documentation ticket on this. - tim Jason Kraftcheck wrote:
Steve Jackson wrote:
On Nov 30, 2009, at 15:36 , Jason Kraftcheck wrote:
So you don't need to know the file type. You need to know whether or not the file contained geometry that was read into CGM. Why not just query CGM to see if it has any geometry?
Fair enough. That seemed to me like a roundabout way of coming at the problem, but it sounds like the simplest fix.
Well, the direct solution would be to determine whether or not MOAB used the ReadCGM class to read the file. But asking about the file type is equally indirect, as CGM can read a variety of file formats as well. If we do want to proved the string name of the reader, then I think the way to do this is to use a file set. The MOAB load_file function allows an optional EntitySet handle to be passed. If that handle is provided, the contents of the file will be added to the set. MOAB should hang pertinent data in tags on that set (file name, file reader name/file type, etc.)
- jason
-- ================================================================ "You will keep in perfect peace him whose mind is steadfast, because he trusts in you." Isaiah 26:3 Tim Tautges Argonne National Laboratory ([email protected]) (telecommuting from UW-Madison) phone: (608) 263-8485 1500 Engineering Dr. fax: (608) 263-4499 Madison, WI 53706
Tim Tautges wrote:
It would help if we documented the following:
- given an extension name or file name, get the name or actual reader/writer which can handle it
- get the extensions a given reader/writer handles and possibly all the readers/writers registered
After looking again at MBReaderWriterSet and MBCore::query_interface, I think all this is already possible, it's just not always clear how they're used. I'll put in a documentation ticket on this.
But MOAB's choice of which reader to use is more complicated that just selecting one based on extension. If it doesn't recognize the extension, it will try them all until one succeeds. That is a good solution, as there is no better test of the type of a file then actually looking at the contents. We do provide the information you describe above, as it is useful in some cases (e.g. constructing a file dialog in verdict), but I don't think utilizing this functionality is the correct solution to Steve's problem. - jason
- tim
Jason Kraftcheck wrote:
Steve Jackson wrote:
On Nov 30, 2009, at 15:36 , Jason Kraftcheck wrote:
So you don't need to know the file type. You need to know whether or not the file contained geometry that was read into CGM. Why not just query CGM to see if it has any geometry?
Fair enough. That seemed to me like a roundabout way of coming at the problem, but it sounds like the simplest fix.
Well, the direct solution would be to determine whether or not MOAB used the ReadCGM class to read the file. But asking about the file type is equally indirect, as CGM can read a variety of file formats as well. If we do want to proved the string name of the reader, then I think the way to do this is to use a file set. The MOAB load_file function allows an optional EntitySet handle to be passed. If that handle is provided, the contents of the file will be added to the set. MOAB should hang pertinent data in tags on that set (file name, file reader name/file type, etc.)
- jason
-- "A foolish consistency is the hobgoblin of little minds" - Ralph Waldo Emerson
Jason Kraftcheck wrote:
But MOAB's choice of which reader to use is more complicated that just selecting one based on extension. If it doesn't recognize the extension, it will try them all until one succeeds. That is a good solution, as there is no better test of the type of a file then actually looking at the contents. We do provide the information you describe above, as it is useful in some cases (e.g. constructing a file dialog in verdict), but I don't think utilizing this functionality is the correct solution to Steve's problem.
- jason
If an extension isn't recognized, though, the function should return NULL or some notion of unknown handler. Also, if an extension is recognized but the registered reader/writer fails, does it cycle through the others? Steve should be able to test the results of calling these functions and act accordingly. Whether the read actually succeeds is another thing that should be handled. - tim -- ================================================================ "You will keep in perfect peace him whose mind is steadfast, because he trusts in you." Isaiah 26:3 Tim Tautges Argonne National Laboratory ([email protected]) (telecommuting from UW-Madison) phone: (608) 263-8485 1500 Engineering Dr. fax: (608) 263-4499 Madison, WI 53706
Tim Tautges wrote:
Jason Kraftcheck wrote:
But MOAB's choice of which reader to use is more complicated that just selecting one based on extension. If it doesn't recognize the extension, it will try them all until one succeeds. That is a good solution, as there is no better test of the type of a file then actually looking at the contents. We do provide the information you describe above, as it is useful in some cases (e.g. constructing a file dialog in verdict), but I don't think utilizing this functionality is the correct solution to Steve's problem.
- jason
If an extension isn't recognized, though, the function should return NULL or some notion of unknown handler.
Yes. So if I had a file named model.cub.bak or model.step.1, it would return NULL. However, MOAB would still "read" it. Steve needs to know if, upon reading said file, a CGM model will be created, which it will. MBReaderWriterTool will return a NULL handler for that extension. It would be more robust for Steve to skip the MBReaderWriterTool stuff entirely, and just look for the "CUB" bytes at the beginning of the file.
Also, if an extension is recognized but the registered reader/writer fails, does it cycle through the others?
I've often wondered if it should, or if we should even rely on extensions at all when reading files, but no it currently does not.
Steve should be able to test the results of calling these functions and act accordingly. Whether the read actually succeeds is another thing that should be handled.
Yes, but I think such a solution is the least robust of many possible options that I can think of. 1) Just check if there is a CGM model 2) Use tag data to communicate which MOAB reader was used 3) Identity file types by actual content (typically first few bytes.) 4) Use file extensions. The first option will likely always work. The second is also robust and future-proof, assuming MOAB only ever uses ReadCGM for all file formats supported by CGM. The third is still robust but requires a little more work and is not as future proof as the first two, as new file formats may be added. The last one (the solution you propose) is not any more future-proof than the third, as MOAB may not be updated with extensions for new CGM file formats either. And MOAB may be changed so as to ignore extensions entirely during reads. And the file extension could be unknown. - jason
On Mon, 30 Nov 2009 15:19:15 -0600, Steve Jackson <[email protected]> wrote:
Serious reason: DagMC has a feature that allows ray tracing to be performed directly on a CAD representation of a geometry, rather than on the faceted representation stored in MOAB. This is done by calling CGM functions (specifically GeometryQueryTool::fire_ray). This CGM-level ray casting only works when the relevant geometry is stored in CGM-- which is expected only if ReadCGM was used to import the geometry into MOAB. In contrast, CAD-based ray casting should be disabled if the file was loaded by some other file loader. So DagMC needs some way to find out if CGM was used to load data.
Does it need to know in advance, or can it just request the geometry object when it needs it? This would enable a user to set up the mesh/geometry association any way they please, rather than necessarily loading it in a particular way. I know Tim is philosophically opposed to making either MOAB or CGM depend on the other, but in that case, any code that necessarily depends on both needs to be moved elsewhere.
Cosmetic reason: DagMC passes some file loading options to MBInterface::load_file. These options go unhandled by MOAB's native file reader, causing load_file to return the MB_UNHANDLED_OPTION error code. This isn't really an error condition, though; we wouldn't pass the options in the first place if we knew the file was going to be handled by MOAB's native loader.
What are you going to do with this file if it's not loaded with the geometry info you need? There is a deeper issue here of finding out which options were actually used. Some options do not change the behavior of the object, they only have memory/performance consequences, and may not be relevant for the file type you are loading. Other options completely produce completely different semantics and the correctness of the program will rely on these options being observed. The current system is difficult to work with because querying properties after the load uses a completely different interface and isn't always possible. Jed
Steve Jackson wrote:
Dagmc loads a file by calling MBInterface::load_file(). For several reasons, dagmc wants to know what type of file is thus loaded, but MBInterface does not provide an obvious way to find out.
Have you not yet responeded to Jed's query as to why you want this feature, or was your response not sent to the list? - jason
participants (4)
-
Jason Kraftcheck -
Jed Brown -
Steve Jackson -
Tim Tautges