Sean said:
yeah, sorry for the ping Sumagna Das -- that's not something you need to read through. Summary is just that gcv needs some lovin' and your work making a plugin for it make that obvious.
So i was busy with my studies and a personal project.......is there anything i can do to help fix GCV?
@Sumagna Das woo hoo! so how'd your testing go? hopefully passed all your exams :)
Yup...the exams went well..
awesome
that's always a good feeling to have that behind you.
As for GCV, I think the main stopper is how mime types are implemented by gcv and bu. If you recall, it was having trouble forwarding your PNG input file to your plugin.
couple issues there, I think
yea......it wasnt recognizing PNG files.
right, that's because PNGs are a 2D type and GCV is expecting 3D types because that's how LIBBU was implemented, separating them into groups
ohh.......thats why it was taking the PNG file as GCV_MODEL_UNKNOWN
Or something like that
you can find that nutty logic in src/libbu/mime.cmake where it autogenerates source code. you can see the source code it generated by looking in the build dir at src/libbu/mime.c
bingo, correct
we had to say "handle anything" because it's a type in a completely different mime type bucket
so I think we need to change that in libbu
i will look into mime.cmake
tomorrow
to either flatten the mime typing like it is in the original data file (see misc/mime.types) with the groupings being optional tagging
actually, that's the best approach I can come up with besides just recreating a mime typing API again (from scratch or otherwise)
probably easier than looking at mime.cmake is to simply look at include/bu/mime.h with a critical eye towards what needs to change
Sean said:
to either flatten the mime typing like it is in the original data file (see misc/mime.types) with the groupings being optional tagging
what do you mean by flatten?
the issue is the bu_mime_context_t parameters -- those have apps pick between 2d, 3d, video, and other mime type sets
they could all be combined into one, for example, thus grouping them into one context (for example)
that's what was meant by flattening them -- grouping into one set
or making null or a default be all sets or something
i just saw the files you told me to see....
what am i supposed to do here?
@Sumagna Das what's your perspective on the mime.h api? we either need to add/create a mime group that has all types (in addition to or instead of the domain-specific groups), or we could remove the groupings so it's just a type-based lookup like the system mime-type system.
Or something else entirely. It's a design decision that has to be made next. From there, the coding changes are pretty straightforward.
maybe think about how you would have WANTED to write the code in gcv, in an ideal world.
we can remove the groupings..
(deleted)
hey @Sean, will any of the files in the rest of the codebase be affected if we remove the groupings?
and one other thing........is there any named type called bu_mime_context
?
@Sean I offer this merely as food for thought - conceptually, could we think about "conversions" between different mime type categories (i.e. images and geometry files) not as conversions but as procedural geometry generations? That would categorize the task of generating some kind of geometry file from a PNG image as a task for a different type of program...
That appeals to me in some ways since it would mean the conceptually ambiguity (i.e. should a PNG import become a binary object in a .g file, a shader texture, a terrain DSP object, etc...) would then be out of scope for GCV.
@Sean i dont know if i were supposed to do this before telling anything but i removed the bu_mime_image_t
-kinda grouping and combined them into bu_mime_context_t
group. I renamed the group containing BU_MIME_APPLICATION
, BU_MIME_IMAGE
, etc from bu_mime_context_t
to bu_mime_context
.
/me is bad at naming variables.
imma send the mime_types.h
and mime.cmake
so that you can see what i did (other than doing the other naming changes)
these are the two main files that have been changed (i know that mime.cmake
changes the second file but it was one of the major changes i did)
i fixed GCV not taking any mime type other than BU_MIME_MODEL_UNKNOWN
the ((bu_mime_context_t)type_int) != BU_MIME_MODEL_UNKNOWN
condition in fmt_type()
function in gcv.c
was causing the problem...i changed it to ((bu_mime_context_t)type_int) != BU_MIME_MODEL_UNKNOWN && type_int != -1
@Sean PS: if you didnt see the mime.cmake
file, then i want to notify you that i flattened the groupings and because of that, every group like bu_mime_model_t
is combined into bu_mime_context_t
starseeker said:
That appeals to me in some ways since it would mean the conceptually ambiguity (i.e. should a PNG import become a binary object in a .g file, a shader texture, a terrain DSP object, etc...) would then be out of scope for GCV.
Hm, interesting though but I think it'd be fairly arbitrary and (more importantly) not user friendly. Don't think it's a distinction that fits our modeling paradigm as implicit geometry means object data is often in some lower-dimensional form. Your gdal linkage is a good example. Perfectly normal for terrain data to live in 2D tiff/png/jpg container, and as such I'd entirely expect gcv to handle converting it. Same for vol data. The data lives in 2D containers, and I would expect gcv to handle them just the same. Pulling out terrain, vol, ebm, pnts, and even BoT creation (e.g., when container is say a txt file with xyz, for example) wouldn't be terribly obvious to me.
I think gcv's on the right track already. The mime type issue is just an issue because the current BU interface is attempting to categorize and the categories are obviously restricting visibility. They're a namespace. We just need to complete the metaphor by introducing global namespacing (i.e., uncategorized), and this should be solved.
I kind of see this getting inverted. We have a master list of types (mime.types) that are string->type mappings. We have a series of additional types that are akin to "image/* -> png, tiff, jpg, gif, ..." mappings so callers can distinguish on any type or rich subsets of types (or exclude types).
Towards that, we may want to make those explicit in our mime.types file so any grouping types are auto-generated instead of encoded.
Sumagna Das said:
imma send the
mime_types.h
andmime.cmake
so that you can see what i did (other than doing the other naming changes)
Can you send an svn diff too? Not easy to see what all was changed in mime.cmake, how it compares.
I'm increasingly thinking we want a traditional string mapping, so apps/callers can do globbing or lookups on their own (e.g., mime.lookup("/path/to/myfile") or mime.lookup(".jpg"))
Sean said:
Sumagna Das said:
imma send the
mime_types.h
andmime.cmake
so that you can see what i did (other than doing the other naming changes)Can you send an svn diff too? Not easy to see what all was changed in mime.cmake, how it compares.
only for mime.cmake?
it might be a little dirty because i wasnt sure about the changes i was making.....if it needs cleaning up, then tell me where it needs
a little cleanup..
I'm not entirely sure I follow - you mean we'd define image/png and terrain/png as distinct mime types, and given a png file the user would need to identify the mime type explicitly so the converter would know what to do with it?
no, not inventing types like that. I meant making the categoric groupings like image/* be an enum type in the same namespace. So like how BU_MIME_IMAGE_JPEG is supposed to match "jpg" or "jpeg" etc, there'd also be a BU_MIME_IMAGE that'd represent all the BU_MIME_IMAGE_* types instead of having a separate context data structure. There'd just be a master registry like sumagna has now with additional groupings like we had before so plugins can just ask for a type, or can narrow in on a subset, or call out a custom set.
(Sorry - I'm sure I'm either being dense or missing the point...)
I'm still not following... when gcv gets the input:
gcv image.tiff output.g
how is the question decided as to whether that tiff image ends up as an ebm, a terrain object, a shader object, or just a straight up binary object holding the image? All of those are potentially valid interpretations of the same data...
The only way I can see is the user must provide somehow additional context that specifies one of those outcomes, but I'm not seeing a good way yet to do it...
SO what should i do about the changes i made in the files for flattening the mime types alongside keeping the group names only?
Sumagna Das said:
SO what should i do about the changes i made in the files for flattening the mime types alongside keeping the group names only?
hey @Sean what should i do about these changes?
Did we ever come to a conclusion on this? I'm really not happy about flattening the image vs. geometry context out of the mime types unless/until we have another way to distinguish those categories...
Looking at the icv/io.h changes in the pull request, bu_mime_context_t just feels too generic to me - personally, I want things to fail immediately and hard at build time if I accidentally try to feed a geometry file type through an image conversion...
I still don't have any good feeling for what gcv is supposed to do when the input "gcv image.png image.g" is given to it...
starseeker said:
Did we ever come to a conclusion on this? I'm really not happy about flattening the image vs. geometry context out of the mime types unless/until we have another way to distinguish those categories...
Looking at the icv/io.h changes in the pull request, bu_mime_context_t just feels too generic to me - personally, I want things to fail immediately and hard at build time if I accidentally try to feed a geometry file type through an image conversion...
oh.......didnt knew you wouldnt agree with that.
@Sumagna Das I'll defer to @Sean - he has a clearer vision than I do of where he wants to go with GCV. I'm just fundamentally bothered by my inability to answer the question "What is supposed to happen when the user gives us 'gcv image.png output.g' on the command line."
The options I know of for "gcv image.png output.g" are:
Just error out with some sort of inadequate specification error unless something like a specific backend is supplied - i.e., require something like "gcv image.png --plugin GDAL output.g" before proceeding. Works, but has negative usability implications.
Always default to the "highest order" output - i.e. for a PNG file, we can default to a height field geometric interpretion and require specification for something else like a texture/shader object or binary object. Easiest from the user perspective IF what we default to is what they want, but potentially frustrating if it does the "wrong" thing for their particular case and they don't know what to do to change the behavior.
Just define any non geometry->geometry conversions as out of scope for gcv - i.e. turning cases involving image data that can't be unambiguously identified as terrain data over to procedural geometry generators rather than the gcv converter. This has the virtue of simplicity, since anything that doesn't have an unambiguous geometric interpretation is simply an invalid input to gcv and another tool is required. However, in prior discussions Sean felt that failing to convert in such cases would be a usability hit.
starseeker said:
Did we ever come to a conclusion on this? I'm really not happy about flattening the image vs. geometry context out of the mime types unless/until we have another way to distinguish those categories...
Looking at the icv/io.h changes in the pull request, bu_mime_context_t just feels too generic to me - personally, I want things to fail immediately and hard at build time if I accidentally try to feed a geometry file type through an image conversion...
i was also checking the changes for the removing the 2nd level groupings and it does seem like that removing them could pose a problem.
if a specific category is not specified, then there is actually a program that some program using these types can be fed anything as input rather than getting files from a specific category. for example, like you said, ICV is supposed to get only images as input but removing the 2nd level grouping can mean that it can get any type of file as input
one thing i did in one of the commits is that alongside keeping the 2nd level grouping is that i added a BU_MIME_AUTO
which acted like a switch saying that search from the whole of the mime types' namespace.
that enum can work pretty well for now for GCV so that it gets all the types of files
but as you said for the 2nd option, the plugin will not know what the user wants and do a default conversion
A lot of excellent insights mentioned, but we shouldn't lose sight of the implementation goal at hand -- namely, creating a vol from a stack of one or more images and how that usability and discovery plays out. The existing BU interface can't/couldn't handle it, so changes are needed. That's not to say that we can also have groupings, or that we don't still also have to sort out what a given conversion request behavior should be, too.
@starseeker I think your summary of "gcv image.png output.g" options are spot-on. I would flat-out reject #3 as unreasonable and unnecessary restriction. The problem of there being multiple conversion results possible for a given input is not unique to images by any stretch. Geometry have that problem as well.
I think the gdal integration is further supporting evidence -- it makes complete usability sense to me that the conversion tool will accept a 2d input and have the wherewithall to generate a 3d representation from it.
As for options #1 and #2, they're not mutually exclusive and I think we'll end up wanting to do a mix of both. They're certainly related to the typing system and ability to do something high-order automatically, but not strictly coupled to it (beyond our existing implementation coupling them).
So then what's our way forward to arrive at a concrete implementation design?
That's where I keep getting stuck... if we want to allow the complexity explosion of N conceptual interpretations of what it means to convert image data to geometry data, how do we encapsulate that in a usable way for programmer and user? Every attempt I've made has fallen short...
Actually I wouldn't have said the first attempt fell short, it just made an assumption that didn't hold up to the next plugin. So we know some adaptation is needed.
Without punting the adaptation to the user yet, there are two issues. First there is/was no way for a plugin to declare that it handles a non-geometric type. Second, there didn't appear to be a way to route to the plugin manually (had to manually disable other plugins).
I think the original plan for gcv plugins is still the way to go -- namely that plugins define the processing architecture by declaring what they can handle and reporting whether they can handle a particular input.
With #1 fixed by doing "some change" to the typing system -- there is a decision we have to immediately face, namely what to do when two plugins support the type and two plugins say yes to handling that particular input. A PNG input is nominally something we can handle today in three ways (gdal, this new vol plugin, and binary/image object).
There's another issue as well - if we're allowing multiple interpretations (terrain, shader, extrusion, binary blob, etc.) then the mime specification isn't going to be sufficient for the plugin API identification on its own. We need some way for a plugin to say "I support image->terrain, image->blob, but not image->shader" (for example.)
That's for filter plugins. There can be many plugins, but a given plugin is going to do one of those. We can probably constrain it to only being one of those from a declaration standpoint, or let the input callback make more complex or specific determinations.
In the original architecture concept, filters did not deal with typed input at all. We could reduce them down to that and it would probably greatly simplify processing (and plugin implementation).
Actually, I semi-lost site of the original prompting issue for the question - in the proposed github pull request, the icv API is changed so that it too takes a generic mime type, rather than just image mime types. For your design vision, is that an OK direction?
That's a good question. I'd not looked into the pull request in detail yet, but the gist I think is not unreasonable. And for similar reasons, say one wanted to implement a plugin that created an image from a .txt file that contained r g b d data, or from an .xls file where some range of cells has rgb values, etc.
I think all that's needed to let that work is for a plugin to be able to list it's types. Any nuance can be handled in the callback. To make it convenient, we can provide meta types (e.g., BU_MIME_IMAGE, BU_MIME_MODEL, etc.).
That would preserve the two-level namespace as data.
The outstanding questions for bu_mime are 1) do we need to make multiple typedefs available, i.e., what code or feature(s) will benefit from a compile-time type restriction and 2) do we want/need defines for meta groupings and 3) do we want/need string-based type associations (whether as a grouping mechanism, for interfacing with other things, or ...?)
i understood most of the part here until the last 4 or 5 messages :sweat_smile:
LOL @Sumagna Das
basically, trying to figure out what/how exactly should bu_mime change so that we can still hard-fail during compilation on a categoric type (if that is needed somewhere) but also support plugins declaring their support and being potentially more nuanced in their input validation callback.
I think @starseeker is probably not (yet)fond of the idea of some tools like icv handling non-image formats (e.g., data files), and that's a valid critique. I see it essentially required and thus will require a bit more thought on how tools like icv/gcv respond when there are 2+ plugins that say they can handle a given input.
For example, we likely will have 3 plugins that read a png file in gcv and they're all roughly equal probability: png-to-dsp-via-gdal, png-to-vol, png-to-binunif
Sean said:
I think @starseeker is probably not (yet)fond of the idea of some tools like icv handling non-image formats (e.g., data files), and that's a valid critique. I see it essentially required and thus will require a bit more thought on how tools like icv/gcv respond when there are 2+ plugins that say they can handle a given input.
For example, we likely will have 3 plugins that read a png file in gcv and they're all roughly equal probability: png-to-dsp-via-gdal, png-to-vol, png-to-binunif
thats a big problem......
did you guys come to any conclusion? i want to finish this thing before my exams from 12th april.
@Sumagna Das I'm not seeing a better way around it. Options seem to be:
A) require non-geometric plugins to resort to being an "unknown" type whereupon the same problem of routing still exists for all such plugins (which would also require something like forced user-specification which would hurt usability/discoverability). I think this is architecturally a problem because there's not a more appropriate place for such functionality, yet typing as unknown would kind of imply they're second-class plugins or otherwise unsupported.
B) let the functionality be handled elsewhere and limit gcv strictly to geometry file inputs. for example, the vol command could read in from images, the dsp command could read in via gdal. while that would be useful in workflows, it seems like it doesn't address gcv being an intuitive place to read data files that result in geoemtry. again, gdal is a great example of this.
C) make changes to the typing system and gcv so it will route files to plugins that handle that file(s) type. fairly unobtrusive change imho. it doesn't answer what happens when multiple plugins handle the same input type but then neither does the current code or options A or B.
D) eliminate the typing system. it's not strictly required. its intent was to improve usability so if there was only one plugin or set of plugins that could handle a given conversion, that it would just do it instead of a user explicitly having to say which plugin (e.g., gcv --i gdal input.png output.g
There is declarative simplicity with D and in some respects we probably should have started there, but B and C have superior usability in my view, C winning out overall as more discoverable.
Towards that end, I think what we should do is keep some means to know we have (for example) and image vs geometry vs something else. I think that can be a sub-typedef like bu_mime_image_t and bu_mime_model_t for compile time restriction or it can be a meta type like BU_MIME_IMAGE for runtime restriction (I don't feel strongly for either being better). That will be helpful for commands like overlay or screengrab that only deal with images. As for gcv, I think that'll generalize to something like bu_mime_t (which has all types) and plugins declare a set of one or more mime types. In the case where multiple plugins match, we'll make it report the conflict, list out available options, and require the user specify.
B and D sound more like it to me.
but the problem still stays that there will a uncertainty about what happens when multiple plugins handle the same file type
we can do B but alongside we can make it report if any conflict exists where multiple plugins are trying to handle the same file.
@Sumagna Das they are certainly options, but they have an undeniable impact on usability and discoverability, and which went or at least go against the original design plans for gcv (that it will figure out what's best when/where it can)
(deleted)
i was trying to find out the real definition of GCV and found out what it was initially made for (Geometry Conversion library) so i think the plugins which handle non-geometry types should be seperated from GCV and either be made into a command inside mged or be made a fully seperate executable or be added as an option to existing commands inside or outside mged.
@Sumagna Das except what constitutes "non-geometry" is very much debatable, it depends on the data format, and depends on the data domain (where it came from).
for example, is a text file full of XYZ vertices a geometry type?
because that's a common "geometry" format that could be a polygonal mesh (it's called xyz format) or it could be point cloud scan data (is that geometry??) or it could be raw terrain elevation data (certainly represents geometry) ...
and yet that same can be said of an image files too -- they're just a quantized array of data. could be terrain (PNG is a standard format for terrain data) ... or could just be an image.
in the medical industry, dicom is their geometry file format, but they are just sets of images. they can represent 3D volumes or point clouds ... or just be images with no 3D implication.
gcv's original scope was the consolidation of a bunch of geometry converters into one tool, but even from the onset that already included data files too, so I don't think it's a out of place to include them. moreover, and more problematically, it doesn't solve a problem by excluding them -- if anything it would create pointless work like extracting gdal from gcv.
didnt know geometry types were this complicated
The waters are muddy and we're learning, will make mistakes. I think it's all good. We can try a direction and if it doesn't work out, we can change it. I think the least code churn at this point is to just tweak bu_mime to provide a means to scan all types and let plugins declare whatever it is they read/write. We'll learn.
I had that part ready so that it could scan from all types
But It would need the 2nd level grouping which I removed
Also
Is it needed tobring back bu_mime_*_t
enums or should they be combined like they are right now?
I think we should keep both typedefs for now. That way commands like screengrab can literally be hard-limited to image formats.
but then also have a bu_mime_t that has them all
(instead of bu_mime_context_t, not really a benefit introducing another term)
can you check the PR
i removed the commit which remove the 2nd level grouping like BU_MIME_IMAGE, etc
i also added BU_MIME_AUTO which searches from all of them
sorry for the inactivity
i had exams going on
now that I am done with the exams
what were the plans for this part @Sean ?
@Sumagna Das how'd the exams go?
no worries, good to focus on your exams.... they're kind of important ;)
Sean said:
Sumagna Das how'd the exams go?
it went pretty well
there is one thing i want to ask
should i bring back all of the bu_mime_*_t
and keep one bu_mime_t
namespace along with it?
@Sumagna Das that would probably be good for now, so an app / use case could choose to be type-limited or not. longer term I think we could probably find a way that does it with fewer API symbols, if needed.
[ 0%] Built target timestamp
[ 0%] Built target BENCHMARK_PIX_cp
Scanning dependencies of target libbu-obj
[ 0%] Built target netpbm
[ 0%] Built target 04238f4c3429a37ca335f9352ba2dc81_cp
[ 0%] Building C object src/libbu/CMakeFiles/libbu-obj.dir/crashreport.c.o
[ 0%] Built target openNURBS_headers_cp
[ 0%] Built target fix_6r_cp
[ 0%] Built target nonie_r_12_cp
[ 0%] Built target nurb_example_c_cp
[ 0%] Built target raydebug_tcl_cp
[ 0%] Building C object src/libbu/CMakeFiles/libbu-obj.dir/mime.c.o
[ 0%] Built target CL_FILES_cp
[ 0%] Built target tpkg_c_cp
[ 0%] Built target termcap_cp
[ 0%] Built target brlman_tcl_cp
[ 0%] Building C object src/libbu/CMakeFiles/libbu-obj.dir/vers.c.o
In file included from /home/sumagnadas/github/brlcad_git/include/bu/mime.h:27,
from /home/sumagnadas/github/brlcad_git/build1/src/libbu/mime.c:21:
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:887:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_AUTO’
887 | BU_MIME_APPLICATION_AUTO,
| ^~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:44:5: note: previous definition of ‘BU_MIME_APPLICATION_AUTO’ was here
44 | BU_MIME_APPLICATION_AUTO,
| ^~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:888:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_ANDREW_DASH_INSET’
888 | BU_MIME_APPLICATION_ANDREW_DASH_INSET,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:45:5: note: previous definition of ‘BU_MIME_APPLICATION_ANDREW_DASH_INSET’ was here
45 | BU_MIME_APPLICATION_ANDREW_DASH_INSET,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:889:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_APPLIXWARE’
889 | BU_MIME_APPLICATION_APPLIXWARE,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:46:5: note: previous definition of ‘BU_MIME_APPLICATION_APPLIXWARE’ was here
46 | BU_MIME_APPLICATION_APPLIXWARE,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:890:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_ATOMCAT_PLUS_XML’
890 | BU_MIME_APPLICATION_ATOMCAT_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:47:5: note: previous definition of ‘BU_MIME_APPLICATION_ATOMCAT_PLUS_XML’ was here
47 | BU_MIME_APPLICATION_ATOMCAT_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:891:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_ATOMSVC_PLUS_XML’
891 | BU_MIME_APPLICATION_ATOMSVC_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:48:5: note: previous definition of ‘BU_MIME_APPLICATION_ATOMSVC_PLUS_XML’ was here
48 | BU_MIME_APPLICATION_ATOMSVC_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:892:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_ATOM_PLUS_XML’
892 | BU_MIME_APPLICATION_ATOM_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:49:5: note: previous definition of ‘BU_MIME_APPLICATION_ATOM_PLUS_XML’ was here
49 | BU_MIME_APPLICATION_ATOM_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:893:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_CCXML_PLUS_XML’
893 | BU_MIME_APPLICATION_CCXML_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:50:5: note: previous definition of ‘BU_MIME_APPLICATION_CCXML_PLUS_XML’ was here
50 | BU_MIME_APPLICATION_CCXML_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:894:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_CDMI_DASH_CAPABILITY’
894 | BU_MIME_APPLICATION_CDMI_DASH_CAPABILITY,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:51:5: note: previous definition of ‘BU_MIME_APPLICATION_CDMI_DASH_CAPABILITY’ was here
51 | BU_MIME_APPLICATION_CDMI_DASH_CAPABILITY,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:895:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_CDMI_DASH_CONTAINER’
895 | BU_MIME_APPLICATION_CDMI_DASH_CONTAINER,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:52:5: note: previous definition of ‘BU_MIME_APPLICATION_CDMI_DASH_CONTAINER’ was here
52 | BU_MIME_APPLICATION_CDMI_DASH_CONTAINER,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:896:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_CDMI_DASH_DOMAIN’
896 | BU_MIME_APPLICATION_CDMI_DASH_DOMAIN,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:53:5: note: previous definition of ‘BU_MIME_APPLICATION_CDMI_DASH_DOMAIN’ was here
53 | BU_MIME_APPLICATION_CDMI_DASH_DOMAIN,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:897:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_CDMI_DASH_OBJECT’
897 | BU_MIME_APPLICATION_CDMI_DASH_OBJECT,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:54:5: note: previous definition of ‘BU_MIME_APPLICATION_CDMI_DASH_OBJECT’ was here
54 | BU_MIME_APPLICATION_CDMI_DASH_OBJECT,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:898:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_CDMI_DASH_QUEUE’
898 | BU_MIME_APPLICATION_CDMI_DASH_QUEUE,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:55:5: note: previous definition of ‘BU_MIME_APPLICATION_CDMI_DASH_QUEUE’ was here
55 | BU_MIME_APPLICATION_CDMI_DASH_QUEUE,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:899:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_CU_DASH_SEEME’
899 | BU_MIME_APPLICATION_CU_DASH_SEEME,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:56:5: note: previous definition of ‘BU_MIME_APPLICATION_CU_DASH_SEEME’ was here
56 | BU_MIME_APPLICATION_CU_DASH_SEEME,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:900:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_DAVMOUNT_PLUS_XML’
900 | BU_MIME_APPLICATION_DAVMOUNT_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:57:5: note: previous definition of ‘BU_MIME_APPLICATION_DAVMOUNT_PLUS_XML’ was here
57 | BU_MIME_APPLICATION_DAVMOUNT_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:901:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_DOCBOOK_PLUS_XML’
901 | BU_MIME_APPLICATION_DOCBOOK_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:58:5: note: previous definition of ‘BU_MIME_APPLICATION_DOCBOOK_PLUS_XML’ was here
58 | BU_MIME_APPLICATION_DOCBOOK_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:902:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_DSSC_PLUS_DER’
902 | BU_MIME_APPLICATION_DSSC_PLUS_DER,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:59:5: note: previous definition of ‘BU_MIME_APPLICATION_DSSC_PLUS_DER’ was here
59 | BU_MIME_APPLICATION_DSSC_PLUS_DER,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:903:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_DSSC_PLUS_XML’
903 | BU_MIME_APPLICATION_DSSC_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:60:5: note: previous definition of ‘BU_MIME_APPLICATION_DSSC_PLUS_XML’ was here
60 | BU_MIME_APPLICATION_DSSC_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:904:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_ECMASCRIPT’
904 | BU_MIME_APPLICATION_ECMASCRIPT,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:61:5: note: previous definition of ‘BU_MIME_APPLICATION_ECMASCRIPT’ was here
61 | BU_MIME_APPLICATION_ECMASCRIPT,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/sumagnadas/github/brlcad_git/build1/include/bu/mime_types.h:905:5: error: redeclaration of enumerator ‘BU_MIME_APPLICATION_EMMA_PLUS_XML’
905 | BU_MIME_APPLICATION_EMMA_PLUS_XML,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.....
i knew something like this would happen
any suggestion how to overcome this?
You've got multiple definitions in the generated output looks like... I'd pick one, check where it's getting defined, and trace that back to see where it's coming from in the generated logic.
A thought - what if we completely eliminate any notion of mime type typedefs, and instead make it all integer defines. The categories would become:
#define BU_MIME_UNKNOWN 0
#define BU_MIME_APPLICATION 1
#define BU_MIME_AUDIO 2
...
and the mime types would be one long list of defines:
#define BU_MIME_APPLICATION_ANDREW_DASH_INSET 1
#define BU_MIME_APPLICATION_APPLIXWARE 2
....
Then we define zero terminated static integer arrays or something similar to encode the context information:
static long BU_MIME_IMAGES[] = {
BU_MIME_IMAGE_PNG,
BU_MIME_IMAGE_JPG,
...
0
};
and a function long bu_mime_context( long mime_id)
to walk the arrays and find the right context.
The only other functions we would need should be translators to/from strings, which we're already generating now.
This both eliminates the separate typedefs for each context, and allows us to assert categories in user code if we so desire.
Then, on the gcv side, we change the plugin setup slightly.
On the GCV library side, we define a series of bit flag types that correspond to various geometry object output categories:
#define BINARY_OBJ 0x01
#define IMAGE_OBJ 0x02
#define GEOM_OBJ 0x04
...
We have each plugin provide a function which takes two integers - a mime context and a mime type and returns an integer holding bit flags set to correspond to what that plugin can either write or create given that input.
The mime context argument could be set to either BU_MIME_UNKNOWN - in which case a plugin will decide on its own if it can handle a PNG image as image data, terrain (geometry) data, or both. If it can do both, it sets both bit flags in the return. If the caller does provide it a mime context (BU_MIME_MODEL, say) then it will only return - if it can do it- the GEOM_OBJ flag set.
Then, for a given pairing of inputs and outputs, we have a way forward. By default, if the user doesn't constrain the solution set, gcv will make a stab at determining the file mime type but will pass BU_MIME_UNKNOWN to the reader/writer plugins to get the full range of options. It will then look at the mime types returned from all the plugins and identify viable pairings. If either or both of the plugin and mime context interpretations are not unique, it will report the available options back to the user and request specification of either or all of a mime context interpretation, desired output object category, and reader/writer plugin to use. If, however, only one unique interpretation is found, then it doesn't have to ask anything and will try the only thing it can.
This allows conversion problems with unique potential solutions (3dm-g, for example) to simply proceed. Ambiguous cases (multiple plugins supporting STL or interpreting PNG as either terrain or an image object) will report the available options and give the user guidance on how to refine the problem.
Theoretically, icv and gcv might collapse completely into just gcv...
We may also want to add a .gcv defaults file where users can set plugin or interpretation defaults so they can avoid specifying things all the time (command line options would override the defaults file, but the defaults file could make things more automatic for "normal" use.)
the define method sounds good
we can work with that
it doesnt require any redefining of symbols/enums
the one thing i am havin problems understanding is the GCV part.
Sumagna Das said:
the one thing i am havin problems understanding is the GCV part.
so in the plugin file, there is a define part?
or is it on the api part?
plus the part about how we are going to name the inputs and outputs for the plugins.
The GCV plugins provide hooks to the main gcv library. Right now (for example) there's a "rhino_can_read" function which takes the file and tests it. What we can try instead is a function that accepts the mime arguments in addition to the file - this allows the plugin to have more context when making its decisions about what it can/can't read.
If, for example, the 3DM mime type was passed in and the context passed in was BU_MIME_MODEL, the rhino_can_read function would know to try the file and see if it can open it. However, if the context passed in was BU_MIME_IMAGE (i.e. the specific conversion path of interest is to treat the 3DM data as an image format) then rhino_can_read would report that it can't read the file. It only supports reading the 3DM format as geometry, not as an image.
So the function would look something like:
static long
rhino_can_read(long mime_context, long mime_type, const char *source_path)
{
if (mime_type != BU_MIME_MODEL_VND_RHINO)
return 0;
if (mime_context != BU_MIME_MODEL)
return 0;
int fv;
ON_String mSC;
ON_3dmProperties mprop;
if (!source_path) return 0;
FILE *fp = ON::OpenFile(source_path,"rb");
if (!fp) return 0;
ON_BinaryFile file(ON::on_read3dm,fp);
if (!file.Read3dmStartSection(&fv, mSC)) return 0;
if (!file.Read3dmProperties(mprop)) return 0;
return GEOM_OBJ;
}
This gets at addressing the issue that was causing me mental indigestion earlier - how to deal with the situation where a tiff image might need to come into a .g as a terrain import or an image. Even a generic GEOM_OBJ return type might not be enough - we may need to encode certain supported BRL-CAD entity types as flags. An image, for example, could be a source for dsp terrain primitives or also for an extruded bitmap...
But as a next step we can probably just see if that approach will work - if it does, more specificity just means defining additional contexts beyond BU_MIME_MODEL and BU_MIME_IMAGE for plugins to check for.
starseeker said:
A thought - what if we completely eliminate any notion of mime type typedefs, and instead make it all integer defines. The categories would become:
#define BU_MIME_UNKNOWN 0 #define BU_MIME_APPLICATION 1 #define BU_MIME_AUDIO 2 ...
and the mime types would be one long list of defines:
#define BU_MIME_APPLICATION_ANDREW_DASH_INSET 1 #define BU_MIME_APPLICATION_APPLIXWARE 2 ....
Then we define zero terminated static integer arrays or something similar to encode the context information:
static long BU_MIME_IMAGES[] = { BU_MIME_IMAGE_PNG, BU_MIME_IMAGE_JPG, ... 0 };
and a function
long bu_mime_context( long mime_id)
to walk the arrays and find the right context.The only other functions we would need should be translators to/from strings, which we're already generating now.
This both eliminates the separate typedefs for each context, and allows us to assert categories in user code if we so desire.
done the first two define parts
now the left of the tasks are
also
should i make the arrays in the mime_types.h file?
or somewhere other would be much better?
whatever you think makes sense - could be inside the generated bu_mime_context funtion
ohk
so what would the function do exactly?
So given an input, it would check a series of arrays to see which one (if any) contain that integer
get an mime type id/value, walk all the arrays, find the right type
if available, return a string that will say which context it belongs to else BU_mime_unknown?
Sumagna Das said:
get an mime type id/value, walk all the arrays, find the right type
if available, return a string that will say which context it belongs to else BU_mime_unknown?
is this roughly the way it will work?
Roughly, yes - I'd return the mime integer, rather than a string - we can define a function to translate mime contexts to strings if we want that (user messages, etc.), but the integer itself is probably enough for most uses.
My first cut at it would be to generate the per-mime-context arrays, then generate a NULL terminated array of pointers to those arrays.
Then you iterate over the array-of-arrays, and iterate over each array's contents.
starseeker said:
Roughly, yes - I'd return the mime integer, rather than a string - we can define a function to translate mime contexts to strings if we want that (user messages, etc.), but the integer itself is probably enough for most uses.
a function which returns a string would be handy for the message as you said
starseeker said:
Then you iterate over the array-of-arrays, and iterate over each array's contents.
that sounds better
I would just make a const char *bu_mime_context_str(long ctx)
function
currently i am trying to atleast get the part for arrays working
then make the array of pointers if it helps
starseeker said:
I would just make a
const char *bu_mime_context_str(long ctx)
function
that i will keep for the endgame
the main part is the one which returns the integer
However you want to approach it. @Sean hasn't weighed in, and he may have other thoughts
thats the problem right now
You mean the big one to return the integer? Yes, that's the main logic.
starseeker said:
You mean the big one to return the integer? Yes, that's the main logic.
yea
foreach(context ${ACTIVE_TYPES})
string(TOUPPER "${context}" c)
set(mcstr "${mcstr} if (mime_${context}(ext) != -1){\n")
set(mcstr "${mcstr} return mime_${context}(ext);\n")
set(mcstr "${mcstr} }\n")
endforeach(context ${ACTIVE_TYPES})
i had this part before to iterate between all of the mime types
do you think i could reuse this logic for this one in "the" function?
you'll have to experiment - it'll most likely take a few iterations to arrive at a final design.
will try to setup atleast the array part right now
then move on to the function
the function is nothing without the arrays
but right now thinking whether it is better to put it with the mime_types.h file or in the mime.c file
which one sounds better for keeping the array for the defines?
If it were me I'd probably define the arrays as part of the function.
ok
lemme try then
vs code just crashed out of nowhere :neutral:
in the current mime.c I generated all the string to number and back mappings as static if checks, IIRC...
You might give Ninja on windows a try... less overhead
It should work - that's what our CI on github is using.
starseeker said:
in the current mime.c I generated all the string to number and back mappings as static if checks, IIRC...
yea
all the functions are present in the mime.c file
starseeker said:
You might give Ninja on windows a try... less overhead
is ninja available in linux?
Oh, sorry - I thought you meant visual studio. yes, ninja is primarily used on Linux
That won't help you though if you're using vs code as your source editor
let me check though
i use the terminal inside VS code for building most of the time as i use a different build folder for this change or else normal building gets messed up
/me uses vim most of the time, and Emacs when he must (DocBook editing usually).
starseeker said:
/me uses vim most of the time, and Emacs when he must (DocBook editing usually).
i heard that vim is a good one but havent tried yet because no time for learning new things :sweat:
have my 10th grade's exam coming next year
and one last thing.....should there be an auto and an unknown special for every category like "BU_MIME_IMAGE_AUTO", "BU_MIME_IMAGE_UNKNOWN" in every array?
right now, the arrays part is ready without those special ones including the array of arrays
now the only part that is left is the real logic which returns the integer for the right context/category
Not sure about the unknowns - my thought right now is one generic unknown mime type is probably enough, unless we think of a use case.
ohk
right now, the only thing i am having a problem is that i can iterate thru the array of arrays but when it comes to the array containing the types, i have no such variable in the cmake file which can help me get the number of elements in each array
so do you know of any condition which can help me get each of the elements in the array
like for using while?
I'm not 100% sure I follow, but you can build a counter in CMake if you need to so you can write out that information. I think it's the math() command...
would it be worth it for each array tho?
i thought that it might make it take more memory while generating the file :shrug:
right now, i just came with an idea. as the last element of the arrays will always be 0, we can put a while loop for *elem !=0.
how does that sound?
Sounds good.
any idea how or where we can make an use of it?
the function is implemented
And also
In how many places we have to change the logic of a function to work with this define logic?
Except for the mime.c file
You could try reworking a gcv plugin and the library to use the new setup, maybe starting with the 3dm (rhino) convertor and disabling the others.
starseeker said:
Then, on the gcv side, we change the plugin setup slightly.
On the GCV library side, we define a series of bit flag types that correspond to various geometry object output categories:
#define BINARY_OBJ 0x01 #define IMAGE_OBJ 0x02 #define GEOM_OBJ 0x04 ...
We have each plugin provide a function which takes two integers - a mime context and a mime type and returns an integer holding bit flags set to correspond to what that plugin can either write or create given that input.
The mime context argument could be set to either BU_MIME_UNKNOWN - in which case a plugin will decide on its own if it can handle a PNG image as image data, terrain (geometry) data, or both. If it can do both, it sets both bit flags in the return. If the caller does provide it a mime context (BU_MIME_MODEL, say) then it will only return - if it can do it- the GEOM_OBJ flag set.
Then, for a given pairing of inputs and outputs, we have a way forward. By default, if the user doesn't constrain the solution set, gcv will make a stab at determining the file mime type but will pass BU_MIME_UNKNOWN to the reader/writer plugins to get the full range of options. It will then look at the mime types returned from all the plugins and identify viable pairings. If either or both of the plugin and mime context interpretations are not unique, it will report the available options back to the user and request specification of either or all of a mime context interpretation, desired output object category, and reader/writer plugin to use. If, however, only one unique interpretation is found, then it doesn't have to ask anything and will try the only thing it can.
This allows conversion problems with unique potential solutions (3dm-g, for example) to simply proceed. Ambiguous cases (multiple plugins supporting STL or interpreting PNG as either terrain or an image object) will report the available options and give the user guidance on how to refine the problem.
this was one of the things you wanted with the gcv library?
if i follow this, there are some questions in my mind
one other question, how do i return both bit flags?
There are tutorials online about bit flags and bit masks - see, for example, https://www.learn-c.org/en/Bitmasks
https://www.codeproject.com/Articles/2247/An-introduction-to-bitwise-operators
Basically the idea is you return a single number, and the on/off status of the individual bits is used to contain information.
I tend to go with an unsigned long long to maximize the potential number of flags that can be set in a single number.
As to how many flags we will need to define, that's one of the things that isn't fully clear yet.
They'll be handled (set and checked) as bit masks (there are other examples in our code where we use such flags)
So we return a single number, but the bit flags are used to encode multiple pieces of information within the single number.
An unsigned long long will be (at least) 64 bits, so that gives us up to 64 flags within that single number.
I would suggest making a small C or C++ program and exploring how those flags work, if you're unfamiliar with them.
starseeker said:
I would suggest making a small C or C++ program and exploring how those flags work, if you're unfamiliar with them.
it looks like i will have to do this to understand it
its a bit mind boggling
I'm late to the party, but I'd question the value of bitsets for typedefs, and they're fundamentally limited to the number of available bits. It'd have to go over 64 bits if we're talking the types themselves (or is this only for categories?), and solutions for that are typically obnoxious...
The usual reason for doing bit flags is for performance, which really isn't needed here. This whole system is primarily dealing with file identification, in I/O land (i.e., as slow as it gets). If the direction is to get a handle to an identifier, then we might as well directly adopt the mime-type classifier string-as-data and ditch all the API complexity.
That would greatly simplify things.
Apps/Libs could set "*" (i.e., mime unknown) or "model\*" (i.e., mime category 'model') etc.
Plugins could declare categories or specific types or sets of types (e.g., "model/*" and/or "text/plain").
Sumagna Das said:
right now, the only thing i am having a problem is that i can iterate thru the array of arrays but when it comes to the array containing the types, i have no such variable in the cmake file which can help me get the number of elements in each array
If you've created a fixed array at compile time, then you can determine the size with:
size_t length = sizeof(array) / sizeof(array[0]);
If I got that correctly, The bit flags are only for the categories and not for all the types.
Sean said:
Sumagna Das said:
right now, the only thing i am having a problem is that i can iterate thru the array of arrays but when it comes to the array containing the types, i have no such variable in the cmake file which can help me get the number of elements in each array
If you've created a fixed array at compile time, then you can determine the size with:
size_t length = sizeof(array) / sizeof(array[0]);
yea got this part working......
one thing i have to ask, should i work using the bit flags?
Sumagna Das said:
one thing i have to ask, should i work using the bit flags?
@Sean
@starseeker got the functions working with the extra arguments but how to use the returned bit flag tho?
right now, testing the syntax atleast thru the 3DM plugin. the other plugins are disabled for now.
Sumagna Das said:
starseeker got the functions working with the extra arguments but how to use the returned bit flag tho?
like what should i do with bit flags?
should i check for the output types?
should i send them to the user through a selection menu?
So my thinking, for what it's worth, was to do the following:
Have the gcv executable support an option to specify the processing mode: --image for example to treat a .tiff file as an image, and --geom to force processing as geometry.
What should happen if you feed gcv the .3dm file and tell it to process it as an image, would be for it to query the plugin with the mime context set to BU_MIME_IMAGE. The plugin, in turn, should recognize that it can't process a 3dm file as an image, and return nothing.
With the --geom option set, the context would be set to BU_MIME_MODEL, and without it the context would be BU_MIME_UNKNOWN. In either of those cases the plugin would then report it could handle the 3dm input successfully, and return a value with the GEOM bit flag set. The gcv executable would then know it had at least one conversion path.
This gets more interesting with an image format like .png. Since it could be interpreted as either an image or terrain data, if we don't supply either --image or --geom to introduce a context both a plugin to read pngs and generate .g files containing those images and the gdal plugin producing geometry files will report they can handle the PNG file. If --image or --geom are supplied, and the prospective plugins return values with their respective bit flags set, gcv can select the plugin that not only handles PNG but handles it as the desired type of information. If neither --image or --geom are supplied and the PNG file is fed to gcv, we don't know what to do with it - there are multiple valid options. In that case gcv can use the return codes from the plugin tests to report the available options. Something like:
gcv terrain.png outfile.g
Error - multiple conversion alternatives found:
Image conversions (--image):
png2gtexture - Import PNG image as BRL-CAD texture file
Geometry conversions (--geom):
gdal - Import PNG image as DSP terrain data
To actually get the gdal conversion path in this scenario, the command would be either:
gdal --geom terrain.png outfile.g
or
gda --plugin=gdal terrain.png outfile.pn
If a plugin could be capable of producing either image or geometry outputs from the same input (let's say hypothetically the gdal plugin was also able to produce a texture as well as a terrain file) it would return with both the image and geom bit flags set. In that case, even if it was the only plugin that could handle the format, gcv would know it needs additional context before the plugin can proceed to do a conversion:
gcv --plugin gdal terrain.png output.png
Error: plugin supports both image and geometry conversion paths:
image: produces a .g texture object
geom: produces a dsp terrain file
The terrain path would then become:
gcv --plugin gdal --geom terrain.png output.png
got the options --geom
and --image
working somewhat. currently it just passes the BU_MIME_MODEL
and BU_MIME_IMAGE
defs respectively.
i just want to ask.....is the returned bit flag mainly going to be used to check if there are options for plugins for a certain file?
and i am a little bit confused right now........i tried to go for it and couldnt find out where it is checking for the types and using the function *_can_read
so it might help if someone can get me thru this confusion
My idea (which @Sean may shoot down - it's just a notion) was to use the return bit flag to determine what sorts of input/output a given importer/exporter can handle.
If I'm following this correctly (it's been a while) struct gcv_filter in include/gcv/api.h has a callback function data_supported - I think that's where the can_read functions get hooked in. To make sure, try stepping through a gcv conversion in gdb and breaking on the can_read function in question - the backtrace should tell you how it's being called.
Here's another stab at how I envisioned this working. Given the conversion input:
gcv file.png file.g
The initial filename based characterizations would be:
mime-characterize png -> BU_MIME_IMAGE, BU_MIME_IMAGE_PNG
mime-characterize g -> BU_MIME_MODEL, BU_MIME_MODEL_VND_BRLCAD_G
Step 1a: ask all reader plugins if they can handle BU_MIME_UNKNOWN, BU_MIME_IMAGE_PNG and collect responses
Step 1b: ask all writer plugins if they can handle BU_MIME_UNKNOWN, BU_MIME_MODEL_VND_BRLCAD_G and collect responses
Step 2: for any plugins that answer non-zero, characterize their responses as being BU_MIME_IMAGE, BU_MIME_MODEL, or both. The possibilities for both readers and writers are:
Step 3: Find matching reader and writer context pairings that offer conversion paths. For our hypothetical example where gdal can read a PNG both as image and terrain data, we would get the following valid conversion path pairings:
(BU_MIME_IMAGE,gdal)->(BU_MIME_IMAGE,g)
(BU_MIME_MODEL,gdal)->(BU_MIME_MODEL,g)
This situation is thus ambiguous - both the reader and writer have multiple valid interpretations of the data. The user will have to provide more context (for example --geom to specify our desired conversion context is BU_MIME_MODEL) to resolve the ambiguity.
starseeker said:
My idea (which Sean may shoot down - it's just a notion) was to use the return bit flag to determine what sorts of input/output a given importer/exporter can handle.
If I'm following this correctly (it's been a while) struct gcv_filter in include/gcv/api.h has a callback function data_supported - I think that's where the can_read functions get hooked in. To make sure, try stepping through a gcv conversion in gdb and breaking on the can_read function in question - the backtrace should tell you how it's being called.
for some reason, the can_read
function wasnt being called when i tried putting it thru gdb. thats why i asked for where it is being called. IIRC in the code the only place where the function was called was in a condition and one of other conditions in that if statement was if (emt == BU_MIME_MODEL_AUTO && ......)
and because of that the function is not being called for some reason.
@Sumagna Das you may have to alter the gcv logic flows somewhat - they've always been a bit haphazard, so if something else makes sense to you feel free to give it a go.
@Sumagna Das how's it going? any luck deciphering the logic flow?
While I'm not convinced there's usability value in having categoric flags, I'm not terribly opposed. More concerned where this is heading. I think the user isn't necessarily going to know what a particular input plugin was coded to receive or what a particular filter plugin is expecting. So they're probably going to have to hunt or try them all to see what they do and that won't be a good user experience.
There's also an issue with many formats that have even more interpretations beyond image or geometry ... could also be data, could be a container format, could be a single format that holds multiple interpretations or multiple representations simultaneously. It's messy and categorization works against us.
As mentioned earlier, I'd think it'd be beneficial to focus on specific issues, such as getting vol plugin to simply work, and address the problems that specific case provokes. That's not to suggest undoing or changing anything that's been done on the pull request, but to wrap it up and get back to considering how that vol plugin works now and talking about that usability.
i.e., how it is discovered and how is it invoked unambiguously with a starting premise that a user begins with a naive invocation such as "gcv input.png output.g"
Sean said:
Sumagna Das how's it going? any luck deciphering the logic flow?
somewhat
havent been able to play with it in the last few days because of studies and dont think i will be able to do that in the next few days
so not much luck you can say
Sean said:
As mentioned earlier, I'd think it'd be beneficial to focus on specific issues, such as getting vol plugin to simply work, and address the problems that specific case provokes. That's not to suggest undoing or changing anything that's been done on the pull request, but to wrap it up and get back to considering how that vol plugin works now and talking about that usability.
i.e., how it is discovered and how is it invoked unambiguously with a starting premise that a user begins with a naive invocation such as "gcv input.png output.g"
thats actually done
i had that on sideby in a git stash so i can put all of the work right now into another stash, pop the stash which contains the vol plugin work and with some minor changes, voila! the plugin and the initial work for the GCV rework is done in the pull request.
Sean said:
While I'm not convinced there's usability value in having categoric flags, I'm not terribly opposed. More concerned where this is heading. I think the user isn't necessarily going to know what a particular input plugin was coded to receive or what a particular filter plugin is expecting. So they're probably going to have to hunt or try them all to see what they do and that won't be a good user experience.
The user won't know what the plugins can do or expect - that's the idea of the proposed scheme, to have the plugins themselves tell gcv what they can and can't do, and have gcv solve the problem of what combinations constitute potentially viable conversion paths. If the path solution is not unique, gcv then presents the viable paths and how to invoke them to the user.
Sean said:
There's also an issue with many formats that have even more interpretations beyond image or geometry ... could also be data, could be a container format, could be a single format that holds multiple interpretations or multiple representations simultaneously. It's messy and categorization works against us.
If we've got inputs that are fundamentally that messy (not all of them are, but I'm sure some are) then I see no alternative other than analyzing them to find the viable interpretations and reporting them back to the user with instructions for how to select the interpretation they want. That means we need some universal language in which to communicate those capabilities and options (data, image, geometry, video, etc.) The set of categoric data possibilities must ultimately be finite in order to be implementable, and for our problems there are usually just a few big ones (image, geometry, etc.) - hence my thinking that we could use the bit flag to communicate the viable options back from a plugin.
Sumagna Das said:
Sean said:
As mentioned earlier, I'd think it'd be beneficial to focus on specific issues, such as getting vol plugin to simply work, and address the problems that specific case provokes. That's not to suggest undoing or changing anything that's been done on the pull request, but to wrap it up and get back to considering how that vol plugin works now and talking about that usability.
i.e., how it is discovered and how is it invoked unambiguously with a starting premise that a user begins with a naive invocation such as "gcv input.png output.g"
thats actually done
i had that on sideby in a git stash so i can put all of the work right now into another stash, pop the stash which contains the vol plugin work and with some minor changes, voila! the plugin and the initial work for the GCV rework is done in the pull request.
i had pushed the vol plugin changes alongside the changes for flattening the mime namespace. review it when you can
starseeker said:
The user won't know what the plugins can do or expect - that's the idea of the proposed scheme, to have the plugins themselves tell gcv what they can and can't do, and have gcv solve the problem of what combinations constitute potentially viable conversion paths. If the path solution is not unique, gcv then presents the viable paths and how to invoke them to the user.
I agree the user won't know, but for that same reason they won't necessarily know whether -image or -data or -model or whatever taxonomy we come up with is appropriate. It's still not unambiguous what that means if the user specifies a png file with a category flag. It turns into "try them all and see what they do". It's compounded by the fact that category flags attempt to characterize an input or/and output homogeneously which isn't necessarily true or even a common case.
The resulting workflow sounds like a problematic UX to me.. So much so that I think we're better off focusing on declarative and getting that UX right first.. It's needed no matter what. Let's keep it simple. We really need to resist overarchitecting as simplicity will be central to any external adoption.
starseeker said:
If we've got inputs that are fundamentally that messy (not all of them are, but I'm sure some are) then I see no alternative other than analyzing them to find the viable interpretations and reporting them back to the user with instructions for how to select the interpretation they want.
Agreed!
That means we need some universal language in which to communicate those capabilities and options (data, image, geometry, video, etc.)
Sort of! :)
I think that's the leap to a particular solution implementat that I don't think is demonstrated. The universal language couple be plain english. If there are three plugins that can handle an input, we could simply itemize them with a description and let the user pick based on that info. In this particular instance, the user would see something like:
$ gcv image.png file.g
Multiple plugins read PNG input. Please select the one most appropriate with the --input=[label] option:
gdal: Reads image and data files typically representing terrain creating height field (DSP) geometry.
png-to-vol: Reads PNG format image files creating volumetric (VOL) geometry.
magick: Reads multiple image file formats.
So then the user can decide which seems most appropriate and issue:
$ gcv --input=png-to-vol image.png file.g
It's simple, discoverable, and doesn't require taxonomy awareness other than what the plugins declare. The user may still try all of them, but it'll be in the context of a plugin's immediate description and other available plugins. We can later look into user preferences for default handlers or auto-pathing.
@Christopher So the next logical question I guess is what is needed to make assetimport prioritized over the other tinygltf method. Could just remove the other method since it's crashing if the other works, or does it handle text gltf better in some regard? Otherwise that's a design issue that needs to be sorted out - how to have smart defaulting.
well, if it's just a matter of wanting it to prioritize assetimport over tinygltf, we just need to recognize it as the default 'mime type'. As of yet, gcv isn't advanced enough have smart defaulting or really any notion fallbacks; Only the hard-set default, anything else is up to the user to manually specify
as for why it's crashing or if one is preferable over the other.. I'm not sure
I'd vote for removing tinygltf in favor of assetimport, unless there's something the former can handle that the latter can't.
I think one of us will have to spend a few minutes looking at the implementations to figure that out. I don't recall the one in gcv being different than the gltf-g but there's clearly some difference or change. Looking at the commits, maybe a casualty of refactoring errors.
I naively assumed gcv was only using assetimport as I'd just ran "gcv file.glb file.g". Either way, I do think the default should be made to work, so if assetimport's working I think that's strong enough motivation to default to it over the gltf plugin. Can schedule them and gltf-g for review in the next minor. Maybe do a quick walkthrough.
Last updated: Jan 09 2025 at 00:46 UTC