616. Add Bold Tag in String

本文介绍了一种算法,用于在给定的字符串中为字典中存在的子串添加加粗标签(<b> 和 </b>)。当两个子串重叠或相邻时,该算法能正确处理它们的组合。

Given a string s and a list of strings dict, you need to add a closed pair of bold tag <b> and </b> to wrap the substrings in s that exist in dict. If two such substrings overlap, you need to wrap them together by only one pair of closed bold tag. Also, if two substrings wrapped by bold tags are consecutive, you need to combine them. 

Example 1:

Input: 
s = "abcxyz123"
dict = ["abc","123"]
Output:
"<b>abc</b>xyz<b>123</b>"

 

Example 2:

Input: 
s = "aaabbcc"
dict = ["aaa","aab","bc"]
Output:
"<b>aaabbc</b>c"
class Solution {
public:
    string addBoldTag(string s, vector<string>& dict) {
        vector<pair<int,int>> nums;
        for (string w : dict) {
            int n = w.size();
            for (int i = 0; (i = s.find(w, i)) != string::npos; i++) {
                nums.push_back({i, i + n});
            }
        }
        
        if (nums.size() == 0)
            return s;
        vector<pair<int,int>> intervals =  mergeIntervals(nums);
        
        for (auto it = intervals.rbegin(); it != intervals.rend(); it++) {
            s.insert(it->second, "</b>");
            s.insert(it->first, "<b>");
        }
        return s;
    }
private:
     vector<pair<int,int>> mergeIntervals(vector<pair<int,int>>&nums)
     {
          vector<pair<int,int>> res;
          if(nums.size()==0) return res;
          sort(nums.begin(),nums.end(),compare);
          res.push_back(nums[0]);
          for(int i = 1;i<nums.size();i++)
          {
             if(nums[i].first<=res.back().second)
                 res.back().second = max(res.back().second,nums[i].second);
             else
                 res.push_back(nums[i]);
          }
          return res;
     }
     static bool compare(pair<int,int>a,pair<int,int>b)
     {
         {return a.first==b.first?a.second<b.second:a.first<b.first;}
     }
    
    
};

 

转载于:https://www.cnblogs.com/jxr041100/p/7885830.html

