28using Alembic::Abc::P3fArraySamplePtr;
29using Alembic::AbcGeom::OCurves;
30using Alembic::AbcGeom::OCurvesSchema;
31using Alembic::AbcGeom::ON3fGeomParam;
32using Alembic::AbcGeom::OV2fGeomParam;
45 abc_curves_schema_ = abc_curves_.getSchema();
72 std::vector<Imath::V3f>
verts;
73 std::vector<int32_t> hvertices;
74 std::vector<Imath::V2f> uv_values;
75 std::vector<Imath::V3f> norm_values;
80 bool export_children = psys->
childcache && part->childtype != 0;
84 context,
const_cast<Mesh *
>(mesh),
verts, norm_values, uv_values, hvertices);
87 if (export_children) {
88 write_hair_child_sample(
89 context,
const_cast<Mesh *
>(mesh),
verts, norm_values, uv_values, hvertices);
93 Alembic::Abc::P3fArraySample iPos(
verts);
94 OCurvesSchema::Sample
sample(iPos, hvertices);
95 sample.setBasis(Alembic::AbcGeom::kNoBasis);
96 sample.setType(Alembic::AbcGeom::kLinear);
97 sample.setWrap(Alembic::AbcGeom::kNonPeriodic);
99 if (!uv_values.empty()) {
100 OV2fGeomParam::Sample uv_smp;
101 uv_smp.setVals(uv_values);
105 if (!norm_values.empty()) {
106 ON3fGeomParam::Sample norm_smp;
107 norm_smp.setVals(norm_values);
108 sample.setNormals(norm_smp);
113 abc_curves_schema_.set(
sample);
118 std::vector<Imath::V3f> &
verts,
119 std::vector<Imath::V3f> &norm_values,
120 std::vector<Imath::V2f> &uv_values,
121 std::vector<int32_t> &hvertices)
128 &mesh->fdata_legacy,
CD_MTFACE, mesh->totface_legacy);
133 if ((!mtface || !mface) && !uv_warning_shown_) {
135 "Warning, no UV set found for underlying geometry of %s.\n",
136 context.object->id.name + 2);
137 uv_warning_shown_ =
true;
150 for (
int p = 0; p < psys->
totpart; p++, pa++) {
158 if (num < mesh->totface_legacy) {
161 const MFace *face = mface ==
nullptr ? nullptr : &mface[num];
162 MTFace *tface = mtface + num;
165 float r_uv[2], mapfw[4], vec[3];
168 uv_values.emplace_back(r_uv[0], r_uv[1]);
171 reinterpret_cast<const float(*)[3]
>(positions.data()),
172 reinterpret_cast<const float(*)[3]
>(vert_normals.
data()),
184 norm_values.push_back(tmp_nor);
188 std::fprintf(stderr,
"Particle to faces overflow (%d/%d)\n", num, mesh->totface_legacy);
196 for (
int n = 0; n < mesh->totface_legacy; n++) {
197 const MFace *face = &mface[n];
198 const MTFace *tface = mtface + n;
206 for (
int o = 0; o < 4; o++) {
207 if (o > 2 && vtx[o] == 0) {
212 uv_values.emplace_back(tface->
uv[o][0], tface->
uv[o][1]);
215 norm_values.push_back(tmp_nor);
228 hvertices.push_back(
steps);
230 for (k = 0; k <
steps; k++, path++) {
236 verts.emplace_back(vert[0], vert[2], -vert[1]);
241void ABCHairWriter::write_hair_child_sample(
const HierarchyContext &context,
243 std::vector<Imath::V3f> &
verts,
244 std::vector<Imath::V3f> &norm_values,
245 std::vector<Imath::V2f> &uv_values,
246 std::vector<int32_t> &hvertices)
254 &mesh->fdata_legacy,
CD_MTFACE, mesh->totface_legacy);
255 const Span<float3> positions = mesh->vert_positions();
256 const Span<float3> vert_normals = mesh->vert_normals();
265 for (
int p = 0; p < psys->
totchild; p++, pc++) {
269 const int num = pc->
num;
273 "Child particle of hair system %s has unknown face index of geometry of %s, skipping "
276 context.object->id.name + 2);
280 const MFace *face = &mface[num];
281 MTFace *tface = mtface + num;
283 float r_uv[2], tmpnor[3], mapfw[4], vec[3];
286 uv_values.emplace_back(r_uv[0], r_uv[1]);
289 reinterpret_cast<const float(*)[3]
>(positions.data()),
290 reinterpret_cast<const float(*)[3]
>(vert_normals.data()),
302 norm_values.emplace_back(tmpnor[0], tmpnor[2], -tmpnor[1]);
305 if (!uv_values.empty()) {
306 uv_values.push_back(uv_values[pc->
parent]);
308 if (!norm_values.empty()) {
309 norm_values.push_back(norm_values[pc->
parent]);
314 hvertices.push_back(
steps);
316 for (
int k = 0; k <
steps; k++) {
322 verts.emplace_back(vert[0], vert[2], -vert[1]);
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
void BKE_mesh_tessface_ensure(Mesh *mesh)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
void psys_interpolate_uvs(const struct MTFace *tface, int quad, const float w[4], float uvco[2])
void psys_interpolate_face(struct Mesh *mesh, const float(*vert_positions)[3], const float(*vert_normals)[3], const struct MFace *mface, struct MTFace *tface, const float(*orcodata)[3], float w[4], float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3])
void mul_m4_v3(const float M[4][4], float r[3])
void invert_m4_m4_safe(float inverse[4][4], const float mat[4][4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define CLOG_WARN(clg_ref,...)
#define CLOG_INFO(clg_ref, level,...)
Object is a sort of wrapper for general info.
constexpr const T * data() const
Alembic::Abc::OCompoundProperty abc_schema_prop_for_custom_props(T abc_schema)
uint32_t timesample_index_
Imath::Box3d bounding_box_
const ABCWriterConstructorArgs args_
virtual void update_bounding_box(Object *object)
virtual Alembic::Abc::OObject get_alembic_object() const override
ABCHairWriter(const ABCWriterConstructorArgs &args)
virtual void do_write(HierarchyContext &context) override
virtual bool check_is_animated(const HierarchyContext &context) const override
Alembic::Abc::OCompoundProperty abc_prop_for_custom_props() override
virtual void create_alembic_objects(const HierarchyContext *context) override
BLI_INLINE void copy_yup_from_zup(float yup[3], const float zup[3])
struct ParticleCacheKey ** childcache
struct ParticleCacheKey ** pathcache
Alembic::Abc::OObject abc_parent