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 &paramListBuilder
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 &paramListBuilder,
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