Mesh: Replace MLoop struct with generic attributes #104424

Merged
Hans Goudey merged 261 commits from refactor-mesh-corners-generic into main 2023-03-20 15:55:25 +01:00
86 changed files with 862 additions and 442 deletions
Showing only changes of commit 58ac992341 - Show all commits

View File

@ -231,7 +231,7 @@ class FileBlockHeader:
self.SDNAIndex = 0
self.Count = 0
self.FileOffset = handle.tell()
#self.Code += ' ' * (4 - len(self.Code))
# self.Code += ' ' * (4 - len(self.Code))
log.debug("found blend-file-block-fileheader {0} {1}".format(self.Code, self.FileOffset))
def skip(self, handle):

View File

@ -33,7 +33,8 @@ aggressive = 2
# Exclude:
# - `./extern/` because it's maintained separately.
# - `./scripts/addons*` & `./tools/` because they are external repositories
# - `./tools/svn_rev_map/` contains data-files which are slow to re-format and don't benefit from formatting.
# - `./scripts/addons*` because it is an external repository.
# which can contain their own configuration and be handled separately.
# - `./scripts/modules/rna_manual_reference.py` because it's a generated data-file.
exclude = """
@ -41,7 +42,8 @@ exclude = """
./scripts/addons/*,
./scripts/addons_contrib/*,
./scripts/modules/rna_manual_reference.py,
./tools/*,
./tools/svn_rev_map/sha1_to_rev.py,
./tools/svn_rev_map/rev_to_sha1.py,
"""
# Omit settings such as `jobs`, `in_place` & `recursive` as they can cause editor utilities that auto-format on save

View File

@ -20,7 +20,7 @@ from freestyle.types import IntegrationType, Operators, Stroke
Operators.select(QuantitativeInvisibilityUP1D(0))
Operators.bidirectional_chain(ChainSilhouetteIterator())
#Operators.sequential_split(pyVertexNatureUP0D(Nature.VIEW_VERTEX), 2)
# Operators.sequential_split(pyVertexNatureUP0D(Nature.VIEW_VERTEX), 2)
Operators.sort(pyZBP1D())
shaders_list = [
ConstantThicknessShader(3),

View File

@ -76,7 +76,7 @@ class DataPathBuilder:
break
if type_ok:
try:
#print("base." + item_new)
# print("base." + item_new)
base_new = eval("base." + item_new)
break # found, don't keep looking
except:

View File

@ -92,7 +92,7 @@ def module_list(path):
folder_list = []
else:
folder_list = []
#folder_list = glob.glob(os.path.join(path,'*'))
# folder_list = glob.glob(os.path.join(path,'*'))
folder_list = [
p for p in folder_list
if (os.path.exists(os.path.join(path, p, '__init__.py')) or

View File

@ -559,7 +559,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
# foobar(text="Foo", text_ctxt=i18n_ctxt.id_object)
if type(node) == ast.Attribute:
if node.attr in i18n_ctxt_ids:
#print(node, node.attr, getattr(i18n_contexts, node.attr))
# print(node, node.attr, getattr(i18n_contexts, node.attr))
return getattr(i18n_contexts, node.attr)
return i18n_contexts.default

View File

@ -7,7 +7,7 @@ import os
import re
import struct
import tempfile
#import time
# import time
from bl_i18n_utils import (
settings,
@ -173,7 +173,7 @@ def list_po_dir(root_path, settings):
isocodes = dict(e for e in isocodes if os.path.isfile(e[1]))
for num_id, name, uid in settings.LANGUAGES[2:]: # Skip "default" and "en" languages!
best_po = find_best_isocode_matches(uid, isocodes)
#print(uid, "->", best_po)
# print(uid, "->", best_po)
if best_po:
isocode = best_po[0]
yield (True, uid, num_id, name, isocode, isocodes[isocode])
@ -438,7 +438,7 @@ class I18nMessages:
# Avoid parsing again!
# Keys should be (pseudo) file-names, values are tuples (hash, I18nMessages)
# Note: only used by po parser currently!
#_parser_cache = {}
# _parser_cache = {}
def __init__(self, uid=None, kind=None, key=None, src=None, settings=settings):
self.settings = settings
@ -791,7 +791,7 @@ class I18nMessages:
k &= src_to_msg[src_enum]
msgmap["enum_label"]["key"] = k
rlbl = getattr(msgs, msgmap["rna_label"]["msgstr"])
#print("rna label: " + rlbl, rlbl in msgid_to_msg, rlbl in msgstr_to_msg)
# print("rna label: " + rlbl, rlbl in msgid_to_msg, rlbl in msgstr_to_msg)
if rlbl:
k = ctxt_to_msg[rna_ctxt].copy()
if k and rlbl in msgid_to_msg:
@ -831,7 +831,7 @@ class I18nMessages:
# Tips (they never have a specific context).
etip = getattr(msgs, msgmap["enum_tip"]["msgstr"])
#print("enum tip: " + etip)
# print("enum tip: " + etip)
if etip:
k = ctxt_to_msg[self.settings.DEFAULT_CONTEXT].copy()
if etip in msgid_to_msg:
@ -845,7 +845,7 @@ class I18nMessages:
k &= src_to_msg[src_enum]
msgmap["enum_tip"]["key"] = k
rtip = getattr(msgs, msgmap["rna_tip"]["msgstr"])
#print("rna tip: " + rtip)
# print("rna tip: " + rtip)
if rtip:
k = ctxt_to_msg[self.settings.DEFAULT_CONTEXT].copy()
if k and rtip in msgid_to_msg:
@ -860,7 +860,7 @@ class I18nMessages:
msgmap["rna_tip"]["key"] = k
# print(k)
btip = getattr(msgs, msgmap["but_tip"]["msgstr"])
#print("button tip: " + btip)
# print("button tip: " + btip)
if btip and btip not in {rtip, etip}:
k = ctxt_to_msg[self.settings.DEFAULT_CONTEXT].copy()
if btip in msgid_to_msg:
@ -1038,7 +1038,7 @@ class I18nMessages:
msgstr_lines.append(line)
else:
self.parsing_errors.append((line_nr, "regular string outside msgctxt, msgid or msgstr scope"))
#self.parsing_errors += (str(comment_lines), str(msgctxt_lines), str(msgid_lines), str(msgstr_lines))
# self.parsing_errors += (str(comment_lines), str(msgctxt_lines), str(msgid_lines), str(msgstr_lines))
# If no final empty line, last message is not finalized!
if reading_msgstr:

View File

@ -69,7 +69,7 @@ def language_menu(args, settings):
continue
for po_path in os.listdir(po_dir):
uid = po_to_uid.get(po_path, None)
#print("Checking %s, found uid %s" % (po_path, uid))
# print("Checking %s, found uid %s" % (po_path, uid))
po_path = os.path.join(settings.TRUNK_PO_DIR, po_path)
if uid is not None:
po = utils_i18n.I18nMessages(uid=uid, kind='PO', src=po_path, settings=settings)

View File

@ -392,7 +392,7 @@ def ngon_tessellate(from_data, indices, fix_loops=True, debug_print=True):
fill = tessellate_polygon([[v[0] for v in loop] for loop in loop_list])
# draw_loops(loop_list)
#raise Exception("done loop")
# raise Exception("done loop")
# map to original indices
fill = [[vert_map[i] for i in f] for f in fill]

View File

@ -329,8 +329,11 @@ def banner(context):
"",
)
# NOTE: Using `OUTPUT` style (intended for the `stdout` is also valid).
# Using `INFO` has a slight advantage that it's excluded by the "Copy as Script" operator.
# As the banner isn't useful to include in a script - leave it out.
for line in message:
add_scrollback(line, 'OUTPUT')
add_scrollback(line, 'INFO')
sc.prompt = PROMPT

View File

@ -25,8 +25,8 @@ def compat_str(text, line_length=0):
text_ls.append(text)
text = '\n '.join(text_ls)
#text = text.replace('.', '.\n')
#text = text.replace(']', ']\n')
# text = text.replace('.', '.\n')
# text = text.replace(']', ']\n')
text = text.replace("\n", "\\n")
text = text.replace('"', '\\"')
return text
@ -135,7 +135,7 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr
if not rna_path.startswith("pose.bones["):
return None
#rna_path_bone = rna_path[:rna_path.index("]") + 1]
# rna_path_bone = rna_path[:rna_path.index("]") + 1]
# return obj.path_resolve(rna_path_bone)
bone_name = rna_path.split("[")[1].split("]")[0]
return obj.pose.bones[bone_name[1:-1]]

View File

@ -629,7 +629,7 @@ def BuildRNAInfo():
except:
return "" # invalid id
#structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpy.doc.structs.values()]
# structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpy.doc.structs.values()]
'''
structs = []
for rna_struct in bpy.doc.structs.values():
@ -703,7 +703,7 @@ def BuildRNAInfo():
# Store a list of functions, remove inherited later
# NOT USED YET
## rna_functions_dict[identifier] = get_direct_functions(rna_struct)
# rna_functions_dict[identifier] = get_direct_functions(rna_struct)
# fill in these later
rna_children_dict[identifier] = []
@ -786,7 +786,7 @@ def BuildRNAInfo():
# if rna_struct.nested:
# continue
#write_struct(rna_struct, '')
# write_struct(rna_struct, '')
info_struct = GetInfoStructRNA(rna_struct)
if rna_base:
info_struct.base = GetInfoStructRNA(rna_struct_dict[rna_base])

View File

@ -164,7 +164,7 @@ class RandomizeLocRotSize(Operator):
scale = None if not self.use_scale else self.scale
scale_even = self.scale_even
#scale_min = self.scale_min
# scale_min = self.scale_min
scale_min = 0
randomize_selected(context, seed, delta,

View File

@ -165,9 +165,9 @@ class prettyface:
def set_uv(f, p1, p2, p3):
# cos =
#v1 = cos[0]-cos[1]
#v2 = cos[1]-cos[2]
#v3 = cos[2]-cos[0]
# v1 = cos[0]-cos[1]
# v2 = cos[1]-cos[2]
# v3 = cos[2]-cos[0]
# angles_co = get_tri_angles(*[v.co for v in f])
angles_co = get_tri_angles(*[f.id_data.vertices[v].co for v in f.vertices]) # XXX25

View File

@ -132,7 +132,6 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel):
rows=rows,
)
col = row.column(align=True)
col.operator("pose.group_add", icon='ADD', text="")
col.operator("pose.group_remove", icon='REMOVE', text="")
@ -218,7 +217,7 @@ class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, Panel):
class DATA_PT_motion_paths(MotionPathButtonsPanel, Panel):
#bl_label = "Bones Motion Paths"
# bl_label = "Bones Motion Paths"
bl_options = {'DEFAULT_CLOSED'}
bl_context = "data"
@ -240,7 +239,7 @@ class DATA_PT_motion_paths(MotionPathButtonsPanel, Panel):
class DATA_PT_motion_paths_display(MotionPathButtonsPanel_display, Panel):
#bl_label = "Bones Motion Paths"
# bl_label = "Bones Motion Paths"
bl_context = "data"
bl_parent_id = "DATA_PT_motion_paths"
bl_options = {'DEFAULT_CLOSED'}

View File

@ -190,7 +190,7 @@ class MASK_PT_point:
col = layout.column()
# Currently only parenting the movie-clip is allowed,
# so do not over-complicate things for now by using single template_ID
#col.template_any_ID(parent, "id", "id_type", text="")
# col.template_any_ID(parent, "id", "id_type", text="")
col.label(text="Parent:")
col.prop(parent, "id", text="")

View File

@ -325,7 +325,7 @@ class OBJECT_PT_lineart(ObjectButtonsPanel, Panel):
class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel):
#bl_label = "Object Motion Paths"
# bl_label = "Object Motion Paths"
bl_context = "object"
bl_options = {'DEFAULT_CLOSED'}
@ -344,7 +344,7 @@ class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel):
class OBJECT_PT_motion_paths_display(MotionPathButtonsPanel_display, Panel):
#bl_label = "Object Motion Paths"
# bl_label = "Object Motion Paths"
bl_context = "object"
bl_parent_id = "OBJECT_PT_motion_paths"
bl_options = {'DEFAULT_CLOSED'}

View File

@ -879,7 +879,7 @@ class PHYSICS_PT_mesh(PhysicButtonsPanel, Panel):
col.prop(domain, "mesh_concave_lower", text="Lower")
# TODO (sebbas): for now just interpolate any upres grids, ie not sampling highres grids
#col.prop(domain, "highres_sampling", text="Flow Sampling:")
# col.prop(domain, "highres_sampling", text="Flow Sampling:")
if domain.cache_type == 'MODULAR':
col.separator()

View File

@ -138,6 +138,13 @@ typedef struct Main {
*/
bool is_locked_for_linking;
/**
* When set, indicates that an unrecoverable error/data corruption was detected.
* Should only be set by readfile code, and used by upper-level code (typically #setup_app_data)
* to cancel a file reading operation.
*/
bool is_read_invalid;
/**
* True if this main is the 'GMAIN' of current Blender.
*

View File

@ -99,6 +99,9 @@ void BKE_mesh_legacy_attribute_strings_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_sharp_edges_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_sharp_edges_from_flags(struct Mesh *mesh);
void BKE_mesh_legacy_uv_seam_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_uv_seam_from_flags(struct Mesh *mesh);
struct MVert *BKE_mesh_legacy_convert_positions_to_verts(
Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,

View File

@ -259,6 +259,7 @@ typedef bool (*MeshRemapIslandsCalc)(const float (*vert_positions)[3],
int totvert,
const struct MEdge *edges,
int totedge,
const bool *uv_seams,
const struct MPoly *polys,
int totpoly,
const int *corner_verts,
@ -277,6 +278,7 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3],
int totvert,
const struct MEdge *edges,
int totedge,
const bool *uv_seams,
const struct MPoly *polys,
int totpoly,
const int *corner_verts,
@ -301,6 +303,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
int totvert,
struct MEdge *edges,
int totedge,
const bool *uv_seams,
struct MPoly *polys,
int totpoly,
const int *corner_verts,

View File

@ -95,7 +95,6 @@ typedef struct CCGDerivedMesh {
struct CCGFace *face;
} * faceMap;
short *edgeFlags;
struct DMFlagMat *faceFlags;
int *reverseFaceMap;

View File

@ -476,6 +476,13 @@ void BKE_blendfile_read_setup_ex(bContext *C,
const bool startup_update_defaults,
const char *startup_app_template)
{
if (bfd->main->is_read_invalid) {
BKE_reports_prepend(reports->reports,
"File could not be read, critical data corruption detected");
BLO_blendfiledata_free(bfd);
return;
}
if (startup_update_defaults) {
if ((params->skip_flags & BLO_READ_SKIP_DATA) == 0) {
BLO_update_defaults_startup_blend(bfd->main, startup_app_template);
@ -503,6 +510,10 @@ struct BlendFileData *BKE_blendfile_read(const char *filepath,
}
BlendFileData *bfd = BLO_read_from_file(filepath, eBLOReadSkip(params->skip_flags), reports);
if (bfd && bfd->main->is_read_invalid) {
BLO_blendfiledata_free(bfd);
bfd = nullptr;
}
if (bfd) {
handle_subversion_warning(bfd->main, reports);
}
@ -519,6 +530,10 @@ struct BlendFileData *BKE_blendfile_read_from_memory(const void *filebuf,
{
BlendFileData *bfd = BLO_read_from_memory(
filebuf, filelength, eBLOReadSkip(params->skip_flags), reports);
if (bfd && bfd->main->is_read_invalid) {
BLO_blendfiledata_free(bfd);
bfd = nullptr;
}
if (bfd) {
/* Pass. */
}
@ -535,6 +550,10 @@ struct BlendFileData *BKE_blendfile_read_from_memfile(Main *bmain,
{
BlendFileData *bfd = BLO_read_from_memfile(
bmain, BKE_main_blendfile_path(bmain), memfile, params, reports);
if (bfd && bfd->main->is_read_invalid) {
BLO_blendfiledata_free(bfd);
bfd = nullptr;
}
if (bfd) {
/* Removing the unused workspaces, screens and wm is useless here, setup_app_data will switch
* those lists with the ones from old bmain, which freeing is much more efficient than

View File

@ -50,6 +50,11 @@
static CLG_LogRef LOG = {"bke.collection"};
/**
* Extra asserts that #Collection.gobject_hash is valid which are too slow even for debug mode.
*/
// #define USE_DEBUG_EXTRA_GOBJECT_ASSERT
/* -------------------------------------------------------------------- */
/** \name Prototypes
* \{ */
@ -61,6 +66,11 @@ static bool collection_child_add(Collection *parent,
static bool collection_child_remove(Collection *parent, Collection *collection);
static bool collection_object_add(
Main *bmain, Collection *collection, Object *ob, int flag, const bool add_us);
static void collection_object_remove_no_gobject_hash(Main *bmain,
Collection *collection,
CollectionObject *cob,
const bool free_us);
static bool collection_object_remove(Main *bmain,
Collection *collection,
Object *ob,
@ -72,6 +82,18 @@ static CollectionParent *collection_find_parent(Collection *child, Collection *c
static bool collection_find_child_recursive(const Collection *parent,
const Collection *collection);
static void collection_gobject_hash_ensure(Collection *collection);
static void collection_gobject_hash_remove_object(Collection *collection, const Object *ob);
static void collection_gobject_hash_update_object(Collection *collection,
Object *ob_old,
CollectionObject *cob);
/** Does nothing unless #USE_DEBUG_EXTRA_GOBJECT_ASSERT is defined. */
static void collection_gobject_hash_assert_internal_consistency(Collection *collection);
#define BLI_ASSERT_COLLECION_GOBJECT_HASH_IS_VALID(collection) \
collection_gobject_hash_assert_internal_consistency(collection)
/** \} */
/* -------------------------------------------------------------------- */
@ -119,6 +141,7 @@ static void collection_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons
BLI_listbase_clear(&collection_dst->gobject);
BLI_listbase_clear(&collection_dst->children);
BLI_listbase_clear(&collection_dst->runtime.parents);
collection_dst->runtime.gobject_hash = NULL;
LISTBASE_FOREACH (CollectionChild *, child, &collection_src->children) {
collection_child_add(collection_dst, child->collection, flag, false);
@ -136,6 +159,11 @@ static void collection_free_data(ID *id)
BKE_previewimg_free(&collection->preview);
BLI_freelistN(&collection->gobject);
if (collection->runtime.gobject_hash) {
BLI_ghash_free(collection->runtime.gobject_hash, NULL, NULL);
collection->runtime.gobject_hash = NULL;
}
BLI_freelistN(&collection->children);
BLI_freelistN(&collection->runtime.parents);
@ -150,7 +178,13 @@ static void collection_foreach_id(ID *id, LibraryForeachIDData *data)
data, collection->runtime.owner_id, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF);
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
Object *cob_ob_old = cob->ob;
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, cob->ob, IDWALK_CB_USER);
if (collection->runtime.gobject_hash) {
collection_gobject_hash_update_object(collection, cob_ob_old, cob);
}
}
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(
@ -288,6 +322,7 @@ static void collection_blend_read_data(BlendDataReader *reader, ID *id)
static void lib_link_collection_data(BlendLibReader *reader, Library *lib, Collection *collection)
{
BLI_assert(collection->runtime.gobject_hash == NULL);
LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection->gobject) {
BLO_read_id_address(reader, lib, &cob->ob);
@ -354,6 +389,7 @@ void BKE_collection_compat_blend_read_expand(struct BlendExpander *expander,
void BKE_collection_blend_read_expand(BlendExpander *expander, Collection *collection)
{
BLI_assert(collection->runtime.gobject_hash == NULL);
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
BLO_expand(expander, cob->ob);
}
@ -518,11 +554,20 @@ bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy)
return false;
}
/* This is being deleted, no need to handle each item.
* NOTE: While it might seem an advantage to use the hash instead of the list-lookup
* it is in fact slower because the items are removed in-order,
* so the list-lookup succeeds on the first test. */
if (collection->runtime.gobject_hash) {
BLI_ghash_free(collection->runtime.gobject_hash, NULL, NULL);
collection->runtime.gobject_hash = NULL;
}
if (hierarchy) {
/* Remove child objects. */
CollectionObject *cob = collection->gobject.first;
while (cob != NULL) {
collection_object_remove(bmain, collection, cob->ob, true);
collection_object_remove_no_gobject_hash(bmain, collection, cob, true);
cob = collection->gobject.first;
}
@ -551,7 +596,7 @@ bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy)
}
/* Remove child object. */
collection_object_remove(bmain, collection, cob->ob, true);
collection_object_remove_no_gobject_hash(bmain, collection, cob, true);
cob = collection->gobject.first;
}
}
@ -938,8 +983,9 @@ bool BKE_collection_has_object(Collection *collection, const Object *ob)
if (ELEM(NULL, collection, ob)) {
return false;
}
return BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob));
BLI_ASSERT_COLLECION_GOBJECT_HASH_IS_VALID(collection);
collection_gobject_hash_ensure(collection);
return BLI_ghash_lookup(collection->runtime.gobject_hash, ob);
}
bool BKE_collection_has_object_recursive(Collection *collection, Object *ob)
@ -1070,13 +1116,15 @@ static bool collection_object_add(
}
}
CollectionObject *cob = BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob));
if (cob) {
collection_gobject_hash_ensure(collection);
CollectionObject **cob_p;
if (BLI_ghash_ensure_p(collection->runtime.gobject_hash, ob, (void ***)&cob_p)) {
return false;
}
cob = MEM_callocN(sizeof(CollectionObject), __func__);
CollectionObject *cob = MEM_callocN(sizeof(CollectionObject), __func__);
cob->ob = ob;
*cob_p = cob;
BLI_addtail(&collection->gobject, cob);
BKE_collection_object_cache_free(collection);
@ -1095,16 +1143,16 @@ static bool collection_object_add(
return true;
}
static bool collection_object_remove(Main *bmain,
Collection *collection,
Object *ob,
const bool free_us)
/**
* A version of #collection_object_remove that does not handle `collection->runtime.gobject_hash`,
* Either the caller must have removed the object from the hash or the hash may be NULL.
*/
static void collection_object_remove_no_gobject_hash(Main *bmain,
Collection *collection,
CollectionObject *cob,
const bool free_us)
{
CollectionObject *cob = BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob));
if (cob == NULL) {
return false;
}
Object *ob = cob->ob;
BLI_freelinkN(&collection->gobject, cob);
BKE_collection_object_cache_free(collection);
@ -1117,7 +1165,19 @@ static bool collection_object_remove(Main *bmain,
collection_tag_update_parent_recursive(
bmain, collection, ID_RECALC_COPY_ON_WRITE | ID_RECALC_GEOMETRY);
}
static bool collection_object_remove(Main *bmain,
Collection *collection,
Object *ob,
const bool free_us)
{
collection_gobject_hash_ensure(collection);
CollectionObject *cob = BLI_ghash_popkey(collection->runtime.gobject_hash, ob, NULL);
if (cob == NULL) {
return false;
}
collection_object_remove_no_gobject_hash(bmain, collection, cob, free_us);
return true;
}
@ -1219,8 +1279,9 @@ bool BKE_collection_object_replace(Main *bmain,
Object *ob_old,
Object *ob_new)
{
CollectionObject *cob = BLI_findptr(
&collection->gobject, ob_old, offsetof(CollectionObject, ob));
collection_gobject_hash_ensure(collection);
CollectionObject *cob;
cob = BLI_ghash_popkey(collection->runtime.gobject_hash, ob_old, NULL);
if (cob == NULL) {
return false;
}
@ -1229,6 +1290,8 @@ bool BKE_collection_object_replace(Main *bmain,
cob->ob = ob_new;
id_us_plus(&cob->ob->id);
BLI_ghash_insert(collection->runtime.gobject_hash, cob->ob, cob);
if (BKE_collection_is_in_scene(collection)) {
BKE_main_collection_sync(bmain);
}
@ -1313,9 +1376,14 @@ void BKE_collections_object_remove_nulls(Main *bmain)
static void collection_object_remove_duplicates(Collection *collection)
{
bool changed = false;
BLI_ASSERT_COLLECION_GOBJECT_HASH_IS_VALID(collection);
const bool use_hash_exists = (collection->runtime.gobject_hash != NULL);
LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection->gobject) {
if (cob->ob->runtime.collection_management) {
if (use_hash_exists) {
collection_gobject_hash_remove_object(collection, cob->ob);
}
BLI_freelinkN(&collection->gobject, cob);
changed = true;
continue;
@ -1578,6 +1646,79 @@ static CollectionParent *collection_find_parent(Collection *child, Collection *c
return BLI_findptr(&child->runtime.parents, collection, offsetof(CollectionParent, collection));
}
static void collection_gobject_hash_ensure(Collection *collection)
{
if (collection->runtime.gobject_hash) {
BLI_ASSERT_COLLECION_GOBJECT_HASH_IS_VALID(collection);
return;
}
GHash *gobject_hash = BLI_ghash_ptr_new_ex(__func__, BLI_listbase_count(&collection->gobject));
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
BLI_ghash_insert(gobject_hash, cob->ob, cob);
}
collection->runtime.gobject_hash = gobject_hash;
BLI_ASSERT_COLLECION_GOBJECT_HASH_IS_VALID(collection);
}
static void collection_gobject_hash_remove_object(Collection *collection, const Object *ob)
{
const bool found = BLI_ghash_remove(collection->runtime.gobject_hash, ob, NULL, NULL);
BLI_assert(found);
UNUSED_VARS_NDEBUG(found);
}
/**
* Update the collections object hash, removing `ob_old`, inserting `cob->ob` as the new key.
*
* \param ob_old: The existing key to `cob` in the hash, not removed when NULL.
* \param cob: The `cob->ob` is to be used as the new key,
* when NULL it's not added back into the hash.
*/
static void collection_gobject_hash_update_object(Collection *collection,
Object *ob_old,
CollectionObject *cob)
{
if (ob_old == cob->ob) {
return;
}
BLI_ASSERT_COLLECION_GOBJECT_HASH_IS_VALID(collection);
if (ob_old) {
collection_gobject_hash_remove_object(collection, ob_old);
}
/* The object may be set to NULL if the ID is being cleared from #collection_foreach_id,
* generally `cob->ob` is not expected to be NULL. */
if (cob->ob) {
BLI_ghash_insert(collection->runtime.gobject_hash, cob->ob, cob);
}
}
/**
* Should only be called by: #BLI_ASSERT_COLLECION_GOBJECT_HASH_IS_VALID macro,
* this is an expensive operation intended only to be used for debugging.
*/
static void collection_gobject_hash_assert_internal_consistency(Collection *collection)
{
#ifdef USE_DEBUG_EXTRA_GOBJECT_ASSERT
if (collection->runtime.gobject_hash == NULL) {
return;
}
GHash *gobject_hash = collection->runtime.gobject_hash;
int gobject_count = 0;
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
CollectionObject *cob_test = BLI_ghash_lookup(gobject_hash, cob->ob);
BLI_assert(cob == cob_test);
gobject_count += 1;
}
const int gobject_hash_count = BLI_ghash_len(gobject_hash);
BLI_assert(gobject_count == gobject_hash_count);
#else
UNUSED_VARS(collection);
#endif /* USE_DEBUG_EXTRA_GOBJECT_ASSERT */
}
static bool collection_child_add(Collection *parent,
Collection *collection,
const int flag,

View File

@ -1009,26 +1009,21 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
return true;
}
if (r_map && cddata_type == CD_FAKE_SEAM) {
const size_t elem_size = sizeof(*((MEdge *)nullptr));
const size_t data_size = sizeof(((MEdge *)nullptr)->flag);
const size_t data_offset = offsetof(MEdge, flag);
const uint64_t data_flag = ME_SEAM;
data_transfer_layersmapping_add_item(r_map,
cddata_type,
mix_mode,
mix_factor,
mix_weights,
BKE_mesh_edges(me_src),
BKE_mesh_edges_for_write(me_dst),
me_src->totedge,
me_dst->totedge,
elem_size,
data_size,
data_offset,
data_flag,
nullptr,
interp_data);
if (!CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, ".uv_seam")) {
CustomData_add_layer_named(
&me_dst->edata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, me_dst->totedge, ".uv_seam");
}
data_transfer_layersmapping_add_item_cd(
r_map,
CD_PROP_BOOL,
mix_mode,
mix_factor,
mix_weights,
CustomData_get_layer_named(&me_src->edata, CD_PROP_BOOL, ".uv_seam"),
CustomData_get_layer_named_for_write(
&me_dst->edata, CD_PROP_BOOL, ".uv_seam", me_dst->totedge),
interp,
interp_data);
return true;
}
if (r_map && cddata_type == CD_FAKE_SHARP) {

View File

@ -2272,7 +2272,7 @@ void BKE_gpencil_stroke_subdivide(bGPdata *gpd, bGPDstroke *gps, int level, int
pt_final->uv_fac = interpf(pt->uv_fac, next->uv_fac, 0.5f);
interp_v4_v4v4(pt_final->uv_fill, pt->uv_fill, next->uv_fill, 0.5f);
CLAMP(pt_final->strength, GPENCIL_STRENGTH_MIN, 1.0f);
pt_final->time = interpf(pt->time, next->time, 0.5f);
pt_final->time = 0;
pt_final->runtime.pt_orig = nullptr;
pt_final->flag = 0;
interp_v4_v4v4(pt_final->vert_color, pt->vert_color, next->vert_color, 0.5f);
@ -2496,6 +2496,7 @@ static void gpencil_generate_edgeloops(Object *ob,
const bool use_seams,
const bool use_vgroups)
{
using namespace blender;
Mesh *me = (Mesh *)ob->data;
if (me->totedge == 0) {
return;
@ -2504,6 +2505,9 @@ static void gpencil_generate_edgeloops(Object *ob,
const Span<MEdge> edges = me->edges();
const Span<MDeformVert> dverts = me->deform_verts();
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(me);
const bke::AttributeAccessor attributes = me->attributes();
const VArray<bool> uv_seams = attributes.lookup_or_default<bool>(
".uv_seam", ATTR_DOMAIN_EDGE, false);
/* Arrays for all edge vertices (forward and backward) that form a edge loop.
* This is reused for each edge-loop to create gpencil stroke. */
@ -2529,7 +2533,7 @@ static void gpencil_generate_edgeloops(Object *ob,
sub_v3_v3v3(gped->vec, vert_positions[ed->v1], vert_positions[ed->v2]);
/* If use seams, mark as done if not a seam. */
if ((use_seams) && ((ed->flag & ME_SEAM) == 0)) {
if ((use_seams) && !uv_seams[i]) {
gped->flag = 1;
}
}

View File

@ -85,11 +85,11 @@ static void layer_collection_free(ViewLayer *view_layer, LayerCollection *lc)
view_layer->active_collection = nullptr;
}
LISTBASE_FOREACH (LayerCollection *, nlc, &lc->layer_collections) {
LISTBASE_FOREACH_MUTABLE (LayerCollection *, nlc, &lc->layer_collections) {
layer_collection_free(view_layer, nlc);
MEM_freeN(nlc);
}
BLI_freelistN(&lc->layer_collections);
BLI_listbase_clear(&lc->layer_collections);
}
static Base *object_base_new(Object *ob)
@ -254,10 +254,11 @@ void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user)
BLI_ghash_free(view_layer->object_bases_hash, nullptr, nullptr);
}
LISTBASE_FOREACH (LayerCollection *, lc, &view_layer->layer_collections) {
LISTBASE_FOREACH_MUTABLE (LayerCollection *, lc, &view_layer->layer_collections) {
layer_collection_free(view_layer, lc);
MEM_freeN(lc);
}
BLI_freelistN(&view_layer->layer_collections);
BLI_listbase_clear(&view_layer->layer_collections);
LISTBASE_FOREACH (ViewLayerEngineData *, sled, &view_layer->drawdata) {
if (sled->storage) {

View File

@ -40,6 +40,13 @@ Main *BKE_main_new()
void BKE_main_free(Main *mainvar)
{
/* In case this is called on a 'split-by-libraries' list of mains.
*
* Should not happen in typical usages, but can occur e.g. if a file reading is aborted. */
if (mainvar->next) {
BKE_main_free(mainvar->next);
}
/* also call when reading a file, erase all, etc */
ListBase *lbarray[INDEX_ID_MAX];
int a;

View File

@ -274,6 +274,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
BKE_mesh_legacy_bevel_weight_from_layers(mesh);
BKE_mesh_legacy_edge_crease_from_layers(mesh);
BKE_mesh_legacy_sharp_edges_to_flags(mesh);
BKE_mesh_legacy_uv_seam_to_flags(mesh);
BKE_mesh_legacy_attribute_strings_to_flags(mesh);
mesh->active_color_attribute = nullptr;
mesh->default_color_attribute = nullptr;

View File

@ -104,9 +104,9 @@ class MeshesToIMeshInfo {
void input_mvert_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_index_in_orig_mesh) const;
const MEdge *input_medge_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_index_in_orig_mesh) const;
void input_medge_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_index_in_orig_mesh) const;
};
/* Given an index `imesh_v` in the `IMesh`, return the index of the
@ -199,24 +199,21 @@ void MeshesToIMeshInfo::input_mvert_for_orig_index(int orig_index,
}
/* Similarly for edges. */
const MEdge *MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_index_in_orig_mesh) const
void MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index,
const Mesh **r_orig_mesh,
int *r_index_in_orig_mesh) const
{
int orig_mesh_index = input_mesh_for_imesh_edge(orig_index);
BLI_assert(0 <= orig_mesh_index && orig_mesh_index < meshes.size());
const Mesh *me = meshes[orig_mesh_index];
const Span<MEdge> edges = me->edges();
int index_in_mesh = orig_index - mesh_edge_offset[orig_mesh_index];
BLI_assert(0 <= index_in_mesh && index_in_mesh < me->totedge);
const MEdge *medge = &edges[index_in_mesh];
if (r_orig_mesh) {
*r_orig_mesh = me;
}
if (r_index_in_orig_mesh) {
*r_index_in_orig_mesh = index_in_mesh;
}
return medge;
}
/**
@ -434,13 +431,10 @@ static void copy_poly_attributes(Mesh *dest_mesh,
/* Similar to copy_vert_attributes but for edge attributes. */
static void copy_edge_attributes(Mesh *dest_mesh,
MEdge *medge,
const MEdge *orig_medge,
const Mesh *orig_me,
int medge_index,
int index_in_orig_me)
{
medge->flag = orig_medge->flag;
CustomData *target_cd = &dest_mesh->edata;
const CustomData *source_cd = &orig_me->edata;
for (int source_layer_i = 0; source_layer_i < source_cd->totlayer; ++source_layer_i) {
@ -776,7 +770,6 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
/* Now that the MEdges are populated, we can copy over the required attributes and custom layers.
*/
MutableSpan<MEdge> edges = result->edges_for_write();
const Span<int> dst_corner_edges = result->corner_edges();
for (int fi : im->face_index_range()) {
const Face *f = im->face(fi);
@ -785,11 +778,9 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
if (f->edge_orig[j] != NO_INDEX) {
const Mesh *orig_me;
int index_in_orig_me;
const MEdge *orig_medge = mim.input_medge_for_orig_index(
f->edge_orig[j], &orig_me, &index_in_orig_me);
mim.input_medge_for_orig_index(f->edge_orig[j], &orig_me, &index_in_orig_me);
int e_index = dst_corner_edges[mp->loopstart + j];
MEdge *medge = &edges[e_index];
copy_edge_attributes(result, medge, orig_medge, orig_me, e_index, index_in_orig_me);
copy_edge_attributes(result, orig_me, e_index, index_in_orig_me);
}
}
}

View File

@ -121,8 +121,6 @@ static void make_edges_mdata_extend(Mesh &mesh)
BLI_edgehashIterator_step(ehi), ++medge, e_index++) {
BLI_edgehashIterator_getKey(ehi, &medge->v1, &medge->v2);
BLI_edgehashIterator_setValue(ehi, POINTER_FROM_UINT(e_index));
medge->flag = 0;
}
BLI_edgehashIterator_free(ehi);

View File

@ -476,7 +476,7 @@ static void convert_mfaces_to_mpolys(ID *id,
/* unrelated but avoid having the FGON flag enabled,
* so we can reuse it later for something else */
me->flag &= ~ME_FGON;
me->flag_legacy &= ~ME_FGON;
}
polyindex = (int *)CustomData_get_layer(fdata, CD_ORIGINDEX);
@ -1379,13 +1379,13 @@ void BKE_mesh_legacy_sharp_edges_to_flags(Mesh *mesh)
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge"))) {
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(edges[i].flag, sharp_edges[i], ME_SHARP);
SET_FLAG_FROM_TEST(edges[i].flag_legacy, sharp_edges[i], ME_SHARP);
}
});
}
else {
for (const int i : edges.index_range()) {
edges[i].flag &= ~ME_SHARP;
edges[i].flag_legacy &= ~ME_SHARP;
}
}
}
@ -1399,13 +1399,14 @@ void BKE_mesh_legacy_sharp_edges_from_flags(Mesh *mesh)
if (attributes.contains("sharp_edge")) {
return;
}
if (std::any_of(
edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & ME_SHARP; })) {
if (std::any_of(edges.begin(), edges.end(), [](const MEdge &edge) {
return edge.flag_legacy & ME_SHARP;
})) {
SpanAttributeWriter<bool> sharp_edges = attributes.lookup_or_add_for_write_only_span<bool>(
"sharp_edge", ATTR_DOMAIN_EDGE);
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
sharp_edges.span[i] = edges[i].flag & ME_SHARP;
sharp_edges.span[i] = edges[i].flag_legacy & ME_SHARP;
}
});
sharp_edges.finish();
@ -1414,6 +1415,54 @@ void BKE_mesh_legacy_sharp_edges_from_flags(Mesh *mesh)
/** \} */
/* -------------------------------------------------------------------- */
/** \name UV Seam Conversion
* \{ */
void BKE_mesh_legacy_uv_seam_to_flags(Mesh *mesh)
{
using namespace blender;
MutableSpan<MEdge> edges = mesh->edges_for_write();
if (const bool *uv_seams = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, ".uv_seam"))) {
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(edges[i].flag_legacy, uv_seams[i], ME_SEAM);
}
});
}
else {
for (const int i : edges.index_range()) {
edges[i].flag_legacy &= ~ME_SEAM;
}
}
}
void BKE_mesh_legacy_uv_seam_from_flags(Mesh *mesh)
{
using namespace blender;
using namespace blender::bke;
const Span<MEdge> edges = mesh->edges();
MutableAttributeAccessor attributes = mesh->attributes_for_write();
if (attributes.contains(".uv_seam")) {
return;
}
if (std::any_of(edges.begin(), edges.end(), [](const MEdge &edge) {
return edge.flag_legacy & ME_SEAM;
})) {
SpanAttributeWriter<bool> uv_seams = attributes.lookup_or_add_for_write_only_span<bool>(
".uv_seam", ATTR_DOMAIN_EDGE);
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
uv_seams.span[i] = edges[i].flag_legacy & ME_SEAM;
}
});
uv_seams.finish();
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Hide Attribute and Legacy Flag Conversion
* \{ */
@ -1438,7 +1487,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
".hide_edge", ATTR_DOMAIN_EDGE, false);
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(edges[i].flag, hide_edge[i], ME_HIDE);
SET_FLAG_FROM_TEST(edges[i].flag_legacy, hide_edge[i], ME_HIDE);
}
});
@ -1476,13 +1525,14 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
}
const Span<MEdge> edges = mesh->edges();
if (std::any_of(
edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & ME_HIDE; })) {
if (std::any_of(edges.begin(), edges.end(), [](const MEdge &edge) {
return edge.flag_legacy & ME_HIDE;
})) {
SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
".hide_edge", ATTR_DOMAIN_EDGE);
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
hide_edge.span[i] = edges[i].flag & ME_HIDE;
hide_edge.span[i] = edges[i].flag_legacy & ME_HIDE;
}
});
hide_edge.finish();
@ -1755,7 +1805,7 @@ void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh)
".select_edge", ATTR_DOMAIN_EDGE, false);
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(edges[i].flag, select_edge[i], SELECT);
SET_FLAG_FROM_TEST(edges[i].flag_legacy, select_edge[i], SELECT);
}
});
@ -1794,13 +1844,14 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
}
const Span<MEdge> edges = mesh->edges();
if (std::any_of(
edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & SELECT; })) {
if (std::any_of(edges.begin(), edges.end(), [](const MEdge &edge) {
return edge.flag_legacy & SELECT;
})) {
SpanAttributeWriter<bool> select_edge = attributes.lookup_or_add_for_write_only_span<bool>(
".select_edge", ATTR_DOMAIN_EDGE);
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
select_edge.span[i] = edges[i].flag & SELECT;
select_edge.span[i] = edges[i].flag_legacy & SELECT;
}
});
select_edge.finish();
@ -1836,12 +1887,12 @@ void BKE_mesh_legacy_convert_loose_edges_to_flag(Mesh *mesh)
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
if (loose_edges.count == 0) {
for (const int64_t i : range) {
edges[i].flag &= ~ME_LOOSEEDGE;
edges[i].flag_legacy &= ~ME_LOOSEEDGE;
}
}
else {
for (const int64_t i : range) {
SET_FLAG_FROM_TEST(edges[i].flag, loose_edges.is_loose_bits[i], ME_LOOSEEDGE);
SET_FLAG_FROM_TEST(edges[i].flag_legacy, loose_edges.is_loose_bits[i], ME_LOOSEEDGE);
}
}
});

