22 #include <pxr/usd/usdGeom/mesh.h>
23 #include <pxr/usd/usdShade/material.h>
24 #include <pxr/usd/usdShade/materialBindingAPI.h>
64 bool needsfree =
false;
67 if (
mesh ==
nullptr) {
114 void USDGenericMeshWriter::write_uv_maps(
const Mesh *
mesh, pxr::UsdGeomMesh usd_mesh)
119 for (
int layer_idx = 0; layer_idx < ldata->
totlayer; layer_idx++) {
129 pxr::TfToken primvar_name(pxr::TfMakeValidIdentifier(layer->
name));
130 pxr::UsdGeomPrimvar uv_coords_primvar = usd_mesh.CreatePrimvar(
131 primvar_name, pxr::SdfValueTypeNames->TexCoord2fArray, pxr::UsdGeomTokens->faceVarying);
134 pxr::VtArray<pxr::GfVec2f> uv_coords;
135 for (
int loop_idx = 0; loop_idx <
mesh->
totloop; loop_idx++) {
136 uv_coords.push_back(pxr::GfVec2f(mloopuv[loop_idx].uv));
139 if (!uv_coords_primvar.HasValue()) {
140 uv_coords_primvar.Set(uv_coords, pxr::UsdTimeCode::Default());
142 const pxr::UsdAttribute &uv_coords_attr = uv_coords_primvar.GetAttr();
143 usd_value_writer_.SetAttribute(uv_coords_attr, pxr::VtValue(uv_coords), timecode);
147 void USDGenericMeshWriter::write_mesh(HierarchyContext &
context,
Mesh *
mesh)
150 pxr::UsdTimeCode defaultTime = pxr::UsdTimeCode::Default();
154 pxr::UsdGeomMesh usd_mesh = pxr::UsdGeomMesh::Define(
stage,
usd_path);
157 USDMeshData usd_mesh_data;
158 get_geometry_data(
mesh, usd_mesh_data);
170 assign_materials(
context, usd_mesh, usd_mesh_data.face_groups);
176 pxr::UsdAttribute attr_points = usd_mesh.CreatePointsAttr(pxr::VtValue(),
true);
177 pxr::UsdAttribute attr_face_vertex_counts = usd_mesh.CreateFaceVertexCountsAttr(pxr::VtValue(),
179 pxr::UsdAttribute attr_face_vertex_indices = usd_mesh.CreateFaceVertexIndicesAttr(pxr::VtValue(),
182 if (!attr_points.HasValue()) {
185 attr_points.Set(usd_mesh_data.points, defaultTime);
186 attr_face_vertex_counts.Set(usd_mesh_data.face_vertex_counts, defaultTime);
187 attr_face_vertex_indices.Set(usd_mesh_data.face_indices, defaultTime);
190 usd_value_writer_.SetAttribute(attr_points, pxr::VtValue(usd_mesh_data.points), timecode);
192 attr_face_vertex_counts, pxr::VtValue(usd_mesh_data.face_vertex_counts), timecode);
194 attr_face_vertex_indices, pxr::VtValue(usd_mesh_data.face_indices), timecode);
196 if (!usd_mesh_data.crease_lengths.empty()) {
197 pxr::UsdAttribute attr_crease_lengths = usd_mesh.CreateCreaseLengthsAttr(pxr::VtValue(),
true);
198 pxr::UsdAttribute attr_crease_indices = usd_mesh.CreateCreaseIndicesAttr(pxr::VtValue(),
true);
199 pxr::UsdAttribute attr_crease_sharpness = usd_mesh.CreateCreaseSharpnessesAttr(pxr::VtValue(),
202 if (!attr_crease_lengths.HasValue()) {
203 attr_crease_lengths.Set(usd_mesh_data.crease_lengths, defaultTime);
204 attr_crease_indices.Set(usd_mesh_data.crease_vertex_indices, defaultTime);
205 attr_crease_sharpness.Set(usd_mesh_data.crease_sharpnesses, defaultTime);
209 attr_crease_lengths, pxr::VtValue(usd_mesh_data.crease_lengths), timecode);
211 attr_crease_indices, pxr::VtValue(usd_mesh_data.crease_vertex_indices), timecode);
213 attr_crease_sharpness, pxr::VtValue(usd_mesh_data.crease_sharpnesses), timecode);
217 write_uv_maps(
mesh, usd_mesh);
220 write_normals(
mesh, usd_mesh);
222 write_surface_velocity(
context.object,
mesh, usd_mesh);
229 usd_mesh.CreateSubdivisionSchemeAttr().Set(pxr::UsdGeomTokens->
none);
232 assign_materials(
context, usd_mesh, usd_mesh_data.face_groups);
242 usd_mesh_data.
points.push_back(pxr::GfVec3f(
verts[i].co));
250 bool construct_face_groups =
mesh->
totcol > 1;
260 for (
int j = 0; j < mpoly->
totloop; ++j, ++loop) {
264 if (construct_face_groups) {
272 const float factor = 1.0f / 255.0f;
276 for (
int edge_idx = 0, totedge =
mesh->
totedge; edge_idx < totedge; ++edge_idx, ++edge) {
281 if (edge->
crease == 255) {
282 sharpness = pxr::UsdGeomMesh::SHARPNESS_INFINITE;
285 sharpness =
static_cast<float>(edge->
crease) * factor;
295 void USDGenericMeshWriter::get_geometry_data(
const Mesh *
mesh, USDMeshData &usd_mesh_data)
302 void USDGenericMeshWriter::assign_materials(
const HierarchyContext &
context,
303 pxr::UsdGeomMesh usd_mesh,
304 const MaterialFaceGroups &usd_face_groups)
306 if (
context.object->totcol == 0) {
313 bool mesh_material_bound =
false;
314 pxr::UsdShadeMaterialBindingAPI material_binding_api(usd_mesh.GetPrim());
315 for (
int mat_num = 0; mat_num <
context.object->totcol; mat_num++) {
322 material_binding_api.Bind(usd_material);
326 usd_mesh.CreateDoubleSidedAttr(
329 mesh_material_bound =
true;
333 if (!mesh_material_bound) {
335 usd_mesh.CreateDoubleSidedAttr(pxr::VtValue(
true));
338 if (!mesh_material_bound || usd_face_groups.size() < 2) {
346 for (
const MaterialFaceGroups::value_type &face_group : usd_face_groups) {
347 short material_number = face_group.first;
348 const pxr::VtIntArray &face_indices = face_group.second;
356 pxr::TfToken material_name = usd_material.GetPath().GetNameToken();
358 pxr::UsdGeomSubset usd_face_subset = material_binding_api.CreateMaterialBindSubset(
359 material_name, face_indices);
360 pxr::UsdShadeMaterialBindingAPI(usd_face_subset.GetPrim()).Bind(usd_material);
364 void USDGenericMeshWriter::write_normals(
const Mesh *
mesh, pxr::UsdGeomMesh usd_mesh)
369 pxr::VtVec3fArray loop_normals;
372 if (lnors !=
nullptr) {
374 for (
int loop_idx = 0, totloop =
mesh->
totloop; loop_idx < totloop; ++loop_idx) {
375 loop_normals.push_back(pxr::GfVec3f(lnors[loop_idx]));
383 for (
int poly_idx = 0, totpoly =
mesh->
totpoly; poly_idx < totpoly; ++poly_idx, ++mpoly) {
389 pxr::GfVec3f pxr_normal(
normal);
390 for (
int loop_idx = 0; loop_idx < mpoly->
totloop; ++loop_idx) {
391 loop_normals.push_back(pxr_normal);
396 for (
int loop_idx = 0; loop_idx < mpoly->
totloop; ++loop_idx, ++mloop) {
398 loop_normals.push_back(pxr::GfVec3f(
normal));
404 pxr::UsdAttribute attr_normals = usd_mesh.CreateNormalsAttr(pxr::VtValue(),
true);
405 if (!attr_normals.HasValue()) {
406 attr_normals.Set(loop_normals, pxr::UsdTimeCode::Default());
408 usd_value_writer_.SetAttribute(attr_normals, pxr::VtValue(loop_normals), timecode);
409 usd_mesh.SetNormalsInterpolation(pxr::UsdGeomTokens->faceVarying);
412 void USDGenericMeshWriter::write_surface_velocity(
Object *
object,
414 pxr::UsdGeomMesh usd_mesh)
441 pxr::VtVec3fArray usd_velocities;
445 for (
int vertex_idx = 0, totvert =
mesh->
totvert; vertex_idx < totvert;
446 ++vertex_idx, ++mesh_velocities) {
447 usd_velocities.push_back(pxr::GfVec3f(mesh_velocities->
vel));
451 usd_mesh.CreateVelocitiesAttr().Set(usd_velocities, timecode);
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_get_layer(const struct CustomData *data, int type)
void BKE_id_free(struct Main *bmain, void *idv)
General operations, lookup, etc. for materials.
struct Material * BKE_object_material_get(struct Object *ob, short act)
void BKE_mesh_calc_poly_normal(const struct MPoly *mpoly, const struct MLoop *loopstart, const struct MVert *mvarray, float r_no[3])
bool BKE_modifier_is_enabled(const struct Scene *scene, struct ModifierData *md, int required_mode)
struct ModifierData * BKE_modifiers_findby_type(const struct Object *ob, ModifierType type)
General operations, lookup, etc. for blender objects.
struct Mesh * BKE_object_get_evaluated_mesh(struct Object *object)
MINLINE void normal_short_to_float_v3(float r[3], const short n[3])
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
#define OB_FLUIDSIM_DOMAIN
bool frame_has_been_written_
const pxr::SdfPath & usd_path() const
void write_visibility(const HierarchyContext &context, const pxr::UsdTimeCode timecode, pxr::UsdGeomImageable &usd_geometry)
pxr::UsdShadeMaterial ensure_usd_material(Material *material)
virtual bool mark_as_instance(const HierarchyContext &context, const pxr::UsdPrim &prim)
pxr::UsdTimeCode get_export_time_code() const
pxr::UsdUtilsSparseValueWriter usd_value_writer_
const USDExporterContext usd_export_context_
USDGenericMeshWriter(const USDExporterContext &ctx)
virtual void do_write(HierarchyContext &context) override
virtual bool is_supported(const HierarchyContext *context) const override
virtual Mesh * get_export_mesh(Object *object_eval, bool &r_needsfree)=0
virtual void free_export_mesh(Mesh *mesh)
USDMeshWriter(const USDExporterContext &ctx)
virtual Mesh * get_export_mesh(Object *object_eval, bool &r_needsfree) override
IconTextureDrawCall normal
static void get_loops_polys(const Mesh *mesh, USDMeshData &usd_mesh_data)
static void get_vertices(const Mesh *mesh, USDMeshData &usd_mesh_data)
static void get_creases(const Mesh *mesh, USDMeshData &usd_mesh_data)
struct SELECTID_Context context
struct FluidsimSettings * fss
struct FluidVertexVelocity * meshVelocities
struct CustomData pdata ldata
enum eEvaluationMode evaluation_mode
bool visible_objects_only
const USDExportParams & export_params
const pxr::SdfPath usd_path
const pxr::UsdStageRefPtr stage
pxr::VtIntArray face_vertex_counts
pxr::VtIntArray crease_vertex_indices
pxr::VtIntArray face_indices
pxr::VtIntArray crease_lengths
std::map< short, pxr::VtIntArray > face_groups
pxr::VtFloatArray crease_sharpnesses
pxr::VtArray< pxr::GfVec3f > points
__forceinline bool none(const avxb &b)