detecting and selecting a face with specific color on a 3dSolid

Hello,

attached are 2 files that have a 3dSolid with one face in a green color.
I want to detect this different face and then use it as a starting face for the smexportosm command.

My first taughts are to loop the 3dSolid faces and check the color properties, then keep a mapping list per color and the list of faces. Then use the select command to activate the face.
I have not found ways to check a 3dSolid faces properties.
If this is not possible I would define the special face color as a setting in my app en then select the face by properties. However this also doesn't seem to work.
I'm mainly using lisp for now but if it can be done in brx that would also be fine.

As we are only using sheet metal I could improve the algorithm by only using the top and bottom faces for sheet metal flange features and checking their properties. It would make the algo more robust as thickness and bend faces would not influence it.

Any hints on this?

Comments

  • to the best of my knowledge, you cannot loop through or traverse the BREP structure of a 3DSolid and select
    certain Faces according to their properties like color, size, area or direction (normals) using Lisp !
    So you have to do it in BRX C++ or C# NET by programming the commands or exposing this functionality to Lisp
    by means of a LispFunction .
    Here is the code of a possible way to do it in C# :
    The command selects Faces of a 3DSolid facing up, down, or being vertical and colorates them...
    You could use the color of the faces to select them and then do something
    I hope this helps

    [CommandMethod("COLORFACES", CommandFlags.UsePickSet)]
            public void colorateFaces()
            {
    
                Document doc = _AcAp.Application.DocumentManager.MdiActiveDocument;
                Database db  = doc.Database;
                Editor   ed  = doc.Editor;
    
                // Ask the user to select Entities to colorate...
                PromptSelectionOptions pSelOptsOn = new PromptSelectionOptions();
    
                pSelOptsOn.MessageForAdding = "\nSelect 3D Solids to colorate their Faces :";
                pSelOptsOn.AllowDuplicates = false;
    
                TypedValue[] selFilter = new TypedValue[1] { new TypedValue(0 , "3DSOLID") };
    
                PromptSelectionResult pSelres = ed.GetSelection(pSelOptsOn, new SelectionFilter(selFilter));
    
                if (pSelres.Status == PromptStatus.Error) return;
                if (pSelres.Status == PromptStatus.Cancel) return;
    
                SelectionSet ss = pSelres.Value;
                ObjectId[] oids = ss.GetObjectIds();
    
                // get a collection from a selection set if needed !!!
                //ObjectIdCollection oIds = new ObjectIdCollection(ss.GetObjectIds());
    
                // an ObjectIdCollection for selected /filtered solid Faces...
                List<SubentityId> ffCol = new List<SubentityId>();
    
                using (Transaction Tx = db.TransactionManager.StartTransaction())
                {
                    foreach (ObjectId oid in oids)
                    {
    
                        Solid3d sol = Tx.GetObject(oid, OpenMode.ForWrite) as Solid3d;
                        ObjectId[] ids = new ObjectId[] { sol.ObjectId };
                        FullSubentityPath path = new FullSubentityPath(ids, new SubentityId(SubentityType.Null, IntPtr.Zero));
                        List<SubentityId> SubentIds = new List<SubentityId>();
    
    
                        // get subentityids of all faces...
                        using (Brep brep = new Brep(path))
                        {
                            foreach (_AcBrep.Face face in brep.Faces)
                            {
                                SubentIds.Add(face.SubentityPath.SubentId);
                            }
                        }
    
                         // loop through all Faces of current 3D Solid and colorate them according to face Normals...!
                        for (int i = 0; i < SubentIds.Count; i++)
                        {
                            FullSubentityPath regpath = new FullSubentityPath(ids, SubentIds[i]);
                            Entity faceEntity = sol.GetSubentity(regpath);
    
                            if (faceEntity.GetType() == typeof(_AcDb.Surface))
                            {
                                _AcDb.Surface SurfaceEntity = sol.GetSubentity(regpath) as _AcDb.Surface;
                                Color color = Color.FromColorIndex(ColorMethod.ByColor, (short)73);
                                sol.SetSubentityColor(SubentIds[i], color);
                             }
    
    
                            else if (faceEntity.GetType() == typeof(_AcDb.Region))
                            {
                                Region regionEntity = sol.GetSubentity(regpath) as Region;
    
                                // horizontal ceiling (normal vertical direction +z))
                                if (AlmostEquals(regionEntity.Normal.Z, 1.0, 0.000000000000001))
                                {
                                     ed.WriteMessage("\n . "
                                        + "(" + regionEntity.Normal.X.ToString() + ", "
                                              + regionEntity.Normal.Y.ToString() + ", "
                                              + regionEntity.Normal.Z.ToString() + ")"
                                        );
    
                                    Color color = Color.FromColorIndex(ColorMethod.ByColor, (short)30);
                                    sol.SetSubentityColor(SubentIds[i], color);
    
                                 }
    
                                // horizontal floor (normal vertical direction -z)
                                //else if ((regionEntity.Normal.X == 0) && (regionEntity.Normal.Y == 0) && (regionEntity.Normal.Z == -1))
                                else if (AlmostEquals(regionEntity.Normal.Z, -1.0, 0.000000000000001))
                                {
                                      ed.WriteMessage("\n . "
                                        + "(" + regionEntity.Normal.X.ToString() + ", "
                                              + regionEntity.Normal.Y.ToString() + ", "
                                              + regionEntity.Normal.Z.ToString() + ")"
                                        );
    
                                    Color color = Color.FromColorIndex(ColorMethod.ByColor, (short)40);
                                    sol.SetSubentityColor(SubentIds[i], color);
                                }
    
                                // Walls (vertical Faces...)
                                else if (regionEntity.Normal.Z == 0.0)
                                {
                                    ed.WriteMessage("\n . "
                                        + "(" + regionEntity.Normal.X.ToString() + ", "
                                              + regionEntity.Normal.Y.ToString() + ", "
                                              + regionEntity.Normal.Z.ToString() + ")"
                                        );
                                    Color color = Color.FromColorIndex(ColorMethod.ByColor, (short)50);
                                    sol.SetSubentityColor(SubentIds[i], color);
    
                                }
                                //Roofs, Ramps and beyond...
                                else if (regionEntity.Normal.Z != 0.0)
                                {
                                      ed.WriteMessage("\n . "
                                        + "(" + regionEntity.Normal.X.ToString() + ", "
                                              + regionEntity.Normal.Y.ToString() + ", "
                                              + regionEntity.Normal.Z.ToString() + ")"
                                        );
    
                                    //Color color = Color.FromColorIndex(ColorMethod.ByColor, (short)50);
                                    Color color = Color.FromRgb(165, 41, 0);
                                    sol.SetSubentityColor(SubentIds[i], color);
    
                                }
                             }
                        }
    
                    }
                    Tx.Commit();
                    }
            }
    
  • Dear Konstantin,

    thanks for your advice.

    Sorry for the late response, but due to covid-19 and shift in priorities this task is postponed for a while. So I'll pick this up within some time.

    Regards,

    Karel

  • Dear Karel,
    Have a look at this solution:

    https://forum.bricsys.com/discussion/comment/44156/#Comment_44156

    I hope this helps
    Regards

  • @KarelVergauwe said:
    Hello,

    attached are 2 files that have a 3dSolid with one face in a green color.
    I want to detect this different face and then use it as a starting face for the smexportosm command.

    Any hints on this?

    Karel,
    I didn't mean to ignore your post, but I am not anyone with solutions. I was in a similar fix. Roy provided a *.LSP which seems to have solved my problem. Konstantin provided more code that may also offer you a solution. I suggest if you haven't already done so, to check their posts.
    Good luck.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Click one of the buttons on the top bar to get involved!