1 //-*****************************************************************************
2 //
3 // Copyright (c) 2009-2012,
4 // Sony Pictures Imageworks Inc. and
5 // Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd.
6 //
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are
11 // met:
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above
15 // copyright notice, this list of conditions and the following disclaimer
16 // in the documentation and/or other materials provided with the
17 // distribution.
18 // * Neither the name of Sony Pictures Imageworks, nor
19 // Industrial Light & Magic, nor the names of their contributors may be used
20 // to endorse or promote products derived from this software without specific
21 // prior written permission.
22 //
23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 //
35 //-*****************************************************************************
36
37 #include "ArbAttrUtil.h"
38 #include <sstream>
39 #include <cstring>
40
41 //-*****************************************************************************
42
~ParamListBuilder()43 ParamListBuilder::~ParamListBuilder()
44 {
45 for ( std::vector<RtString>::iterator I = m_retainedStrings.begin();
46 I != m_retainedStrings.end(); ++I )
47 {
48 free( (*I) );
49 }
50
51 m_retainedStrings.clear();
52 }
53
54
55 //-*****************************************************************************
add(const std::string & declaration,RtPointer value,ArraySamplePtr sampleToRetain)56 void ParamListBuilder::add( const std::string & declaration, RtPointer value,
57 ArraySamplePtr sampleToRetain )
58 {
59 //save a copy of the declaration string
60 m_retainedStrings.push_back( strdup( declaration.c_str() ) );
61 m_outputDeclarations.push_back( m_retainedStrings.back() );
62
63 m_values.push_back( value );
64
65 if ( sampleToRetain )
66 {
67 m_retainedSamples.push_back( sampleToRetain );
68 }
69 }
70
71 //-*****************************************************************************
n()72 RtInt ParamListBuilder::n()
73 {
74 return (RtInt) m_values.size();
75 }
76
77 //-*****************************************************************************
nms()78 RtToken* ParamListBuilder::nms()
79 {
80 if ( m_outputDeclarations.empty() ) { return 0; }
81
82 return &m_outputDeclarations.front();
83 }
84
85 //-*****************************************************************************
vals()86 RtPointer* ParamListBuilder::vals()
87 {
88 if ( m_values.empty() ) { return NULL; };
89
90 return &m_values.front();
91 }
92
93 //-*****************************************************************************
finishStringVector()94 RtPointer ParamListBuilder::finishStringVector()
95 {
96 RtPointer previous = NULL;
97
98 if ( !m_convertedStringVectors.empty() )
99 {
100 previous = &( (*m_convertedStringVectors.back())[0] );
101 }
102
103 m_convertedStringVectors.push_back( SharedRtStringVector(
104 new std::vector<RtString> ) );
105
106 return previous;
107 }
108
109 //-*****************************************************************************
addStringValue(const std::string & value,bool retainLocally)110 void ParamListBuilder::addStringValue( const std::string &value,
111 bool retainLocally )
112 {
113 if ( m_convertedStringVectors.empty() )
114 {
115 finishStringVector();
116 }
117
118 if ( retainLocally )
119 {
120 m_retainedStrings.push_back( strdup( value.c_str() ) );
121 m_convertedStringVectors.back()->push_back( m_retainedStrings.back() );
122 }
123 else
124 {
125 m_convertedStringVectors.back()->push_back(
126 const_cast<RtString>( value.c_str() ) );
127 }
128 }
129
130 //-*****************************************************************************
GetPrmanScopeString(GeometryScope scope)131 std::string GetPrmanScopeString( GeometryScope scope )
132 {
133 switch (scope)
134 {
135 case kUniformScope:
136 return "uniform";
137 case kVaryingScope:
138 return "varying";
139 case kVertexScope:
140 return "vertex";
141 case kFacevaryingScope:
142 return "facevarying";
143 case kConstantScope:
144 default:
145 return "constant";
146 }
147 }
148
149 //-*****************************************************************************
AddStringGeomParamToParamListBuilder(ICompoundProperty & parent,const PropertyHeader & propHeader,ISampleSelector & sampleSelector,ParamListBuilder & paramListBuilder)150 void AddStringGeomParamToParamListBuilder(
151 ICompoundProperty &parent,
152 const PropertyHeader &propHeader,
153 ISampleSelector &sampleSelector,
154 ParamListBuilder ¶mListBuilder
155 )
156 {
157 IStringGeomParam param( parent, propHeader.getName() );
158
159 if ( !param.valid() )
160 {
161 //TODO error message?
162 return;
163 }
164
165 std::string rmanType = GetPrmanScopeString( param.getScope() ) + " ";
166 rmanType += "string";
167
168 if ( param.getArrayExtent() > 1 )
169 {
170 std::ostringstream buffer;
171 buffer << "[" << param.getArrayExtent() << "]";
172 rmanType += buffer.str();
173 }
174
175 rmanType += " " + propHeader.getName();
176
177 StringArraySamplePtr valueSample = param.getExpandedValue(
178 sampleSelector ).getVals();
179
180
181 for ( size_t i = 0; i < valueSample->size(); ++i )
182 {
183 paramListBuilder.addStringValue( (*valueSample)[i] );
184 }
185
186 RtPointer dataStart = paramListBuilder.finishStringVector();
187
188 paramListBuilder.add(rmanType, dataStart, valueSample);
189
190 }
191
192
193 //-*****************************************************************************
AddArbitraryGeomParams(ICompoundProperty & parent,ISampleSelector & sampleSelector,ParamListBuilder & paramListBuilder,const std::set<std::string> * excludeNames)194 void AddArbitraryGeomParams( ICompoundProperty &parent,
195 ISampleSelector &sampleSelector,
196 ParamListBuilder ¶mListBuilder,
197 const std::set<std::string> * excludeNames
198 )
199 {
200 if ( !parent.valid() )
201 {
202 return;
203 }
204
205 for ( size_t i = 0; i < parent.getNumProperties(); ++i )
206 {
207 const PropertyHeader &propHeader = parent.getPropertyHeader( i );
208 const std::string &propName = propHeader.getName();
209
210 if (propName.empty()
211 || ( excludeNames
212 && excludeNames->find( propName ) != excludeNames->end() ) )
213 {
214 continue;
215 }
216
217 if ( IFloatGeomParam::matches( propHeader ) )
218 {
219 AddGeomParamToParamListBuilder<IFloatGeomParam>(
220 parent,
221 propHeader,
222 sampleSelector,
223 "float",
224 paramListBuilder);
225 }
226 else if ( IDoubleGeomParam::matches( propHeader ) )
227 {
228 AddGeomParamToParamListBuilderAsFloat<IDoubleGeomParam, double>(
229 parent,
230 propHeader,
231 sampleSelector,
232 "float",
233 paramListBuilder);
234 }
235 else if ( IV3dGeomParam::matches( propHeader ) )
236 {
237 AddGeomParamToParamListBuilderAsFloat<IV3dGeomParam, double>(
238 parent,
239 propHeader,
240 sampleSelector,
241 "vector",
242 paramListBuilder);
243 }
244 else if ( IInt32GeomParam::matches( propHeader ) )
245 {
246 AddGeomParamToParamListBuilder<IInt32GeomParam>(
247 parent,
248 propHeader,
249 sampleSelector,
250 "int",
251 paramListBuilder);
252 }
253 else if ( IStringGeomParam::matches( propHeader ) )
254 {
255 AddStringGeomParamToParamListBuilder(
256 parent,
257 propHeader,
258 sampleSelector,
259 paramListBuilder);
260 }
261 else if ( IV2fGeomParam::matches( propHeader ) )
262 {
263 AddGeomParamToParamListBuilder<IV2fGeomParam>(
264 parent,
265 propHeader,
266 sampleSelector,
267 "float",
268 paramListBuilder,
269 2);
270 }
271 else if ( IV3fGeomParam::matches( propHeader ) )
272 {
273 AddGeomParamToParamListBuilder<IV3fGeomParam>(
274 parent,
275 propHeader,
276 sampleSelector,
277 "vector",
278 paramListBuilder);
279 }
280 else if ( IP3fGeomParam::matches( propHeader ) )
281 {
282 AddGeomParamToParamListBuilder<IP3fGeomParam>(
283 parent,
284 propHeader,
285 sampleSelector,
286 "point",
287 paramListBuilder);
288 }
289 else if ( IP3dGeomParam::matches( propHeader ) )
290 {
291 AddGeomParamToParamListBuilderAsFloat<IP3dGeomParam, double>(
292 parent,
293 propHeader,
294 sampleSelector,
295 "point",
296 paramListBuilder);
297 }
298 else if ( IN3fGeomParam::matches( propHeader ) )
299 {
300 AddGeomParamToParamListBuilder<IN3fGeomParam>(
301 parent,
302 propHeader,
303 sampleSelector,
304 "normal",
305 paramListBuilder);
306 }
307 else if ( IC3fGeomParam::matches( propHeader ) )
308 {
309 AddGeomParamToParamListBuilder<IC3fGeomParam>(
310 parent,
311 propHeader,
312 sampleSelector,
313 "color",
314 paramListBuilder);
315 }
316 else if ( IM44fGeomParam::matches( propHeader ) )
317 {
318 AddGeomParamToParamListBuilder<IM44fGeomParam>(
319 parent,
320 propHeader,
321 sampleSelector,
322 "matrix",
323 paramListBuilder);
324 }
325 else if ( IBoolGeomParam::matches( propHeader ) )
326 {
327 AddGeomParamToParamListBuilderAsInt<IBoolGeomParam, bool_t>(
328 parent,
329 propHeader,
330 sampleSelector,
331 paramListBuilder);
332 }
333
334 }
335 }
336