View File

@ -994,8 +994,8 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
sizeof(*innrcut->indices) * size_t(num_innercut_items));
}
static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges,
const int totedge,
static bool mesh_calc_islands_loop_poly_uv(const int totedge,
const bool *uv_seams,
const MPoly *polys,
const int totpoly,
const int *corner_verts,
@ -1081,7 +1081,7 @@ static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges,
}
/* Edge is UV boundary if tagged as seam. */
return (edges[edge_index].flag & ME_SEAM) != 0;
return uv_seams && uv_seams[edge_index];
};
poly_edge_loop_islands_calc(totedge,
@ -1181,6 +1181,7 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3],
const int totvert,
const MEdge *edges,
const int totedge,
const bool *uv_seams,
const MPoly *polys,
const int totpoly,
const int *corner_verts,
@ -1189,8 +1190,8 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3],
MeshIslandStore *r_island_store)
{
UNUSED_VARS(vert_positions, totvert);
return mesh_calc_islands_loop_poly_uv(edges,
totedge,
return mesh_calc_islands_loop_poly_uv(totedge,
uv_seams,
polys,
totpoly,
corner_verts,
@ -1204,6 +1205,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
const int totvert,
MEdge *edges,
const int totedge,
const bool *uv_seams,
MPoly *polys,
const int totpoly,
const int *corner_verts,
@ -1212,10 +1214,17 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
const float (*luvs)[2],
MeshIslandStore *r_island_store)
{
UNUSED_VARS(vert_positions, totvert);
UNUSED_VARS(vert_positions, totvert, edges);
BLI_assert(luvs != nullptr);
return mesh_calc_islands_loop_poly_uv(
edges, totedge, polys, totpoly, corner_verts, corner_edges, totloop, luvs, r_island_store);
return mesh_calc_islands_loop_poly_uv(totedge,
uv_seams,
polys,
totpoly,
corner_verts,
corner_edges,
totloop,
luvs,
r_island_store);
}
/** \} */

View File

@ -1446,10 +1446,13 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
/* First, generate the islands, if possible. */
if (gen_islands_src) {
const bool *uv_seams = static_cast<const bool *>(
CustomData_get_layer_named(&me_src->edata, CD_PROP_BOOL, ".uv_seam"));
use_islands = gen_islands_src(positions_src,
num_verts_src,
edges_src.data(),
int(edges_src.size()),
uv_seams,
polys_src.data(),
int(polys_src.size()),
corner_verts_src.data(),

View File

@ -909,11 +909,10 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, float (*r_positions)[3])
}
/* utility function */
BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2, const short flag)
BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2)
{
med->v1 = v1;
med->v2 = v2;
med->flag = flag;
}
static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
@ -925,7 +924,6 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
int gridSize = ccgSubSurf_getGridSize(ss);
int edgeSize = ccgSubSurf_getEdgeSize(ss);
uint i = 0;
short *edgeFlags = ccgdm->edgeFlags;
totface = ccgSubSurf_getNumFaces(ss);
for (index = 0; index < totface; index++) {
@ -936,20 +934,17 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
for (x = 0; x < gridSize - 1; x++) {
ccgDM_to_MEdge(&medge[i++],
getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize),
getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize),
0);
getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize));
}
for (x = 1; x < gridSize - 1; x++) {
for (y = 0; y < gridSize - 1; y++) {
ccgDM_to_MEdge(&medge[i++],
getFaceIndex(ss, f, S, x, y, edgeSize, gridSize),
getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize),
0);
getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize));
ccgDM_to_MEdge(&medge[i++],
getFaceIndex(ss, f, S, y, x, edgeSize, gridSize),
getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize),
0);
getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize));
}
}
}
@ -958,21 +953,9 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
totedge = ccgSubSurf_getNumEdges(ss);
for (index = 0; index < totedge; index++) {
CCGEdge *e = ccgdm->edgeMap[index].edge;
short ed_flag = 0;
int x;
int edgeIdx = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e));
if (edgeFlags) {
if (edgeIdx != -1) {
ed_flag |= (edgeFlags[index] & ME_SEAM);
}
}
for (x = 0; x < edgeSize - 1; x++) {
ccgDM_to_MEdge(&medge[i++],
getEdgeIndex(ss, e, x, edgeSize),
getEdgeIndex(ss, e, x + 1, edgeSize),
ed_flag);
for (int x = 0; x < edgeSize - 1; x++) {
ccgDM_to_MEdge(
&medge[i++], getEdgeIndex(ss, e, x, edgeSize), getEdgeIndex(ss, e, x + 1, edgeSize));
}
}
}
@ -1216,7 +1199,6 @@ static void ccgDM_release(DerivedMesh *dm)
if (ccgdm->pmap_mem) {
MEM_freeN(ccgdm->pmap_mem);
}
MEM_freeN(ccgdm->edgeFlags);
MEM_freeN(ccgdm->faceFlags);
MEM_freeN(ccgdm->vertMap);
MEM_freeN(ccgdm->edgeMap);
@ -1586,7 +1568,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
int index;
int i;
int vertNum = 0, edgeNum = 0, faceNum = 0;
short *edgeFlags = ccgdm->edgeFlags;
DMFlagMat *faceFlags = ccgdm->faceFlags;
int *polyidx = nullptr;
blender::Vector<int, 16> loopidx;
@ -1598,7 +1579,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
int gridSideEdges;
int gridInternalEdges;
WeightTable wtable = {nullptr};
MEdge *medge = nullptr;
bool has_edge_cd;
edgeSize = ccgSubSurf_getEdgeSize(ss);
@ -1609,8 +1589,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
gridSideEdges = gridSize - 1;
gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
medge = dm->getEdgeArray(dm);
const MPoly *mpoly = static_cast<const MPoly *>(CustomData_get_layer(&dm->polyData, CD_MPOLY));
const int *material_indices = static_cast<const int *>(
CustomData_get_layer_named(&dm->polyData, CD_MPOLY, "material_index"));
@ -1789,10 +1767,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
ccgdm->edgeMap[index].startVert = vertNum;
ccgdm->edgeMap[index].startEdge = edgeNum;
if (edgeIdx >= 0 && edgeFlags) {
edgeFlags[edgeIdx] = medge[edgeIdx].flag;
}
/* set the edge base vert */
*((int *)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
@ -1874,6 +1848,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
CCGDerivedMesh *ccgdm = MEM_cnew<CCGDerivedMesh>(__func__);
BLI_assert(totedge == ccgSubSurf_getNumEdges(ss));
UNUSED_VARS_NDEBUG(totedge);
BLI_assert(totface == ccgSubSurf_getNumFaces(ss));
DM_from_template(&ccgdm->dm,
dm,
@ -1896,7 +1871,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
ccgdm->useSubsurfUv = useSubsurfUv;
/* CDDM hack. */
ccgdm->edgeFlags = static_cast<short *>(MEM_callocN(sizeof(short) * totedge, "edgeFlags"));
ccgdm->faceFlags = static_cast<DMFlagMat *>(
MEM_callocN(sizeof(DMFlagMat) * totface, "faceFlags"));

View File

@ -178,6 +178,8 @@ set(SRC
BLI_assert.h
BLI_astar.h
BLI_atomic_disjoint_set.hh
BLI_bit_ref.hh
BLI_bit_span.hh
BLI_bit_vector.hh
BLI_bitmap.h
BLI_bitmap_draw_2d.h

View File

@ -288,6 +288,26 @@ struct LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh);
*/
void BLO_blendhandle_close(BlendHandle *bh);
/** Mark the given Main (and the 'root' local one in case of lib-split Mains) as invalid, and
* generate an error report containing given `message`. */
void BLO_read_invalidate_message(BlendHandle *bh, struct Main *bmain, const char *message);
/**
* BLI_assert-like macro to check a condition, and if `false`, fail the whole .blend reading
* process by marking the Main data-base as invalid, and returning provided `_ret_value`.
*
* NOTE: About usages:
* - #BLI_assert should be used when the error is considered as a bug, but there is some code to
* recover from it and produce a valid Main data-base.
* - #BLO_read_assert_message should be used when the error is not considered as recoverable.
*/
#define BLO_read_assert_message(_check_expr, _ret_value, _bh, _bmain, _message) \
if (_check_expr) { \
BLO_read_invalidate_message((_bh), (_bmain), (_message)); \
return _ret_value; \
} \
(void)0
/** \} */
#define BLO_GROUP_MAX 32

View File

@ -385,6 +385,13 @@ void BLO_blendhandle_close(BlendHandle *bh)
blo_filedata_free(fd);
}
void BLO_read_invalidate_message(BlendHandle *bh, Main *bmain, const char *message)
{
FileData *fd = reinterpret_cast<FileData *>(bh);
blo_readfile_invalidate(fd, bmain, message);
}
/**********/
BlendFileData *BLO_read_from_file(const char *filepath,

View File

@ -320,6 +320,10 @@ static void add_main_to_main(Main *mainvar, Main *from)
ListBase *lbarray[INDEX_ID_MAX], *fromarray[INDEX_ID_MAX];
int a;
if (from->is_read_invalid) {
mainvar->is_read_invalid = true;
}
set_listbasepointers(mainvar, lbarray);
a = set_listbasepointers(from, fromarray);
while (a--) {
@ -340,6 +344,9 @@ void blo_join_main(ListBase *mainlist)
}
while ((tojoin = mainl->next)) {
if (tojoin->is_read_invalid) {
mainl->is_read_invalid = true;
}
add_main_to_main(mainl, tojoin);
BLI_remlink(mainlist, tojoin);
BKE_main_free(tojoin);
@ -548,6 +555,21 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab
return m;
}
void blo_readfile_invalidate(FileData *fd, Main *bmain, const char *message)
{
/* Tag given bmain, and 'root 'local' main one (in case given one is a library one) as invalid.
*/
bmain->is_read_invalid = true;
for (; bmain->prev != nullptr; bmain = bmain->prev)
;
bmain->is_read_invalid = true;
BLO_reportf_wrap(fd->reports,
RPT_ERROR,
"A critical error happened (the blend file is likely corrupted): %s",
message);
}
/** \} */
/* -------------------------------------------------------------------- */
@ -3564,15 +3586,33 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
main->build_hash);
}
blo_do_versions_pre250(fd, lib, main);
blo_do_versions_250(fd, lib, main);
blo_do_versions_260(fd, lib, main);
blo_do_versions_270(fd, lib, main);
blo_do_versions_280(fd, lib, main);
blo_do_versions_290(fd, lib, main);
blo_do_versions_300(fd, lib, main);
blo_do_versions_400(fd, lib, main);
blo_do_versions_cycles(fd, lib, main);
if (!main->is_read_invalid) {
blo_do_versions_pre250(fd, lib, main);
}
if (!main->is_read_invalid) {
blo_do_versions_250(fd, lib, main);
}
if (!main->is_read_invalid) {
blo_do_versions_260(fd, lib, main);
}
if (!main->is_read_invalid) {
blo_do_versions_270(fd, lib, main);
}
if (!main->is_read_invalid) {
blo_do_versions_280(fd, lib, main);
}
if (!main->is_read_invalid) {
blo_do_versions_290(fd, lib, main);
}
if (!main->is_read_invalid) {
blo_do_versions_300(fd, lib, main);
}
if (!main->is_read_invalid) {
blo_do_versions_400(fd, lib, main);
}
if (!main->is_read_invalid) {
blo_do_versions_cycles(fd, lib, main);
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
@ -3582,7 +3622,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
main->is_locked_for_linking = false;
}
static void do_versions_after_linking(Main *main, ReportList *reports)
static void do_versions_after_linking(FileData *fd, Main *main)
{
CLOG_INFO(&LOG,
2,
@ -3595,13 +3635,27 @@ static void do_versions_after_linking(Main *main, ReportList *reports)
/* Don't allow versioning to create new data-blocks. */
main->is_locked_for_linking = true;
do_versions_after_linking_250(main);
do_versions_after_linking_260(main);
do_versions_after_linking_270(main);
do_versions_after_linking_280(main, reports);
do_versions_after_linking_290(main, reports);
do_versions_after_linking_300(main, reports);
do_versions_after_linking_cycles(main);
if (!main->is_read_invalid) {
do_versions_after_linking_250(main);
}
if (!main->is_read_invalid) {
do_versions_after_linking_260(main);
}
if (!main->is_read_invalid) {
do_versions_after_linking_270(main);
}
if (!main->is_read_invalid) {
do_versions_after_linking_280(fd, main);
}
if (!main->is_read_invalid) {
do_versions_after_linking_290(fd, main);
}
if (!main->is_read_invalid) {
do_versions_after_linking_300(fd, main);
}
if (!main->is_read_invalid) {
do_versions_after_linking_cycles(main);
}
main->is_locked_for_linking = false;
}
@ -3810,6 +3864,9 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
static void blo_read_file_checks(Main *bmain)
{
#ifndef NDEBUG
BLI_assert(bmain->next == nullptr);
BLI_assert(!bmain->is_read_invalid);
LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) {
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
/* This pointer is deprecated and should always be nullptr. */
@ -3914,6 +3971,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
bhead = read_libblock(fd, bfd->main, bhead, LIB_TAG_LOCAL, false, nullptr);
}
}
if (bfd->main->is_read_invalid) {
return bfd;
}
}
/* do before read_libraries, but skip undo case */
@ -3927,6 +3988,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
}
}
if (bfd->main->is_read_invalid) {
return bfd;
}
if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
fd->reports->duration.libraries = PIL_check_seconds_timer();
read_libraries(fd, &mainlist);
@ -3953,7 +4018,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
blo_split_main(&mainlist, bfd->main);
LISTBASE_FOREACH (Main *, mainvar, &mainlist) {
BLI_assert(mainvar->versionfile != 0);
do_versions_after_linking(mainvar, fd->reports->reports);
do_versions_after_linking(fd, mainvar);
}
blo_join_main(&mainlist);
@ -3963,6 +4028,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
BKE_main_id_refcount_recompute(bfd->main, false);
}
if (bfd->main->is_read_invalid) {
return bfd;
}
/* After all data has been read and versioned, uses LIB_TAG_NEW. Theoretically this should
* not be calculated in the undo case, but it is currently needed even on undo to recalculate
* a cache. */
@ -4174,6 +4243,10 @@ static void expand_doit_library(void *fdhandle, Main *mainvar, void *old)
{
FileData *fd = static_cast<FileData *>(fdhandle);
if (mainvar->is_read_invalid) {
return;
}
BHead *bhead = find_bhead(fd, old);
if (bhead == nullptr) {
return;
@ -4432,7 +4505,16 @@ ID *BLO_library_link_named_part(Main *mainl,
const LibraryLink_Params *params)
{
FileData *fd = (FileData *)(*bh);
return link_named_part(mainl, fd, idcode, name, params->flag);
ID *ret_id = nullptr;
if (!mainl->is_read_invalid) {
ret_id = link_named_part(mainl, fd, idcode, name, params->flag);
}
if (mainl->is_read_invalid) {
return nullptr;
}
return ret_id;
}
/* common routine to append/link something from a library */
@ -4562,6 +4644,10 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag)
mainvar = static_cast<Main *>((*fd)->mainlist->first);
mainl = nullptr; /* blo_join_main free's mainl, can't use anymore */
if (mainvar->is_read_invalid) {
return;
}
lib_link_all(*fd, mainvar);
after_liblink_merged_bmain_process(mainvar);
@ -4582,9 +4668,13 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag)
* or they will go again through do_versions - bad, very bad! */
split_main_newid(mainvar, main_newid);
do_versions_after_linking(main_newid, (*fd)->reports->reports);
do_versions_after_linking(*fd, main_newid);
add_main_to_main(mainvar, main_newid);
if (mainvar->is_read_invalid) {
return;
}
}
blo_join_main((*fd)->mainlist);
@ -4631,9 +4721,12 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag)
void BLO_library_link_end(Main *mainl, BlendHandle **bh, const LibraryLink_Params *params)
{
FileData *fd = (FileData *)(*bh);
library_link_end(mainl, &fd, params->flag);
*bh = (BlendHandle *)fd;
FileData *fd = reinterpret_cast<FileData *>(*bh);
if (!mainl->is_read_invalid) {
library_link_end(mainl, &fd, params->flag);
*bh = reinterpret_cast<BlendHandle *>(fd);
}
}
void *BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname)

