Object Color

import Rhino.Geometry as rg
import Rhino.Display as rd
import rhinoscriptsyntax as rs
import System.Drawing as sd

class ZPoint:
    def __init__(self,x,y,z):
        self.Zx=x
        self.Zy=y
        self.Zz=z
    def createPoint(self):
        self.pt=rg.Point3d(self.Zx,self.Zy,self.Zz)
        return self.pt
    def clr(self,Alpha,red,green,blue):
        self.A=Alpha
        self.r=red
        self.g=green
        self.b=blue
        if "display" not in globals():
            global display
            display=rd.CustomDisplay(True)
        display.Clear()
        if displayColor==False:
            display.Dispose()
            del display
        else:
            self.color=sd.Color.FromArgb(self.A,self.r,self.g,self.b)
            return display.AddPoint(self.pt,self.color,rd.PointStyle.X,5)

a=[]
for i in range(3):
    obj=ZPoint(i,0,0)
    obj.createPoint()
    a.append(obj.clr(100,i,0,50))

i try to display all objects color but it appears on of them in my point list.what is my mistake in my code_?

I think having that CustomDisplay object in the globals is making it harder than it should be to manage its state. I tend to use the sticky dictionary for variables that need to survive between solves of the component, otherwise it’s too easy to lose track of them and have them active but inaccessible.

Having that object inside the ZPoint class makes this harder as well.

Basically what you want is to create a new CustomDisplay each time, and make sure the previous, if it existed, has been disposed. Additionally, calling Dispose multiple times on the same object is probably harmless but not good form.

Here’s one way to do this, starting form your code and simplifying the ZPoint class:

import Rhino.Geometry as rg
import Rhino.Display as rd
import rhinoscriptsyntax as rs
import System.Drawing as sd
from scriptcontext import sticky


class ZPoint:
    def __init__(self, *pos):
        self.pt = rg.Point3d(*pos)

    def clr(self, alpha, red, green, blue, display):
        color = sd.Color.FromArgb(alpha, red, green, blue)
        return display.AddPoint(self.pt, color, rd.PointStyle.X, 5)

display = sticky.get("display", rd.CustomDisplay(True))
if not display.IsDisposed:
    display.Dispose()
display = rd.CustomDisplay(True)
sticky["display"] = display

if not displayColor:
    display.Dispose()
else:
    for i in range(3):
        obj = ZPoint(i, 0, 0)
        obj.clr(100, i * 50, 250 - i * 50, 50, display)
1 Like

thak you for ur replying.But my aim is to create a color method in my class for using every time when i call and maybe later every geometric object without bake

I think this is what the clr method here is doing: every time you call it on a ZPoint object it will add a special color display for that point, to the display object. That display object is properly disposed of when not used anymore.

There is no bake here.

You can reproduce a similar class for different kind of objects, and add displays for them to the same display object – as it is effectively a list of things to show it’s capable of keeping track of multiple types at the same time.

Why do you need to do this in Python? The Grasshopper component “Custom Preview” lets you do the same thing you are doing here. You can send a complete material for each object, as well a just a color.

These helper functions might also help:

That said, since Rhino 6/7 I’ve started to implement this method instead:

Also, you probably shouldn’t name a function clr. Since that’s the name of the .NET common language runtime namespace. Which might cause conflicts if you need to import clr when referencing an assembly etc.