protected DMesh3 MakeDebugGraphMesh()
        {
            DMesh3 graphMesh = new DMesh3();

            graphMesh.EnableVertexColors(Vector3f.One);
            foreach (int vid in Graph.VertexIndices())
            {
                if (TipVertices.Contains(vid))
                {
                    MeshEditor.AppendBox(graphMesh, Graph.GetVertex(vid), 0.3f, Colorf.Green);
                }
                else if (TipBaseVertices.Contains(vid))
                {
                    MeshEditor.AppendBox(graphMesh, Graph.GetVertex(vid), 0.225f, Colorf.Magenta);
                }
                else if (GroundVertices.Contains(vid))
                {
                    MeshEditor.AppendBox(graphMesh, Graph.GetVertex(vid), 0.35f, Colorf.Blue);
                }
                else
                {
                    MeshEditor.AppendBox(graphMesh, Graph.GetVertex(vid), 0.15f, Colorf.White);
                }
            }
            foreach (int eid in Graph.EdgeIndices())
            {
                Segment3d seg = Graph.GetEdgeSegment(eid);
                MeshEditor.AppendLine(graphMesh, seg, 0.1f);
            }
            return(graphMesh);
        }
Esempio n. 2
0
        public static DMesh3 ToDMesh3(this Rhino.Geometry.Mesh ms)
        {
            int numV = ms.Vertices.Count;
            int numF = ms.Faces.Count;
            int numC = ms.VertexColors.Count;

            List <Vector3f> Vertices  = new List <Vector3f>(numV);
            List <Vector3i> Triangles = new List <Vector3i>(numF);

            for (int i = 0; i < numV; i++)
            {
                Vertices.Add(ms.Vertices[i].ToVec3f());
            }

            for (int i = 0; i < numF; i++)
            {
                Triangles.Add(ms.Faces[i].ToVec3i());
            }

            DMesh3 dMs = DMesh3Builder.Build <Vector3f, Vector3i, Vector3f>(Vertices, Triangles);

            if (numV == numC)
            {
                dMs.EnableVertexColors(new Vector3f(0.5, 0.5, 0.5));

                for (int i = 0; i < numV; i++)
                {
                    dMs.SetVertexColor(i, new Vector3f((float)ms.VertexColors[i].R / 255, (float)ms.VertexColors[i].G / 255, (float)ms.VertexColors[i].B / 255));
                }
            }

            return(dMs);
        }
Esempio n. 3
0
        public DMesh3 getMesh()
        {
            BpcData pc = GetBakedPointCloud();

            ulong size;

            byte[] data = GetPackedMesh(out size);
            Console.WriteLine($"Rawmesh size: {size}");

            List <int> tris = new List <int>();

            if (size > 0)
            {
                for (int position = 0; position < (int)size; position += 12)
                {
                    tris.Add((int)BitConverter.ToUInt32(data, position));
                    tris.Add((int)BitConverter.ToUInt32(data, position + 4));
                    tris.Add((int)BitConverter.ToUInt32(data, position + 8));
                }
            }

            DMesh3 dmesh = DMesh3Builder.Build <Vector3d, int, int>(pc.positions, tris);

            if (pc.colors.Count() > 0)
            {
                dmesh.EnableVertexColors(new Vector3f());
                foreach (int idx in dmesh.VertexIndices())
                {
                    dmesh.SetVertexColor(idx, pc.colors.ElementAt(idx));
                }
            }
            return(dmesh);
        }
