예제 #1
0
        //create group and add it into the group hierarchy (top -> down creation)
        private IfcGroup CreateGroup(string groupName, string classification, IfcGroup parentGroup)
        {
            IfcGroup group = _model.Instances.Where <IfcGroup>(g => g.Name == groupName).FirstOrDefault();

            if (group == null)
            {
                group = _model.Instances.New <IfcGroup>(g => { g.Name = groupName; g.Description = classification; });
            }

            if (parentGroup != null)
            {
                //check if it is not already child group.
                IfcGroup child = parentGroup.GetGroupedObjects <IfcGroup>().Where(g => g.Name == groupName).FirstOrDefault();
                if (child == null)
                {
                    //ad if it is not
                    parentGroup.AddObjectToGroup(group);
                }
            }

            //add to the root groups if this is root (there is no parent group)
            if (parentGroup == null)
            {
                RootGroups.Add(group);
            }

            _numCreated++;
            return(group);
        }
예제 #2
0
        /// <summary>
        /// Performs grouping based on the XML data provided.
        /// </summary>
        /// <param name="errLog">Stream for err output</param>
        /// <returns>True if grouping was successful. False otherwise.</returns>
        public bool PerformGrouping()
        {
            errLog = new StringWriter();

            if (_xmlDoc == null)
            {
                errLog.WriteLine("No input XML data.");
                return(false);
            }

            //get all group nodes
            XmlNodeList groups = _xmlDoc.GetElementsByTagName("group");

            if (groups == null || groups.Count == 0)
            {
                errLog.WriteLine("No group rules in the XML document");
                return(false);
            }

            //clear groups from elements
            ClearGroups(_rootGroup);


            //create group for all non-grouped elements
            IfcGroup noGroup = GetGroup("No group");

            if (noGroup == null)
            {
                noGroup = _model.Instances.New <IfcGroup>(gr => { gr.Name = "No group"; gr.Description = ""; });
                _rootGroup.AddObjectToGroup(noGroup);
            }
            List <IfcElement>    allElements = _model.Instances.OfType <IfcElement>().ToList();
            List <IfcTypeObject> allTypes    = _model.Instances.OfType <IfcTypeObject>().ToList();

            foreach (XmlNode group in groups)
            {
                grpName = GetName(group);
                if (String.IsNullOrEmpty(grpName))
                {
                    errLog.WriteLine("Group without name detected. All information in this group specification will be skipped.");
                    continue;
                }

                //search for the existing group with the same name (convert to upper case for the comparison) and create new group if none exists.
                IfcGroup iGroup = GetGroup(grpName);
                if (iGroup == null)
                {
                    iGroup = _model.Instances.New <IfcGroup>(gr => gr.Name = grpName);
                    _rootGroup.AddObjectToGroup(iGroup);
                }


                //process all ifc objects specified for the group
                XmlNodeList elements = ((XmlElement)group).GetElementsByTagName("element");
                foreach (XmlNode element in group)
                {
                    eName = GetName(element);
                    if (String.IsNullOrEmpty(eName))
                    {
                        errLog.WriteLine("Element without name detected in group '" + grpName + "'. This element will NOT be included in the");
                        continue;
                    }

                    //get elemType for reflection of attributes
                    IfcType ifcType;
                    if (!IfcMetaData.TryGetIfcType(eName, out ifcType))
                    {
                        continue;
                    }
                    else
                    {
                        elemType = ifcType.Type;
                    }
                    XbimQueryBuilder qBuilder = new XbimQueryBuilder(elemType);

                    //process all element attributes
                    XmlNodeList attributeGroups = ((XmlElement)element).GetElementsByTagName("attributes");
                    //there could be different grouping rules for attribute rules inside (all, none, oneOf, any)
                    foreach (XmlNode attrGroup in attributeGroups)
                    {
                        CreateAttributeCondition(qBuilder, attrGroup);
                    }

                    //process element properties
                    XmlNodeList propertyGroups = ((XmlElement)element).GetElementsByTagName("properties");
                    //there could be different grouping rules for attribute rules inside (all, none, oneOf, any)
                    foreach (XmlNode propGroup in propertyGroups)
                    {
                        CreatePropertyCondition(qBuilder, propGroup);
                    }


                    //element type processing
                    IEnumerable <IPersistIfcEntity> types = null;
                    XmlNodeList elTypeNodeList            = (element as XmlElement).GetElementsByTagName("elementType");
                    foreach (XmlNode elTypeNode in elTypeNodeList) //there should be just one 'elTypeNode'
                    {
                        XbimQueryBuilder typeQueryBuilder = null;
                        elTypeName = elTypeNode.InnerText;
                        if (string.IsNullOrEmpty(elTypeName))
                        {
                            errLog.WriteLine("Name of the element type is not specified for element of type '" + eName + "'. Element type conditions will not be applied. ");
                            continue;
                        }

                        IfcType ifcTypeLookup;
                        if (!IfcMetaData.TryGetIfcType(eName, out ifcTypeLookup))
                        {
                            continue;
                        }
                        else
                        {
                            elemType = ifcTypeLookup.Type;
                        }
                        if (!typeof(IfcTypeObject).IsAssignableFrom(elemType))
                        {
                            errLog.WriteLine("'" + elTypeName + "' is not type object.");
                            continue;
                        }

                        typeQueryBuilder = new XbimQueryBuilder(elTypeName);

                        //type attributes
                        XmlNodeList typeAttrGroups = ((XmlElement)element).GetElementsByTagName("typeAttributes");
                        foreach (XmlNode typeAttrGrpNode in typeAttrGroups)
                        {
                            CreateAttributeCondition(typeQueryBuilder, typeAttrGrpNode);
                        }

                        //process element type properties
                        XmlNodeList typePropGroups = ((XmlElement)element).GetElementsByTagName("typeProperties");
                        //there could be different grouping rules for attribute rules inside (all, none, oneOf, any)
                        foreach (XmlNode propGroup in typePropGroups)
                        {
                            CreatePropertyCondition(typeQueryBuilder, propGroup);
                        }


                        types = _model.Instances.Where <IPersistIfcEntity>(typeQueryBuilder.BuildQuery());
                        break;
                    }

                    //get elements and element type
                    IEnumerable <IPersistIfcEntity> instances = allElements.Where(qBuilder.BuildQuery().Compile()).ToList();

                    //check elements against element type (if defined)
                    if (types != null)
                    {
                        instances = FilterElementsByType(instances, types);
                    }

                    //add result to the group
                    foreach (var inst in instances)
                    {
                        IfcElement el = inst as IfcElement;
                        if (el != null && allElements.Remove(el))
                        {
                            IfcTypeObject type = el.GetDefiningType();
                            if (allTypes.Remove(type)) //ensure that it is not added twice
                            {
                                iGroup.AddObjectToGroup(type);
                            }

                            //get all elements of this type
                            IEnumerable <IfcRelDefinesByType> rels = _model.Instances.Where <IfcRelDefinesByType>(r => r.RelatingType == type);
                            foreach (var rel in rels)
                            {
                                IEnumerable <IfcElement> elemOfType = rel.RelatedObjects.OfType <IfcElement>();
                                foreach (var item in elemOfType)
                                {
                                    allElements.Remove(item);
                                }
                            }
                            //IfcObjectDefinition objDef = inst as IfcObjectDefinition;
                            //if (objDef != null) iGroup.AddObjectToGroup(objDef);
                        }
                    }
                }
            }

            //fill the no-group group with elements which are not in any group
            foreach (IfcTypeObject element in allTypes)
            {
                noGroup.AddObjectToGroup(element);
            }
            return(true);
        }