Files
test/source/blender/io/usd/intern/usd_reader_prim.h
Michael B Johnson b262655d39 USD: export to a single root prim by default
This PR adds the following changes:

A single root is always set as default. After talking to Wave and
Spiff, we settled on root being the best default. Users who don't
want a single root prim inserted, can choose to clear the field
The root prim no longer requires the user to prefix the field with /.
It will implicitly insert that for them.

On export, the root_prim hierarchy is now defined all as Xform
instead of just the final prim in the path. Each prim also has
custom metadata added to show that it was generated by Blender.
This follows convention in other DCCs as well.

On import, the code now finds the hierarchy of generated prims
using that metadata. It then skips importing them. This means that
you can roundtrip hierarchies even with an inserted root.

Co-authored-by: Dhruv Govil <dgovil2@apple.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/113187
2023-10-20 10:58:40 -04:00

152 lines
3.7 KiB
C++

/* SPDX-FileCopyrightText: 2021 Tangent Animation. All rights reserved.
* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Adapted from the Blender Alembic importer implementation. */
#pragma once
#include "usd.h"
#include "WM_types.hh"
#include <pxr/usd/sdf/path.h>
#include <pxr/usd/usd/prim.h>
#include <map>
#include <string>
struct CacheFile;
struct Main;
struct Material;
struct Object;
namespace blender::io::usd {
struct ImportSettings {
bool do_convert_mat;
float conversion_mat[4][4];
int from_up;
int from_forward;
float scale;
bool is_sequence;
bool set_frame_range;
/* Length and frame offset of file sequences. */
int sequence_len;
int sequence_offset;
/* From MeshSeqCacheModifierData.read_flag */
int read_flag;
bool validate_meshes;
CacheFile *cache_file;
/* Map a USD material prim path to a Blender material name.
* This map is updated by readers during stage traversal.
* This field is mutable because it is used to keep track
* of what the importer is doing. This is necessary even
* when all the other import settings are to remain const. */
mutable std::map<std::string, std::string> usd_path_to_mat_name;
/* Map a material name to Blender material.
* This map is updated by readers during stage traversal,
* and is mutable similar to the map above. */
mutable std::map<std::string, Material *> mat_name_to_mat;
/* We use the stage metersPerUnit to convert camera properties from USD scene units to the
* correct millimeter scale that Blender uses for camera parameters. */
double stage_meters_per_unit;
pxr::SdfPath skip_prefix;
ImportSettings()
: do_convert_mat(false),
from_up(0),
from_forward(0),
scale(1.0f),
is_sequence(false),
set_frame_range(false),
sequence_len(1),
sequence_offset(0),
read_flag(0),
validate_meshes(false),
cache_file(NULL),
stage_meters_per_unit(1.0),
skip_prefix(pxr::SdfPath{})
{
}
};
/* Most generic USD Reader. */
class USDPrimReader {
protected:
std::string name_;
std::string prim_path_;
Object *object_;
pxr::UsdPrim prim_;
const USDImportParams &import_params_;
USDPrimReader *parent_reader_;
const ImportSettings *settings_;
int refcount_;
public:
USDPrimReader(const pxr::UsdPrim &prim,
const USDImportParams &import_params,
const ImportSettings &settings);
virtual ~USDPrimReader();
const pxr::UsdPrim &prim() const;
virtual bool valid() const;
virtual void create_object(Main *bmain, double motionSampleTime) = 0;
virtual void read_object_data(Main * /*bmain*/, double /*motionSampleTime*/){};
Object *object() const;
void object(Object *ob);
USDPrimReader *parent() const
{
return parent_reader_;
}
void parent(USDPrimReader *parent)
{
parent_reader_ = parent;
}
/** Get the wmJobWorkerStatus-provided `reports` list pointer, to use with the BKE_report API. */
ReportList *reports() const
{
return import_params_.worker_status->reports;
}
/* Since readers might be referenced through handles
* maintained by modifiers and constraints, we provide
* a reference count to facilitate managing the object
* lifetime.
* TODO(makowalski): investigate transitioning to using
* smart pointers for readers, or, alternatively look into
* making the lifetime management more robust, e.g., by
* making the destructors protected and implementing deletion
* in decref(), etc. */
int refcount() const;
void incref();
void decref();
const std::string &name() const
{
return name_;
}
const std::string &prim_path() const
{
return prim_path_;
}
};
} // namespace blender::io::usd