View File

@ -219,9 +219,9 @@ void blo_do_versions_cycles(struct FileData *fd, struct Library *lib, struct Mai
void do_versions_after_linking_250(struct Main *bmain);
void do_versions_after_linking_260(struct Main *bmain);
void do_versions_after_linking_270(struct Main *bmain);
void do_versions_after_linking_280(struct Main *bmain, struct ReportList *reports);
void do_versions_after_linking_290(struct Main *bmain, struct ReportList *reports);
void do_versions_after_linking_300(struct Main *bmain, struct ReportList *reports);
void do_versions_after_linking_280(struct FileData *fd, struct Main *bmain);
void do_versions_after_linking_290(struct FileData *fd, struct Main *bmain);
void do_versions_after_linking_300(struct FileData *fd, struct Main *bmain);
void do_versions_after_linking_cycles(struct Main *bmain);
/**
@ -232,6 +232,10 @@ void do_versions_after_linking_cycles(struct Main *bmain);
*/
void *blo_read_get_new_globaldata_address(struct FileData *fd, const void *adr);
/* Mark the Main data as invalid (.blend file reading should be aborted ASAP, and the already read
* data should be discarded). Also add an error report to `fd` including given `message`. */
void blo_readfile_invalidate(struct FileData *fd, struct Main *bmain, const char *message);
#ifdef __cplusplus
}
#endif

