42 object_name_ = obj_eval->
id.
name + 2;
43 export_mesh_ =
nullptr;
51 mesh_edges_ = export_mesh_->edges();
52 mesh_faces_ = export_mesh_->faces();
53 mesh_corner_verts_ = export_mesh_->corner_verts();
54 sharp_faces_ = *export_mesh_->attributes().lookup_or_default<
bool>(
64 this->triangulate_mesh_eval();
67 this->
materials.reinitialize(export_mesh_->totcol);
68 for (
const int i : this->
materials.index_range()) {
72 set_world_axes_transform(*obj_eval,
87void OBJMesh::set_mesh(
Mesh *mesh)
89 if (owned_export_mesh_) {
92 owned_export_mesh_ = mesh;
93 export_mesh_ = owned_export_mesh_;
94 mesh_edges_ = mesh->edges();
95 mesh_faces_ = mesh->faces();
96 mesh_corner_verts_ = mesh->corner_verts();
97 sharp_faces_ = *export_mesh_->
attributes().lookup_or_default<
bool>(
103 if (owned_export_mesh_) {
105 owned_export_mesh_ =
nullptr;
107 export_mesh_ =
nullptr;
108 corner_to_uv_index_ = {};
109 uv_coords_.clear_and_shrink();
110 corner_to_normal_index_ = {};
113 if (face_smooth_groups_) {
115 face_smooth_groups_ =
nullptr;
119void OBJMesh::triangulate_mesh_eval()
133 const int triangulate_min_verts = 4;
139 triangulate_min_verts,
146 this->set_mesh(triangulated);
149void OBJMesh::set_world_axes_transform(
const Object &obj_eval,
152 const float global_scale,
153 const bool apply_transform)
159 const float4x4 &object_to_world = apply_transform ? obj_eval.object_to_world() :
164 world_and_axes_transform_.location() = axes_transform * object_to_world.location();
165 world_and_axes_transform_[3][3] = object_to_world[3][3];
168 world_and_axes_transform_;
178 return export_mesh_->verts_num;
183 return export_mesh_->faces_num;
188 return int(uv_coords_.size());
193 return export_mesh_->edges_num;
206 return face_smooth_groups_[face_index];
216 export_mesh_->verts_num,
218 export_mesh_->corner_edges(),
219 export_mesh_->corner_verts(),
223 &tot_smooth_groups_);
228 export_mesh_->corner_edges(),
231 &tot_smooth_groups_);
246 face_order_.reinitialize(material_indices_span.
size());
249 int mat_a = material_indices_span[a];
250 int mat_b = material_indices_span[b];
251 if (mat_a != mat_b) {
252 return mat_a < mat_b;
260 return !sharp_faces_[face_index];
270 return export_mesh_->id.name + 2;
291 uv_to_index.
reserve(export_mesh_->verts_num);
292 uv_coords_.reserve(export_mesh_->verts_num);
294 corner_to_uv_index_.reinitialize(uv_map.
size());
296 for (
int index = 0; index < int(uv_map.
size()); index++) {
297 float2 uv = uv_map[index];
299 if (uv_index == -1) {
300 uv_index = uv_to_index.
size();
301 uv_to_index.
add(uv, uv_index);
302 uv_coords_.append(uv);
304 corner_to_uv_index_[index] = uv_index;
311 float scale =
powf(10.0, round_digits);
312 return ceilf(scale * f - 0.49999999f) / scale;
331 constexpr int round_digits = 4;
334 unique_normals.
reserve(export_mesh_->faces_num);
335 corner_to_normal_index_.reinitialize(export_mesh_->corners_num);
339 auto add_normal = [&](
const float3 &normal) {
345 switch (export_mesh_->normals_domain()) {
347 const Span<float3> face_normals = export_mesh_->face_normals();
348 for (
const int face : mesh_faces_.index_range()) {
349 const int index = add_normal(face_normals[face]);
350 corner_to_normal_index_.as_mutable_span().slice(mesh_faces_[face]).fill(index);
355 const Span<float3> vert_normals = export_mesh_->vert_normals();
358 if (verts_no_face.
count == 0) {
359 for (
const int vert : vert_normals.
index_range()) {
360 vert_normal_indices[vert] = add_normal(vert_normals[vert]);
364 for (
const int vert : vert_normals.
index_range()) {
366 vert_normal_indices[vert] = add_normal(vert_normals[vert]);
372 corner_to_normal_index_.as_mutable_span());
376 const Span<float3> corner_normals = export_mesh_->corner_normals();
377 for (
const int corner : corner_normals.
index_range()) {
378 corner_to_normal_index_[corner] = add_normal(corner_normals[corner]);
384 normal_coords_ = unique_normals.
as_span();
395 BLI_assert(face_index < export_mesh_->faces_num);
402 group_weights.
fill(0);
403 bool found_any_group =
false;
404 for (
const int vert : mesh_corner_verts_.slice(mesh_faces_[face_index])) {
406 for (
int weight_i = 0; weight_i < dv.
totweight; ++weight_i) {
407 const auto group = dv.
dw[weight_i].
def_nr;
408 if (group < group_weights.
size()) {
409 group_weights[group] += dv.
dw[weight_i].
weight;
410 found_any_group =
true;
415 if (!found_any_group) {
419 int16_t max_idx = std::max_element(group_weights.
begin(), group_weights.
end()) -
420 group_weights.
begin();
427 BLI_findlink(&export_mesh_->vertex_group_names, def_group_index)));
428 return vertex_group.
name;
CustomData interface, see also DNA_customdata_types.h.
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
void BKE_id_free(Main *bmain, void *idv)
General operations, lookup, etc. for materials.
Material * BKE_object_material_get_eval(Object *ob, short act)
Mesh * BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings)
Mesh * BKE_mesh_new_from_object(Depsgraph *depsgraph, Object *object, bool preserve_all_data_layers, bool preserve_origindex, bool ensure_subdivision)
BMesh * BKE_mesh_to_bmesh_ex(const Mesh *mesh, const BMeshCreateParams *create_params, const BMeshFromMeshParams *convert_params)
int * BKE_mesh_calc_smoothgroups(int edges_num, blender::OffsetIndices< int > faces, blender::Span< int > corner_edges, blender::Span< bool > sharp_edges, blender::Span< bool > sharp_faces, int *r_totgroup)
int * BKE_mesh_calc_smoothgroups_bitflags(int edges_num, int verts_num, blender::OffsetIndices< int > faces, blender::Span< int > corner_edges, blender::Span< int > corner_verts, blender::Span< bool > sharp_edges, blender::Span< bool > sharp_faces, bool use_boundary_vertices_for_bitflags, int *r_totgroup)
General operations, lookup, etc. for blender objects.
const Mesh * BKE_object_get_pre_modified_mesh(const Object *object)
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
bool mat3_from_axis_conversion(int src_forward, int src_up, int dst_forward, int dst_up, float r_mat[3][3])
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ MOD_TRIANGULATE_QUAD_SHORTEDGE
@ MOD_TRIANGULATE_NGON_BEAUTY
Object is a sort of wrapper for general info.
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
ATTR_WARN_UNUSED_RESULT const BMVert * v
void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method, const int min_vertices, const bool tag_only, BMOperator *op, BMOpSlot *slot_facemap_out, BMOpSlot *slot_facemap_double_out)
BPy_StructRNA * depsgraph
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
Span< T > as_span() const
bool add(const Key &key, const Value &value)
Value lookup_default(const Key &key, const Value &default_value) const
constexpr int64_t size() const
constexpr void fill(const T &value) const
constexpr T * end() const
constexpr T * begin() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
constexpr bool is_empty() const
T get_internal_single() const
int64_t index_of_or_add(const Key &key)
void reserve(const int64_t n)
Span< Key > as_span() const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
GAttributeReader lookup(const StringRef attribute_id) const
const char * get_face_deform_group_name(int16_t def_group_index) const
int16_t get_face_deform_group_index(int face_index, MutableSpan< float > group_weights) const
bool is_ith_face_smooth(int face_index) const
int tot_deform_groups() const
int16_t tot_materials() const
void calc_smooth_groups(bool use_bitflags)
StringRef get_object_mesh_name() const
int tot_uv_vertices() const
Array< const Material * > materials
void store_uv_coords_and_indices()
void store_normal_coords_and_indices()
StringRef get_object_name() const
OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Object *mesh_object)
int ith_smooth_group(int face_index) const
void MEM_freeN(void *vmemh)
void gather(const GVArray &src, const IndexMask &indices, GMutableSpan dst, int64_t grain_size=4096)
void fill_index_range(MutableSpan< T > span, const T start=0)
static float round_float_to_n_digits(const float f, int round_digits)
static float3 round_float3_to_n_digits(const float3 &v, int round_digits)
MatBase< T, NumCol, NumRow > transpose(const MatBase< T, NumRow, NumCol > &mat)
bool is_negative(const MatBase< T, 3, 3 > &mat)
CartesianBasis invert(const CartesianBasis &basis)
MatT from_scale(const VecBase< typename MatT::base_type, ScaleDim > &scale)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
MatBase< float, 4, 4 > float4x4
void parallel_sort(RandomAccessIterator begin, RandomAccessIterator end)
VecBase< float, 2 > float2
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
bool export_triangulated_mesh
static MatBase identity()
blender::BitVector is_loose_bits