40 if (tot_verts_object <= 0) {
45 this->fixup_invalid_faces();
49 mesh_geometry_.
edges_.size(),
53 this->create_vertices(
mesh);
55 this->create_edges(
mesh);
56 this->create_uv_verts(
mesh);
57 this->create_normals(
mesh);
58 this->create_colors(
mesh);
61 bool verbose_validate =
false;
63 verbose_validate =
true;
73 Map<std::string, std::unique_ptr<MTLMaterial>> &materials,
79 if (
mesh ==
nullptr) {
85 if (ob_name.empty()) {
92 this->create_materials(bmain, materials, created_materials, obj, import_params.
relative_paths);
99 this->create_vertex_groups(obj);
104void MeshFromGeometry::fixup_invalid_faces()
123 int vertex_idx = mesh_geometry_.
face_corners_[corner_idx].vert_index;
124 if (used_verts.
contains(vertex_idx)) {
128 used_verts.
add(vertex_idx);
144 const FaceCorner &corner = mesh_geometry_.
face_corners_[corner_idx];
145 face_verts.append(corner.vert_index);
146 face_normals.append(corner.vertex_normal_index);
147 face_uvs.append(corner.uv_vert_index);
161 for (Span<int> face : new_faces) {
162 if (face.size() < 3) {
166 new_face.vertex_group_index = face_vertex_group;
167 new_face.material_index = face_material;
168 new_face.shaded_smooth = face_shaded_smooth;
170 new_face.corner_count_ = face.size();
171 for (
int idx : face) {
172 BLI_assert(idx >= 0 && idx < face_verts.size());
173 mesh_geometry_.
face_corners_.append({face_verts[idx], face_uvs[idx], face_normals[idx]});
181void MeshFromGeometry::create_vertices(
Mesh *
mesh)
183 MutableSpan<float3> positions =
mesh->vert_positions_for_write();
196 BLI_assert(local_vi >= 0 && local_vi < mesh->verts_num);
202void MeshFromGeometry::create_faces(
Mesh *
mesh,
bool use_vertex_groups)
204 MutableSpan<MDeformVert> dverts;
207 dverts =
mesh->deform_verts_for_write();
210 Span<float3> positions =
mesh->vert_positions();
211 MutableSpan<int> face_offsets =
mesh->face_offsets_for_write();
212 MutableSpan<int> corner_verts =
mesh->corner_verts_for_write();
213 bke::MutableAttributeAccessor attributes =
mesh->attributes_for_write();
214 bke::SpanAttributeWriter<int> material_indices =
217 const bool set_face_sharpness = !has_normals();
218 bke::SpanAttributeWriter<bool> sharp_faces = attributes.lookup_or_add_for_write_span<
bool>(
221 int corner_index = 0;
223 for (
int face_idx = 0; face_idx <
mesh->
faces_num; ++face_idx) {
224 const FaceElem &curr_face = mesh_geometry_.
face_elements_[face_idx];
225 if (curr_face.corner_count_ < 3) {
227 CLOG_WARN(&
LOG,
"Face with less than 3 vertices found, skipping.");
231 face_offsets[face_idx] = corner_index;
232 if (set_face_sharpness) {
235 sharp_faces.span[face_idx] = !curr_face.shaded_smooth;
238 material_indices.span[face_idx] = curr_face.material_index;
241 material_indices.span[face_idx] = std::max(material_indices.span[face_idx], 0);
243 for (
int idx = 0; idx < curr_face.corner_count_; ++idx) {
244 const FaceCorner &curr_corner = mesh_geometry_.
face_corners_[curr_face.start_index_ + idx];
246 curr_corner.vert_index, 0);
249 if (!dverts.is_empty()) {
250 const int group_index = curr_face.vertex_group_index;
252 if (group_index >= 0 ||
true) {
262 if (!set_face_sharpness) {
269 positions, corner_verts.slice(face_offsets[face_idx], curr_face.corner_count_));
270 if (area < 1.0e-12f) {
271 sharp_faces.span[face_idx] =
true;
276 material_indices.finish();
277 sharp_faces.finish();
280void MeshFromGeometry::create_vertex_groups(
Object *obj)
283 if (
mesh->deform_verts().is_empty()) {
286 for (
const std::string &
name : mesh_geometry_.group_order_) {
291void MeshFromGeometry::create_edges(
Mesh *
mesh)
293 MutableSpan<int2> edges =
mesh->edges_for_write();
298 for (
int i = 0; i < tot_edges; ++i) {
299 const int2 &src_edge = mesh_geometry_.
edges_[i];
300 int2 &dst_edge = edges[i];
303 BLI_assert(dst_edge[0] < total_verts && dst_edge[1] < total_verts);
311void MeshFromGeometry::create_uv_verts(
Mesh *
mesh)
317 bke::MutableAttributeAccessor attributes =
mesh->attributes_for_write();
318 bke::SpanAttributeWriter<float2> uv_map = attributes.lookup_or_add_for_write_only_span<
float2>(
321 int corner_index = 0;
322 bool added_uv =
false;
324 for (
const FaceElem &curr_face : mesh_geometry_.face_elements_) {
325 for (
int idx = 0; idx < curr_face.corner_count_; ++idx) {
326 const FaceCorner &curr_corner = mesh_geometry_.
face_corners_[curr_face.start_index_ + idx];
327 if (curr_corner.uv_vert_index >= 0 &&
328 curr_corner.uv_vert_index < global_vertices_.
uv_vertices.size())
330 uv_map.span[corner_index] = global_vertices_.
uv_vertices[curr_corner.uv_vert_index];
334 uv_map.span[corner_index] = {0.0f, 0.0f};
350 attributes.remove(
"UVMap");
355 const std::string &
name,
356 Map<std::string, std::unique_ptr<MTLMaterial>> &materials,
362 if (found_mat !=
nullptr) {
369 const MTLMaterial &mtl = *materials.lookup_or_add(
name, std::make_unique<MTLMaterial>());
382void MeshFromGeometry::create_materials(
Main *bmain,
383 Map<std::string, std::unique_ptr<MTLMaterial>> &materials,
388 for (
const std::string &
name : mesh_geometry_.material_order_) {
390 bmain,
name, materials, created_materials, relative_paths);
391 if (mat ==
nullptr) {
401bool MeshFromGeometry::has_normals()
const
406void MeshFromGeometry::create_normals(
Mesh *
mesh)
408 if (!has_normals()) {
413 int corner_index = 0;
414 for (
const FaceElem &curr_face : mesh_geometry_.face_elements_) {
415 for (
int idx = 0; idx < curr_face.corner_count_; ++idx) {
416 const FaceCorner &curr_corner = mesh_geometry_.
face_corners_[curr_face.start_index_ + idx];
417 int n_index = curr_corner.vertex_normal_index;
419 if (n_index >= 0 && n_index < global_vertices_.
vert_normals.size()) {
422 corner_normals[corner_index] = normal;
429void MeshFromGeometry::create_colors(
Mesh *
mesh)
437 for (
int vi : mesh_geometry_.vertices_) {
451 for (
auto item : mesh_geometry_.global_to_local_vertices_.items()) {
452 const int vi = item.key;
453 const int local_vi = item.value;
455 BLI_assert(local_vi >= 0 && local_vi < mesh->verts_num);
457 colors[local_vi] =
float4(c.
x, c.
y, c.
z, 1.0);
void BKE_id_attributes_default_color_set(struct ID *id, std::optional< blender::StringRef > name)
struct CustomDataLayer * BKE_attribute_new(AttributeOwner &owner, blender::StringRef name, eCustomDataType type, blender::bke::AttrDomain domain, struct ReportList *reports)
void BKE_id_attributes_active_color_set(struct ID *id, std::optional< blender::StringRef > name)
General operations, lookup, etc. for materials.
void BKE_object_material_assign_single_obdata(Main *bmain, Object *ob, Material *ma, short act)
Material * BKE_material_add(Main *bmain, const char *name)
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_after_single_tree_change(Main &bmain, bNodeTree &modified_tree, const NodeTreeUpdateExtraParams ¶ms={})
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(...)
#define CLOG_WARN(clg_ref,...)
static AttributeOwner from_id(ID *id)
const Value * lookup_ptr(const Key &key) const
Value lookup_default(const Key &key, const Value &default_value) 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)
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)
void mesh_set_custom_normals(Mesh &mesh, MutableSpan< float3 > corner_normals)
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
struct bNodeTree * nodetree
bool import_vertex_groups
char collection_separator
int get_vertex_count() const
Map< int, int > global_to_local_vertices_
Vector< FaceCorner > face_corners_
std::string geometry_name_
Vector< FaceElem > face_elements_
Vector< float3 > vertex_colors
bool has_vertex_color(size_t index) const
Vector< float3 > vertices
Vector< float2 > uv_vertices
Vector< float3 > vert_normals