public InventorParameters ExtractParameters(Document doc, dynamic userParameters) { /* The resulting json will be like this: * { * "length" : { * "unit": "in", * "value": "10 in", * "values": ["5 in", "10 in", "15 in"] * }, * "width": { * "unit": "in", * "value": "20 in", * } * } */ try { var parameters = new InventorParameters(); foreach (dynamic param in userParameters) { var nominalValue = param.Expression; try { var unitType = doc.UnitsOfMeasure.GetTypeFromString(param.Units); var value = doc.UnitsOfMeasure.GetValueFromExpression(param.Expression, unitType); nominalValue = doc.UnitsOfMeasure.GetPreciseStringFromValue(value, unitType); } // not all unitTypes seem to be convertible (e.g. kTextUnits). In that case, we'll go on with param.Expression assigned before. catch (Exception e) { LogError("Can't get nominalValue for " + param.Name + ": " + e.Message); } var parameter = new InventorParameter { Unit = param.Units, Value = nominalValue, Values = param.ExpressionList?.GetExpressionList() ?? new string[0] }; parameters.Add(param.Name, parameter); } return(parameters); } catch (Exception e) { LogError("Error reading params: " + e.Message); return(null); } }
private void ProcessParameter(ParameterControlSpec spec) { if (_allowedParameters.TryGetValue(spec.ParameterName, out var knownParameter)) { var result = new InventorParameter { Label = spec.Name.Trim(), Unit = knownParameter.Unit, ReadOnly = spec.ReadOnly, Value = knownParameter.Value, Values = knownParameter.Values }; _collectedParameters.Add(spec.ParameterName, result); } }
private static void SetExpression(Parameter parameter, InventorParameter paramData, Document doc) { // using strongly typed `parameter.get_Units()` throws: // "Failed to set 'PartMaterial' parameter. Error is System.Runtime.InteropServices.COMException (0x80020003): Member not found. (Exception from HRESULT: 0x80020003 (DISP_E_MEMBERNOTFOUND))" // and using dynamic (late binding) helps. So stick with it. dynamic dynParameter = parameter; string expression = paramData.Value; if (dynParameter.Units != "Text") { // it's necessary to trim off double quote for non-text parameters if (expression.StartsWith("\"") && expression.EndsWith("\"")) { expression = expression.Substring(1, expression.Length - 2); LogTrace($"Expression normalized to '{expression}'"); } } else { // on the other hand, expression validation will fail without the double quotes for text parameters if (!expression.StartsWith("\"")) { expression = "\"" + expression; } if (!expression.EndsWith("\"")) { expression = expression + "\""; } } var docUnitsOfMeasure = doc.UnitsOfMeasure; var unitType = docUnitsOfMeasure.GetTypeFromString(dynParameter.Units); LogTrace($"Checking expression validity on update for {expression} and unit type {dynParameter.Units} / {unitType}"); if (docUnitsOfMeasure.IsExpressionValid(expression, unitType)) { // apply the expression paramData.ErrorMessage = null; dynParameter.Expression = expression; } else { LogTrace($"Expression '{expression}' invalid for unit type '{unitType}' on update attempt"); paramData.ErrorMessage = "Parameter's expression is not valid for its unit type"; } }
private static void SetExpression(Parameter parameter, InventorParameter paramData) { // using strongly typed `parameter.get_Units()` throws: // "Failed to set 'PartMaterial' parameter. Error is System.Runtime.InteropServices.COMException (0x80020003): Member not found. (Exception from HRESULT: 0x80020003 (DISP_E_MEMBERNOTFOUND))" // and using dynamic (late binding) helps. So stick with it. dynamic dynParameter = parameter; string expression = paramData.Value; if (dynParameter.Units != "Text") { // it's necessary to trim off double quote for non-text parameters if (expression.StartsWith("\"") && expression.EndsWith("\"")) { expression = expression.Substring(1, expression.Length - 2); LogTrace($"Expression normalized to '{expression}'"); } } // apply the expression dynParameter.Expression = expression; }
private InventorParameters ExtractParameters(Document doc, dynamic userParameters) { /* The resulting json will be like this: * { * "length" : { * "unit": "in", * "value": "10 in", * "values": ["5 in", "10 in", "15 in"] * }, * "width": { * "unit": "in", * "value": "20 in", * } * } */ try { var parameters = new InventorParameters(); var docUnitsOfMeasure = doc.UnitsOfMeasure; foreach (dynamic param in userParameters) { var nominalValue = param.Expression; string errorMessage = null; try { var unitType = docUnitsOfMeasure.GetTypeFromString(param.Units); LogTrace($"Checking expression validity on extraction for {param.Expression} and unit type {param.Units} / {unitType}"); if (docUnitsOfMeasure.IsExpressionValid(param.Expression, unitType)) { var value = docUnitsOfMeasure.GetValueFromExpression(param.Expression, unitType); nominalValue = docUnitsOfMeasure.GetPreciseStringFromValue(value, unitType); } else { LogTrace($"Expression '{param.Expression}' invalid for unit type '{unitType}' on extract attempt"); errorMessage = "Parameter's expression is not valid for its unit type"; } } // not all unitTypes seem to be convertible (e.g. kTextUnits). In that case, we'll go on with param.Expression assigned before. catch (Exception e) { LogError("Can't get nominalValue for " + param.Name + ": " + e.Message); } var parameter = new InventorParameter { Unit = param.Units, Value = nominalValue, Values = param.ExpressionList?.GetExpressionList() ?? new string[0], ErrorMessage = errorMessage }; parameters.Add(param.Name, parameter); } return(parameters); } catch (Exception e) { LogError("Error reading params: " + e.Message); return(null); } }
public void RunWithArguments(Document doc, NameValueMap map) { LogTrace($"RunWithArguments called with {doc.DisplayName} with {map.Count} arguments"); using (new HeartBeat()) { Parameters parameters; switch (doc.DocumentType) { case DocumentTypeEnum.kPartDocumentObject: parameters = ((PartDocument)doc).ComponentDefinition.Parameters; break; case DocumentTypeEnum.kAssemblyDocumentObject: parameters = ((AssemblyDocument)doc).ComponentDefinition.Parameters; break; default: LogError($"Unsupported document type: {doc.DocumentType}"); return; } LogTrace("Read parameters"); string paramFile = (string)map.Value["_1"]; string json = System.IO.File.ReadAllText(paramFile); LogTrace(json); var incomingParams = JsonConvert.DeserializeObject <InventorParameters>(json); bool changed = false; foreach (var pair in incomingParams) { string paramName = pair.Key; InventorParameter paramData = pair.Value; try { var userParameter = parameters[paramName]; string expression = userParameter.Expression; if (!paramData.Value.Equals(expression)) { LogTrace($"Applying '{paramData.Value}' to '{paramName}'"); SetExpression(userParameter, paramData, doc); changed = true; if (paramData.ErrorMessage != null) { // there was an invalid expression the UI will prompt the user to fix, so don't bother changing the rest of the parameters LogTrace("Skip update for the remaining parameters"); break; } } else { LogTrace($"Skipping '{paramName}'"); } } catch (Exception e) { // some parameters (maybe when parameter gets driven by iLogic rule) are throwing error on change. // so swallow the thrown error, log about it and continue LogError($"Failed to set '{paramName}' parameter. Error is {e}."); } } var paramsExtractor = new ParametersExtractor(); paramsExtractor.Extract(doc, parameters, incomingParams); } }
public void RunWithArguments(Document doc, NameValueMap map) { LogTrace($"RunWithArguments called with {doc.DisplayName} with {map.Count} arguments"); using (new HeartBeat()) { Parameters parameters; switch (doc.DocumentType) { case DocumentTypeEnum.kPartDocumentObject: parameters = ((PartDocument)doc).ComponentDefinition.Parameters; break; case DocumentTypeEnum.kAssemblyDocumentObject: parameters = ((AssemblyDocument)doc).ComponentDefinition.Parameters; break; default: LogError($"Unsupported document type: {doc.DocumentType}"); return; } LogTrace("Read parameters"); string paramFile = (string)map.Value["_1"]; string json = System.IO.File.ReadAllText(paramFile); LogTrace(json); var incomingParams = JsonConvert.DeserializeObject <InventorParameters>(json); bool changed = false; foreach (var pair in incomingParams) { string paramName = pair.Key; InventorParameter paramData = pair.Value; try { var userParameter = parameters[paramName]; string expression = userParameter.Expression; if (!paramData.Value.Equals(expression)) { LogTrace($"Applying '{paramData.Value}' to '{paramName}'"); SetExpression(userParameter, paramData); changed = true; } else { LogTrace($"Skipping '{paramName}'"); } } catch (Exception e) { // some parameters (maybe when parameter gets driven by iLogic rule) are throwing error on change. // so swallow the thrown error, log about it and continue LogError($"Failed to set '{paramName}' parameter. Error is {e}."); } } // don't do anything unless parameters really changed if (changed) { LogTrace("Updating"); doc.Update2(); LogTrace("Saving"); doc.Save2(SaveDependents: true); LogTrace("Closing"); doc.Close(true); } else { LogTrace("Update is not required."); } } }