Esempio n. 4
0
        public static void Restore(DMesh3 mesh, BinaryReader reader)
        {
            int version = reader.ReadInt32();

            if (version != DMesh3Version)
            {
                throw new Exception("gSerialization.Restore: Incorrect DMesh3Version!");
            }

            MeshComponents components = (MeshComponents)reader.ReadInt32();

            Restore(mesh.VerticesBuffer, reader);
            Restore(mesh.TrianglesBuffer, reader);
            Restore(mesh.EdgesBuffer, reader);
            Restore(mesh.EdgesRefCounts.RawRefCounts, reader);

            if ((components & MeshComponents.VertexNormals) != 0)
            {
                mesh.EnableVertexNormals(Vector3F.AxisY);
                Restore(mesh.NormalsBuffer, reader);
            }
            else
            {
                mesh.DiscardVertexNormals();
            }

            if ((components & MeshComponents.VertexColors) != 0)
            {
                mesh.EnableVertexColors(Vector3F.One);
                Restore(mesh.ColorsBuffer, reader);
            }
            else
            {
                mesh.DiscardVertexColors();
            }

            if ((components & MeshComponents.VertexUVs) != 0)
            {
                mesh.EnableVertexUVs(Vector2F.Zero);
                Restore(mesh.UVBuffer, reader);
            }
            else
            {
                mesh.DiscardVertexUVs();
            }

            if ((components & MeshComponents.FaceGroups) != 0)
            {
                mesh.EnableTriangleGroups(0);
                Restore(mesh.GroupsBuffer, reader);
            }
            else
            {
                mesh.DiscardTriangleGroups();
            }

            mesh.RebuildFromEdgeRefcounts();
        }
Esempio n. 5
0
        public static void SetColorsFromScalarF(DMesh3 mesh, Func <int, float> ScalarF, Vector2f scaleRange)
        {
            mesh.EnableVertexColors(Vector3f.Zero);

            foreach (int vid in mesh.VertexIndices())
            {
                float f = ScalarF(vid);
                float t = (f - scaleRange[0]) / (scaleRange[1] - scaleRange[0]);
                mesh.SetVertexColor(vid, t * Vector3f.One);
            }
        }
        void compute_trimmed_mesh()
        {
            // curve is on base leg, map to deformed leg
            // [TODO] really should be doing this via deformation, rather than nearest-point
            DCurve3 curve = new DCurve3(CurveSource.GetICurve());

            for (int i = 0; i < curve.VertexCount; ++i)
            {
                curve[i] = MeshQueries.NearestPointFrame(cachedInputMesh, cachedInputMeshSpatial, curve[i]).Origin;
            }

            TrimmedMesh = new DMesh3(cachedInputMesh);
            TrimmedMesh.EnableTriangleGroups(0);

            AxisAlignedBox3d bounds = TrimmedMesh.CachedBounds;

            // try to find seed based on raycast, which doesn't always work.
            // Note that seed is the seed for the *eroded* region, not the kept region
            Vector3d basePt  = bounds.Center + 10 * bounds.Extents.y * Vector3d.AxisY;
            int      hit_tid = cachedInputMeshSpatial.FindNearestHitTriangle(new Ray3d(basePt, -Vector3d.AxisY));
            Vector3d seed    = cachedInputMesh.GetTriCentroid(hit_tid);

            if (flip_trim_side)
            {
                basePt  = bounds.Center - 10 * bounds.Extents.y * Vector3d.AxisY;
                hit_tid = cachedInputMeshSpatial.FindNearestHitTriangle(new Ray3d(basePt, Vector3d.AxisY));
                seed    = cachedInputMesh.GetTriCentroid(hit_tid);
            }

            MeshTrimLoop trim = new MeshTrimLoop(TrimmedMesh, curve, seed, cachedInputMeshSpatial);

            trim.Trim();

            if (TrimmedMesh.HasVertexColors == false)
            {
                TrimmedMesh.EnableVertexColors(SocketVertexColor);
            }
            else
            {
                foreach (int vid in TrimmedMesh.VertexIndices())
                {
                    TrimmedMesh.SetVertexColor(vid, SocketVertexColor);
                }
            }

            MeshTransforms.FromFrame(TrimmedMesh, cachedInputsTransform);
        }
        void set_failure_output(DMesh3 lastOKMesh)
        {
            if (lastOKMesh == null)
            {
                Sphere3Generator_NormalizedCube gen = new Sphere3Generator_NormalizedCube()
                {
                    Radius = 50
                };
                ResultMesh = gen.Generate().MakeDMesh();
            }
            else
            {
                ResultMesh = new DMesh3(lastOKMesh, false, MeshComponents.None);
            }
            ResultMesh.EnableVertexColors(Colorf.VideoRed);

            last_result_status = ResultStatus.ErrorResult;
        }