Imports System.Data Imports NPOI.HSSF.UserModel Imports NPOI.SS.UserModel Imports System.Collections.Generic Partial Class MIT2_AcceptQuery Inherits System.Web.UI.Page Dim db As SqlDb = New SqlDb() Dim ds As DataSet Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load If Not IsPostBack Then Dim sql = "SELECT DISTINCT 公司編號,公司名稱 FROM MITDEVIL.料號_count" ddlDataSet(pear, sql, "公司名稱", "公司編號") End If End Sub Sub ddlDataSet(ByVal dll As DropDownList, ByVal sql As String, ByVal text As String, ByVal value As String) ds = db.FillDataSet(sql) dll.Items.Clear() dll.DataSource = ds dll.DataTextField = text dll.DataValueField = value dll.DataBind() dll.Items.Insert(0, "") End Sub Protected Sub BTN_search_Click(sender As Object, e As System.EventArgs) Handles BTN_search.Click Dim sql As String = "SELECT 驗收單號 ,驗收序號 ,驗收人員 ,CONVERT(varchar(10),資料日期,111) 資料日期 ," & _ " 廠商編號 ,廠商名稱 ,料號 ,品名規格, 數量, 價格 ,單位 ,幣別 ,備註 ,廠別 ,匯率 ,異動類型 ," & _ " CONVERT(varchar(10),異動日期 ,111) 異動日期 ,集團類別 ,Price_Copy,Money,Date_Price_Copy " & _ " FROM [MITDEVIL].[計劃異動] WHERE 1=1 " If pear.Text = "" Then System.Web.UI.ScriptManager.RegisterStartupScript(UpdatePanel1, GetType(UpdatePanel), "AjaxMsgBox", "alert('請選擇基準公司!');", True) Exit Sub Else sql = sql + " AND 公司編號='" + pear.SelectedItem.Value + "'" End If If part_number.Text <> "" Then sql = sql + " AND 料號='" + part_number.Text + "'" End If If stradate.Value <> "" Then sql = sql + " AND 資料日期 >='" + stradate.Value + "'" End If If enddate.Value <> "" Then sql = sql + " AND 資料日期 <= '" + enddate.Value + "'" End If If createdate.Value <> "" Then sql = sql + " AND convert(char(10),創建日期,111) = convert(char(10),'" + createdate.Value + "',111)" End If sql = sql + " ORDER BY 資料日期 DESC " ViewState("AcceptDT") = db.FillDataSet(sql).Tables(0) GridView1.DataSource = db.FillDataSet(sql) ViewState("sql") = sql GridView1.DataBind() End Sub Protected Sub btn_export_Click(sender As Object, e As System.EventArgs) Handles btn_export.Click Dim arr As New ArrayList Try arr.Add("驗收單號") arr.Add("驗收序號") arr.Add("驗收人員") arr.Add("資料日期") arr.Add("廠商編號") arr.Add("廠商名稱") arr.Add("料號") arr.Add("品名規格") arr.Add("數量") arr.Add("價格") arr.Add("單位") arr.Add("幣別") arr.Add("備註") arr.Add("廠別") arr.Add("匯率") arr.Add("異動類型") arr.Add("異動日期") arr.Add("集團類別") arr.Add("價格冊單價") arr.Add("價格冊幣別") arr.Add("價格冊生效日期") SaveDate(CreateExcel(db.FillDataSet(ViewState("sql")), arr), "驗收單資料.xls") Catch ex As Exception Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "MsgBox", "alert(轉檔失敗,請重試或者聯繫系統負責人');", True) ' Return End Try End Sub Private Function CreateExcel(ByVal ds As DataSet, ByVal arrs As ArrayList) As NPOI.SS.UserModel.IWorkbook Dim workbook As IWorkbook = New NPOI.HSSF.UserModel.HSSFWorkbook() Dim sheet As New ArrayList Dim sheet1 As NPOI.SS.UserModel.ISheet = workbook.CreateSheet(arrs(0)) sheet.Add(sheet1) If arrs.Count = 4 Then Dim sheet4 As NPOI.SS.UserModel.ISheet = workbook.CreateSheet(arrs(3)) sheet.Add(sheet4) End If Dim headstyle As ICellStyle = workbook.CreateCellStyle Dim headfontstyle As HSSFFont = workbook.CreateFont 'Dim textfontstyle As HSSFFont = workbook.CreateFont Dim textstyle As HSSFCellStyle = workbook.CreateCellStyle Dim textstyle2 As HSSFCellStyle = workbook.CreateCellStyle Dim textstyle3 As HSSFCellStyle = workbook.CreateCellStyle Dim textstyle4 As HSSFCellStyle = workbook.CreateCellStyle Dim formact As HSSFDataFormat = workbook.CreateDataFormat Dim arr As New ArrayList With headfontstyle .Boldweight = NPOI.SS.UserModel.FontBoldWeight.Bold End With 'With textfontstyle ' .Boldweight = NPOI.SS.UserModel.FontBoldWeight.Bold ' .Color = NPOI.SS.UserModel.FontColor.Red 'End With With headstyle .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center ' .VerticalAlignment = SS.UserModel.VerticalAlignment.Center '.WrapText = True .SetFont(headfontstyle) .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin End With With textstyle .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin End With With textstyle2 '日期格式的 .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin .DataFormat = HSSFDataFormat.GetBuiltinFormat("yyyy/MM/dd") End With With textstyle3 '數值帶千分位格式的 .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Right .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin '.DataFormat = HSSFDataFormat.GetBuiltinFormat("G/通用格式") .DataFormat = formact.GetFormat("0.00") End With With textstyle4 '數值格式的 .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Right .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin .DataFormat = formact.GetFormat("0") End With arr.Add(textstyle) arr.Add(textstyle2) arr.Add(textstyle3) arr.Add(textstyle4) '開始寫入SHEET1 '创建行 Dim row As NPOI.SS.UserModel.IRow = sheet(0).CreateRow(0) For k As Integer = 0 To arrs.Count - 1 '创建单元格 Dim cell As NPOI.SS.UserModel.ICell = row.CreateCell(k) '设置单元格值 cell.SetCellValue(arrs(k).ToString) cell.CellStyle = headstyle Next For i As Integer = 0 To ds.Tables(0).Rows.Count - 1 '创建行 row = sheet(0).CreateRow(i + 1) For j As Integer = 0 To ds.Tables(0).Columns.Count - 1 '创建单元格 Dim cell As NPOI.SS.UserModel.ICell = row.CreateCell(j) '设置单元格值 'cell.SetCellValue(ds.Tables(0).Rows(i)(field.Item(j).ToString).ToString) ' cell.CellStyle = textstyle SetCellValueByColumnType(row, j, ds.Tables(0).Rows(i)(j), ds.Tables(0).Columns(j), arr) Next Next For i As Integer = 0 To ds.Tables(0).Columns.Count - 1 sheet(0).AutoSizeColumn(i) Next Return workbook End Function Private Sub SetCellValueByColumnType(ByVal myExcelRow As NPOI.SS.UserModel.IRow, ByVal myNewCellIndex As Integer, _ ByVal myValue As Object, ByVal myDataColumn As DataColumn, ByVal arr As ArrayList) If myExcelRow Is Nothing Then Exit Sub If myNewCellIndex < 0 Then Exit Sub If myValue Is Nothing Then Exit Sub If myDataColumn Is Nothing Then Exit Sub Select Case (myDataColumn.DataType.ToString()) Case "System.String" '://字符串类型 myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) Case "System.DateTime" '://日期类型 If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToDateTime(myValue).ToShortDateString) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(1) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case "System.Boolean" '://布尔型 If Not IsDBNull(myValue) Then If Convert.ToBoolean(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue("True") Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue("False") End If End If Case "System.Int16", "System.Int32", "System.Int64" '://整型 If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToInt64(myValue)) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(3) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case "System.Byte" If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToByte(myValue)) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case "System.Decimal" '://浮点型 If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToDecimal(myValue)) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(2) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case "System.Double" If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToDouble(myValue)) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(2) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End Select End Sub Private Sub SaveDate(ByVal workbook As NPOI.SS.UserModel.IWorkbook, ByVal ExcelName As String) Dim ms As IO.MemoryStream Try '建立資料流 ms = New IO.MemoryStream() '寫入資料流 workbook.Write(ms) '在頁面輸出資料 Dim filename As String = "attachment;filename=" & HttpUtility.UrlEncode(ExcelName, Encoding.UTF8).ToString() Response.AddHeader("Content-Disposition", filename) Response.BinaryWrite(ms.ToArray()) Catch ex As Exception Finally '釋放資源 If Not ms Is Nothing Then ms.Dispose() ms.Close() End If End Try End Sub Protected Sub GridView1_PageIndexChanging(sender As Object, e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles GridView1.PageIndexChanging GridView1.PageIndex = e.NewPageIndex GridView1.DataSource = ViewState("AcceptDT") GridView1.DataBind() End Sub End Cl给gridciew1绑定一个翻页功能
06-21
private static void replaceTagWithAppendText(XWPFParagraph paragraph, String tag, DocModelText textModel) { log.info("处理标签替换: {}, 新增内容: {}", tag, textModel.getText()); // 1. 合并所有Run文本,获取完整内容(改为可修改列表,解决之前的异常) List<XWPFRun> runs = new ArrayList<>(paragraph.getRuns()); StringBuilder fullText = new StringBuilder(); for (XWPFRun run : runs) { String runText = run.getText(0); if (runText != null) { fullText.append(runText); } } String originalFullText = fullText.toString(); log.info("段落原始完整文本: [{}]", originalFullText); // 检查标签是否存在 if (!originalFullText.contains(tag)) { log.info("段落中未找到标签: {}", tag); return; } // 2. 拆分原始文本:标签前 + 标签 + 标签后 int tagStartIndex = originalFullText.indexOf(tag); int tagEndIndex = tagStartIndex + tag.length(); String textBeforeTag = originalFullText.substring(0, tagStartIndex); String textAfterTag = originalFullText.substring(tagEndIndex); // 3. 清空所有Run的文本(保留样式结构) for (XWPFRun run : runs) { run.setText("", 0); } // 4. 重新填充内容:标签前内容 + 新增内容 + 标签后内容 XWPFRun currentRun = runs.get(0); int currentRunIndex = 0; // 填充标签前的内容 if (!textBeforeTag.isEmpty()) { currentRun.setText(textBeforeTag, 0); currentRunIndex++; if (currentRunIndex < runs.size()) { currentRun = runs.get(currentRunIndex); } else { currentRun = paragraph.createRun(); // 新增:创建时取消加粗 currentRun.setBold(false); runs.add(currentRun); } } // 填充新增内容(支持换行,核心修改点) XWPFRun newContentRun = currentRun; if (currentRunIndex < runs.size()) { newContentRun = runs.get(currentRunIndex); } else { newContentRun = paragraph.createRun(); // 新增:创建时取消加粗 newContentRun.setBold(false); runs.add(newContentRun); } // 处理换行(修改为拆分后逐行处理,仅修复样式) String[] contentLines = textModel.getText().split("\n"); // 处理第一行 newContentRun.setText(contentLines[0], 0); applyNewContentStyle(newContentRun, textModel); currentRunIndex++; // 处理剩余行(仅新增这部分逻辑,修复加粗问题) for (int i = 1; i < contentLines.length; i++) { XWPFRun lineRun; if (currentRunIndex < runs.size()) { lineRun = runs.get(currentRunIndex); // 新增:复用Run时取消加粗 lineRun.setBold(false); } else { lineRun = paragraph.createRun(); // 新增:创建新Run时取消加粗 lineRun.setBold(false); runs.add(lineRun); } // 添加换行并设置内容 lineRun.addCarriageReturn(); lineRun.setText(contentLines[i], 0); applyNewContentStyle(lineRun, textModel); currentRunIndex++; } // 填充标签后的内容 if (!textAfterTag.isEmpty()) { if (currentRunIndex < runs.size()) { currentRun = runs.get(currentRunIndex); } else { currentRun = paragraph.createRun(); // 新增:创建时取消加粗 currentRun.setBold(false); runs.add(currentRun); } currentRun.setText(textAfterTag, 0); } // 5. 清理多余的空Run(避免黑边) for (int i = runs.size() - 1; i >= currentRunIndex + 1; i--) { paragraph.removeRun(i); } log.info("标签替换完成,最终内容: [{}]", textBeforeTag + textModel.getText() + textAfterTag); } 有问题
08-27
using WinFormsFont = System.Drawing.Font; using WinFormsSize = System.Drawing.Size; using WinFormsPoint = System.Drawing.Point; using WinFormsFontStyle = System.Drawing.FontStyle; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Windows.Forms; using SystemException = System.Exception; using AcadRuntimeException = Autodesk.AutoCAD.Runtime.Exception; using Point = System.Drawing.Point; using Size = System.Drawing.Size; using Label = System.Windows.Forms.Label; using AcadApplication = Autodesk.AutoCAD.ApplicationServices.Application; using WinFormsDialogResult = System.Windows.Forms.DialogResult; namespace BeamSectionPlugin { #region 参数类 public class BeamParameters { public int Thickness { get; set; } = 15; public double DefaultSlabThickness { get; set; } = 120; // 默认板厚 public BeamBottomSetting BeamBottom { get; set; } = new BeamBottomSetting(); public BeamSideSetting BeamSide { get; set; } = new BeamSideSetting(); public SlabSetting Slab { get; set; } = new SlabSetting(); } public class BeamBottomSetting { public string SecondaryMaterial { get; set; } = "木方"; public string SecondarySpec { get; set; } = "40x90"; public string SecondaryDirection { get; set; } = "横向"; public string SecondarySpacing { get; set; } = "@200"; public string PrimaryMaterial { get; set; } = "木方"; public string PrimarySpec { get; set; } = "100x100"; public string PrimaryDirection { get; set; } = "纵向"; public string PrimarySpacing { get; set; } = ""; } public class BeamSideSetting { public bool Enabled { get; set; } = false; public string SecondaryMaterial { get; set; } = "木方"; public string SecondarySpec { get; set; } = "40x90"; public string SecondaryDirection { get; set; } = "垂直"; public string SecondarySpacing { get; set; } = "@200"; public string PrimaryMaterial { get; set; } = "木方"; public string PrimarySpec { get; set; } = "100x100"; public string PrimaryLayout { get; set; } = "双拼"; public double BoltDiameter { get; set; } = 12; public double BoltStartHeight { get; set; } = 50; public double BoltSlabHeight { get; set; } = 250; public double BoltSpacing { get; set; } = 500; } public class SlabSetting { public string SecondaryMaterial { get; set; } = "木方"; public string SecondarySpec { get; set; } = "40x90"; public string SecondaryDirection { get; set; } = "横向"; public double SecondarySpacing { get; set; } = 200; public string PrimaryMaterial { get; set; } = "木方"; public string PrimarySpec { get; set; } = "100x100"; public string PrimaryDirection { get; set; } = "纵向"; public int SteelCount { get; set; } = 1; // 顶托内方钢数量 } public class SlabParams { public double Thickness { get; set; } = 120; // 默认120mm public double Offset { get; set; } = 0; // 升降板高度 } public class BeamSegment { public Point3d Start { get; set; } public Point3d End { get; set; } public double Height { get; set; } public SlabParams Slab { get; set; } public Point3d BeamTopStart { get; set; } // 梁顶起点 public Point3d BeamTopEnd { get; set; } // 梁顶终点 public Point3d SlabTopStart { get; set; } // 板顶起点 public Point3d SlabTopEnd { get; set; } // 板顶终点 } #endregion #region WinForms 窗体 public class BeamSectionForm : Form { // 材料库数据 private readonly Dictionary<string, List<string>> materialLib = new Dictionary<string, List<string>> { {"木方", new List<string>{"40x90", "50x100", "100x100"}}, {"钢管", new List<string>{"Φ48x2.5", "Φ48x2.7", "Φ48x3"}}, {"方钢", new List<string>{"40x40x1.5", "50x50x1.5", "50x100x3"}}, {"工字钢", new List<string>{"I8", "I10", "I12", "I14", "I16"}} }; // UI 控件声明 private TabControl mainTabControl; private Button btnDraw; private TextBox txtThickness; private TextBox txtDefaultSlabThickness; // 默认板厚输入框 private ComboBox cmbBeamBottomSecMaterial, cmbBeamBottomSecSpec, cmbBeamBottomSecDirection; private TextBox txtBeamBottomSecSpacing, txtBeamBottomPriSpacing; private ComboBox cmbBeamBottomPriMaterial, cmbBeamBottomPriSpec, cmbBeamBottomPriDirection; private CheckBox chkBeamSideEnabled; private ComboBox cmbBeamSideSecMaterial, cmbBeamSideSecSpec, cmbBeamSideSecDirection; private TextBox txtBeamSideSecSpacing; private ComboBox cmbBeamSidePriMaterial, cmbBeamSidePriSpec, cmbBeamSidePriLayout; private TextBox txtBoltDiameter, txtBoltStartHeight, txtBoltSlabHeight, txtBoltSpacing; private ComboBox cmbSlabSecMaterial, cmbSlabSecSpec, cmbSlabSecDirection; private TextBox txtSlabSecSpacing; private ComboBox cmbSlabPriMaterial, cmbSlabPriSpec, cmbSlabPriDirection; private TextBox txtSlabPriSteelCount; // 顶托内方钢数量 public BeamSectionForm() { InitializeComponents(); } private void InitializeComponents() { try { // 窗体设置 (更紧凑) this.Size = new WinFormsSize(650, 300); this.Text = "梁板剖面图参数设置"; this.StartPosition = FormStartPosition.CenterScreen; this.Font = new WinFormsFont("Microsoft YaHei UI", 9F); // 主选项卡 mainTabControl = new TabControl { Location = new WinFormsPoint(10, 40), Size = new WinFormsSize(620, 480), Font = new WinFormsFont("Microsoft YaHei UI", 9F) }; this.Controls.Add(mainTabControl); // 创建选项卡 CreateBeamBottomTab(); CreateSlabTab(); // 模板厚度设置 Label lblThickness = new Label { Text = "梁板统一模板厚(mm):", Location = new WinFormsPoint(20, 15), AutoSize = true }; txtThickness = new TextBox { Location = new WinFormsPoint(150, 12), Width = 50, Text = "15" }; this.Controls.Add(lblThickness); this.Controls.Add(txtThickness); // 添加默认板厚设置 Label lblDefaultSlab = new Label { Text = "默认板厚(mm):", Location = new WinFormsPoint(220, 15), AutoSize = true }; txtDefaultSlabThickness = new TextBox { Location = new WinFormsPoint(310, 12), Width = 50, Text = "120" }; this.Controls.Add(lblDefaultSlab); this.Controls.Add(txtDefaultSlabThickness); // 绘制按钮 btnDraw = new Button { Text = "开始绘制", Location = new WinFormsPoint(280, 530), Size = new WinFormsSize(100, 35), Font = new WinFormsFont("Microsoft YaHei UI", 9.75F, WinFormsFontStyle.Bold) }; btnDraw.Click += BtnDraw_Click; this.Controls.Add(btnDraw); } catch (SystemException ex) { MessageBox.Show($"窗体初始化错误: {ex.Message}\n{ex.StackTrace}", "严重错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void CreateBeamBottomTab() { try { TabPage tabBeam = new TabPage("梁下及梁侧设置"); mainTabControl.TabPages.Add(tabBeam); // 梁下次龙骨设置 GroupBox gbBeamBottomSecondary = new GroupBox { Text = "梁下次龙骨设置", Location = new Point(10, 10), Size = new Size(700, 60) }; tabBeam.Controls.Add(gbBeamBottomSecondary); int yPos = 25; AddMaterialControls(gbBeamBottomSecondary, ref yPos, out cmbBeamBottomSecMaterial, out cmbBeamBottomSecSpec, out cmbBeamBottomSecDirection, out txtBeamBottomSecSpacing, true); // 梁下主龙骨设置 GroupBox gbBeamBottomPrimary = new GroupBox { Text = "梁下主龙骨设置", Location = new Point(10, 100), Size = new Size(700, 60) }; tabBeam.Controls.Add(gbBeamBottomPrimary); yPos = 25; AddMaterialControls(gbBeamBottomPrimary, ref yPos, out cmbBeamBottomPriMaterial, out cmbBeamBottomPriSpec, out cmbBeamBottomPriDirection, out txtBeamBottomPriSpacing, true); // 梁侧设置 GroupBox gbBeamSide = new GroupBox { Text = "梁侧龙骨设置", Location = new Point(10, 180), Size = new Size(700, 150) }; tabBeam.Controls.Add(gbBeamSide); // 启用梁侧设置 chkBeamSideEnabled = new CheckBox { Text = "启用梁侧设置", Location = new Point(20, 25), Checked = false }; chkBeamSideEnabled.CheckedChanged += ChkBeamSideEnabled_CheckedChanged; gbBeamSide.Controls.Add(chkBeamSideEnabled); // 梁侧次龙骨 GroupBox gbBeamSideSecondary = new GroupBox { Text = "次龙骨", Location = new Point(20, 50), Size = new Size(660, 40) }; gbBeamSide.Controls.Add(gbBeamSideSecondary); int subYPos = 15; AddMaterialControls(gbBeamSideSecondary, ref subYPos, out cmbBeamSideSecMaterial, out cmbBeamSideSecSpec, out cmbBeamSideSecDirection, out txtBeamSideSecSpacing, true); // 梁侧主龙骨 (移除间距输入框) GroupBox gbBeamSidePrimary = new GroupBox { Text = "主龙骨", Location = new Point(20, 100), Size = new Size(660, 40) }; gbBeamSide.Controls.Add(gbBeamSidePrimary); subYPos = 15; // 材料选择 Label lblPriMaterial = new Label { Text = "材料:", Location = new Point(20, subYPos), AutoSize = true }; gbBeamSidePrimary.Controls.Add(lblPriMaterial); cmbBeamSidePriMaterial = new ComboBox { Location = new Point(60, subYPos), Width = 80, DropDownStyle = ComboBoxStyle.DropDownList }; cmbBeamSidePriMaterial.Items.AddRange(new object[] { "木方", "钢管", "方钢", "工字钢" }); cmbBeamSidePriMaterial.SelectedIndex = 0; cmbBeamSidePriMaterial.SelectedIndexChanged += Material_SelectedIndexChanged; gbBeamSidePrimary.Controls.Add(cmbBeamSidePriMaterial); // 规格选择 Label lblPriSpec = new Label { Text = "规格:", Location = new Point(150, subYPos), AutoSize = true }; gbBeamSidePrimary.Controls.Add(lblPriSpec); cmbBeamSidePriSpec = new ComboBox { Location = new Point(190, subYPos), Width = 80 }; UpdateSpecOptions(cmbBeamSidePriMaterial, cmbBeamSidePriSpec); gbBeamSidePrimary.Controls.Add(cmbBeamSidePriSpec); // 布置方式 Label lblPriLayout = new Label { Text = "布置方式:", Location = new Point(300, subYPos), AutoSize = true }; gbBeamSidePrimary.Controls.Add(lblPriLayout); cmbBeamSidePriLayout = new ComboBox { Location = new Point(370, subYPos), Width = 80 }; cmbBeamSidePriLayout.Items.AddRange(new object[] { "双拼", "单根" }); cmbBeamSidePriLayout.SelectedIndex = 0; gbBeamSidePrimary.Controls.Add(cmbBeamSidePriLayout); // 对拉螺栓设置 GroupBox gbBolts = new GroupBox { Text = "对拉螺栓设置", Location = new Point(10, 350), Size = new Size(700, 80) }; tabBeam.Controls.Add(gbBolts); // 螺栓参数 int xPos = 20; int yBoltPos = 25; AddBoltControl(gbBolts, "螺栓直径(mm):", ref xPos, yBoltPos, out txtBoltDiameter, "12"); AddBoltControl(gbBolts, "底部距梁底高(mm):", ref xPos, yBoltPos, out txtBoltStartHeight, "50"); xPos = 20; yBoltPos = 55; AddBoltControl(gbBolts, "板底距螺栓高(mm):", ref xPos, yBoltPos, out txtBoltSlabHeight, "250"); AddBoltControl(gbBolts, "螺栓间距(mm):", ref xPos, yBoltPos, out txtBoltSpacing, "500"); } catch (SystemException ex) { MessageBox.Show($"创建梁下选项卡错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void CreateSlabTab() { try { TabPage tabSlab = new TabPage("板下设置"); mainTabControl.TabPages.Add(tabSlab); // 板下次龙骨设置 GroupBox gbSlabSecondary = new GroupBox { Text = "板下次龙骨设置", Location = new Point(10, 20), Size = new Size(700, 100) }; tabSlab.Controls.Add(gbSlabSecondary); int yPos = 25; AddMaterialControls(gbSlabSecondary, ref yPos, out cmbSlabSecMaterial, out cmbSlabSecSpec, out cmbSlabSecDirection, out txtSlabSecSpacing, true); // 板下主龙骨设置 (修改为顶托内方钢数量) GroupBox gbSlabPrimary = new GroupBox { Text = "板下主龙骨设置", Location = new Point(10, 130), Size = new Size(700, 100) }; tabSlab.Controls.Add(gbSlabPrimary); yPos = 25; // 材料选择 Label lblPriMaterial = new Label { Text = "材料:", Location = new Point(20, yPos), AutoSize = true }; gbSlabPrimary.Controls.Add(lblPriMaterial); cmbSlabPriMaterial = new ComboBox { Location = new Point(60, yPos), Width = 80, DropDownStyle = ComboBoxStyle.DropDownList }; cmbSlabPriMaterial.Items.AddRange(new object[] { "木方", "钢管", "方钢", "工字钢" }); cmbSlabPriMaterial.SelectedIndex = 0; cmbSlabPriMaterial.SelectedIndexChanged += Material_SelectedIndexChanged; gbSlabPrimary.Controls.Add(cmbSlabPriMaterial); // 规格选择 Label lblPriSpec = new Label { Text = "规格:", Location = new Point(150, yPos), AutoSize = true }; gbSlabPrimary.Controls.Add(lblPriSpec); cmbSlabPriSpec = new ComboBox { Location = new Point(190, yPos), Width = 80 }; UpdateSpecOptions(cmbSlabPriMaterial, cmbSlabPriSpec); gbSlabPrimary.Controls.Add(cmbSlabPriSpec); // 布置方向 Label lblDirection = new Label { Text = "布置方向:", Location = new Point(280, yPos), AutoSize = true }; gbSlabPrimary.Controls.Add(lblDirection); cmbSlabPriDirection = new ComboBox { Location = new Point(350, yPos), Width = 70 }; cmbSlabPriDirection.Items.AddRange(new object[] { "横向", "纵向", "垂直" }); cmbSlabPriDirection.SelectedIndex = 0; gbSlabPrimary.Controls.Add(cmbSlabPriDirection); // 顶托内方钢数量 (修改后的字段) Label lblSteelCount = new Label { Text = "顶托方钢数量:", Location = new Point(450, yPos), AutoSize = true }; gbSlabPrimary.Controls.Add(lblSteelCount); txtSlabPriSteelCount = new TextBox { Location = new Point(540, yPos), Width = 40, Text = "1" }; gbSlabPrimary.Controls.Add(txtSlabPriSteelCount); // 根据方向更新控件状态 - 修改为纵向时启用 cmbSlabPriDirection.SelectedIndexChanged += (s, e) => { string direction = cmbSlabPriDirection.SelectedItem?.ToString() ?? ""; bool isLongitudinal = direction == "纵向"; txtSlabPriSteelCount.Enabled = isLongitudinal; txtSlabPriSteelCount.BackColor = isLongitudinal ? SystemColors.Window : SystemColors.Control; }; // 初始状态 txtSlabPriSteelCount.Enabled = (cmbSlabPriDirection.SelectedItem?.ToString() == "纵向"); } catch (SystemException ex) { MessageBox.Show($"创建板下选项卡错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void AddMaterialControls(Control parent, ref int yPos, out ComboBox cmbMaterial, out ComboBox cmbSpec, out ComboBox cmbDirection, out TextBox txtSpacing, bool includeSpacing) { cmbMaterial = null; cmbSpec = null; cmbDirection = null; txtSpacing = null; try { // 材料选择 Label lblMaterial = new Label { Text = "材料:", Location = new Point(20, yPos), AutoSize = true }; parent.Controls.Add(lblMaterial); cmbMaterial = new ComboBox { Location = new Point(60, yPos), Width = 80, DropDownStyle = ComboBoxStyle.DropDownList }; cmbMaterial.Items.AddRange(new object[] { "木方", "钢管", "方钢", "工字钢" }); cmbMaterial.SelectedIndex = 0; cmbMaterial.SelectedIndexChanged += Material_SelectedIndexChanged; parent.Controls.Add(cmbMaterial); // 规格选择 Label lblSpec = new Label { Text = "规格:", Location = new Point(150, yPos), AutoSize = true }; parent.Controls.Add(lblSpec); cmbSpec = new ComboBox { Location = new Point(190, yPos), Width = 80 }; UpdateSpecOptions(cmbMaterial, cmbSpec); parent.Controls.Add(cmbSpec); // 布置方向 Label lblDirection = new Label { Text = "布置方向:", Location = new Point(300, yPos), AutoSize = true }; parent.Controls.Add(lblDirection); cmbDirection = new ComboBox { Location = new Point(370, yPos), Width = 80 }; cmbDirection.Items.AddRange(new object[] { "横向", "纵向", "垂直" }); cmbDirection.SelectedIndex = 0; parent.Controls.Add(cmbDirection); // 间距设置 if (includeSpacing) { Label lblSpacing = new Label { Text = "间距:", Location = new Point(460, yPos), AutoSize = true }; parent.Controls.Add(lblSpacing); txtSpacing = new TextBox { Location = new Point(500, yPos), Width = 70, Tag = parent.Text }; parent.Controls.Add(txtSpacing); // 使用局部变量解决闭包问题 var localCmbDirection = cmbDirection; var localTxtSpacing = txtSpacing; var localLblSpacing = lblSpacing; // 订阅方向改变事件 - 修改为纵向时启用 cmbDirection.SelectedIndexChanged += (s, e) => { UpdateDirectionControls(localCmbDirection, localTxtSpacing, localLblSpacing, parent.Text); }; // 初始化时更新控件状态 UpdateDirectionControls(cmbDirection, txtSpacing, lblSpacing, parent.Text); } yPos += 30; } catch (SystemException ex) { MessageBox.Show($"添加材料控件错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } // 关键修改:纵向时启用间距输入 private void UpdateDirectionControls(ComboBox cmbDirection, TextBox txtSpacing, Label lblSpacing, string parentText) { if (cmbDirection == null || txtSpacing == null || lblSpacing == null) return; string direction = cmbDirection.SelectedItem?.ToString() ?? ""; bool isLongitudinal = direction == "纵向"; // 修改为纵向时启用 // 规则:只有纵向方向启用间距输入 txtSpacing.Enabled = isLongitudinal; txtSpacing.BackColor = isLongitudinal ? SystemColors.Window : SystemColors.Control; lblSpacing.Enabled = isLongitudinal; } private void AddBoltControl(Control parent, string label, ref int xPos, int yPos, out TextBox textBox, string defaultValue) { textBox = new TextBox(); try { Label lbl = new Label { Text = label, Location = new Point(xPos, yPos), AutoSize = true }; parent.Controls.Add(lbl); textBox = new TextBox { Location = new Point(xPos + lbl.Width + 5, yPos), Width = 80, Text = defaultValue }; parent.Controls.Add(textBox); xPos += lbl.Width + 90; } catch (SystemException ex) { MessageBox.Show($"添加螺栓控件错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void Material_SelectedIndexChanged(object sender, EventArgs e) { try { ComboBox cmbMaterial = sender as ComboBox; if (cmbMaterial == null) return; foreach (Control ctrl in cmbMaterial.Parent.Controls) { if (ctrl is ComboBox cmbSpec && ctrl != cmbMaterial && ctrl.Location.Y == cmbMaterial.Location.Y) { UpdateSpecOptions(cmbMaterial, cmbSpec); break; } } } catch (SystemException ex) { MessageBox.Show($"材料选择变更错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void UpdateSpecOptions(ComboBox cmbMaterial, ComboBox cmbSpec) { try { if (cmbMaterial?.SelectedItem == null) return; var material = cmbMaterial.SelectedItem.ToString(); if (cmbSpec == null) return; cmbSpec.Items.Clear(); if (materialLib.ContainsKey(material)) { cmbSpec.Items.AddRange(materialLib[material].ToArray()); if (cmbSpec.Items.Count > 0) cmbSpec.SelectedIndex = 0; } } catch (SystemException ex) { MessageBox.Show($"更新规格选项错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void ChkBeamSideEnabled_CheckedChanged(object sender, EventArgs e) { try { bool enabled = chkBeamSideEnabled.Checked; // 启用/禁用所有梁侧控件 cmbBeamSideSecMaterial.Enabled = enabled; cmbBeamSideSecSpec.Enabled = enabled; cmbBeamSideSecDirection.Enabled = enabled; txtBeamSideSecSpacing.Enabled = enabled; cmbBeamSidePriMaterial.Enabled = enabled; cmbBeamSidePriSpec.Enabled = enabled; cmbBeamSidePriLayout.Enabled = enabled; txtBoltDiameter.Enabled = enabled; txtBoltStartHeight.Enabled = enabled; txtBoltSlabHeight.Enabled = enabled; txtBoltSpacing.Enabled = enabled; } catch (SystemException ex) { MessageBox.Show($"梁侧启用状态变更错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void BtnDraw_Click(object sender, EventArgs e) { try { if (!ValidateInputs()) { MessageBox.Show("请填写所有必填参数", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } this.DialogResult = WinFormsDialogResult.OK; this.Close(); } catch (SystemException ex) { MessageBox.Show($"按钮点击错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private bool ValidateInputs() { try { // 验证模板厚度 if (string.IsNullOrEmpty(txtThickness.Text) || !int.TryParse(txtThickness.Text, out _)) return false; // 验证默认板厚 if (string.IsNullOrEmpty(txtDefaultSlabThickness.Text) || !double.TryParse(txtDefaultSlabThickness.Text, out _)) return false; // 验证梁下次龙骨 - 修改为纵向时验证 if (cmbBeamBottomSecDirection.SelectedItem?.ToString() == "纵向" && string.IsNullOrEmpty(txtBeamBottomSecSpacing.Text)) return false; // 验证梁下主龙骨 - 修改为纵向时验证 string beamBottomPriDirection = cmbBeamBottomPriDirection?.SelectedItem?.ToString(); if (beamBottomPriDirection == "纵向" && (string.IsNullOrEmpty(txtBeamBottomPriSpacing.Text) || !double.TryParse(txtBeamBottomPriSpacing.Text, out _))) return false; // 验证梁侧设置 if (chkBeamSideEnabled.Checked) { // 梁侧次龙骨 - 修改为纵向时验证 if (cmbBeamSideSecDirection.SelectedItem?.ToString() == "纵向" && string.IsNullOrEmpty(txtBeamSideSecSpacing.Text)) return false; if (!double.TryParse(txtBoltDiameter.Text, out _) || !double.TryParse(txtBoltStartHeight.Text, out _) || !double.TryParse(txtBoltSlabHeight.Text, out _) || !double.TryParse(txtBoltSpacing.Text, out _)) return false; } // 验证板下次龙骨 - 修改为纵向时验证 if (cmbSlabSecDirection.SelectedItem?.ToString() == "纵向" && !double.TryParse(txtSlabSecSpacing.Text, out _)) return false; // 验证板下主龙骨 string slabPriDirection = cmbSlabPriDirection?.SelectedItem?.ToString(); if (slabPriDirection == "纵向" && (string.IsNullOrEmpty(txtSlabPriSteelCount.Text) || !int.TryParse(txtSlabPriSteelCount.Text, out _))) return false; return true; } catch (SystemException ex) { MessageBox.Show($"输入验证错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } } public BeamParameters GetParameters() { try { return new BeamParameters { Thickness = int.TryParse(txtThickness.Text, out int thick) ? thick : 15, DefaultSlabThickness = double.TryParse(txtDefaultSlabThickness.Text, out double slabThick) ? slabThick : 120, BeamBottom = new BeamBottomSetting { SecondaryMaterial = cmbBeamBottomSecMaterial?.SelectedItem?.ToString() ?? "木方", SecondarySpec = cmbBeamBottomSecSpec?.SelectedItem?.ToString() ?? "40x90", SecondaryDirection = cmbBeamBottomSecDirection?.SelectedItem?.ToString() ?? "横向", SecondarySpacing = txtBeamBottomSecSpacing?.Text ?? "@200", PrimaryMaterial = cmbBeamBottomPriMaterial?.SelectedItem?.ToString() ?? "木方", PrimarySpec = cmbBeamBottomPriSpec?.SelectedItem?.ToString() ?? "100x100", PrimaryDirection = cmbBeamBottomPriDirection?.SelectedItem?.ToString() ?? "纵向", PrimarySpacing = txtBeamBottomPriSpacing?.Text ?? "" }, BeamSide = new BeamSideSetting { Enabled = chkBeamSideEnabled.Checked, SecondaryMaterial = cmbBeamSideSecMaterial?.SelectedItem?.ToString() ?? "木方", SecondarySpec = cmbBeamSideSecSpec?.SelectedItem?.ToString() ?? "40x90", SecondaryDirection = cmbBeamSideSecDirection?.SelectedItem?.ToString() ?? "垂直", SecondarySpacing = txtBeamSideSecSpacing?.Text ?? "@200", PrimaryMaterial = cmbBeamSidePriMaterial?.SelectedItem?.ToString() ?? "木方", PrimarySpec = cmbBeamSidePriSpec?.SelectedItem?.ToString() ?? "100x100", PrimaryLayout = cmbBeamSidePriLayout?.SelectedItem?.ToString() ?? "双拼", BoltDiameter = double.TryParse(txtBoltDiameter.Text, out double boltDia) ? boltDia : 12, BoltStartHeight = double.TryParse(txtBoltStartHeight.Text, out double boltStart) ? boltStart : 50, BoltSlabHeight = double.TryParse(txtBoltSlabHeight.Text, out double boltSlab) ? boltSlab : 250, BoltSpacing = double.TryParse(txtBoltSpacing.Text, out double boltSpace) ? boltSpace : 500 }, Slab = new SlabSetting { SecondaryMaterial = cmbSlabSecMaterial?.SelectedItem?.ToString() ?? "木方", SecondarySpec = cmbSlabSecSpec?.SelectedItem?.ToString() ?? "40x90", SecondaryDirection = cmbSlabSecDirection?.SelectedItem?.ToString() ?? "横向", SecondarySpacing = double.TryParse(txtSlabSecSpacing.Text, out double secSpacing) ? secSpacing : 200, PrimaryMaterial = cmbSlabPriMaterial?.SelectedItem?.ToString() ?? "木方", PrimarySpec = cmbSlabPriSpec?.SelectedItem?.ToString() ?? "100x100", PrimaryDirection = cmbSlabPriDirection?.SelectedItem?.ToString() ?? "纵向", SteelCount = int.TryParse(txtSlabPriSteelCount.Text, out int steelCount) ? steelCount : 1 } }; } catch (SystemException ex) { MessageBox.Show($"获取参数错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return new BeamParameters(); } } } #endregion #region AutoCAD 命令 public class BeamSectionCommands { [CommandMethod("DB")] public static void DrawBeamSection() { try { var doc = AcadApplication.DocumentManager.MdiActiveDocument; if (doc == null) { AcadApplication.ShowAlertDialog("没有活动文档!"); return; } var db = doc.Database; var ed = doc.Editor; using (var form = new BeamSectionForm()) { var res = AcadApplication.ShowModalDialog(form); if (res != WinFormsDialogResult.OK) { ed.WriteMessage("\n用户取消操作。"); return; } // 获取参数 var parameters = form.GetParameters(); // 开始连续绘制 DrawContinuousBeamSections(ed, db, parameters); } } catch (SystemException ex) { var doc = AcadApplication.DocumentManager.MdiActiveDocument; if (doc != null) { var ed = doc.Editor; ed.WriteMessage($"\n严重错误: {ex.Message}\n{ex.StackTrace}"); } else { MessageBox.Show($"严重错误: {ex.Message}", "梁板剖面图错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } private static void DrawContinuousBeamSections(Editor ed, Database db, BeamParameters parameters) { try { List<BeamSegment> segments = new List<BeamSegment>(); double currentSlabThickness = parameters.DefaultSlabThickness; double currentSlabOffset = 0; bool isFirstSegment = true; using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTableRecord btr = (BlockTableRecord)tr.GetObject( SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite); // 1. 获取第一点 Point3d startPt = GetPoint(ed, "请点击梁的第一点(按ESC结束):"); if (double.IsNaN(startPt.X)) return; Point3d currentPt = startPt; double previousBeamHeight = 0; while (true) { // 2. 获取第二点(后续段增加选项) string promptMsg = isFirstSegment ? "请点击梁的第二点(按ESC结束):" : "请点击梁的第二点[板厚(A)/升降板(S)]:"; Point3d endPt = GetPoint(ed, promptMsg, currentPt); if (double.IsNaN(endPt.X)) break; // 3. 第一段需要输入梁高 double beamHeight; if (isFirstSegment) { beamHeight = GetHeight(ed); if (double.IsNaN(beamHeight)) break; previousBeamHeight = beamHeight; isFirstSegment = false; } else { beamHeight = previousBeamHeight; // 4. 处理板厚/升降板选项 var pko = new PromptKeywordOptions("\n设置板参数[板厚(A)/升降板(S)/继续(C)] <C>:"); pko.Keywords.Add("A"); pko.Keywords.Add("S"); pko.Keywords.Add("C"); pko.Keywords.Default = "C"; var pkr = ed.GetKeywords(pko); if (pkr.Status != PromptStatus.OK) break; if (pkr.StringResult == "A") { var pdo = new PromptDoubleOptions("\n输入板厚(mm):"); pdo.DefaultValue = currentSlabThickness; pdo.UseDefaultValue = true; pdo.AllowNegative = false; var pdr = ed.GetDouble(pdo); if (pdr.Status != PromptStatus.OK) break; currentSlabThickness = pdr.Value; } else if (pkr.StringResult == "S") { var pdo = new PromptDoubleOptions("\n请输入升降板高度(升板为正数,降板为负数)mm:"); pdo.DefaultValue = currentSlabOffset; pdo.UseDefaultValue = true; pdo.AllowNegative = true; var pdr = ed.GetDouble(pdo); if (pdr.Status != PromptStatus.OK) break; currentSlabOffset = pdr.Value; } } // 创建梁段 var segment = new BeamSegment { Start = currentPt, End = endPt, Height = beamHeight, Slab = new SlabParams { Thickness = currentSlabThickness, Offset = currentSlabOffset } }; segments.Add(segment); currentPt = endPt; previousBeamHeight = beamHeight; } // 绘制所有梁段 if (segments.Count > 0) { DrawBeamSegments(ed, btr, tr, segments, parameters); tr.Commit(); ed.WriteMessage($"\n成功绘制 {segments.Count} 段梁板剖面!"); } else { tr.Abort(); ed.WriteMessage("\n未绘制任何梁段。"); } } } catch (SystemException ex) { ed.WriteMessage($"\n错误: {ex.Message}"); } } private static void DrawBeamSegments(Editor ed, BlockTableRecord btr, Transaction tr, List<BeamSegment> segments, BeamParameters parameters) { try { // 创建多段线 Polyline poly = new Polyline(); poly.SetDatabaseDefaults(); // 添加起点 Point3d startPt = segments[0].Start; poly.AddVertexAt(0, new Point2d(startPt.X, startPt.Y), 0, 0, 0); // 遍历所有梁段 foreach (var segment in segments) { // 计算梁底位置 (向下偏移梁高) Point3d beamBottomPt = new Point3d( segment.End.X, segment.End.Y + segment.Height, segment.End.Z); // 计算板底位置 (梁底再向下偏移板厚) Point3d slabBottomPt = new Point3d( segment.End.X, beamBottomPt.Y + segment.Slab.Thickness, segment.End.Z); // 添加顶点 poly.AddVertexAt(poly.NumberOfVertices, new Point2d(segment.End.X, segment.End.Y), 0, 0, 0); poly.AddVertexAt(poly.NumberOfVertices, new Point2d(beamBottomPt.X, beamBottomPt.Y), 0, 0, 0); poly.AddVertexAt(poly.NumberOfVertices, new Point2d(slabBottomPt.X, slabBottomPt.Y), 0, 0, 0); } // 闭合多段线 poly.Closed = true; btr.AppendEntity(poly); tr.AddNewlyCreatedDBObject(poly, true); // 添加混凝土填充 Hatch hatch = new Hatch(); hatch.SetDatabaseDefaults(); hatch.SetHatchPattern(HatchPatternType.PreDefined, "ANSI31"); hatch.PatternScale = 50; hatch.ColorIndex = 8; btr.AppendEntity(hatch); tr.AddNewlyCreatedDBObject(hatch, true); hatch.Associative = true; hatch.AppendLoop(HatchLoopTypes.Outermost, new ObjectIdCollection { poly.ObjectId }); // 添加标注 DrawAllDimensionsAndMembers(ed, btr, tr, segments, parameters); } catch (SystemException ex) { ed.WriteMessage($"\n绘制梁段错误: {ex.Message}"); } } private static void DrawAllDimensionsAndMembers(Editor ed, BlockTableRecord btr, Transaction tr, List<BeamSegment> segments, BeamParameters parameters) { try { // 绘制每个梁段的尺寸标注 foreach (var segment in segments) { // 梁宽标注 var dimWidth = new AlignedDimension(); dimWidth.SetDatabaseDefaults(); dimWidth.XLine1Point = segment.Start; dimWidth.XLine2Point = new Point3d(segment.End.X, segment.Start.Y, segment.Start.Z); dimWidth.DimLinePoint = new Point3d( (segment.Start.X + segment.End.X) / 2, segment.Start.Y - 50, segment.Start.Z); btr.AppendEntity(dimWidth); tr.AddNewlyCreatedDBObject(dimWidth, true); // 梁高标注 var dimHeight = new AlignedDimension(); dimHeight.SetDatabaseDefaults(); dimHeight.XLine1Point = segment.Start; dimHeight.XLine2Point = new Point3d(segment.Start.X, segment.Start.Y + segment.Height, segment.Start.Z); dimHeight.DimLinePoint = new Point3d( segment.Start.X - 50, (segment.Start.Y + segment.Start.Y + segment.Height) / 2, segment.Start.Z); btr.AppendEntity(dimHeight); tr.AddNewlyCreatedDBObject(dimHeight, true); // 板厚标注 Point3d beamBottom = new Point3d( segment.End.X, segment.End.Y + segment.Height, segment.End.Z); Point3d slabBottom = new Point3d( segment.End.X, beamBottom.Y + segment.Slab.Thickness, segment.End.Z); var dimSlab = new AlignedDimension(); dimSlab.SetDatabaseDefaults(); dimSlab.XLine1Point = beamBottom; dimSlab.XLine2Point = slabBottom; dimSlab.DimLinePoint = new Point3d( segment.End.X + 50, (beamBottom.Y + slabBottom.Y) / 2, segment.End.Z); btr.AppendEntity(dimSlab); tr.AddNewlyCreatedDBObject(dimSlab, true); } // 绘制主次龙骨(简化的实现) // 实际应用中应根据参数设置详细绘制 } catch (SystemException ex) { ed.WriteMessage($"\n标注和龙骨绘制错误: {ex.Message}"); } } private static Point3d GetPoint(Editor ed, string message, Point3d? basePoint = null) { try { var opts = new PromptPointOptions(message); if (basePoint.HasValue) { opts.UseBasePoint = true; opts.BasePoint = basePoint.Value; } var res = ed.GetPoint(opts); return res.Status == PromptStatus.OK ? res.Value : new Point3d(double.NaN, double.NaN, double.NaN); } catch { return new Point3d(double.NaN, double.NaN, double.NaN); } } private static double GetHeight(Editor ed) { try { var opts = new PromptDoubleOptions("请输入梁高(mm):"); opts.AllowNegative = false; var res = ed.GetDouble(opts); return res.Status == PromptStatus.OK ? res.Value : double.NaN; } catch { return double.NaN; } } private static void DrawBeamBottomMembers(BlockTableRecord btr, Transaction tr, Polyline beamPoly, BeamParameters parameters) { double beamLength = beamPoly.Length; // 梁下次龙骨 if (parameters.BeamBottom.SecondaryDirection == "纵向") { double spacing = ParseSpacing(parameters.BeamBottom.SecondarySpacing, beamLength); for (double pos = spacing; pos < beamLength; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.BeamBottom.SecondarySpec, 0); } } // 梁下主龙骨 if (parameters.BeamBottom.PrimaryDirection == "纵向") { if (double.TryParse(parameters.BeamBottom.PrimarySpacing, out double spacing)) { for (double pos = spacing; pos < beamLength; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.BeamBottom.PrimarySpec, 0); } } } else if (parameters.BeamBottom.PrimaryDirection == "纵向") { double spacing = 1000; // 默认纵向间距 for (double pos = spacing; pos < beamLength; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.BeamBottom.PrimarySpec, 0); } } // 梁侧龙骨(如果启用) if (parameters.BeamSide.Enabled) { // 实现梁侧龙骨绘制逻辑... } } private static void DrawSlabMembers(BlockTableRecord btr, Transaction tr, Polyline beamPoly, BeamParameters parameters) { // 板下次龙骨 if (parameters.Slab.SecondaryDirection == "纵向") { double spacing = parameters.Slab.SecondarySpacing; for (double pos = spacing; pos < beamPoly.Length; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.Slab.SecondarySpec, 0); } } // 板下主龙骨 if (parameters.Slab.PrimaryDirection == "纵向") { // 根据顶托内方钢数量绘制 for (int i = 0; i < parameters.Slab.SteelCount; i++) { // 绘制顶托内的方钢 // 这里需要根据实际位置计算 } } else if (parameters.Slab.PrimaryDirection == "纵向") { double spacing = 1000; // 默认纵向间距 for (double pos = spacing; pos < beamPoly.Length; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.Slab.PrimarySpec, 0); } } } private static void DrawMemberSection(BlockTableRecord btr, Transaction tr, Point3d loc, string spec, double angle) { double width = 10, height = 10; ParseMemberSpec(spec, ref width, ref height); var rect = new Polyline(); rect.AddVertexAt(0, new Point2d(loc.X - width / 2, loc.Y - height / 2), 0, 0, 0); rect.AddVertexAt(1, new Point2d(loc.X + width / 2, loc.Y - height / 2), 0, 0, 0); rect.AddVertexAt(2, new Point2d(loc.X + width / 2, loc.Y + height / 2), 0, 0, 0); rect.AddVertexAt(3, new Point2d(loc.X - width / 2, loc.Y + height / 2), 0, 0, 0); rect.Closed = true; if (angle != 0) { Matrix3d rotation = Matrix3d.Rotation(angle, Vector3d.ZAxis, loc); rect.TransformBy(rotation); } btr.AppendEntity(rect); tr.AddNewlyCreatedDBObject(rect, true); } private static void ParseMemberSpec(string spec, ref double width, ref double height) { if (spec.Contains("x") && !spec.Contains("Φ")) { string[] parts = spec.Split('x'); if (parts.Length >= 2) { string wStr = new string(parts[0].Where(c => char.IsDigit(c) || c == '.').ToArray()); string hStr = new string(parts[1].Where(c => char.IsDigit(c) || c == '.').ToArray()); double.TryParse(wStr, out width); double.TryParse(hStr, out height); } } else if (spec.Contains("Φ")) { string diamPart = spec.Split('x')[0].Replace("Φ", ""); string wStr = new string(diamPart.Where(c => char.IsDigit(c) || c == '.').ToArray()); double.TryParse(wStr, out width); height = width; } else if (spec.StartsWith("I")) { string num = new string(spec.Where(char.IsDigit).ToArray()); if (int.TryParse(num, out int size)) { width = size * 0.5; height = size; } } if (width <= 0) width = 10; if (height <= 0) height = 10; } private static double ParseSpacing(string input, double totalLength) { if (input.Contains("@")) { string numPart = new string(input.Replace("@", "").Where(c => char.IsDigit(c) || c == '.').ToArray()); if (double.TryParse(numPart, out double spacing)) return spacing; } else if (input.Contains("根")) { string numPart = new string(input.Where(char.IsDigit).ToArray()); if (int.TryParse(numPart, out int count) && count > 1) return totalLength / (count - 1); } return 200; } } #endregion } 命令: NETLOAD 命令: DB 请点击梁的第一点(按ESC结束): 请点击梁的第二点(按ESC结束): <正交 开> 请输入梁高(mm): 1000 请点击梁的第二点[板厚(A)/升降板(S)]: A 点无效。 请点击梁的第二点[板厚(A)/升降板(S)]: S 点无效。 请点击梁的第二点[板厚(A)/升降板(S)]: 设置板参数[板厚(A)/升降板(S)/继续(C)] <C> [A/S/C] <C>: C 请点击梁的第二点[板厚(A)/升降板(S)]: 设置板参数[板厚(A)/升降板(S)/继续(C)] <C> [A/S/C] <C>: *取消* 成功绘制 2 段梁板剖面! 命令: 正在重生成模型。 绘制步骤错误,未按以下步骤实现绘制: 1、命令栏显示:请点击梁的第一点: 2、命令栏显示:点击梁的第二点: 3、命令栏显示:请输入梁高(mm): 4、命令栏显示:请点击梁的第一点: 5、命令栏显示:请点击梁的第二点[板厚(A)升降板(S)]: 如果选(A): 5.1、命令栏显示:输入板厚(mm)<120>: 6、命令栏显示:请点击梁的第二点[板厚(A)升降板(S)]: 如果选(S): 6.1、命令栏显示:请输入升降板高度(升板为正数,降板为负数)mm<0.00>: 7、命令栏显示:请点击梁的第二点[板厚(A)升降板(S)]: 如果无需选择(A)(S) 7.1、命令栏显示:请点击梁的第二点: 8、命令栏显示:请点击梁高(mm): 接下来重复4至8步骤 4、命令栏显示:请点击梁的第一点: 5、命令栏显示:请点击梁的第二点[板厚(A)升降板(S)]: 如果选(A): 5.1、命令栏显示:输入板厚(mm)<120>: 6、命令栏显示:请点击梁的第二点[板厚(A)升降板(S)]: 如果选(S): 6.1、命令栏显示:请输入升降板高度(升板为正数,降板为负数)mm<0.00>: 7、命令栏显示:请点击梁的第二点[板厚(A)升降板(S)]: 如果无需选择(A)(S) 7.1、命令栏显示:请点击梁的第二点: 9、命令栏显示:请点击梁高(mm):
08-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值