/// <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); }
public IfcElementSignature(IfcElement elem, Xbim3DModelContext geometryContext) { XbimMatrix3D m3D = XbimMatrix3D.Identity; if (elem.ObjectPlacement != null) { m3D = elem.ObjectPlacement.ToMatrix3D(); } var geomManager = elem.ModelOf.GeometryManager; ShapeId = 0; //get the 3D shape var shapes = geometryContext.ShapeInstancesOf(elem); if (shapes.Any()) { XbimRect3D r3D = XbimRect3D.Empty; foreach (var shape in shapes) { if (r3D.IsEmpty) { r3D = shape.BoundingBox; } else { r3D.Union(shape.BoundingBox); } } XbimPoint3D p3D = r3D.Centroid(); p3D = m3D.Transform(p3D); BoundingSphereRadius = r3D.Length() / 2; CentroidX = p3D.X; CentroidY = p3D.Y; CentroidZ = p3D.Z; } //get the defining type IfcTypeObject ot = elem.GetDefiningType(); IfcMaterialSelect material = elem.GetMaterial(); //sort out property definitions List <IfcPropertySet> psets = elem.GetAllPropertySets(); PropertyCount = psets.SelectMany(p => p.HasProperties).Count(); psets.Sort(new PropertySetNameComparer()); foreach (var pset in psets) { PropertySetNamesKey ^= pset.Name.GetHashCode(); } List <IfcPropertySingleValue> props = psets.SelectMany(p => p.HasProperties).OfType <IfcPropertySingleValue>().ToList(); props.Sort(new PropertySingleValueNameComparer()); foreach (var prop in props) { PropertyNamesKey ^= prop.Name.GetHashCode(); } props.Sort(new PropertySingleValueValueComparer()); foreach (var prop in props) { PropertyValuesKey ^= prop.NominalValue.GetHashCode(); } ModelID = elem.EntityLabel; SchemaType = elem.GetType().Name; DefinedTypeId = (ot == null ? "" : ot.GlobalId.ToPart21); GlobalId = elem.GlobalId; OwningUser = elem.OwnerHistory.LastModifyingUser != null?elem.OwnerHistory.LastModifyingUser.ToString() : elem.OwnerHistory.OwningUser.ToString(); Name = elem.Name ?? ""; Description = elem.Description ?? ""; HasAssignmentsKey = elem.HasAssignments.Count(); IsDecomposedByKey = elem.IsDecomposedBy.Count(); DecomposesKey = elem.Decomposes.Count(); HasAssociationsKey = elem.HasAssociations.Count(); ObjectType = elem.ObjectType ?? ""; MaterialName = material == null ? "" : material.Name; ReferencedByKey = elem.ReferencedBy.Count(); Tag = elem.Tag ?? ""; HasStructuralMemberKey = elem.HasStructuralMember.Count(); FillsVoidsKey = elem.FillsVoids.Count(); ConnectedToKey = elem.ConnectedTo.Count(); HasCoveringsKey = elem.HasCoverings.Count(); HasProjectionsKey = elem.HasProjections.Count(); ReferencedInStructuresKey = elem.ReferencedInStructures.Count(); HasPortsKey = elem.HasPorts.Count(); HasOpeningsKey = elem.HasOpenings.Count(); IsConnectionRealizationKey = elem.IsConnectionRealization.Count(); ProvidesBoundariesKey = elem.ProvidesBoundaries.Count(); ConnectedFromKey = elem.ConnectedFrom.Count(); ContainedInStructureKey = elem.ContainedInStructure.Count(); }