public static IStepFileHeader GetStepFileHeader(Stream stream)
        {
            var parser     = new XbimP21Parser(stream, null, -1);
            var stepHeader = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty);

            parser.EntityCreate += (string name, long?label, bool header, out int[] ints) =>
            {
                //allow all attributes to be parsed
                ints = null;
                if (header)
                {
                    switch (name)
                    {
                    case "FILE_DESCRIPTION":
                        return(stepHeader.FileDescription);

                    case "FILE_NAME":
                        return(stepHeader.FileName);

                    case "FILE_SCHEMA":
                        return(stepHeader.FileSchema);

                    default:
                        return(null);
                    }
                }
                parser.Cancel = true;     //done enough
                return(null);
            };
            parser.Parse();
            stream.Close();
            return(stepHeader);
        }
        public void StepFileHeaderVersionTest()
        {
            var model  = new StepModel(new Ifc4.EntityFactoryIfc4());
            var header = new StepFileHeader(StepFileHeader.HeaderCreationMode.InitWithXbimDefaults, model);

            Assert.IsTrue(header.FileName.OriginatingSystem == model.GetType().GetTypeInfo().Assembly.GetName().Name);
            Assert.IsTrue(header.FileName.PreprocessorVersion == string.Format("Processor version {0}", model.GetType().GetTypeInfo().Assembly.GetName().Version));
        }
Exemple #3
0
 public StepModel(EntityFactoryResolverDelegate factoryResolver, ILogger logger = null, int labelFrom = 0)
 {
     Logger           = logger ?? XbimLogging.CreateLogger <StepModel>();
     _factoryResolver = factoryResolver;
     _instances       = new EntityCollection(this, labelFrom);
     IsTransactional  = true;
     Header           = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty, this);
     ModelFactors     = new XbimModelFactors(Math.PI / 180, 1e-3, 1e-5);
 }
Exemple #4
0
        private StepFileHeader ReadHeader(XmlReader input, StepFileHeader header)
        {
            var depth = input.Depth;

            while (input.Read())
            {
                if (input.NodeType == XmlNodeType.EndElement && input.Depth == depth)
                {
                    break;
                }
                if (input.NodeType != XmlNodeType.Element)
                {
                    continue;
                }

                switch (input.LocalName.ToLowerInvariant())
                {
                case "name":
                    header.FileName.Name = input.ReadInnerXml();
                    break;

                case "time_stamp":
                    header.FileName.TimeStamp = input.ReadInnerXml();
                    break;

                case "author":
                    header.FileName.AuthorName.Add(input.ReadInnerXml());
                    break;

                case "organization":
                    header.FileName.Organization.Add(input.ReadInnerXml());
                    break;

                case "preprocessor_version":
                    header.FileName.PreprocessorVersion = input.ReadInnerXml();
                    break;

                case "originating_system":
                    header.FileName.OriginatingSystem = input.ReadInnerXml();
                    break;

                case "authorization":
                    header.FileName.AuthorizationName = input.ReadInnerXml();
                    break;

                case "documentation":
                    header.FileDescription.Description.Add(input.ReadInnerXml());
                    break;
                }
            }
            return(header);
        }
Exemple #5
0
        public StepModel(IEntityFactory entityFactory, int labelFrom)
        {
            Logger = Logger ?? XbimLogging.CreateLogger<StepModel>();
            InitFromEntityFactory(entityFactory);

            _instances = new EntityCollection(this, labelFrom);

            IsTransactional = true;
            ModelFactors = new XbimModelFactors(Math.PI / 180, 1e-3, 1e-5);

            Header = new StepFileHeader(StepFileHeader.HeaderCreationMode.InitWithXbimDefaults, this);
            foreach (var schemasId in EntityFactory.SchemasIds)
                Header.FileSchema.Schemas.Add(schemasId);
        }
