i have this problem, i need solution

i have this problem, i need solution

dinhthit25
Contributor Contributor
590 Views
7 Replies
Message 1 of 8

i have this problem, i need solution

dinhthit25
Contributor
Contributor

i have this error applying color to solid3d
i using C#.net framework 4.8 at visual studio 2022 when i use the method i alway have this error
Error applying color to face: Exception of type 'Autodesk.AutoCAD.BoundaryRepresentation.Exception' was thrown.

here my code:

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.BoundaryRepresentation;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.Geometry;
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 choose 2 colors.");
                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("\nObject not found.");
                    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
                            {
                                ApplyStripesToFace(face, _color1, _color2);
                                faceIndex++;
                            }
                            catch (System.Exception ex)
                            {
                                ed.WriteMessage($"\nError applying color to face: {ex.Message}");
                            }
                        }
                    }

                    tr.Commit();
                }
            }
        }




        private void ApplyStripesToFace(Autodesk.AutoCAD.BoundaryRepresentation.Face face, Autodesk.AutoCAD.Colors.Color color1, Autodesk.AutoCAD.Colors.Color color2)
        {
            try
            {
                var loops = face.Loops.ToArray();
                if (loops.Length > 0)
                {
                    var loop = loops[0];  // Giả sử chỉ có một vòng lặp trên mỗi mặt

                    // Chia mặt thành các vùng sọc
                    var segments = SplitFaceIntoStripes(face, 5); // Chia thành 5 vùng (ví dụ)

                    for (int i = 0; i < segments.Count; i++)
                    {
                        var stripeFace = segments[i];
                        var stripeColor = (i % 2 == 0) ? color1 : color2;

                        // Áp dụng màu cho vùng
                        ApplyColorToFace(stripeFace, stripeColor);
                    }
                }
            }
            catch (System.Exception ex)
            {
                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\nError creating stripes on face: {ex.Message}");
            }
        }



        private List<Autodesk.AutoCAD.BoundaryRepresentation.Face> SplitFaceIntoStripes(Autodesk.AutoCAD.BoundaryRepresentation.Face face, int stripeCount)
        {
            var stripes = new List<Autodesk.AutoCAD.BoundaryRepresentation.Face>();

            // Logic để chia mặt thành các vùng stripe (giả định chia đều theo chiều cao hoặc chiều dài)
            // TODO: Cần thêm logic chia chính xác dựa trên hình học của mặt

            for (int i = 0; i < stripeCount; i++)
            {
                stripes.Add(face); // Tạm thêm mặt gốc (để placeholder logic)
            }

            return stripes;
        }


        private void ApplyColorToFace(Autodesk.AutoCAD.BoundaryRepresentation.Face face, Autodesk.AutoCAD.Colors.Color color)
        {
            var subentityId = face.SubentityPath.SubentId;

            using (Transaction tr = Application.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction())
            {
                Solid3d solid = tr.GetObject(face.SubentityPath.GetObjectIds().First(), OpenMode.ForWrite) as Solid3d;
                if (solid != null)
                {
                    solid.SetSubentityColor(subentityId, color);
                }

                tr.Commit();
            }
        }


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

 

 

0 Likes
Accepted solutions (1)
591 Views
7 Replies
Replies (7)
Message 2 of 8

_gile
Consultant
Consultant

Hi,

What do you expect with this code?

                    // Chia mặt thành các vùng sọc
                    var segments = SplitFaceIntoStripes(face, 5); // Chia thành 5 vùng (ví dụ)

                    for (int i = 0; i < segments.Count; i++)
                    {
                        var stripeFace = segments[i];
                        var stripeColor = (i % 2 == 0) ? color1 : color2;

                        // Áp dụng màu cho vùng
                        ApplyColorToFace(stripeFace, stripeColor);
                    }

 

The 'segments' variable is a list which will contain 5 times the same face; { face, face, face, face, face }

So, when running the for loop you set the same face color, one time with color1, next time with color2 and so on until 5 times.

 

You should explain what you try to achieve with the ApplyColorTo3DObject method, and do not ned to post all the WPF related code which is not relevant for your issue.

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 8

_gile
Consultant
Consultant

Perhaps you could attach a picture showing what you want to get.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 4 of 8

dinhthit25
Contributor
Contributor

thanks you for your advise, im trying to paint 2 color alternate on every face and the code you ask i use to divide a face of a 3D object in AutoCAD into stripes and apply alternating colors (stripe colors) to these regions(i forgot change the node to english, sorry).

// Chia mặt thành các vùng sọc
                    var segments = SplitFaceIntoStripes(face, 5); // Chia thành 5 vùng (ví dụ)

                    for (int i = 0; i < segments.Count; i++)
                    {
                        var stripeFace = segments[i];
                        var stripeColor = (i % 2 == 0) ? color1 : color2;

                        // Áp dụng màu cho vùng
                        ApplyColorToFace(stripeFace, stripeColor);
                    }  

 

0 Likes
Message 5 of 8

_gile
Consultant
Consultant

You cannot "paint 2 color alternate on every face" by setting the face color. The Solid3d.SetSubentityColor method applies a single color to the whole subentity (Face, Edge or Vertex).



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 8

dinhthit25
Contributor
Contributor

so that why it won't work thank you
and may i ask which is best way to paint 2 color alternate on every face

0 Likes
Message 7 of 8

_gile
Consultant
Consultant
Accepted solution

Perhaps you could apply a 'striped' Material (if you can find or create one). You apply a Material with the Solid3d.SetSubentityMaterial method as you do for a color.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 8 of 8

dinhthit25
Contributor
Contributor

thank you i will try that way

0 Likes