/// <summary> /// Tests for duplicate or missing uuids. /// </summary> /// <param name="mvd">the mvdXML element to test</param> /// <returns>An enumerable of strings with failure feedback; empty if all tests are passed.</returns> public static IEnumerable <string> ReportUuidIssues(this mvdXML mvd) { // unique key violations // var dicUuidAndType = mvd.GetUuidDictionary(); var duplicatesdicUuidAndType = dicUuidAndType.Where(x => x.Value > 1); foreach (var dupe in duplicatesdicUuidAndType) { yield return($"not unique constraint violated for {dupe.Key.ReferencedType.Name} uuid: {dupe.Key.ReferencedUuid} (repeated in {dupe.Value} items)."); } // required keys violations // var fullRequired = ((IReference)mvd).AllReferences().GroupBy(x => x.Referenced) .Select(group => new { referenced = group.Key, Sources = group.Select(g => g.Referencing) }); foreach (var required in fullRequired) { if (!dicUuidAndType.ContainsKey(required.referenced)) { yield return($"referenced items missing: {required.referenced.ReferencedType.Name} uuid: {required.referenced.ReferencedUuid} does not exist."); foreach (var source in required.Sources) { yield return($"\treferencing source is: {source.GetType().Name} uuid: {source.GetUuid()}"); } } } }
private static Dictionary <MvdItemReference, int> GetUuidDictionary(this mvdXML mvd) { var ret = new Dictionary <MvdItemReference, int>(); AddDic(ret, mvd); foreach (var conceptTemplate in mvd.GetAllConceptTemplates()) { AddDic(ret, conceptTemplate); } foreach (var item in mvd.GetAllConcepts()) { AddDic(ret, item); } foreach (var item in mvd.GetAllConceptsRoots()) { AddDic(ret, item); } foreach (var item in mvd.Views) { AddDic(ret, item); foreach (var modelViewExchangeRequirement in item.ExchangeRequirements) { AddDic(ret, modelViewExchangeRequirement); } } return(ret); }
public static IEnumerable <MvdValidationResult> ValidateModel(mvdXML mvd, IModel model) { // MVD validation rules are likely to traverse inverse relations using (model.BeginEntityCaching()) using (model.BeginInverseCaching()) { var engine = new MvdEngine(mvd, model); var objects = model.Instances .OfType <IIfcObject>() .ToList(); var validated = new HashSet <int>(); foreach (var root in engine.ConceptRoots) { var applicable = objects.Where(o => root.AppliesTo(o)); foreach (var item in applicable) { validated.Add(item.EntityLabel); foreach (var concept in root.Concepts) { var passes = concept.Test(item, Concept.ConceptTestMode.Raw); yield return(new MvdValidationResult(item, concept, passes)); } } } // report all IfcObjects which were not checked foreach (var item in objects.Where(o => !validated.Contains(o.EntityLabel))) { yield return(new MvdValidationResult(item, null, ConceptTestResult.DoesNotApply)); } } }
/// <summary> /// Initialises the engine given instances of an xbim model and an mvdxml /// </summary> /// <param name="modelViewDefinition">modelviewdefinition instance that defines the validation logic</param> /// <param name="model">xbim model to be tested</param> /// <param name="forceModelSchema">sets the value for the <see cref="ForceModelSchema" /> property of the engine</param> public MvdEngine(mvdXML modelViewDefinition, IModel model, bool forceModelSchema = false) { _model = model; Mvd = modelViewDefinition; _forceModelSchema = forceModelSchema; FixReferences(); ClearCache(); }
/// <summary> /// Tests the existence of required variable names in the templates. /// </summary> /// <param name="mvd">the mvdXML element to test</param> /// <returns>An enumerable of strings with failure feedback; empty if all tests are passed.</returns> public static IEnumerable <string> ReportVariableNameIssues(this mvdXML mvd) { foreach (var concept in mvd.GetAllConcepts()) { foreach (var reportIssue in ReportVariableNameIssues(concept)) { yield return(reportIssue); } } }
public static IEnumerable <MvdValidationResult> ValidateModel(mvdXML mvd, Stream ifcStream, ILogger logger, bool forceGCCollect = false) { // load stripped down model without geometry objects using (var model = MemoryModel.OpenReadStep21(ifcStream, logger, null, ignoreTypes, false, false)) { // there is usually stuff to collect after parsing. if (forceGCCollect) { GC.Collect(); } return(ValidateModel(mvd, model).ToList()); } }
private void OpenFile(object sender, RoutedEventArgs e) { var openFile = new OpenFileDialog { Filter = @"mvdXML|*.mvdXML;*.xml" }; var res = openFile.ShowDialog(); if (!res.HasValue || res.Value != true) { return; } using (new WaitCursor()) { mvdXML mvd = null; try { var comp = mvdXML.TestCompatibility(openFile.FileName); if (comp == mvdXML.CompatibilityResult.InvalidNameSpace) { var newName = Path.GetTempFileName(); if (mvdXML.FixNamespace(openFile.FileName, newName)) { mvd = mvdXML.LoadFromFile(newName); } else { var msg = $"Attempt to fix namespace in invalid xml file [{openFile.FileName}] failed."; NotifyError(msg, null); } } else { mvd = mvdXML.LoadFromFile(openFile.FileName); } } catch (Exception ex) { var msg = $"Invalid xml file [{openFile.FileName}]."; NotifyError(msg, ex); } if (mvd == null) { return; } try { Doc = new MvdEngine(mvd, Model, AdaptSchema); } catch (Exception ex) { var msg = $"Error creating engine from valid mvdXML [{openFile.FileName}]."; NotifyError(msg, ex); } if (Doc == null) { return; } UpdateUiLists(); IsFileOpen = true; // the following are going to be inverted by the call to UnMatchedToggle and WarnToggle straight after _useAmber = false; _useBlue = false; UnMatchedToggle(null, null); WarnToggle(null, null); ColorGroupChanged(null, null); } }