1 // 2 // Copyright 2019 Pixar 3 // 4 // Licensed under the Apache License, Version 2.0 (the "Apache License") 5 // with the following modification; you may not use this file except in 6 // compliance with the Apache License and the following modification to it: 7 // Section 6. Trademarks. is deleted and replaced with: 8 // 9 // 6. Trademarks. This License does not grant permission to use the trade 10 // names, trademarks, service marks, or product names of the Licensor 11 // and its affiliates, except as required to comply with Section 4(c) of 12 // the License and to reproduce the content of the NOTICE file. 13 // 14 // You may obtain a copy of the Apache License at 15 // 16 // http://www.apache.org/licenses/LICENSE-2.0 17 // 18 // Unless required by applicable law or agreed to in writing, software 19 // distributed under the Apache License with the above modification is 20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 21 // KIND, either express or implied. See the Apache License for the specific 22 // language governing permissions and limitations under the Apache License. 23 // 24 #ifndef PXR_EXTRAS_USD_EXAMPLES_USD_RECURSIVE_PAYLOADS_EXAMPLE_FILE_FORMAT_H 25 #define PXR_EXTRAS_USD_EXAMPLES_USD_RECURSIVE_PAYLOADS_EXAMPLE_FILE_FORMAT_H 26 27 #include "pxr/pxr.h" 28 #include "pxr/usd/sdf/fileFormat.h" 29 #include "pxr/usd/pcp/dynamicFileFormatInterface.h" 30 #include "pxr/base/tf/staticTokens.h" 31 #include <string> 32 33 PXR_NAMESPACE_OPEN_SCOPE 34 35 #define USD_RECURSIVE_PAYLOADS_EXAMPLE_FILE_FORMAT_TOKENS \ 36 ((Id, "usdRecursivePayloadsExample")) \ 37 ((Version, "1.0")) \ 38 ((Target, "usd")) \ 39 ((Extension, "usdrecursivepayloadsexample")) \ 40 ((Depth, "UsdExample_depth")) \ 41 ((Num, "UsdExample_num")) \ 42 ((Radius, "UsdExample_radius")) \ 43 ((Height, "UsdExample_height")) \ 44 ((ArgDict, "UsdExample_argDict")) \ 45 ((PayloadId, "UsdExample_payloadId")) 46 47 TF_DECLARE_PUBLIC_TOKENS(UsdRecursivePayloadsExampleFileFormatTokens, 48 USD_RECURSIVE_PAYLOADS_EXAMPLE_FILE_FORMAT_TOKENS); 49 50 TF_DECLARE_WEAK_AND_REF_PTRS(UsdRecursivePayloadsExampleFileFormat); 51 TF_DECLARE_WEAK_AND_REF_PTRS(SdfLayerBase); 52 53 /// \class UsdRecursivePayloadsExampleFileFormat 54 /// 55 /// This is an example of a dynamic file format plugin that demonstrates one 56 /// method of generating dynamic content from composed metadata fields in scene 57 /// description by creating scene description with payloads to the same dynamic 58 /// file but with different parameters. 59 /// 60 /// This contents of a file of this format are expected to be the same as usda 61 /// file content. If the file is opened with file format arguments for "num" and 62 /// "depth" that are greater than 0, then it will generate a ring of Xform prim 63 /// children that will each have a payload to this file again but with depth-1. 64 /// It will also adds a "geom" child that references the payload asset file 65 /// with no parameters, just reading it as an sdf file and referencing the 66 /// default prim. Thus we end up with a recursively generated set of prims 67 /// containing the contents of the dynamic file. 68 /// 69 /// As an example if you have the following prim defined in a usd file: 70 /// 71 /// def Xform "Root" ( 72 /// UsdExample_num = 2 73 /// UsdExample_depth = 3 74 /// UsdExample_radius = 20.0 75 /// payload = @cone.usdrecursivepayloadsexample@ 76 /// ) {} 77 /// 78 /// It will generate a prim structure that looks something like this: 79 /// 80 /// Root (payload = @cone.usdrecursivepayloadsexample@ 81 /// | UsdExample_num = 2 82 /// | UsdExample_depth = 3 83 /// | UsdExample_radius = 20.0) 84 /// | 85 /// | geom (reference = @cone.usdrecursivepayloadsexample@) 86 /// | 87 /// | Xform__2_0 (payload = @cone.usdrecursivepayloadsexample@ 88 /// | | UsdExample_num = 2 89 /// | | UsdExample_depth = 2 90 /// | | UsdExample_radius = 10.0) 91 /// | | 92 /// | | geom (reference = @cone.usdrecursivepayloadsexample@) 93 /// | | 94 /// | | Xform__1_0 (payload = @cone.usdrecursivepayloadsexample@ 95 /// | | | UsdExample_num = 2 96 /// | | | UsdExample_depth = 1 97 /// | | | UsdExample_radius = 5.0) 98 /// | | | 99 /// | | | geom (reference = @cone.usdrecursivepayloadsexample@) 100 /// | | 101 /// | | Xform__1_1 (payload = @cone.usdrecursivepayloadsexample@ 102 /// | | | UsdExample_num = 2 103 /// | | | UsdExample_depth = 1 104 /// | | | UsdExample_radius = 5.0) 105 /// | | | 106 /// | | | geom (reference = @cone.usdrecursivepayloadsexample@) 107 /// | 108 /// | Xform__2_1 (payload = @cone.usdrecursivepayloadsexample@ 109 /// | | UsdExample_num = 2 110 /// | | UsdExample_depth = 2 111 /// | | UsdExample_radius = 10.0) 112 /// | | 113 /// | | geom (reference = @cone.usdrecursivepayloadsexample@) 114 /// | | 115 /// | | Xform__1_0 (payload = @cone.usdrecursivepayloadsexample@ 116 /// | | | UsdExample_num = 2 117 /// | | | UsdExample_depth = 1 118 /// | | | UsdExample_radius = 5.0) 119 /// | | | 120 /// | | | geom (reference = @cone.usdrecursivepayloadsexample@) 121 /// | | 122 /// | | Xform__1_1 (payload = @cone.usdrecursivepayloadsexample@ 123 /// | | | UsdExample_num = 2 124 /// | | | UsdExample_depth = 1 125 /// | | | UsdExample_radius = 5.0) 126 /// | | | 127 /// | | | geom (reference = @cone.usdrecursivepayloadsexample@) 128 /// 129 /// Valid metadata field parameters: 130 /// depth - The number of times to recurse when generating rings of prims 131 /// num - The number of prims to place in the ring at each level of depth. 132 /// radius - The radius of the ring around the parent prim which generated 133 /// prims are placed. 134 /// height - Vertical distance above the parent where the ring is placed. 135 /// argDict - A dictionary of values that can specify the above parameters for 136 /// specifically IDed payloads. 137 /// 138 class UsdRecursivePayloadsExampleFileFormat : public SdfFileFormat, 139 public PcpDynamicFileFormatInterface 140 { 141 public: 142 143 // SdfFileFormat overrides. 144 bool CanRead(const std::string &file) const override; 145 bool Read(SdfLayer *layer, 146 const std::string& resolvedPath, 147 bool metadataOnly) const override; 148 149 // We override Write methods so SdfLayer::ExportToString() etc, work. 150 // Writing this layer will write out the generated layer contents. 151 bool WriteToString(const SdfLayer& layer, 152 std::string* str, 153 const std::string& comment=std::string()) const override; 154 bool WriteToStream(const SdfSpecHandle &spec, 155 std::ostream& out, 156 size_t indent) const override; 157 158 // A required override for generating dynamic arguments that are 159 // particular to this file format. 160 void ComposeFieldsForFileFormatArguments( 161 const std::string& assetPath, 162 const PcpDynamicFileFormatContext& context, 163 FileFormatArguments* args, 164 VtValue *dependencyContextData) const override; 165 166 // Another required override for dynamic file arguments to help determine 167 // which changes may cause prims using this file format to be invalidated. 168 bool CanFieldChangeAffectFileFormatArguments( 169 const TfToken& field, 170 const VtValue& oldValue, 171 const VtValue& newValue, 172 const VtValue &dependencyContextData) const override; 173 174 protected: 175 SDF_FILE_FORMAT_FACTORY_ACCESS; 176 177 virtual ~UsdRecursivePayloadsExampleFileFormat(); 178 UsdRecursivePayloadsExampleFileFormat(); 179 }; 180 181 182 PXR_NAMESPACE_CLOSE_SCOPE 183 184 #endif // PXR_EXTRAS_USD_EXAMPLES_USD_RECURSIVE_PAYLOADS_EXAMPLE_FILE_FORMAT_H 185