fix for #7537: When you rotate a slab, it makes one of the material layers fatter than the designated thickness.#7705
fix for #7537: When you rotate a slab, it makes one of the material layers fatter than the designated thickness.#7705theoryshaw wants to merge 2 commits into
Conversation
|
possible fix for #7537 |
…er ordering Three related bugs fixed in the slab material layer set workflow: 1. EditAssignedMaterial (operator.py): Applying a custom offset to one slab instance incorrectly regenerated geometry for ALL slabs sharing the same IfcMaterialLayerSet. Replaced regenerate_from_layer_set (sweeps all users) with per-element regenerate_from_occurence for AXIS3 slabs and targeted recalculate_walls for AXIS2 walls. Each element's IfcMaterialLayerSetUsage attributes are now updated individually before regeneration. 2. slice_layerset_mesh (loader.py): Loader.unit_scale is a class variable only set during full file import, so it was stale (= 1) during live geometry updates on foot-based IFC files. Layer bisect planes were being computed in IFC feet while the mesh was in Blender metres, placing all cuts completely outside the mesh. Fixed by computing unit_scale fresh from the IFC file on each call via ifcopenshell.util.unit.calculate_unit_scale. 3. OffsetFromReferenceLine stale / layer order reversed (slab.py, loader.py): A guard (and custom_offset is None) in change_thickness prevented writing the correct OffsetFromReferenceLine (position.z) to the usage when a custom offset was active. This left the value at 0.0 instead of the actual slab bottom (e.g. -1.0 IFC units for a TOP-reference slab), so the bisect starting point co was at the reference plane rather than the slab bottom, reversing layer assignments or missing layers entirely. Removed the guard — safe because each element has its own IfcMaterialLayerSetUsage instance. Reverted the AXIS3 bisect normal back to (0,0,1) (upward from co at slab bottom) which is correct once OffsetFromReferenceLine is properly set.
Three bugs fixed: 1. EditAssignedMaterial was sweeping all slabs that share a layer set when changing material properties, instead of updating only the selected element's assigned material. 2. slice_layerset_mesh (loader.py): layer bisect positions were scaled incorrectly due to a stale unit_scale and a reversed/missing DirectionSense guard. Now always recalculates unit_scale fresh and correctly applies sense_factor. 3. change_thickness (slab.py): extrusion depth was computed as `thickness / cos(obj.rotation_euler.x)`, which incorrectly scaled ObjectPlacement-rotated slabs (where the extrusion direction is local Z and no scaling is needed). The correct formula is `thickness / extrusion_vec.z`, which handles both ObjectPlacement rotation (extrusion_vec.z ≈ 1.0 → no scale) and ExtrudedDirection tilts (extrusion_vec.z < 1.0 → scale up) uniformly. The resulting slab was 1.414× too thick for 45°-rotated slabs, making both material layers appear fatter than specified. slice_layerset_mesh retains a depth_scale safety factor (extrusion_vec.z × ifc_depth / total_layer_thickness) as a robustness guard for IFC files from other authoring tools where extrusion depth may not match the sum of LayerThicknesses.
64b1061 to
7c738c1
Compare
|
@theoryshaw Is this PR still relavant? I wasn't able to reproduce #7537 |
|
@theoryshaw I see what is going on. See this commit for the explanation. That's why x angle is locked in Blender. |
|
Yes it's still relevant from my perspective. If you open the test file |
|
@theoryshaw Just a heads up that I'm going to start working on this. |
|
Sounds good. Were you just going to review this pr, or come up with something from scratch? |
|
@theoryshaw A bit of both, I guess. I'm just trying to figure out the best approach since this part of the code is very prone to unintended consequences. |
|
@theoryshaw Could you test now after the latest commits? There are a few things about the PR that I didn't fully comprehend. I'm not sure if it is necessary to change loader.py and the way the layer set is regenerated. Maybe I missed something. Let me know what you think. |
|
@brunoperdigao cool, it seems to work. I'm going to close this PR, so it doesn't build to BonsaiPR then. Will keep testing via that build. |
Fix slab layer geometry for rotated and angled slabs
Three bugs fixed:
EditAssignedMaterial was sweeping all slabs that share a layer set
when changing material properties, instead of updating only the
selected element's assigned material.
slice_layerset_mesh (loader.py): layer bisect positions were scaled
incorrectly due to a stale unit_scale and a reversed/missing
DirectionSense guard. Now always recalculates unit_scale fresh and
correctly applies sense_factor.
change_thickness (slab.py): extrusion depth was computed as
thickness / cos(obj.rotation_euler.x), which incorrectly scaledObjectPlacement-rotated slabs (where the extrusion direction is
local Z and no scaling is needed). The correct formula is
thickness / extrusion_vec.z, which handles both ObjectPlacementrotation (extrusion_vec.z ≈ 1.0 → no scale) and ExtrudedDirection
tilts (extrusion_vec.z < 1.0 → scale up) uniformly. The resulting
slab was 1.414× too thick for 45°-rotated slabs, making both
material layers appear fatter than specified.
slice_layerset_mesh retains a depth_scale safety factor
(extrusion_vec.z × ifc_depth / total_layer_thickness) as a
robustness guard for IFC files from other authoring tools where
extrusion depth may not match the sum of LayerThicknesses.