Exemple #6
0
        public static IStepFileHeader LoadStep21Header(Stream stream)
        {
            var header  = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty, null);
            var scanner = new XbimP21Scanner(stream, 1000);

            scanner.EntityCreate += (string name, long?label, bool inHeader) =>
            {
                if (inHeader)
                {
                    switch (name)
                    {
                    case "FILE_DESCRIPTION":
                        return(header.FileDescription);

                    case "FILE_NAME":
                        return(header.FileName);

                    case "FILE_SCHEMA":
                        if (header.FileSchema != null)
                        {
                            //set to new schema if it was set before from EntityFactory data
                            header.FileSchema = new StepFileSchema();
                        }
                        return(header.FileSchema);

                    default:
                        return(null);
                    }
                }
                else
                {
                    return(null);
                }
            };
            try
            {
                scanner.Parse(true);
            }
            catch (Exception e)
            {
                var position = scanner.CurrentPosition;
                throw new XbimParserException(string.Format("Parser failed on line {0}, column {1}", position.EndLine, position.EndColumn), e);
            }
            return(header);
        }
        public MemoryModel(IEntityFactory entityFactory, int labelFrom = 0)
        {
            if (entityFactory == null)
            {
                throw new ArgumentNullException("entityFactory");
            }

            _entityFactory = entityFactory;
            _instances     = new EntityCollection(this, labelFrom);
            Header         = new StepFileHeader(StepFileHeader.HeaderCreationMode.InitWithXbimDefaults);
            foreach (var schemasId in _instances.Factory.SchemasIds)
            {
                Header.FileSchema.Schemas.Add(schemasId);
            }
            ModelFactors    = new XbimModelFactors(Math.PI / 180, 1e-3, 1e-5);
            Metadata        = ExpressMetaData.GetMetadata(entityFactory.GetType().Module);
            IsTransactional = true;
        }
 internal IStepFileHeader ReadHeader()
 {
     if (Api.TryMoveFirst(Sesid, GlobalsTable))
     {
         var hd = Api.RetrieveColumn(Sesid, GlobalsTable, IfcHeaderColumn);
         if (hd == null)
         {
             return(null);           //there is nothing in at the moment
         }
         var br  = new BinaryReader(new MemoryStream(hd));
         var hdr = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty);
         hdr.Read(br);
         return(hdr);
     }
     else
     {
         return(null);
     }
 }
