static IList <GeometryObject> ImportObject(File3dm model, GeometryBase geometry, ObjectAttributes attributes, Document doc, Dictionary <string, Autodesk.Revit.DB.Material> materials, double scaleFactor)
        {
            var layer = model.AllLayers.FindIndex(attributes.LayerIndex);

            if (layer?.IsVisible ?? false)
            {
                using (var ctx = Convert.Context.Push())
                {
                    switch (attributes.MaterialSource)
                    {
                    case ObjectMaterialSource.MaterialFromObject:
                    {
                        var modelMaterial = attributes.MaterialIndex < 0 ? Rhino.DocObjects.Material.DefaultMaterial : model.AllMaterials.FindIndex(attributes.MaterialIndex);
                        ctx.MaterialId = ToHost(modelMaterial, doc, materials);
                        break;
                    }

                    case ObjectMaterialSource.MaterialFromLayer:
                    {
                        var modelLayer    = model.AllLayers.FindIndex(attributes.LayerIndex);
                        var modelMaterial = modelLayer.RenderMaterialIndex < 0 ? Rhino.DocObjects.Material.DefaultMaterial : model.AllMaterials.FindIndex(modelLayer.RenderMaterialIndex);
                        ctx.MaterialId = ToHost(modelMaterial, doc, materials);
                        break;
                    }
                    }

                    if (geometry is InstanceReferenceGeometry instance)
                    {
                        if (model.AllInstanceDefinitions.FindId(instance.ParentIdefId) is InstanceDefinitionGeometry definition)
                        {
                            var definitionId = definition.Id.ToString();
                            var library      = DirectShapeLibrary.GetDirectShapeLibrary(doc);
                            if (!library.Contains(definitionId))
                            {
                                var objectIds = definition.GetObjectIds();
                                var GNodes    = objectIds.
                                                Select(x => model.Objects.FindId(x)).
                                                Cast <File3dmObject>().
                                                SelectMany(x => ImportObject(model, x.Geometry, x.Attributes, doc, materials, scaleFactor));

                                library.AddDefinition(definitionId, GNodes.ToArray());
                            }

                            var xform = instance.Xform.ChangeUnits(scaleFactor);
                            return(DirectShape.CreateGeometryInstance(doc, definitionId, xform.ToHost()));
                        }
                    }
                    else
                    {
                        return(geometry.ToHostMultiple(scaleFactor).ToList());
                    }
                }
            }

            return(new GeometryObject[0]);
        }
        public static Result Import3DMFile(string filePath, Document doc, BuiltInCategory builtInCategory)
        {
            try
            {
                DirectShapeLibrary.GetDirectShapeLibrary(doc).Reset();

                using (var model = File3dm.Read(filePath))
                {
                    var scaleFactor = RhinoMath.UnitScale(model.Settings.ModelUnitSystem, Revit.ModelUnitSystem);

                    using (var trans = new Transaction(doc, "Import 3D Model"))
                    {
                        if (trans.Start() == TransactionStatus.Started)
                        {
                            var categoryId = new ElementId(builtInCategory);
                            var materials  = GetMaterialsByName(doc);

                            var type = DirectShapeType.Create(doc, Path.GetFileName(filePath), categoryId);

                            foreach (var obj in model.Objects.Where(x => !x.Attributes.IsInstanceDefinitionObject && x.Attributes.Space == ActiveSpace.ModelSpace))
                            {
                                if (!obj.Attributes.Visible)
                                {
                                    continue;
                                }

                                var geometryList = ImportObject(model, obj.Geometry, obj.Attributes, doc, materials, scaleFactor).ToArray();
                                if (geometryList == null)
                                {
                                    continue;
                                }

                                try { type.AppendShape(geometryList); }
                                catch (Autodesk.Revit.Exceptions.ArgumentException) { }
                            }

                            var ds = DirectShape.CreateElement(doc, type.Category.Id);
                            ds.SetTypeId(type.Id);

                            var library = DirectShapeLibrary.GetDirectShapeLibrary(doc);
                            if (!library.ContainsType(type.UniqueId))
                            {
                                library.AddDefinitionType(type.UniqueId, type.Id);
                            }

                            ds.SetShape(DirectShape.CreateGeometryInstance(doc, type.UniqueId, Autodesk.Revit.DB.Transform.Identity));

                            if (trans.Commit() == TransactionStatus.Committed)
                            {
                                var elements = new ElementId[] { ds.Id };
                                Revit.ActiveUIDocument.Selection.SetElementIds(elements);
                                Revit.ActiveUIDocument.ShowElements(elements);

                                return(Result.Succeeded);
                            }
                        }
                    }
                }
            }
            finally
            {
                DirectShapeLibrary.GetDirectShapeLibrary(doc).Reset();
            }

            return(Result.Failed);
        }
