Blender  V2.93
usd_writer_abstract.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2019 Blender Foundation.
17  * All rights reserved.
18  */
19 #include "usd_writer_abstract.h"
20 #include "usd_hierarchy_iterator.h"
21 
22 #include <pxr/base/tf/stringUtils.h>
23 
24 #include "BLI_assert.h"
25 
26 /* TfToken objects are not cheap to construct, so we do it once. */
27 namespace usdtokens {
28 /* Materials */
29 static const pxr::TfToken diffuse_color("diffuseColor", pxr::TfToken::Immortal);
30 static const pxr::TfToken metallic("metallic", pxr::TfToken::Immortal);
31 static const pxr::TfToken preview_shader("previewShader", pxr::TfToken::Immortal);
32 static const pxr::TfToken preview_surface("UsdPreviewSurface", pxr::TfToken::Immortal);
33 static const pxr::TfToken roughness("roughness", pxr::TfToken::Immortal);
34 static const pxr::TfToken surface("surface", pxr::TfToken::Immortal);
35 } // namespace usdtokens
36 
37 namespace blender::io::usd {
38 
40  : usd_export_context_(usd_export_context), frame_has_been_written_(false), is_animated_(false)
41 {
42 }
43 
44 bool USDAbstractWriter::is_supported(const HierarchyContext * /*context*/) const
45 {
46  return true;
47 }
48 
50 {
51  if (is_animated_) {
53  }
54  /* By using the default timecode USD won't even write a single `timeSample` for non-animated
55  * data. Instead, it writes it as non-timesampled. */
56  static pxr::UsdTimeCode default_timecode = pxr::UsdTimeCode::Default();
57  return default_timecode;
58 }
59 
61 {
65  }
66  else if (!is_animated_) {
67  /* A frame has already been written, and without animation one frame is enough. */
68  return;
69  }
70 
72 
74 }
75 
76 const pxr::SdfPath &USDAbstractWriter::usd_path() const
77 {
79 }
80 
82 {
83  static pxr::SdfPath material_library_path("/_materials");
84  pxr::UsdStageRefPtr stage = usd_export_context_.stage;
85 
86  /* Construct the material. */
87  pxr::TfToken material_name(usd_export_context_.hierarchy_iterator->get_id_name(&material->id));
88  pxr::SdfPath usd_path = material_library_path.AppendChild(material_name);
89  pxr::UsdShadeMaterial usd_material = pxr::UsdShadeMaterial::Get(stage, usd_path);
90  if (usd_material) {
91  return usd_material;
92  }
93  usd_material = pxr::UsdShadeMaterial::Define(stage, usd_path);
94 
95  /* Construct the shader. */
96  pxr::SdfPath shader_path = usd_path.AppendChild(usdtokens::preview_shader);
97  pxr::UsdShadeShader shader = pxr::UsdShadeShader::Define(stage, shader_path);
98  shader.CreateIdAttr(pxr::VtValue(usdtokens::preview_surface));
99  shader.CreateInput(usdtokens::diffuse_color, pxr::SdfValueTypeNames->Color3f)
100  .Set(pxr::GfVec3f(material->r, material->g, material->b));
101  shader.CreateInput(usdtokens::roughness, pxr::SdfValueTypeNames->Float).Set(material->roughness);
102  shader.CreateInput(usdtokens::metallic, pxr::SdfValueTypeNames->Float).Set(material->metallic);
103 
104  /* Connect the shader and the material together. */
105  usd_material.CreateSurfaceOutput().ConnectToSource(shader, usdtokens::surface);
106 
107  return usd_material;
108 }
109 
111  const pxr::UsdTimeCode timecode,
112  pxr::UsdGeomImageable &usd_geometry)
113 {
114  pxr::UsdAttribute attr_visibility = usd_geometry.CreateVisibilityAttr(pxr::VtValue(), true);
115 
116  const bool is_visible = context.is_object_visible(
118  const pxr::TfToken visibility = is_visible ? pxr::UsdGeomTokens->inherited :
119  pxr::UsdGeomTokens->invisible;
120 
121  usd_value_writer_.SetAttribute(attr_visibility, pxr::VtValue(visibility), timecode);
122 }
123 
124 /* Reference the original data instead of writing a copy. */
125 bool USDAbstractWriter::mark_as_instance(const HierarchyContext &context, const pxr::UsdPrim &prim)
126 {
127  BLI_assert(context.is_instance());
128 
129  if (context.export_path == context.original_export_path) {
130  printf("USD ref error: export path is reference path: %s\n", context.export_path.c_str());
131  BLI_assert(!"USD reference error");
132  return false;
133  }
134 
135  pxr::SdfPath ref_path(context.original_export_path);
136  if (!prim.GetReferences().AddInternalReference(ref_path)) {
137  /* See this URL for a description fo why referencing may fail"
138  * https://graphics.pixar.com/usd/docs/api/class_usd_references.html#Usd_Failing_References
139  */
140  printf("USD Export warning: unable to add reference from %s to %s, not instancing object\n",
141  context.export_path.c_str(),
142  context.original_export_path.c_str());
143  return false;
144  }
145 
146  return true;
147 }
148 
149 } // namespace blender::io::usd
#define BLI_assert(a)
Definition: BLI_assert.h:58
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner Anti Mix RGB Hue Separate TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC Boolean Random Float
virtual std::string get_id_name(const ID *id) const
virtual bool check_is_animated(const HierarchyContext &context) const
virtual void do_write(HierarchyContext &context)=0
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_
USDAbstractWriter(const USDExporterContext &usd_export_context)
virtual void write(HierarchyContext &context) override
virtual bool is_supported(const HierarchyContext *context) const
const USDExporterContext usd_export_context_
const pxr::UsdTimeCode & get_export_time_code() const
EvaluationStage stage
Definition: deg_eval.cc:96
Material material
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
static const pxr::TfToken preview_shader("previewShader", pxr::TfToken::Immortal)
static const pxr::TfToken surface("surface", pxr::TfToken::Immortal)
static const pxr::TfToken roughness("roughness", pxr::TfToken::Immortal)
static const pxr::TfToken metallic("metallic", pxr::TfToken::Immortal)
static const pxr::TfToken diffuse_color("diffuseColor", pxr::TfToken::Immortal)
static const pxr::TfToken preview_surface("UsdPreviewSurface", pxr::TfToken::Immortal)
struct SELECTID_Context context
Definition: select_engine.c:47
bool export_animation
Definition: usd.h:31
enum eEvaluationMode evaluation_mode
Definition: usd.h:39
const USDHierarchyIterator * hierarchy_iterator