Open m-7761 opened 5 years ago
Blender has heavily customizable layouts so it makes sense to save them. This doesn't seem true for Misfit/Maverick Model 3D (grid size, view background color (to do), model rendering settings, viewport camera positions?).
Does anyone else who views the model care about these? It's annoying to open a random Blender model and try to figure out how do I just look at the model in regular mode! Also it seems like it would cause interop problems if multiple editors used .mm3d but different view rendering settings.
It could be useful to save the view state as a local file as filename.maverickview
or in the global config file something (not part of mm3d format) so user can easily save and resume later. It would be easier to leave out of svn/git repositories if it's not included in the .mm3d file itself. (I have to manually remove local export information that Inkscape saves in .svg. I don't want to have to scrap local data from .mm3d as well. Though .mm3d will silently end up using full paths instead of relative paths if image in different directory which is also a local data annoyance.)
It's not something I'm interested in working on at this time.
I'm mainly pointing out it's a bug in the File->New system, and other multi-window pathways. If I need to extend the mm3d format, it will be better if it agrees with other implementations. (I'm looking for comment on how to proceed, not will you proceed.)
I'm trying to implement ModelViewport without depending on UI code. TextureWidget too.
I feel like all of the config stuff accessed by modelviewport.cc logically belong inside the model data. If it were there, it would be easier to implement.
I think the viewport layout and camera coordinates should also be saved in the model file. The layout is part of the existing config file. Whereas view coordinates aren't saved. In many software the views are synonomous with cameras.
Pretty much everything I've mentioned falls into the View category in the menu. I think it makes sense to think of that menu as the dynamic menu, and locate all of its states in the model files.
Many of the menus have special qualities, like the Tools menu is Tool objects, and the Geometry menu is Command objects.
The View menu is the only menu that holds a state. Well, I've moved the Snap submenu into the View menu, since I felt it fits better there. It holds a state.
The other menus are static... except for the Animation menu has items enabled and disabled depending on if it's in animation mode. Being static means that they are functionally global objects, shared by all main-windows.
The incoherence bug this Issue describes is limited to the View+Snap menu. I think moving these settings into the model file would solve both this problem and abstracting ModelViewport from UI dependency elegantly.
EDITED: I probably should have mentioned that I'm right now torn, since I ripped out the super ugly "preferences" code in favor of a simple solution that looks like config.get("ui_3dgrid_xy",false)
that is a simple wrapper around wxWidget's cross-platform system-configuration facility. I think Qt probably has a system-config facility too, that would save MM3D from implementing this itself. The only trouble is this makes the config part of the UI/platform dependent code. I don't see that as a problem, but I want to explain why it's a problem for modelviewport.cc to interact with this facility. (It's a larger, more complicated class, that is not trivial to implement in terms of an alternative UI.)
Update: I'm currently removing code that I consider part of the "implui" component from the "depui" component. I think the "depui" part should be rolled into "mm3dcore" and removed.
Part of how I did this involved just defining some methods and leaving them unimplemented, so that the linker finds them in the "implui" code. I think that is the simplest strategy.
modelviewport.cc uses the config system a lot. I think that config should be part of "implui". In one case (how joints are drawn) in the "tools" component I added a method to Model to remember the last used joint mode that is not hidden.
However, the joint setting is part of the Views menu. In the case of modelviewport.cc there are many settings like the joint setting. I feel like these settings should go into Model also, like the joint setting. (Note: many of the render settings probably are already part of Model.)
Whether or not they are saved to the file... I think they should be, but that can be a preference... plus it could be more work to implement.
By putting them into Model, saved or not, they would at least solve the multi-main window bug that is at the heart of this issue.
I feel like it's not appropriate to build a direct bridge to the config system. That would be a hack. And likewise the libmm3d and mm3dcore code should operate independently.
EDITED: For the record, I think that if these are saved, that they shouldn't be subject to undo/redo. And also, I think it would be an improvement if selecting things doesn't cause the opened file to prompt for saving. Blender does that, and I think it does more harm than good, since it's not normative, and it leaves you wracking your brain for if you actually modified it or not.
My prescription to normalize this is to change setDrawJoints to a bool value, like setDrawProjections. And add setDrawLines. And add setDrawOptions that sets a bitmask of DO_BADTEX and DO_CULLBACKFACES etc, and add DO_BONES to that. Remove DrawJointModeE.
Preferably switch setCanvasDrawMode, etc. over to using the same Model enum.
Add similar settings to Model for snap modes, and for viewportsettings stuff.
All that leaves is the viewports layout. I think it's not a problem bug wise to leave out, since it doesn't leak across windows.
Here (in no particular order) is the model.h code I went with for this, just for review:
//https://github.com/zturtleman/mm3d/issues/56
void setDrawOption(int mode, bool set)
{
if(set) m_drawOptions|=mode;
if(!set) m_drawOptions&=~mode;
}
int getDrawOptions()const{ return m_drawOptions; };
void setDrawJoints(bool o){ m_drawJoints = o; }
bool getDrawJoints()const{ return m_drawJoints; }
void setDrawSelection(bool o){ m_drawSelection = o; }
bool getDrawSelection()const{ return m_drawSelection; }
//FIX ME
//https://github.com/zturtleman/mm3d/issues/63
//#ifdef MM3D_EDIT
//TextureWidget API (texwidget.cc)
void setSelectedUv(const std::vector<int> &uvList);
void getSelectedUv(std::vector<int> &uvList)const;
void clearSelectedUv();
//https://github.com/zturtleman/mm3d/issues/56
//ModelViewport API (modelviewport.cc)
ViewportUnits &getViewportUnits(){ return m_viewportUnits; }
//#endif
//https://github.com/zturtleman/mm3d/issues/56
struct ViewportUnits
{
enum{ VertexSnap=1,UnitSnap=2 };
int snap;
enum{ BinaryGrid=0,DecimalGrid,FixedGrid };
int grid;
int lines3d;
double inc,inc3d;
int xyz3d; //1|2|4
ViewportUnits(){ memset(this,0x00,sizeof(*this)); }
};
// Drawing options. These are defined as powers of 2 so that they
// can be combined with a bitwise OR.
enum
{
DO_NONE = 0x00, // FLAT mode
DO_TEXTURE = 0x01,
DO_SMOOTHING = 0x02, // Normal smoothing/blending between faces
DO_WIREFRAME = 0x04,
DO_BADTEX = 0x08, // Render bad textures,or render as no texture
DO_ALPHA = 0x10, // Do alpha blending
DO_BACKFACECULL = 0x20, // Do not render triangles that face away from the camera
DO_BONES = 0x40, //2019 //Removing DrawJointModeE
};
//REMOVE ME
/*https://github.com/zturtleman/mm3d/issues/56
enum DrawJointModeE
{
JOINTMODE_NONE = 0,
JOINTMODE_LINES,
JOINTMODE_BONES,
JOINTMODE_MAX
};*/
Mainly these changes just bring these other settings in line with the getDrawJoints and getDrawProjections settings. The joints one is changed to a bool
.
Model::draw is made to add m_drawOptions to its mode parameter. It just adds culling and the bad-texture bits. Those are things that are cumbersome to pass in manually.
Of course, a lot of code must be changed to accommodate this change. This fixes the multi-window bug at the heart of this ticket. None of these settings are saved. But they persist through a window session.
These constitute the dynamic settings. So instead of getting these settings from the config file they are got from the Model. And when the config is changed, both it and the model must be changed.
Snapping is lumped into the viewport-settings structure. I think this is simple enough to agree upon.
Do you care to draw up a plan to extend the mm3d file to facilitate this? Currently the multi-window system doesn't reflect the correct configuration states. I'm not sure it would be desirable if it did. The larger problem is those global states should be local states. It would be better if they at least stayed consistent for a window session. But the simpler approach I believe is to store them in the model, as Blender does.
Under Blender there is a Default file used by New. And an Import option that pulls the data into the current session, instead of dropping it. Oddly Blender doesn't support that with its own Blend files. Not easily anyway. I think this is a good system.
I would recommend using Close to load the default file into the current window, or New to make a new window. (Something else I think might be nice, is if multiple models can coexist in tabs. Like a multi-model file. Using tabs the models can be seen together (i.e. for reference) but kept apart at the same time. It could be a basis for instancing.)
P.S. I think what would be a good niche is software that supports lots of kind of animation without limits. And excels at converting the complex model into a simple morph-target animation. That is, take models with lots of kind of animation strategies, but reduce them in the end as a file export step to a universal representation, that is just a quality morph-target format, for runtimes to use. I think morph-target animation is actually the future for anything like video games that aren't about astronomical polygon counts. It's easy to do the animation on multi-core CPUs today. And it's easy to render them in batches. Whereas other animation types can't render a lot at once--can't do the whole rig/multiple rigs--and can't do arbitrary animations.