Blender V5.0
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
8
9#pragma once
10
11#include <cstdio>
12
13#include "BLI_string_ref.hh"
14#include "BLI_utility_mixins.hh"
15#include "BLI_vector.hh"
16
17/* SEP macro from BLI path utils clashes with SEP symbol in fmt headers. */
18#undef SEP
19#include <fmt/format.h>
20
21namespace blender::io::obj {
22
31 private:
32 using VectorChar = Vector<char>;
33 Vector<VectorChar> blocks_;
34 size_t buffer_chunk_size_;
35
36 public:
37 FormatHandler(size_t buffer_chunk_size = 64 * 1024) : buffer_chunk_size_(buffer_chunk_size) {}
38
39 /* Write contents to the buffer(s) into a file, and clear the buffers. */
40 void write_to_file(FILE *f)
41 {
42 for (const auto &b : blocks_) {
43 fwrite(b.data(), 1, b.size(), f);
44 }
45 blocks_.clear();
46 }
47
48 std::string get_as_string() const
49 {
50 std::string s;
51 for (const auto &b : blocks_) {
52 s.append(b.data(), b.size());
53 }
54 return s;
55 }
56 size_t get_block_count() const
57 {
58 return blocks_.size();
59 }
60
62 {
63 blocks_.insert(blocks_.end(),
64 std::make_move_iterator(v.blocks_.begin()),
65 std::make_move_iterator(v.blocks_.end()));
66 v.blocks_.clear();
67 }
68
69 void write_obj_vertex(float x, float y, float z)
70 {
71 write_impl("v {:.6f} {:.6f} {:.6f}\n", x, y, z);
72 }
73 void write_obj_vertex_color(float x, float y, float z, float r, float g, float b)
74 {
75 write_impl("v {:.6f} {:.6f} {:.6f} {:.4f} {:.4f} {:.4f}\n", x, y, z, r, g, b);
76 }
77 void write_obj_uv(float x, float y)
78 {
79 write_impl("vt {:.6f} {:.6f}\n", x, y);
80 }
81 void write_obj_normal(float x, float y, float z)
82 {
83 write_impl("vn {:.4f} {:.4f} {:.4f}\n", x, y, z);
84 }
86 {
87 write_impl("f");
88 }
90 {
92 }
93 void write_obj_face_v_uv_normal(int v, int uv, int n)
94 {
95 write_impl(" {}/{}/{}", v, uv, n);
96 }
97 void write_obj_face_v_normal(int v, int n)
98 {
99 write_impl(" {}//{}", v, n);
100 }
101 void write_obj_face_v_uv(int v, int uv)
102 {
103 write_impl(" {}/{}", v, uv);
104 }
106 {
107 write_impl(" {}", v);
108 }
110 {
111 write_impl("usemtl {}\n", s);
112 }
114 {
115 write_impl("mtllib {}\n", s);
116 }
118 {
119 write_impl("s {}\n", s);
120 }
122 {
123 write_impl("g {}\n", s);
124 }
126 {
127 write_impl("o {}\n", s);
128 }
129 void write_obj_edge(int a, int b)
130 {
131 write_impl("l {} {}\n", a, b);
132 }
134 {
135 write_impl("cstype bspline\n");
136 }
138 {
139 write_impl("deg {}\n", deg);
140 }
142 {
143 write_impl("curv");
144 }
146 {
148 }
150 {
151 write_impl("parm u");
152 }
154 {
155 write_impl(" {:.6f}", v);
156 }
158 {
159 write_impl("\n");
160 }
162 {
163 write_impl("end\n");
164 }
166 {
167 write_impl("\n");
168 }
169
171 {
172 write_impl("newmtl {}\n", s);
173 }
174 void write_mtl_float(const char *type, float v)
175 {
176 write_impl("{} {:.6f}\n", type, v);
177 }
178 void write_mtl_float3(const char *type, float r, float g, float b)
179 {
180 write_impl("{} {:.6f} {:.6f} {:.6f}\n", type, r, g, b);
181 }
182 void write_mtl_illum(int mode)
183 {
184 write_impl("illum {}\n", mode);
185 }
186 /* NOTE: options, if present, will have its own leading space. */
187 void write_mtl_map(const char *type, StringRef options, StringRef value)
188 {
189 write_impl("{}{} {}\n", type, options, value);
190 }
191
193 {
194 write_impl("{}\n", s);
195 }
196
197 private:
198 /* Ensure the last block contains at least this amount of free space.
199 * If not, add a new block with max of block size & the amount of space needed. */
200 void ensure_space(size_t at_least)
201 {
202 if (blocks_.is_empty() || (blocks_.last().capacity() - blocks_.last().size() < at_least)) {
203 blocks_.append(VectorChar());
204 blocks_.last().reserve(std::max(at_least, buffer_chunk_size_));
205 }
206 }
207
208 template<typename... T> void write_impl(fmt::format_string<T...> fmt, T &&...args)
209 {
210 /* Format into a local buffer. */
211 fmt::memory_buffer buf;
212 fmt::format_to(fmt::appender(buf), fmt, std::forward<T>(args)...);
213 size_t len = buf.size();
214 ensure_space(len);
215 VectorChar &bb = blocks_.last();
216 bb.insert(bb.end(), buf.begin(), buf.end());
217 }
218};
219
220} // namespace blender::io::obj
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
NonCopyable(const NonCopyable &other)=delete
NonMovable(NonMovable &&other)=delete
void append(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)
CCL_NAMESPACE_BEGIN struct Options options
#define T
uint len