View File

@ -1171,7 +1171,7 @@ static void do_version_fcurve_hide_viewport_fix(struct ID *UNUSED(id),
fcu->rna_path = BLI_strdupn("hide_viewport", 13);
}
void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
void do_versions_after_linking_280(FileData *fd, Main *bmain)
{
bool use_collection_compat_28 = true;
@ -1241,6 +1241,12 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
if (!MAIN_VERSION_ATLEAST(bmain, 280, 0)) {
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
BLO_read_assert_message(screen->scene == NULL,
,
(BlendHandle *)fd,
bmain,
"No Screen data-block should ever have a NULL `scene` pointer");
/* same render-layer as do_version_workspaces_after_lib_link will activate,
* so same layer as BKE_view_layer_default_view would return */
ViewLayer *layer = screen->scene->view_layers.first;

View File

@ -411,7 +411,7 @@ static void version_node_socket_duplicate(bNodeTree *ntree,
}
}
void do_versions_after_linking_290(Main *bmain, ReportList * /*reports*/)
void do_versions_after_linking_290(FileData * /*fd*/, Main *bmain)
{
if (!MAIN_VERSION_ATLEAST(bmain, 290, 1)) {
/* Patch old grease pencil modifiers material filter. */

View File

@ -939,7 +939,7 @@ static void version_geometry_nodes_primitive_uv_maps(bNodeTree &ntree)
}
}
void do_versions_after_linking_300(Main *bmain, ReportList * /*reports*/)
void do_versions_after_linking_300(FileData * /*fd*/, Main *bmain)
{
if (MAIN_VERSION_ATLEAST(bmain, 300, 0) && !MAIN_VERSION_ATLEAST(bmain, 300, 1)) {
/* Set zero user text objects to have a fake user. */

View File

@ -35,6 +35,7 @@ static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh)
BKE_mesh_legacy_sharp_edges_from_flags(&mesh);
BKE_mesh_legacy_face_set_to_generic(&mesh);
BKE_mesh_legacy_edge_crease_to_layers(&mesh);
BKE_mesh_legacy_uv_seam_from_flags(&mesh);
BKE_mesh_legacy_convert_verts_to_positions(&mesh);
BKE_mesh_legacy_attribute_flags_to_strings(&mesh);
BKE_mesh_legacy_convert_loops_to_corners(&mesh);

View File

@ -113,21 +113,11 @@ using blender::Span;
using blender::StringRef;
using blender::Vector;
static char bm_edge_flag_from_mflag(const short mflag)
{
return ((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | BM_ELEM_DRAW;
}
static char bm_face_flag_from_mflag(const char mflag)
{
return ((mflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0);
}
static short bm_edge_flag_to_mflag(const BMEdge *e)
{
const char hflag = e->head.hflag;
return (hflag & BM_ELEM_SEAM) ? ME_SEAM : 0;
}
static char bm_face_flag_to_mflag(const BMFace *f)
{
const char hflag = f->head.hflag;
@ -144,6 +134,7 @@ bool BM_attribute_stored_in_bmesh_builtin(const StringRef name)
".hide_vert",
".hide_edge",
".hide_poly",
".uv_seam",
".select_vert",
".select_edge",
".select_poly",
@ -441,6 +432,8 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
&me->pdata, CD_PROP_INT32, "material_index");
const bool *sharp_edges = (const bool *)CustomData_get_layer_named(
&me->edata, CD_PROP_BOOL, "sharp_edge");
const bool *uv_seams = (const bool *)CustomData_get_layer_named(
&me->edata, CD_PROP_BOOL, ".uv_seam");
const Span<float3> positions = me->vert_positions();
Array<BMVert *> vtable(me->totvert);
@ -486,8 +479,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
bm, vtable[medge[i].v1], vtable[medge[i].v2], nullptr, BM_CREATE_SKIP_CD);
BM_elem_index_set(e, i); /* set_ok */
/* Transfer flags. */
e->head.hflag = bm_edge_flag_from_mflag(medge[i].flag);
e->head.hflag = 0;
if (uv_seams && uv_seams[i]) {
BM_elem_flag_enable(e, BM_ELEM_SEAM);
}
if (hide_edge && hide_edge[i]) {
BM_elem_flag_enable(e, BM_ELEM_HIDDEN);
}
@ -1272,6 +1267,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
bool need_hide_poly = false;
bool need_material_index = false;
bool need_sharp_edge = false;
bool need_uv_seam = false;
i = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@ -1299,7 +1295,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
medge[i].v1 = BM_elem_index_get(e->v1);
medge[i].v2 = BM_elem_index_get(e->v2);
medge[i].flag = bm_edge_flag_to_mflag(e);
if (BM_elem_flag_test(e, BM_ELEM_SEAM)) {
need_uv_seam = true;
}
if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
need_hide_edge = true;
}
@ -1373,6 +1371,13 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
return !BM_elem_flag_test(BM_edge_at_index(bm, i), BM_ELEM_SMOOTH);
});
}
if (need_uv_seam) {
BM_mesh_elem_table_ensure(bm, BM_EDGE);
write_fn_to_attribute<bool>(
me->attributes_for_write(), ".uv_seam", ATTR_DOMAIN_EDGE, [&](const int i) {
return BM_elem_flag_test(BM_edge_at_index(bm, i), BM_ELEM_SEAM);
});
}
/* Patch hook indices and vertex parents. */
if (params->calc_object_remap && (ototvert > 0)) {
@ -1510,7 +1515,8 @@ static void bm_edge_table_build(BMesh &bm,
MutableSpan<const BMEdge *> table,
bool &need_select_edge,
bool &need_hide_edge,
bool &need_sharp_edge)
bool &need_sharp_edge,
bool &need_uv_seams)
{
char hflag = 0;
BMIter iter;
@ -1524,6 +1530,7 @@ static void bm_edge_table_build(BMesh &bm,
need_select_edge = (hflag & BM_ELEM_SELECT) != 0;
need_hide_edge = (hflag & BM_ELEM_HIDDEN) != 0;
need_sharp_edge = (hflag & BM_ELEM_SMOOTH) != 0;
need_uv_seams = (hflag & BM_ELEM_SEAM) != 0;
}
static void bm_face_loop_table_build(BMesh &bm,
@ -1588,7 +1595,8 @@ static void bm_to_mesh_edges(const BMesh &bm,
Mesh &mesh,
MutableSpan<bool> select_edge,
MutableSpan<bool> hide_edge,
MutableSpan<bool> sharp_edge)
MutableSpan<bool> sharp_edge,
MutableSpan<bool> uv_seams)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.edata, mesh.edata);
MutableSpan<MEdge> dst_edges = mesh.edges_for_write();
@ -1598,7 +1606,6 @@ static void bm_to_mesh_edges(const BMesh &bm,
MEdge &dst_edge = dst_edges[edge_i];
dst_edge.v1 = BM_elem_index_get(src_edge.v1);
dst_edge.v2 = BM_elem_index_get(src_edge.v2);
dst_edge.flag = bm_edge_flag_to_mflag(&src_edge);
bmesh_block_copy_to_mesh_attributes(info, edge_i, src_edge.head.data);
}
if (!select_edge.is_empty()) {
@ -1616,6 +1623,11 @@ static void bm_to_mesh_edges(const BMesh &bm,
sharp_edge[edge_i] = !BM_elem_flag_test(bm_edges[edge_i], BM_ELEM_SMOOTH);
}
}
if (!uv_seams.is_empty()) {
for (const int edge_i : range) {
uv_seams[edge_i] = BM_elem_flag_test(bm_edges[edge_i], BM_ELEM_SEAM);
}
}
});
}
@ -1730,6 +1742,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
bool need_hide_poly = false;
bool need_material_index = false;
bool need_sharp_edge = false;
bool need_uv_seams = false;
Array<const BMVert *> vert_table;
Array<const BMEdge *> edge_table;
Array<const BMFace *> face_table;
@ -1742,7 +1755,8 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
},
[&]() {
edge_table.reinitialize(bm->totedge);
bm_edge_table_build(*bm, edge_table, need_select_edge, need_hide_edge, need_sharp_edge);
bm_edge_table_build(
*bm, edge_table, need_select_edge, need_hide_edge, need_sharp_edge, need_uv_seams);
},
[&]() {
face_table.reinitialize(bm->totface);
@ -1760,6 +1774,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
bke::SpanAttributeWriter<bool> select_edge;
bke::SpanAttributeWriter<bool> hide_edge;
bke::SpanAttributeWriter<bool> sharp_edge;
bke::SpanAttributeWriter<bool> uv_seams;
bke::SpanAttributeWriter<bool> select_poly;
bke::SpanAttributeWriter<bool> hide_poly;
bke::SpanAttributeWriter<int> material_index;
@ -1775,6 +1790,9 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
if (need_sharp_edge) {
sharp_edge = attrs.lookup_or_add_for_write_only_span<bool>("sharp_edge", ATTR_DOMAIN_EDGE);
}
if (need_uv_seams) {
uv_seams = attrs.lookup_or_add_for_write_only_span<bool>(".uv_seam", ATTR_DOMAIN_EDGE);
}
if (need_hide_edge) {
hide_edge = attrs.lookup_or_add_for_write_only_span<bool>(".hide_edge", ATTR_DOMAIN_EDGE);
}
@ -1794,7 +1812,13 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
me->totvert > 1024,
[&]() { bm_to_mesh_verts(*bm, vert_table, *me, select_vert.span, hide_vert.span); },
[&]() {
bm_to_mesh_edges(*bm, edge_table, *me, select_edge.span, hide_edge.span, sharp_edge.span);
bm_to_mesh_edges(*bm,
edge_table,
*me,
select_edge.span,
hide_edge.span,
sharp_edge.span,
uv_seams.span);
},
[&]() {
bm_to_mesh_faces(
@ -1807,6 +1831,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
select_edge.finish();
hide_edge.finish();
sharp_edge.finish();
uv_seams.finish();
select_poly.finish();
hide_poly.finish();
material_index.finish();

View File

@ -10,9 +10,9 @@ set(INC
../../bmesh
../../depsgraph
../../draw
../../functions
../../geometry
../../gpu
../../functions
../../imbuf
../../makesdna
../../makesrna

View File

@ -224,10 +224,11 @@ static void build_poly_connections(blender::AtomicDisjointSet &islands,
{
using namespace blender;
const Span<MPoly> polys = mesh.polys();
const Span<MEdge> edges = mesh.edges();
const Span<int> corner_edges = mesh.corner_edges();
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
const bke::AttributeAccessor attributes = mesh.attributes();
const VArray<bool> uv_seams = attributes.lookup_or_default<bool>(
".uv_seam", ATTR_DOMAIN_EDGE, false);
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
@ -243,7 +244,7 @@ static void build_poly_connections(blender::AtomicDisjointSet &islands,
for (const int poly_loop_index : poly_edges.index_range()) {
const int outer_edge = poly_edges[poly_loop_index];
if (skip_seams && (edges[outer_edge].flag & ME_SEAM) != 0) {
if (skip_seams && uv_seams[outer_edge]) {
continue;
}
@ -252,7 +253,7 @@ static void build_poly_connections(blender::AtomicDisjointSet &islands,
if (outer_edge == inner_edge) {
continue;
}
if (skip_seams && (edges[inner_edge].flag & ME_SEAM) != 0) {
if (skip_seams && uv_seams[inner_edge]) {
continue;
}
islands.join(inner_edge, outer_edge);
@ -277,6 +278,8 @@ static void paintface_select_linked_faces(Mesh &mesh,
const Span<int> corner_edges = mesh.corner_edges();
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
const VArray<bool> uv_seams = attributes.lookup_or_default<bool>(
".uv_seam", ATTR_DOMAIN_EDGE, false);
bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
".select_poly", ATTR_DOMAIN_FACE);
@ -284,7 +287,7 @@ static void paintface_select_linked_faces(Mesh &mesh,
for (const int i : face_indices) {
const MPoly &poly = polys[i];
for (const int edge : corner_edges.slice(poly.loopstart, poly.totloop)) {
if ((edges[edge].flag & ME_SEAM) != 0) {
if (uv_seams[edge]) {
continue;
}
const int root = islands.find_root(edge);

View File

@ -679,10 +679,11 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
break;
}
case SCULPT_FACE_SETS_FROM_UV_SEAMS: {
const Span<MEdge> edges = mesh->edges();
const VArraySpan<bool> uv_seams = mesh->attributes().lookup_or_default<bool>(
".uv_seam", ATTR_DOMAIN_EDGE, false);
sculpt_face_sets_init_flood_fill(
ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool {
return (edges[edge].flag & ME_SEAM) == 0;
return !uv_seams[edge];
});
break;
}

View File

@ -1441,8 +1441,6 @@ static void customdata_weld(
int src_i, dest_i;
int j;
short flag = 0;
/* interpolates a layer at a time */
dest_i = 0;
for (src_i = 0; src_i < source->totlayer; src_i++) {
@ -1464,10 +1462,7 @@ static void customdata_weld(
if (dest->layers[dest_i].type == type) {
void *src_data = source->layers[src_i].data;
if (type == CD_MEDGE) {
for (j = 0; j < count; j++) {
MEdge *me_src = &((MEdge *)src_data)[src_indices[j]];
flag |= me_src->flag;
}
/* Pass. */
}
else if (CustomData_layer_has_interp(dest, dest_i)) {
/* Already calculated.
@ -1500,8 +1495,7 @@ static void customdata_weld(
CustomDataLayer *layer_dst = &dest->layers[dest_i];
const int type = layer_dst->type;
if (type == CD_MEDGE) {
MEdge *me = &((MEdge *)layer_dst->data)[dest_index];
me->flag = flag;
/* Pass. */
}
else if (CustomData_layer_has_interp(dest, dest_i)) {
/* Already calculated. */

View File

@ -6,10 +6,7 @@
#include "GEO_uv_parametrizer.h"
#include "MEM_guardedalloc.h"
#include "BLI_array.hh"
#include "BLI_boxpack_2d.h"
#include "BLI_convexhull_2d.h"
#include "BLI_ghash.h"
#include "BLI_heap.h"
@ -19,6 +16,8 @@
#include "BLI_rand.h"
#include "BLI_vector.hh"
#include "GEO_uv_pack.hh"
#include "eigen_capi.h"
/* Utils */
@ -136,20 +135,18 @@ struct PChart {
PEdge *collapsed_edges;
PFace *collapsed_faces;
float area_uv;
float area_3d;
float origin[2];
union PChartUnion {
struct PChartLscm {
LinearSolver *context;
float *abf_alpha;
PVert *pin1, *pin2;
PVert *single_pin;
float single_pin_area;
float single_pin_uv[2];
} lscm;
struct PChartPack {
float rescale, area;
float size[2];
float origin[2];
} pack;
} u;
bool has_pins;
@ -3019,7 +3016,7 @@ static void p_chart_lscm_begin(PChart *chart, bool live, bool abf)
#endif
if (npins == 1) {
chart->u.lscm.single_pin_area = p_chart_uv_area(chart);
chart->area_uv = p_chart_uv_area(chart);
for (v = chart->verts; v; v = v->nextlink) {
if (v->flag & PVERT_PIN) {
chart->u.lscm.single_pin = v;
@ -3069,8 +3066,8 @@ static bool p_chart_lscm_solve(ParamHandle *handle, PChart *chart)
}
if (chart->u.lscm.single_pin) {
/* If only one pin, save pin location for transform later. */
copy_v2_v2(chart->u.lscm.single_pin_uv, chart->u.lscm.single_pin->uv);
/* If only one pin, save location as origin. */
copy_v2_v2(chart->origin, chart->u.lscm.single_pin->uv);
}
if (chart->u.lscm.pin1) {
@ -3204,15 +3201,15 @@ static void p_chart_lscm_transform_single_pin(PChart *chart)
/* If only one pin, keep UV area the same. */
const float new_area = p_chart_uv_area(chart);
if (new_area > 0.0f) {
const float scale = chart->u.lscm.single_pin_area / new_area;
const float scale = chart->area_uv / new_area;
if (scale > 0.0f) {
p_chart_uv_scale(chart, sqrtf(scale));
}
}
/* Translate to keep the pinned vertex in place. */
/* Translate to keep the pinned UV in place. */
float offset[2];
sub_v2_v2v2(offset, chart->u.lscm.single_pin_uv, pin->uv);
sub_v2_v2v2(offset, chart->origin, pin->uv);
p_chart_uv_translate(chart, offset);
}
@ -3226,7 +3223,6 @@ static void p_chart_lscm_end(PChart *chart)
chart->u.lscm.pin1 = nullptr;
chart->u.lscm.pin2 = nullptr;
chart->u.lscm.single_pin = nullptr;
chart->u.lscm.single_pin_area = 0.0f;
}
/* Stretch */
@ -4150,15 +4146,6 @@ void GEO_uv_parametrizer_pack(ParamHandle *handle,
bool do_rotate,
bool ignore_pinned)
{
/* box packing variables */
BoxPack *boxarray, *box;
float tot_width, tot_height, scale;
PChart *chart;
int i, unpacked = 0;
float trans[2];
double area = 0.0;
if (handle->ncharts == 0) {
return;
}
@ -4171,80 +4158,84 @@ void GEO_uv_parametrizer_pack(ParamHandle *handle,
if (handle->aspx != handle->aspy) {
GEO_uv_parametrizer_scale(handle, 1.0f / handle->aspx, 1.0f / handle->aspy);
}
/* we may not use all these boxes */
boxarray = (BoxPack *)MEM_mallocN(handle->ncharts * sizeof(BoxPack), "BoxPack box");
for (i = 0; i < handle->ncharts; i++) {
chart = handle->charts[i];
blender::Vector<blender::geometry::PackIsland *> pack_island_vector;
int unpacked = 0;
for (int i = 0; i < handle->ncharts; i++) {
PChart *chart = handle->charts[i];
if (ignore_pinned && chart->has_pins) {
unpacked++;
continue;
}
box = boxarray + (i - unpacked);
blender::geometry::PackIsland *pack_island = new blender::geometry::PackIsland();
pack_island_vector.append(pack_island);
p_chart_uv_bbox(chart, trans, chart->u.pack.size);
float minv[2];
float maxv[2];
p_chart_uv_bbox(chart, minv, maxv);
pack_island->bounds_rect.xmin = minv[0];
pack_island->bounds_rect.ymin = minv[1];
pack_island->bounds_rect.xmax = maxv[0];
pack_island->bounds_rect.ymax = maxv[1];
}
trans[0] = -trans[0];
trans[1] = -trans[1];
UVPackIsland_Params params{};
params.rotate = do_rotate;
params.only_selected_uvs = false;
params.only_selected_faces = false;
params.use_seams = false;
params.correct_aspect = false;
params.ignore_pinned = false;
params.pin_unselected = false;
params.margin = margin;
params.margin_method = ED_UVPACK_MARGIN_SCALED;
params.udim_base_offset[0] = 0.0f;
params.udim_base_offset[1] = 0.0f;
p_chart_uv_translate(chart, trans);
float scale[2] = {1.0f, 1.0f};
BoxPack *box_array = pack_islands(pack_island_vector, params, scale);
box->w = chart->u.pack.size[0] + trans[0];
box->h = chart->u.pack.size[1] + trans[1];
box->index = i; /* Warning this index skips chart->has_pins boxes. */
for (int64_t i : pack_island_vector.index_range()) {
BoxPack *box = box_array + i;
blender::geometry::PackIsland *pack_island = pack_island_vector[box->index];
pack_island->bounds_rect.xmin = box->x;
pack_island->bounds_rect.ymin = box->y;
pack_island->bounds_rect.xmax = box->x + box->w;
pack_island->bounds_rect.ymax = box->y + box->h;
}
if (margin > 0.0f) {
area += double(sqrtf(box->w * box->h));
unpacked = 0;
for (int i = 0; i < handle->ncharts; i++) {
PChart *chart = handle->charts[i];
if (ignore_pinned && chart->has_pins) {
unpacked++;
continue;
}
}
blender::geometry::PackIsland *pack_island = pack_island_vector[i - unpacked];
if (margin > 0.0f) {
/* multiply the margin by the area to give predictable results not dependent on UV scale,
* ...Without using the area running pack multiple times also gives a bad feedback loop.
* multiply by 0.1 so the margin value from the UI can be from
* 0.0 to 1.0 but not give a massive margin */
margin = (margin * float(area)) * 0.1f;
unpacked = 0;
for (i = 0; i < handle->ncharts; i++) {
chart = handle->charts[i];
float minv[2];
float maxv[2];
p_chart_uv_bbox(chart, minv, maxv);
if (ignore_pinned && chart->has_pins) {
unpacked++;
continue;
}
box = boxarray + (i - unpacked);
trans[0] = margin;
trans[1] = margin;
p_chart_uv_translate(chart, trans);
box->w += margin * 2;
box->h += margin * 2;
/* TODO: Replace with #mul_v2_m2_add_v2v2 here soon. */
float m[2];
float b[2];
m[0] = scale[0];
m[1] = scale[1];
b[0] = pack_island->bounds_rect.xmin - minv[0];
b[1] = pack_island->bounds_rect.ymin - minv[1];
for (PVert *v = chart->verts; v; v = v->nextlink) {
/* Unusual accumulate-and-multiply here (will) reduce round-off error. */
v->uv[0] = m[0] * (v->uv[0] + b[0]);
v->uv[1] = m[1] * (v->uv[1] + b[1]);
}
pack_island_vector[i - unpacked] = nullptr;
delete pack_island;
}
BLI_box_pack_2d(boxarray, handle->ncharts - unpacked, &tot_width, &tot_height);
if (tot_height > tot_width) {
scale = tot_height != 0.0f ? (1.0f / tot_height) : 1.0f;
}
else {
scale = tot_width != 0.0f ? (1.0f / tot_width) : 1.0f;
}
for (i = 0; i < handle->ncharts - unpacked; i++) {
box = boxarray + i;
trans[0] = box->x;
trans[1] = box->y;
chart = handle->charts[box->index];
p_chart_uv_translate(chart, trans);
p_chart_uv_scale(chart, scale);
}
MEM_freeN(boxarray);
MEM_freeN(box_array);
if (handle->aspx != handle->aspy) {
GEO_uv_parametrizer_scale(handle, handle->aspx, handle->aspy);
}
@ -4255,10 +4246,9 @@ void GEO_uv_parametrizer_average(ParamHandle *phandle,
bool scale_uv,
bool shear)
{
PChart *chart;
int i;
float tot_uvarea = 0.0f, tot_facearea = 0.0f;
float tot_fac, fac;
float tot_area_3d = 0.0f;
float tot_area_uv = 0.0f;
float minv[2], maxv[2], trans[2];
if (phandle->ncharts == 0) {
@ -4266,14 +4256,15 @@ void GEO_uv_parametrizer_average(ParamHandle *phandle,
}
for (i = 0; i < phandle->ncharts; i++) {
chart = phandle->charts[i];
PChart *chart = phandle->charts[i];
if (ignore_pinned && chart->has_pins) {
continue;
}
/* Store original bounding box midpoint. */
p_chart_uv_bbox(chart, minv, maxv);
mid_v2_v2v2(chart->u.pack.origin, minv, maxv);
mid_v2_v2v2(chart->origin, minv, maxv);
if (scale_uv || shear) {
/* It's possible that for some "bad" inputs, the following iteration will converge slowly or
@ -4349,45 +4340,45 @@ void GEO_uv_parametrizer_average(ParamHandle *phandle,
}
}
chart->u.pack.area = 0.0f; /* 3d area */
chart->u.pack.rescale = 0.0f; /* UV area, abusing rescale for tmp storage, oh well :/ */
chart->area_3d = 0.0f;
chart->area_uv = 0.0f;
for (PFace *f = chart->faces; f; f = f->nextlink) {
chart->u.pack.area += p_face_area(f);
chart->u.pack.rescale += fabsf(p_face_uv_area_signed(f));
chart->area_3d += p_face_area(f);
chart->area_uv += fabsf(p_face_uv_area_signed(f));
}
tot_facearea += chart->u.pack.area;
tot_uvarea += chart->u.pack.rescale;
tot_area_3d += chart->area_3d;
tot_area_uv += chart->area_uv;
}
if (tot_facearea == tot_uvarea || tot_facearea == 0.0f || tot_uvarea == 0.0f) {
/* nothing to do */
if (tot_area_3d == 0.0f || tot_area_uv == 0.0f) {
/* Prevent divide by zero. */
return;
}
tot_fac = tot_facearea / tot_uvarea;
const float tot_fac = tot_area_3d / tot_area_uv;
for (i = 0; i < phandle->ncharts; i++) {
chart = phandle->charts[i];
PChart *chart = phandle->charts[i];
if (ignore_pinned && chart->has_pins) {
continue;
}
if (chart->u.pack.area != 0.0f && chart->u.pack.rescale != 0.0f) {
fac = chart->u.pack.area / chart->u.pack.rescale;
if (chart->area_3d != 0.0f && chart->area_uv != 0.0f) {
const float fac = chart->area_3d / chart->area_uv;
/* Average scale. */
p_chart_uv_scale(chart, sqrtf(fac / tot_fac));
/* Get the current island center. */
/* Get the current island bounding box. */
p_chart_uv_bbox(chart, minv, maxv);
/* Move to original center. */
/* Move back to original midpoint. */
mid_v2_v2v2(trans, minv, maxv);
negate_v2(trans);
add_v2_v2(trans, chart->u.pack.origin);
sub_v2_v2v2(trans, chart->origin, trans);
p_chart_uv_translate(chart, trans);
}
}

View File

@ -384,7 +384,7 @@ static void build_sequential(Object *ob,
/* Cycling backwards through zero-points to fix them. */
for (int k = 0; k < zeropoints; k++) {
float linear_fill = interpf(
deltatime, 0, ((float)k + 1) / (zeropoints + 1)); /* Factor = Proportion. */
0, deltatime, ((float)k + 1) / (zeropoints + 1)); /* Factor = Proportion. */
idx_times[curpoint - k - 1] = sumtime + linear_fill;
}
}

View File

@ -192,17 +192,17 @@ set(VULKAN_SRC
vulkan/vk_backend.cc
vulkan/vk_batch.cc
vulkan/vk_buffer.cc
vulkan/vk_context.cc
vulkan/vk_command_buffer.cc
vulkan/vk_common.cc
vulkan/vk_context.cc
vulkan/vk_descriptor_pools.cc
vulkan/vk_descriptor_set.cc
vulkan/vk_drawlist.cc
vulkan/vk_fence.cc
vulkan/vk_framebuffer.cc
vulkan/vk_index_buffer.cc
vulkan/vk_pipeline.cc
vulkan/vk_memory.cc
vulkan/vk_pipeline.cc
vulkan/vk_pixel_buffer.cc
vulkan/vk_query.cc
vulkan/vk_shader.cc
@ -217,17 +217,17 @@ set(VULKAN_SRC
vulkan/vk_backend.hh
vulkan/vk_batch.hh
vulkan/vk_buffer.hh
vulkan/vk_context.hh
vulkan/vk_command_buffer.hh
vulkan/vk_common.hh
vulkan/vk_context.hh
vulkan/vk_descriptor_pools.hh
vulkan/vk_descriptor_set.hh
vulkan/vk_drawlist.hh
vulkan/vk_fence.hh
vulkan/vk_framebuffer.hh
vulkan/vk_index_buffer.hh
vulkan/vk_pipeline.hh
vulkan/vk_memory.hh
vulkan/vk_pipeline.hh
vulkan/vk_pixel_buffer.hh
vulkan/vk_query.hh
vulkan/vk_shader.hh
@ -302,7 +302,7 @@ endif()
if(WITH_VULKAN_BACKEND)
list(APPEND INC
../../../extern/vulkan_memory_allocator/
../../../extern/vulkan_memory_allocator
)
list(APPEND INC_SYS
${VULKAN_INCLUDE_DIRS}

View File

@ -19,6 +19,7 @@ extern "C" {
struct Collection;
struct Object;
struct GHash;
typedef struct CollectionObject {
struct CollectionObject *next, *prev;
@ -61,6 +62,9 @@ typedef struct Collection_Runtime {
/** List of collections that are a parent of this data-block. */
ListBase parents;
/** An optional map for faster lookups on #Collection.gobject */
struct GHash *gobject_hash;
uint8_t tag;
char _pad0[7];

View File

@ -32,23 +32,23 @@ typedef struct MEdge {
* Deprecated bevel weight storage, now located in #CD_BWEIGHT, except for file read and write.
*/
char bweight_legacy;
short flag;
short flag_legacy;
} MEdge;
#ifdef DNA_DEPRECATED_ALLOW
/** #MEdge.flag */
enum {
/** Deprecated selection status. Now stored in ".select_edge" attribute. */
/* SELECT = (1 << 0), */
ME_SEAM = (1 << 2),
/** Deprecated hide status. Now stored in ".hide_edge" attribute. */
/* ME_HIDE = (1 << 4), */
#ifdef DNA_DEPRECATED_ALLOW
/** Deprecated hide status. Now stored in ".hide_edge" attribute. */
/* ME_HIDE = (1 << 4), */
/** Deprecated loose edge status. Now stored in #Mesh::loose_edges() runtime cache. */
ME_LOOSEEDGE = (1 << 7),
/** Deprecated sharp edge status. Now stored in "sharp_edge" attribute. */
ME_SHARP = (1 << 9),
#endif
};
#endif
/**
* Mesh Faces.

View File

@ -89,6 +89,7 @@ DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_mask, material_m
DNA_STRUCT_RENAME_ELEM(MDefCell, totinfluence, influences_num)
DNA_STRUCT_RENAME_ELEM(MEdge, bweight, bweight_legacy)
DNA_STRUCT_RENAME_ELEM(MEdge, crease, crease_legacy)
DNA_STRUCT_RENAME_ELEM(MEdge, flag, flag_legacy)
DNA_STRUCT_RENAME_ELEM(MPoly, mat_nr, mat_nr_legacy)
DNA_STRUCT_RENAME_ELEM(MVert, bweight, bweight_legacy)
DNA_STRUCT_RENAME_ELEM(MVert, co, co_legacy)

View File

@ -1759,6 +1759,32 @@ static void rna_MeshEdge_use_edge_sharp_set(PointerRNA *ptr, bool value)
sharp_edge[index] = value;
}
static bool rna_MeshEdge_use_seam_get(PointerRNA *ptr)
{
const Mesh *mesh = rna_mesh(ptr);
const bool *seam_edge = (const bool *)CustomData_get_layer_named(
&mesh->edata, CD_PROP_BOOL, ".uv_seam");
const int index = rna_MeshEdge_index_get(ptr);
return seam_edge == NULL ? false : seam_edge[index];
}
static void rna_MeshEdge_use_seam_set(PointerRNA *ptr, bool value)
{
Mesh *mesh = rna_mesh(ptr);
bool *seam_edge = (bool *)CustomData_get_layer_named_for_write(
&mesh->edata, CD_PROP_BOOL, ".uv_seam", mesh->totedge);
if (!seam_edge) {
if (!value) {
/* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
return;
}
seam_edge = (bool *)CustomData_add_layer_named(
&mesh->edata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, mesh->totedge, ".uv_seam");
}
const int index = rna_MeshEdge_index_get(ptr);
seam_edge[index] = value;
}
static bool rna_MeshEdge_is_loose_get(PointerRNA *ptr)
{
const Mesh *mesh = rna_mesh(ptr);
@ -2732,7 +2758,7 @@ static void rna_def_medge(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
prop = RNA_def_property(srna, "use_seam", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SEAM);
RNA_def_property_boolean_funcs(prop, "rna_MeshEdge_use_seam_get", "rna_MeshEdge_use_seam_set");
RNA_def_property_ui_text(prop, "Seam", "Seam edge for UV unwrapping");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");

View File

@ -7224,7 +7224,7 @@ static void rna_def_scene_display(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SCENE | NA_EDITED, "rna_Scene_set_update");
prop = RNA_def_property(srna, "matcap_ssao_distance", PROP_FLOAT, PROP_NONE);
prop = RNA_def_property(srna, "matcap_ssao_distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_ui_text(
prop, "Distance", "Distance of object that contribute to the Cavity/Edge effect");
RNA_def_property_range(prop, 0.0f, 100000.0f);

View File

@ -590,7 +590,6 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh,
cut_edge.v1 = dst_corner_verts[mp_dst.loopstart];
cut_edge.v2 = dst_corner_verts[i_ml_dst];
BLI_assert(cut_edge.v1 != cut_edge.v2);
cut_edge.flag = 0;
edge_index++;
/* Only handle one of the cuts per iteration. */

View File

@ -450,7 +450,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
for (uint i = 0; i < totedge; i++, med_orig++, med_new++) {
med_new->v1 = med_orig->v1;
med_new->v2 = med_orig->v2;
med_new->flag = med_orig->flag;
}
/* build polygon -> edge map */
@ -802,7 +801,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* add the new edge */
med_new->v1 = varray_stride + j;
med_new->v2 = med_new->v1 - totvert;
med_new->flag = 0;
med_new++;
}
}
@ -820,7 +818,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
for (uint i = 0; i < totvert; i++) {
med_new->v1 = i;
med_new->v2 = varray_stride + i;
med_new->flag = 0;
med_new++;
}
}
@ -947,7 +944,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
if (step) { /* The first set is already done */
med_new->v1 = i1;
med_new->v2 = i2;
med_new->flag = med_new_firstloop->flag;
med_new++;
}
i1 += totvert;
@ -975,7 +971,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* new vertical edge */
med_new->v1 = i1;
med_new->v2 = i2;
med_new->flag = med_new_firstloop->flag;
med_new++;
}

View File

@ -2073,7 +2073,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
BLI_assert(v2 != MOD_SOLIDIFY_EMPTY_TAG);
edges[insert].v1 = v1;
edges[insert].v2 = v2;
edges[insert].flag = orig_edges[(*l)->old_edge].flag;
if (result_edge_crease) {
result_edge_crease[insert] = orig_edge_crease ? orig_edge_crease[(*l)->old_edge] :
0.0f;
@ -2162,14 +2161,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
float max_bweight;
float last_max_bweight = 0.0f;
float first_max_bweight = 0.0f;
short flag;
short last_flag = 0;
short first_flag = 0;
for (uint j = 0; g->valid; g++) {
if ((do_rim && !g->is_orig_closed) || (do_shell && g->split)) {
max_crease = 0;
max_bweight = 0;
flag = 0;
BLI_assert(g->edges_len >= 2);
@ -2187,7 +2182,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
else {
for (uint k = 1; k < g->edges_len - 1; k++) {
const uint orig_edge_index = g->edges[k]->old_edge;
const MEdge *ed = &orig_edges[orig_edge_index];
if (result_edge_crease) {
if (orig_edge_crease && orig_edge_crease[orig_edge_index] > max_crease) {
max_crease = orig_edge_crease[orig_edge_index];
@ -2201,7 +2195,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
}
}
flag |= ed->flag;
}
}
@ -2222,7 +2215,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
first_g = g;
first_max_crease = max_crease;
first_max_bweight = max_bweight;
first_flag = flag;
}
else {
last_g->open_face_edge = edge_index;
@ -2236,7 +2228,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
edges[edge_index].v1 = last_g->new_vert;
edges[edge_index].v2 = g->new_vert;
edges[edge_index].flag = ((last_flag | flag) & ME_SEAM);
if (result_edge_crease) {
result_edge_crease[edge_index] = max_ff(mv_crease,
min_ff(last_max_crease, max_crease));
@ -2250,7 +2241,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
last_g = g;
last_max_crease = max_crease;
last_max_bweight = max_bweight;
last_flag = flag;
j++;
}
if (!(g + 1)->valid || g->topo_group != (g + 1)->topo_group) {
@ -2269,7 +2259,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
last_g->open_face_edge = edge_index;
edges[edge_index].v1 = last_g->new_vert;
edges[edge_index].v2 = first_g->new_vert;
edges[edge_index].flag = ((last_flag | first_flag) & ME_SEAM);
if (result_edge_crease) {
result_edge_crease[edge_index] = max_ff(mv_crease,
min_ff(last_max_crease, first_max_crease));
@ -2373,8 +2362,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
first_max_crease = 0;
last_max_bweight = 0;
first_max_bweight = 0;
last_flag = 0;
first_flag = 0;
}
}
}

View File

@ -152,7 +152,6 @@ static MEdge new_edge(const int v1, const int v2)
MEdge edge;
edge.v1 = v1;
edge.v2 = v2;
edge.flag = 0;
return edge;
}

View File

@ -231,6 +231,89 @@ static PyObject *pygpu_batch_draw(BPyGPUBatch *self, PyObject *args)
Py_RETURN_NONE;
}
PyDoc_STRVAR(
pygpu_batch_draw_instanced_doc,
".. method:: draw_instanced(program, *, instance_start=0, instance_count=0)\n"
"\n"
" Draw multiple instances of the drawing program with the parameters assigned\n"
" to the batch. In the vertex shader, `gl_InstanceID` will contain the instance\n"
" number being drawn.\n"
"\n"
" :arg program: Program that performs the drawing operations.\n"
" :type program: :class:`gpu.types.GPUShader`\n"
" :arg instance_start: Number of the first instance to draw.\n"
" :type instance_start: int\n"
" :arg instance_count: Number of instances to draw. When not provided or set to 0\n"
" the number of instances will be determined by the number of rows in the first\n"
" vertex buffer.\n"
" :type instance_count: int\n");
static PyObject *pygpu_batch_draw_instanced(BPyGPUBatch *self, PyObject *args, PyObject *kw)
{
BPyGPUShader *py_program = NULL;
int instance_start = 0;
int instance_count = 0;
static const char *_keywords[] = {"program", "instance_start", "instance_count", NULL};
static _PyArg_Parser _parser = {
"O!" /* `program` */
"|$" /* Optional keyword only arguments. */
"i" /* `instance_start` */
"i" /* `instance_count' */
":GPUBatch.draw_instanced",
_keywords,
0,
};
if (!_PyArg_ParseTupleAndKeywordsFast(
args, kw, &_parser, &BPyGPUShader_Type, &py_program, &instance_start, &instance_count)) {
return NULL;
}
GPU_batch_set_shader(self->batch, py_program->shader);
GPU_batch_draw_instance_range(self->batch, instance_start, instance_count);
Py_RETURN_NONE;
}
PyDoc_STRVAR(pygpu_batch_draw_range_doc,
".. method:: draw_range(program, *, elem_start=0, elem_count=0)\n"
"\n"
" Run the drawing program with the parameters assigned to the batch. Only draw\n"
" the `elem_count` elements of the index buffer starting at `elem_start` \n"
"\n"
" :arg program: Program that performs the drawing operations.\n"
" :type program: :class:`gpu.types.GPUShader`\n"
" :arg elem_start: First index to draw. When not provided or set to 0 drawing\n"
" will start from the first element of the index buffer.\n"
" :type elem_start: int\n"
" :arg elem_count: Number of elements of the index buffer to draw. When not\n"
" provided or set to 0 all elements from `elem_start` to the end of the\n"
" index buffer will be drawn.\n"
" :type elem_count: int\n");
static PyObject *pygpu_batch_draw_range(BPyGPUBatch *self, PyObject *args, PyObject *kw)
{
BPyGPUShader *py_program = NULL;
int elem_start = 0;
int elem_count = 0;
static const char *_keywords[] = {"program", "elem_start", "elem_count", NULL};
static _PyArg_Parser _parser = {
"O!" /* `program` */
"|$" /* Optional keyword only arguments. */
"i" /* `elem_start' */
"i" /* `elem_count' */
":GPUBatch.draw_range",
_keywords,
0,
};
if (!_PyArg_ParseTupleAndKeywordsFast(
args, kw, &_parser, &BPyGPUShader_Type, &py_program, &elem_start, &elem_count)) {
return NULL;
}
GPU_batch_set_shader(self->batch, py_program->shader);
GPU_batch_draw_range(self->batch, elem_start, elem_count);
Py_RETURN_NONE;
}
static PyObject *pygpu_batch_program_use_begin(BPyGPUBatch *self)
{
if (!pygpu_batch_is_program_or_error(self)) {
@ -253,6 +336,14 @@ static struct PyMethodDef pygpu_batch__tp_methods[] = {
{"vertbuf_add", (PyCFunction)pygpu_batch_vertbuf_add, METH_O, pygpu_batch_vertbuf_add_doc},
{"program_set", (PyCFunction)pygpu_batch_program_set, METH_O, pygpu_batch_program_set_doc},
{"draw", (PyCFunction)pygpu_batch_draw, METH_VARARGS, pygpu_batch_draw_doc},
{"draw_instanced",
(PyCFunction)pygpu_batch_draw_instanced,
METH_VARARGS | METH_KEYWORDS,
pygpu_batch_draw_instanced_doc},
{"draw_range",
(PyCFunction)pygpu_batch_draw_range,
METH_VARARGS | METH_KEYWORDS,
pygpu_batch_draw_range_doc},
{"_program_use_begin", (PyCFunction)pygpu_batch_program_use_begin, METH_NOARGS, ""},
{"_program_use_end", (PyCFunction)pygpu_batch_program_use_end, METH_NOARGS, ""},
{NULL, NULL, 0, NULL},

View File

@ -34,8 +34,8 @@ def seek(r, txt, recurs):
newtxt = ''
if recurs > MAX_RECURSIVE:
#print ("Recursion is over max")
#print (txt)
# print ("Recursion is over max")
# print (txt)
return
type_r = type(r)
@ -124,7 +124,7 @@ for d in dir(bpy.types):
'''
# print dir(bpy)
#import sys
# import sys
# sys.exit()
print("iter over ", seek_count, "rna items")

View File

@ -5,7 +5,7 @@
# Needed for 'bl_keymap_utils.keymap_hierarchy' which inspects tools.
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, "release", "scripts", "startup"))
sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, "scripts", "startup"))
del sys, os
from bl_keymap_utils import keymap_hierarchy

View File

@ -103,8 +103,11 @@ def _test_id_gen(data_attr, args_create=(DUMMY_NAME,), create_method="new"):
test_Action = _test_id_gen("actions")
test_Armature = _test_id_gen("armatures")
test_Brush = _test_id_gen("brushes")
test_Camera = _test_id_gen("cameras")
test_Group = _test_id_gen("groups")
test_Collection = _test_id_gen("collections")
test_GreasePencil = _test_id_gen("grease_pencils")
test_HairCurves = _test_id_gen("hair_curves")
test_Lattice = _test_id_gen("lattices")
test_LineStyle = _test_id_gen("linestyles")
test_Mask = _test_id_gen("masks")
@ -115,11 +118,13 @@ test_MovieClip = _test_id_gen("movieclips", args_create=(DUMMY_PATH,), create_me
test_Object = _test_id_gen("objects", args_create=(DUMMY_NAME, None))
test_Palette = _test_id_gen("palettes")
test_Particle = _test_id_gen("particles")
test_PointCloud = _test_id_gen("pointclouds")
test_Scene = _test_id_gen("scenes")
test_Sound = _test_id_gen("sounds", args_create=(DUMMY_PATH,), create_method="load")
test_Speaker = _test_id_gen("speakers")
test_Text = _test_id_gen("texts")
test_VectorFont = _test_id_gen("fonts", args_create=("<builtin>",), create_method="load")
test_Volume = _test_id_gen("volumes")
test_World = _test_id_gen("worlds")
ns = globals()
@ -127,6 +132,8 @@ for t in bpy.data.curves.bl_rna.functions["new"].parameters["type"].enum_items.k
ns["test_Curve_%s" % t] = _test_id_gen("curves", args_create=(DUMMY_NAME, t))
for t in bpy.data.lights.bl_rna.functions["new"].parameters["type"].enum_items.keys():
ns["test_Light_%s" % t] = _test_id_gen("lights", args_create=(DUMMY_NAME, t))
for t in bpy.data.lightprobes.bl_rna.functions["new"].parameters["type"].enum_items.keys():
ns["test_LightProbe_%s" % t] = _test_id_gen("lightprobes", args_create=(DUMMY_NAME, t))
# types are a dynamic enum, have to hard-code.
for t in "ShaderNodeTree", "CompositorNodeTree", "TextureNodeTree":
ns["test_NodeGroup_%s" % t] = _test_id_gen("node_groups", args_create=(DUMMY_NAME, t))

View File

@ -31,7 +31,7 @@ def with_tempdir(wrapped):
@functools.wraps(wrapped)
def decorator(*args, **kwargs):
dirname = tempfile.mkdtemp(prefix='blender-collada-test')
#print("Using tempdir %s" % dirname)
# print("Using tempdir %s" % dirname)
try:
retval = wrapped(*args, pathlib.Path(dirname), **kwargs)
except:

View File

@ -31,7 +31,7 @@ def with_tempdir(wrapped):
@functools.wraps(wrapped)
def decorator(*args, **kwargs):
dirname = tempfile.mkdtemp(prefix='blender-collada-test')
#print("Using tempdir %s" % dirname)
# print("Using tempdir %s" % dirname)
try:
retval = wrapped(*args, pathlib.Path(dirname), **kwargs)
except:

View File

@ -56,7 +56,7 @@ IGNORE_CMAKE = (
UTF8_CHECK = True
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..")))
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
# doesn't have to exist, just use as reference
BUILD_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(SOURCE_DIR, "..", "build"))))

View File

@ -83,7 +83,7 @@ def deprecations() -> List[Tuple[datetime.datetime, Tuple[str, int], str]]:
# *DEPRECATED* 2010/12/22 ``some.py.func`` more info.
"""
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..")))
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
SKIP_DIRS_ABS = [os.path.join(SOURCE_DIR, p) for p in SKIP_DIRS]

View File

@ -64,7 +64,7 @@ from check_spelling_c_config import (
)
BASEDIR = os.path.abspath(os.path.dirname(__file__))
ROOTDIR = os.path.normpath(os.path.join(BASEDIR, "..", "..", ".."))
ROOTDIR = os.path.normpath(os.path.join(BASEDIR, "..", ".."))
# Ensure native slashes.
files_ignore = {

View File

@ -11,7 +11,7 @@ sys.path.append(os.path.join(PWD, "..", "utils_maintenance", "modules"))
from batch_edit_text import run
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(PWD, "..", "..", ".."))))
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(PWD, "..", ".."))))
# TODO, move to config file
SOURCE_DIRS = (

View File

@ -28,7 +28,8 @@ from typing import (
# Constants
CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
SOURCE_DIR = os.path.normpath(os.path.join(CURRENT_DIR, "..", "..", ".."))
SOURCE_DIR = os.path.normpath(os.path.join(CURRENT_DIR, "..", ".."))
WIKI_URL = "https://wiki.blender.org/wiki/Source/File_Structure"
WIKI_URL_EDIT = "https://wiki.blender.org/w/index.php?title=Source/File_Structure&action=edit"

View File

@ -5,7 +5,7 @@
import os
CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(CURRENT_DIR, "..", "..", ".."))))
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(CURRENT_DIR, "..", ".."))))
print("creating git-log of %r" % SOURCE_DIR)
os.chdir(SOURCE_DIR)

View File

@ -14,7 +14,7 @@ import sys
import os
MODULE_DIR = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", "utils"))
SOURCE_DIR = os.path.normpath(os.path.join(MODULE_DIR, "..", "..", "..", ".git"))
SOURCE_DIR = os.path.normpath(os.path.join(MODULE_DIR, "..", "..", ".git"))
sys.path.append(MODULE_DIR)

View File

@ -1,47 +0,0 @@
# SPDX-License-Identifier: GPL-2.0-or-later
[tool.autopep8]
# Configuratuion for `autopep8`, allowing the command: autopep8 .
# to reformat all source files.
#
# NOTE: the settings defined here map directly to commmand line arguments
# which will override these settings when passed in to autopep8.
max_line_length = 120
ignore = [
# Info: Use `isinstance()` instead of comparing types directly.
# Why disable? Changes code logic, in rare cases we want to compare exact types.
"E721",
# Info: Fix bare except.
# Why disable? Disruptive, leave our exceptions alone.
"E722",
# Info: Fix module level import not at top of file.
# Why disable? Re-ordering imports is disruptive and breaks some scripts
# that need to check if a module has already been loaded in the case of reloading.
"E402",
# Info: Try to make lines fit within --max-line-length characters.
# Why disable? Causes lines to be wrapped, where long lines have the trailing bracket moved to the end of the line.
# If trailing commas were respected as they are by clang-format this might be acceptable.
# Note that this doesn't disable all line wrapping.
"E501",
# Info: Fix various deprecated code (via lib2to3)
# Why disable? Does nothing besides incorrectly adding a duplicate import,
# could be reported as a bug except this is likely to be removed soon, see:
# https://github.com/python/cpython/issues/84540.
"W690",
]
# Use aggressive as many useful edits are disabled unless it's enabled.
# Any edits which are overly disruptive or risky can be removed in the `ignore` list.
aggressive = 2
# Exclude:
# - `./svn_rev_map/` contains data-files which are slow to re-format and don't benefit from formatting.
exclude = """
./svn_rev_map/sha1_to_rev.py,
./svn_rev_map/rev_to_sha1.py,
"""
# Omit settings such as `jobs`, `in_place` & `recursive` as they can cause editor utilities that auto-format on save
# to fail if the STDIN/STDOUT is used for formatting (which isn't compatible with these options).

View File

@ -25,7 +25,7 @@ PATHS: Tuple[str, ...] = (
)
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(
os.path.join(os.path.dirname(__file__), "..", "..", ".."))))
os.path.join(os.path.dirname(__file__), "..", ".."))))
PATHS = tuple(
os.path.join(SOURCE_DIR, p.replace("/", os.sep))

View File

@ -68,13 +68,13 @@ del sys
source_dst = os.path.join(
os.path.dirname(__file__),
"..", "..", "..",
"..", "..",
"release", "datafiles", "userdef", "userdef_default_theme.c",
)
dna_rename_defs_h = os.path.join(
os.path.dirname(__file__),
"..", "..", "..",
"..", "..",
"source", "blender", "makesdna", "intern", "dna_rename_defs.h",
)

View File

@ -347,7 +347,7 @@ def release_log_init(path, source_dir, blender_rev, start_sha1, end_sha1, rstate
main_cat = sub_cats_to_main_cats.get(main_cat, None)
else:
sub_cat = None
#~ print("hl MAINCAT:", hl, main_cat, " | ", sub_cat)
# print("hl MAINCAT:", hl, main_cat, " | ", sub_cat)
break
header.append(hl)
@ -372,7 +372,7 @@ def release_log_init(path, source_dir, blender_rev, start_sha1, end_sha1, rstate
sub_cat = None
else:
main_cat = None
#~ print("l SUBCAT:", l, main_cat, " | ", sub_cat)
# print("l SUBCAT:", l, main_cat, " | ", sub_cat)
elif l.startswith("=="):
main_cat = l.strip(" =")
if main_cat not in main_cats:
@ -380,18 +380,18 @@ def release_log_init(path, source_dir, blender_rev, start_sha1, end_sha1, rstate
main_cat = sub_cats_to_main_cats.get(main_cat, None)
else:
sub_cat = None
#~ print("l MAINCAT:", l, main_cat, " | ", sub_cat)
# print("l MAINCAT:", l, main_cat, " | ", sub_cat)
elif "Fix " in l:
if "Fix {{BugReport|" in l:
main_cat_data, _ = release_log.setdefault(main_cat, ({}, {}))
main_cat_data.setdefault(sub_cat, []).append(l)
count[0] += 1
#~ print("l REPORTED:", l)
# print("l REPORTED:", l)
else:
_, main_cat_data_unreported = release_log.setdefault(main_cat, ({}, {}))
main_cat_data_unreported.setdefault(sub_cat, []).append(l)
count[1] += 1
#~ print("l UNREPORTED:", l)
# print("l UNREPORTED:", l)
l_rstate = l.strip("* ")
if l_rstate.startswith("["):
end = l_rstate.find("]")

View File

@ -56,8 +56,8 @@ class App:
self.doit = Button(frame2, text="Print", command=self.doit)
self.doit.grid(row=0, column=1, pady=20)
#self.doitlab = Label(frame2, text="(Output to stdout)");
#self.doitlab.grid(row=1, column=1);
# self.doitlab = Label(frame2, text="(Output to stdout)");
# self.doitlab.grid(row=1, column=1);
self.parse = Button(frame2, text="Parse", command=self.parsetext)
self.parse.grid(row=0, column=2, pady=20)
@ -117,7 +117,7 @@ class App:
self.prev.config(width=self.size + 1, height=self.size + 1)
for n in range(self.states):
self.updateprev(n)
#self.prev.grid(row=0, column=4, padx=self.gridsz, pady=self.gridsz)
# self.prev.grid(row=0, column=4, padx=self.gridsz, pady=self.gridsz)
def scrnclick1(self, event):
self.scrnclick(event, 1)
@ -264,7 +264,7 @@ class App:
m |= 1
if (self.state[(i * 8) + (7 - j)] == 1):
b |= 1
#print((i * 8) + (7 - j), self.state[(i * 8) + (7 - j)], m)
# print((i * 8) + (7 - j), self.state[(i * 8) + (7 - j)], m)
mask.append(m)
bitmap.append(b)

View File

@ -441,10 +441,10 @@ def module_classes(mod):
def main():
import os
BASE_DIR = os.path.join(os.path.dirname(__file__), "..", "..", "..")
BASE_DIR = os.path.join(os.path.dirname(__file__), "..", "..")
BASE_DIR = os.path.normpath(os.path.abspath(BASE_DIR))
MODULE_DIR_UI = os.path.join(BASE_DIR, "release", "scripts", "startup")
MODULE_DIR_MOD = os.path.join(BASE_DIR, "release", "scripts", "modules")
MODULE_DIR_UI = os.path.join(BASE_DIR, "scripts", "startup")
MODULE_DIR_MOD = os.path.join(BASE_DIR, "scripts", "modules")
print("Using base dir: %r" % BASE_DIR)
print("Using module dir: %r" % MODULE_DIR_UI)

View File

@ -39,7 +39,7 @@ except ImportError:
sys.exit(1)
# The root of Blender's source directory.
BASE_DIR = os.path.join(os.path.dirname(__file__), "..", "..", "..")
BASE_DIR = os.path.join(os.path.dirname(__file__), "..", "..")
# Names that don't match this regex can't be used as URL's.
re_name_sanity_match = re.compile("[a-zA-Z0-9._*]+")
@ -131,7 +131,7 @@ def main():
parser.add_argument(
"--output",
dest="output",
default=os.path.join(BASE_DIR, "release", "scripts", "modules", "rna_manual_reference.py"),
default=os.path.join(BASE_DIR, "scripts", "modules", "rna_manual_reference.py"),
required=False,
help="path to output including filename and extentsion",
metavar="FILE")

View File

@ -13,7 +13,7 @@ from typing import (
Optional,
)
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(PWD, "..", "..", ".."))))
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(PWD, "..", ".."))))
# TODO, move to config file
SOURCE_DIRS = (

View File

@ -23,7 +23,7 @@ sys.path.append(os.path.join(PWD, "modules"))
from batch_edit_text import run
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(PWD, "..", "..", ".."))))
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(PWD, "..", ".."))))
# TODO: move to configuration file.
SOURCE_DIRS = (

View File

@ -19,7 +19,7 @@ sys.path.append(os.path.join(PWD, "modules"))
from batch_edit_text import run
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(PWD, "..", "..", ".."))))
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(PWD, "..", ".."))))
# TODO, move to config file
SOURCE_DIRS = (

View File

@ -48,7 +48,7 @@ VERBOSE_EDIT_ACTION = False
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
SOURCE_DIR = os.path.normpath(os.path.join(BASE_DIR, "..", "..", ".."))
SOURCE_DIR = os.path.normpath(os.path.join(BASE_DIR, "..", ".."))
# -----------------------------------------------------------------------------

View File

@ -22,7 +22,7 @@ PATHS = (
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(
os.path.join(os.path.dirname(__file__), "..", "..", ".."))))
os.path.join(os.path.dirname(__file__), "..", ".."))))
PATHS = tuple(
os.path.join(SOURCE_DIR, p.replace("/", os.sep))