static ElementId ToHost(Rhino.DocObjects.Material mat, Document doc, Dictionary <string, Autodesk.Revit.DB.Material> materials)
        {
            var id = ElementId.InvalidElementId;

            if (mat.HasName)
            {
                var matName = mat.Name;
                if (materials.TryGetValue(matName, out var material))
                {
                    id = material.Id;
                }
                else
                {
                    id = Autodesk.Revit.DB.Material.Create(doc, matName);
                    var newMaterial = doc.GetElement(id) as Autodesk.Revit.DB.Material;

                    newMaterial.Color             = mat.PreviewColor.ToHost();
                    newMaterial.Shininess         = (int)Math.Round(mat.Shine / Rhino.DocObjects.Material.MaxShine * 128.0);
                    newMaterial.Smoothness        = (int)Math.Round(mat.Reflectivity * 100.0);
                    newMaterial.Transparency      = (int)Math.Round(mat.Transparency * 100.0);
                    newMaterial.AppearanceAssetId = ToHost(mat.RenderMaterial, doc, matName);

                    materials.Add(matName, newMaterial);
                }
            }

            return(id);
        }
Example #2
0
        private static ProbableMaterial WhatMaterial(RenderMaterial rm, Rhino.DocObjects.Material m)
        {
            if (rm.TypeId.Equals(RenderMaterial.PictureMaterialGuid))
            {
                return(ProbableMaterial.Picture);
            }
            if (rm.TypeId.Equals(RenderMaterial.PlasterMaterialGuid))
            {
                return(ProbableMaterial.Plaster);
            }
            if (rm.TypeId.Equals(RenderMaterial.GlassMaterialGuid))
            {
                return(ProbableMaterial.Glass);
            }
            if (rm.TypeId.Equals(RenderMaterial.GemMaterialGuid))
            {
                return(ProbableMaterial.Gem);
            }
            if (rm.TypeId.Equals(RenderMaterial.PaintMaterialGuid))
            {
                return(ProbableMaterial.Paint);
            }
            if (rm.TypeId.Equals(RenderMaterial.PlasticMaterialGuid))
            {
                return(ProbableMaterial.Plastic);
            }
            if (rm.TypeId.Equals(RenderMaterial.MetalMaterialGuid))
            {
                return(ProbableMaterial.Metal);
            }


            if (rm.SmellsLikePlaster || rm.SmellsLikeTexturedPlaster)
            {
                return(ProbableMaterial.Plaster);
            }
            if (rm.SmellsLikeGlass || rm.SmellsLikeTexturedGlass)
            {
                return(ProbableMaterial.Glass);
            }
            if (rm.SmellsLikeGem || rm.SmellsLikeTexturedGem)
            {
                return(ProbableMaterial.Gem);
            }
            if (rm.SmellsLikePaint || rm.SmellsLikeTexturedPaint)
            {
                return(ProbableMaterial.Paint);
            }
            if (rm.SmellsLikePlastic || rm.SmellsLikeTexturedPlastic)
            {
                return(ProbableMaterial.Plastic);
            }
            if (rm.SmellsLikeMetal || rm.SmellsLikeTexturedMetal)
            {
                return(ProbableMaterial.Metal);
            }

            return(ProbableMaterial.Custom);
        }
        void HandleBaseColor(Rhino.DocObjects.Material rhinoMaterial, glTFLoader.Schema.Material gltfMaterial)
        {
            Rhino.DocObjects.Texture baseColorDoc    = rhinoMaterial.GetTexture(TextureType.PBR_BaseColor);
            Rhino.DocObjects.Texture alphaTextureDoc = rhinoMaterial.GetTexture(TextureType.PBR_Alpha);

            RenderTexture baseColorTexture = rhinoMaterial.RenderMaterial.GetTextureFromUsage(RenderMaterial.StandardChildSlots.PbrBaseColor);
            RenderTexture alphaTexture     = rhinoMaterial.RenderMaterial.GetTextureFromUsage(RenderMaterial.StandardChildSlots.PbrAlpha);

            bool baseColorLinear = baseColorTexture == null ? false : IsLinear(baseColorTexture);

            bool hasBaseColorTexture = baseColorDoc == null ? false : baseColorDoc.Enabled;
            bool hasAlphaTexture     = alphaTextureDoc == null ? false : alphaTextureDoc.Enabled;

            bool baseColorDiffuseAlphaForTransparency = rhinoMaterial.PhysicallyBased.UseBaseColorTextureAlphaForObjectAlphaTransparencyTexture;

            Color4f baseColor = rhinoMaterial.PhysicallyBased.BaseColor;

            if (workflow.PreProcessColors)
            {
                baseColor = Color4f.ApplyGamma(baseColor, workflow.PreProcessGamma);
            }

            if (!hasBaseColorTexture && !hasAlphaTexture)
            {
                gltfMaterial.PbrMetallicRoughness.BaseColorFactor = new float[]
                {
                    baseColor.R,
                    baseColor.G,
                    baseColor.B,
                    (float)rhinoMaterial.PhysicallyBased.Alpha,
                };

                if (rhinoMaterial.PhysicallyBased.Alpha == 1.0)
                {
                    gltfMaterial.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.OPAQUE;
                }
                else
                {
                    gltfMaterial.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.BLEND;
                }
            }
            else
            {
                gltfMaterial.PbrMetallicRoughness.BaseColorTexture = CombineBaseColorAndAlphaTexture(baseColorTexture, alphaTexture, baseColorDiffuseAlphaForTransparency, baseColor, baseColorLinear, (float)rhinoMaterial.PhysicallyBased.Alpha, out bool hasAlpha);

                if (hasAlpha)
                {
                    gltfMaterial.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.BLEND;
                }
                else
                {
                    gltfMaterial.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.OPAQUE;
                }
            }
        }
        int GetMaterial(Rhino.DocObjects.Material material, Guid materialId)
        {
            if (!materialsMap.TryGetValue(materialId, out int materialIndex))
            {
                RhinoMaterialGltfConverter materialConverter = new RhinoMaterialGltfConverter(options, dummy, binaryBuffer, material, workflow);
                materialIndex = materialConverter.AddMaterial();
                materialsMap.Add(materialId, materialIndex);
            }

            return(materialIndex);
        }
