material.pop breaks mt->mat_nr #28111
Labels
No Label
Interest
Animation & Rigging
Interest
Blender Cloud
Interest
Collada
Interest
Core
Interest
Documentation
Interest
Eevee & Viewport
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
Import and Export
Interest
Modeling
Interest
Modifiers
Interest
Nodes & Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds, Tests & Devices
Interest
Python API
Interest
Rendering & Cycles
Interest
Sculpt, Paint & Texture
Interest
Translations
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Meta
Good First Issue
Meta
Papercut
Module
Add-ons (BF-Blender)
Module
Add-ons (Community)
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender-addons#28111
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
%%%code comment: After the material is removed the old mat_nr assigned to the faces is not remapped. (in material.c::material_pop_id())
In the attached file run the script:
import bpy
ob=bpy.context.object
me=ob.data
me.materials.pop(1)
now the third face (which has a valid material) no longer point to a valid material.
This will mess up with the materials of the faces.%%%
Changed status to: 'Open'
%%%It seems like a simple fix actually. something along: for MFace in mesh: if mat_nr > index mat_nr --;
I guess the material_append_id function is broken too.%%%
%%%attached a patch to fix this%%%
%%%repeating what I said in the mailing list:
"It's a small and simple patch, but I'm checking for specific datablock types in the functions (i.e. if (GS(id->name) == ID_ME) ) and I'm not so confident this is the best way to go. Until now the functions are all dealing with the datablock type in a generic way (e.g. by using give_matarar_id(ID *id)).
An alternative (slightly more elegant) is to add a function give_mesh_id(ID *id) which returns a Mesh or null. Or even a "give_data_id(id, ID_ME)"."%%%
%%%The function material_pop_id duplicates code from object_remove_material_slot, which has code to do this mat_nr remapping. Ideally these function should share as much code as possible, but if you don't want to make too many changes, at least this part code be put in a common function.%%%
%%%Not sure if this is a bug, when writing exporters I had to add in support for out of range material values since this wuold happen from time to time, even though the UI tries to disallow it.
Theres also a case where you may want to rebuild material list without changing the face materials.
So if this behavior is changed I think it should be optional.%%%
%%%Campbell, for one to rebuild a material list you would need a 'replace' function, no? The materials.append takes no "index" parameter. (unless you remove all of them and append them in order. It seems a strange workflow though, even for a hack solution.
imho out of range materials is a bug to be addressed at read time, not a case to be reinforced again here.
Attached a matpop.diff patch for the problem following Brecht instructions (I did it early before your reply).
Note that the current behavior (which removes the material slot AND the material) really seems like a bug.
An alternative is to make the materials.pop() function to remove the material and keep the material slot (and skip material number remapping).%%%
%%%fixed on rev. 38879.
from the log:
create a new parameter for materials.pop() to not remove material slot.
this way the mat_nr is still the old one.
for the default behaviour we now have material remapping (i.e. data_delete_material_index_id(id, index)).
This new function is brought from the material_slot remove function.
While running tests I got some:
Error: Not freed memory blocks: 2
Data from OB len: 24 0x11cc26d88
Data from OB len: 4 0x11cc26de8
I couldn't reproduce though, so I take that the code is fine. If there is a problem I suspect it would in the code for: /* don't remove material slot, only clear it*/ (material.c:603).%%%
Changed status from 'Open' to: 'Resolved'