Select solids by face color?

I'm working with some imported files that have hundreds of 3D objects of different colors, all on Layer 0. If you slice any of the objects open, you can see that the color is only applied to the faces ofthe object. I would like to assign like colored objects to different layers. The filter does not work. It does not recognize the color of faces, just a solid color object.

Does anyone know how to do this?

«1

Comments

  • @Jim Canale
    You need to google this. There was a huge discussion on this or a similar topic in the adesk groups I think.
    It was Tony Tanzillo (Godzillo) going back and forth with some dreamers and winning every time, but the talk was informative.
    In general, you need to use .net to do this at minimum, then possibly c++ but I don't think so. Kean's blog through the interface likely has info on this too. Its not a trivial question but is solvable.

  • @James Maeding said:
    @Jim Canale
    You need to google this. There was a huge discussion on this or a similar topic in the adesk groups I think.
    It was Tony Tanzillo (Godzillo) going back and forth with some dreamers and winning every time, but the talk was informative.
    In general, you need to use .net to do this at minimum, then possibly c++ but I don't think so. Kean's blog through the interface likely has info on this too. Its not a trivial question but is solvable.

    Thanks. I Googled before your posted, but didn't find any related information. I'll have to change my search terms, and try again.

    If this requires .net or C++ it's hopeless. I can't even write *.lsp code. Not my wheelhouse. I'm 65 and rapidly losing my health and eyesight while trying to keep my job, so I don't know if a last ditch effort is worth it

  • Thanks. I opened the link but it referred me to a separate discussion that didn't seem relevant.

  • Found a thread suggesting QSELECT, or SELECTSIMILAR. had already tried both with no success.

  • Yah, you need a .net program, not built into acad or bcad.
  • An entity list of a solid with face colors contains color information. So my guess is that Lisp code can also be used here.

  • Hi Jim,
    the Faces of Solids are not Entities but Subentities of the Solid Entities and cannot be selected using their properties like color, material or orientation !
    You cannot select all the faces in a drawing having a specific color, neither can you assign a layer to a face of a solid.
    You can only select interactively in the drawing editor certain faces of the same solid and change their colors using the command SOLIDEDIT.
    If you want to be able to select faces of solids having specific properties e.g. color, area, material etc and assign to these faces new
    values for their properties
    e.g "select all red faces of 1000 solids and turn them to green or select all faces of those solids and turn them to yellow if their area is < 25"
    then you can do it ONLY programmatically using C++ or C# .NET. You can't do it with lisp !
    Have a look also at this thread which has similar content...i have provided some example code there.

    https://forum.bricsys.com/discussion/comment/44094#Comment_44094

    So what are you trying to do ?

  • Are these Solids or just Meshes or even loose Faces ?

    Or from which App were they coming from and which file format ?

    (The idea is to open the data in a 3D App and do the separation there)

  • Roy Klein Gebbinck
    edited April 2020

    Selecting solids based on a subentity (face or edge) color is possible with Lisp.

    Proof of concept:

    (defun c:SelectSolidsWithSubColor ( / aci ss)
      (if
        (and
          (setq aci (getint "\nAci color: "))
          (setq ss (ssget "_X" (list (cons 1 (strcat "truecolor-adesk-attrib*" (itoa (+ (lsh accolormethodbyaci 24) aci)) " `#")))))
        )
        (sssetfirst nil ss)
      )
      (princ)
    )
    
  • Yes you can select the Solid Entities having Faces of a specific color BUT not the Faces themselves with Lisp !

  • @Konstantin Sakellaris said:
    Hi Jim,
    the Faces of Solids are not Entities but Subentities of the Solid Entities and cannot be selected using their properties like color, material or orientation !

    .............

    So what are you trying to do ?

    Konstantin,
    Thank you. The 3D solids (rectangular and irregular blocks) have all been painted with various colors on their faces. (If you slice one in half, it is the color of layer 0 inside.) I want to assign blocks with certain face colors to certain layers. If I could propagate the face color through the entire solid that would work too, because then I could select them with QSelect.

  • @Michael Mayer said:
    Are these Solids or just Meshes or even loose Faces ?

    Or from which App were they coming from and which file format ?

    (The idea is to open the data in a 3D App and do the separation there)

    Michael,
    I'm tasked with creating 3D models of a half dozen printed wiring assemblies. First step is creation of the unpopulated PC board. Next the download or creation of component models. And finally locating the components on the board. To do the last step accurately, the board must have the copper patterns or solder mask layers. The project engineer is emailing me the native files (*.BRD) from Eagle CAD (an Autodesk PCB layout program) I've been importing the *.brd into FreeCAD, then exporting it to a color STEP file. The FreeCAD export puts all the physical layers of the PCB (FR4 laminate, top and bottom copper, top and bottom solder mask, top and bottom solder paste, top and bottom silkscreen) on Layer 0. The hundreds of solid objects are identifiable by color, but I can't snap components to them unless I can simplify things by turning off some physical layers. Furthermore, the manager wants me to remove the board traces and silkscreen once the board is populated, so the designs can't be stolen.

  • @Roy Klein Gebbinck said:
    An entity list of a solid with face colors contains color information. So my guess is that Lisp code can also be used here.

    Roy, I appreciate the suggestion and the sample code, but I'm lost when people show me code. Never learned it, and at this late date in my life, not sure I want to invest the time in learning. I have a deadline for this project. and I've got to find some way to complete it soon.

  • Oh,
    *.BRD is quite an exotic file format.

    Fine that FreeCAD can import it and that you get Solids though.

    AFAIK FreeCAD has no Layer System at all.
    I don't think I ever tried to export a DWG from it. Would be useless
    for me if everything exports to Layer 0 only.
    Maybe there are any workarounds from FreeCAD, like by naming,
    which could offer search and separation options in Bricscad later ...

  • @Jim Canale the provided code should work for you if the faces have ACI colors. But if you don't try... Shrug...

  • Roy Klein Gebbinck
    edited April 2020

    Here is a slightly extended version of the code.

    Works with ACI and RGB colors.
    Note that the first color found on the source object is used in the selection filter.

    (defun GetSubColorNumber (enm)
      (vl-some
        '(lambda (sub / clr)
          (and
            (= 1 (car sub))
            (wcmatch (cdr sub) "truecolor-adesk-attrib*")
            (setq clr (atoi (cadr (reverse (vle-string-split " " (cdr sub))))))
            (vl-position (lsh clr -24) (list accolormethodbyaci accolormethodbyrgb))
          )
          clr
        )
        (entget enm)
      )
    )
    
    (defun c:SelectSolidsWithSubColor ( / clr enm)
      (if
        (and
          (setq enm (car (entsel)))
          (= "3DSOLID" (vle-entget 0 enm))
          (setq clr (GetSubColorNumber enm))
        )
        (sssetfirst nil (ssget "_X" (list (cons 1 (strcat "truecolor-adesk-attrib*" (itoa clr) " `#")))))
      )
      (princ)
    )
    
  • @Roy Klein Gebbinck
    Very nice, love it when the lispers rise to the occasion.

  • @Roy Klein Gebbinck said:
    @Jim Canale the provided code should work for you if the faces have ACI colors. But if you don't try... Shrug...

    Thank you Roy. I am completely willing to try it. But how do I invoke the code?

  • @Michael Mayer said:
    Oh,
    *.BRD is quite an exotic file format.

    Fine that FreeCAD can import it and that you get Solids though.

    AFAIK FreeCAD has no Layer System at all.
    I don't think I ever tried to export a DWG from it. Would be useless
    for me if everything exports to Layer 0 only.
    Maybe there are any workarounds from FreeCAD, like by naming,
    which could offer search and separation options in Bricscad later ...

    Mike,
    The facility to import *.BRD's and other PCB CAD is found in an add-on to FreeCAD. The export from FreeCAD is all on Layer 0, but the physical PCB layers are identified by unique face colors. I'm assuming once I get Roy's code running, I will be able to select objects with specific face colors and assign them to different layers. Then I can use the PCB import to build my 3D PWA.

    If this works, I will owe Roy a debt of gratitude. Unfortunately, I can't repay him the favor, as I know nothing about programming. I'm old. When I was in college we designed vacuum tube amplifiers. I had to teach myself Autocad. I'm a slow learner.

  • Instructions:

    Save the attached Lisp File.

    Read the instructions you can find here:
    http://www.b-k-g.nl/loading-lisp-programs.html

    The command name to use is:
    SelectSolidsWithSubColor

  • @Roy Klein Gebbinck

    Roy,

    Thanks. I already knew how to save and load the program. And after looking at the file with a text editor, I figured out how to invoke the command. but it is not working for me. I will try again in the morning. I will let you know.

  • Post a (stripped down) sample DWG.

  • Hi Jim,
    due to the fact that the content of this thread is of general interest for users and lispers, i have programmed a lisp function in C#.NET
    which exposes certain subentity (in this case Faces) properties to the Lisp environment in a List and associates them with the main Entity a 3DSolid.
    The function and the return list have the following form

    (nl-getFaceInfo (ssget) ) the only argument is a selection set of 3D solids and the return list is

    ( ENAME HANDLE ( Face_ID Face_Type Face_Perimeter Face_Area Normal_Vector (if Type=Region) RGB_color Color_NAME or Index )
    (next face.....)
    (next face.....)
    (next face.....)
    .
    .
    )

    <Entity name: 2ede73e0> 
    "25D" 
    (1 "Surface" 1492.33240725419 97087.9489612077 (0 255 0) "green") 
    (2 "Region" 277.438807723436 2064.43582544874 (0.0 0.0 1.0) (0 0 0) "BYLAYER") 
    (3 "Surface" 2572.50663293589 175768.161280446 (2 131 148) "2,131,148") 
    (4 "Region" 311.324418033249 2281.40079727486 (0.0 0.0 -1.0) (26 195 36) "26,195,36") 
    (5 "Region" 79.628030319379 246.347225567993 (0.0 0.0 1.0) (0 0 0) "BYLAYER") 
    (6 "Region" 289.136595998814 2596.87527272948 (0.0 -1.0 0.0) (235 75 65) "235,75,65") 
    (7 "Region" 833.799123454887 33452.4598059416 (0.0 0.0 1.0) (115 70 174) "115,70,174") 
    (8 "Region" 520.619617779971 9428.73446978049 (0.0 -1.0 0.0) (242 4 141) "242,4,141") 
    (9 "Region" 748.65189639295 22372.8383768698 (-0.707106781186548 0.0 0.707106781186548) (0 255 0) "green") 
    (10 "Region" 317.339103390687 4310.37207213025 (1.0 0.0 0.0) (0 0 0) "BYLAYER") 
    (11 "Region" 1016.59937554973 33184.4181080199 (0.0 0.0 1.0) (0 0 0) "BYLAYER") 
    (12 "Region" 85.8325855198297 47.1070378024594 (0.0 0.0 -1.0) (26 195 36) "26,195,36") 
    (13 "Surface" 250.337414208527 2830.43543809951 (0 255 0) "green") 
    (14 "Region" 403.511011576603 8283.9654464393 (0.0 1.0 0.0) (0 0 0) "BYLAYER") 
    (15 "Surface" 5.27729243377409 0.771813638579688 (0 255 0) "green") 
    (16 "Region" 879.611445225848 61570.3864159636 (0.0 0.0 1.0) (34 221 89) "34,221,89") 
    (17 "Region" 89.666516282657 52.5855402146048 (0.0 0.707106781186546 0.707106781186549) (0 255 0) "green") 
    (18 "Surface" 2220.86828695285 246470.556172568 (110 224 97) "110,224,97") 
    (19 "Region" 2016.4957199039 160125.372464529 (-1.0 0.0 0.0) (120 115 144) "") 
    (20 "Region" 1561.08064036309 134572.763506899 (0.0 1.0 0.0) (45 236 68) "45,236,68") 120,115,144
    (21 "Region" 1345.88093697505 44931.5296086404 (1.0 0.0 0.0) (43 174 203) "43,174,203") 
    (22 "Region" 1810.96898917888 145505.621487902 (0.0 -1.0 0.0) (0 0 0) "BYLAYER") 
    (23 "Region" 1854.57923790943 214700.221773109 (0.0 0.0 -1.0) (143 204 174) "143,204,174") 
    

    The list associates the ENAME and HANLE of a 3D solid with the properties of its subentity faces !
    So as soon as the list is created, it can be queried again and again by a lisp program, looking up
    properties of the Faces and returning a selection set of Solids satisfying the query.
    The combinations are unlimited....for example
    " select all solids having faces with area >30"
    "select all solids having faces with color red or a specific color" (your case !)
    "select all solids having a certain orientation Normal_Vector= ..."
    etc

    I have also provided a lisp program to query the list and select solids having a faces with a certain color
    I assume this is what you need !

    (defun c:SBFC (/  ensol colors)
      ;select the required solids 
      (print "Select the required 3D solids : \n")
      (setq $$FACEINFO§§ (if (= $$FACEINFO§§ nil)  (nl-GetFaceInfo (ssget '((0 . "3DSOLID")) ) )$$FACEINFO§§ ) 
            ssByCol (ssadd)
            colors  (getstring T "Enter Color Name or Number (red, yellow,etc.. or 8-255 or BYLAYER or TrueColor 999,999,999) : \n")
      )
      ;(setq colors "red")
      (foreach m $$FACEINFO§§
        (setq ensol (car m)) ;get the ename of the solid
              (foreach f (cdr(cdr m))
                (cond 
                  (( = (cadr f) "Surface" )
                   (if (= (nth 5 f) colors) (ssadd ensol ssByCol))
                  )
                  (( = (cadr f) "Region" )
                   (if (= (nth 6 f) colors) (ssadd ensol ssByCol))
                  )
                )
              )
      )
      (sssetfirst nil ssByCol)
       ;ssByCol
    )
    (defun c:SBFCRESET () (setq $$FACEINFO§§ nil))
    

    The program defines 2 commands SBFC (Solids By Face Color) and SBFCRESET to be able to reset the list and select solids again
    if you need to query a different selection set of Solids within the same DWG file.
    Here is how to proceed
    Load both attached programs using the command APPLOAD and check Loaded and Autoload to have the programs automatically loaded
    in every Bricscad session and drawing.
    Then call the command SBFC and proceed...
    You could select some solids having a face color then reselect from these selected solids using another color thus combining 2 colors
    I can imagine that lispers in the Forum and probably colleages of yours could write wonderfull lisp routines to query the list of properties..
    I hope this helps...!
    You find attached the programs and a DWG test file
    The .dll file GetFaceInfo_BC.dll is compiled against Bricscad 20 x64, so if you have another version of Bricscad and therefore problem to load it ,
    i can provide a different version of the file appropriate for your system...but try it first, I would be glad to hear from you...i am 63 .......
    Enjoy

    image

  • I am attaching a new version of the file GetFaceInfo_BC.dll after having corrected a small bug....

  • @Roy Klein Gebbinck said:
    Post a (stripped down) sample DWG.

    Roy,
    Had to chop it up to almost nothing to attach it. What is the limit on the filesize of uploads?

  • @Konstantin Sakellaris said:
    I am attaching a new version of the file GetFaceInfo_BC.dll after having corrected a small bug....

    Konstantin,
    Thank you. You will have to give me a while to try to digest this. I know how to save and load a LISP file. I know nothing about C# NET.

  • @Konstantin Sakellaris
    That is nice, I bet many people don't know you can write a lisp function with .net.
    There is a bug I found with sending lists back from .net, which maybe bcad does not have.
    If I remember right, it would take a list of 3 integers, such as your rgb color item, and format it as a point instead of leaving it as a list.
    By format, I mean the first number in the dotted pair. That caused issues back in lisp, and it wasn't something you could work around.
    I ended up doing things purely through a string, where you serialize your lists and only send and receive strings from lisp and .net.
    You unserialize on each end back to a list.

    Also, if you could post the code to your main function in .net, that would be educational.
    I have libraries of helper functions I can't post as they are proprietary, but I typically can show at least what properties I am accessing.
    Up to you, once code is posted everyone can use it so totally your call of course.
    I do tell people not to use tools they don't have code for, in critical workflows, but then my purgeids is exactly that, but I would be happy to share code to help others make their own tool like mine. Kean actually posted the code originally, but I know how to use things like virtual grid by infralution so some specialized skills in there. The point is, trouble loves company so always fun to see others' code :)
    thx

  • I feel so stupid listening to you guys.....

  • @Jim Canale said:

    @Konstantin Sakellaris said:
    I am attaching a new version of the file GetFaceInfo_BC.dll after having corrected a small bug....

    Konstantin,
    Thank you. You will have to give me a while to try to digest this. I know how to save and load a LISP file. I know nothing about C# NET.

    @Jim Canale
    In this case, the .dll is the same as a lisp to you, but you must load using netload command, not drag in like lisp file.
    Once the dll is loaded, load the lisp and use the lisp function.
    I keep thinking though, can't eaglecad produce a dxf or dwg?
    I need to read your past posts, but am thinking if its traces on a board, maybe you get teh 2d linework from eaglecad, and pull into bcad and extrude.
    Like make the 3d thing from the 2d info.