introduce detect_text() and friends

This commit is contained in:
jrkb 2025-05-25 14:16:15 +02:00
parent 7a034efd1c
commit c27cf41368
2 changed files with 423 additions and 147 deletions

View file

@ -451,7 +451,7 @@ class ABC3D_PT_TextPlacement(bpy.types.Panel):
@classmethod
def poll(self, context):
if (
type(context.active_object) != type(None)
context.active_object is not None
and context.active_object.type == "CURVE"
):
self.can_place = True
@ -502,8 +502,8 @@ class ABC3D_PT_TextManagement(bpy.types.Panel):
for c in t.text_object.children:
if (
len(c.users_collection) > 0
and not isinstance(c.get(f"{utils.prefix()}_linked_textobject"), None)
and c.get(f"{utils.prefix()}_linked_textobject") == t.text_id
and not isinstance(c.get(f"{utils.prefix()}_text_id"), None)
and c.get(f"{utils.prefix()}_text_id") == t.text_id
):
remove_me = False
# not sure how to solve this reliably atm,
@ -542,14 +542,14 @@ class ABC3D_PT_TextManagement(bpy.types.Panel):
remove_list.append(i)
for i in remove_list:
if type(abc3d_data.available_texts[i].text_object) != type(None):
if abc3d_data.available_texts[i].text_object is not None:
mom = abc3d_data.available_texts[i].text_object
def delif(o, p):
if p in o:
del o[p]
delif(mom, f"{utils.prefix()}_linked_textobject")
delif(mom, f"{utils.prefix()}_text_id")
delif(mom, f"{utils.prefix()}_font_name")
delif(mom, f"{utils.prefix()}_face_name")
delif(mom, f"{utils.prefix()}_font_size")
@ -736,11 +736,11 @@ class ABC3D_PT_TextPropertiesPanel(bpy.types.Panel):
# and bpy.context.object.select_get():
a_o = bpy.context.active_object
if a_o is not None:
if f"{utils.prefix()}_linked_textobject" in a_o:
text_index = a_o[f"{utils.prefix()}_linked_textobject"]
if f"{utils.prefix()}_text_id" in a_o:
text_index = a_o[f"{utils.prefix()}_text_id"]
return bpy.context.scene.abc3d_data.available_texts[text_index]
elif a_o.parent is not None and f"{utils.prefix()}_linked_textobject" in a_o.parent:
text_index = a_o.parent[f"{utils.prefix()}_linked_textobject"]
elif a_o.parent is not None and f"{utils.prefix()}_text_id" in a_o.parent:
text_index = a_o.parent[f"{utils.prefix()}_text_id"]
return bpy.context.scene.abc3d_data.available_texts[text_index]
else:
for t in bpy.context.scene.abc3d_data.available_texts:
@ -752,9 +752,9 @@ class ABC3D_PT_TextPropertiesPanel(bpy.types.Panel):
def get_active_glyph_properties(self):
a_o = bpy.context.active_object
if a_o is not None:
if (f"{utils.prefix()}_linked_textobject" in a_o
if (f"{utils.prefix()}_text_id" in a_o
and f"{utils.prefix()}_glyph_index" in a_o):
text_index = a_o[f"{utils.prefix()}_linked_textobject"]
text_index = a_o[f"{utils.prefix()}_text_id"]
glyph_index = a_o[f"{utils.prefix()}_glyph_index"]
return bpy.context.scene.abc3d_data.available_texts[text_index].glyphs[glyph_index]
else:
@ -795,13 +795,13 @@ class ABC3D_PT_TextPropertiesPanel(bpy.types.Panel):
@classmethod
def poll(self, context):
return self.get_active_text_properties(self) is not None
try:
return self.get_active_text_properties(self) is not None
except IndexError:
return False
def draw(self, context):
layout = self.layout
wm = context.window_manager
scene = context.scene
abc3d_data = scene.abc3d_data
props = self.get_active_text_properties()
glyph_props = self.get_active_glyph_properties()
@ -1190,6 +1190,11 @@ class ABC3D_OT_RemoveText(bpy.types.Operator):
description="Remove both ABC3D text functionality and the objects/meshes",
default=True,
)
remove_custom_properties: bpy.props.BoolProperty(
name="Remove Custom Properties",
description="Remove ABC3D custom properties of objects",
default=True,
)
def invoke(self, context, event):
wm = context.window_manager
@ -1206,26 +1211,27 @@ class ABC3D_OT_RemoveText(bpy.types.Operator):
return {"CANCELLED"}
i = abc3d_data.active_text_index
if type(abc3d_data.available_texts[i].text_object) != type(None):
if abc3d_data.available_texts[i].text_object is not None:
mom = abc3d_data.available_texts[i].text_object
def delif(o, p):
if p in o:
del o[p]
if self.remove_custom_properties:
def delif(o, p):
if p in o:
del o[p]
delif(mom, f"{utils.prefix()}_type")
delif(mom, f"{utils.prefix()}_linked_textobject")
delif(mom, f"{utils.prefix()}_font_name")
delif(mom, f"{utils.prefix()}_face_name")
delif(mom, f"{utils.prefix()}_font_size")
delif(mom, f"{utils.prefix()}_letter_spacing")
delif(mom, f"{utils.prefix()}_orientation")
delif(mom, f"{utils.prefix()}_translation")
delif(mom, f"{utils.prefix()}_offset")
delif(mom, f"{utils.prefix()}_type")
delif(mom, f"{utils.prefix()}_text_id")
delif(mom, f"{utils.prefix()}_font_name")
delif(mom, f"{utils.prefix()}_face_name")
delif(mom, f"{utils.prefix()}_font_size")
delif(mom, f"{utils.prefix()}_letter_spacing")
delif(mom, f"{utils.prefix()}_orientation")
delif(mom, f"{utils.prefix()}_translation")
delif(mom, f"{utils.prefix()}_offset")
if self.remove_objects:
remove_list = []
for g in abc3d_data.available_texts[i].glyphs:
if type(g) != type(None):
if g is not None:
remove_list.append(g.glyph_object)
butils.simply_delete_objects(remove_list)
@ -1787,18 +1793,61 @@ def compare_text_object_with_object(t, o, strict=False):
def detect_text():
lock_depsgraph_updates(auto_unlock_s=-1)
print("DETECT TEXT:: begin")
scene = bpy.context.scene
abc3d_data = scene.abc3d_data
for o in scene.objects:
if o[f"{utils.prefix()}_type"] == "textobject":
linked_textobject = int(o[f"{utils.prefix()}_linked_textobject"])
required_keys = [
"type",
"text_id",
"font_name",
"face_name",
"text",
]
objects = scene.objects
for o in objects:
print(f" {o.name=}")
valid = True
for key in required_keys:
if butils.get_key(key) not in o:
# print(f" key {butils.get_key(key)} not there")
valid = False
break
if not valid:
continue
print(" object may be valid textobject")
if o[butils.get_key("type")] == "textobject":
print(" {o.name=} a textobject")
print(f" {type(o)=} {o.name=}")
current_text_id = int(o[butils.get_key("text_id")])
if (
len(abc3d_data.available_texts) > linked_textobject
and abc3d_data.available_texts[linked_textobject].text_object == o
len(abc3d_data.available_texts) > current_text_id
and abc3d_data.available_texts[current_text_id].text_object == o
):
t = abc3d_data.available_texts[linked_textobject]
a = test_availability(o["font_name"], o["face_name"], o["text"])
butils.transfer_blender_object_to_text_properties(o, t)
print(" {o.name=} seems fine")
pass
# t = abc3d_data.available_texts[text_id]
# a = test_availability(o[butils.get_key("font_name")],
# o[butils.get_key("face_name")],
# o[butils.get_key("text")])
# butils.transfer_text_object_to_text_properties(o, t)
else:
butils.link_text_object_with_new_text_properties(o, scene)
# print(" {o.name=} is a duplicate")
# text_id = butils.find_free_text_id()
# t = abc3d_data.available_texts.add()
# t["text_id"] = text_id
# print(f" found free {text_id=}")
# print(" preparing text")
# butils.prepare_text(o[butils.get_key("font_name")],
# o[butils.get_key("face_name")],
# o[butils.get_key("text")])
# print(" prepared text, transferring text object")
# t.text_object = o
# butils.transfer_text_object_to_text_properties(o, t)
# print(" {o.name=} transerred text object")
print("DETECT TEXT:: end")
unlock_depsgraph_updates()
def load_used_glyphs():
@ -1850,21 +1899,25 @@ def on_frame_changed(self, dummy):
butils.set_text_on_curve(t)
depsgraph_updates_locked = False
depsgraph_updates_locked = 0
def unlock_depsgraph_updates():
global depsgraph_updates_locked
depsgraph_updates_locked = False
depsgraph_updates_locked -= 1
def lock_depsgraph_updates():
def lock_depsgraph_updates(auto_unlock_s=1):
global depsgraph_updates_locked
depsgraph_updates_locked = True
if bpy.app.timers.is_registered(unlock_depsgraph_updates):
bpy.app.timers.unregister(unlock_depsgraph_updates)
bpy.app.timers.register(unlock_depsgraph_updates, first_interval=1)
depsgraph_updates_locked += 1
if auto_unlock_s >= 0:
if bpy.app.timers.is_registered(unlock_depsgraph_updates):
bpy.app.timers.unregister(unlock_depsgraph_updates)
bpy.app.timers.register(unlock_depsgraph_updates, first_interval=auto_unlock_s)
def are_depsgraph_updates_locked():
global depsgraph_updates_locked
return depsgraph_updates_locked > 0
import time
@ -1872,29 +1925,44 @@ import time
@persistent
def on_depsgraph_update(scene, depsgraph):
global depsgraph_updates_locked
if not bpy.context.mode.startswith("EDIT") and not depsgraph_updates_locked:
print("DEPSGRAPH:: BEGIN")
if not bpy.context.mode.startswith("EDIT") and not are_depsgraph_updates_locked():
for u in depsgraph.updates:
if (
f"{utils.prefix()}_linked_textobject" in u.id.keys()
and f"{utils.prefix()}_type" in u.id.keys()
and u.id[f"{utils.prefix()}_type"] == "textobject"
butils.get_key("text_id") in u.id.keys()
and butils.get_key("type") in u.id.keys()
and u.id[butils.get_key("type")] == "textobject"
):
linked_textobject = u.id[f"{utils.prefix()}_linked_textobject"]
if (
u.is_updated_geometry
and len(scene.abc3d_data.available_texts) > linked_textobject
):
lock_depsgraph_updates()
print("DEPSGRAPH:: we have a textobject")
text_id = u.id[butils.get_key("text_id")]
if u.is_updated_geometry:
print(" updated geometry is true")
print(f" is {len(scene.abc3d_data.available_texts)} bigger than {text_id=} is true?")
# butils.detect_texts()
if len(scene.abc3d_data.available_texts) > text_id:
print(" YES")
print(" is ? text object is not u.id")
if scene.abc3d_data.available_texts[text_id].text_object != u.id:
print(" yes")
else:
print(" no")
else:
print(" NO")
print("DEPSGRAPH:: done textobject")
# lock_depsgraph_updates()
def later():
if butils.lock_depsgraph_update_n_times <= 0:
butils.set_text_on_curve(
scene.abc3d_data.available_texts[linked_textobject]
)
elif butils.lock_depsgraph_update_n_times <= 0:
butils.lock_depsgraph_update_n_times -= 1
# def later():
# if butils.lock_depsgraph_update_n_times <= 0:
# butils.set_text_on_curve(
# scene.abc3d_data.available_texts[text_id]
# )
# elif butils.lock_depsgraph_update_n_times <= 0:
# butils.lock_depsgraph_update_n_times -= 1
butils.run_in_main_thread(later)
# butils.run_in_main_thread(later)
if are_depsgraph_updates_locked():
print(" L O C K E D")
print("DEPSGRAPH:: done")
def register():