Exemple #3
0
        static IList <GeometryObject> ImportObject(File3dm model, GeometryBase geometry, ObjectAttributes attributes, Document doc, Dictionary <string, Autodesk.Revit.DB.Material> materials, double scaleFactor)
        {
            using (var ga = Convert.GraphicAttributes.Push())
            {
                switch (attributes.MaterialSource)
                {
                case ObjectMaterialSource.MaterialFromObject:
                {
                    var modelMaterial = attributes.MaterialIndex < 0 ? Rhino.DocObjects.Material.DefaultMaterial : model.AllMaterials.FindIndex(attributes.MaterialIndex);
                    ga.MaterialId = ToHost(modelMaterial, doc, materials);
                    break;
                }

                case ObjectMaterialSource.MaterialFromLayer:
                {
                    var modelLayer    = model.AllLayers.FindIndex(attributes.LayerIndex);
                    var modelMaterial = modelLayer.RenderMaterialIndex < 0 ? Rhino.DocObjects.Material.DefaultMaterial : model.AllMaterials.FindIndex(modelLayer.RenderMaterialIndex);
                    ga.MaterialId = ToHost(modelMaterial, doc, materials);
                    break;
                }
                }

                if (geometry is InstanceReferenceGeometry instance)
                {
                    if (model.AllInstanceDefinitions.FindId(instance.ParentIdefId) is InstanceDefinitionGeometry definition)
                    {
                        var objectIds = definition.GetObjectIds();

                        // Compute a definition ID that includes InstanceDefinition Name, Id and content object Ids
                        var definitionId = definition.Name;
                        {
                            var data = new byte[(objectIds.Length + 1) * 16];

                            Buffer.BlockCopy(instance.ParentIdefId.ToByteArray(), 0, data, 0, 16);
                            for (int i = 0; i < objectIds.Length; i++)
                            {
                                Buffer.BlockCopy(objectIds[i].ToByteArray(), 0, data, (i * 16), 16);
                            }

                            using (var sha256 = System.Security.Cryptography.SHA256.Create())
                                definitionId += $"[{ByteArrayToString(sha256.ComputeHash(data))}]";
                        }

                        var library = DirectShapeLibrary.GetDirectShapeLibrary(doc);
                        if (!library.Contains(definitionId))
                        {
                            var GNodes = objectIds.
                                         Select(x => model.Objects.FindId(x)).
                                         Cast <File3dmObject>().
                                         SelectMany(x => ImportObject(model, x.Geometry, x.Attributes, doc, materials, scaleFactor));

                            library.AddDefinition(definitionId, GNodes.ToArray());
                        }

                        var xform = instance.Xform;

                        xform.Affineize();
                        xform.DecomposeAffine(out Vector3d translation, out var linear);
                        xform = Rhino.Geometry.Transform.Translation(translation * scaleFactor) * linear;

                        return(DirectShape.CreateGeometryInstance(doc, definitionId, xform.ToHost()));
                    }

                    return(new GeometryObject[0]);
                }
                else
                {
                    return(geometry.ToHost(scaleFactor).ToList());
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Create geometry for a particular representation item.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="lcs">Local coordinate system for the geometry, without scale.</param>
        /// <param name="scaledLcs">Local coordinate system for the geometry, including scale, potentially non-uniform.</param>
        /// <param name="guid">The guid of an element for which represntation is being created.</param>
        protected override void CreateShapeInternal(IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid)
        {
            base.CreateShapeInternal(shapeEditScope, lcs, scaledLcs, guid);

            // Check scale; if it is uniform, create an instance.  If not, create a shape directly.
            // TODO: Instead allow creation of instances based on similar scaling.
            double scaleX      = MappingTarget.Scale;
            double scaleY      = MappingTarget.ScaleY.HasValue ? MappingTarget.ScaleY.Value : scaleX;
            double scaleZ      = MappingTarget.ScaleZ.HasValue ? MappingTarget.ScaleZ.Value : scaleX;
            bool   isUnitScale = (MathUtil.IsAlmostEqual(scaleX, 1.0) &&
                                  MathUtil.IsAlmostEqual(scaleY, 1.0) &&
                                  MathUtil.IsAlmostEqual(scaleZ, 1.0));

            Transform mappingTransform = MappingTarget.Transform;

            Transform newLcs =
                (mappingTransform == null) ? lcs : (lcs?.Multiply(mappingTransform) ?? mappingTransform);

            Transform newScaledLcs =
                (mappingTransform == null) ? scaledLcs : (scaledLcs?.Multiply(mappingTransform) ?? mappingTransform);

            bool isFootprint = (shapeEditScope.ContainingRepresentation.Identifier == IFCRepresentationIdentifier.FootPrint);

            bool canCreateType = !shapeEditScope.PreventInstances && !isFootprint && isUnitScale &&
                                 (newLcs?.IsConformal ?? true) &&
                                 (newScaledLcs?.IsConformal ?? true) &&
                                 (shapeEditScope.ContainingRepresentation != null);

            if (canCreateType)
            {
                int mappingSourceId  = MappingSource.Id;
                int geometrySourceId = FindAlternateGeometrySource(mappingSourceId);
                MappingSource.CreateShape(shapeEditScope, null, null, guid);

                if (shapeEditScope.Creator != null)
                {
                    Importer.TheProcessor.PostProcessMappedItem(shapeEditScope.Creator.Id,
                                                                shapeEditScope.Creator.GlobalId,
                                                                shapeEditScope.Creator.EntityType.ToString(),
                                                                shapeEditScope.Creator.CategoryId,
                                                                geometrySourceId,
                                                                newLcs);
                }

                // NAVIS_TODO: Figure out how not to do this.
                IList <GeometryObject> instances = DirectShape.CreateGeometryInstance(
                    shapeEditScope.Document, mappingSourceId.ToString(), newLcs);
                foreach (GeometryObject instance in instances)
                {
                    shapeEditScope.AddGeometry(IFCSolidInfo.Create(Id, instance));
                }
            }
            else
            {
                if (!isUnitScale)
                {
                    XYZ       xScale         = new XYZ(scaleX, 0.0, 0.0);
                    XYZ       yScale         = new XYZ(0.0, scaleY, 0.0);
                    XYZ       zScale         = new XYZ(0.0, 0.0, scaleZ);
                    Transform scaleTransform = Transform.Identity;
                    scaleTransform.set_Basis(0, xScale);
                    scaleTransform.set_Basis(1, yScale);
                    scaleTransform.set_Basis(2, zScale);
                    newScaledLcs = newScaledLcs.Multiply(scaleTransform);
                }

                MappingSource.CreateShape(shapeEditScope, newLcs, newScaledLcs, guid);
            }
        }
        /// <summary>
        /// Create geometry for a particular representation item.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="lcs">Local coordinate system for the geometry, without scale.</param>
        /// <param name="scaledLcs">Local coordinate system for the geometry, including scale, potentially non-uniform.</param>
        /// <param name="guid">The guid of an element for which represntation is being created.</param>
        protected override void CreateShapeInternal(IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid)
        {
            base.CreateShapeInternal(shapeEditScope, lcs, scaledLcs, guid);

            // Check scale; if it is uniform, create an instance.  If not, create a shape directly.
            // TODO: Instead allow creation of instances based on similar scaling.
            double scaleX      = MappingTarget.Scale;
            double scaleY      = MappingTarget.ScaleY.HasValue ? MappingTarget.ScaleY.Value : scaleX;
            double scaleZ      = MappingTarget.ScaleZ.HasValue ? MappingTarget.ScaleZ.Value : scaleX;
            bool   isUnitScale = (MathUtil.IsAlmostEqual(scaleX, 1.0) &&
                                  MathUtil.IsAlmostEqual(scaleY, 1.0) &&
                                  MathUtil.IsAlmostEqual(scaleZ, 1.0));

            Transform mappingTransform = MappingTarget.Transform;

            Transform newLcs = null;

            if (lcs == null)
            {
                newLcs = mappingTransform;
            }
            else if (mappingTransform == null)
            {
                newLcs = lcs;
            }
            else
            {
                newLcs = lcs.Multiply(mappingTransform);
            }

            Transform newScaledLcs = null;

            if (scaledLcs == null)
            {
                newScaledLcs = mappingTransform;
            }
            else if (mappingTransform == null)
            {
                newScaledLcs = scaledLcs;
            }
            else
            {
                newScaledLcs = scaledLcs.Multiply(mappingTransform);
            }

            // Pass in newLCS = null, use newLCS for instance.
            bool isFootprint   = (shapeEditScope.ContainingRepresentation.Identifier == IFCRepresentationIdentifier.FootPrint);
            bool canCreateType = (newLcs != null && newLcs.IsConformal) &&
                                 (newScaledLcs != null && newScaledLcs.IsConformal) &&
                                 isUnitScale &&
                                 (shapeEditScope.ContainingRepresentation != null && !isFootprint);

            if (canCreateType)
            {
                MappingSource.CreateShape(shapeEditScope, null, null, guid);
                IList <GeometryObject> instances = DirectShape.CreateGeometryInstance(shapeEditScope.Document, MappingSource.Id.ToString(), newLcs);
                foreach (GeometryObject instance in instances)
                {
                    shapeEditScope.AddGeometry(IFCSolidInfo.Create(Id, instance));
                }
            }
            else
            {
                if (!isUnitScale)
                {
                    XYZ       xScale         = new XYZ(scaleX, 0.0, 0.0);
                    XYZ       yScale         = new XYZ(0.0, scaleY, 0.0);
                    XYZ       zScale         = new XYZ(0.0, 0.0, scaleZ);
                    Transform scaleTransform = Transform.Identity;
                    scaleTransform.set_Basis(0, xScale);
                    scaleTransform.set_Basis(1, yScale);
                    scaleTransform.set_Basis(2, zScale);
                    newScaledLcs = newScaledLcs.Multiply(scaleTransform);
                }

                MappingSource.CreateShape(shapeEditScope, newLcs, newScaledLcs, guid);
            }
        }