Exemple #9
0
        protected virtual int LoadStep21(XbimP21Scanner parser)
        {
            if (Header == null)
            {
                Header = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty, this);
            }

            if (EntityFactory == null && _factoryResolver == null)
            {
                throw new XbimParserException("EntityFactory is not defined and no resolver is specified to create one. Data can't be created.");
            }

            parser.EntityCreate += (string name, long?label, bool header) =>
            {
                if (header)
                {
                    switch (name)
                    {
                    case "FILE_DESCRIPTION":
                        return(Header.FileDescription);

                    case "FILE_NAME":
                        return(Header.FileName);

                    case "FILE_SCHEMA":
                        if (Header.FileSchema != null)
                        {
                            //set to new schema if it was set before from EntityFactory data
                            Header.FileSchema = new StepFileSchema();
                        }
                        return(Header.FileSchema);

                    default:
                        return(null);
                    }
                }

                if (EntityFactory == null)
                {
                    EntityFactory = _factoryResolver(Header.FileSchema.Schemas);
                    if (EntityFactory == null)
                    {
                        throw new XbimParserException($"Entity factory resolver didn't resolve factory for schema '{string.Join(", ", Header.FileSchema.Schemas)}'");
                    }
                    InitFromEntityFactory(EntityFactory);
                }

                if (label == null)
                {
                    return(EntityFactory.New(name));
                }

                var ent = EntityFactory.New(this, name, (int)label, true);

                // if entity is null do not add so that the file load operation can survive an illegal entity
                // e.g. an abstract class instantiation.
                if (ent != null)
                {
                    _instances.InternalAdd(ent);
                }
                else
                {
                    var msg = $"Error in file at label {label} for type {name}.";
                    if (Metadata.ExpressType(name).Type.GetTypeInfo().IsAbstract)
                    {
                        msg = string.Format("Illegal element in file; cannot instantiate the abstract type {0} at label {1}.", name, label);
                    }
                    Logger?.LogError(msg);
                }

                //make sure that new added entities will have higher labels to avoid any clashes
                if (label >= _instances.CurrentLabel)
                {
                    _instances.CurrentLabel = (int)label;
                }
                return(ent);
            };
            try
            {
                parser.Parse();

                //fix header with the schema if it was not a part of the data
                if (Header.FileSchema.Schemas.Count == 0)
                {
                    foreach (var s in EntityFactory.SchemasIds)
                    {
                        Header.FileSchema.Schemas.Add(s);
                    }
                }
            }
            catch (Exception e)
            {
                var position = parser.CurrentPosition;
                throw new XbimParserException(string.Format("Parser failed on line {0}, column {1}", position.EndLine, position.EndColumn), e);
            }

            // if the model is empty, having just a header, entity factory might still be empty
            if (EntityFactory == null)
            {
                EntityFactory = _factoryResolver(Header.FileSchema.Schemas);
                if (EntityFactory == null)
                {
                    throw new XbimParserException($"Entity factory resolver didn't resolve factory for schema '{string.Join(", ", Header.FileSchema.Schemas)}'");
                }
                InitFromEntityFactory(EntityFactory);
            }

            //fix case if necessary
            for (int i = 0; i < Header.FileSchema.Schemas.Count; i++)
            {
                var id = Header.FileSchema.Schemas[i];


                var sid = EntityFactory.SchemasIds.FirstOrDefault(s => id.StartsWith(s, StringComparison.OrdinalIgnoreCase));
                if (sid == null)
                {
                    //add in a bit of flexibility for old Ifc models with weird schema names
                    var old2xSchemaNamesThatAreOK = new[] { "IFC2X2_FINAL", "IFC2X2" };
                    if (old2xSchemaNamesThatAreOK.FirstOrDefault(s => string.Equals(s, id, StringComparison.OrdinalIgnoreCase)) == null)
                    {
                        throw new XbimParserException("Mismatch between schema defined in the file and schemas available in the data model.");
                    }
                    else
                    {
                        sid = EntityFactory.SchemasIds.FirstOrDefault(s => string.Equals(s, "IFC2X3", StringComparison.OrdinalIgnoreCase));
                    }
                }
                //if the case is different set it to the one from entity factory
                if (id != sid)
                {
                    Header.FileSchema.Schemas[i] = sid;
                }
            }

            return(parser.ErrorCount);
        }
        public StepFileHeader Read(Stream xmlStream)
        {
            //   using (var xmlInStream = new StreamReader(inputStream, Encoding.GetEncoding("ISO-8859-9"))) //this is a work around to ensure latin character sets are read
            using (var input = XmlReader.Create(xmlStream))
            {
                _streamSize = xmlStream.Length;

                // Read until end of file
                _idMap          = new Dictionary <string, int>();
                _lastId         = 0;
                _entitiesParsed = 0;
                var foundHeader = false;
                var header      = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty);

                //IFC2x3 was the first IFC mapped to XML so IFC version wasn't explicit. So we need to put it in to keep the data complete
                header.FileSchema.Schemas.Add("IFC2X3");
                var headerId = "";

                while (_currentNode == null && input.Read()) //read through to UOS
                {
                    switch (input.NodeType)
                    {
                    case XmlNodeType.Element:
                        if (String.Compare(input.LocalName, "uos", StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            _currentNode = new XmlUosCollection();
                        }
                        else if (
                            String.Compare(input.LocalName, "iso_10303_28", StringComparison.OrdinalIgnoreCase) ==
                            0)
                        {
                            foundHeader = true;

                            if (!string.IsNullOrWhiteSpace(input.Prefix))
                            {
                                _expressNamespace  = input.Prefix;
                                _cTypeAttribute    = _expressNamespace + ":cType";
                                _posAttribute      = _expressNamespace + ":pos";
                                _expressNamespace += ":";
                            }
                            else
                            {
                                _cTypeAttribute = "cType";
                                _posAttribute   = "pos";
                            }     //correct the values if the namespace is defined correctly
                            while (input.MoveToNextAttribute())
                            {
                                if (input.Value == "urn:oid:1.0.10303.28.2.1.1" ||
                                    input.Value ==
                                    "urn:iso.org:standard:10303:part(28):version(2):xmlschema:common")
                                {
                                    _expressNamespace  = input.LocalName;
                                    _cTypeAttribute    = _expressNamespace + ":cType";
                                    _posAttribute      = _expressNamespace + ":pos";
                                    _expressNamespace += ":";
                                    break;
                                }
                            }
                        }
                        else
                        {
                            headerId = input.LocalName.ToLower();
                        }
                        break;

                    case XmlNodeType.Text:
                        switch (headerId)
                        {
                        case "name":
                            header.FileName.Name = input.Value;
                            break;

                        case "time_stamp":
                            header.FileName.TimeStamp = input.Value;
                            break;

                        case "author":
                            header.FileName.AuthorName.Add(input.Value);
                            break;

                        case "organization":
                            header.FileName.Organization.Add(input.Value);
                            break;

                        case "preprocessor_version":
                            header.FileName.PreprocessorVersion = input.Value;
                            break;

                        case "originating_system":
                            header.FileName.OriginatingSystem = input.Value;
                            break;

                        case "authorization":
                            header.FileName.AuthorizationName = input.Value;
                            break;

                        case "documentation":
                            header.FileDescription.Description.Add(input.Value);
                            break;
                        }
                        break;
                    }
                }
                if (!foundHeader)
                {
                    throw new Exception("Invalid XML format, iso_10303_28 tag not found");
                }

                var prevInputType = XmlNodeType.None;
                var prevInputName = "";

                // set counter for start of every element that is not empty, and reduce it on every end of that element



                try
                {
                    while (input.Read())
                    {
                        if (_streamSize != -1 && ProgressStatus != null)
                        {
                            double pos           = xmlStream.Position;
                            var    newPercentage = Convert.ToInt32(pos / _streamSize * 100.0);
                            if (newPercentage > _percentageParsed)
                            {
                                ProgressStatus(_percentageParsed, "Parsing");
                                _percentageParsed = newPercentage;
                            }
                        }
                        switch (input.NodeType)
                        {
                        case XmlNodeType.Element:
                            StartElement(input);
                            break;

                        case XmlNodeType.EndElement:
                            IPersistEntity toWrite;
                            //if toWrite has a value we have completed an Ifc Entity
                            EndElement(input, prevInputType, prevInputName, out toWrite);
                            if (toWrite != null)
                            {
                                _entitiesParsed++;
                                _finish(toWrite);
                            }
                            break;

                        case XmlNodeType.Whitespace:
                            SetValue(input, prevInputType);
                            break;

                        case XmlNodeType.Text:
                            SetValue(input, prevInputType);
                            break;
                        }
                        prevInputType = input.NodeType;
                        prevInputName = input.LocalName;
                    }
                }
                catch (Exception e)
                {
                    throw new Exception(
                              String.Format("Error reading XML, Line={0}, Position={1}, Tag='{2}'",
                                            ((IXmlLineInfo)input).LineNumber, ((IXmlLineInfo)input).LinePosition, input.LocalName), e);
                }
                if (ProgressStatus != null)
                {
                    ProgressStatus(100, "Parsing");
                }
                return(header);
            }
        }
