Blender V4.3
obj_export_io.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#pragma once
10
11#include <cstdio>
12#include <type_traits>
13
14#include "BLI_compiler_attrs.h"
15#include "BLI_fileops.h"
16#include "BLI_string_ref.hh"
17#include "BLI_utility_mixins.hh"
18#include "BLI_vector.hh"
19
20/* SEP macro from BLI path utils clashes with SEP symbol in fmt headers. */
21#undef SEP
22#include <fmt/format.h>
23
24namespace blender::io::obj {
25
34 private:
36 Vector<VectorChar> blocks_;
37 size_t buffer_chunk_size_;
38
39 public:
40 FormatHandler(size_t buffer_chunk_size = 64 * 1024) : buffer_chunk_size_(buffer_chunk_size) {}
41
42 /* Write contents to the buffer(s) into a file, and clear the buffers. */
43 void write_to_file(FILE *f)
44 {
45 for (const auto &b : blocks_) {
46 fwrite(b.data(), 1, b.size(), f);
47 }
48 blocks_.clear();
49 }
50
51 std::string get_as_string() const
52 {
53 std::string s;
54 for (const auto &b : blocks_) {
55 s.append(b.data(), b.size());
56 }
57 return s;
58 }
59 size_t get_block_count() const
60 {
61 return blocks_.size();
62 }
63
65 {
66 blocks_.insert(blocks_.end(),
67 std::make_move_iterator(v.blocks_.begin()),
68 std::make_move_iterator(v.blocks_.end()));
69 v.blocks_.clear();
70 }
71
72 void write_obj_vertex(float x, float y, float z)
73 {
74 write_impl("v {:.6f} {:.6f} {:.6f}\n", x, y, z);
75 }
76 void write_obj_vertex_color(float x, float y, float z, float r, float g, float b)
77 {
78 write_impl("v {:.6f} {:.6f} {:.6f} {:.4f} {:.4f} {:.4f}\n", x, y, z, r, g, b);
79 }
80 void write_obj_uv(float x, float y)
81 {
82 write_impl("vt {:.6f} {:.6f}\n", x, y);
83 }
84 void write_obj_normal(float x, float y, float z)
85 {
86 write_impl("vn {:.4f} {:.4f} {:.4f}\n", x, y, z);
87 }
89 {
90 write_impl("f");
91 }
93 {
95 }
96 void write_obj_face_v_uv_normal(int v, int uv, int n)
97 {
98 write_impl(" {}/{}/{}", v, uv, n);
99 }
100 void write_obj_face_v_normal(int v, int n)
101 {
102 write_impl(" {}//{}", v, n);
103 }
104 void write_obj_face_v_uv(int v, int uv)
105 {
106 write_impl(" {}/{}", v, uv);
107 }
109 {
110 write_impl(" {}", v);
111 }
113 {
114 write_impl("usemtl {}\n", s);
115 }
117 {
118 write_impl("mtllib {}\n", s);
119 }
121 {
122 write_impl("s {}\n", s);
123 }
125 {
126 write_impl("g {}\n", s);
127 }
129 {
130 write_impl("o {}\n", s);
131 }
132 void write_obj_edge(int a, int b)
133 {
134 write_impl("l {} {}\n", a, b);
135 }
137 {
138 write_impl("cstype bspline\n");
139 }
141 {
142 write_impl("deg {}\n", deg);
143 }
145 {
146 write_impl("curv 0.0 1.0");
147 }
149 {
151 }
153 {
154 write_impl("parm u 0.0");
155 }
157 {
158 write_impl(" {:.6f}", v);
159 }
161 {
162 write_impl(" 1.0\n");
163 }
165 {
166 write_impl("end\n");
167 }
169 {
170 write_impl("\n");
171 }
172
174 {
175 write_impl("newmtl {}\n", s);
176 }
177 void write_mtl_float(const char *type, float v)
178 {
179 write_impl("{} {:.6f}\n", type, v);
180 }
181 void write_mtl_float3(const char *type, float r, float g, float b)
182 {
183 write_impl("{} {:.6f} {:.6f} {:.6f}\n", type, r, g, b);
184 }
185 void write_mtl_illum(int mode)
186 {
187 write_impl("illum {}\n", mode);
188 }
189 /* NOTE: options, if present, will have its own leading space. */
190 void write_mtl_map(const char *type, StringRef options, StringRef value)
191 {
192 write_impl("{}{} {}\n", type, options, value);
193 }
194
196 {
197 write_impl("{}\n", s);
198 }
199
200 private:
201 /* Ensure the last block contains at least this amount of free space.
202 * If not, add a new block with max of block size & the amount of space needed. */
203 void ensure_space(size_t at_least)
204 {
205 if (blocks_.is_empty() || (blocks_.last().capacity() - blocks_.last().size() < at_least)) {
206 blocks_.append(VectorChar());
207 blocks_.last().reserve(std::max(at_least, buffer_chunk_size_));
208 }
209 }
210
211 template<typename... T> void write_impl(const char *fmt, T &&...args)
212 {
213 /* Format into a local buffer. */
214 fmt::memory_buffer buf;
215 fmt::format_to(fmt::appender(buf), fmt, std::forward<T>(args)...);
216 size_t len = buf.size();
217 ensure_space(len);
218 VectorChar &bb = blocks_.last();
219 bb.insert(bb.end(), buf.begin(), buf.end());
220 }
221};
222
223} // namespace blender::io::obj
File and directory operations.
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
int64_t size() const
void append(const T &value)
void insert(const int64_t insert_index, const T &value)
const T & last(const int64_t n=0) const
bool is_empty() const
void write_obj_face_v_normal(int v, int n)
void write_obj_normal(float x, float y, float z)
void write_mtl_map(const char *type, StringRef options, StringRef value)
void write_obj_face_v_uv_normal(int v, int uv, int n)
void write_mtl_float3(const char *type, float r, float g, float b)
void write_obj_vertex(float x, float y, float z)
void write_obj_vertex_color(float x, float y, float z, float r, float g, float b)
void write_obj_uv(float x, float y)
void write_obj_face_v_uv(int v, int uv)
std::string get_as_string() const
FormatHandler(size_t buffer_chunk_size=64 *1024)
void write_mtl_float(const char *type, float v)
void append_from(FormatHandler &v)
local_group_size(16, 16) .push_constant(Type b
CCL_NAMESPACE_BEGIN struct Options options
int len