36 const int64_t tot_verts_object{mesh_geometry_.get_vertex_count()};
37 if (tot_verts_object <= 0) {
42 this->fixup_invalid_faces();
46 mesh_geometry_.edges_.size(),
47 mesh_geometry_.face_elements_.size(),
48 mesh_geometry_.total_corner_);
50 this->create_vertices(mesh);
52 this->create_edges(mesh);
53 this->create_uv_verts(mesh);
54 this->create_normals(mesh);
55 this->create_colors(mesh);
57 if (import_params.
validate_meshes || mesh_geometry_.has_invalid_faces_) {
58 bool verbose_validate =
false;
60 verbose_validate =
true;
70 Map<std::string, std::unique_ptr<MTLMaterial>> &materials,
76 if (mesh ==
nullptr) {
82 if (ob_name.empty()) {
89 this->create_materials(bmain, materials, created_materials,
obj, import_params.
relative_paths);
96 this->create_vertex_groups(
obj);
101void MeshFromGeometry::fixup_invalid_faces()
120 int vertex_idx = mesh_geometry_.
face_corners_[corner_idx].vert_index;
121 if (used_verts.
contains(vertex_idx)) {
125 used_verts.
add(vertex_idx);
133 Vector<int, 8> face_verts;
134 Vector<int, 8> face_uvs;
135 Vector<int, 8> face_normals;
141 const FaceCorner &corner = mesh_geometry_.face_corners_[corner_idx];
142 face_verts.
append(corner.vert_index);
143 face_normals.
append(corner.vertex_normal_index);
144 face_uvs.
append(corner.uv_vert_index);
152 mesh_geometry_.face_elements_.remove_and_reorder(face_idx);
155 Vector<Vector<int>> new_faces =
fixup_invalid_face(global_vertices_.vertices, face_verts);
158 for (Span<int> face : new_faces) {
159 if (face.size() < 3) {
163 new_face.vertex_group_index = face_vertex_group;
164 new_face.material_index = face_material;
165 new_face.shaded_smooth = face_shaded_smooth;
166 new_face.start_index_ = mesh_geometry_.face_corners_.size();
167 new_face.corner_count_ = face.size();
168 for (
int idx : face) {
170 mesh_geometry_.face_corners_.append({face_verts[idx], face_uvs[idx], face_normals[idx]});
172 mesh_geometry_.face_elements_.append(new_face);
173 mesh_geometry_.total_corner_ += face.size();
178void MeshFromGeometry::create_vertices(
Mesh *mesh)
180 MutableSpan<float3> positions = mesh->vert_positions_for_write();
185 mesh_geometry_.global_to_local_vertices_.
clear();
186 mesh_geometry_.global_to_local_vertices_.reserve(mesh_geometry_.vertices_.size());
187 for (
int vi = mesh_geometry_.vertex_index_min_; vi <= mesh_geometry_.vertex_index_max_; ++vi) {
188 BLI_assert(vi >= 0 && vi < global_vertices_.vertices.size());
189 if (!mesh_geometry_.vertices_.contains(vi)) {
192 int local_vi =
int(mesh_geometry_.global_to_local_vertices_.size());
193 BLI_assert(local_vi >= 0 && local_vi < mesh->verts_num);
194 copy_v3_v3(positions[local_vi], global_vertices_.vertices[vi]);
195 mesh_geometry_.global_to_local_vertices_.add_new(vi, local_vi);
199void MeshFromGeometry::create_faces(
Mesh *mesh,
bool use_vertex_groups)
201 MutableSpan<MDeformVert> dverts;
202 const int64_t total_verts = mesh_geometry_.get_vertex_count();
203 if (use_vertex_groups && total_verts && mesh_geometry_.has_vertex_groups_) {
204 dverts = mesh->deform_verts_for_write();
207 Span<float3> positions = mesh->vert_positions();
208 MutableSpan<int> face_offsets = mesh->face_offsets_for_write();
209 MutableSpan<int> corner_verts = mesh->corner_verts_for_write();
210 bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
211 bke::SpanAttributeWriter<int> material_indices =
214 const bool set_face_sharpness = !has_normals();
215 bke::SpanAttributeWriter<bool> sharp_faces = attributes.lookup_or_add_for_write_span<
bool>(
218 int corner_index = 0;
220 for (
int face_idx = 0; face_idx < mesh->
faces_num; ++face_idx) {
221 const FaceElem &curr_face = mesh_geometry_.face_elements_[face_idx];
222 if (curr_face.corner_count_ < 3) {
224 std::cerr <<
"Face with less than 3 vertices found, skipping." << std::endl;
228 face_offsets[face_idx] = corner_index;
229 if (set_face_sharpness) {
232 sharp_faces.span[face_idx] = !curr_face.shaded_smooth;
235 material_indices.span[face_idx] = curr_face.material_index;
238 if (material_indices.span[face_idx] < 0) {
239 material_indices.span[face_idx] = 0;
242 for (
int idx = 0; idx < curr_face.corner_count_; ++idx) {
243 const FaceCorner &curr_corner = mesh_geometry_.face_corners_[curr_face.start_index_ + idx];
244 corner_verts[corner_index] = mesh_geometry_.global_to_local_vertices_.lookup_default(
245 curr_corner.vert_index, 0);
249 const int group_index = curr_face.vertex_group_index;
251 if (group_index >= 0 ||
true) {
261 if (!set_face_sharpness) {
268 positions, corner_verts.
slice(face_offsets[face_idx], curr_face.corner_count_));
269 if (area < 1.0e-12f) {
270 sharp_faces.span[face_idx] =
true;
275 material_indices.finish();
276 sharp_faces.finish();
279void MeshFromGeometry::create_vertex_groups(
Object *obj)
282 if (mesh->deform_verts().is_empty()) {
285 for (
const std::string &name : mesh_geometry_.group_order_) {
290void MeshFromGeometry::create_edges(
Mesh *mesh)
292 MutableSpan<int2> edges = mesh->edges_for_write();
294 const int64_t tot_edges{mesh_geometry_.edges_.size()};
295 const int64_t total_verts{mesh_geometry_.get_vertex_count()};
297 for (
int i = 0; i < tot_edges; ++i) {
298 const int2 &src_edge = mesh_geometry_.edges_[i];
299 int2 &dst_edge = edges[i];
300 dst_edge[0] = mesh_geometry_.global_to_local_vertices_.lookup_default(src_edge[0], 0);
301 dst_edge[1] = mesh_geometry_.global_to_local_vertices_.lookup_default(src_edge[1], 0);
302 BLI_assert(dst_edge[0] < total_verts && dst_edge[1] < total_verts);
310void MeshFromGeometry::create_uv_verts(
Mesh *mesh)
312 if (global_vertices_.uv_vertices.size() <= 0) {
316 bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
317 bke::SpanAttributeWriter<float2> uv_map = attributes.lookup_or_add_for_write_only_span<
float2>(
320 int corner_index = 0;
321 bool added_uv =
false;
323 for (
const FaceElem &curr_face : mesh_geometry_.face_elements_) {
324 for (
int idx = 0; idx < curr_face.corner_count_; ++idx) {
325 const FaceCorner &curr_corner = mesh_geometry_.face_corners_[curr_face.start_index_ + idx];
326 if (curr_corner.uv_vert_index >= 0 &&
327 curr_corner.uv_vert_index < global_vertices_.uv_vertices.size())
329 uv_map.span[corner_index] = global_vertices_.uv_vertices[curr_corner.uv_vert_index];
333 uv_map.span[corner_index] = {0.0f, 0.0f};
349 attributes.remove(
"UVMap");
354 const std::string &name,
355 Map<std::string, std::unique_ptr<MTLMaterial>> &materials,
361 if (found_mat !=
nullptr) {
368 const MTLMaterial &mtl = *materials.lookup_or_add(name, std::make_unique<MTLMaterial>());
377 created_materials.
add_new(name, mat);
381void MeshFromGeometry::create_materials(
Main *bmain,
382 Map<std::string, std::unique_ptr<MTLMaterial>> &materials,
389 bmain, name, materials, created_materials, relative_paths);
390 if (mat ==
nullptr) {
400bool MeshFromGeometry::has_normals()
const
402 return !global_vertices_.vert_normals.is_empty() && mesh_geometry_.total_corner_ != 0;
405void MeshFromGeometry::create_normals(
Mesh *mesh)
407 if (!has_normals()) {
411 Array<float3> corner_normals(mesh_geometry_.total_corner_);
412 int corner_index = 0;
413 for (
const FaceElem &curr_face : mesh_geometry_.face_elements_) {
414 for (
int idx = 0; idx < curr_face.corner_count_; ++idx) {
415 const FaceCorner &curr_corner = mesh_geometry_.face_corners_[curr_face.start_index_ + idx];
416 int n_index = curr_corner.vertex_normal_index;
418 if (n_index >= 0 && n_index < global_vertices_.vert_normals.size()) {
419 normal = global_vertices_.vert_normals[n_index];
421 corner_normals[corner_index] =
normal;
428void MeshFromGeometry::create_colors(
Mesh *mesh)
431 if (global_vertices_.vertex_colors.is_empty()) {
436 for (
int vi : mesh_geometry_.vertices_) {
437 if (!global_vertices_.has_vertex_color(vi)) {
450 for (
auto item : mesh_geometry_.global_to_local_vertices_.items()) {
451 const int vi = item.key;
452 const int local_vi = item.value;
453 BLI_assert(vi >= 0 && vi < global_vertices_.vertex_colors.size());
454 BLI_assert(local_vi >= 0 && local_vi < mesh->verts_num);
455 const float3 &c = global_vertices_.vertex_colors[vi];
456 colors[local_vi] =
float4(c.
x, c.
y, c.
z, 1.0);
void BKE_id_attributes_default_color_set(struct ID *id, const char *name)
void BKE_id_attributes_active_color_set(struct ID *id, const char *name)
struct CustomDataLayer * BKE_attribute_new(AttributeOwner &owner, const char *name, eCustomDataType type, blender::bke::AttrDomain domain, struct ReportList *reports)
General operations, lookup, etc. for materials.
void BKE_object_material_assign_single_obdata(struct Main *bmain, struct Object *ob, struct Material *ma, short act)
struct Material * BKE_material_add(struct Main *bmain, const char *name)
void BKE_mesh_set_custom_normals(Mesh *mesh, float(*r_custom_loop_normals)[3])
bool BKE_mesh_validate(Mesh *mesh, bool do_verbose, bool cddata_check_mask)
Mesh * BKE_mesh_new_nomain(int verts_num, int edges_num, int faces_num, int corners_num)
void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
void BKE_ntree_update_main_tree(Main *bmain, bNodeTree *ntree, NodeTreeUpdateExtraParams *params)
General operations, lookup, etc. for blender objects.
void * BKE_object_obdata_add_from_type(Main *bmain, int type, const char *name) ATTR_NONNULL(1)
Object * BKE_object_add_only_object(Main *bmain, int type, const char *name) ATTR_RETURNS_NONNULL
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define UNUSED_VARS_NDEBUG(...)
struct CustomDataLayer CustomDataLayer
struct MDeformWeight MDeformWeight
static AttributeOwner from_id(ID *id)
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr bool is_empty() const
void append(const T &value)
void reserve(const int64_t min_capacity)
const Value * lookup_ptr(const Key &key) const
void add_new(const Key &key, const Value &value)
bool contains(const Key &key) const
Mesh * create_mesh(const OBJImportParams &import_params)
Object * create_mesh_object(Main *bmain, Map< std::string, std::unique_ptr< MTLMaterial > > &materials, Map< std::string, Material * > &created_materials, const OBJImportParams &import_params)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
float face_area_calc(Span< float3 > vert_positions, Span< int > face_verts)
void mesh_calc_edges(Mesh &mesh, bool keep_existing_edges, bool select_new_edges)
static Material * get_or_create_material(Main *bmain, const std::string &name, Map< std::string, std::unique_ptr< MTLMaterial > > &materials, Map< std::string, Material * > &created_materials, bool relative_paths)
bNodeTree * create_mtl_node_tree(Main *bmain, const MTLMaterial &mtl_mat, Material *mat, bool relative_paths)
void transform_object(Object *object, const OBJImportParams &import_params)
Vector< Vector< int > > fixup_invalid_face(Span< float3 > vert_positions, Span< int > face_verts)
std::string get_geometry_name(const std::string &full_name, char separator)
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< float, 3 > float3
struct bNodeTree * nodetree
void clear(bool preserve_shaders=false) override
bool import_vertex_groups
char collection_separator
Vector< std::string > material_order_
Vector< FaceCorner > face_corners_
Vector< FaceElem > face_elements_