detect textobject and allow primitive duplication

This commit is contained in:
jrkb 2025-05-25 20:36:46 +02:00
parent 10e57dd46a
commit 88cfaf3be7
2 changed files with 151 additions and 28 deletions

View file

@ -137,9 +137,12 @@ class ABC3D_glyph_properties(bpy.types.PropertyGroup):
def update_callback(self, context):
if self.text_id >= 0:
butils.set_text_on_curve(
context.scene.abc3d_data.available_texts[self.text_id]
)
# butils.set_text_on_curve(
# context.scene.abc3d_data.available_texts[self.text_id]
# )
t = butils.get_text_properties(self.text_id)
if t is not None:
butils.set_text_on_curve(t)
glyph_id: bpy.props.StringProperty(maxlen=1)
text_id: bpy.props.IntProperty(
@ -259,6 +262,7 @@ class ABC3D_text_properties(bpy.types.PropertyGroup):
)
distribution_type: bpy.props.StringProperty()
glyphs: bpy.props.CollectionProperty(type=ABC3D_glyph_properties)
actual_text: bpy.props.StringProperty()
class ABC3D_data(bpy.types.PropertyGroup):
@ -1942,8 +1946,8 @@ def on_depsgraph_update(scene, depsgraph):
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:
text_properties = scene.abc3d_data.available_texts[text_id]
text_properties = butils.get_text_properties(text_id)
if text_properties is not None:
print(" YES")
print(f" is ? {text_properties.text_object.name=} is {u.id.name=}")
if text_properties.text_object == u.id.original:

165
butils.py
View file

