This is an initial implementation of a USD importer. This work is comprised of Tangent Animation's open source USD importer, combined with features @makowalski had implemented. The design is very similar to the approach taken in the Alembic importer. The core functionality resides in a collection of "reader" classes, each of which is responsible for converting an instance of a USD prim to the corresponding Blender Object representation. The flow of control for the conversion can be followed in the `import_startjob()` and `import_endjob()` functions in `usd_capi.cc`. The `USDStageReader` class is responsible for traversing the USD stage and instantiating the appropriate readers. Reviewed By: sybren, HooglyBoogly Differential Revision: https://developer.blender.org/D10700
525 lines
19 KiB
C
525 lines
19 KiB
C
/*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
/** \file
|
|
* \ingroup editor/io
|
|
*/
|
|
|
|
#ifdef WITH_USD
|
|
# include "DNA_modifier_types.h"
|
|
# include "DNA_space_types.h"
|
|
# include <string.h>
|
|
|
|
# include "BKE_context.h"
|
|
# include "BKE_main.h"
|
|
# include "BKE_report.h"
|
|
|
|
# include "BLI_blenlib.h"
|
|
# include "BLI_path_util.h"
|
|
# include "BLI_string.h"
|
|
# include "BLI_utildefines.h"
|
|
|
|
# include "BLT_translation.h"
|
|
|
|
# include "ED_object.h"
|
|
|
|
# include "MEM_guardedalloc.h"
|
|
|
|
# include "RNA_access.h"
|
|
# include "RNA_define.h"
|
|
|
|
# include "RNA_enum_types.h"
|
|
|
|
# include "UI_interface.h"
|
|
# include "UI_resources.h"
|
|
|
|
# include "WM_api.h"
|
|
# include "WM_types.h"
|
|
|
|
# include "DEG_depsgraph.h"
|
|
|
|
# include "io_usd.h"
|
|
# include "usd.h"
|
|
|
|
# include "stdio.h"
|
|
|
|
const EnumPropertyItem rna_enum_usd_export_evaluation_mode_items[] = {
|
|
{DAG_EVAL_RENDER,
|
|
"RENDER",
|
|
0,
|
|
"Render",
|
|
"Use Render settings for object visibility, modifier settings, etc"},
|
|
{DAG_EVAL_VIEWPORT,
|
|
"VIEWPORT",
|
|
0,
|
|
"Viewport",
|
|
"Use Viewport settings for object visibility, modifier settings, etc"},
|
|
{0, NULL, 0, NULL, NULL},
|
|
};
|
|
|
|
/* Stored in the wmOperator's customdata field to indicate it should run as a background job.
|
|
* This is set when the operator is invoked, and not set when it is only executed. */
|
|
enum { AS_BACKGROUND_JOB = 1 };
|
|
typedef struct eUSDOperatorOptions {
|
|
bool as_background_job;
|
|
} eUSDOperatorOptions;
|
|
|
|
static int wm_usd_export_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
|
{
|
|
eUSDOperatorOptions *options = MEM_callocN(sizeof(eUSDOperatorOptions), "eUSDOperatorOptions");
|
|
options->as_background_job = true;
|
|
op->customdata = options;
|
|
|
|
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
|
|
Main *bmain = CTX_data_main(C);
|
|
char filepath[FILE_MAX];
|
|
const char *main_blendfile_path = BKE_main_blendfile_path(bmain);
|
|
|
|
if (main_blendfile_path[0] == '\0') {
|
|
BLI_strncpy(filepath, "untitled", sizeof(filepath));
|
|
}
|
|
else {
|
|
BLI_strncpy(filepath, main_blendfile_path, sizeof(filepath));
|
|
}
|
|
|
|
BLI_path_extension_replace(filepath, sizeof(filepath), ".usdc");
|
|
RNA_string_set(op->ptr, "filepath", filepath);
|
|
}
|
|
|
|
WM_event_add_fileselect(C, op);
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
}
|
|
|
|
static int wm_usd_export_exec(bContext *C, wmOperator *op)
|
|
{
|
|
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
|
|
BKE_report(op->reports, RPT_ERROR, "No filename given");
|
|
return OPERATOR_CANCELLED;
|
|
}
|
|
|
|
char filename[FILE_MAX];
|
|
RNA_string_get(op->ptr, "filepath", filename);
|
|
|
|
eUSDOperatorOptions *options = (eUSDOperatorOptions *)op->customdata;
|
|
const bool as_background_job = (options != NULL && options->as_background_job);
|
|
MEM_SAFE_FREE(op->customdata);
|
|
|
|
const bool selected_objects_only = RNA_boolean_get(op->ptr, "selected_objects_only");
|
|
const bool visible_objects_only = RNA_boolean_get(op->ptr, "visible_objects_only");
|
|
const bool export_animation = RNA_boolean_get(op->ptr, "export_animation");
|
|
const bool export_hair = RNA_boolean_get(op->ptr, "export_hair");
|
|
const bool export_uvmaps = RNA_boolean_get(op->ptr, "export_uvmaps");
|
|
const bool export_normals = RNA_boolean_get(op->ptr, "export_normals");
|
|
const bool export_materials = RNA_boolean_get(op->ptr, "export_materials");
|
|
const bool use_instancing = RNA_boolean_get(op->ptr, "use_instancing");
|
|
const bool evaluation_mode = RNA_enum_get(op->ptr, "evaluation_mode");
|
|
|
|
struct USDExportParams params = {
|
|
export_animation,
|
|
export_hair,
|
|
export_uvmaps,
|
|
export_normals,
|
|
export_materials,
|
|
selected_objects_only,
|
|
visible_objects_only,
|
|
use_instancing,
|
|
evaluation_mode,
|
|
};
|
|
|
|
bool ok = USD_export(C, filename, ¶ms, as_background_job);
|
|
|
|
return as_background_job || ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
|
}
|
|
|
|
static void wm_usd_export_draw(bContext *UNUSED(C), wmOperator *op)
|
|
{
|
|
uiLayout *layout = op->layout;
|
|
uiLayout *col;
|
|
struct PointerRNA *ptr = op->ptr;
|
|
|
|
uiLayoutSetPropSep(layout, true);
|
|
|
|
uiLayout *box = uiLayoutBox(layout);
|
|
|
|
col = uiLayoutColumn(box, true);
|
|
uiItemR(col, ptr, "selected_objects_only", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "visible_objects_only", 0, NULL, ICON_NONE);
|
|
|
|
col = uiLayoutColumn(box, true);
|
|
uiItemR(col, ptr, "export_animation", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "export_hair", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "export_uvmaps", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "export_normals", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "export_materials", 0, NULL, ICON_NONE);
|
|
|
|
col = uiLayoutColumn(box, true);
|
|
uiItemR(col, ptr, "evaluation_mode", 0, NULL, ICON_NONE);
|
|
|
|
box = uiLayoutBox(layout);
|
|
uiItemL(box, IFACE_("Experimental"), ICON_NONE);
|
|
uiItemR(box, ptr, "use_instancing", 0, NULL, ICON_NONE);
|
|
}
|
|
|
|
void WM_OT_usd_export(struct wmOperatorType *ot)
|
|
{
|
|
ot->name = "Export USD";
|
|
ot->description = "Export current scene in a USD archive";
|
|
ot->idname = "WM_OT_usd_export";
|
|
|
|
ot->invoke = wm_usd_export_invoke;
|
|
ot->exec = wm_usd_export_exec;
|
|
ot->poll = WM_operator_winactive;
|
|
ot->ui = wm_usd_export_draw;
|
|
|
|
WM_operator_properties_filesel(ot,
|
|
FILE_TYPE_FOLDER | FILE_TYPE_USD,
|
|
FILE_BLENDER,
|
|
FILE_SAVE,
|
|
WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS,
|
|
FILE_DEFAULTDISPLAY,
|
|
FILE_SORT_DEFAULT);
|
|
|
|
RNA_def_boolean(ot->srna,
|
|
"selected_objects_only",
|
|
false,
|
|
"Selection Only",
|
|
"Only selected objects are exported. Unselected parents of selected objects are "
|
|
"exported as empty transform");
|
|
|
|
RNA_def_boolean(ot->srna,
|
|
"visible_objects_only",
|
|
true,
|
|
"Visible Only",
|
|
"Only visible objects are exported. Invisible parents of exported objects are "
|
|
"exported as empty transform");
|
|
|
|
RNA_def_boolean(ot->srna,
|
|
"export_animation",
|
|
false,
|
|
"Animation",
|
|
"When checked, the render frame range is exported. When false, only the current "
|
|
"frame is exported");
|
|
RNA_def_boolean(
|
|
ot->srna, "export_hair", false, "Hair", "When checked, hair is exported as USD curves");
|
|
RNA_def_boolean(ot->srna,
|
|
"export_uvmaps",
|
|
true,
|
|
"UV Maps",
|
|
"When checked, all UV maps of exported meshes are included in the export");
|
|
RNA_def_boolean(ot->srna,
|
|
"export_normals",
|
|
true,
|
|
"Normals",
|
|
"When checked, normals of exported meshes are included in the export");
|
|
RNA_def_boolean(ot->srna,
|
|
"export_materials",
|
|
true,
|
|
"Materials",
|
|
"When checked, the viewport settings of materials are exported as USD preview "
|
|
"materials, and material assignments are exported as geometry subsets");
|
|
|
|
RNA_def_boolean(ot->srna,
|
|
"use_instancing",
|
|
false,
|
|
"Instancing",
|
|
"When checked, instanced objects are exported as references in USD. "
|
|
"When unchecked, instanced objects are exported as real objects");
|
|
|
|
RNA_def_enum(ot->srna,
|
|
"evaluation_mode",
|
|
rna_enum_usd_export_evaluation_mode_items,
|
|
DAG_EVAL_RENDER,
|
|
"Use Settings for",
|
|
"Determines visibility of objects, modifier settings, and other areas where there "
|
|
"are different settings for viewport and rendering");
|
|
}
|
|
|
|
/* ====== USD Import ====== */
|
|
|
|
static int wm_usd_import_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
|
{
|
|
eUSDOperatorOptions *options = MEM_callocN(sizeof(eUSDOperatorOptions), "eUSDOperatorOptions");
|
|
options->as_background_job = true;
|
|
op->customdata = options;
|
|
|
|
return WM_operator_filesel(C, op, event);
|
|
}
|
|
|
|
static int wm_usd_import_exec(bContext *C, wmOperator *op)
|
|
{
|
|
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
|
|
BKE_report(op->reports, RPT_ERROR, "No filename given");
|
|
return OPERATOR_CANCELLED;
|
|
}
|
|
|
|
char filename[FILE_MAX];
|
|
RNA_string_get(op->ptr, "filepath", filename);
|
|
|
|
eUSDOperatorOptions *options = (eUSDOperatorOptions *)op->customdata;
|
|
const bool as_background_job = (options != NULL && options->as_background_job);
|
|
MEM_SAFE_FREE(op->customdata);
|
|
|
|
const float scale = RNA_float_get(op->ptr, "scale");
|
|
|
|
const bool set_frame_range = RNA_boolean_get(op->ptr, "set_frame_range");
|
|
|
|
const bool read_mesh_uvs = RNA_boolean_get(op->ptr, "read_mesh_uvs");
|
|
const bool read_mesh_colors = RNA_boolean_get(op->ptr, "read_mesh_colors");
|
|
|
|
char mesh_read_flag = MOD_MESHSEQ_READ_VERT | MOD_MESHSEQ_READ_POLY;
|
|
if (read_mesh_uvs) {
|
|
mesh_read_flag |= MOD_MESHSEQ_READ_UV;
|
|
}
|
|
if (read_mesh_colors) {
|
|
mesh_read_flag |= MOD_MESHSEQ_READ_COLOR;
|
|
}
|
|
|
|
const bool import_cameras = RNA_boolean_get(op->ptr, "import_cameras");
|
|
const bool import_curves = RNA_boolean_get(op->ptr, "import_curves");
|
|
const bool import_lights = RNA_boolean_get(op->ptr, "import_lights");
|
|
const bool import_materials = RNA_boolean_get(op->ptr, "import_materials");
|
|
const bool import_meshes = RNA_boolean_get(op->ptr, "import_meshes");
|
|
const bool import_volumes = RNA_boolean_get(op->ptr, "import_volumes");
|
|
|
|
const bool import_subdiv = RNA_boolean_get(op->ptr, "import_subdiv");
|
|
|
|
const bool import_instance_proxies = RNA_boolean_get(op->ptr, "import_instance_proxies");
|
|
|
|
const bool import_visible_only = RNA_boolean_get(op->ptr, "import_visible_only");
|
|
|
|
const bool create_collection = RNA_boolean_get(op->ptr, "create_collection");
|
|
|
|
char *prim_path_mask = malloc(1024);
|
|
RNA_string_get(op->ptr, "prim_path_mask", prim_path_mask);
|
|
|
|
const bool import_guide = RNA_boolean_get(op->ptr, "import_guide");
|
|
const bool import_proxy = RNA_boolean_get(op->ptr, "import_proxy");
|
|
const bool import_render = RNA_boolean_get(op->ptr, "import_render");
|
|
|
|
const bool import_usd_preview = RNA_boolean_get(op->ptr, "import_usd_preview");
|
|
const bool set_material_blend = RNA_boolean_get(op->ptr, "set_material_blend");
|
|
|
|
const float light_intensity_scale = RNA_float_get(op->ptr, "light_intensity_scale");
|
|
|
|
/* TODO(makowalski): Add support for sequences. */
|
|
const bool is_sequence = false;
|
|
int offset = 0;
|
|
int sequence_len = 1;
|
|
|
|
/* Switch out of edit mode to avoid being stuck in it (T54326). */
|
|
Object *obedit = CTX_data_edit_object(C);
|
|
if (obedit) {
|
|
ED_object_mode_set(C, OB_MODE_EDIT);
|
|
}
|
|
|
|
const bool validate_meshes = false;
|
|
const bool use_instancing = false;
|
|
|
|
struct USDImportParams params = {.scale = scale,
|
|
.is_sequence = is_sequence,
|
|
.set_frame_range = set_frame_range,
|
|
.sequence_len = sequence_len,
|
|
.offset = offset,
|
|
.validate_meshes = validate_meshes,
|
|
.mesh_read_flag = mesh_read_flag,
|
|
.import_cameras = import_cameras,
|
|
.import_curves = import_curves,
|
|
.import_lights = import_lights,
|
|
.import_materials = import_materials,
|
|
.import_meshes = import_meshes,
|
|
.import_volumes = import_volumes,
|
|
.prim_path_mask = prim_path_mask,
|
|
.import_subdiv = import_subdiv,
|
|
.import_instance_proxies = import_instance_proxies,
|
|
.create_collection = create_collection,
|
|
.import_guide = import_guide,
|
|
.import_proxy = import_proxy,
|
|
.import_render = import_render,
|
|
.import_visible_only = import_visible_only,
|
|
.use_instancing = use_instancing,
|
|
.import_usd_preview = import_usd_preview,
|
|
.set_material_blend = set_material_blend,
|
|
.light_intensity_scale = light_intensity_scale};
|
|
|
|
const bool ok = USD_import(C, filename, ¶ms, as_background_job);
|
|
|
|
return as_background_job || ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
|
}
|
|
|
|
static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op)
|
|
{
|
|
uiLayout *layout = op->layout;
|
|
struct PointerRNA *ptr = op->ptr;
|
|
|
|
uiLayoutSetPropSep(layout, true);
|
|
uiLayoutSetPropDecorate(layout, false);
|
|
|
|
uiLayout *box = uiLayoutBox(layout);
|
|
uiLayout *col = uiLayoutColumnWithHeading(box, true, IFACE_("Data Types"));
|
|
uiItemR(col, ptr, "import_cameras", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "import_curves", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "import_lights", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "import_materials", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "import_meshes", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "import_volumes", 0, NULL, ICON_NONE);
|
|
uiItemR(box, ptr, "prim_path_mask", 0, NULL, ICON_NONE);
|
|
uiItemR(box, ptr, "scale", 0, NULL, ICON_NONE);
|
|
|
|
box = uiLayoutBox(layout);
|
|
col = uiLayoutColumnWithHeading(box, true, IFACE_("Mesh Data"));
|
|
uiItemR(col, ptr, "read_mesh_uvs", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "read_mesh_colors", 0, NULL, ICON_NONE);
|
|
col = uiLayoutColumnWithHeading(box, true, IFACE_("Include"));
|
|
uiItemR(col, ptr, "import_subdiv", 0, IFACE_("Subdivision"), ICON_NONE);
|
|
uiItemR(col, ptr, "import_instance_proxies", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "import_visible_only", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "import_guide", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "import_proxy", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "import_render", 0, NULL, ICON_NONE);
|
|
|
|
col = uiLayoutColumnWithHeading(box, true, IFACE_("Options"));
|
|
uiItemR(col, ptr, "set_frame_range", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "relative_path", 0, NULL, ICON_NONE);
|
|
uiItemR(col, ptr, "create_collection", 0, NULL, ICON_NONE);
|
|
uiItemR(box, ptr, "light_intensity_scale", 0, NULL, ICON_NONE);
|
|
|
|
box = uiLayoutBox(layout);
|
|
col = uiLayoutColumnWithHeading(box, true, IFACE_("Experimental"));
|
|
uiItemR(col, ptr, "import_usd_preview", 0, NULL, ICON_NONE);
|
|
uiLayoutSetEnabled(col, RNA_boolean_get(ptr, "import_materials"));
|
|
uiLayout *row = uiLayoutRow(col, true);
|
|
uiItemR(row, ptr, "set_material_blend", 0, NULL, ICON_NONE);
|
|
uiLayoutSetEnabled(row, RNA_boolean_get(ptr, "import_usd_preview"));
|
|
}
|
|
|
|
void WM_OT_usd_import(struct wmOperatorType *ot)
|
|
{
|
|
ot->name = "Import USD";
|
|
ot->description = "Import USD stage into current scene";
|
|
ot->idname = "WM_OT_usd_import";
|
|
|
|
ot->invoke = wm_usd_import_invoke;
|
|
ot->exec = wm_usd_import_exec;
|
|
ot->poll = WM_operator_winactive;
|
|
ot->ui = wm_usd_import_draw;
|
|
|
|
WM_operator_properties_filesel(ot,
|
|
FILE_TYPE_FOLDER | FILE_TYPE_USD,
|
|
FILE_BLENDER,
|
|
FILE_OPENFILE,
|
|
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_SHOW_PROPS,
|
|
FILE_DEFAULTDISPLAY,
|
|
FILE_SORT_ALPHA);
|
|
|
|
RNA_def_float(
|
|
ot->srna,
|
|
"scale",
|
|
1.0f,
|
|
0.0001f,
|
|
1000.0f,
|
|
"Scale",
|
|
"Value by which to enlarge or shrink the objects with respect to the world's origin",
|
|
0.0001f,
|
|
1000.0f);
|
|
|
|
RNA_def_boolean(ot->srna,
|
|
"set_frame_range",
|
|
true,
|
|
"Set Frame Range",
|
|
"Update the scene's start and end frame to match those of the USD archive");
|
|
|
|
RNA_def_boolean(ot->srna, "import_cameras", true, "Cameras", "");
|
|
RNA_def_boolean(ot->srna, "import_curves", true, "Curves", "");
|
|
RNA_def_boolean(ot->srna, "import_lights", true, "Lights", "");
|
|
RNA_def_boolean(ot->srna, "import_materials", true, "Materials", "");
|
|
RNA_def_boolean(ot->srna, "import_meshes", true, "Meshes", "");
|
|
RNA_def_boolean(ot->srna, "import_volumes", true, "Volumes", "");
|
|
|
|
RNA_def_boolean(ot->srna,
|
|
"import_subdiv",
|
|
false,
|
|
"Import Subdivision Scheme",
|
|
"Create subdivision surface modifiers based on the USD "
|
|
"SubdivisionScheme attribute");
|
|
|
|
RNA_def_boolean(ot->srna,
|
|
"import_instance_proxies",
|
|
true,
|
|
"Import Instance Proxies",
|
|
"Create unique Blender objects for USD instances");
|
|
|
|
RNA_def_boolean(ot->srna,
|
|
"import_visible_only",
|
|
true,
|
|
"Visible Primitives Only",
|
|
"Do not import invisible USD primitives. "
|
|
"Only applies to primitives with a non-animated visibility attribute. "
|
|
"Primitives with animated visibility will always be imported");
|
|
|
|
RNA_def_boolean(ot->srna,
|
|
"create_collection",
|
|
false,
|
|
"Create Collection",
|
|
"Add all imported objects to a new collection");
|
|
|
|
RNA_def_boolean(ot->srna, "read_mesh_uvs", true, "UV Coordinates", "Read mesh UV coordinates");
|
|
|
|
RNA_def_boolean(ot->srna, "read_mesh_colors", false, "Vertex Colors", "Read mesh vertex colors");
|
|
|
|
RNA_def_string(ot->srna,
|
|
"prim_path_mask",
|
|
NULL,
|
|
1024,
|
|
"Path Mask",
|
|
"Import only the subset of the USD scene rooted at the given primitive");
|
|
|
|
RNA_def_boolean(ot->srna, "import_guide", false, "Guide", "Import guide geometry");
|
|
|
|
RNA_def_boolean(ot->srna, "import_proxy", true, "Proxy", "Import proxy geometry");
|
|
|
|
RNA_def_boolean(ot->srna, "import_render", true, "Render", "Import final render geometry");
|
|
|
|
RNA_def_boolean(ot->srna,
|
|
"import_usd_preview",
|
|
false,
|
|
"Import USD Preview",
|
|
"Convert UsdPreviewSurface shaders to Principled BSDF shader networks");
|
|
|
|
RNA_def_boolean(ot->srna,
|
|
"set_material_blend",
|
|
true,
|
|
"Set Material Blend",
|
|
"If the Import USD Preview option is enabled, "
|
|
"the material blend method will automatically be set based on the "
|
|
"shader's opacity and opacityThreshold inputs");
|
|
|
|
RNA_def_float(ot->srna,
|
|
"light_intensity_scale",
|
|
1.0f,
|
|
0.0001f,
|
|
10000.0f,
|
|
"Light Intensity Scale",
|
|
"Scale for the intensity of imported lights",
|
|
0.0001f,
|
|
1000.0f);
|
|
}
|
|
|
|
#endif /* WITH_USD */
|