Esempio n. 8
0
        public static DMesh3 MakeFailureOutput(DMesh3 sourceMesh, bool bCopy = true)
        {
            DMesh3 failMesh = null;

            if (sourceMesh == null)
            {
                Sphere3Generator_NormalizedCube gen = new Sphere3Generator_NormalizedCube()
                {
                    Radius = 25
                };
                failMesh = gen.Generate().MakeDMesh();
                failMesh.EnableVertexColors(Colorf.VideoRed);
            }
            else if (bCopy)
            {
                failMesh = new DMesh3(sourceMesh, false, MeshComponents.None);
                failMesh.EnableVertexColors(Colorf.VideoRed);
            }
            TagAsFailureMesh(failMesh);
            return(failMesh);
        }
Esempio n. 9
0
        /// <summary>
        /// copy vertex positions from sourceMesh.
        /// [TODO] perhaps can refactor into a call to EditAndUpdateMesh() ?
        /// </summary>
        public void UpdateVertices(DMesh3 sourceMesh, bool bNormals = true, bool bColors = true)
        {
            if (sourceMesh.MaxVertexID != mesh.MaxVertexID)
            {
                throw new Exception("DMeshSO.UpdateVertexPositions: not enough positions provided!");
            }

            bNormals &= sourceMesh.HasVertexNormals;
            if (bNormals && mesh.HasVertexNormals == false)
            {
                mesh.EnableVertexNormals(Vector3f.AxisY);
            }
            bColors &= sourceMesh.HasVertexColors;
            if (bColors && mesh.HasVertexColors == false)
            {
                mesh.EnableVertexColors(Colorf.White);
            }

            lock (mesh_write_lock) {
                foreach (int vid in mesh.VertexIndices())
                {
                    Vector3d sourceV = sourceMesh.GetVertex(vid);
                    mesh.SetVertex(vid, sourceV);
                    if (bNormals)
                    {
                        Vector3f sourceN = sourceMesh.GetVertexNormal(vid);
                        mesh.SetVertexNormal(vid, sourceN);
                    }
                    if (bColors)
                    {
                        Vector3f sourceC = sourceMesh.GetVertexColor(vid);
                        mesh.SetVertexColor(vid, sourceC);
                    }
                }
            }

            fast_mesh_update(bNormals, bColors);
            post_mesh_modified();
        }
Esempio n. 10
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            DMesh3_goo   goo  = null;
            List <Color> cols = new List <Color>();

            DA.GetData(0, ref goo);
            DA.GetDataList(1, cols);

            DMesh3 msh = new DMesh3(goo.Value);

            msh.EnableVertexColors(new g3.Vector3f(0.5, 0.5, 0.5));

            var indices = msh.VertexIndices();

            if (cols.Count == msh.VertexCount)
            {
                int counter = 0;
                foreach (int i in indices)
                {
                    msh.SetVertexColor(i, new g3.Vector3f((float)cols[counter].R / 255, (float)cols[counter].G / 255, (float)cols[counter].B / 255));
                    counter++;
                }
            }
            else if (cols.Count == 1)
            {
                foreach (int i in indices)
                {
                    msh.SetVertexColor(i, new g3.Vector3f((float)cols[0].R / 255, (float)cols[0].G / 255, (float)cols[0].B / 255));
                }
            }
            else
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Number of colours either need to be that same amount as number of vertices in mesh, or a single one");
            }

            DA.SetData(0, msh);
        }