@ -927,44 +927,120 @@ def get_glyph(glyph_id, font_name, face_name, notify_on_replacement=False):
return glyph_tmp.original
def transfer_text_object_to_text_properties(o, text_properties, id_from_text_properties=True):
def get_text_properties(text_id, scene = None):
if scene is None:
scene = bpy.context.scene
abc3d_data = scene.abc3d_data
for t in abc3d_data.available_texts:
if text_id == t.text_id:
return t
return None
def transfer_text_object_to_text_properties(text_object, text_properties, id_from_text_properties=True):
print("TRANSFER:: BEGIN")
print(f" {text_properties['text_id']=}")
print(f" {type(o)=}")
print(f" {type(text_object)=}")
possible_brother_text_id = text_object[get_key("text_id")] if get_key("text_id") in text_object else ""
for key in text_object_keys:
if key in ignore_keys_in_text_object_comparison:
continue
object_key = get_key(key)
if id_from_text_properties and key == "text_id":
o[object_key] = text_properties["text_id"]
text_object[object_key] = text_properties["text_id"]
print(f" {object_key} <= {key}")
else:
text_object_property = o[object_key] if object_key in o else False
text_object_property = text_object[object_key] if object_key in text_object else False
if text_object_property is not False:
print(f" {object_key} => {key}")
text_properties[key] = text_object_property
print(f" {dict(text_properties)=}")
print(f" {text_properties['offset']=}")
unfortunate_children = o.children
def kill_children():
completely_delete_objects(unfortunate_children)
run_in_main_thread(kill_children)
# found_glyphs_with_indices = []
# for glyph_object in o.children:
# if is_glyph_object(glyph_object):
# if "glyph_index" in glyph_object:
# found_glyphs_with_indices.append(glyph_object)
if len(text_object.children) == 0:
print("could be duplicate?")
if possible_brother_text_id != text_properties["text_id"] and possible_brother_text_id != "":
pass
found_reconstructable_glyphs = False
glyph_objects_with_indices = []
required_keys = [
"glyph_index",
"glyph_id",
"type"
]
for glyph_object in text_object.children:
if is_glyph_object(glyph_object):
has_required_keys = True
for key in required_keys:
if get_key(key) not in glyph_object:
has_required_keys = False
if has_required_keys:
inner_node = None
glyph_id = glyph_object[get_key("glyph_id")]
for c in glyph_object.children:
if c.name.startswith(f"{glyph_id}_mesh"):
inner_node = c
if inner_node is not None:
glyph_objects_with_indices.append(glyph_object)
glyph_objects_with_indices.sort(key=lambda g: g[get_key("glyph_index")])
print(f" {glyph_objects_with_indices=}")
text = ""
for g in glyph_objects_with_indices:
text += g[get_key("glyph_id")]
is_good_text = False
if len(text) > 0:
if text == text_properties.text:
is_good_text = True
print(f"{text=} is a good text because it is the same")
else:
availability = Font.test_availability(text_properties.font_name, text_properties.face_name, text_properties.text)
AVAILABILITY = Font.test_availability(text_properties.font_name, text_properties.face_name, text_properties.text.swapcase())
t_text = text_properties.text
for c in availability["missing"]:
t_text = t_text.replace(c, "")
for c in AVAILABILITY["missing"]:
t_text = t_text.replace(c, "")
if len(t_text) == len(text):
print(f"{text=} is a good text because it is the same considering what is possible")
is_good_text = True
if is_good_text:
print(" GOOD TEXT")
# for glyph_index, glyph_object in enumerate(glyph_objects_with_indices):
# print(f"{glyph_index}: {glyph_object}")
# if glyph_index == glyph_object[get_key("glyph_index")]:
# print("yeey glyph_index matches")
# else:
# completely_delete_objects([glyph_object])
# print("nooo glyph_idex macthes not")
# found_reconstructable_glyphs = True
text_properties.actual_text = text
text_properties.glyphs.clear()
prepare_text(text_properties.font_name, text_properties.face_name, text)
fail_after_all = False
for glyph_index, glyph_object in enumerate(glyph_objects_with_indices):
glyph_id = glyph_object[get_key("glyph_id")]
# glyph_tmp = Font.get_glyph(text_properties.font_name,
# text_properties.face_name,
# glyph_id)
# glyph = glyph_tmp.original
glyph_properties = text_properties.glyphs.add()
transfer_glyph_object_to_glyph_properties(glyph_object, glyph_properties)
glyph_properties["glyph_object"] = glyph_object
glyph_properties["glyph_index"] = glyph_index
inner_node = None
for c in glyph_object.children:
if c.name.startswith(f"{glyph_id}_mesh"):
inner_node = c
print(f"found inner node {inner_node.name=} for {glyph_id=}")
if inner_node is None:
fail_after_all = True
pass
glyph_properties["glyph_object"] = glyph_object
if not fail_after_all:
found_reconstructable_glyphs = True
# found_glyphs_with_indices.sort(key=lambda g: g["glyph_index"])
# text = ""
# for g in found_glyphs_with_indices:
# text += g["glyph_id"]
# if len(text_properties.glyphs) == len(text):
# for g in found_glyphs_with_indices:
# i = g["glyph_index"]
# gp = text_properties.glyphs[i]
# if gp["glyph_id"] == g["glyph_id"] or gp["glyph_id"] == g["glyph_id"].swapcase():
# if "alternate" in g:
@ -990,6 +1066,18 @@ def transfer_text_object_to_text_properties(o, text_properties, id_from_text_pro
# # if object_key in g:
# # gp[key] = g[object_key]
if not found_reconstructable_glyphs:
print("KILL THE GLYPHS")
text_properties.actual_text = ""
text_properties.glyphs.clear()
unfortunate_children = text_object.children
print("KILL THE CHILDREN")
completely_delete_objects(unfortunate_children)
def kill_children():
print("KILL THE CHILDREN")
completely_delete_objects(unfortunate_children)
run_in_main_thread(kill_children)
if "font_name" in text_properties and "face_name" in text_properties:
font_name = text_properties["font_name"]
face_name = text_properties["face_name"]
@ -1004,7 +1092,7 @@ def link_text_object_with_new_text_properties(text_object, scene=None):
text_id = find_free_text_id()
text_properties = scene.abc3d_data.available_texts.add()
text_properties["text_id"] = text_id
text_object[get_key("text_id")] = text_id
# text_object[get_key("text_id")] = text_id
print(f" found free {text_id=}")
print(" preparing text")
prepare_text(text_object[get_key("font_name")],
@ -1057,31 +1145,52 @@ def transfer_properties_to_glyph_object(text_properties, glyph_properties, glyph
glyph_object[get_key("type")] = "glyph"
glyph_object[get_key("text_id")] = text_properties["text_id"]
def transfer_glyph_object_to_glyph_properties(glyph_object, glyph_properties):
for key in glyph_object_keys:
if key in ignore_keys_in_glyph_object_transfer:
continue
glyph_properties[key] = glyph_object[get_key(key)]
glyph_properties["text_id"] = glyph_object[get_key("text_id")]
import inspect
def would_regenerate(text_properties):
if len(text_properties.text) != len(text_properties.glyphs):
print("REGENERATE?")
if len(text_properties.actual_text) != len(text_properties.glyphs):
print(inspect.currentframe().f_lineno)
return True
if len(text_properties.glyphs) == 0:
print(inspect.currentframe().f_lineno)
return True
for i, g in enumerate(text_properties.glyphs):
if not hasattr(g.glyph_object, "type"):
print(inspect.currentframe().f_lineno)
return True
elif g.glyph_object.type != "EMPTY":
print(inspect.currentframe().f_lineno)
return True
# check if perhaps one glyph was deleted
elif g.glyph_object is None:
print(inspect.currentframe().f_lineno)
return True
elif g.glyph_object.parent is None:
print(inspect.currentframe().f_lineno)
return True
elif g.glyph_object.parent.users_collection != g.glyph_object.users_collection:
print(inspect.currentframe().f_lineno)
return True
elif len(text_properties.text) > i and g.glyph_id != text_properties.text[i]:
print(inspect.currentframe().f_lineno)
return True
elif len(text_properties.text) > i and (
g.glyph_object[f"{utils.prefix()}_font_name"] != text_properties.font_name
or g.glyph_object[f"{utils.prefix()}_face_name"]
!= text_properties.face_name
):
print(inspect.currentframe().f_lineno)
return True
print("NOT REGENERATE")
return False
@ -1123,6 +1232,9 @@ def parent_to_curve(o, c):
def set_text_on_curve(text_properties, reset_timeout_s=0.1, reset_depsgraph_n=4, can_regenerate=False):
# for i in range (0, 42):
# print("WATCH OUT, WE DO NOT SET THE TEXT ATM")
# return False
"""set_text_on_curve
An earlier reset cancels the other.
@ -1160,6 +1272,8 @@ def set_text_on_curve(text_properties, reset_timeout_s=0.1, reset_depsgraph_n=4,
# mom.data.use_path = True
regenerate = can_regenerate and would_regenerate(text_properties)
if regenerate:
print("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRREGENERATE")
# if we regenerate.... delete objects
if regenerate and text_properties.get("glyphs"):
@ -1178,6 +1292,7 @@ def set_text_on_curve(text_properties, reset_timeout_s=0.1, reset_depsgraph_n=4,
is_command = False
previous_spline_index = -1
actual_text = ""
for i, c in enumerate(text_properties.text):
face = Font.fonts[text_properties.font_name].faces[text_properties.face_name]
scalor = face.unit_factor * text_properties.font_size
@ -1247,6 +1362,7 @@ def set_text_on_curve(text_properties, reset_timeout_s=0.1, reset_depsgraph_n=4,
glyph_properties["glyph_id"] = glyph_id
glyph_properties["text_id"] = text_properties.text_id
glyph_properties["letter_spacing"] = 0
actual_text += glyph_id
############### NODE SCENE MANAGEMENT
@ -1397,6 +1513,9 @@ def set_text_on_curve(text_properties, reset_timeout_s=0.1, reset_depsgraph_n=4,
glyph_index += 1
previous_spline_index = spline_index
if regenerate:
text_properties["actual_text"] = actual_text
return True