Example #5
0
        static ElementId ToHost(Rhino.DocObjects.Material mat, Document doc, Dictionary <string, Autodesk.Revit.DB.Material> materials)
        {
            var id = ElementId.InvalidElementId;

            if (materials.TryGetValue(mat.Name ?? "Default", out var material))
            {
                id = material.Id;
            }
            else
            {
                id = Autodesk.Revit.DB.Material.Create(doc, mat.Name);
                var newMaterial = doc.GetElement(id) as Autodesk.Revit.DB.Material;

                newMaterial.Color = new Autodesk.Revit.DB.Color(255, 255, 255);
#if REVIT_2019
                if (newMaterial.AppearanceAssetId == ElementId.InvalidElementId)
                {
                    if (AppearanceAssetElement.GetAppearanceAssetElementByName(doc, mat.Name) is AppearanceAssetElement appearanceAssetElement)
                    {
                        newMaterial.AppearanceAssetId = appearanceAssetElement.Id;
                    }
                    else
                    {
                        appearanceAssetElement = AppearanceAssetElement.GetAppearanceAssetElementByName(doc, "Generic");
                        if (appearanceAssetElement is null)
                        {
                            var assets = Revit.ActiveUIApplication.Application.GetAssets(AssetType.Appearance);
                            foreach (var asset in assets)
                            {
                                if (asset.Name == "Generic")
                                {
                                    appearanceAssetElement        = AppearanceAssetElement.Create(doc, mat.Name, asset);
                                    newMaterial.AppearanceAssetId = appearanceAssetElement.Id;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            appearanceAssetElement        = appearanceAssetElement.Duplicate(mat.Name);
                            newMaterial.AppearanceAssetId = appearanceAssetElement.Id;
                        }

                        if (newMaterial.AppearanceAssetId != ElementId.InvalidElementId)
                        {
                            using (var editScope = new AppearanceAssetEditScope(doc))
                            {
                                var editableAsset          = editScope.Start(newMaterial.AppearanceAssetId);
                                var genericDiffuseProperty = editableAsset.FindByName("generic_diffuse") as AssetPropertyDoubleArray4d;
                                genericDiffuseProperty.SetValueAsColor(mat.DiffuseColor.ToHost());

                                var properties = new List <AssetProperty>(editableAsset.Size);
                                for (int i = 0; i < editableAsset.Size; i++)
                                {
                                    properties.Add(editableAsset[i]);
                                }

                                editScope.Commit(false);
                            }
                        }
                    }
                }
#endif
                materials.Add(mat.Name, newMaterial);
            }

            return(id);
        }
    public static Rhino.Commands.Result AddTexture(Rhino.RhinoDoc doc)
    {
        // Select object to add texture
        const ObjectType filter = Rhino.DocObjects.ObjectType.Surface |
                                  Rhino.DocObjects.ObjectType.PolysrfFilter |
                                  Rhino.DocObjects.ObjectType.Mesh;

        Rhino.DocObjects.ObjRef objref;
        Rhino.Commands.Result   rc = Rhino.Input.RhinoGet.GetOneObject("Select object to add texture", false, filter, out objref);
        if (rc != Rhino.Commands.Result.Success)
        {
            return(rc);
        }

        Rhino.DocObjects.RhinoObject rhino_object = objref.Object();
        if (rhino_object == null)
        {
            return(Rhino.Commands.Result.Failure);
        }

        // Select texture
        Rhino.UI.OpenFileDialog fd = new Rhino.UI.OpenFileDialog();
        fd.Filter = "Image Files (*.bmp;*.png;*.jpg)|*.bmp;*.png;*.jpg";
        if (fd.ShowDialog() != System.Windows.Forms.DialogResult.OK)
        {
            return(Rhino.Commands.Result.Cancel);
        }

        // Verify texture
        string bitmap_filename = fd.FileName;

        if (string.IsNullOrEmpty(bitmap_filename) || !System.IO.File.Exists(bitmap_filename))
        {
            return(Rhino.Commands.Result.Nothing);
        }

        // Make sure the object has it's material source set to "material_from_object"
        rhino_object.Attributes.MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromObject;

        // Make sure the object has a material assigned
        int material_index = rhino_object.Attributes.MaterialIndex;

        if (material_index < 0)
        {
            // Create a new material based on Rhino's default material
            material_index = doc.Materials.Add();
            // Assign the new material (index) to the object.
            rhino_object.Attributes.MaterialIndex = material_index;
        }

        if (material_index >= 0)
        {
            Rhino.DocObjects.Material mat = doc.Materials[material_index];
            mat.SetBumpTexture(bitmap_filename);
            mat.CommitChanges();

            //Don't forget to update the object, if necessary
            rhino_object.CommitChanges();

            doc.Views.Redraw();
            return(Rhino.Commands.Result.Success);
        }

        return(Rhino.Commands.Result.Failure);
    }
Example #7
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            double tolerance = doc.ModelAbsoluteTolerance;

            List <Curve> icur = new List <Curve>();

            GetObject gcr = new Rhino.Input.Custom.GetObject();

            gcr.SetCommandPrompt("Select reference circles for stones. (No curves)");
            gcr.GeometryFilter              = Rhino.DocObjects.ObjectType.Curve;
            gcr.GroupSelect                 = true;
            gcr.SubObjectSelect             = true;
            gcr.DeselectAllBeforePostSelect = true;
            gcr.OneByOnePostSelect          = false;
            gcr.GetMultiple(1, 0);

            for (int ie = 0; ie < gcr.ObjectCount; ie++)
            {
                Rhino.DocObjects.ObjRef      objref = gcr.Object(ie);
                Rhino.DocObjects.RhinoObject obj    = objref.Object();
                if (obj == null)
                {
                    return(Result.Failure);
                }
                Curve refcr = objref.Curve();
                if (refcr == null)
                {
                    return(Result.Failure);
                }
                obj.Select(false);

                icur.Add(refcr);
            }
            var rm = FindMaterial(doc, "Diamond");

            if (null == rm)
            {
                //Didn't find the material - create one and carry on.

                //Create a basic material
                var custom = new Rhino.DocObjects.Material();
                custom.Reflectivity = 1;
                custom.Transparency = 0.2;
                custom.SetEnvironmentTexture(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/Free Jewels Rhino Plug-Ins/Dia3.jpg");
                custom.Name = "Diamond";
                custom.CommitChanges();

                rm = RenderMaterial.CreateBasicMaterial(custom);

                var docMats = doc.RenderMaterials;

                //docMats.BeginChange(RenderContent.ChangeContexts.Program);
                docMats.Add(rm);
                //docMats.EndChange();
            }



            // Create Stone Mesh
            Rhino.Geometry.Mesh mesh = new Rhino.Geometry.Mesh();


            mesh.Vertices.Add(0.0, 0.0, -0.44);      //0

            mesh.Vertices.Add(0.0, 0.097, -0.363);   //1
            mesh.Vertices.Add(0.069, 0.069, -0.363); //2
            mesh.Vertices.Add(0.097, 0.0, -0.363);   //3

            mesh.Vertices.Add(0.0, 0.5, -0.013);     //4
            mesh.Vertices.Add(0.098, 0.49, -0.005);  //5
            mesh.Vertices.Add(0.191, 0.462, -0.013); //6
            mesh.Vertices.Add(0.278, 0.416, -0.005); //7
            mesh.Vertices.Add(0.354, 0.354, -0.013); //8
            mesh.Vertices.Add(0.416, 0.278, -0.005); //9
            mesh.Vertices.Add(0.462, 0.191, -0.013); //10
            mesh.Vertices.Add(0.49, 0.098, -0.005);  //11
            mesh.Vertices.Add(0.5, 0.0, -0.013);     //12

            mesh.Vertices.Add(0.0, 0.5, 0.013);      //13
            mesh.Vertices.Add(0.098, 0.49, 0.005);   //14
            mesh.Vertices.Add(0.191, 0.462, 0.013);  //15
            mesh.Vertices.Add(0.278, 0.416, 0.005);  //16
            mesh.Vertices.Add(0.354, 0.354, 0.013);  //17
            mesh.Vertices.Add(0.416, 0.278, 0.005);  //18
            mesh.Vertices.Add(0.462, 0.191, 0.013);  //19
            mesh.Vertices.Add(0.49, 0.098, 0.005);   //20
            mesh.Vertices.Add(0.5, 0.0, 0.013);      //21

            mesh.Vertices.Add(0.0, 0.372, 0.12);     //22
            mesh.Vertices.Add(0.263, 0.263, 0.12);   //23
            mesh.Vertices.Add(0.372, 0.0, 0.12);     //24
            mesh.Vertices.Add(0.263, -0.263, 0.12);  //25
            mesh.Vertices.Add(0.0, -0.372, 0.12);    //26
            mesh.Vertices.Add(-0.263, -0.263, 0.12); //27
            mesh.Vertices.Add(-0.372, 0.0, 0.12);    //28
            mesh.Vertices.Add(-0.263, 0.263, 0.12);  //29

            mesh.Vertices.Add(0.109, 0.263, 0.16);   //30
            mesh.Vertices.Add(0.263, 0.109, 0.16);   //31
            mesh.Vertices.Add(0.263, -0.109, 0.16);  //32
            mesh.Vertices.Add(0.109, -0.263, 0.16);  //33
            mesh.Vertices.Add(-0.109, -0.263, 0.16); //34
            mesh.Vertices.Add(-0.263, -0.109, 0.16); //35
            mesh.Vertices.Add(-0.263, 0.109, 0.16);  //36
            mesh.Vertices.Add(-0.109, 0.263, 0.16);  //37

            mesh.Vertices.Add(0.0, 0.0, 0.16);       //38

            mesh.Faces.AddFace(0, 1, 6, 2);
            mesh.Faces.AddFace(0, 2, 10, 3);

            mesh.Faces.AddFace(1, 4, 5, 6);
            mesh.Faces.AddFace(2, 6, 7, 8);
            mesh.Faces.AddFace(2, 8, 9, 10);
            mesh.Faces.AddFace(3, 10, 11, 12);

            mesh.Faces.AddFace(4, 13, 14, 5);
            mesh.Faces.AddFace(5, 14, 15, 6);
            mesh.Faces.AddFace(6, 15, 16, 7);
            mesh.Faces.AddFace(7, 16, 17, 8);
            mesh.Faces.AddFace(8, 17, 18, 9);
            mesh.Faces.AddFace(9, 18, 19, 10);
            mesh.Faces.AddFace(10, 19, 20, 11);
            mesh.Faces.AddFace(11, 20, 21, 12);

            mesh.Faces.AddFace(13, 22, 15, 14);
            mesh.Faces.AddFace(15, 23, 17, 16);
            mesh.Faces.AddFace(17, 23, 19, 18);
            mesh.Faces.AddFace(19, 24, 21, 20);

            mesh.Faces.AddFace(15, 22, 30, 23);
            mesh.Faces.AddFace(19, 23, 31, 24);

            mesh.Faces.AddFace(23, 30, 31);
            mesh.Faces.AddFace(24, 31, 32);

            mesh.Faces.AddFace(32, 31, 30, 38);

            mesh.Unweld(0.001, false);

            Mesh meshAll = new Mesh();

            for (int i = 0; i < 4; i++)
            {
                meshAll.Append(mesh);
                Point3d  center = new Point3d(0.0, 0.0, 0.0);
                Vector3d rotVec = new Vector3d(0.0, 0.0, 1.0);
                mesh.Rotate(Math.PI / 2, rotVec, center);
            }
            meshAll.Compact();
            meshAll.Weld(0.001);

            //Get object Guid to apply render material
            var         meshGuid = doc.Objects.AddMesh(meshAll);
            ObjRef      objre    = new ObjRef(meshGuid);
            RhinoObject obje     = objre.Object();

            obje.RenderMaterial = rm;
            obje.CommitChanges();

            //Make InstanceDefinition
            string instDefCount = DateTime.Now.ToString("ddMMyyyyHHmmss");

            var geometry = new System.Collections.Generic.List <Rhino.Geometry.GeometryBase>()
            {
                obje.Geometry
            };
            var attributes = new System.Collections.Generic.List <Rhino.DocObjects.ObjectAttributes>()
            {
                obje.Attributes
            };


            var stoneIndex = doc.InstanceDefinitions.Add("Stone" + instDefCount, "StoneMesh 1mm", Point3d.Origin, geometry, attributes);

            List <InstanceReferenceGeometry> meshPave = new List <InstanceReferenceGeometry>();


            foreach (Curve c in icur)
            {
                Circle circle1 = new Circle();
                c.TryGetCircle(out circle1, tolerance);
                double   radius     = circle1.Diameter;
                Point3d  center     = circle1.Center;
                Vector3d moveV      = new Vector3d(center);
                Vector3d zaxis      = new Vector3d(0.0, 0.0, 1.0);
                Plane    planeOr    = new Plane(center, zaxis);
                Plane    planeNew   = circle1.Plane;
                var      transform1 = Transform.Translation(moveV);
                var      transform2 = Transform.Scale(center, radius);
                var      transform3 = Transform.PlaneToPlane(planeOr, planeNew);

                var stoneA = doc.Objects.AddInstanceObject(stoneIndex, transform1);
                var stoneB = doc.Objects.Transform(stoneA, transform2, true);
                var stoneC = doc.Objects.Transform(stoneB, transform3, true);

                ids.Add(stoneC);
            }
            doc.Groups.Add(ids);
            doc.Objects.Delete(obje);
            doc.Views.Redraw();

            return(Result.Success);
        }
Example #8
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            int currIntOption = 0;
            var gi            = new GetOption();

            gi.SetCommandPrompt("Material Index");
            gi.AcceptNumber(true, true);
            var resgi = gi.Get();

            if (resgi == GetResult.Number)
            {
                currIntOption = Convert.ToInt32(gi.Number());
            }

            Rhino.Input.Custom.GetObject go = new Rhino.Input.Custom.GetObject();
            go.SetCommandPrompt("Select objects to apply material");
            go.GroupSelect     = true;
            go.SubObjectSelect = false;
            go.EnableClearObjectsOnEntry(false);
            go.EnableUnselectObjectsOnExit(false);
            go.DeselectAllBeforePostSelect = false;
            go.GetMultiple(1, 0);


            //Nothing to do - get out quick.
            if (go.ObjectCount == 0)
            {
                return(Result.Success);
            }

            var rm = FindMaterial(doc, matName[currIntOption]);

            if (null == rm)
            {
                //Didn't find the material - create one and carry on.

                //Create a basic material
                var custom = new Rhino.DocObjects.Material();
                custom.Name = matName[currIntOption];

                if (currIntOption == 13)
                {
                    custom.SetEnvironmentTexture(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/Free Jewels Rhino Plug-Ins/Dia3.jpg");
                }
                custom.CommitChanges();

                rm = RenderMaterial.CreateBasicMaterial(custom);
                rm.BeginChange(RenderContent.ChangeContexts.Program);
                rm.SetParameter("diffuse", System.Drawing.Color.Black);
                rm.SetParameter("reflectivity", 1.0);
                rm.SetParameter("reflectivity-color", System.Drawing.Color.FromArgb(r[currIntOption], g[currIntOption], b[currIntOption]));
                rm.SetParameter("transparency", fjMatTrans[currIntOption]);
                rm.SetParameter("shine", fjMatShine[currIntOption]);
                rm.SetParameter("polish-amount", fjMatShine[currIntOption]);
                rm.EndChange();

                var docMats = doc.RenderMaterials;

                docMats.Add(rm);
            }

            //Now we always have a material to assign, this part is easy
            for (int i = 0; i < go.ObjectCount; i++)
            {
                var obj = go.Object(i).Object();

                obj.RenderMaterial = rm;
                obj.CommitChanges();
            }

            doc.Views.Redraw();
            return(Result.Success);
        }
Example #9
0
        public static void Load(string filename, RhinoDoc doc)
        {
            var model = Interface.LoadModel(filename);

            if (model != null)
            {
                // dictionary with deserialized buffer data
                var bufferData = new Dictionary <int, byte[]>();

                // accessorData contains a dictionary to the buffer data meant to be accessed by an accessor via a bufferView
                var accessorData = new Dictionary <int, dynamic>();

                // material data contains a dictionary with the material index and the Rhino material ID
                var materialData = new Dictionary <int, int>();

                // mesh data
                var meshData = new Dictionary <int, List <Rhino.Geometry.Mesh> >();

                var nodeXformData = new Dictionary <int, Transform>();

                var dir = Path.GetDirectoryName(filename);

                #region Read Buffers

                for (int i = 0; i < model.Buffers.Length; i++)
                {
                    var data = Interface.LoadBinaryBuffer(model, i, filename);
                    bufferData.Add(i, data);
                }

                #endregion

                #region Process Images

                //go through images in model
                //save them to disk if necessary

                const string EMBEDDEDPNG  = "data:image/png;base64,";
                const string EMBEDDEDJPEG = "data:image/jpeg;base64,";

                var imageData = new Dictionary <int, string>(); //image index, image path

                if (model.Images != null)
                {
                    for (int i = 0; i < model.Images.Length; i++)
                    {
                        var image       = model.Images[i];
                        var name        = image.Name ?? "embeddedImage_" + i;
                        var extension   = string.Empty;
                        var imageStream = Stream.Null;

                        if (image.BufferView.HasValue)
                        {
                            imageStream = Interface.OpenImageFile(model, i, filename);
                            if (image.MimeType.HasValue)
                            {
                                if (image.MimeType == glTFLoader.Schema.Image.MimeTypeEnum.image_jpeg)
                                {
                                    extension = ".jpg";
                                }
                                else if (image.MimeType == glTFLoader.Schema.Image.MimeTypeEnum.image_png)
                                {
                                    extension = ".png";
                                }
                            }

                            var imgPath = Path.Combine(dir, "EmbeddedImages");
                            if (!Directory.Exists(imgPath))
                            {
                                Directory.CreateDirectory(imgPath);
                            }
                            imgPath = Path.Combine(imgPath, name + extension);

                            using (var fileStream = File.Create(imgPath))
                            {
                                imageStream.Seek(0, SeekOrigin.Begin);
                                imageStream.CopyTo(fileStream);
                                imageData.Add(i, imgPath);
                            }
                        }

                        if (image.Uri != null && image.Uri.StartsWith("data:image/"))
                        {
                            if (image.Uri.StartsWith(EMBEDDEDPNG))
                            {
                                extension = ".png";
                            }
                            if (image.Uri.StartsWith(EMBEDDEDJPEG))
                            {
                                extension = ".jpg";
                            }

                            imageStream = Interface.OpenImageFile(model, i, filename);

                            var imgPath = Path.Combine(dir, "EmbeddedImages");
                            if (!Directory.Exists(imgPath))
                            {
                                Directory.CreateDirectory(imgPath);
                            }
                            imgPath = Path.Combine(imgPath, name + extension);

                            using (var fileStream = File.Create(imgPath))
                            {
                                imageStream.Seek(0, SeekOrigin.Begin);
                                imageStream.CopyTo(fileStream);
                                imageData.Add(i, imgPath);
                            }
                        }

                        if (image.Uri != null && File.Exists(Path.Combine(dir, image.Uri)))
                        {
                            imageData.Add(i, Path.Combine(dir, image.Uri));
                        }
                    }
                }

                #endregion

                #region Process Materials

                // TODO: Update for Rhino 7 PBR Materials

                if (model.Materials != null)
                {
                    for (int i = 0; i < model.Materials.Length; i++)
                    {
                        var mat      = model.Materials[i];
                        var rhinoMat = new Rhino.DocObjects.Material();

                        var texId    = -1;
                        int?sourceId = null;

                        if (mat.NormalTexture != null)
                        {
                        }
                        if (mat.OcclusionTexture != null)
                        {
                        }
                        if (mat.EmissiveTexture != null)
                        {
                        }

                        if (mat.PbrMetallicRoughness.BaseColorTexture != null)
                        {
                            texId    = mat.PbrMetallicRoughness.BaseColorTexture.Index;
                            sourceId = model.Textures[texId].Source.Value;
                            rhinoMat.SetBitmapTexture(imageData[sourceId.Value]);
                        }

                        if (mat.PbrMetallicRoughness.MetallicRoughnessTexture != null)
                        {
                            texId    = mat.PbrMetallicRoughness.MetallicRoughnessTexture.Index;
                            sourceId = model.Textures[texId].Source.Value;
                            rhinoMat.SetBumpTexture(imageData[sourceId.Value]);
                        }

                        rhinoMat.Name = mat.Name;

                        var id   = doc.Materials.Add(rhinoMat);
                        var rMat = Rhino.Render.RenderMaterial.CreateBasicMaterial(rhinoMat, doc);
                        doc.RenderMaterials.Add(rMat);

                        materialData.Add(i, id);
                    }
                }

                #endregion

                #region Access Buffers

                for (int i = 0; i < model.Accessors.Length; i++)
                {
                    var accessor = model.Accessors[i];

                    //process, afterwards, check if sparse

                    if (accessor.BufferView != null)
                    {
                        var bufferView = model.BufferViews[accessor.BufferView.Value];

                        var buffer = bufferData[bufferView.Buffer]; //byte[]

                        //calculate byte length
                        var elementBytes = GetTypeMultiplier(accessor.Type) * GetComponentTypeMultiplier(accessor.ComponentType);
                        var stride       = bufferView.ByteStride != null ? bufferView.ByteStride.Value : 0;
                        var strideDiff   = stride > 0 ? stride - elementBytes : 0;
                        var count        = (elementBytes + strideDiff) * accessor.Count;

                        var arr = new byte[count];

                        System.Buffer.BlockCopy(buffer, bufferView.ByteOffset + accessor.ByteOffset, arr, 0, count);

                        var res = AccessBuffer(accessor.Type, accessor.Count, accessor.ComponentType, stride, arr);

                        accessorData.Add(i, res);
                    }

                    // if accessor is sparse, need to modify the data. accessorData index is i

                    if (accessor.Sparse != null)
                    {
                        //TODO
                        //If a BufferView is specified in the accessor, sparse acts a a way to replace  values
                        //if a BufferView does not exist in the accessor, just process the sparse data

                        //access construct data

                        var bufferViewI = model.BufferViews[accessor.Sparse.Indices.BufferView];

                        var bufferI = bufferData[bufferViewI.Buffer]; //byte[]

                        var sparseComponentType = (Accessor.ComponentTypeEnum)accessor.Sparse.Indices.ComponentType;

                        //calculate count
                        var elementBytesI = GetTypeMultiplier(Accessor.TypeEnum.SCALAR) * GetComponentTypeMultiplier(sparseComponentType);
                        var strideI       = bufferViewI.ByteStride != null ? bufferViewI.ByteStride.Value : 0;
                        var strideDiffI   = strideI > 0 ? strideI - elementBytesI : 0;
                        var countI        = (elementBytesI + strideDiffI) * accessor.Sparse.Count;

                        var arrI = new byte[countI];
                        System.Buffer.BlockCopy(bufferI, accessor.Sparse.Indices.ByteOffset + bufferViewI.ByteOffset, arrI, 0, countI);

                        var resIndices = AccessBuffer(Accessor.TypeEnum.SCALAR, accessor.Sparse.Count, sparseComponentType, strideI, arrI);

                        /////////

                        var bufferViewV = model.BufferViews[accessor.Sparse.Values.BufferView];

                        var bufferV = bufferData[bufferViewV.Buffer]; //byte[]

                        //calculate count
                        var elementBytesV = GetTypeMultiplier(accessor.Type) * GetComponentTypeMultiplier(accessor.ComponentType);
                        var strideV       = bufferViewV.ByteStride != null ? bufferViewV.ByteStride.Value : 0;
                        var strideDiffV   = strideV > 0 ? strideV - elementBytesV : 0;
                        var countV        = (elementBytesV + strideDiffV) * accessor.Sparse.Count;

                        var arrV = new byte[countV];
                        System.Buffer.BlockCopy(bufferV, accessor.Sparse.Values.ByteOffset + bufferViewV.ByteOffset, arrV, 0, countV);

                        var resValues = AccessBuffer(accessor.Type, accessor.Sparse.Count, accessor.ComponentType, strideV, arrV);

                        //mod accessorData
                        var valueCnt = 0;

                        for (int j = 0; j < accessor.Sparse.Count; j++)
                        {
                            var index             = resIndices[j];
                            var mult              = GetTypeMultiplier(accessor.Type);
                            var indexAccessorData = index * mult;

                            for (int k = 0; k < mult; k++)
                            {
                                accessorData[i][indexAccessorData + k] = resValues[valueCnt];
                                valueCnt++;
                            }
                        }
                    }
                }

                #endregion

                #region Process Meshes

                //foreach (var m in model.Meshes)
                for (int j = 0; j < model.Meshes.Length; j++)
                {
                    var m = model.Meshes[j];

                    var groupId = doc.Groups.Add(m.Name);

                    var meshes = new List <Rhino.Geometry.Mesh>();

                    foreach (var mp in m.Primitives)
                    {
                        //Do I need to treat different MeshPrimitive.ModeEnum differently? Yes because if we get POINTS, LINES, LINE_LOOP, LINE_STRIP then it won't be a mesh

                        var meshPart = new Rhino.Geometry.Mesh();

                        foreach (var att in mp.Attributes)
                        {
                            var attributeData = accessorData[att.Value];

                            switch (att.Key)
                            {
                            case "POSITION":

                                var pts = new List <Point3d>();

                                for (int i = 0; i <= attributeData.Count - 3; i = i + 3)
                                {
                                    pts.Add(new Point3d(attributeData[i], attributeData[i + 1], attributeData[i + 2]));
                                }

                                meshPart.Vertices.AddVertices(pts);

                                break;

                            case "TEXCOORD_0":

                                var uvs = new List <Point2f>();

                                for (int i = 0; i <= attributeData.Count - 2; i = i + 2)
                                {
                                    uvs.Add(new Point2f(attributeData[i], attributeData[i + 1]));
                                }

                                meshPart.TextureCoordinates.AddRange(uvs.ToArray());

                                break;

                            case "NORMAL":

                                var normals = new List <Vector3f>();

                                for (int i = 0; i <= attributeData.Count - 3; i = i + 3)
                                {
                                    normals.Add(new Vector3f(attributeData[i], attributeData[i + 1], attributeData[i + 2]));
                                }

                                meshPart.Normals.AddRange(normals.ToArray());

                                break;

                            case "COLOR_0":

                                var colors = new List <Color>();

                                for (int i = 0; i <= attributeData.Count - 3; i = i + 3)
                                {
                                    colors.Add(ColorFromSingle(attributeData[i], attributeData[i + 1], attributeData[i + 2]));
                                }

                                meshPart.VertexColors.AppendColors(colors.ToArray());

                                break;

                            default:

                                RhinoApp.WriteLine("Rhino glTF Importer: Attribute {0} not supported in Rhino. Skipping.", att.Key);

                                /* NOT SUPPORTED IN RHINO ... yet
                                 *
                                 * - TANGENT
                                 * - TEXCOORD_1 //might be supported with multiple mapping channels?
                                 * - JOINTS_0
                                 * - WEIGHTS_0
                                 *
                                 */

                                break;
                            }
                        }

                        if (mp.Indices != null)
                        {
                            // Indices can be defined as UNSIGNED_BYTE 5121 or UNSIGNED_SHORT 5123, maybe even as UNSIGNED_INT 5125

                            var faceIds = accessorData[mp.Indices.Value];
                            var faces   = new List <MeshFace>();

                            for (int i = 0; i <= faceIds.Count - 3; i = i + 3)
                            {
                                faces.Add(new MeshFace((int)faceIds[i], (int)faceIds[i + 1], (int)faceIds[i + 2]));
                            }

                            meshPart.Faces.AddFaces(faces);
                        }

                        //meshPart.Weld(Math.PI);
                        // TODO: CLEANUP
                        var oa = new ObjectAttributes
                        {
                            MaterialSource = ObjectMaterialSource.MaterialFromObject,
                            MaterialIndex  = (mp.Material != null) ? materialData[mp.Material.Value] : 0,
                            Name           = m.Name
                        };

                        //if (mp.Material != null)
                        //oa.MaterialIndex = materialData[mp.Material.Value];

                        meshPart.Compact();

#if DEBUG
                        if (!meshPart.IsValid)
                        {
                            //meshPart.Weld(Math.PI);
                            //meshPart.Vertices.Align(0.0001);
                            //meshPart.Vertices.CombineIdentical(true, true);
                            //meshPart.Vertices.CullUnused();
                            //meshPart.FaceNormals.ComputeFaceNormals();
                            //meshPart.Normals.ComputeNormals();

                            if (!meshPart.IsValid)
                            {
                                for (int i = 0; i < meshPart.Vertices.Count; i++)
                                {
                                    doc.Objects.AddTextDot(i.ToString(), meshPart.Vertices[i]);
                                    var ptD = new Point3d(meshPart.Vertices[i]);
                                    ptD.Transform(Transform.Translation(meshPart.Normals[i]));
                                    doc.Objects.AddLine(meshPart.Vertices[i], ptD);
                                }
                                foreach (var mf in meshPart.Faces)
                                {
                                    RhinoApp.WriteLine("Rhino glTF: Mesh Face - {0}", mf);
                                }
                                doc.Objects.AddPoints(meshPart.Vertices.ToPoint3dArray());
                            }
                            else
                            {
                                doc.Objects.AddMesh(meshPart, oa);
                            }
                        }
#endif

                        // var guid = doc.Objects.AddMesh(meshPart, oa);
                        // doc.Groups.AddToGroup(groupId, guid);

                        meshes.Add(meshPart);
                    }

                    meshData.Add(j, meshes);
                }

                #endregion

                #region Process Nodes Transforms

                for (int i = 0; i < model.Nodes.Length; i++)
                {
                    nodeXformData.Add(i, ProcessNode(model.Nodes[i]));
                }

                //for (int i = 0; i < model.Nodes.Length; i++)
                //TraverseNode(model, model.Nodes[i], Transform.Unset, meshData);

                TraverseNode(model, model.Nodes[model.Scenes[model.Scene.Value].Nodes[0]], Transform.Identity, meshData);

                #endregion

                #region Add to doc

                for (int i = 0; i < model.Nodes.Length; i++)
                {
                    var n = model.Nodes[i];
                    if (n.Mesh.HasValue)
                    {
                        int j = 0;
                        foreach (var meshes in meshData.Values)
                        {
                            var group = doc.Groups.Add(n.Name);
                            foreach (var m in meshes)
                            {
                                // TODO: Assign material
                                var oa = new ObjectAttributes
                                {
                                    Name = model.Meshes[j].Name
                                };
                                var guid = doc.Objects.AddMesh(m, oa);
                                doc.Groups.AddToGroup(group, guid);
                            }
                            j++;
                        }
                    }
                }

                #endregion
            }
        }
Example #10
0
        public glTFLoader.Schema.TextureInfo AddMetallicRoughnessTexture(Rhino.DocObjects.Material rhinoMaterial)
        {
            Rhino.DocObjects.Texture metalTexture     = rhinoMaterial.PhysicallyBased.GetTexture(TextureType.PBR_Metallic);
            Rhino.DocObjects.Texture roughnessTexture = rhinoMaterial.PhysicallyBased.GetTexture(TextureType.PBR_Roughness);

            bool hasMetalTexture     = metalTexture == null ? false : metalTexture.Enabled;
            bool hasRoughnessTexture = roughnessTexture == null ? false : roughnessTexture.Enabled;

            RenderTexture renderTextureMetal     = null;
            RenderTexture renderTextureRoughness = null;

            int mWidth  = 0;
            int mHeight = 0;
            int rWidth  = 0;
            int rHeight = 0;

            // Get the textures
            if (hasMetalTexture)
            {
                renderTextureMetal = rhinoMaterial.RenderMaterial.GetTextureFromUsage(Rhino.Render.RenderMaterial.StandardChildSlots.PbrMetallic);
                renderTextureMetal.PixelSize(out mWidth, out mHeight, out int _w0);
            }

            if (hasRoughnessTexture)
            {
                renderTextureRoughness = rhinoMaterial.RenderMaterial.GetTextureFromUsage(RenderMaterial.StandardChildSlots.PbrRoughness);
                renderTextureRoughness.PixelSize(out rWidth, out rHeight, out int _w1);
            }

            int width  = Math.Max(mWidth, rWidth);
            int height = Math.Max(mHeight, rHeight);

            TextureEvaluator evalMetal     = null;
            TextureEvaluator evalRoughness = null;

            // Metal
            if (hasMetalTexture)
            {
                evalMetal = renderTextureMetal.CreateEvaluator(RenderTexture.TextureEvaluatorFlags.Normal);
            }

            // Roughness
            if (hasRoughnessTexture)
            {
                evalRoughness = renderTextureRoughness.CreateEvaluator(RenderTexture.TextureEvaluatorFlags.Normal);
            }

            // Copy Metal to the blue channel, roughness to the green
            var bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            float metallic  = (float)rhinoMaterial.PhysicallyBased.Metallic;
            float roughness = (float)rhinoMaterial.PhysicallyBased.Roughness;

            for (var j = 0; j < height - 1; j += 1)
            {
                for (var i = 0; i < width - 1; i += 1)
                {
                    double x = (double)i / (double)(width - 1);
                    double y = (double)j / (double)(height - 1);

                    Point3d uvw = new Point3d(x, y, 0.0);

                    float g = 0;
                    float b = 0;
                    if (hasMetalTexture)
                    {
                        Color4f metal = evalMetal.GetColor(uvw, Vector3d.Zero, Vector3d.Zero);
                        b = metal.L; //grayscale maps, so we want lumonosity
                    }
                    else
                    {
                        b = metallic;
                    }

                    if (hasRoughnessTexture)
                    {
                        Color4f roughnessColor = evalRoughness.GetColor(uvw, Vector3d.ZAxis, Vector3d.Zero);
                        g = roughnessColor.L; //grayscale maps, so we want lumonosity
                    }
                    else
                    {
                        g = roughness;
                    }

                    Color4f color = new Color4f(0.0f, g, b, 1.0f);
                    bitmap.SetPixel(i, height - j - 1, color.AsSystemColor());
                }
            }

            return(GetTextureInfoFromBitmap(bitmap));
        }
Example #11
0
 public RhinoMaterialGltfConverter(glTFExportOptions options, gltfSchemaDummy dummy, List <byte> binaryBuffer, Rhino.DocObjects.Material rhinoMaterial, LinearWorkflow workflow)
 {
     this.options       = options;
     this.dummy         = dummy;
     this.binaryBuffer  = binaryBuffer;
     this.rhinoMaterial = rhinoMaterial;
     this.workflow      = workflow;
 }
Example #12
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            /*
             * Original Version Written by Giulio Piacentino - 2010 11 21 - for Grasshopper 0.8.002
             * Enhanced by Co-de-iT (Alessio) - now bakes on chosen layer(s) and in groups
             */
            GeometryBase obj = null;

            if (!DA.GetData(0, ref obj))
            {
                return;
            }

            string name = "";

            DA.GetData(1, ref name);
            string layer = "";

            DA.GetData(2, ref layer);

            Color color = new Color();

            DA.GetData(3, ref color);
            Object material = new Object();

            DA.GetData(4, ref material);
            int group_n = 0;

            DA.GetData(5, ref group_n);

            bool group = false;

            DA.GetData(6, ref group);
            bool bake_iT = false;

            DA.GetData(7, ref bake_iT);

            if (!bake_iT)
            {
                return;
            }

            //Make new attribute to set name
            Rhino.DocObjects.ObjectAttributes att = new Rhino.DocObjects.ObjectAttributes();

            //Set object name
            if (!string.IsNullOrEmpty(name))
            {
                att.Name = name;
            }

            //Set color
            if (!color.IsEmpty)
            {
                att.ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject; //Make the color type "by object"
                att.ObjectColor = color;

                att.PlotColorSource = Rhino.DocObjects.ObjectPlotColorSource.PlotColorFromObject; //Make the plot color type "by object"
                att.PlotColor       = color;
            }

            // Set group

            if (group)
            {
                Rhino.RhinoDoc.ActiveDoc.Groups.Add(Convert.ToString(group_n));
                att.AddToGroup(group_n);
            }

            //Set layer
            if (!string.IsNullOrEmpty(layer) && Rhino.DocObjects.Layer.IsValidName(layer))
            {
                //Get the current layer index
                Rhino.DocObjects.Tables.LayerTable layerTable = Rhino.RhinoDoc.ActiveDoc.Layers;
                //int layerIndex = layerTable.Find(layer, true);
                int layerIndex = layerTable.FindByFullPath(layer, -1);

                if (layerIndex < 0)                                                //This layer does not exist, we add it
                {
                    Rhino.DocObjects.Layer onlayer = new Rhino.DocObjects.Layer(); //Make a new layer
                    onlayer.Name  = layer;
                    onlayer.Color = Color.Gainsboro;                               // sets new layer color - future dev: choose new layers color

                    layerIndex = layerTable.Add(onlayer);                          //Add the layer to the layer table
                    if (layerIndex > -1)                                           //We managed to add the layer!
                    {
                        att.LayerIndex = layerIndex;
                        //Print("Added new layer to the document at position " + layerIndex + " named " + layer + ". ");
                    }
                    //else
                    //Print("Layer did not add. Try cleaning up your layers."); //This never happened to me.
                }
                else
                {
                    att.LayerIndex = layerIndex; //We simply add to the existing layer
                }
            }


            //Set plotweight
            //if (pWidth > 0)
            //{
            //    att.PlotWeightSource = Rhino.DocObjects.ObjectPlotWeightSource.PlotWeightFromObject;
            //    att.PlotWeight = pWidth;
            //}


            //Set material

            bool materialByName = !string.IsNullOrEmpty(material as string);

            Rhino.Display.DisplayMaterial inMaterial;
            if (material is GH_Material)
            {
                GH_Material gMat = material as GH_Material;
                inMaterial = gMat.Value as Rhino.Display.DisplayMaterial;
            }
            else
            {
                inMaterial = material as Rhino.Display.DisplayMaterial;
            }
            if (material is Color)
            {
                inMaterial = new Rhino.Display.DisplayMaterial((Color)material);
            }
            if (material != null && inMaterial == null && !materialByName)
            {
                if (!(material is string))
                {
                    try //We also resort to try with IConvertible
                    {
                        inMaterial = (Rhino.Display.DisplayMaterial)Convert.ChangeType(material, typeof(Rhino.Display.DisplayMaterial));
                    }
                    catch (InvalidCastException)
                    {
                    }
                }
            }
            if (inMaterial != null || materialByName)
            {
                string matName;

                if (!materialByName)
                {
                    matName = string.Format("D:{0}-E:{1}-S:{2},{3}-T:{4}",
                                            Format(inMaterial.Diffuse),
                                            Format(inMaterial.Emission),
                                            Format(inMaterial.Specular),
                                            inMaterial.Shine.ToString(),
                                            inMaterial.Transparency.ToString()
                                            );
                }
                else
                {
                    matName = (string)material;
                }

                int materialIndex = Rhino.RhinoDoc.ActiveDoc.Materials.Find(matName, true);
                if (materialIndex < 0 && !materialByName)                     //Material does not exist and we have its specs
                {
                    materialIndex = Rhino.RhinoDoc.ActiveDoc.Materials.Add(); //Let's add it
                    if (materialIndex > -1)
                    {
                        //Print("Added new material at position " + materialIndex + " named \"" + matName + "\". ");
                        Rhino.DocObjects.Material m = Rhino.RhinoDoc.ActiveDoc.Materials[materialIndex];
                        m.Name          = matName;
                        m.DiffuseColor  = inMaterial.Diffuse;
                        m.EmissionColor = inMaterial.Emission;
                        //m.ReflectionColor = inMaterial.Specular;
                        m.SpecularColor = inMaterial.Specular;
                        m.Shine         = inMaterial.Shine;
                        m.Transparency  = inMaterial.Transparency;
                        //m.TransparentColor = no equivalent

                        m.CommitChanges();

                        att.MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromObject;
                        att.MaterialIndex  = materialIndex;
                    }
                    else
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Material did not add. Try cleaning up your materials."); //This never happened to me.
                    }
                }
                else if (materialIndex < 0 && materialByName) //Material does not exist and we do not have its specs. We do nothing
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Warning: material name not found. I cannot set the source to this material name. Add a material with name: " + matName);
                }
                else
                {
                    //If this material exists, we do not replace it!
                    att.MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromObject;
                    att.MaterialIndex  = materialIndex;
                }
            }

            //Set wire density
            //if (wires == -1 || wires > 0)
            //{
            //    att.WireDensity = wires;
            //}


            //Bake to the right type of object
            switch (obj.ObjectType)
            {
            case Rhino.DocObjects.ObjectType.Brep:
                Rhino.RhinoDoc.ActiveDoc.Objects.AddBrep(obj as Brep, att);
                break;

            case Rhino.DocObjects.ObjectType.Curve:
                Rhino.RhinoDoc.ActiveDoc.Objects.AddCurve(obj as Curve, att);
                break;

            case Rhino.DocObjects.ObjectType.Point:
                Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint((obj as Rhino.Geometry.Point).Location, att);
                break;

            case Rhino.DocObjects.ObjectType.Surface:
                Rhino.RhinoDoc.ActiveDoc.Objects.AddSurface(obj as Surface, att);
                break;

            case Rhino.DocObjects.ObjectType.Mesh:
                Rhino.RhinoDoc.ActiveDoc.Objects.AddMesh(obj as Mesh, att);
                break;

            case Rhino.DocObjects.ObjectType.Extrusion:
                typeof(Rhino.DocObjects.Tables.ObjectTable).InvokeMember("AddExtrusion", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod, null, Rhino.RhinoDoc.ActiveDoc.Objects, new object[] { obj, att });
                break;

            case Rhino.DocObjects.ObjectType.PointSet:
                Rhino.RhinoDoc.ActiveDoc.Objects.AddPointCloud(obj as Rhino.Geometry.PointCloud, att);     //This is a speculative entry
                break;

            default:
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The script does not know how to handle this type of geometry: " + obj.GetType().FullName);
                break;
            }
        }
        private void AddRhinoObjectText(Rhino.Geometry.Mesh[] rhinoMeshes, Rhino.DocObjects.Material material, Guid materialId, RhinoObject rhinoObject)
        {
            int materialIndex = GetMaterial(material, materialId);

            var primitives = new List <MeshPrimitive>();

            foreach (var rhinoMesh in rhinoMeshes)
            {
                if (options.MapRhinoZToGltfY)
                {
                    rhinoMesh.Transform(ZtoYUp);
                }
                rhinoMesh.TextureCoordinates.ReverseTextureCoordinates(1);

                rhinoMesh.Faces.ConvertQuadsToTriangles();

                var vtxBuffer    = CreateVerticesBuffer(rhinoMesh.Vertices, out Point3d vtxMin, out Point3d vtxMax);
                int vtxBufferIdx = dummy.Buffers.AddAndReturnIndex(vtxBuffer);

                var idsBuffer    = CreateIndicesBuffer(rhinoMesh.Faces, out int indicesCount);
                int idsBufferIdx = dummy.Buffers.AddAndReturnIndex(idsBuffer);

                var normalsBuffer    = CreateNormalsBuffer(rhinoMesh.Normals, out Vector3f normalsMin, out Vector3f normalsMax);
                int normalsBufferIdx = dummy.Buffers.AddAndReturnIndex(normalsBuffer);

                var texCoordsBuffer    = CreateTextureCoordinatesBuffer(rhinoMesh.TextureCoordinates, out Point2f texCoordsMin, out Point2f texCoordsMax);
                int texCoordsBufferIdx = dummy.Buffers.AddAndReturnIndex(texCoordsBuffer);

                var vtxBufferView = new BufferView()
                {
                    Buffer     = vtxBufferIdx,
                    ByteOffset = 0,
                    ByteLength = vtxBuffer.ByteLength,
                    Target     = BufferView.TargetEnum.ARRAY_BUFFER,
                };

                int vtxBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(vtxBufferView);

                var idsBufferView = new BufferView()
                {
                    Buffer     = idsBufferIdx,
                    ByteOffset = 0,
                    ByteLength = idsBuffer.ByteLength,
                    Target     = BufferView.TargetEnum.ELEMENT_ARRAY_BUFFER,
                };

                int idsBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(idsBufferView);

                BufferView normalsBufferView = new BufferView()
                {
                    Buffer     = normalsBufferIdx,
                    ByteOffset = 0,
                    ByteLength = normalsBuffer.ByteLength,
                    Target     = BufferView.TargetEnum.ARRAY_BUFFER,
                };

                int normalsBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(normalsBufferView);

                BufferView texCoordsBufferView = new BufferView()
                {
                    Buffer     = texCoordsBufferIdx,
                    ByteOffset = 0,
                    ByteLength = texCoordsBuffer.ByteLength,
                    Target     = BufferView.TargetEnum.ARRAY_BUFFER,
                };

                int texCoordsBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(texCoordsBufferView);

                // Create accessors
                Accessor vtxAccessor = new Accessor()
                {
                    BufferView    = vtxBufferViewIdx,
                    Count         = rhinoMesh.Vertices.Count,
                    Min           = new float[] { (float)vtxMin.X, (float)vtxMin.Y, (float)vtxMin.Z },
                    Max           = new float[] { (float)vtxMax.X, (float)vtxMax.Y, (float)vtxMax.Z },
                    Type          = Accessor.TypeEnum.VEC3,
                    ComponentType = Accessor.ComponentTypeEnum.FLOAT,
                    ByteOffset    = 0,
                };

                int vtxAccessorIdx = dummy.Accessors.AddAndReturnIndex(vtxAccessor);

                Accessor idsAccessor = new Accessor()
                {
                    BufferView    = idsBufferViewIdx,
                    Count         = indicesCount,
                    Min           = new float[] { 0 },
                    Max           = new float[] { rhinoMesh.Vertices.Count - 1 },
                    Type          = Accessor.TypeEnum.SCALAR,
                    ComponentType = Accessor.ComponentTypeEnum.UNSIGNED_INT,
                    ByteOffset    = 0,
                };

                int idsAccessorIdx = dummy.Accessors.AddAndReturnIndex(idsAccessor);

                Accessor normalsAccessor = new Accessor()
                {
                    BufferView    = normalsBufferViewIdx,
                    Count         = rhinoMesh.Normals.Count,
                    Min           = new float[] { normalsMin.X, normalsMin.Y, normalsMin.Z },
                    Max           = new float[] { normalsMax.X, normalsMax.Y, normalsMax.Z },
                    Type          = Accessor.TypeEnum.VEC3,
                    ComponentType = Accessor.ComponentTypeEnum.FLOAT,
                    ByteOffset    = 0,
                };

                int normalsAccessorIdx = dummy.Accessors.AddAndReturnIndex(normalsAccessor);

                Accessor texCoordsAccessor = new Accessor()
                {
                    BufferView    = texCoordsBufferViewIdx,
                    Count         = rhinoMesh.TextureCoordinates.Count,
                    Min           = new float[] { texCoordsMin.X, texCoordsMin.Y },
                    Max           = new float[] { texCoordsMax.X, texCoordsMax.Y },
                    Type          = Accessor.TypeEnum.VEC2,
                    ComponentType = Accessor.ComponentTypeEnum.FLOAT,
                    ByteOffset    = 0,
                };

                int texCoordsAccessorIdx = dummy.Accessors.AddAndReturnIndex(texCoordsAccessor);

                var primitive = new MeshPrimitive()
                {
                    Attributes = new Dictionary <string, int>()
                    {
                        { Constants.PositionAttributeTag, vtxAccessorIdx },
                        { Constants.NormalAttributeTag, normalsAccessorIdx },
                        { Constants.TexCoord0AttributeTag, texCoordsAccessorIdx },
                    },
                    Indices  = idsAccessorIdx,
                    Material = materialIndex,
                };

                // Create mesh
                primitives.Add(primitive);
            }

            var mesh = new glTFLoader.Schema.Mesh()
            {
                Primitives = primitives.ToArray(),
            };
            int idxMesh = dummy.Meshes.AddAndReturnIndex(mesh);

            var node = new Node()
            {
                Mesh = idxMesh,
                Name = string.IsNullOrEmpty(rhinoObject.Name) ? null : rhinoObject.Name,
            };

            int idxNode = dummy.Nodes.AddAndReturnIndex(node);

            dummy.Scenes[dummy.Scene].Nodes.Add(idxNode);
        }
        private void AddRhinoObjectDraco(Rhino.Geometry.Mesh[] rhinoMeshes, Rhino.DocObjects.Material material, Guid materialId, RhinoObject rhinoObject)
        {
            int materialIndex = GetMaterial(material, materialId);

            var primitives = new List <MeshPrimitive>();

            // For each rhino mesh, create gl-buffers, gl-meshes, etc.
            foreach (var rhinoMesh in rhinoMeshes)
            {
                if (options.MapRhinoZToGltfY)
                {
                    rhinoMesh.Transform(ZtoYUp);
                }
                rhinoMesh.TextureCoordinates.ReverseTextureCoordinates(1);

                var dracoComp = DracoCompression.Compress(
                    rhinoMesh,
                    new DracoCompressionOptions()
                {
                    CompressionLevel                   = options.DracoCompressionLevel,
                    IncludeNormals                     = true,
                    IncludeTextureCoordinates          = true,
                    IncludeVertexColors                = false,
                    PositionQuantizationBits           = options.DracoQuantizationBitsPosition,
                    NormalQuantizationBits             = options.DracoQuantizationBitsNormal,
                    TextureCoordintateQuantizationBits = options.DracoQuantizationBitsTexture
                }
                    );

                DracoGeometryInfo dracoGeoInfo = AddDracoGeometry(dracoComp);

                var compMeshBufferView = new BufferView()
                {
                    Buffer     = dracoGeoInfo.bufferIndex,
                    ByteOffset = dracoGeoInfo.byteOffset,
                    ByteLength = dracoGeoInfo.byteLength,
                };

                int compMeshBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(compMeshBufferView);

                var vtxAccessor = new Accessor
                {
                    Type          = Accessor.TypeEnum.VEC3,
                    ComponentType = Accessor.ComponentTypeEnum.FLOAT,
                    Count         = dracoGeoInfo.verticesNum,
                    Min           = dracoGeoInfo.verticesMin,
                    Max           = dracoGeoInfo.verticesMax,
                    ByteOffset    = 0,
                };

                int vtxAccessorIdx = dummy.Accessors.AddAndReturnIndex(vtxAccessor);

                // // Accessor Triangles Vertex IDs
                var idsAccessor = new Accessor
                {
                    Type          = Accessor.TypeEnum.SCALAR,
                    ComponentType = Accessor.ComponentTypeEnum.UNSIGNED_INT,
                    Count         = dracoGeoInfo.trianglesNum,
                    Min           = new float[] { dracoGeoInfo.trianglesMin },
                    Max           = new float[] { dracoGeoInfo.trianglesMax },
                    ByteOffset    = 0,
                };

                int idsAccessorIdx = dummy.Accessors.AddAndReturnIndex(idsAccessor);

                // Accessor Normals
                var normalsAccessor = new Accessor
                {
                    Type          = Accessor.TypeEnum.VEC3,
                    ComponentType = Accessor.ComponentTypeEnum.FLOAT,
                    Count         = dracoGeoInfo.normalsNum,
                    Min           = dracoGeoInfo.normalsMin,
                    Max           = dracoGeoInfo.normalsMax,
                    ByteOffset    = 0,
                };

                int normalsAccessorIdx = dummy.Accessors.AddAndReturnIndex(normalsAccessor);

                // Accessor TexCoords
                var texCoordsAccessor = new Accessor
                {
                    Type          = Accessor.TypeEnum.VEC2,
                    ComponentType = Accessor.ComponentTypeEnum.FLOAT,
                    Count         = dracoGeoInfo.texCoordsNum,
                    Min           = dracoGeoInfo.texCoordsMin,
                    Max           = dracoGeoInfo.texCoordsMax,
                    ByteOffset    = 0,
                };

                int texCoordsAccessorIdx = dummy.Accessors.AddAndReturnIndex(texCoordsAccessor);

                var primitive = new MeshPrimitive()
                {
                    Attributes = new Dictionary <string, int>()
                    {
                        { Constants.PositionAttributeTag, vtxAccessorIdx },
                        { Constants.NormalAttributeTag, normalsAccessorIdx },
                        { Constants.TexCoord0AttributeTag, texCoordsAccessorIdx },
                    },
                    Indices    = idsAccessorIdx,
                    Material   = materialIndex,
                    Extensions = new Dictionary <string, object>()
                    {
                        {
                            Constants.DracoMeshCompressionExtensionTag,
                            new
                            {
                                bufferView = compMeshBufferViewIdx,
                                attributes = new
                                {
                                    POSITION   = 0,
                                    NORMAL     = 1,
                                    TEXCOORD_0 = 2
                                }
                            }
                        }
                    }
                };

                // Create mesh
                primitives.Add(primitive);
            }

            var mesh = new glTFLoader.Schema.Mesh()
            {
                Primitives = primitives.ToArray(),
            };

            int meshIndex = dummy.Meshes.AddAndReturnIndex(mesh);

            var node = new Node()
            {
                Mesh = meshIndex,
            };
            int nodeIndex = dummy.Nodes.AddAndReturnIndex(node);

            dummy.Scenes[dummy.Scene].Nodes.Add(nodeIndex);
        }