Esempio n. 11
0
        public virtual DMesh3 RestoreDMesh(TypedAttribSet attributes)
        {
            bool           is_compressed = false;
            TypedAttribSet meshAttr      = find_struct(attributes, IOStrings.BinaryDMeshStruct);

            if (meshAttr == null)
            {
                meshAttr      = find_struct(attributes, IOStrings.CompressedDMeshStruct);
                is_compressed = true;
            }
            if (meshAttr == null)
            {
                throw new Exception("SOFactory.RestoreDMesh: DMesh binary or compressed struct not found!");
            }

            VectorArray3d v = null;
            VectorArray3f n = null, c = null;
            VectorArray2f uv = null;

            VectorArray3i t = null;

            int[] g = null;

            IndexArray4i e = null;

            short[] e_ref = null;

            var storageMode = IOStrings.MeshStorageMode.EdgeRefCounts;

            if (meshAttr.ContainsKey(IOStrings.AMeshStorageMode))
            {
                storageMode = (IOStrings.MeshStorageMode)(int) meshAttr[IOStrings.AMeshStorageMode];
            }

            if (is_compressed)
            {
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshVertices3Compressed))
                {
                    v = meshAttr[IOStrings.AMeshVertices3Compressed] as VectorArray3d;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshNormals3Compressed))
                {
                    n = meshAttr[IOStrings.AMeshNormals3Compressed] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshColors3Compressed))
                {
                    c = meshAttr[IOStrings.AMeshColors3Compressed] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshUVs2Compressed))
                {
                    uv = meshAttr[IOStrings.AMeshUVs2Compressed] as VectorArray2f;
                }

                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTrianglesCompressed))
                {
                    t = meshAttr[IOStrings.AMeshTrianglesCompressed] as VectorArray3i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTriangleGroupsCompressed))
                {
                    g = meshAttr[IOStrings.AMeshTriangleGroupsCompressed] as int[];
                }

                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshEdgesCompressed))
                {
                    e = meshAttr[IOStrings.AMeshEdgesCompressed] as IndexArray4i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshEdgeRefCountsCompressed))
                {
                    e_ref = meshAttr[IOStrings.AMeshEdgeRefCountsCompressed] as short[];
                }
            }
            else
            {
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshVertices3Binary))
                {
                    v = meshAttr[IOStrings.AMeshVertices3Binary] as VectorArray3d;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshNormals3Binary))
                {
                    n = meshAttr[IOStrings.AMeshNormals3Binary] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshColors3Binary))
                {
                    c = meshAttr[IOStrings.AMeshColors3Binary] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshUVs2Binary))
                {
                    uv = meshAttr[IOStrings.AMeshUVs2Binary] as VectorArray2f;
                }

                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTrianglesBinary))
                {
                    t = meshAttr[IOStrings.AMeshTrianglesBinary] as VectorArray3i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTriangleGroupsBinary))
                {
                    g = meshAttr[IOStrings.AMeshTriangleGroupsBinary] as int[];
                }

                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshEdgesBinary))
                {
                    e = meshAttr[IOStrings.AMeshEdgesBinary] as IndexArray4i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshEdgeRefCountsBinary))
                {
                    e_ref = meshAttr[IOStrings.AMeshEdgeRefCountsBinary] as short[];
                }
            }

            DMesh3 m = new DMesh3();

            if (n != null)
            {
                m.EnableVertexNormals(Vector3f.Zero);
            }
            if (c != null)
            {
                m.EnableVertexColors(Vector3f.Zero);
            }
            if (uv != null)
            {
                m.EnableVertexUVs(Vector2f.Zero);
            }
            if (g != null)
            {
                m.EnableTriangleGroups(0);
            }

            if (storageMode == IOStrings.MeshStorageMode.EdgeRefCounts)
            {
                if (v == null || t == null || e == null || e_ref == null)
                {
                    return(null);
                }

                m.VerticesBuffer = new DVector <double>(v);
                if (n != null)
                {
                    m.NormalsBuffer = new DVector <float>(n);
                }
                if (c != null)
                {
                    m.ColorsBuffer = new DVector <float>(c);
                }
                if (uv != null)
                {
                    m.UVBuffer = new DVector <float>(uv);
                }
                m.TrianglesBuffer = new DVector <int>(t);
                if (g != null)
                {
                    m.GroupsBuffer = new DVector <int>(g);
                }

                m.EdgesBuffer    = new DVector <int>(e);
                m.EdgesRefCounts = new RefCountVector(e_ref);
                m.RebuildFromEdgeRefcounts();
            }
            else if (storageMode == IOStrings.MeshStorageMode.Minimal)
            {
                if (v == null || t == null)
                {
                    return(null);
                }

                int           NV    = v.Count;
                NewVertexInfo vinfo = new NewVertexInfo();
                for (int k = 0; k < NV; ++k)
                {
                    vinfo.v = v[k];
                    if (n != null)
                    {
                        vinfo.n = n[k];
                    }
                    if (c != null)
                    {
                        vinfo.c = c[k];
                    }
                    if (uv != null)
                    {
                        vinfo.uv = uv[k];
                    }
                    m.AppendVertex(ref vinfo);
                }

                int NT = t.Count;
                for (int k = 0; k < NT; ++k)
                {
                    Vector3i tri  = t[k];
                    int      setg = (g == null) ? -1 : g[k];
                    m.AppendTriangle(tri, setg);
                }
            }
            else
            {
                throw new Exception("SOFactory.RestoreDMesh: unsupported mesh storage mode");
            }

            return(m);
        }
