コード例 #1
0
            // If geometry does not contain normals, colors, and/or uvs, dummy values
            // will be added.
            public ExportMesh(GeometryPool pool)
            {
                m_pool = pool;
                FbxUtils.ApplyFbxTexcoordHack(m_pool);
                m_linearColor = ExportUtils.ConvertToLinearColorspace(m_pool.m_Colors);

                var layout   = m_pool.Layout;
                var numVerts = m_pool.m_Vertices.Count;

                // TODO: all this padding code seems super bogus; try to remove.
                if (!layout.bUseNormals)
                {
                    var lst = m_pool.m_Normals;
                    lst.SetCount(numVerts);
                    for (int i = 0; i < numVerts; ++i)
                    {
                        lst[i] = Vector3.up;
                    }
                }

                if (!layout.bUseColors)
                {
                    var lst = m_linearColor;
                    lst.SetCount(numVerts);
                    for (int i = 0; i < numVerts; ++i)
                    {
                        lst[i] = Color.white;
                    }
                }
            }
コード例 #2
0
        // -------------------------------------------------------------------------------------------- //
        // Export Logic
        // -------------------------------------------------------------------------------------------- //

        /// Exports either all brush strokes or the given selection to the specified file.
        static public void ExportPayload(string outputFile)
        {
            // Would be nice to find a way to kick this off automatically.
            // Redundant calls are ignored.
            if (!InitUsd.Initialize())
            {
                return;
            }

            // Unity is left handed (DX), USD is right handed (GL)
            var payload      = ExportCollector.GetExportPayload(AxisConvention.kUsd);
            var brushCatalog = BrushCatalog.m_Instance;

            // The Scene object provids serialization methods arbitrary C# objects to USD.
            USD.NET.Scene scene = USD.NET.Scene.Create(outputFile);

            // The target time at which samples will be written.
            //
            // In this case, all data is being written to the "default" time, which means it can be
            // overridden by animated values later.
            scene.Time = null;

            // Bracketing times to specify the valid animation range.
            scene.StartTime = 1.0;
            scene.EndTime   = 1.0;

            const string kGeomName   = "/Geom";
            const string kCurvesName = "/Curves";

            string path = "";

            AddSketchRoot(scene, GetSketchPath()); // Create: </Sketch>

            CreateXform(scene, GetStrokesPath());  // Create: </Sketch/Strokes>
            CreateXform(scene, GetModelsPath());   // Create: </Sketch/Models>

            // Main export loop.
            try
            {
                foreach (ExportUtils.GroupPayload group in payload.groups)
                {
                    // Example: </Sketch/Strokes/Group_0>
                    path = GetGroupPath(group.id);
                    CreateXform(scene, path);

                    // Example: </Sketch/Strokes/Group_0/Geom>
                    CreateXform(scene, path + kGeomName);

                    // Example: </Sketch/Strokes/Group_0/Curves>
                    CreateXform(scene, path + kCurvesName);

                    int iBrushMeshPayload = -1;
                    foreach (var brushMeshPayload in group.brushMeshes)
                    {
                        ++iBrushMeshPayload;
                        // Conditionally moves Normal into Texcoord1 so that the normal semantic is respected.
                        // This only has an effect when layout.bFbxExportNormalAsTexcoord1 == true.
                        // Note that this modifies the GeometryPool in place.
                        FbxUtils.ApplyFbxTexcoordHack(brushMeshPayload.geometry);

                        // Brushes are expected to be batched by type/GUID.
                        Guid   brushGuid = brushMeshPayload.strokes[0].m_BrushGuid;
                        string brushName = "/" +
                                           SanitizeIdentifier(brushCatalog.GetBrush(brushGuid).DurableName) + "_";

                        // Example: </Sketch/Strokes/Group_0/Geom/Marker_0>
                        string meshPath = path + kGeomName + brushName;

                        // Example: </Sketch/Strokes/Group_0/Curves/Marker_0>
                        string curvePath = path + kCurvesName + brushName;

                        var geomPool       = brushMeshPayload.geometry;
                        var strokes        = brushMeshPayload.strokes;
                        var mat44          = Matrix4x4.identity;
                        var meshPrimPath   = new pxr.SdfPath(meshPath + iBrushMeshPayload.ToString());
                        var curvesPrimPath = new pxr.SdfPath(curvePath + iBrushMeshPayload.ToString());

                        //
                        // Geometry
                        //
                        BrushSample brushSample = GetBrushSample(geomPool, strokes, mat44);

                        // Write the BrushSample to the same point in the scenegraph at which it exists in Tilt
                        // Brush. Notice this method is Async, it is queued to a background thread to perform I/O
                        // which means it is not safe to read from the scene until WaitForWrites() is called.
                        scene.Write(meshPrimPath, brushSample);

                        //
                        // Stroke Curves
                        //
                        var curvesSample = GetCurvesSample(payload, strokes, Matrix4x4.identity);
                        scene.Write(curvesPrimPath, curvesSample);

                        //
                        // Materials
                        //
                        double?oldTime = scene.Time;
                        scene.Time = null;

                        string materialPath = CreateMaterialNetwork(
                            scene,
                            brushMeshPayload.exportableMaterial,
                            GetStrokesPath());

                        BindMaterial(scene, meshPrimPath.ToString(), materialPath);
                        BindMaterial(scene, curvesPrimPath.ToString(), materialPath);

                        scene.Time = oldTime;
                    }
                }

                //
                // Models
                //

                var knownModels = new Dictionary <Model, string>();

                int iModelMeshPayload = -1;
                foreach (var modelMeshPayload in payload.modelMeshes)
                {
                    ++iModelMeshPayload;
                    var modelId         = modelMeshPayload.modelId;
                    var modelNamePrefix = "/Model_"
                                          + SanitizeIdentifier(modelMeshPayload.model.GetExportName())
                                          + "_";
                    var modelName = modelNamePrefix + modelId;

                    var xf = modelMeshPayload.xform;
                    // Geometry pools may be repeated and should be turned into references.
                    var geomPool = modelMeshPayload.geometry;

                    var modelRootPath = new pxr.SdfPath(GetModelsPath() + modelName);

                    // Example: </Sketch/Models/Model_Andy_0>
                    CreateXform(scene, modelRootPath, xf);

                    // Example: </Sketch/Models/Model_Andy_0/Geom>
                    CreateXform(scene, modelRootPath + kGeomName);

                    string modelPathToReference;
                    if (knownModels.TryGetValue(modelMeshPayload.model, out modelPathToReference) &&
                        modelPathToReference != modelRootPath)
                    {
                        // Create an Xform, note that the world transform here will override the referenced model.
                        var meshXf = new MeshXformSample();
                        meshXf.transform = xf;
                        scene.Write(modelRootPath, meshXf);
                        // Add a USD reference to previously created model.
                        var prim = scene.Stage.GetPrimAtPath(modelRootPath);
                        prim.GetReferences().AddReference("", new pxr.SdfPath(modelPathToReference));
                        continue;
                    }

                    // Example: </Sketch/Models/Geom/Model_Andy_0/Mesh_0>
                    path = modelRootPath + kGeomName + "/Mesh_" + iModelMeshPayload.ToString();

                    var meshPrimPath = new pxr.SdfPath(path);
                    var meshSample   = new MeshSample();

                    GetMeshSample(geomPool, Matrix4x4.identity, meshSample);
                    scene.Write(path, meshSample);
                    scene.Stage.GetPrimAtPath(new pxr.SdfPath(path)).SetInstanceable(true);

                    //
                    // Materials
                    //

                    // Author at default time.
                    double?oldTime = scene.Time;
                    scene.Time = null;

                    // Model materials must live under the model root, since we will reference the model.
                    string materialPath = CreateMaterialNetwork(
                        scene,
                        modelMeshPayload.exportableMaterial,
                        modelRootPath);
                    BindMaterial(scene, meshPrimPath.ToString(), materialPath);

                    // Continue authoring at the desired time index.
                    scene.Time = oldTime;

                    //
                    // Setup to be referenced.
                    //
                    if (!knownModels.ContainsKey(modelMeshPayload.model))
                    {
                        knownModels.Add(modelMeshPayload.model, modelRootPath);
                    }
                }
            }
            catch
            {
                scene.Save();
                scene.Close();
                throw;
            }

            // Save will force a sync with all async reads and writes.
            scene.Save();
            scene.Close();
        }