52void OBJWriter::write_vert_uv_normal_indices(
FormatHandler &fh,
60 vert_indices.
size() == normal_indices.
size());
64 const int n = vert_indices.
size();
67 for (
int j = 0; j < n; ++j) {
69 uv_indices[j] + uv_offset,
70 normal_indices[j] + normal_offset);
77 for (
int k = 0; k < n; ++k) {
78 int j = k == 0 ? 0 : n - k;
80 uv_indices[j] + uv_offset,
81 normal_indices[j] + normal_offset);
87void OBJWriter::write_vert_normal_indices(FormatHandler &fh,
88 const IndexOffsets &offsets,
95 const int vertex_offset = offsets.vertex_offset + 1;
96 const int normal_offset = offsets.normal_offset + 1;
97 const int n = vert_indices.
size();
98 fh.write_obj_face_begin();
100 for (
int j = 0; j < n; ++j) {
101 fh.write_obj_face_v_normal(vert_indices[j] + vertex_offset,
102 normal_indices[j] + normal_offset);
106 for (
int k = 0; k < n; ++k) {
107 int j = k == 0 ? 0 : n - k;
108 fh.write_obj_face_v_normal(vert_indices[j] + vertex_offset,
109 normal_indices[j] + normal_offset);
112 fh.write_obj_face_end();
115void OBJWriter::write_vert_uv_indices(FormatHandler &fh,
116 const IndexOffsets &offsets,
117 Span<int> vert_indices,
118 Span<int> uv_indices,
122 BLI_assert(vert_indices.size() == uv_indices.size());
123 const int vertex_offset = offsets.vertex_offset + 1;
124 const int uv_offset = offsets.uv_vertex_offset + 1;
125 const int n = vert_indices.size();
126 fh.write_obj_face_begin();
128 for (
int j = 0; j < n; ++j) {
129 fh.write_obj_face_v_uv(vert_indices[j] + vertex_offset, uv_indices[j] + uv_offset);
133 for (
int k = 0; k < n; ++k) {
134 int j = k == 0 ? 0 : n - k;
135 fh.write_obj_face_v_uv(vert_indices[j] + vertex_offset, uv_indices[j] + uv_offset);
138 fh.write_obj_face_end();
141void OBJWriter::write_vert_indices(FormatHandler &fh,
142 const IndexOffsets &offsets,
143 Span<int> vert_indices,
148 const int vertex_offset = offsets.vertex_offset + 1;
149 const int n = vert_indices.size();
150 fh.write_obj_face_begin();
152 for (
int j = 0; j < n; ++j) {
153 fh.write_obj_face_v(vert_indices[j] + vertex_offset);
157 for (
int k = 0; k < n; ++k) {
158 int j = k == 0 ? 0 : n - k;
159 fh.write_obj_face_v(vert_indices[j] + vertex_offset);
162 fh.write_obj_face_end();
167 using namespace std::string_literals;
181 sizeof(mtl_dir_name),
183 sizeof(mtl_file_name));
191 std::replace(r_name.begin(), r_name.end(),
' ',
'_');
221template<
typename Function>
224 if (tot_count <= 0) {
231 if (chunk_count == 1) {
232 for (
int i = 0; i < tot_count; i++) {
240 for (
const int r :
range) {
242 int i_end = std::min(i_start +
chunk_size, tot_count);
244 for (
int i = i_start; i < i_end; i++) {
257 bool write_colors)
const
262 const StringRef name = mesh->active_color_attribute;
267 if (write_colors && !name.is_empty()) {
293 const float2 &uv_vertex = uv_coords[i];
294 buf.write_obj_uv(uv_vertex[0], uv_vertex[1]);
303 const float3 &normal = normal_coords[i];
304 buf.write_obj_normal(normal[0], normal[1], normal[2]);
308OBJWriter::func_vert_uv_normal_indices OBJWriter::get_face_element_writer(
309 const int total_uv_vertices)
const
312 if (export_params_.
export_uv && (total_uv_vertices > 0)) {
314 return &OBJWriter::write_vert_uv_normal_indices;
317 return &OBJWriter::write_vert_normal_indices;
320 if (export_params_.
export_uv && (total_uv_vertices > 0)) {
321 return &OBJWriter::write_vert_uv_indices;
324 return &OBJWriter::write_vert_indices;
333 if (mesh.is_ith_face_smooth(face_idx)) {
344 const func_vert_uv_normal_indices face_element_writer = get_face_element_writer(
347 const int tot_faces = obj_mesh_data.
tot_faces();
351 const VArray<int> material_indices = *attributes.lookup_or_default<
int>(
367 const int prev_group =
get_smooth_group(obj_mesh_data, export_params_, prev_i);
369 if (group != prev_group) {
377 local_weights.
resize(tot_deform_groups);
380 prev_i, local_weights);
382 if (group != prev_group) {
393 const int16_t mat = std::max(0, material_indices[i]);
394 if (mat != prev_mat) {
401 const char *mat_name = matname_fn(mat);
418 (this->*face_element_writer)(buf,
429 const OBJMesh &obj_mesh_data)
const
433 if (loose_edges.
count == 0) {
438 for (
const int64_t i : edges.index_range()) {
449 for (
int spline_idx = 0; spline_idx < total_splines; spline_idx++) {
451 for (
int vertex_idx = 0; vertex_idx < total_vertices; vertex_idx++) {
471 for (
int i = 0; i < total_control_points; i++) {
488 for (
int i = 1; i <= total_control_points + 2; i++) {
489 float parm = 1.0f * i / (total_control_points + 2 + 1);
491 if (i <= nurbs_degree) {
494 else if (i > total_control_points + 2 - nurbs_degree) {
522 "array size mismatch");
530 std::ostringstream r_string;
531 r_string << numbers[0] <<
" " << numbers[1] <<
" " << numbers[2];
532 return r_string.str();
541 STRNCPY(mtl_path, obj_filepath);
545 throw std::system_error(ENAMETOOLONG, std::system_category(),
"");
548 mtl_filepath_ = mtl_path;
549 outfile_ =
BLI_fopen(mtl_filepath_.c_str(),
"wb");
551 throw std::system_error(errno, std::system_category(),
"Cannot open file " + mtl_filepath_);
558 if (std::fclose(outfile_)) {
559 std::cerr <<
"Error: could not close the file '" << mtl_filepath_
560 <<
"' properly, it may be corrupted." << std::endl;
567 using namespace std::string_literals;
568 const char *blen_basename = (blen_filepath && blen_filepath[0] !=
'\0') ?
572 blen_basename +
"'");
578 return mtl_filepath_;
581void MTLWriter::write_bsdf_properties(
const MTLMaterial &mtl,
bool write_pbr)
627 if (mtl.
aniso >= 0.0f) {
641void MTLWriter::write_texture_map(
const MTLMaterial &mtl_material,
643 const MTLTexMap &texture_map,
644 const char *blen_filedir,
645 const char *dest_dir,
647 Set<std::pair<std::string, std::string>> ©_set)
651 if (texture_map.translation !=
float3{0.0f, 0.0f, 0.0f}) {
654 if (texture_map.scale !=
float3{1.0f, 1.0f, 1.0f}) {
658 options.append(
" -bm ").append(std::to_string(mtl_material.normal_strength));
662 texture_map.image_path.c_str(), blen_filedir, dest_dir, path_mode, ©_set);
664 std::replace(path.begin(), path.end(),
'\\',
'/');
682 const char *dest_dir,
685 if (mtlmaterials_.is_empty()) {
694 std::sort(mtlmaterials_.begin(),
701 write_bsdf_properties(mtlmat, write_pbr);
704 if (!
tex.is_valid()) {
714 mtlmat, (
MTLTexMapType)key,
tex, blen_filedir, dest_dir, path_mode, copy_set);
727 r_mtl_indices[i] = -1;
731 if (mtlmat_index != -1) {
732 r_mtl_indices[i] = mtlmat_index;
736 r_mtl_indices[i] = mtlmaterials_.size() - 1;
737 material_map_.
add_new(material, r_mtl_indices[i]);
740 return r_mtl_indices;
745 if (index < 0 || index >= mtlmaterials_.size()) {
748 return mtlmaterials_[index].name.c_str();
const char * BKE_blender_version_string(void)
#define BLI_STATIC_ASSERT(a, msg)
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3])
void void void const char * BLI_path_basename(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
bool BLI_path_extension_replace(char *path, size_t path_maxncpy, const char *ext) ATTR_NONNULL(1
void BLI_path_slash_native(char *path) ATTR_NONNULL(1)
int BLI_path_normalize(char *path) ATTR_NONNULL(1)
void BLI_path_split_dir_file(const char *filepath, char *dir, size_t dir_maxncpy, char *file, size_t file_maxncpy) ATTR_NONNULL(1
void void BLI_path_split_dir_part(const char *filepath, char *dir, size_t dir_maxncpy) ATTR_NONNULL(1
#define STRNCPY(dst, src)
Value lookup_default(const Key &key, const Value &default_value) const
void add_new(const Key &key, const Value &value)
constexpr int64_t size() const
constexpr const char * data() const
void resize(const int64_t new_size)
MTLWriter(const char *obj_filepath, bool write_file) noexcept(false)
Vector< int > add_materials(const OBJMesh &mesh_to_export)
void write_header(const char *blen_filepath)
void write_materials(const char *blen_filepath, ePathReferenceMode path_mode, const char *dest_dir, bool write_pbr)
StringRefNull mtl_file_path() const
const char * mtlmaterial_name(int index)
int total_spline_vertices(int spline_index) const
int total_spline_control_points(int spline_index) const
short get_nurbs_flagu(int spline_index) const
float3 vertex_coordinates(int spline_index, int vertex_index, float global_scale) const
int get_nurbs_degree(int spline_index) const
const char * get_curve_name() const
int total_splines() 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
int tot_deform_groups() const
int16_t tot_materials() const
StringRef get_object_mesh_name() const
Span< int > get_face_uv_indices(const int face_index) const
bool is_mirrored_transform() const
int remap_face_index(int i) const
int tot_uv_vertices() const
Array< const Material * > materials
Span< float3 > get_normal_coords() const
const float4x4 & get_world_axes_transform() const
StringRef get_object_name() const
const Span< float2 > get_uv_coords() const
Span< int > get_face_normal_indices(const int face_index) const
Span< int > calc_face_vert_indices(const int face_index) const
const Mesh * get_mesh() const
void write_normals(FormatHandler &fh, OBJMesh &obj_mesh_data)
void write_uv_coords(FormatHandler &fh, OBJMesh &obj_mesh_data) const
void write_header() const
void write_mtllib_name(const StringRefNull mtl_filepath) const
void write_nurbs_curve(FormatHandler &fh, const OBJCurve &obj_nurbs_data) const
void write_face_elements(FormatHandler &fh, const IndexOffsets &offsets, const OBJMesh &obj_mesh_data, FunctionRef< const char *(int)> matname_fn)
void write_vertex_coords(FormatHandler &fh, const OBJMesh &obj_mesh_data, bool write_colors) const
void write_edges_indices(FormatHandler &fh, const IndexOffsets &offsets, const OBJMesh &obj_mesh_data) const
void write_object_name(FormatHandler &fh, const OBJMesh &obj_mesh_data) const
local_group_size(16, 16) .push_constant(Type b
CCL_NAMESPACE_BEGIN struct Options options
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
static void spaces_to_underscores(std::string &r_name)
static bool is_pbr_map(MTLTexMapType type)
static const char * tex_map_type_to_string[]
const int SMOOTH_GROUP_DEFAULT
static const char * MATERIAL_GROUP_DISABLED
MTLMaterial mtlmaterial_for_material(const Material *material)
const int SMOOTH_GROUP_DISABLED
static int get_smooth_group(const OBJMesh &mesh, const OBJExportParams ¶ms, int face_idx)
void obj_parallel_chunked_output(FormatHandler &fh, int tot_count, const Function &function)
static bool is_non_pbr_map(MTLTexMapType type)
static std::string float3_to_string(const float3 &numbers)
static const int chunk_size
static int calc_chunk_count(int count)
static const char * DEFORM_GROUP_DISABLED
std::string path_reference(StringRefNull filepath, StringRefNull base_src, StringRefNull base_dst, ePathReferenceMode mode, Set< std::pair< std::string, std::string > > *copy_set)
void path_reference_copy(const Set< std::pair< std::string, std::string > > ©_set)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
bool export_material_groups
bool export_object_groups
bool export_vertex_groups
blender::BitVector is_loose_bits
const MTLTexMap & tex_map_of_type(MTLTexMapType key) const