-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcreate_specific_rendermaterial.literate
145 lines (110 loc) · 5.5 KB
/
create_specific_rendermaterial.literate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# Creating a specific material
_written by Nathan 'jesterKing' Letwory_
## Introduction
To create a specific material type we are going to use `RenderMaterial` from the
`Rhino.Render` namespace.
In this example we'll create a Paint material. To do so we'll need the type
GUID. The different type GUIDs can be found under `RenderMaterial` static
properties. In our case we need
[`RenderMaterial.PaintMaterialGuid`](https://developer.rhino3d.com/api/RhinoCommon/html/P_Rhino_Render_RenderMaterial_PaintMaterialGuid.htm).
A new instance we create with one of the static method [`RenderContent.Create()`
overloads](https://developer.rhino3d.com/api/RhinoCommon/html/Overload_Rhino_Render_RenderContent_Create.htm).
Using one of these overloads will result in the material being created _and_
added to the persistent content list. In other words it will show up in the
material editor.
## Main structure of the script
The script will be implemented as a script, not a command. It will import the
necessary modules and namespaces. It'll take note of the currently selected
objects. Then it will create a Paint material with random color assigned to it.
Finally the new material will be assigned to each of the selected objects.
```py : <<Creation Script.*>>= ./create_specific_rendermaterial.py $ template=rhipysrc.template
<<import necessary libraries>>
<<check for an object selection>>
<<if object selection exists create material and assign>>
```
## The imports
We need access to the `Rhino.Render` namespace for the material and render
content related classes. Further we want to access the document. For that we are
going to use `scriptcontext`. We'll import just the namespaces or modules
meaning we'll have to include these when using classes and functionality they
provide. We're doing that for this script to make it clear where the used bits
and pieces come from.
To create a random color we'll need the `random` module along with access to
`Color4f` from the `Rhino.Display` namespace.
```py : <<import necessary libraries>>=
import System
import Rhino.Display
import Rhino.Render
```
```py : <<import necessary libraries>>=+
import scriptcontext
import random
```
## Retrieve object selection
We'll keep the next part of the script simple. We're not going to ask the user
to select anything. Instead the script relies on the selection already being
made. We still create a material, but without a selection no assignment will be
made.
```py : <<check for an object selection>>=
# get object selection
object_selection = [ob for ob in scriptcontext.doc.Objects if ob.IsSelected(False)]
```
## Create and setup the material
We'll create and assign the material only when there is an object selection.
```py : <<if object selection exists create material and assign>>=
# only if we have a selection do the work
if object_selection:
<<create a paint material with random color>>
<<assign the material to the object selection>>
```
To create the material we use `RenderContent.Create`. We don't need much else
besides the render content GUID and the document.
Once we have a material we need to bracket any changes we want to make between
`BeginChange()` and `EndChange()` calls. Otherwise Rhino will ignore any
programmatical changes to the render content because it is already in the
document after creation.
We set a name suffixed with a new GUID each time this material is created by the
script. This so we don't end up with materials that have the same name. While it
is possible to do so with a script names should really be unique.
```py : <<create a paint material with random color>>=
# create material
render_material = Rhino.Render.RenderContent.Create(
Rhino.Render.RenderMaterial.PaintMaterialGuid,
Rhino.Render.RenderContent.ShowContentChooserFlags.None,
scriptcontext.doc)
render_material.BeginChange(Rhino.Render.RenderContent.ChangeContexts.Program)
render_material.Name = "PYSCRIPTCREATED " + System.Guid.NewGuid().ToString()
random_color = Rhino.Display.Color4f(
random.random(),
random.random(),
random.random(),
1.0)
render_material.SetParameter("color", random_color)
render_material.EndChange()
```
## Assign material to objects
Now that we have a material we can assign it to each object in our selection.
For Rhino to notice changes to objects in the document we need to do something
similar like the method above for changing render content that is already in the
document. We have to `CommitChanges()` on the object for the changes to stick.
```py : <<assign the material to the object selection>>=
# assign
for ob in object_selection:
print("Adding material", render_material.Name, "to", ob)
ob.RenderMaterial = render_material
ob.CommitChanges()
```
## Conclusion
It is relatively straightforward to programmatically create new render content
in Rhino. There are a few mechanisms the programmer needs to be mindful of:
bracketing of changes to render content, and explicitely committing changes made
to document objects.
Note that this particular implementation does not really check whether it is
useful to even have a `RenderMaterial` assigned. It would be good to add that
extra security.
Furthermore the script could be improved with a piece of code that actually
queries the user for object selection if none has been made.
These improvements are left to the reader to implement, as the main goal here
has been achieved: show how to create and assign a new material of a specific
type.
The generated script is in the repository [here](https://github.com/jesterKing/rhipy/blob/master/create_specific_rendermaterial.py)