如何重载以 FullSubentityPath 作为参数的 Brep 构造函数?

问题描述 投票:0回答:1

我不太了解重载构造函数,有人可以向我解释一下吗?

因为我尝试重载构造函数但总是失败。

当我运行代码时,我总是遇到这个异常

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;
            }
        }
    }
}

它运行但结果不同

c# autocad objectarx
1个回答
0
投票

我建议放弃 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(错误)

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.