Primary edit and secondary edit are described at the top of the thread. But I'll sum it up once more anyway:

* Primary: If clicking on unselected terrain the current brush should be applied to the terrain
* Secondary: The texture of the current brush should be set to the terrain texture that was clicked on.

We discussed the terrain texture selection PR before. I believe you found it too complicated to deal with. This is basically about setting (and rendering) the terrain selection. This is needed for the primary edit function, since clicking on a selected piece of terrain will apply the brush texture to the whole selection (we may add a user setting to enable/disable this particular function, since not all users may want to use it).

The brush feature is more or less done, although it's still missing some features (dropdown menu of recently used textures, texture overlay to brush buttons) and if those features aren't yet developed, code needs to be cleaned. I'm gonna give it some time to get some feedback so I can continue development. It's been a good learning process of C++ and Qt, and therefore it's now easier to read other code.

I'm doing research on vfs for texture overlay, and terrain data structures / command system for texture editing. Those tasks are more complicated, and I'm not sure if my skills are yet up to the task. I'll try anyway, and if I make good progress, I'll post a PR. This is after all a superb opportunity for me to learn intermediate to advanced coding skills. Currently in my local branch, I've just got the terraingrid loaded from data, created some framework for new command for modifying land data (although I wonder if some of the existing ones would have been enough).

I would rather not reserve terrain texture editing task for myself, as it's a greatly anticipated feature, and I'm sure there are people out there who could code it better and quicker than me. On the other hand, I have plenty of time to dabble with this, and I'm motivated to learn.

In the above code mId is probably cell id in some form (#X Y) maybe? And instead of DATA_VHGT, texture editing should target DATA_VTEX. As defined in components/esm/loadland.hpp, somewhere down there should be variables uint16_t mTextures[LAND_NUM_TEXTURES], where static const int LAND_NUM_TEXTURES = LAND_TEXTURE_SIZE * LAND_TEXTURE_SIZE, when static const int LAND_TEXTURE_SIZE = 16.

That mTextures data probably needs to be copied into temporary array, then somehow through command system it needs to go back to records. CSMWorld::TouchLandCommand at model/world/commands.cpp is probably a good start for that.

edit: I'm scrambling together something like this to terraintextureedit.cpp... Feeling a bit lost here.

There is something weird wit worldspacehitresult hit (WorldIntersectPoint), it doesn't correlate to map at all. Does it correlate to x-y coordinates of texels/texture maps in object that is hit? In the latter case totally different hit handling is needed. I wonder if PlutonicOverkill got it working here https://github.com/OpenMW/openmw/pull/1414 ... I don't get the coordinate code over there, at least not yet.

edit: The conversion of coordiantes was found from PlutonicOverkills code, using variables hit.worldPos.x() and hit.worldPos.y(). I can now edit textures in single point mode.

edit (to-do): make a deep copy of land data when modifying (mNew), do changes via commands system, enhance circle algorithm, use mouse release to build command macro's instead of just single click editing.

Uhm, lots of stuff. Too much to go into every detail. But I'll try to pick out the important parts.

In data.cpp command addColumn is adding those columns to mLand. I've backtraced that IdCollection holds std::vector<Column<ESXRecordT> *>mColumns, and addColumn uses push_back to append data to that variable. Not quite sure how that vector variable, apparently holding records, work.

It does not. Again, the columns are just a binding layer between the underlying data structure and the Qt tables. They don't hold data. The data is in the mRecords.

That mTextures data probably needs to be copied into temporary array, then somehow through command system it needs to go back to records

Correct.

CSMWorld::TouchLandCommand at model/world/commands.cpp is probably a good start for that.

Its more complicated. Usually you change fields in a table with the ModifyCommand. TouchLand Command modifies the LandTexture records, which (again) do not hold the texture grid. Since the land record and the land texture records must have the same modification state it is necessary to touch the land texture records (and pulling them out of base state) when modifying a Land record that is still in base state.

Please don't ever do that! You are assigning a dynamic allocated object to a local variable. That is basically just a resources leak waiting to happen. Its different with Qt, because Qt has this fancy (and annoying) QObject resources management system. But in generally in C++ this construct is a very bad idea.

Thanks for the video. Very helpful. I was about to test your code myself, but I can already see the remaining issues now.

We don't allow permanently open UI windows like that. The window is supposed to be transient. And the texture dropping is meant to aim for the toolbar button, not the buttons in the window. Also, there are a few transient windows like this already (don't remember exactly which off the top of my head). Maybe you could look at them and see if you can match the style/layout?

After that we should go ahead with the merge (without the texture overlay).

I think there may be an issue with your editing code, but I don't really want to review it on the forum. That's what github is for. I suggest you move your editing code to a separate branch (based on the terraintexturemodebrushes branch) and start a separate pull request.