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();
117 Span<int> vert_indices,
118 Span<int> uv_indices,
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();
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(),
' ',
'_');
198 if (export_params_.export_object_groups) {
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
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;
344 const func_vert_uv_normal_indices face_element_writer = get_face_element_writer(
347 const int tot_faces = obj_mesh_data.
tot_faces();
367 const int prev_group =
get_smooth_group(obj_mesh_data, export_params_, prev_i);
369 if (group != prev_group) {
375 if (export_params_.export_vertex_groups) {
377 local_weights.
resize(tot_deform_groups);
380 prev_i, local_weights);
382 if (group != prev_group) {
389 if ((export_params_.export_materials || export_params_.export_material_groups) &&
393 const int16_t mat = std::max(0, material_indices[i]);
394 if (mat != prev_mat) {
396 if (export_params_.export_materials) {
401 const char *mat_name = matname_fn(mat);
405 if (export_params_.export_material_groups) {
410 if (export_params_.export_materials) {
418 (this->*face_element_writer)(buf,
429 const OBJMesh &obj_mesh_data)
const
433 if (loose_edges.
count == 0) {
449 for (
int spline_idx = 0; spline_idx < total_splines; spline_idx++) {
451 for (
int vertex_idx = 0; vertex_idx < total_vertices; vertex_idx++) {
453 spline_idx, vertex_idx, export_params_.global_scale);
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_);
557 fmt_handler_.write_to_file(outfile_);
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 +
"'");
573 fmt_handler_.write_string(
"# www.blender.org");
578 return mtl_filepath_;
581void MTLWriter::write_bsdf_properties(
const MTLMaterial &mtl,
bool write_pbr)
602 fmt_handler_.write_mtl_float3(
605 fmt_handler_.write_mtl_float(
"Ni", mtl.
ior);
607 fmt_handler_.write_mtl_float(
"d", mtl.
alpha);
613 fmt_handler_.write_mtl_float(
"Pr", mtl.
roughness);
616 fmt_handler_.write_mtl_float(
"Pm", mtl.
metallic);
619 fmt_handler_.write_mtl_float(
"Ps", mtl.
sheen);
627 if (mtl.
aniso >= 0.0f) {
628 fmt_handler_.write_mtl_float(
"aniso", mtl.
aniso);
631 fmt_handler_.write_mtl_float(
"anisor", mtl.
aniso_rot);
635 fmt_handler_.write_mtl_float3(
641void MTLWriter::write_texture_map(
const MTLMaterial &mtl_material,
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(),
699 fmt_handler_.write_string(
"");
700 fmt_handler_.write_mtl_newmtl(mtlmat.name);
701 write_bsdf_properties(mtlmat, write_pbr);
703 const MTLTexMap &tex = mtlmat.texture_maps[key];
714 mtlmat, (
MTLTexMapType)key, tex, blen_filedir, dest_dir, path_mode, copy_set);
727 r_mtl_indices[i] = -1;
730 int mtlmat_index = material_map_.lookup_default(material, -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)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
constexpr int64_t size() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
constexpr const char * data() const
void resize(const int64_t new_size)
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
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
bool is_ith_face_smooth(int face_index) 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
int ith_smooth_group(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))
MatBase< float, 4, 4 > float4x4
VecBase< int32_t, 2 > int2
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
char * active_color_attribute
blender::BitVector is_loose_bits
const MTLTexMap & tex_map_of_type(MTLTexMapType key) const