Join surfaces & keep colors?

Rhino 7 has per face polysurface colors. Why isn’t there an option to keep different colors when you join surfaces or create a solid? Is there another tool for this I don’t know?

Hello- there is not a good way at the moment from single surfaces because single surfaces do not have per face colors assigned - Join pays attention to perface color assignment but these are not possible on single surfaces. I think there is a bug track item to allow this, I’ll see if I can find it, but it may be that it would just be confusing most of the time.

-Pascal

Maybe Join now needs a “PreserveObjectColors” option…

4 Likes

Yeah, that might be a good thing to try … but it would need to be more ‘granular’ wording (PreserveSurfaceColors or sum’n) since meshes and curves do not support this at all.

-Pascal

3 Likes

The single surface can have a face color, but subobject selection of the face is not possible via the UI ( Sub-object select face of monoface brep ).

The following script will set the face color of separate surfaces to their object color if the face color has not already been set (not System.Color.Empty). It can be used before _Join, _CreateSolid, etc.

Python script
from __future__ import print_function
import Rhino.DocObjects as rd
import rhinoscriptsyntax as rs
import scriptcontext as sc

from System.Drawing import Color

def main():
    
    gBs = rs.GetObjects("Select surfaces", filter=rs.filter.surface, preselect=True)
    if gBs is None: return
    
    gBs_Mod = []
    sLogs = []
    
    for gB in gBs:
        rdB = rs.coercerhinoobject(gB)
        
        if rdB.Attributes.ColorSource == rd.ObjectColorSource.ColorFromLayer:
            layer = sc.doc.Layers.FindIndex(rdB.Attributes.LayerIndex)
            color = layer.Color
        elif rdB.Attributes.ColorSource == rd.ObjectColorSource.ColorFromObject:
            color = rdB.Attributes.ObjectColor
        else:
            sLogs.append(str(rdB.Attributes.ColorSource))
            continue

        rgF = rdB.BrepGeometry.Faces[0]

        if rgF.PerFaceColor != Color.Empty or rgF.PerFaceColor == color:
            continue

        rgF.PerFaceColor = color

        if rdB.CommitChanges():
            gBs_Mod.append(gB)

    if gBs_Mod:
        print("{} surface face colors were modified.".format(len(gBs_Mod)))
    else:
        print("No surface face colors were modified.")

    if sLogs:
        for sLog in set(sLogs):
            print("{} surfaces have {} color source and were not modified.".format(
                sLogs.count(sLog), sLog))

    sc.doc.Views.Redraw()

if __name__ == '__main__': main()
1 Like