1 /**************************************************************************\
2 * Copyright (c) Kongsberg Oil & Gas Technologies AS
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of the copyright holder nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32
33 /*!
34 \class SoMaterialBinding SoMaterialBinding.h Inventor/nodes/SoMaterialBinding.h
35 \brief The SoMaterialBinding class is a node for setting up how materials are mapped to shapes.
36
37 \ingroup nodes
38
39 The material binding specified in nodes of this type decides how the
40 material values of SoMaterial nodes are mapped on the builtin
41 geometry shape nodes.
42
43 The exact meaning of a binding depends on what particular shape type
44 a material or a set of materials are applied to.
45
46 Here is a very simple usage example:
47
48 \verbatim
49 #Inventor V2.1 ascii
50
51 Separator {
52 Coordinate3 {
53 point [ 0 0 0, 1 0 0, 1 1 0 ]
54 }
55
56 Material {
57 diffuseColor [ 1 0 0, 1 1 0, 0 0 1 ]
58 }
59
60 MaterialBinding {
61 value PER_VERTEX_INDEXED
62 }
63
64 IndexedFaceSet {
65 coordIndex [ 0, 1, 2, -1 ]
66 materialIndex [ 0, 1, 0 ]
67 }
68 }
69 \endverbatim
70
71 With SoMaterialBinding::value set to \c PER_VERTEX_INDEXED above,
72 the material indices will be taken from the
73 SoIndexedFaceSet::materialIndex field when rendering.
74
75 If SoMaterialBinding::value was set to \c PER_VERTEX_INDEXED as
76 above, and the SoIndexedFaceSet::materialIndex was undefined or
77 empty, indices would implicitly be taken from the
78 SoIndexedFaceSet::coordIndex field.
79
80 If SoMaterialBinding::value is set to \c PER_VERTEX, colors will be
81 fetched in a monotonically increasing manner from the
82 SoMaterial::diffuseColor field, starting at index 0.
83
84 <b>FILE FORMAT/DEFAULTS:</b>
85 \code
86 MaterialBinding {
87 value OVERALL
88 }
89 \endcode
90
91 \sa SoMaterial
92 */
93
94 // *************************************************************************
95
96 #include <Inventor/actions/SoCallbackAction.h>
97
98 #include <Inventor/actions/SoGLRenderAction.h>
99 #include <Inventor/actions/SoGetPrimitiveCountAction.h>
100 #include <Inventor/actions/SoPickAction.h>
101 #include <Inventor/elements/SoMaterialBindingElement.h>
102 #include <Inventor/elements/SoOverrideElement.h>
103
104 #include "nodes/SoSubNodeP.h"
105
106 // *************************************************************************
107
108 /*!
109 \enum SoMaterialBinding::Binding
110 Enumeration of available types of material binding.
111 */
112 /*!
113 \var SoMaterialBinding::Binding SoMaterialBinding::OVERALL
114 Apply the same material to the complete shape.
115 */
116 /*!
117 \var SoMaterialBinding::Binding SoMaterialBinding::PER_PART
118
119 Get a new material from the pool of material values for each \e part
120 of the shape, where the definition of a \e part depends on the shape
121 type.
122
123 Materials are fetched from index 0 and onwards, incrementing the
124 index into the material pool by 1 for each new part in the order
125 defined by the particular shape type.
126
127 Important portability note: it was previously allowed with the SGI
128 Inventor library to supply too few colors versus the number of parts
129 of the subsequent shapes in the scene graph. Coloring would then
130 cycle through the available colors.
131
132 Since SGI Open Inventor v2.1, this was disallowed, though -- enough
133 colors for all parts must be supplied, or behavior will be
134 unspecified (likely to cause a crash, in fact). Note that the
135 «Inventor Mentor» book contains a description of the \e old, \e
136 invalid behavior in Chapter 5, section "Binding Nodes" (middle of
137 page 128 in the 10th printing).
138 */
139 /*!
140 \var SoMaterialBinding::Binding SoMaterialBinding::PER_PART_INDEXED
141
142 Get a new material from the pool of material values for each \e part
143 of the shape, where the definition of a \e part depends on the shape
144 type.
145
146 Materials are fetched by the index value settings of the shape.
147 */
148 /*!
149 \var SoMaterialBinding::Binding SoMaterialBinding::PER_FACE
150
151 Get a new material from the pool of material values for each polygon
152 \e face of the shape.
153
154 Materials are fetched from index 0 and onwards, incrementing the
155 index into the material pool by 1 for each new face of the shape
156 node.
157
158 Note that individual faces after tessellation of complex shapes
159 (like SoCylinder nodes) are \e not considered to be separate
160 entities, and so this binding will be treated in the same manner as
161 SoMaterialBinding::PER_PART for those.
162 */
163 /*!
164 \var SoMaterialBinding::Binding SoMaterialBinding::PER_FACE_INDEXED
165
166 Get a new material from the pool of material values for each polygon
167 \e face of the shape.
168
169 Materials are fetched by the index value settings of the shape.
170
171 Note that individual faces after tessellation of complex shapes
172 (like SoCylinder nodes) are \e not considered to be separate
173 entities, and so this binding will be treated in the same manner as
174 SoMaterialBinding::PER_PART_INDEXED for those.
175 */
176 /*!
177 \var SoMaterialBinding::Binding SoMaterialBinding::PER_VERTEX
178
179 Get a new material from the pool of material values for each
180 polygon, line or point \e vertex of the shape.
181
182 Materials are fetched from index 0 and onwards, incrementing the
183 index into the material pool by 1 for each new vertex of the shape
184 node.
185 */
186 /*!
187 \var SoMaterialBinding::Binding SoMaterialBinding::PER_VERTEX_INDEXED
188
189 Get a new material from the pool of material values for each
190 polygon, line or point \e vertex of the shape.
191
192 Materials are fetched by the index value settings of the shape.
193 */
194
195
196
197 // Note: Inventor format files with SoMaterialBinding nodes with one
198 // of the two obsoleted values below will be updated upon import to
199 // contain the value for SoMaterialBinding::OVERALL. Ditto for calls
200 // to SoMaterialBinding::value.setValue([DEFAULT | NONE]).
201 //
202 // This happens automatically due to the way So[SM]FEnum fields are
203 // implemented.
204 // --mortene
205
206 /*!
207 \var SoMaterialBinding::Binding SoMaterialBinding::DEFAULT
208 Obsolete. Don't use this value.
209 */
210 /*!
211 \var SoMaterialBinding::Binding SoMaterialBinding::NONE
212 Obsolete. Don't use this value.
213 */
214
215
216 /*!
217 \var SoSFEnum SoMaterialBinding::value
218
219 The material binding to use for subsequent shape nodes in the scene
220 graph. The default binding is SoMaterialBinding::OVERALL.
221 */
222
223
224 // *************************************************************************
225
226 SO_NODE_SOURCE(SoMaterialBinding);
227
228 /*!
229 Constructor.
230 */
SoMaterialBinding(void)231 SoMaterialBinding::SoMaterialBinding(void)
232 {
233 SO_NODE_INTERNAL_CONSTRUCTOR(SoMaterialBinding);
234
235 SO_NODE_ADD_FIELD(value, (OVERALL));
236
237 SO_NODE_DEFINE_ENUM_VALUE(Binding, OVERALL);
238 SO_NODE_DEFINE_ENUM_VALUE(Binding, PER_PART);
239 SO_NODE_DEFINE_ENUM_VALUE(Binding, PER_PART_INDEXED);
240 SO_NODE_DEFINE_ENUM_VALUE(Binding, PER_FACE);
241 SO_NODE_DEFINE_ENUM_VALUE(Binding, PER_FACE_INDEXED);
242 SO_NODE_DEFINE_ENUM_VALUE(Binding, PER_VERTEX);
243 SO_NODE_DEFINE_ENUM_VALUE(Binding, PER_VERTEX_INDEXED);
244 SO_NODE_DEFINE_ENUM_VALUE(Binding, DEFAULT);
245 SO_NODE_DEFINE_ENUM_VALUE(Binding, NONE);
246
247 SO_NODE_SET_SF_ENUM_TYPE(value, Binding);
248 }
249
250
251 /*!
252 Destructor.
253 */
~SoMaterialBinding()254 SoMaterialBinding::~SoMaterialBinding()
255 {
256 }
257
258 // Doc from superclass.
259 void
initClass(void)260 SoMaterialBinding::initClass(void)
261 {
262 SO_NODE_INTERNAL_INIT_CLASS(SoMaterialBinding, SO_FROM_INVENTOR_1|SoNode::VRML1);
263
264 SO_ENABLE(SoGLRenderAction, SoMaterialBindingElement);
265 SO_ENABLE(SoPickAction, SoMaterialBindingElement);
266 SO_ENABLE(SoCallbackAction, SoMaterialBindingElement);
267 SO_ENABLE(SoGetPrimitiveCountAction, SoMaterialBindingElement);
268 }
269
270 // Doc from superclass.
271 void
GLRender(SoGLRenderAction * action)272 SoMaterialBinding::GLRender(SoGLRenderAction * action)
273 {
274 SoMaterialBinding::doAction(action);
275 }
276
277 // Doc from superclass.
278 void
doAction(SoAction * action)279 SoMaterialBinding::doAction(SoAction * action)
280 {
281 if (!this->value.isIgnored()
282 && !SoOverrideElement::getMaterialBindingOverride(action->getState())) {
283 SoMaterialBindingElement::set(action->getState(),
284 (SoMaterialBindingElement::Binding)
285 this->value.getValue());
286 if (this->isOverride()) {
287 SoOverrideElement::setMaterialBindingOverride(action->getState(), this, TRUE);
288 }
289 }
290 }
291
292 // Doc from superclass.
293 void
callback(SoCallbackAction * action)294 SoMaterialBinding::callback(SoCallbackAction * action)
295 {
296 SoMaterialBinding::doAction((SoAction *)action);
297 }
298
299 // Doc from superclass.
300 void
pick(SoPickAction * action)301 SoMaterialBinding::pick(SoPickAction * action)
302 {
303 SoMaterialBinding::doAction(action);
304 }
305
306 // Doc from superclass.
307 void
getPrimitiveCount(SoGetPrimitiveCountAction * action)308 SoMaterialBinding::getPrimitiveCount(SoGetPrimitiveCountAction * action)
309 {
310 SoMaterialBinding::doAction(action);
311 }
312