WorldEdit

WorldEdit

43M Downloads

Place axis-aware blocks: Optimize for density of block at the axis-pointing surface

mk-pmb opened this issue ยท 2 comments

commented

The Problem

I'm building grids of oak logs and chains in water or air. It's tedious to select lots of small regions in order to set the correct orientation.

A Solution

My concept of block density is: void < air < non-air liquid < partial block < transparent full block < opaque full block.

I'd like to give my preference for whether the axis-aligned sides (oak log rings, chain ends) should prefer higher or lower density, and a priority list of fixed directions that decides in the case the density preference can be satisfied equally by multiple axes.
The measurement of neighboring blocks' density shall compare the block that would be the neighbor after placement.
Example: When placing a straight line of chain floating in air, it would compare to the to-be-placed chains and thus a preference for higher density would connect all of them.

The syntax could be something like //replace glass oak_log[axis=Dxz] where D means high density (d = low density). If multiple axes will achieve it: If one of them is the X axis, use [axis=x]. Otherwise, if the Z axis is one of the equally-good axes, use [axis=z]. If there's still ambiguity, pick any of the good axes. (In this example, there should only be one remaining choice anyway.)

Alternatives

No response

Anything Else?

No response

commented

You're going to have to clarify this more, maybe with some pictures. It's not clear how your definition of density applies to an axis.

Moreover, this sounds incredibly specific and complex, and might be better suited as an expression mask.

commented

What kind of picture would help? I assume, a screenshot of my glass construction that shall be converted?

I made a simplified version of just the framework without surroundings and without the interiors of the rooms:

We'll need numerical values for the densities. I have no experience what would be good numbers, but for the explanation in this post, these will work well enough:

Density Block category Relevant examples
0 void
1 air air, cave_air
2 non-air liquid water, lava
4 partial block chain, oak_fence
8 transparent full block glass, glowstone
16 opaque full block oak_log

Some users will probably want an easy way to configure their own values, but that's not part of this feature request, because for me it's easy to patch and recompile.

Now assume I have a cuboid selection that includes the blocks that are marked with letters, and I issue the suggested command: //replace glass oak_log[axis=Dxz]

WE would need to replace block A. To do so, it assesses a score for each possible axis value.

  • X axis: The neighbors on axis-aligned surfaces would be the corner glowstone (density 8) and block B, which after placings would be an oak log (density 16), giving a combined density score of 8+16 = 24.
  • Y axis: The neighbors would be the water below (2) and the air above (1), sum = 3
  • Z axis: The neighbors would be the water in front (2) and the water behind (2), sum = 4.
  • My preference is high density, so X axis wins. A will become oak_log[axis=x].

Block B: Same except the X neighbors are A and C, which will both become oak logs (16), sum = 32, winning with even more of a margin. B will become oak_log[axis=x].

Block K: For both X and Z axis, the neighbors are air (1) so their sum is 2. Y axis is the same situation as A but rotated: The neighbors are the corner glowstone (8) and block L which will become oak log (16), sum = 24. K will become oak_log[axis=y].

Block L: For both X and Z axis, the neighbors are air (1) so their sum is 2. Y axis neighbors (K and M) will become oak log (16) so their sum is 32. Y axis wins, L will become oak_log[axis=y].

Block P: Like A but rotated, will become oak_log[axis=z].

Block Q: Like B but rotated, will become oak_log[axis=z].

If I were to add glowstone to the //replace pattern, WE would have to also replace the corner glowstone.

  • X axis: Left neighbor is water (2), right neighbor is block A and will become oak log (16), sum = 18.
  • Y axis: Glass above and below will become oak log (8 each) = 16.
  • Z axis: Water behind (2), block P in front will become oak log (16), sum = 18.
  • Thus, X and Z axes are both equally good choices, and we need to use the priority list.
  • The first priority candidate is x, and the X axis is eligible, so it instantly wins. The glowstone will be replaced with oak_log[axis=x].

I haven't checked inner corners yet, but I'm very optimistic that with this algorithm, selecting the entire structure and applying //replace glass,glowstone oak_log[axis=Dxz] (Edit: probably rather Dyx) will place solid oak pillars and connect them horizontally using oak trunk segments of length 9, giving a result that would perfectly //rotate 90 into itself.