Exemple #11
0
        public StepFileHeader Read(Stream xmlStream, bool onlyHeader = false)
        {
            //   using (var xmlInStream = new StreamReader(inputStream, Encoding.GetEncoding("ISO-8859-9"))) //this is a work around to ensure Latin character sets are read

            using (var input = XmlReader.Create(xmlStream))
            {
                _streamSize = xmlStream.Length;
                _idMap      = new Dictionary <string, int>();

                var header        = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty);
                var rootElement   = true;
                var headerElement = true;
                while (input.Read())
                {
                    //skip everything except for element nodes
                    if (input.NodeType != XmlNodeType.Element)
                    {
                        continue;
                    }

                    if (rootElement)
                    {
                        ReadSchemaInHeader(input, header);
                        rootElement = false;
                        continue;
                    }

                    if (headerElement)
                    {
                        //header is the first inner node if defined (it is optional)
                        var name = input.LocalName.ToLowerInvariant();
                        if ((name == "header" || name == "iso_10303_28_header") && !input.IsEmptyElement)
                        {
                            header = ReadHeader(input, header);
                        }
                        headerElement = false;
                        continue;
                    }

                    //if this is IFC2x3 file and we only need the header we need to make sure we read schema information from "uos" element
                    if (input.LocalName == "uos")
                    {
                        ReadSchemaInHeader(input, header);
                    }

                    if (onlyHeader)
                    {
                        return(header);
                    }

                    //process all root entities in the file (that has to be IPersistEntity)
                    ReadEntity(input);
                    if (_streamSize != -1 && ProgressStatus != null)
                    {
                        double pos           = xmlStream.Position;
                        var    newPercentage = Convert.ToInt32(pos / _streamSize * 100.0);
                        if (newPercentage > _percentageParsed)
                        {
                            ProgressStatus(_percentageParsed, "Parsing");
                            _percentageParsed = newPercentage;
                        }
                    }
                }
                if (ProgressStatus != null)
                {
                    ProgressStatus(100, "Parsing");
                }
                return(header);
            }
        }
        /// <summary>
        /// Opens the model from STEP21 file.
        /// </summary>
        /// <param name="stream">Path to the file</param>
        /// <param name="streamSize"></param>
        /// <param name="progDelegate"></param>
        /// <returns>Number of errors in parsing. Always check this to be null or the model might be incomplete.</returns>
        public virtual int LoadStep21(Stream stream, long streamSize, ReportProgressDelegate progDelegate = null)
        {
            var parser = new XbimP21Parser(stream, Metadata, streamSize);

            if (progDelegate != null)
            {
                parser.ProgressStatus += progDelegate;
            }
            var first = true;

            Header = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty);
            parser.EntityCreate += (string name, long?label, bool header, out int[] ints) =>
            {
                //allow all attributes to be parsed
                ints = null;

                if (header)
                {
                    switch (name)
                    {
                    case "FILE_DESCRIPTION":
                        return(Header.FileDescription);

                    case "FILE_NAME":
                        return(Header.FileName);

                    case "FILE_SCHEMA":
                        return(Header.FileSchema);

                    default:
                        return(null);
                    }
                }

                if (label == null)
                {
                    return(_instances.Factory.New(name));
                }
                //if this is a first non-header entity header is read completely by now.
                //So we should check if the schema declared in the file is the one declared in EntityFactory
                if (first)
                {
                    first = false;
                    if (!Header.FileSchema.Schemas.All(s => _instances.Factory.SchemasIds.Contains(s)))
                    {
                        throw new Exception("Mismatch between schema defined in the file and schemas available in the data model.");
                    }
                }

                var typeId = Metadata.ExpressTypeId(name);
                var ent    = _instances.Factory.New(this, typeId, (int)label, true);

                // if entity is null do not add so that the file load operation can survive an illegal entity
                // e.g. an abstract class instantiation.
                if (ent != null)
                {
                    _instances.InternalAdd(ent);
                }
                else
                {
                    var msg = $"Error in file at label {label} for type {name}.";
                    if (Metadata.ExpressType(typeId).Type.IsAbstract)
                    {
                        msg = $"Illegal element in file; cannot instantiate the abstract type {name} at label {label}.";
                    }
                    Log.Error(msg);
                }

                //make sure that new added entities will have higher labels to avoid any clashes
                if (label >= _instances.CurrentLabel)
                {
                    _instances.CurrentLabel = (int)label;
                }
                return(ent);
            };
            parser.Parse();
            if (progDelegate != null)
            {
                parser.ProgressStatus -= progDelegate;
            }
            return(parser.ErrorCount);
        }