我不太了解重载构造函数,有人可以向我解释一下吗?
因为我尝试重载构造函数但总是失败。
当我运行代码时,我总是遇到这个异常
Autodesk.AutoCAD.BoundaryRepresentation.Exception 被抛出。
我在 Visual Studio 2022 中使用 .NET Framework v4.8。
谁能给我解释一下吗?
这是我的代码:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.BoundaryRepresentation;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.ComponentModel;
using System.Linq;
using System.Windows.Input;
namespace _3dInterfacePaint.ViewModels
{
public class MainWindowViewModel : INotifyPropertyChanged
{
private string _selectedColor1;
private string _selectedColor2;
private Autodesk.AutoCAD.Colors.Color _color1;
private Autodesk.AutoCAD.Colors.Color _color2;
public string SelectedColor1
{
get => _selectedColor1;
set { _selectedColor1 = value; OnPropertyChanged(nameof(SelectedColor1)); }
}
public string SelectedColor2
{
get => _selectedColor2;
set { _selectedColor2 = value; OnPropertyChanged(nameof(SelectedColor2)); }
}
public ICommand SelectColor1Command { get; }
public ICommand SelectColor2Command { get; }
public ICommand ApplyColorsCommand { get; }
public MainWindowViewModel()
{
SelectColor1Command = new RelayCommand(_ => SelectColor(1));
SelectColor2Command = new RelayCommand(_ => SelectColor(2));
ApplyColorsCommand = new RelayCommand(_ => ApplyColorsTo3DObject());
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void SelectColor(int colorNumber)
{
var colorDialog = new Autodesk.AutoCAD.Windows.ColorDialog();
if (colorDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
if (colorNumber == 1)
{
_color1 = colorDialog.Color;
SelectedColor1 = $"First Color: {_color1.ColorIndex}";
}
else
{
_color2 = colorDialog.Color;
SelectedColor2 = $"Second Color: {_color2.ColorIndex}";
}
}
}
private Point3d GetFaceCentroid(Autodesk.AutoCAD.BoundaryRepresentation.Face face)
{
Point3dCollection points = new Point3dCollection();
// Lấy tất cả các cạnh thông qua Loops
foreach (var loop in face.Loops)
{
foreach (var edge in loop.Edges)
{
var curve = edge.Curve; // Curve3d của cạnh
points.Add(curve.StartPoint);
points.Add(curve.EndPoint);
}
}
// Tính trung tâm của các điểm
double x = 0, y = 0, z = 0;
foreach (Point3d pt in points)
{
x += pt.X;
y += pt.Y;
z += pt.Z;
}
int count = points.Count;
return new Point3d(x / count, y / count, z / count);
}
private void ApplyColorsTo3DObject()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
if (_color1 == null || _color2 == null)
{
ed.WriteMessage("\nPlease choose two colors before applying.");
return;
}
using (var lck = doc.LockDocument())
{
PromptEntityOptions peo = new PromptEntityOptions("\nSelect a 3D object:");
peo.SetRejectMessage("\nNot a valid Solid3d.");
peo.AddAllowedClass(typeof(Solid3d), true);
var per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
{
ed.WriteMessage("\nNo valid object selected.");
return;
}
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Solid3d solid3d = tr.GetObject(per.ObjectId, OpenMode.ForWrite) as Solid3d;
if (solid3d == null)
{
ed.WriteMessage("\nSelected object is not a valid Solid3d.");
return;
}
try
{
// **Corrected Code:**
// Create FullSubentityPath to access BREP from the Solid3d object
var fullSubentityPath = new FullSubentityPath(new[] { per.ObjectId }, new SubentityId(SubentityType.Null, IntPtr.Zero));
// Use FullSubentityPath to create BREP
using (var brep = new Brep(fullSubentityPath)) // Pass FullSubentityPath here
{
int faceIndex = 0;
var faces = brep.Faces.ToArray();
foreach (var face in faces)
{
try
{
var subEntityId = face.SubentityPath.SubentId;
var centroid = GetFaceCentroid(face);
int stripeIndex = (int)(centroid.Z / 1.0);
var colorToApply = (stripeIndex % 2 == 0) ? _color1 : _color2;
solid3d.SetSubentityColor(subEntityId, colorToApply);
faceIndex++;
}
catch (System.Exception ex)
{
ed.WriteMessage($"\nError applying color to face: {ex.Message}");
}
}
}
tr.Commit();
ed.WriteMessage("\nStriped painting applied successfully.");
}
catch (System.Exception ex)
{
ed.WriteMessage($"\nUnexpected error: {ex.Message}");
}
}
}
}
private void ApplyColorToFace(Autodesk.AutoCAD.BoundaryRepresentation.Face face, Autodesk.AutoCAD.Colors.Color color, Solid3d solid3d)
{
try
{
var subEntityId = face.SubentityPath.SubentId;
solid3d.SetSubentityColor(subEntityId, color);
}
catch (System.Exception ex)
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\nError applying color to face: {ex.Message}");
}
}
public class RelayCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public bool CanExecute(object parameter) => _canExecute?.Invoke(parameter) ?? true;
public void Execute(object parameter) => _execute(parameter);
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
}
}
}
这是更新代码:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.BoundaryRepresentation;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Input;
using _3dInterfacePaint.Views;
namespace _3dInterfacePaint.ViewModels
{
public class MainWindowViewModel : INotifyPropertyChanged
{
private string _selectedColor1;
private string _selectedColor2;
private Autodesk.AutoCAD.Colors.Color _color1;
private Autodesk.AutoCAD.Colors.Color _color2;
public string SelectedColor1
{
get => _selectedColor1;
set { _selectedColor1 = value; OnPropertyChanged(nameof(SelectedColor1)); }
}
public string SelectedColor2
{
get => _selectedColor2;
set { _selectedColor2 = value; OnPropertyChanged(nameof(SelectedColor2)); }
}
public ICommand SelectColor1Command { get; }
public ICommand SelectColor2Command { get; }
public ICommand ApplyColorsCommand { get; }
public MainWindowViewModel()
{
SelectColor1Command = new RelayCommand(_ => SelectColor(1));
SelectColor2Command = new RelayCommand(_ => SelectColor(2));
ApplyColorsCommand = new RelayCommand(_ => ApplyColorsTo3DObject());
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void SelectColor(int colorNumber)
{
var colorDialog = new Autodesk.AutoCAD.Windows.ColorDialog();
if (colorDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
if (colorNumber == 1)
{
_color1 = colorDialog.Color;
SelectedColor1 = $"First 1: {_color1.ColorIndex}";
}
else
{
_color2 = colorDialog.Color;
SelectedColor2 = $"Second 2: {_color2.ColorIndex}";
}
}
}
private void ApplyColorsTo3DObject()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
if (_color1 == null || _color2 == null)
{
ed.WriteMessage("\nPlease chose 2 color.");
return;
}
using (var lck = doc.LockDocument())
{
PromptEntityOptions peo = new PromptEntityOptions("\nSelect 3D object:");
peo.SetRejectMessage("\nNot Solid3d.");
peo.AddAllowedClass(typeof(Solid3d), true);
var per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
{
ed.WriteMessage("\nUnfound object.");
return;
}
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Solid3d solid3d = tr.GetObject(per.ObjectId, OpenMode.ForWrite) as Solid3d;
if (solid3d == null)
{
ed.WriteMessage("\nSelected object is not a valid Solid3d.");
return;
}
var fullSubentityPath = new FullSubentityPath(new[] { per.ObjectId }, new SubentityId(SubentityType.Null, IntPtr.Zero));
using (var brep = new Brep(fullSubentityPath))
{
int faceIndex = 0;
var faces = brep.Faces.ToArray();
foreach (var face in faces)
{
try
{
var subEntityId = face.SubentityPath.SubentId;
var colorToApply = (faceIndex % 2 == 0) ? _color1 : _color2;
solid3d.SetSubentityColor(subEntityId, colorToApply);
faceIndex++;
}
catch (System.Exception ex)
{
ed.WriteMessage($"\nError applying color to face: {ex.Message}");
}
}
}
tr.Commit();
}
}
}
private void ApplyStripesToFace(Autodesk.AutoCAD.BoundaryRepresentation.Face face, int faceIndex)
{
try
{
var loops = face.Loops.ToArray();
if (loops.Length == 0) return;
var loop = loops[0];
var edges = loop.Edges.ToArray();
for (int i = 0; i < edges.Length; i++)
{
var edge = edges[i];
var color = (i % 2 == 0) ? _color1 : _color2;
ApplyColorToEdge(edge, color);
}
}
catch (System.Exception ex)
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\nError creating stripes on face: {ex.Message}");
}
}
private void ApplyColorToEdge(Autodesk.AutoCAD.BoundaryRepresentation.Edge edge, Autodesk.AutoCAD.Colors.Color color)
{
try
{
var subentityId = edge.SubentityPath.SubentId;
// Lấy ObjectId từ FullSubentityPath
var objectId = edge.SubentityPath.GetObjectIds().FirstOrDefault();
if (objectId == ObjectId.Null)
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nFailed to retrieve ObjectId for edge.");
return;
}
using (Transaction tr = Application.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction())
{
Solid3d solid = tr.GetObject(objectId, OpenMode.ForWrite) as Solid3d;
if (solid != null)
{
solid.SetSubentityColor(subentityId, color);
}
tr.Commit();
}
}
catch (System.Exception ex)
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\nError applying color to edge: {ex.Message}");
}
}
public class RelayCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public bool CanExecute(object parameter) => _canExecute?.Invoke(parameter) ?? true;
public void Execute(object parameter) => _execute(parameter);
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
}
}
}
它运行但结果不同
我建议放弃 Brep 并使用 AssocPersSubentityIdPE ,它比 Brep 快得多,这是一个使用 ObjectARX 的 Python 包装器的示例。
导入回溯 从pyrx_imp导入Rx、Ge、Gi、Db、Ap、Ed、Br def PyRxCmd_doit1() -> 无: 尝试: ps, id, pnt = Ed.Editor.entSel(" 选择:“,Db.Solid3d.desc()) dbent = Db.Solid3d(id,Db.OpenMode.kForWrite) pe = Db.AssocPersSubentIdPE(dbent.queryX(Db.AssocPersSubentIdPE.desc())) 对于枚举中的 idx、faceId(pe.getAllSubentities(dbent, Db.SubentType.kFaceSubentType)): clr = Db.Color() clr.setColorIndex(idx) dbent.setSubentColor(faceId,clr) 除了异常错误: 回溯.print_exception(错误)