Esempio n. 12
0
    // Use this for initialization
    public override void Awake()
    {
        // if we need to auto-configure Rift vs Vive vs (?) VR, we need
        // to do this before any other F3 setup, because MainCamera will change
        // and we are caching that in a lot of places...
        if (AutoConfigVR)
        {
            VRCameraRig = gs.VRPlatform.AutoConfigureVR();
        }

        // restore any settings
        SceneGraphConfig.RestorePreferences();

        // set up some defaults
        // this will move the ground plane down, but the bunnies will be floating...
        //SceneGraphConfig.InitialSceneTranslate = -4.0f * Vector3f.AxisY;
        SceneGraphConfig.DefaultSceneCurveVisualDegrees = 0.5f;
        SceneGraphConfig.DefaultPivotVisualDegrees      = 2.3f;
        SceneGraphConfig.DefaultAxisGizmoVisualDegrees  = 25.0f;
        PolyCurveSO.DefaultHitWidthMultiplier           = 2.5f;

        SceneOptions options = new SceneOptions();

        options.UseSystemMouseCursor  = false;
        options.Use2DCockpit          = false;
        options.EnableTransforms      = true;
        options.EnableCockpit         = true;
        options.EnableDefaultLighting = false;
        options.CockpitInitializer    = new SetupOrthoVRCockpit();

        options.MouseCameraControls = new MayaCameraHotkeys()
        {
            MousePanSpeed = 5.0f, MouseZoomSpeed = 5.0f
        };
        options.SpatialCameraRig = VRCameraRig;

        // very verbose
        options.LogLevel = 2;

        // hacks for stuff
#if F3_ENABLE_TEXT_MESH_PRO
        SceneGraphConfig.TextLabelZOffset = -0.01f;
#else
        SceneGraphConfig.TextLabelZOffset = -0.3f;
#endif


        context    = new FContext();
        OG.Context = context;
        OrthogenUI.ActiveContext = context;
        context.Start(options);


        // Set up standard scene lighting if enabled
        if (options.EnableDefaultLighting)
        {
            GameObject lighting = GameObject.Find("SceneLighting");
            if (lighting == null)
            {
                lighting = new GameObject("SceneLighting");
            }
            SceneLightingSetup setup = lighting.AddComponent <SceneLightingSetup>();
            setup.Context              = context;
            setup.ShadowLightCount     = 0;
            setup.AdjustShadowDistance = false;
            setup.LightDistance        = 1000.0f; // related to total scene scale...
        }

        // override sun so that it doesn't stick to one of the scene lights
        RenderSettings.sun = GameObject.Find("SunLight").GetComponent <Light>();

        //GameObjectFactory.CurveRendererSource = new VectrosityCurveRendererFactory();

        // set up ground plane geometry (optional)
        GameObject boundsObject = GameObject.Find("Bounds");
        if (boundsObject != null)
        {
            context.Scene.AddWorldBoundsObject(boundsObject);
        }


        /*
         * ORTHOGEN-SPECIFIC SETUP STARTS HERE
         */

        // set up scene and tools like Orthogen wants them
        OGActions.InitializeVRUsageContext();
        OrthogenMaterials.InitializeMaterials();
        OrthogenMaterials.ScanMaterial = new UnitySOMaterial(MaterialUtil.SafeLoadMaterial("scan_material"));
        //OrthogenMaterials.RectifiedLegMaterial = OrthogenMaterials.ScanMaterial;
        OGActions.InitializeF3Scene(context);
        OGActions.InitializeF3Tools(context);
        OGActions.InitializeF3VRTools(context);
        OGActions.PostConfigureTools_Demo();
        OGActions.ConfigurePlatformInput_VR();


        /*
         * optional things specific to demo app
         */

        // ground plane stays below socket as it is updated
        DemoActions.AddRepositionGroundPlaneOnSocketEdit();


        /*
         * import sample mesh
         */
        bool do_scan_demo = true;

        // load sample mesh
        string assetPath   = Application.dataPath;
        string samplesPath = Path.Combine(assetPath, "..", "sample_files");
        //string sampleFile = Path.Combine(samplesPath, "sample_socket_off.obj");
        string sampleFile = Path.Combine(samplesPath, "sample_socket_1.obj");
        if (do_scan_demo)
        {
            sampleFile = Path.Combine(samplesPath, "scan_1_remesh.obj");
        }
        if (File.Exists(sampleFile) == false)
        {
            sampleFile = Path.Combine(samplesPath, "sample_socket_1.obj");
        }
        DMesh3 mesh = StandardMeshReader.ReadMesh(sampleFile);
        // read sample file from Resources instead
        //MemoryStream sampleFileStream = FResources.LoadBinary("sample_socket_1");
        //DMesh3 mesh = StandardMeshReader.ReadMesh(sampleFileStream, "obj");
        if (mesh.HasVertexColors == false)
        {
            mesh.EnableVertexColors(Colorf.Silver);
        }

        // transform to our coordinate system
        double scale = Units.MetersTo(Units.Linear.Millimeters); // this mesh is in meters, so scale to mm
        MeshTransforms.FlipLeftRightCoordSystems(mesh);          // convert to unity coordinate system
        MeshTransforms.Scale(mesh, scale);

        if (do_scan_demo)
        {
            OGActions.SetSizeMode(OGActions.SizeModes.RealSize);
        }
        else
        {
            OGActions.SetSizeMode(OGActions.SizeModes.DemoSize);
        }

        // initialize the datamodel
        OGActions.BeginSocketDesignFromScan(Context, mesh);

        // set up my UI tests/etc
        configure_unity_ui();

        // [RMS] do this next frame because SteamVR needs a chance to set up and position the cockpit
        OGActions.RecenterVRView(true);

        add_vr_head(context);

        // dgraph tests
        //DGTest.test(Debug.Log);
    }
