public static MappingSinglePoint Create(Point3DContainer _point_container, Component _direct_parent, TypeNode _tn, bool _as_example, out MappingError err) { // attempt a preliminary mapping of coordinates Dictionary <string, TypeNode> coords_mapping = MappingSinglePoint.PreliminaryMapping(_point_container, _direct_parent, _tn, _as_example, out err); if (err != MappingError.NONE) { return(null); } // perform actual mapping if (coords_mapping["x"] != null && coords_mapping["y"] != null && coords_mapping["z"] != null) { MappingSinglePoint msp = new MappingSinglePoint(_point_container, _direct_parent, _tn, _as_example); msp.coords_mapping = coords_mapping; _tn.MostRecentMapping = msp; return(msp); } else { err = MappingError.INSTANTIATION_OF_TYPE_IMPOSSIBLE; return(null); } }
/// <summary> /// This method accepts both a partial and a full matching. /// The matching rules are: 1. Components can match only COMPLEX TypeNodes. 2. Parameters can match only SIMPLE TypeNodes. /// 3. GeometricRelationshipscan only match a NON_BINDABLE TypeNode with exactly one SubNode of COMPLEX type. /// </summary> public static void MatchStructure(Component _comp, TypeNode _tn, ref List <KeyValuePair <string, TypeNode> > correspondencies, out MappingError err) { if (correspondencies == null) { correspondencies = new List <KeyValuePair <string, TypeNode> >(); } err = MappingError.NONE; if (_comp == null || _tn == null) { err = MappingError.MISSING_MAPPING_END; return; } if (_tn.BindingType == TypeNodeContentBindingType.NOT_BINDABLE || _tn.BindingType == TypeNodeContentBindingType.SIMPLE) { err = MappingError.COMPONENT_TO_TYPE_MISMATCH; return; } if (_tn.BindingType == TypeNodeContentBindingType.KEY) { err = MappingError.NO_MAPPING_TO_ID_ALLOWED; return; } if (correspondencies.Where(x => x.Key == MappingComponent.PREFIX_COMP + _comp.ID.ToString()).Count() > 0) { err = MappingError.ID_DUPLICATION; return; } // at least top-level matching is possible List <KeyValuePair <string, TypeNode> > new_correspondencies = new List <KeyValuePair <string, TypeNode> >(); new_correspondencies.Add(new KeyValuePair <string, TypeNode>(MappingComponent.PREFIX_COMP + _comp.ID.ToString(), _tn)); bool transferred_id = false; if (_tn.SubNodes == null || _tn.SubNodes.Count == 0) { return; } // attempt matching of structure foreach (TypeNode sN in _tn.SubNodes) { if (sN.BindingType == TypeNodeContentBindingType.SIMPLE) { // look for an existing mapping bool found_existing = false; if (sN.AllMappings != null && sN.AllMappings.Count > 0) { MappingObject mo = sN.AllMappings.FirstOrDefault(x => (x is MappingParameter) && _comp.ContainedParameters.ContainsKey((x as MappingParameter).MappedParameter.ID)); if (mo != null) { string p_key = MappingComponent.PREFIX_PARAM + (mo as MappingParameter).MappedParameter.ID.ToString(); if (!(correspondencies.Where(x => x.Key == p_key).Count() > 0) && !(new_correspondencies.Where(x => x.Key == p_key).Count() > 0)) { new_correspondencies.Add(new KeyValuePair <string, TypeNode>(p_key, sN)); } found_existing = true; } } // try to match it to a parameter if (!found_existing && _comp.ContainedParameters.Count() > 0) { Parameter p = _comp.ContainedParameters.FirstOrDefault(x => x.Value != null && MappingObject.StringsCouldMeanTheSame(x.Value.Name, sN.Label)).Value; if (p != null) { string p_key = MappingComponent.PREFIX_PARAM + p.ID.ToString(); if (!(correspondencies.Where(x => x.Key == p_key).Count() > 0) && !(new_correspondencies.Where(x => x.Key == p_key).Count() > 0)) { new_correspondencies.Add(new KeyValuePair <string, TypeNode>(p_key, sN)); } } } } else if (sN.BindingType == TypeNodeContentBindingType.NOT_BINDABLE) { // try to match it to a geometric relationship if (sN.IsEnumerable && sN.SubNodes != null && sN.SubNodes.Count == 1) { TypeNode sN_1 = sN.SubNodes[0]; if (sN_1.BindingType == TypeNodeContentBindingType.COMPLEX) { bool match_w_geometry_found = false; foreach (GeometricRelationship gr in _comp.R2GInstances) { // get the path points as identifiable containers List <HierarchicalContainer> geometry = gr.GeometricContent; if (geometry.Count == 0) { continue; } foreach (HierarchicalContainer hc in geometry) { Point3DContainer p3dc = hc as Point3DContainer; if (p3dc == null) { continue; } // CHECK IF A MAPPING IS AT ALL POSSIBLE MappingError sN_1_test_err = MappingError.NONE; MappingSinglePoint.PreliminaryMapping(p3dc, _comp, sN_1, false, out sN_1_test_err); if (sN_1_test_err != MappingError.NONE) { break; } // look for an existing mapping bool found_existing = false; if (sN_1.AllMappings != null && sN_1.AllMappings.Count > 0) { MappingObject mo = sN_1.AllMappings.FirstOrDefault(x => (x is MappingSinglePoint) && (x as MappingSinglePoint).MappedPointC.ID_primary == p3dc.ID_primary && (x as MappingSinglePoint).MappedPointC.ID_secondary == p3dc.ID_secondary); if (mo != null) { string p_key = MappingComponent.PREFIX_P3DC + (mo as MappingSinglePoint).MappedPointC.ID_primary.ToString() + "_" + (mo as MappingSinglePoint).MappedPointC.ID_secondary.ToString(); if (!(correspondencies.Where(x => x.Key == p_key).Count() > 0) && !(new_correspondencies.Where(x => x.Key == p_key).Count() > 0)) { new_correspondencies.Add(new KeyValuePair <string, TypeNode>(p_key, sN_1)); } found_existing = true; match_w_geometry_found = true; } } // try to create a new mapping if (!found_existing) { MappingError sN_1_m_err = MappingError.NONE; MappingSinglePoint.PreliminaryMapping(p3dc, _comp, sN_1, false, out sN_1_m_err); if (sN_1_m_err == MappingError.NONE) { // mapping successful string p_key = MappingComponent.PREFIX_P3DC + p3dc.ID_primary.ToString() + "_" + p3dc.ID_secondary.ToString(); if (!(correspondencies.Where(x => x.Key == p_key).Count() > 0) && !(new_correspondencies.Where(x => x.Key == p_key).Count() > 0)) { new_correspondencies.Add(new KeyValuePair <string, TypeNode>(p_key, sN_1)); } match_w_geometry_found = true; } } } } if (!match_w_geometry_found) { // try to match it to a sub-component -> RECURSION if (sN.SubNodes != null && sN.SubNodes.Count > 0) { foreach (TypeNode ssN in sN.SubNodes) { int nr_current_correspondencies = correspondencies.Count; // attempt a matching foreach (var entry in _comp.ContainedComponents) { Component sC = entry.Value; if (sC == null) { continue; } MappingError sC_err = MappingError.NONE; MappingComponent.MatchStructure(sC, ssN, ref correspondencies, out sC_err); if (sC_err == MappingError.NONE && correspondencies.Count > nr_current_correspondencies) { // success break; } } } } } } } } else if (sN.BindingType == TypeNodeContentBindingType.KEY) { // pass the ID of the component string key_id = MappingComponent.PREFIX_ID + _comp.ID.ToString(); if (!(correspondencies.Where(x => x.Key == key_id).Count() > 0) && !(new_correspondencies.Where(x => x.Key == key_id).Count() > 0)) { new_correspondencies.Add(new KeyValuePair <string, TypeNode>(key_id, sN)); transferred_id = true; } } else if (sN.BindingType == TypeNodeContentBindingType.COMPLEX) { // try to match it to a sub-component -> RECURSION if (sN.SubNodes != null && sN.SubNodes.Count > 0) { foreach (TypeNode ssN in sN.SubNodes) { int nr_current_correspondencies = correspondencies.Count; // attempt a matching foreach (var entry in _comp.ContainedComponents) { Component sC = entry.Value; if (sC == null) { continue; } MappingError sC_err = MappingError.NONE; MappingComponent.MatchStructure(sC, ssN, ref correspondencies, out sC_err); if (sC_err == MappingError.NONE && correspondencies.Count > nr_current_correspondencies) { // success break; } } } } } } if ((new_correspondencies.Count < 2) || (new_correspondencies.Count < 3 && transferred_id)) { // only a match at the highest level -> not enough -> do not add } else { // the method traverses the component from BOTTOM to TOP // the mapping is performed TOP to BOTTOM -> insert at the start for (int i = 0; i < new_correspondencies.Count; i++) { var entry = new_correspondencies[i]; correspondencies.Insert(i, new KeyValuePair <string, TypeNode>(entry.Key, entry.Value)); } } }