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):
最新发布