Esempio n. 13
0
    // Use this for initialization
    public override void Awake()
    {
        // if we need to auto-configure Rift vs Vive vs (?) VR, we need
        // to do this before any other F3 setup, because MainCamera will change
        // and we are caching that in a lot of places...
        if (AutoConfigVR)
        {
            VRCameraRig = gs.VRPlatform.AutoConfigureVR();
        }

        // restore any settings
        SceneGraphConfig.RestorePreferences();

        // set up some defaults
        // this will move the ground plane down, but the bunnies will be floating...
        //SceneGraphConfig.InitialSceneTranslate = -4.0f * Vector3f.AxisY;
        SceneGraphConfig.DefaultSceneCurveVisualDegrees = 0.35f;
        SceneGraphConfig.DefaultPivotVisualDegrees      = 2.3f;
        SceneGraphConfig.DefaultAxisGizmoVisualDegrees  = 25.0f;

        // make curves easier to click
        PolyCurveSO.DefaultHitWidthMultiplier = 2.0f;

        SceneOptions options = new SceneOptions();

        options.UseSystemMouseCursor = true;
        options.EnableTransforms     = true;
        options.EnableCockpit        = true;
        options.CockpitInitializer   = new SetupOrthoGenCockpit();

        options.MouseCameraControls = new MayaCameraHotkeys()
        {
            MousePanSpeed = 5.0f, MouseZoomSpeed = 5.0f
        };
        options.SpatialCameraRig = VRCameraRig;

        options.Use2DCockpit             = true;
        options.ConstantSize2DCockpit    = true;
        FPlatform.EditorPixelScaleFactor = 1.0f;

        // very verbose
        options.LogLevel = 2;

        context    = new FContext();
        OG.Context = context;
        OrthogenUI.ActiveContext = context;
        context.Start(options);

        DebugUtil.Log("started context");

        // Set up standard scene lighting if enabled
        if (options.EnableDefaultLighting)
        {
            GameObject lighting = GameObject.Find("SceneLighting");
            if (lighting == null)
            {
                lighting = new GameObject("SceneLighting");
            }
            SceneLightingSetup setup = lighting.AddComponent <SceneLightingSetup>();
            setup.Context       = context;
            setup.LightDistance = 30.0f; // related to total scene scale...
        }


        //GameObjectFactory.CurveRendererSource = new VectrosityCurveRendererFactory();

        // set up ground plane geometry (optional)
        GameObject boundsObject = GameObject.Find("Bounds");

        if (boundsObject != null)
        {
            context.Scene.AddWorldBoundsObject(boundsObject);
        }


        /*
         * ORTHOGEN-SPECIFIC SETUP STARTS HERE
         */

        // set up scene and tools like Orthogen wants them
        OGActions.InitializeUsageContext(OGActions.UsageContext.OrthoVRApp);
        //OGActions.InitializeUsageContext(OGActions.UsageContext.NiaOrthogenApp);
        OrthogenMaterials.InitializeMaterials();
        OGActions.InitializeF3Scene(context);
        OGActions.InitializeF3Tools(context);
        OGActions.PostConfigureTools_Demo();
        OGActions.ConfigurePlatformInput_Mouse();

        /*
         * optional things specific to demo app
         */

        // ground plane stays below socket as it is updated
        DemoActions.AddRepositionGroundPlaneOnSocketEdit();


        /*
         * import sample mesh
         */

        // load sample mesh
        string assetPath   = Application.dataPath;
        string samplesPath = Path.Combine(assetPath, "..", "sample_files");
        //string sampleFile = Path.Combine(samplesPath, "sample_socket_off.obj");
        //string sampleFile = Path.Combine(samplesPath, "sample_socket_1.obj");
        //string sampleFile = Path.Combine(samplesPath, "scan_1_raw.obj");
        string sampleFile = Path.Combine(samplesPath, "scan_1_remesh.obj");
        DMesh3 mesh       = StandardMeshReader.ReadMesh(sampleFile);

        if (mesh.HasVertexColors == false)
        {
            mesh.EnableVertexColors(Colorf.Silver);
        }
        // read sample file from Resources instead
        //MemoryStream sampleFileStream = FResources.LoadBinary("sample_socket_1");
        //DMesh3 mesh = StandardMeshReader.ReadMesh(sampleFileStream, "obj");
        double scale = Units.MetersTo(Units.Linear.Millimeters); // this mesh is in meters, so scale to mm

        MeshTransforms.FlipLeftRightCoordSystems(mesh);          // convert to unity coordinate system
        MeshTransforms.Scale(mesh, scale);

        // initialize the datamodel
        OGActions.BeginSocketDesignFromScan(Context, mesh);

        // set up my UI tests/etc
        configure_unity_ui();

        // dgraph tests
        //DGTest.test(Debug.Log);
    }