Search code examples
c#autocadobjectarx

How to fix exeption type of in C#.net ObjectArx


when i run my code i alway have this line Exception of type Autodesk.AutoCAD.BoundaryRepresentation.Exception was thrown. im using .netFramework 4.8 in visual studio 2022 does anyone have the same error or know how to fix it here is the code

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;

namespace _3Dinterface.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())
                {
                    var solid3d = tr.GetObject(per.ObjectId, OpenMode.ForWrite) as Solid3d;
                    if (solid3d == null)
                    {
                        ed.WriteMessage("\nobject not Solid3d.");
                        return;
                    }

                    try
                    {
                        using (Brep brep = new Brep(solid3d))
                        {
                            int faceIndex = 0;

                           
                            foreach (var face in brep.Faces)
                            {
                                try
                                {
                                   
                                    var colorToApply = (faceIndex % 2 == 0) ? _color1 : _color2;
                                    ApplyColorToFace(face, colorToApply);
                                    faceIndex++;
                                }
                                catch (System.Exception ex)
                                {
                                    ed.WriteMessage($"\nERROR: {ex.Message}");
                                }
                            }
                        }

                        ed.WriteMessage("\nSucceed .");
                    }
                    catch (System.Exception ex)
                    {
                        ed.WriteMessage($"\nError in Solid3d: {ex.Message}");
                    }

                    tr.Commit();
                }
            }
        }

        
        private void ApplyColorToFace(Autodesk.AutoCAD.BoundaryRepresentation.Face face, Autodesk.AutoCAD.Colors.Color color)
        {
            if (face != null)
            {
                try
                {
                    var subEntityPath = face.SubentityPath; 
                    var entityId = subEntityPath.GetObjectIds().FirstOrDefault(); 

                    if (entityId.IsValid)
                    {
                        using (Transaction tr = Application.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction())
                        {
                            Solid3d solid = tr.GetObject(entityId, OpenMode.ForWrite) as Solid3d;
                            ObjectId[] ids = new ObjectId[] { entityId };
                            FullSubentityPath path = new FullSubentityPath(ids, new SubentityId(SubentityType.Null, IntPtr.Zero));
                            List<SubentityId> SubentIds = new List<SubentityId>();
                            using(Autodesk.AutoCAD.BoundaryRepresentation.Brep brep = new Autodesk.AutoCAD.BoundaryRepresentation.Brep(path))
                            {
                                foreach (Autodesk.AutoCAD.BoundaryRepresentation.Edge edge in brep.Edges)
                                {
                                    SubentIds.Add(edge.SubentityPath.SubentId);
                                }
                            }
                            foreach (SubentityId subentId in SubentIds)
                            {
                                var entity = tr.GetObject(entityId, OpenMode.ForWrite) as Entity;
                                if (entity != null)
                                {
                                    entity.Color = color; 
                                }
                                tr.Commit();
                            }
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\nError in 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;
            }
        }
    }
}


I try write the code differ way and debugging the code but still the same


Solution

  • To be able to access to the Faces SubentityPath, you have to use the overload constructor of Brep which takes a FullSubentityPath as argument.

    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: {ex.Message}");
            }
        }
    }