private void BwGenerateSap2000_DoWork(object sender, DoWorkEventArgs e) { // The first thing is to remove from the table the rows that have PL as the frame section // First of all, manipulates the data so that we can work with it in a better way HashSet <string> uniqueMaterials = new HashSet <string>(); HashSet <(string Section, string Material)> uniqueFrameSections = new HashSet <(string Section, string Material)>(); bwGenerateSap2000.ReportProgress(0, "Getting unique Materials, Profiles and Points from the Tekla Table."); int counter = 0; foreach (DataRow row in beamTable.Rows) { uniqueMaterials.Add(row.Field <string>("Material")); uniqueFrameSections.Add((row.Field <string>("Profile"), row.Field <string>("Material"))); } bwGenerateSap2000.ReportProgress(100, "Got unique Materials and Profiles."); bwGenerateSap2000.ReportProgress(0, "Opening SAP2000 Software."); // Opens a new Sap2000 empty model S2KModel.InitSingleton_NewInstance(UnitsEnum.kip_in_F, false); S2KModel.SM.NewModelBlank(false, UnitsEnum.kip_in_F); bwGenerateSap2000.ReportProgress(0, "SAP2000 Software Open."); // Adds the Materials to Sap2000 bwGenerateSap2000.ReportProgress(counter = 0, "Sending the Material Definitions to SAP2000."); Dictionary <string, string> TeklaToSapMatTranslate = new Dictionary <string, string>(); foreach (string TeklaMatName in uniqueMaterials) { string SapMatName = null; switch (TeklaMatName) { case "A500-GR.B-42": SapMatName = S2KModel.SM.MaterialMan.AddNewMaterial(MatTypeEnum.Steel, "United States", "ASTM A500", "Grade B, Fy 42 (HSS Round)"); break; case "A500-GR.B-46": SapMatName = S2KModel.SM.MaterialMan.AddNewMaterial(MatTypeEnum.Steel, "United States", "ASTM A500", "Grade B, Fy 46 (HSS Rect.)"); break; case "A36": SapMatName = S2KModel.SM.MaterialMan.AddNewMaterial(MatTypeEnum.Steel, "United States", "ASTM A36", "Grade 36"); break; case "A992": SapMatName = S2KModel.SM.MaterialMan.AddNewMaterial(MatTypeEnum.Steel, "United States", "ASTM A992", "Grade 50"); break; case "NOT_DEFINED": SapMatName = S2KModel.SM.MaterialMan.SetMaterial(MatTypeEnum.Steel, TeklaMatName); break; case "5000": SapMatName = S2KModel.SM.MaterialMan.SetMaterial(MatTypeEnum.Steel, TeklaMatName); break; case "A53-B": SapMatName = S2KModel.SM.MaterialMan.AddNewMaterial(MatTypeEnum.Steel, "United States", "ASTM A53", "Grade B"); break; case "F1554-GR.55": SapMatName = S2KModel.SM.MaterialMan.SetMaterial(MatTypeEnum.Steel, TeklaMatName); break; case "A563": SapMatName = S2KModel.SM.MaterialMan.SetMaterial(MatTypeEnum.Steel, TeklaMatName); break; case "A572-Gr 42": SapMatName = S2KModel.SM.MaterialMan.SetMaterial(MatTypeEnum.Steel, TeklaMatName); break; case "57250_CVNB": case "A572-50": case "A572-Gr 50": if (!TeklaToSapMatTranslate.Values.Contains("A572Gr50")) { SapMatName = S2KModel.SM.MaterialMan.AddNewMaterial(MatTypeEnum.Steel, "United States", "ASTM A572", "Grade 50"); } else { SapMatName = "A572Gr50"; } break; default: SapMatName = S2KModel.SM.MaterialMan.SetMaterial(MatTypeEnum.Steel, TeklaMatName); break; } TeklaToSapMatTranslate.Add(TeklaMatName, SapMatName); bwGenerateSap2000.ReportProgress(S2KStaticMethods.ProgressPercent(counter++, uniqueMaterials.Count)); } bwGenerateSap2000.ReportProgress(counter = 100, "Sent the Material Definitions to SAP2000."); // Adds the Profiles to Sap2000 bwGenerateSap2000.ReportProgress(counter = 0, "Sending the Section Definitions to SAP2000."); foreach ((string Section, string Material) in uniqueFrameSections) { bool ret = false; Regex HSSPipeTeklaRegex = new Regex(@"^HSS\d*X\d*\.\d*"); // Is it a custom I section from Tekla? if (Section.StartsWith("HI")) { // It is a custom I beam // HI406.4-25.4-25.4*609.6 string tempSectionName = Section.Replace("HI", ""); string[] chunks = tempSectionName.Split(new char[] { '-', '*' }); ret = S2KModel.SM.FrameSecMan.SetOrAddISection(Section + "_" + TeklaToSapMatTranslate[Material], TeklaToSapMatTranslate[Material], double.Parse(chunks[0]) / 25.4, double.Parse(chunks[3]) / 25.4, double.Parse(chunks[2]) / 25.4, double.Parse(chunks[1]) / 25.4, double.Parse(chunks[3]) / 25.4, double.Parse(chunks[2]) / 25.4); } else if (HSSPipeTeklaRegex.IsMatch(Section)) { ret = S2KModel.SM.FrameSecMan.ImportFrameSection(Section + "_" + TeklaToSapMatTranslate[Material], TeklaToSapMatTranslate[Material], "AISC15.pro", Section.Replace("X0.", "X.")); } else { ret = S2KModel.SM.FrameSecMan.ImportFrameSection(Section + "_" + TeklaToSapMatTranslate[Material], TeklaToSapMatTranslate[Material], "AISC15.pro", Section); } if (!ret) { bwGenerateSap2000.ReportProgress(-1, $"Could not Add Section: {Section}_{TeklaToSapMatTranslate[Material]}{Environment.NewLine}"); } bwGenerateSap2000.ReportProgress(S2KStaticMethods.ProgressPercent(counter++, uniqueFrameSections.Count)); } bwGenerateSap2000.ReportProgress(counter = 100, "Sent the Section Definitions to SAP2000."); S2KModel.SM.WindowVisible = true; // Adds the points and the frames Dictionary <Point3D, SapPoint> uniquePoints = new Dictionary <Point3D, SapPoint>(); bwGenerateSap2000.ReportProgress(counter = 0, "Sending the Points and Frames to SAP2000."); foreach (DataRow row in beamTable.Rows) { // Gets the start point string startPointStr = row.Field <string>("StartPoint"); startPointStr = startPointStr.Trim(new char[] { '(', ')' }); double[] startPointValues = (from a in startPointStr.Split(new char[] { ',' }) select Math.Round(double.Parse(a) / 25.4, 3)).ToArray(); Point3D startPoint = new Point3D(startPointValues[0], startPointValues[1], startPointValues[2]); SapPoint sapStartPoint = null; // Add to the model or get if (uniquePoints.ContainsKey(startPoint)) { sapStartPoint = uniquePoints[startPoint]; } else { sapStartPoint = S2KModel.SM.PointMan.AddByPoint3D_ReturnSapEntity(startPoint); if (sapStartPoint == null) { throw new Exception($"Point located at {startPointStr} could not be added to the Sap2000 model."); } uniquePoints.Add(startPoint, sapStartPoint); } // Gets the end point string endPointStr = row.Field <string>("endPoint"); endPointStr = endPointStr.Trim(new char[] { '(', ')' }); double[] endPointValues = (from a in endPointStr.Split(new char[] { ',' }) select Math.Round(double.Parse(a) / 25.4, 3)).ToArray(); Point3D endPoint = new Point3D(endPointValues[0], endPointValues[1], endPointValues[2]); SapPoint sapEndPoint = null; // Add to the model or get if (uniquePoints.ContainsKey(endPoint)) { sapEndPoint = uniquePoints[endPoint]; } else { sapEndPoint = S2KModel.SM.PointMan.AddByPoint3D_ReturnSapEntity(endPoint); if (sapEndPoint == null) { throw new Exception($"Point located at {endPointStr} could not be added to the Sap2000 model."); } uniquePoints.Add(endPoint, sapEndPoint); } int b = 0; b++; // Adds the frame SapFrame addedFrame = S2KModel.SM.FrameMan.AddByPoint_ReturnSapEntity(sapStartPoint, sapEndPoint, row.Field <string>("Profile") + "_" + TeklaToSapMatTranslate[row.Field <string>("Material")]); List <int> failedFrameRows = new List <int>(); // Keeps track of the failed frames if (addedFrame == null) { bwGenerateSap2000.ReportProgress(-1, $"Could not Add Frame. Table Row {beamTable.Rows.IndexOf(row)} | {row.Field<string>("Profile")} | Start: {row.Field<string>("StartPoint")} | End: {row.Field<string>("EndPoint")}{Environment.NewLine}"); } else { // the frame has been added // Attempts to rotate the frame in accordance to the angle double rotateAngle = GetRotateAngleFromTeklaString(row.Field <string>("Position")); addedFrame.SetLocalAxes(rotateAngle); } bwGenerateSap2000.ReportProgress(S2KStaticMethods.ProgressPercent(counter++, beamTable.Rows.Count)); } bwGenerateSap2000.ReportProgress(counter = 100, "Sent the Frames to SAP2000."); S2KModel.SM.ShowSapAsync(); }
private async void MatchSap2000ElementsButton_Click(object sender, RoutedEventArgs e) { this.DisableWindow(); try { Action <IProgress <ProgressData> > work = (progReporter) => { progReporter.Report(ProgressData.SetMessage("Getting all Nodes from 3DSMax.", true)); List <IINode> allNodes = MaxHelper.MaxInterface.GetAllNodesOfTheScene(); progReporter.Report(ProgressData.SetMessage("Getting all Frames From SAP2000.")); List <SapFrame> allFrames = this.sModel.FrameMan.GetAll(progReporter); progReporter.Report(ProgressData.SetMessage($"Getting group definitions [[for frame: ***]]")); for (int i = 0; i < allFrames.Count; i++) { SapFrame frame = allFrames[i]; // Touches to acquire bool a = frame.Groups != null; progReporter.Report(ProgressData.UpdateProgress(i, allFrames.Count, frame.Name)); } progReporter.Report(ProgressData.SetMessage("Creating work copy of Frame List.")); List <SapFrame> allFramesConsuming = new List <SapFrame>(allFrames); progReporter.Report(ProgressData.SetMessage("Matching 3DSMax Nodes to SAP2000 Elements. [[Current Node: ***]]")); for (int i = 0; i < allNodes.Count; i++) { IINode node = allNodes[i]; if (node.IsRootNode) { continue; } progReporter.Report(ProgressData.UpdateProgress(i, allNodes.Count, node.Name)); (double volume, Point3D center)? nodeVolumeAndCentroid = node.GetVolumeAndMassCenter(); if (nodeVolumeAndCentroid.HasValue) { // Gets closest frame SapFrame closest = allFramesConsuming.MinBy(a => a.Centroid.DistanceTo(nodeVolumeAndCentroid.Value.center)).First(); double distance = closest.Centroid.DistanceTo(nodeVolumeAndCentroid.Value.center); // Renames the 3DSMax Node node.Name = $"Frame: {closest.Name}"; } } }; // Runs the job async Task task = new Task(() => work(this.bStatusBarBindings.ProgressReporter)); task.Start(); await task; } catch (Exception ex) { S2KStaticMethods.ShowWarningMessageBox($"Could not match the 3DSMax elements to the SAP2000 elements.{Environment.NewLine}{ex.Message}"); } finally { this.bStatusBarBindings.IProgressReporter.Report(ProgressData.Reset()); this.EnableWindow(); } }