/JS.Library/SolidWorks/SWAssembly/SWAssemblyHelper.cs
C# | 510 lines | 364 code | 80 blank | 66 comment | 64 complexity | 24783080b75207a00ac10b67040badf6 MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Xml.Linq;
- using SolidWorks.Interop.sldworks;
- using SolidWorks.Interop.swconst;
- using System.Reflection;
- using System.Text.RegularExpressions;
- using System.Linq;
- namespace JS.Library.SolidWorks.SWAssembly
- {
- public struct PatternContent
- {
- public string regex;
- public string infodatatype;
- public string customproperty;
- }
- public class SWAssemblyHelper
- {
- public enum InfoType { COMPONENTTYPE, MAJORVERSION, MINORVERSION,Id,NAME,TYPE,SUBTYPE }
- public enum InfoDataType { TEXT, NUMERIC }
- public enum ComponentSelection { VISIBLE, UNSUPPRESED, ALL}
- public static List<object> RemoveSuppressed(object[] components)
- {
- List<object> cleaned = new List<object>();
- foreach(Component2 c in components)
- {
- if (!c.IsSuppressed())
- {
- cleaned.Add(c);
- }
- }
- return cleaned;
- }
- /// <summary>
- /// Receives a list with assembly components and returns a list with components that meet the
- /// requirements specified in the select parameter
- /// </summary>
- /// <param name="components"></param>
- /// <param name="select"></param>
- /// <returns></returns>
- public static List<object> SelectComponents(object[] components, ComponentSelection select)
- {
- List<object> cleaned = new List<object>();
- switch (select)
- {
- case ComponentSelection.ALL:
- return components.ToList();
- case ComponentSelection.UNSUPPRESED:
- foreach (Component2 c in components)
- {
- if (!c.IsSuppressed())
- {
- cleaned.Add(c);
- }
- }
- return cleaned;
- case ComponentSelection.VISIBLE:
- foreach (Component2 c in components)
- {
- if (!c.IsHidden(true))
- {
- cleaned.Add(c);
- }
- }
- return cleaned;
- default:
- return components.ToList();
- }
- }
- public static List<AsmComponent> GetDataFromAssemblyEntries(object[] components, XDocument config)
- {
- //List<Dictionary<InfoType, string>> allpatterns = ReadPatterns2(config);
- List<Dictionary<InfoType, PatternContent>> allpatterns = ReadPatterns2(config);
- Dictionary<string, Dictionary<InfoType, PatternContent>> allpatterns2 = ReadPatterns3(config);
- List<AsmComponent> comps = new List<AsmComponent>();
- // new 2018-08-13
- // TODO: read from config
- List<KeyValuePair<string,string>> cusPropNames = new List<KeyValuePair<string,string>>();
- cusPropNames.Add(new KeyValuePair<string,string>("subtype","ListPrtType"));
- foreach (Component2 c in components)
- {
- AsmComponent comp = GetDataFromAssemblyEntry4(allpatterns2, c,cusPropNames);
- if (comp == null)
- {
- Console.WriteLine("comp==null ", c.Name);
- continue;
- }
- if (comp != null && (comp.id.Length > 0 || comp.name.Length > 0))
- {
- if (comps.Find(x => (x.id == comp.id) && (x.majorversion == comp.majorversion) && (x.minorversion == comp.minorversion) && (x.name == comp.name)) != null)
- {
- comps.Find(x => (x.id == comp.id) && (x.majorversion == comp.majorversion) && (x.minorversion == comp.minorversion) && (x.name == comp.name)).quantity++;
- }
- else
- {
- comps.Add(comp);
- }
- }
- else
- {
- comps.Add(comp);
- }
-
- }
- return comps;
- }
- public static AsmComponent BuildAsmComponent(Dictionary<InfoType,PatternContent> infopatterns, List<string> results, string rawentrydata)
- {
- if(infopatterns.Count != results.Count)
- {
- return null;
- }
- AsmComponent ac = new AsmComponent();
- ac.rawdata = rawentrydata;
- int i = 0;
- foreach(InfoType it in infopatterns.Keys)
- {
- try
- {
- if (results[i] == null) { results[i] = ""; }
- JS.Library.Helper.Objects.SetPropertyValue(ac, it.ToString(), results[i]);
- }
- catch (Exception e)
- {
- }
- ++i;
- }
-
- return ac;
-
- }
- public static List<string> GetDataFromAssemblyEntry(Dictionary<InfoType,PatternContent> infopatterns, Component2 entry)
- {
- //throw new NotImplementedException();
- List<string> results = new List<string>();
- List<InfoType> ipkeys = infopatterns.Keys.ToList();
- foreach(InfoType it in ipkeys)
- {
- PatternContent pc;
- string pattern;
- if(infopatterns.TryGetValue(it,out pc) == true)
- {
- pattern = pc.regex;
- string result = Helper.Strings.GetFirstRegexMatch(entry.Name, pattern);
- result = FormatToType(result, pc.infodatatype);
- results.Add(result);
- }
- }
-
- return results;
- }
- public static string FormatToType(string input, string idt)
- {
- InfoDataType i;
- string allowed = "[^0123456789]";
- if(Enum.TryParse(idt,true,out i))
- {
- switch (i)
- {
- case InfoDataType.NUMERIC:
- return Regex.Replace(input, allowed, string.Empty, RegexOptions.IgnoreCase);
- case InfoDataType.TEXT:
- return input;
- }
- }
- return input;
- }
- public static AsmComponent GetDataFromAssemblyEntry2(List<Dictionary<InfoType,PatternContent>> infopatterns, Component2 entry)
- {
- List<AsmComponent> comps = new List<AsmComponent>();
- foreach (Dictionary<InfoType,PatternContent> dic in infopatterns)
- {
- // check the component type first (assembly, part, standartpart,....)
- if (dic.ContainsKey(InfoType.COMPONENTTYPE))
- {
- string comptpe;
- PatternContent pc;
- dic.TryGetValue(InfoType.COMPONENTTYPE, out pc);
- comptpe = pc.regex;
-
- if (Helper.Strings.GetFirstRegexMatch(entry.Name, comptpe) != null)
- {
- List<string> data = GetDataFromAssemblyEntry(dic, entry);
- string rawdata = entry.Name;
- AsmComponent comp = BuildAsmComponent(dic, data,rawdata);
- return comp;
- }
- }
- else
- {
- // entry is not the current componenttype, try the next one....
- continue;
- }
- }
- return null;
- }
- public static AsmComponent GetDataFromAssemblyEntry3(Dictionary<string,Dictionary<InfoType, PatternContent>> infopatterns, Component2 entry)
- {
- List<AsmComponent> comps = new List<AsmComponent>();
- foreach (KeyValuePair<string,Dictionary<InfoType,PatternContent>> dicentry in infopatterns)
- {
- Dictionary<InfoType, PatternContent> dic = dicentry.Value;
-
- // check the component type first (assembly, part, standartpart,....)
- if (dic.ContainsKey(InfoType.COMPONENTTYPE))
- {
- string comptpe;
- PatternContent pc;
- dic.TryGetValue(InfoType.COMPONENTTYPE, out pc);
- comptpe = pc.regex;
- if (Helper.Strings.GetFirstRegexMatch(entry.Name, comptpe) != null)
- {
- List<string> data = GetDataFromAssemblyEntry(dic, entry);
- string rawdata = entry.Name;
-
- AsmComponent comp = BuildAsmComponent(dic, data, rawdata);
- if (comp != null)
- {
- comp.componenttypename = dicentry.Key;
- }
- return comp;
- }
- }
- else
- {
- // entry is not the current componenttype, try the next one....
- continue;
- }
- }
- return null;
- }
- /// <summary>
- /// Reads the components properties from custom properties and from the filename as specified in config.xml
- /// </summary>
- /// <param name="infopatterns"></param>
- /// <param name="entry"></param>
- /// <param name="cusPropNames">List with key-value-pairs where the key is the target member name of the Component object, value the solidworks custom property name</param>
- /// <returns></returns>
- public static AsmComponent GetDataFromAssemblyEntry4(Dictionary<string, Dictionary<InfoType, PatternContent>> infopatterns, Component2 entry, List<KeyValuePair<string,string>> cusPropNames)
- {
- List<AsmComponent> comps = new List<AsmComponent>();
- foreach (KeyValuePair<string, Dictionary<InfoType, PatternContent>> dicentry in infopatterns)
- {
- Dictionary<InfoType, PatternContent> dic = dicentry.Value;
- // check the component type first (assembly, part, standartpart,....)
- if (dic.ContainsKey(InfoType.COMPONENTTYPE))
- {
- string comptpe;
- PatternContent pc;
- dic.TryGetValue(InfoType.COMPONENTTYPE, out pc);
- comptpe = pc.regex;
-
- if (Helper.Strings.GetFirstRegexMatch(entry.Name, comptpe) != null)
- {
- List<string> data = GetDataFromAssemblyEntry(dic, entry);
- string rawdata = entry.Name;
- AsmComponent comp = BuildAsmComponent(dic, data, rawdata);
- if (comp != null)
- {
- comp.componenttypename = dicentry.Key;
- }
- // if there is a link to a custom property, try to use it first
- // TODO 2018-08-28
- // get all solidworks custom property names
- List<string> allMemberNames = (from propConf in cusPropNames select propConf.Key).Distinct().ToList();
- List<string> allCusPropNames = (from propConf in cusPropNames select propConf.Value).Distinct().ToList();
- // get all values to the property names
- Dictionary<string, string> properties = GetCustomProperties(entry, allCusPropNames);
- if (properties != null)
- {
- List<string> allPropValues = (from propVal in properties select propVal.Value).Distinct().ToList();
- // find a member according to each found property, if there is a member-> set value
- if (comp != null && (allMemberNames.Count == allPropValues.Count))
- {
- for (int i = 0; i < allMemberNames.Count(); ++i)
- {
- JS.Library.Helper.Objects.SetPropertyValue(comp, allMemberNames[i], allPropValues[i]);
- }
- }
- }
- return comp;
- }
-
- }
- else
- {
- // entry is not the current componenttype, try the next one....
- continue;
- }
- }
- return null;
- }
- /// <summary>
- /// returns a dictionary with the custom properties where the property name is key, the custom property value is the according value
- /// if no property with specified name is found, the value will be an empty string
- /// </summary>
- /// <param name="component"></param>
- /// <param name="cusPropNames"></param>
- /// <returns></returns>
- public static Dictionary<string,string> GetCustomProperties(Component2 component, List<string> cusPropNames)
- {
- Dictionary<string, string> properties = new Dictionary<string, string>();
- try
- {
- ModelDoc2 swModel = component.GetModelDoc2();
- ModelDocExtension swModelDocExt = swModel.Extension;
- CustomPropertyManager swCustProp = swModelDocExt.CustomPropertyManager[""];
- foreach (string cusPropName in cusPropNames)
- {
- string cusPropVal;
- string cusPropValOut;
- bool status = swCustProp.Get4(cusPropName, false, out cusPropVal, out cusPropValOut);
- properties.Add(cusPropName, cusPropValOut);
- }
- }catch(Exception e)
- {
- return null;
- }
- return properties;
- }
- public List<InfoDataType> GetInfoDatatype(XDocument config)
- {
- throw new NotImplementedException();
- }
- /// <summary>
- /// Reads all desired regex patterns in the given order of the InfoType array and returns it as a dictionary whith infopattern as
- /// key and the regex pattern as value
- /// </summary>
- /// <param name="its"></param>
- /// <param name="configfilepath"></param>
- /// <returns></returns>
- public static Dictionary<InfoType,string> ReadPatterns(InfoType[] its, XDocument config)
- {
- Dictionary<InfoType, string> patternlist = new Dictionary<InfoType, string>();
- foreach (InfoType it in its)
- {
- patternlist.Add(it, ReadRegexPattern(it,config));
- }
- return patternlist;
- }
- /// <summary>
- /// Reads the regular expression patterns for the specified types from the config file.
- /// configuration file must contain the structure /Config/RegexConfig/<SolidworksTypename>/<pattern>
- /// </summary>
- /// <param name="config"></param>
- /// <returns></returns>
- public static List<Dictionary<InfoType,PatternContent>> ReadPatterns2(XDocument config)
- {
- List<Dictionary<InfoType, PatternContent>> allpatterns = new List<Dictionary<InfoType, PatternContent>>();
- // find regexconfig root element
- XElement regexroot = config.Element("Config").Element("RegexConfig");
- if (regexroot == null)
- {
- return null;
- }
- //get all descendents and add a dictionary with patterns and infotypes to the list
- foreach(XElement regexchild in regexroot.Elements())
- {
- Dictionary<InfoType, PatternContent> rchild = new Dictionary<InfoType, PatternContent>();
- foreach(XElement pattern in regexchild.Elements("pattern"))
- {
- InfoType it;
- if(Enum.TryParse(pattern.Attribute("name").Value,true, out it))
- {
- PatternContent pc;
- pc.infodatatype = pattern.Attribute("type").Value;
- pc.regex = pattern.Attribute("regex").Value;
- pc.customproperty = (pattern.Attribute("customproperty") != null) ?pattern.Attribute("customproperty").Value:"";
- rchild.Add(it, pc);
- }
-
- }
- allpatterns.Add(rchild);
- }
- return allpatterns;
- }
- /// <summary>
- /// Reads the regular expression patterns for the specified types from the config file.
- /// configuration file must contain the structure /Config/RegexConfig/<SolidworksTypename>/<pattern>
- /// </summary>
- /// <param name="config"></param>
- /// <returns></returns>
- public static Dictionary<string,Dictionary<InfoType, PatternContent>> ReadPatterns3(XDocument config)
- {
- Dictionary<string,Dictionary<InfoType, PatternContent>> allpatterns = new Dictionary<string,Dictionary<InfoType, PatternContent>>();
- // find regexconfig root element
- XElement regexroot = config.Element("Config").Element("RegexConfig");
- if (regexroot == null)
- {
- return null;
- }
- //get all descendents and add a dictionary with patterns and infotypes to the list
- foreach (XElement regexchild in regexroot.Elements())
- {
- Dictionary<InfoType, PatternContent> rchild = new Dictionary<InfoType, PatternContent>();
- foreach (XElement pattern in regexchild.Elements("pattern"))
- {
- InfoType it;
- if (Enum.TryParse(pattern.Attribute("name").Value, true, out it))
- {
- PatternContent pc;
- pc.infodatatype = pattern.Attribute("type").Value;
- pc.regex = pattern.Attribute("regex").Value;
- pc.customproperty = (pattern.Attribute("customproperty") != null) ? pattern.Attribute("customproperty").Value : "";
- rchild.Add(it, pc);
- }
- }
- string key = regexchild.Name.ToString();
- allpatterns.Add(key,rchild);
- }
- return allpatterns;
- }
- /// <summary>
- /// Reads the regex pattern according to the infotype from the config xml file
- /// </summary>
- /// <param name="infotype"></param>
- /// <returns></returns>
- public static string ReadRegexPattern(InfoType infotype, XDocument xd, string regexconfigelementname="/RegexConfig/SWAssembly")
- {
- try
- {
- // Find the xelement with attribute name == infotype and read it's "pattern" attribute's value
- XElement xe = File.Xml.GetElementByAttributeNameAndValue("name", infotype.ToString(), xd,regexconfigelementname);
- if (xe == null)
- {
- return null;
- }
- return File.Xml.GetAttributeValue(xe,"regex");
- }
- catch (Exception ex)
- {
- return null;
- }
- //throw new NotImplementedException();
-
- }
- }
-
- }