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 // SoConvertAll is an internal class used for converting values
34 // between all built-in field types.
35 //
36 // Note that this class is not supposed to be used by the application
37 // programmer -- so the API class definition header file is not
38 // installed.
39 
40 // *************************************************************************
41 
42 #include "engines/SoConvertAll.h"
43 
44 #include "SbBasicP.h"
45 
46 #include <cassert>
47 
48 #include <Inventor/SoDB.h>
49 #include <Inventor/errors/SoDebugError.h>
50 #include <Inventor/fields/SoFields.h>
51 #include <Inventor/lists/SoEngineOutputList.h>
52 #include <Inventor/lists/SoFieldList.h>
53 #include <Inventor/lists/SoTypeList.h>
54 
55 #include "tidbitsp.h"
56 #include "engines/SoSubEngineP.h"
57 #include "misc/SbHash.h"
58 
59 // *************************************************************************
60 
61 // FIXME: should perhaps use SbTime::parseDate() for So[SM]FString ->
62 // So[SM]FTime conversion? 20000331 mortene.
63 
64 // *************************************************************************
65 
66 typedef void convert_func(SoField * from, SoField * to);
67 typedef SbHash<uint32_t, convert_func *> UInt32ToConverterFuncMap;
68 
69 static UInt32ToConverterFuncMap * convertfunc_dict = NULL;
70 
71 // *************************************************************************
72 
73 // SoConvertAll uses a dynamic list for each instance with information
74 // about input fields and engine outputs, not like the other engines
75 // (which have a single static list for each class).
76 //
77 // Because of this, we can't use the SO_ENGINE_ABSTRACT_SOURCE macro.
78 
79 PRIVATE_ENGINE_TYPESYSTEM_SOURCE(SoConvertAll);
80 unsigned int SoConvertAll::classinstances = 0;
81 const SoFieldData ** SoConvertAll::parentinputdata = NULL;
82 const SoEngineOutputData ** SoConvertAll::parentoutputdata = NULL;
83 
84 const SoFieldData *
getFieldData(void) const85 SoConvertAll::getFieldData(void) const
86 {
87   return this->inputdata_instance;
88 }
89 
90 const SoEngineOutputData *
getOutputData(void) const91 SoConvertAll::getOutputData(void) const
92 {
93   return this->outputdata_instance;
94 }
95 
96 // These are unused, but we list them here since they are part of the
97 // SO_ENGINE_ABSTRACT_HEADER macro, which we are using for
98 // convenience.
99 SoFieldData * SoConvertAll::inputdata = reinterpret_cast<SoFieldData *>(0x1);
100 SoEngineOutputData * SoConvertAll::outputdata = reinterpret_cast<SoEngineOutputData *>(0x1);
getInputDataPtr(void)101 const SoFieldData ** SoConvertAll::getInputDataPtr(void) { return NULL; }
getOutputDataPtr(void)102 const SoEngineOutputData ** SoConvertAll::getOutputDataPtr(void) { return NULL; }
103 
104 void
atexit_cleanup(void)105 SoConvertAll::atexit_cleanup(void)
106 {
107   SoConvertAll::parentinputdata = NULL;
108   SoConvertAll::parentoutputdata = NULL;
109   SoConvertAll::classTypeId STATIC_SOTYPE_INIT;
110   SoConvertAll::classinstances = 0;
111 }
112 
113 // Defines functions for converting between vec2*-fields with different primitive types
114 #define SOCONVERTALL_SINGLE2SINGLE_VEC2(_fromto_, _from_, _to_, _fromtype_, _totype_, _toprim_) \
115 static void _fromto_(SoField * from, SoField * to) { \
116   _fromtype_ val(coin_assert_cast<_from_ *>(from)->getValue()); \
117   coin_assert_cast<_to_ *>(to)->setValue(_totype_(static_cast<_toprim_>(val[0]), static_cast<_toprim_>(val[1]))); \
118 }
119 
120 #define SOCONVERTALL_SINGLE2MULTI_VEC2(_fromto_, _from_, _to_, _fromtype_, _totype_, _toprim_) \
121 static void _fromto_(SoField * from, SoField * to) { \
122   _fromtype_ val(coin_assert_cast<_from_ *>(from)->getValue()); \
123   coin_assert_cast<_to_ *>(to)->setValue(_totype_(static_cast<_toprim_>(val[0]), static_cast<_toprim_>(val[1]))); \
124 }
125 
126 #define SOCONVERTALL_MULTI2SINGLE_VEC2(_fromto_, _from_, _to_, _fromtype_, _totype_, _toprim_) \
127 static void _fromto_(SoField * from, SoField * to) { \
128   _fromtype_ val(coin_assert_cast<_from_ *>(from)->operator[](0)); \
129   coin_assert_cast<_to_ *>(to)->setValue(_totype_(static_cast<_toprim_>(val[0]), static_cast<_toprim_>(val[1]))); \
130 }
131 
132 #define SOCONVERTALL_MULTI2MULTI_VEC2(_fromto_, _from_, _to_, _fromtype_, _totype_, _toprim_) \
133 static void _fromto_(SoField * from, SoField * to) { \
134   const int num = coin_assert_cast<_from_ *>(from)->getNum(); \
135   for ( int i = 0; i < num; i++ ) { \
136     _fromtype_ val(coin_assert_cast<_from_ *>(from)->operator[](i)); \
137     coin_assert_cast<_to_ *>(to)->set1Value(i, _totype_(static_cast<_toprim_>(val[0]), static_cast<_toprim_>(val[1]))); \
138   } \
139 }
140 
141 // Defines functions for converting between vec3*-fields with different primitive types
142 #define SOCONVERTALL_SINGLE2SINGLE_VEC3(_fromto_, _from_, _to_, _fromtype_, _totype_, _toprim_) \
143 static void _fromto_(SoField * from, SoField * to) { \
144   _fromtype_ val(coin_assert_cast<_from_ *>(from)->getValue()); \
145   coin_assert_cast<_to_ *>(to)->setValue(_totype_(static_cast<_toprim_>(val[0]), static_cast<_toprim_>(val[1]), static_cast<_toprim_>(val[2]))); \
146 }
147 
148 #define SOCONVERTALL_SINGLE2MULTI_VEC3(_fromto_, _from_, _to_, _fromtype_, _totype_, _toprim_) \
149 static void _fromto_(SoField * from, SoField * to) { \
150   _fromtype_ val(coin_assert_cast<_from_ *>(from)->getValue()); \
151   coin_assert_cast<_to_ *>(to)->setValue(_totype_(static_cast<_toprim_>(val[0]), static_cast<_toprim_>(val[1]), static_cast<_toprim_>(val[2]))); \
152 }
153 
154 #define SOCONVERTALL_MULTI2SINGLE_VEC3(_fromto_, _from_, _to_, _fromtype_, _totype_, _toprim_) \
155 static void _fromto_(SoField * from, SoField * to) { \
156   _fromtype_ val(coin_assert_cast<_from_ *>(from)->operator[](0)); \
157   coin_assert_cast<_to_ *>(to)->setValue(_totype_(static_cast<_toprim_>(val[0]), static_cast<_toprim_>(val[1]), static_cast<_toprim_>(val[2]))); \
158 }
159 
160 #define SOCONVERTALL_MULTI2MULTI_VEC3(_fromto_, _from_, _to_, _fromtype_, _totype_, _toprim_) \
161 static void _fromto_(SoField * from, SoField * to) { \
162   const int num = coin_assert_cast<_from_ *>(from)->getNum(); \
163   for ( int i = 0; i < num; i++ ) { \
164     _fromtype_ val(coin_assert_cast<_from_ *>(from)->operator[](i)); \
165     coin_assert_cast<_to_ *>(to)->set1Value(i, _totype_(static_cast<_toprim_>(val[0]), static_cast<_toprim_>(val[1]), static_cast<_toprim_>(val[2]))); \
166   } \
167 }
168 
169 // vec4 is only Vec4f - no other types yet
170 
171 // short-to-float (no SoMFVec2s exists yet)
172 SOCONVERTALL_SINGLE2SINGLE_VEC2(SoSFVec2f_to_SoSFVec2s, SoSFVec2f, SoSFVec2s, SbVec2f, SbVec2s, short);
173 SOCONVERTALL_SINGLE2SINGLE_VEC2(SoSFVec2s_to_SoSFVec2f, SoSFVec2s, SoSFVec2f, SbVec2s, SbVec2f, float);
174 // SOCONVERTALL_SINGLE2MULTI_VEC2(SoSFVec2f_to_SoMFVec2s, SoSFVec2f, SoMFVec2s, SbVec2f, SbVec2s, short);
175 SOCONVERTALL_SINGLE2MULTI_VEC2(SoSFVec2s_to_SoMFVec2f, SoSFVec2s, SoMFVec2f, SbVec2s, SbVec2f, float);
176 SOCONVERTALL_MULTI2SINGLE_VEC2(SoMFVec2f_to_SoSFVec2s, SoMFVec2f, SoSFVec2s, SbVec2f, SbVec2s, short);
177 // SOCONVERTALL_MULTI2SINGLE_VEC2(SoMFVec2s_to_SoSFVec2f, SoMFVec2s, SoSFVec2f, SbVec2s, SbVec2f, float);
178 // SOCONVERTALL_MULTI2MULTI_VEC2(SoMFVec2f_to_SoMFVec2s, SoMFVec2f, SoMFVec2s, SbVec2f, SbVec2s, short);
179 // SOCONVERTALL_MULTI2MULTI_VEC2(SoMFVec2s_to_SoMFVec2f, SoMFVec2s, SoMFVec2f, SbVec2s, SbVec2f, float);
180 
181 // float-to-double
182 SOCONVERTALL_SINGLE2SINGLE_VEC3(SoSFVec3f_to_SoSFVec3d, SoSFVec3f, SoSFVec3d, SbVec3f, SbVec3d, double);
183 SOCONVERTALL_SINGLE2SINGLE_VEC3(SoSFVec3d_to_SoSFVec3f, SoSFVec3d, SoSFVec3f, SbVec3d, SbVec3f, float);
184 SOCONVERTALL_SINGLE2MULTI_VEC3(SoSFVec3f_to_SoMFVec3d, SoSFVec3f, SoMFVec3d, SbVec3f, SbVec3d, double);
185 SOCONVERTALL_SINGLE2MULTI_VEC3(SoSFVec3d_to_SoMFVec3f, SoSFVec3d, SoMFVec3f, SbVec3d, SbVec3f, float);
186 SOCONVERTALL_MULTI2SINGLE_VEC3(SoMFVec3f_to_SoSFVec3d, SoMFVec3f, SoSFVec3d, SbVec3f, SbVec3d, double);
187 SOCONVERTALL_MULTI2SINGLE_VEC3(SoMFVec3d_to_SoSFVec3f, SoMFVec3d, SoSFVec3f, SbVec3d, SbVec3f, float);
188 SOCONVERTALL_MULTI2MULTI_VEC3(SoMFVec3f_to_SoMFVec3d, SoMFVec3f, SoMFVec3d, SbVec3f, SbVec3d, double);
189 SOCONVERTALL_MULTI2MULTI_VEC3(SoMFVec3d_to_SoMFVec3f, SoMFVec3d, SoMFVec3f, SbVec3d, SbVec3f, float);
190 
191 // short-to-float (no SoMFVec3s exists yet)
192 SOCONVERTALL_SINGLE2SINGLE_VEC3(SoSFVec3s_to_SoSFVec3f, SoSFVec3s, SoSFVec3f, SbVec3s, SbVec3f, float);
193 SOCONVERTALL_SINGLE2SINGLE_VEC3(SoSFVec3f_to_SoSFVec3s, SoSFVec3f, SoSFVec3s, SbVec3f, SbVec3s, short);
194 SOCONVERTALL_SINGLE2MULTI_VEC3(SoSFVec3s_to_SoMFVec3f, SoSFVec3s, SoMFVec3f, SbVec3s, SbVec3f, float);
195 // SOCONVERTALL_SINGLE2MULTI_VEC3(SoSFVec3f_to_SoMFVec3s, SoSFVec3f, SoMFVec3s, SbVec3f, SbVec3s, short);
196 // SOCONVERTALL_MULTI2SINGLE_VEC3(SoMFVec3s_to_SoSFVec3f, SoMFVec3s, SoSFVec3f, SbVec3s, SbVec3f, float);
197 SOCONVERTALL_MULTI2SINGLE_VEC3(SoMFVec3f_to_SoSFVec3s, SoMFVec3f, SoSFVec3s, SbVec3f, SbVec3s, short);
198 // SOCONVERTALL_MULTI2MULTI_VEC3(SoMFVec3s_to_SoMFVec3f, SoMFVec3s, SoMFVec3f, SbVec3s, SbVec3f, float);
199 // SOCONVERTALL_MULTI2MULTI_VEC3(SoMFVec3f_to_SoMFVec3s, SoMFVec3f, SoMFVec3s, SbVec3f, SbVec3s, short);
200 
201 // short-to-double (no SoMFVec3s exists yet)
202 SOCONVERTALL_SINGLE2SINGLE_VEC3(SoSFVec3s_to_SoSFVec3d, SoSFVec3s, SoSFVec3d, SbVec3s, SbVec3d, double);
203 SOCONVERTALL_SINGLE2SINGLE_VEC3(SoSFVec3d_to_SoSFVec3s, SoSFVec3d, SoSFVec3s, SbVec3d, SbVec3s, short);
204 SOCONVERTALL_SINGLE2MULTI_VEC3(SoSFVec3s_to_SoMFVec3d, SoSFVec3s, SoMFVec3d, SbVec3s, SbVec3d, double);
205 // SOCONVERTALL_SINGLE2MULTI_VEC3(SoSFVec3d_to_SoMFVec3s, SoSFVec3d, SoMFVec3s, SbVec3d, SbVec3s, short);
206 // SOCONVERTALL_MULTI2SINGLE_VEC3(SoMFVec3s_to_SoSFVec3d, SoMFVec3s, SoSFVec3d, SbVec3s, SbVec3d, double);
207 SOCONVERTALL_MULTI2SINGLE_VEC3(SoMFVec3d_to_SoSFVec3s, SoMFVec3d, SoSFVec3s, SbVec3d, SbVec3s, short);
208 // SOCONVERTALL_MULTI2MULTI_VEC3(SoMFVec3s_to_SoMFVec3d, SoMFVec3s, SoMFVec3d, SbVec3s, SbVec3d, double);
209 // SOCONVERTALL_MULTI2MULTI_VEC3(SoMFVec3d_to_SoMFVec3s, SoMFVec3d, SoMFVec3s, SbVec3d, SbVec3s, short);
210 
211 #undef SOCONVERTALL_SINGLE2SINGLE_VEC2
212 #undef SOCONVERTALL_SINGLE2MULTI_VEC2
213 #undef SOCONVERTALL_MULTI2SINGLE_VEC2
214 #undef SOCONVERTALL_MULTI2MULTI_VEC2
215 #undef SOCONVERTALL_SINGLE2SINGLE_VEC3
216 #undef SOCONVERTALL_SINGLE2MULTI_VEC3
217 #undef SOCONVERTALL_MULTI2SINGLE_VEC3
218 #undef SOCONVERTALL_MULTI2MULTI_VEC3
219 
220 // Defines function for converting SoSFXXX -> SoMFXXX.
221 #define SOCONVERTALL_SINGLE2MULTI(_fromto_, _from_, _to_) \
222 static void _fromto_(SoField * from, SoField * to) \
223 { \
224   coin_assert_cast<_to_ *>(to)->setValue(coin_assert_cast<_from_ *>(from)->getValue()); \
225 }
226 
227 // Defines function for converting SoMFXXX -> SoSFXXX.
228 #define SOCONVERTALL_MULTI2SINGLE(_fromto_, _from_, _to_) \
229 static void _fromto_(SoField * from, SoField * to) \
230 { \
231   if (coin_assert_cast<_from_ *>(from)->getNum() > 0) \
232     coin_assert_cast<_to_ *>(to)->setValue((*coin_assert_cast<_from_ *>(from))[0]); \
233 }
234 
235 
236 SOCONVERTALL_SINGLE2MULTI(SoSFBitMask_SoMFBitMask, SoSFBitMask, SoMFBitMask);
237 SOCONVERTALL_MULTI2SINGLE(SoMFBitMask_SoSFBitMask, SoMFBitMask, SoSFBitMask);
238 SOCONVERTALL_SINGLE2MULTI(SoSFBool_SoMFBool, SoSFBool, SoMFBool);
239 SOCONVERTALL_MULTI2SINGLE(SoMFBool_SoSFBool, SoMFBool, SoSFBool);
240 SOCONVERTALL_SINGLE2MULTI(SoSFColor_SoMFColor, SoSFColor, SoMFColor);
241 SOCONVERTALL_MULTI2SINGLE(SoMFColor_SoSFColor, SoMFColor, SoSFColor);
242 SOCONVERTALL_SINGLE2MULTI(SoSFEnum_SoMFEnum, SoSFEnum, SoMFEnum);
243 SOCONVERTALL_MULTI2SINGLE(SoMFEnum_SoSFEnum, SoMFEnum, SoSFEnum);
244 SOCONVERTALL_SINGLE2MULTI(SoSFFloat_SoMFFloat, SoSFFloat, SoMFFloat);
245 SOCONVERTALL_MULTI2SINGLE(SoMFFloat_SoSFFloat, SoMFFloat, SoSFFloat);
246 SOCONVERTALL_SINGLE2MULTI(SoSFInt32_SoMFInt32, SoSFInt32, SoMFInt32);
247 SOCONVERTALL_MULTI2SINGLE(SoMFInt32_SoSFInt32, SoMFInt32, SoSFInt32);
248 SOCONVERTALL_SINGLE2MULTI(SoSFMatrix_SoMFMatrix, SoSFMatrix, SoMFMatrix);
249 SOCONVERTALL_MULTI2SINGLE(SoMFMatrix_SoSFMatrix, SoMFMatrix, SoSFMatrix);
250 SOCONVERTALL_SINGLE2MULTI(SoSFName_SoMFName, SoSFName, SoMFName);
251 SOCONVERTALL_MULTI2SINGLE(SoMFName_SoSFName, SoMFName, SoSFName);
252 SOCONVERTALL_SINGLE2MULTI(SoSFNode_SoMFNode, SoSFNode, SoMFNode);
253 SOCONVERTALL_MULTI2SINGLE(SoMFNode_SoSFNode, SoMFNode, SoSFNode);
254 SOCONVERTALL_SINGLE2MULTI(SoSFPath_SoMFPath, SoSFPath, SoMFPath);
255 SOCONVERTALL_MULTI2SINGLE(SoMFPath_SoSFPath, SoMFPath, SoSFPath);
256 SOCONVERTALL_SINGLE2MULTI(SoSFPlane_SoMFPlane, SoSFPlane, SoMFPlane);
257 SOCONVERTALL_MULTI2SINGLE(SoMFPlane_SoSFPlane, SoMFPlane, SoSFPlane);
258 SOCONVERTALL_SINGLE2MULTI(SoSFRotation_SoMFRotation, SoSFRotation, SoMFRotation);
259 SOCONVERTALL_MULTI2SINGLE(SoMFRotation_SoSFRotation, SoMFRotation, SoSFRotation);
260 SOCONVERTALL_SINGLE2MULTI(SoSFShort_SoMFShort, SoSFShort, SoMFShort);
261 SOCONVERTALL_MULTI2SINGLE(SoMFShort_SoSFShort, SoMFShort, SoSFShort);
262 SOCONVERTALL_SINGLE2MULTI(SoSFString_SoMFString, SoSFString, SoMFString);
263 SOCONVERTALL_MULTI2SINGLE(SoMFString_SoSFString, SoMFString, SoSFString);
264 SOCONVERTALL_SINGLE2MULTI(SoSFTime_SoMFTime, SoSFTime, SoMFTime);
265 SOCONVERTALL_MULTI2SINGLE(SoMFTime_SoSFTime, SoMFTime, SoSFTime);
266 SOCONVERTALL_SINGLE2MULTI(SoSFUInt32_SoMFUInt32, SoSFUInt32, SoMFUInt32);
267 SOCONVERTALL_MULTI2SINGLE(SoMFUInt32_SoSFUInt32, SoMFUInt32, SoSFUInt32);
268 SOCONVERTALL_SINGLE2MULTI(SoSFUShort_SoMFUShort, SoSFUShort, SoMFUShort);
269 SOCONVERTALL_MULTI2SINGLE(SoMFUShort_SoSFUShort, SoMFUShort, SoSFUShort);
270 // SOCONVERTALL_SINGLE2MULTI(SoSFVec2s_SoMFVec2s, SoSFVec2s, SoMFVec2s);
271 // SOCONVERTALL_MULTI2SINGLE(SoMFVec2s_SoSFVec2s, SoMFVec2s, SoSFVec2s);
272 SOCONVERTALL_SINGLE2MULTI(SoSFVec2f_SoMFVec2f, SoSFVec2f, SoMFVec2f);
273 SOCONVERTALL_MULTI2SINGLE(SoMFVec2f_SoSFVec2f, SoMFVec2f, SoSFVec2f);
274 // SOCONVERTALL_SINGLE2MULTI(SoSFVec3s_SoMFVec3s, SoSFVec3s, SoMFVec3s);
275 // SOCONVERTALL_MULTI2SINGLE(SoMFVec3s_SoSFVec3s, SoMFVec3s, SoSFVec3s);
276 SOCONVERTALL_SINGLE2MULTI(SoSFVec3f_SoMFVec3f, SoSFVec3f, SoMFVec3f);
277 SOCONVERTALL_MULTI2SINGLE(SoMFVec3f_SoSFVec3f, SoMFVec3f, SoSFVec3f);
278 SOCONVERTALL_SINGLE2MULTI(SoSFVec3d_SoMFVec3d, SoSFVec3d, SoMFVec3d);
279 SOCONVERTALL_MULTI2SINGLE(SoMFVec3d_SoSFVec3d, SoMFVec3d, SoSFVec3d);
280 SOCONVERTALL_SINGLE2MULTI(SoSFVec4f_SoMFVec4f, SoSFVec4f, SoMFVec4f);
281 SOCONVERTALL_MULTI2SINGLE(SoMFVec4f_SoSFVec4f, SoMFVec4f, SoSFVec4f);
282 
283 #undef SOCONVERTALL_SINGLE2MULTI
284 #undef SOCONVERTALL_MULTI2SINGLE
285 
286 
287 // Function for converting SoField -> SoSFString.
field_to_sfstring(SoField * from,SoField * to)288 static void field_to_sfstring(SoField * from, SoField * to)
289 {
290   SbString s;
291   from->get(s);
292   coin_assert_cast<SoSFString *>(to)->setValue(s);
293 }
294 
295 // Function for converting SoSFString -> SoField.
sfstring_to_field(SoField * from,SoField * to)296 static void sfstring_to_field(SoField * from, SoField * to)
297 {
298   to->set(coin_assert_cast<SoSFString *>(from)->getValue().getString());
299 }
300 
301 // Function for converting SoSField -> SoMFString.
sfield_to_mfstring(SoField * from,SoField * to)302 static void sfield_to_mfstring(SoField * from, SoField * to)
303 {
304   SbString s;
305   coin_assert_cast<SoSField *>(from)->get(s);
306   coin_assert_cast<SoMFString *>(to)->setValue(s);
307 }
308 
309 // Function for converting SoMFString -> SoSField.
mfstring_to_sfield(SoField * from,SoField * to)310 static void mfstring_to_sfield(SoField * from, SoField * to)
311 {
312   if (coin_assert_cast<SoMFString *>(from)->getNum() > 0)
313     coin_assert_cast<SoSField *>(to)->set((*coin_assert_cast<SoMFString *>(from))[0].getString());
314 }
315 
316 // Function for converting SoMField -> SoMFString.
mfield_to_mfstring(SoField * from,SoField * to)317 static void mfield_to_mfstring(SoField * from, SoField * to)
318 {
319   unsigned int numvals = coin_assert_cast<SoMField *>(from)->getNum();
320   coin_assert_cast<SoMField *>(to)->setNum(numvals);
321   SbString s;
322   for (unsigned int i=0; i < numvals; i++) {
323     coin_assert_cast<SoMField *>(from)->get1(i, s);
324     coin_assert_cast<SoMFString *>(to)->set1Value(i, s);
325   }
326 }
327 
328 // Function for converting SoMFString -> SoMField.
mfstring_to_mfield(SoField * from,SoField * to)329 static void mfstring_to_mfield(SoField * from, SoField * to)
330 {
331   unsigned int numvals = coin_assert_cast<SoMField *>(from)->getNum();
332   coin_assert_cast<SoMField *>(to)->setNum(numvals);
333 
334   for (unsigned int i=0; i < numvals; i++)
335     coin_assert_cast<SoMField *>(to)->set1(i, (*coin_assert_cast<SoMFString *>(from))[i].getString());
336 }
337 
338 // Defines function for converting SoSField -> SoField, where
339 // conversion is just a typecast.
340 #define SOCONVERTALL_CAST_SFIELD2FIELD(_fromto_, _from_, _to_, _tobase_) \
341 static void _fromto_(SoField * from, SoField * to) \
342 { \
343   coin_assert_cast<_to_ *>(to)->setValue(static_cast<_tobase_>(coin_assert_cast<_from_ *>(from)->getValue())); \
344 }
345 
346 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFBool_SoSFFloat, SoSFBool, SoSFFloat, float);
347 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFBool_SoMFFloat, SoSFBool, SoMFFloat, float);
348 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFFloat_SoSFBool, SoSFFloat, SoSFBool, SbBool);
349 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFFloat_SoMFBool, SoSFFloat, SoMFBool, SbBool);
350 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFBool_SoSFInt32, SoSFBool, SoSFInt32, int32_t);
351 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFBool_SoMFInt32, SoSFBool, SoMFInt32, int32_t);
352 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFInt32_SoSFBool, SoSFInt32, SoSFBool, SbBool);
353 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFInt32_SoMFBool, SoSFInt32, SoMFBool, SbBool);
354 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFBool_SoSFShort, SoSFBool, SoSFShort, short);
355 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFBool_SoMFShort, SoSFBool, SoMFShort, short);
356 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFShort_SoSFBool, SoSFShort, SoSFBool, SbBool);
357 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFShort_SoMFBool, SoSFShort, SoMFBool, SbBool);
358 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFBool_SoSFUInt32, SoSFBool, SoSFUInt32, unsigned short);
359 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFBool_SoMFUInt32, SoSFBool, SoMFUInt32, unsigned short);
360 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUInt32_SoSFBool, SoSFUInt32, SoSFBool, SbBool);
361 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUInt32_SoMFBool, SoSFUInt32, SoMFBool, SbBool);
362 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFBool_SoSFUShort, SoSFBool, SoSFUShort, unsigned short);
363 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFBool_SoMFUShort, SoSFBool, SoMFUShort, unsigned short);
364 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUShort_SoSFBool, SoSFUShort, SoSFBool, SbBool);
365 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUShort_SoMFBool, SoSFUShort, SoMFBool, SbBool);
366 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFColor_SoSFVec3f, SoSFColor, SoSFVec3f, SbVec3f);
367 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFColor_SoMFVec3f, SoSFColor, SoMFVec3f, SbVec3f);
368 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFVec3f_SoSFColor, SoSFVec3f, SoSFColor, SbColor);
369 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFVec3f_SoMFColor, SoSFVec3f, SoMFColor, SbColor);
370 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFFloat_SoSFInt32, SoSFFloat, SoSFInt32, int32_t);
371 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFFloat_SoMFInt32, SoSFFloat, SoMFInt32, int32_t);
372 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFInt32_SoSFFloat, SoSFInt32, SoSFFloat, float);
373 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFInt32_SoMFFloat, SoSFInt32, SoMFFloat, float);
374 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFFloat_SoSFShort, SoSFFloat, SoSFShort, short);
375 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFFloat_SoMFShort, SoSFFloat, SoMFShort, short);
376 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFShort_SoSFFloat, SoSFShort, SoSFFloat, float);
377 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFShort_SoMFFloat, SoSFShort, SoMFFloat, float);
378 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFFloat_SoSFUInt32, SoSFFloat, SoSFUInt32, uint32_t);
379 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFFloat_SoMFUInt32, SoSFFloat, SoMFUInt32, uint32_t);
380 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUInt32_SoSFFloat, SoSFUInt32, SoSFFloat, float);
381 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUInt32_SoMFFloat, SoSFUInt32, SoMFFloat, float);
382 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFFloat_SoSFUShort, SoSFFloat, SoSFUShort, unsigned short);
383 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFFloat_SoMFUShort, SoSFFloat, SoMFUShort, unsigned short);
384 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUShort_SoSFFloat, SoSFUShort, SoSFFloat, float);
385 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUShort_SoMFFloat, SoSFUShort, SoMFFloat, float);
386 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFInt32_SoSFShort, SoSFInt32, SoSFShort, short);
387 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFInt32_SoMFShort, SoSFInt32, SoMFShort, short);
388 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFShort_SoSFInt32, SoSFShort, SoSFInt32, int32_t);
389 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFShort_SoMFInt32, SoSFShort, SoMFInt32, int32_t);
390 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFInt32_SoSFUInt32, SoSFInt32, SoSFUInt32, uint32_t);
391 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFInt32_SoMFUInt32, SoSFInt32, SoMFUInt32, uint32_t);
392 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUInt32_SoSFInt32, SoSFUInt32, SoSFInt32, int32_t);
393 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUInt32_SoMFInt32, SoSFUInt32, SoMFInt32, int32_t);
394 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFInt32_SoSFUShort, SoSFInt32, SoSFUShort, unsigned short);
395 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFInt32_SoMFUShort, SoSFInt32, SoMFUShort, unsigned short);
396 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUShort_SoSFInt32, SoSFUShort, SoSFInt32, int32_t);
397 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUShort_SoMFInt32, SoSFUShort, SoMFInt32, int32_t);
398 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFShort_SoSFUInt32, SoSFShort, SoSFUInt32, uint32_t);
399 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFShort_SoMFUInt32, SoSFShort, SoMFUInt32, uint32_t);
400 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUInt32_SoSFShort, SoSFUInt32, SoSFShort, short);
401 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUInt32_SoMFShort, SoSFUInt32, SoMFShort, short);
402 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFShort_SoSFUShort, SoSFShort, SoSFUShort, unsigned short);
403 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFShort_SoMFUShort, SoSFShort, SoMFUShort, unsigned short);
404 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUShort_SoSFShort, SoSFUShort, SoSFShort, short);
405 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUShort_SoMFShort, SoSFUShort, SoMFShort, short);
406 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUInt32_SoSFUShort, SoSFUInt32, SoSFUShort, unsigned short);
407 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUInt32_SoMFUShort, SoSFUInt32, SoMFUShort, unsigned short);
408 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUShort_SoSFUInt32, SoSFUShort, SoSFUInt32, uint32_t);
409 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFUShort_SoMFUInt32, SoSFUShort, SoMFUInt32, uint32_t);
410 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFFloat_SoSFTime, SoSFFloat, SoSFTime, SbTime);
411 SOCONVERTALL_CAST_SFIELD2FIELD(SoSFFloat_SoMFTime, SoSFFloat, SoMFTime, SbTime);
412 
413 // Defines function for converting SoMField -> SoSField, where
414 // conversion is just a typecast.
415 #define SOCONVERTALL_CAST_MFIELD2SFIELD(_fromto_, _from_, _to_, _tobase_) \
416 static void _fromto_(SoField * from, SoField * to) \
417 { \
418   if (coin_assert_cast<_from_ *>(from)->getNum() > 0) \
419     coin_assert_cast<_to_ *>(to)->setValue(static_cast<_tobase_>((*coin_assert_cast<_from_ *>(from))[0])); \
420 }
421 
422 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFBool_SoSFFloat, SoMFBool, SoSFFloat, float);
423 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFFloat_SoSFBool, SoMFFloat, SoSFBool, SbBool);
424 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFBool_SoSFInt32, SoMFBool, SoSFInt32, int32_t);
425 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFInt32_SoSFBool, SoMFInt32, SoSFBool, SbBool);
426 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFBool_SoSFShort, SoMFBool, SoSFShort, short);
427 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFShort_SoSFBool, SoMFShort, SoSFBool, SbBool);
428 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFBool_SoSFUInt32, SoMFBool, SoSFUInt32, uint32_t);
429 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFUInt32_SoSFBool, SoMFUInt32, SoSFBool, SbBool);
430 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFBool_SoSFUShort, SoMFBool, SoSFUShort, unsigned short);
431 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFUShort_SoSFBool, SoMFUShort, SoSFBool, SbBool);
432 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFColor_SoSFVec3f, SoMFColor, SoSFVec3f, SbVec3f);
433 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFVec3f_SoSFColor, SoMFVec3f, SoSFColor, SbColor);
434 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFFloat_SoSFInt32, SoMFFloat, SoSFInt32, int32_t);
435 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFInt32_SoSFFloat, SoMFInt32, SoSFFloat, float);
436 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFFloat_SoSFShort, SoMFFloat, SoSFShort, short);
437 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFShort_SoSFFloat, SoMFShort, SoSFFloat, float);
438 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFFloat_SoSFUInt32, SoMFFloat, SoSFUInt32, uint32_t);
439 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFUInt32_SoSFFloat, SoMFUInt32, SoSFFloat, float);
440 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFFloat_SoSFUShort, SoMFFloat, SoSFUShort, unsigned short);
441 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFUShort_SoSFFloat, SoMFUShort, SoSFFloat, float);
442 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFInt32_SoSFShort, SoMFInt32, SoSFShort, short);
443 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFShort_SoSFInt32, SoMFShort, SoSFInt32, int32_t);
444 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFInt32_SoSFUInt32, SoMFInt32, SoSFUInt32, uint32_t);
445 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFUInt32_SoSFInt32, SoMFUInt32, SoSFInt32, int32_t);
446 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFInt32_SoSFUShort, SoMFInt32, SoSFUShort, unsigned short);
447 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFUShort_SoSFInt32, SoMFUShort, SoSFInt32, int32_t);
448 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFShort_SoSFUInt32, SoMFShort, SoSFUInt32, uint32_t);
449 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFUInt32_SoSFShort, SoMFUInt32, SoSFShort, short);
450 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFShort_SoSFUShort, SoMFShort, SoSFUShort, unsigned short);
451 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFUShort_SoSFShort, SoMFUShort, SoSFShort, short);
452 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFUInt32_SoSFUShort, SoMFUInt32, SoSFUShort, unsigned short);
453 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFUShort_SoSFUInt32, SoMFUShort, SoSFUInt32, uint32_t);
454 SOCONVERTALL_CAST_MFIELD2SFIELD(SoMFFloat_SoSFTime, SoMFFloat, SoSFTime, SbTime);
455 
456 // Defines functions for converting SoMField -> SoMField, where
457 // conversion is just a typecast.
458 #define SOCONVERTALL_CAST_MFIELD2MFIELD(_fromto_, _from_, _to_, _tobase_) \
459 static void _fromto_(SoField * from, SoField * to) \
460 { \
461   unsigned int numvals = coin_assert_cast<SoMField *>(from)->getNum(); \
462   coin_assert_cast<SoMField *>(to)->setNum(numvals); \
463   for (unsigned int i=0; i < numvals; i++) \
464     coin_assert_cast<_to_ *>(to)->set1Value(i, static_cast<_tobase_>((*coin_assert_cast<_from_ *>(from))[i])); \
465 }
466 
467 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFBool_SoMFFloat, SoMFBool, SoMFFloat, float);
468 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFFloat_SoMFBool, SoMFFloat, SoMFBool, SbBool);
469 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFBool_SoMFInt32, SoMFBool, SoMFInt32, int32_t);
470 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFInt32_SoMFBool, SoMFInt32, SoMFBool, SbBool);
471 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFBool_SoMFShort, SoMFBool, SoMFShort, short);
472 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFShort_SoMFBool, SoMFShort, SoMFBool, SbBool);
473 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFBool_SoMFUInt32, SoMFBool, SoMFUInt32, uint32_t);
474 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFUInt32_SoMFBool, SoMFUInt32, SoMFBool, SbBool);
475 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFBool_SoMFUShort, SoMFBool, SoMFUShort, unsigned short);
476 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFUShort_SoMFBool, SoMFUShort, SoMFBool, SbBool);
477 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFColor_SoMFVec3f, SoMFColor, SoMFVec3f, SbVec3f);
478 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFVec3f_SoMFColor, SoMFVec3f, SoMFColor, SbColor);
479 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFFloat_SoMFInt32, SoMFFloat, SoMFInt32, int32_t);
480 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFInt32_SoMFFloat, SoMFInt32, SoMFFloat, float);
481 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFFloat_SoMFShort, SoMFFloat, SoMFShort, short);
482 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFShort_SoMFFloat, SoMFShort, SoMFFloat, float);
483 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFFloat_SoMFUInt32, SoMFFloat, SoMFUInt32, uint32_t);
484 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFUInt32_SoMFFloat, SoMFUInt32, SoMFFloat, float);
485 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFFloat_SoMFUShort, SoMFFloat, SoMFUShort, unsigned short);
486 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFUShort_SoMFFloat, SoMFUShort, SoMFFloat, float);
487 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFInt32_SoMFShort, SoMFInt32, SoMFShort, short);
488 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFShort_SoMFInt32, SoMFShort, SoMFInt32, int32_t);
489 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFInt32_SoMFUInt32, SoMFInt32, SoMFUInt32, uint32_t);
490 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFUInt32_SoMFInt32, SoMFUInt32, SoMFInt32, int32_t);
491 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFInt32_SoMFUShort, SoMFInt32, SoMFUShort, unsigned short);
492 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFUShort_SoMFInt32, SoMFUShort, SoMFInt32, int32_t);
493 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFShort_SoMFUInt32, SoMFShort, SoMFUInt32, uint32_t);
494 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFUInt32_SoMFShort, SoMFUInt32, SoMFShort, short);
495 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFShort_SoMFUShort, SoMFShort, SoMFUShort, unsigned short);
496 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFUShort_SoMFShort, SoMFUShort, SoMFShort, short);
497 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFUInt32_SoMFUShort, SoMFUInt32, SoMFUShort, unsigned short);
498 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFUShort_SoMFUInt32, SoMFUShort, SoMFUInt32, uint32_t);
499 SOCONVERTALL_CAST_MFIELD2MFIELD(SoMFFloat_SoMFTime, SoMFFloat, SoMFTime, SbTime);
500 
501 
502 // Defines function for converting SoSFTime -> So[SM]FFloat.
503 #define SOCONVERTALL_CAST_SFTIME2SFFLOAT(_fromto_, _to_) \
504 static void _fromto_(SoField * from, SoField * to) \
505 { \
506   coin_assert_cast<_to_ *>(to)->setValue(static_cast<float>(coin_assert_cast<SoSFTime *>(from)->getValue().getValue())); \
507 }
508 
509 SOCONVERTALL_CAST_SFTIME2SFFLOAT(SoSFTime_SoSFFloat, SoSFFloat);
510 SOCONVERTALL_CAST_SFTIME2SFFLOAT(SoSFTime_SoMFFloat, SoMFFloat);
511 
512 // Function for converting SoMFTime -> SoSFFloat.
SoMFTime_SoSFFloat(SoField * from,SoField * to)513 static void SoMFTime_SoSFFloat(SoField * from, SoField * to)
514 {
515   if (coin_assert_cast<SoMField *>(from)->getNum() > 0)
516     coin_assert_cast<SoSFFloat *>(to)->setValue(static_cast<float>(((*coin_assert_cast<SoMFTime *>(from))[0]).getValue()));
517 }
518 
519 // Function for converting SoMFTime -> SoMFFloat.
SoMFTime_SoMFFloat(SoField * from,SoField * to)520 static void SoMFTime_SoMFFloat(SoField * from, SoField * to)
521 {
522   unsigned int numvals = coin_assert_cast<SoMField *>(from)->getNum();
523   coin_assert_cast<SoMField *>(to)->setNum(numvals);
524   for (unsigned int i=0; i < numvals; i++)
525     coin_assert_cast<SoMFFloat *>(to)->set1Value(i, static_cast<float>(((*coin_assert_cast<SoMFTime *>(from))[i]).getValue()));
526 }
527 
528 
529 
530 // Defines function for converting SoSFMatrix -> So[SM]FRotation.
531 #define SOCONVERTALL_SFMATRIX2ROTATION(_fromto_, _to_) \
532 static void _fromto_(SoField * from, SoField * to) \
533 { \
534   coin_assert_cast<_to_ *>(to)->setValue(SbRotation(coin_assert_cast<SoSFMatrix *>(from)->getValue())); \
535 }
536 
537 SOCONVERTALL_SFMATRIX2ROTATION(SoSFMatrix_SoSFRotation, SoSFRotation);
538 SOCONVERTALL_SFMATRIX2ROTATION(SoSFMatrix_SoMFRotation, SoMFRotation);
539 
540 // Function for converting SoMFMatrix -> SoSFRotation.
SoMFMatrix_SoSFRotation(SoField * from,SoField * to)541 static void SoMFMatrix_SoSFRotation(SoField * from, SoField * to)
542 {
543   if (coin_assert_cast<SoMField *>(from)->getNum() > 0)
544     coin_assert_cast<SoSFRotation *>(to)->setValue(SbRotation(((*coin_assert_cast<SoMFMatrix *>(from))[0])));
545 }
546 
547 // Function for converting SoMFMatrix -> SoMFRotation.
SoMFMatrix_SoMFRotation(SoField * from,SoField * to)548 static void SoMFMatrix_SoMFRotation(SoField * from, SoField * to)
549 {
550   for (int i=0; i < coin_assert_cast<SoMField *>(from)->getNum(); i++)
551     coin_assert_cast<SoMFRotation *>(to)->set1Value(i, SbRotation(((*coin_assert_cast<SoMFMatrix *>(from))[i])));
552 }
553 
554 
555 // Defines function for converting SoSFRotation -> So[SM]FMatrix.
556 #define SOCONVERTALL_SFROTATION2MATRIX(_fromto_, _to_) \
557 static void _fromto_(SoField * from, SoField * to) \
558 { \
559   SbMatrix mat; \
560   mat.setRotate(coin_assert_cast<SoSFRotation *>(from)->getValue()); \
561   coin_assert_cast<_to_ *>(to)->setValue(mat); \
562 }
563 
564 SOCONVERTALL_SFROTATION2MATRIX(SoSFRotation_SoSFMatrix, SoSFMatrix);
565 SOCONVERTALL_SFROTATION2MATRIX(SoSFRotation_SoMFMatrix, SoMFMatrix);
566 
567 // Function for converting SoMFRotation -> SoSFMatrix.
SoMFRotation_SoSFMatrix(SoField * from,SoField * to)568 static void SoMFRotation_SoSFMatrix(SoField * from, SoField * to)
569 {
570   if (coin_assert_cast<SoMField *>(from)->getNum() > 0) {
571     SbMatrix mat;
572     mat.setRotate((*coin_assert_cast<SoMFRotation *>(from))[0]);
573     coin_assert_cast<SoSFMatrix *>(to)->setValue(mat);
574   }
575 }
576 
577 // Function for converting SoMFRotation -> SoMFMatrix.
SoMFRotation_SoMFMatrix(SoField * from,SoField * to)578 static void SoMFRotation_SoMFMatrix(SoField * from, SoField * to)
579 {
580   unsigned int numvals = coin_assert_cast<SoMField *>(from)->getNum();
581   coin_assert_cast<SoMField *>(to)->setNum(numvals);
582   for (unsigned int i=0; i < numvals; i++) {
583     SbMatrix mat;
584     mat.setRotate((*coin_assert_cast<SoMFRotation *>(from))[i]);
585     coin_assert_cast<SoMFMatrix *>(to)->set1Value(i, mat);
586   }
587 }
588 
589 
590 // Helper function for the So[SM]FTime -> So[SM]FString converters
591 // below.
time2string(const SbTime & t,SbString & s)592 static void time2string(const SbTime & t, SbString & s)
593 {
594   // Value is less than a year, assume we're counting seconds. Use
595   // resolution at millisecond accuracy.
596   if (t.getValue() < (60.0*60.0*24.0*365.0)) {
597     cc_string storedlocale;
598     SbBool changed = coin_locale_set_portable(&storedlocale);
599     s.sprintf("%.3f", t.getValue());
600     if (changed) { coin_locale_reset(&storedlocale); }
601   }
602 
603   // Value is more than a year, assume we're interested in the date
604   // and time.
605 #if 0 // Don't default to ISO 8601 conformant string, ...
606   // Note: if this is ever enabled, remember that the format string
607   // need to be different on MSWindows systems.
608   else s = t.formatDate("%A %Y-%m-%d %H:%M:%S");
609 #else // .. follow Open Inventor instead.
610   else s = t.formatDate();
611 #endif
612 }
613 
614 // Function for converting SoSFTime -> SoSFString.
sftime_to_sfstring(SoField * from,SoField * to)615 static void sftime_to_sfstring(SoField * from, SoField * to)
616 {
617   SbString s;
618   time2string(coin_assert_cast<SoSFTime *>(from)->getValue(), s);
619   coin_assert_cast<SoSFString *>(to)->setValue(s);
620 }
621 
622 // Function for converting SoSFTime -> SoMFString.
sftime_to_mfstring(SoField * from,SoField * to)623 static void sftime_to_mfstring(SoField * from, SoField * to)
624 {
625   SbString s;
626   time2string(coin_assert_cast<SoSFTime *>(from)->getValue(), s);
627   coin_assert_cast<SoMFString *>(to)->setValue(s);
628 }
629 
630 // Function for converting SoMFTime -> SoSFString.
mftime_to_sfstring(SoField * from,SoField * to)631 static void mftime_to_sfstring(SoField * from, SoField * to)
632 {
633   SoMFTime * ff = coin_assert_cast<SoMFTime *>(from);
634   if (ff->getNum() > 0) {
635     SbString s;
636     time2string((*ff)[0], s);
637     coin_assert_cast<SoSFString *>(to)->setValue(s);
638   }
639 }
640 
641 // Function for converting SoMFTime -> SoMFString.
mftime_to_mfstring(SoField * from,SoField * to)642 static void mftime_to_mfstring(SoField * from, SoField * to)
643 {
644   SoMFTime * ff = coin_assert_cast<SoMFTime *>(from);
645   unsigned int numvals = ff->getNum();
646   coin_assert_cast<SoMField *>(to)->setNum(numvals);
647   SbString s;
648   for (unsigned int i=0; i < numvals; i++) {
649     time2string((*ff)[i], s);
650     coin_assert_cast<SoMFString *>(to)->set1Value(i, s);
651   }
652 }
653 
654 // Function for "converting" SoField -> SoSFTrigger _and_
655 // SoSFTrigger -> SoField.
to_and_from_sftrigger(SoField * COIN_UNUSED_ARG (from),SoField * to)656 static void to_and_from_sftrigger(SoField * COIN_UNUSED_ARG(from), SoField * to)
657 {
658   to->setDirty(FALSE);
659 }
660 
661 static void
register_convertfunc(convert_func * f,SoType from,SoType to)662 register_convertfunc(convert_func * f, SoType from, SoType to)
663 {
664   SoDB::addConverter(from, to, SoConvertAll::getClassTypeId());
665   uint32_t val = (static_cast<uint32_t>(from.getKey()) << 16) + to.getKey();
666   SbBool nonexist = convertfunc_dict->put(val, f);
667   assert(nonexist);
668 }
669 
670 extern "C" {
671 
convertall_cleanup_dict(void)672 static void convertall_cleanup_dict(void)
673 {
674   delete convertfunc_dict;
675   convertfunc_dict = NULL;
676 }
677 
678 } // extern "C"
679 
680 // doc in super
681 void
initClass(void)682 SoConvertAll::initClass(void)
683 {
684   convertfunc_dict = new UInt32ToConverterFuncMap;
685   coin_atexit(convertall_cleanup_dict, CC_ATEXIT_NORMAL);
686 
687   // SoConvertAll doesn't have a createInstance() method (because it
688   // doesn't have a default constructor), so use the ABSTRACT macros.
689   SO_ENGINE_INTERNAL_INIT_ABSTRACT_CLASS(SoConvertAll);
690 
691   struct Conversion {
692     convert_func * func;
693     const char * from;
694     const char * to;
695   };
696 
697   struct Conversion allconverters[] = {
698     { SoSFBitMask_SoMFBitMask, "SoSFBitMask", "SoMFBitMask" },
699     { SoMFBitMask_SoSFBitMask, "SoMFBitMask", "SoSFBitMask" },
700     { SoSFBool_SoMFBool, "SoSFBool", "SoMFBool" },
701     { SoMFBool_SoSFBool, "SoMFBool", "SoSFBool" },
702     { SoSFColor_SoMFColor, "SoSFColor", "SoMFColor" },
703     { SoMFColor_SoSFColor, "SoMFColor", "SoSFColor" },
704     { SoSFEnum_SoMFEnum, "SoSFEnum", "SoMFEnum" },
705     { SoMFEnum_SoSFEnum, "SoMFEnum", "SoSFEnum" },
706     { SoSFFloat_SoMFFloat, "SoSFFloat", "SoMFFloat" },
707     { SoMFFloat_SoSFFloat, "SoMFFloat", "SoSFFloat" },
708     { SoSFInt32_SoMFInt32, "SoSFInt32", "SoMFInt32" },
709     { SoMFInt32_SoSFInt32, "SoMFInt32", "SoSFInt32" },
710     { SoSFMatrix_SoMFMatrix, "SoSFMatrix", "SoMFMatrix" },
711     { SoMFMatrix_SoSFMatrix, "SoMFMatrix", "SoSFMatrix" },
712     { SoSFName_SoMFName, "SoSFName", "SoMFName" },
713     { SoMFName_SoSFName, "SoMFName", "SoSFName" },
714     { SoSFNode_SoMFNode, "SoSFNode", "SoMFNode" },
715     { SoMFNode_SoSFNode, "SoMFNode", "SoSFNode" },
716     { SoSFPath_SoMFPath, "SoSFPath", "SoMFPath" },
717     { SoMFPath_SoSFPath, "SoMFPath", "SoSFPath" },
718     { SoSFPlane_SoMFPlane, "SoSFPlane", "SoMFPlane" },
719     { SoMFPlane_SoSFPlane, "SoMFPlane", "SoSFPlane" },
720     { SoSFRotation_SoMFRotation, "SoSFRotation", "SoMFRotation" },
721     { SoMFRotation_SoSFRotation, "SoMFRotation", "SoSFRotation" },
722     { SoSFShort_SoMFShort, "SoSFShort", "SoMFShort" },
723     { SoMFShort_SoSFShort, "SoMFShort", "SoSFShort" },
724     { SoSFString_SoMFString, "SoSFString", "SoMFString" },
725     { SoMFString_SoSFString, "SoMFString", "SoSFString" },
726     { SoSFTime_SoMFTime, "SoSFTime", "SoMFTime" },
727     { SoMFTime_SoSFTime, "SoMFTime", "SoSFTime" },
728     { SoSFUInt32_SoMFUInt32, "SoSFUInt32", "SoMFUInt32" },
729     { SoMFUInt32_SoSFUInt32, "SoMFUInt32", "SoSFUInt32" },
730     { SoSFUShort_SoMFUShort, "SoSFUShort", "SoMFUShort" },
731     { SoMFUShort_SoSFUShort, "SoMFUShort", "SoSFUShort" },
732     { SoSFVec2f_SoMFVec2f, "SoSFVec2f", "SoMFVec2f" },
733     { SoMFVec2f_SoSFVec2f, "SoMFVec2f", "SoSFVec2f" },
734     { SoSFVec3f_SoMFVec3f, "SoSFVec3f", "SoMFVec3f" },
735     { SoMFVec3f_SoSFVec3f, "SoMFVec3f", "SoSFVec3f" },
736     { SoSFVec4f_SoMFVec4f, "SoSFVec4f", "SoMFVec4f" },
737     { SoMFVec4f_SoSFVec4f, "SoMFVec4f", "SoSFVec4f" },
738     { SoSFVec3d_SoMFVec3d, "SoSFVec3d", "SoMFVec3d" },
739     { SoMFVec3d_SoSFVec3d, "SoMFVec3d", "SoSFVec3d" },
740     { field_to_sfstring, "SoMFBitMask", "SoSFString" },
741     { field_to_sfstring, "SoMFBool", "SoSFString" },
742     { field_to_sfstring, "SoMFColor", "SoSFString" },
743     { field_to_sfstring, "SoMFEnum", "SoSFString" },
744     { field_to_sfstring, "SoMFFloat", "SoSFString" },
745     { field_to_sfstring, "SoMFInt32", "SoSFString" },
746     { field_to_sfstring, "SoMFMatrix", "SoSFString" },
747     { field_to_sfstring, "SoMFName", "SoSFString" },
748     { field_to_sfstring, "SoMFNode", "SoSFString" },
749     { field_to_sfstring, "SoMFPath", "SoSFString" },
750     { field_to_sfstring, "SoMFPlane", "SoSFString" },
751     { field_to_sfstring, "SoMFRotation", "SoSFString" },
752     { field_to_sfstring, "SoMFShort", "SoSFString" },
753     { field_to_sfstring, "SoMFUInt32", "SoSFString" },
754     { field_to_sfstring, "SoMFUShort", "SoSFString" },
755     { field_to_sfstring, "SoMFVec2f", "SoSFString" },
756     { field_to_sfstring, "SoMFVec3f", "SoSFString" },
757     { field_to_sfstring, "SoMFVec4f", "SoSFString" },
758     { field_to_sfstring, "SoSFBitMask", "SoSFString" },
759     { field_to_sfstring, "SoSFBool", "SoSFString" },
760     { field_to_sfstring, "SoSFColor", "SoSFString" },
761     { field_to_sfstring, "SoSFEnum", "SoSFString" },
762     { field_to_sfstring, "SoSFFloat", "SoSFString" },
763     { field_to_sfstring, "SoSFInt32", "SoSFString" },
764     { field_to_sfstring, "SoSFMatrix", "SoSFString" },
765     { field_to_sfstring, "SoSFName", "SoSFString" },
766     { field_to_sfstring, "SoSFNode", "SoSFString" },
767     { field_to_sfstring, "SoSFPath", "SoSFString" },
768     { field_to_sfstring, "SoSFPlane", "SoSFString" },
769     { field_to_sfstring, "SoSFRotation", "SoSFString" },
770     { field_to_sfstring, "SoSFShort", "SoSFString" },
771     { field_to_sfstring, "SoSFUInt32", "SoSFString" },
772     { field_to_sfstring, "SoSFUShort", "SoSFString" },
773     { field_to_sfstring, "SoSFVec2s", "SoSFString" },
774     { field_to_sfstring, "SoSFVec2f", "SoSFString" },
775     { field_to_sfstring, "SoSFVec3s", "SoSFString" },
776     { field_to_sfstring, "SoSFVec3f", "SoSFString" },
777     { field_to_sfstring, "SoSFVec3d", "SoSFString" },
778     { field_to_sfstring, "SoSFVec4f", "SoSFString" },
779     { sfield_to_mfstring, "SoSFBitMask", "SoMFString" },
780     { sfield_to_mfstring, "SoSFBool", "SoMFString" },
781     { sfield_to_mfstring, "SoSFColor", "SoMFString" },
782     { sfield_to_mfstring, "SoSFEnum", "SoMFString" },
783     { sfield_to_mfstring, "SoSFFloat", "SoMFString" },
784     { sfield_to_mfstring, "SoSFInt32", "SoMFString" },
785     { sfield_to_mfstring, "SoSFMatrix", "SoMFString" },
786     { sfield_to_mfstring, "SoSFName", "SoMFString" },
787     { sfield_to_mfstring, "SoSFNode", "SoMFString" },
788     { sfield_to_mfstring, "SoSFPath", "SoMFString" },
789     { sfield_to_mfstring, "SoSFPlane", "SoMFString" },
790     { sfield_to_mfstring, "SoSFRotation", "SoMFString" },
791     { sfield_to_mfstring, "SoSFShort", "SoMFString" },
792     { sfield_to_mfstring, "SoSFUInt32", "SoMFString" },
793     { sfield_to_mfstring, "SoSFUShort", "SoMFString" },
794     { sfield_to_mfstring, "SoSFVec2s", "SoMFString" },
795     { sfield_to_mfstring, "SoSFVec2f", "SoMFString" },
796     { sfield_to_mfstring, "SoSFVec3s", "SoMFString" },
797     { sfield_to_mfstring, "SoSFVec3f", "SoMFString" },
798     { sfield_to_mfstring, "SoSFVec3d", "SoMFString" },
799     { sfield_to_mfstring, "SoSFVec4f", "SoMFString" },
800     { mfield_to_mfstring, "SoMFBitMask", "SoMFString" },
801     { mfield_to_mfstring, "SoMFBool", "SoMFString" },
802     { mfield_to_mfstring, "SoMFColor", "SoMFString" },
803     { mfield_to_mfstring, "SoMFEnum", "SoMFString" },
804     { mfield_to_mfstring, "SoMFFloat", "SoMFString" },
805     { mfield_to_mfstring, "SoMFInt32", "SoMFString" },
806     { mfield_to_mfstring, "SoMFMatrix", "SoMFString" },
807     { mfield_to_mfstring, "SoMFName", "SoMFString" },
808     { mfield_to_mfstring, "SoMFNode", "SoMFString" },
809     { mfield_to_mfstring, "SoMFPath", "SoMFString" },
810     { mfield_to_mfstring, "SoMFPlane", "SoMFString" },
811     { mfield_to_mfstring, "SoMFRotation", "SoMFString" },
812     { mfield_to_mfstring, "SoMFShort", "SoMFString" },
813     { mfield_to_mfstring, "SoMFUInt32", "SoMFString" },
814     { mfield_to_mfstring, "SoMFUShort", "SoMFString" },
815     { mfield_to_mfstring, "SoMFVec2f", "SoMFString" },
816     { mfield_to_mfstring, "SoMFVec3f", "SoMFString" },
817     { mfield_to_mfstring, "SoMFVec3d", "SoMFString" },
818     { mfield_to_mfstring, "SoMFVec4f", "SoMFString" },
819     { sfstring_to_field, "SoSFString", "SoSFBitMask" },
820     { sfstring_to_field, "SoSFString", "SoSFBool" },
821     { sfstring_to_field, "SoSFString", "SoSFColor" },
822     { sfstring_to_field, "SoSFString", "SoSFEnum" },
823     { sfstring_to_field, "SoSFString", "SoSFFloat" },
824     { sfstring_to_field, "SoSFString", "SoSFInt32" },
825     { sfstring_to_field, "SoSFString", "SoSFMatrix" },
826     { sfstring_to_field, "SoSFString", "SoSFName" },
827     { sfstring_to_field, "SoSFString", "SoSFNode" },
828     { sfstring_to_field, "SoSFString", "SoSFPath" },
829     { sfstring_to_field, "SoSFString", "SoSFPlane" },
830     { sfstring_to_field, "SoSFString", "SoSFRotation" },
831     { sfstring_to_field, "SoSFString", "SoSFShort" },
832     { sfstring_to_field, "SoSFString", "SoSFTime" },
833     { sfstring_to_field, "SoSFString", "SoSFUInt32" },
834     { sfstring_to_field, "SoSFString", "SoSFUShort" },
835     { sfstring_to_field, "SoSFString", "SoSFVec2s" },
836     { sfstring_to_field, "SoSFString", "SoSFVec2f" },
837     { sfstring_to_field, "SoSFString", "SoSFVec3s" },
838     { sfstring_to_field, "SoSFString", "SoSFVec3f" },
839     { sfstring_to_field, "SoSFString", "SoSFVec3d" },
840     { sfstring_to_field, "SoSFString", "SoSFVec4f" },
841     { sfstring_to_field, "SoSFString", "SoMFBitMask" },
842     { sfstring_to_field, "SoSFString", "SoMFBool" },
843     { sfstring_to_field, "SoSFString", "SoMFColor" },
844     { sfstring_to_field, "SoSFString", "SoMFEnum" },
845     { sfstring_to_field, "SoSFString", "SoMFFloat" },
846     { sfstring_to_field, "SoSFString", "SoMFInt32" },
847     { sfstring_to_field, "SoSFString", "SoMFMatrix" },
848     { sfstring_to_field, "SoSFString", "SoMFName" },
849     { sfstring_to_field, "SoSFString", "SoMFNode" },
850     { sfstring_to_field, "SoSFString", "SoMFPath" },
851     { sfstring_to_field, "SoSFString", "SoMFPlane" },
852     { sfstring_to_field, "SoSFString", "SoMFRotation" },
853     { sfstring_to_field, "SoSFString", "SoMFShort" },
854     { sfstring_to_field, "SoSFString", "SoMFTime" },
855     { sfstring_to_field, "SoSFString", "SoMFUInt32" },
856     { sfstring_to_field, "SoSFString", "SoMFUShort" },
857     { sfstring_to_field, "SoSFString", "SoMFVec2f" },
858     { sfstring_to_field, "SoSFString", "SoMFVec3f" },
859     { sfstring_to_field, "SoSFString", "SoMFVec3d" },
860     { sfstring_to_field, "SoSFString", "SoMFVec4f" },
861     { mfstring_to_sfield, "SoMFString", "SoSFBitMask" },
862     { mfstring_to_sfield, "SoMFString", "SoSFBool" },
863     { mfstring_to_sfield, "SoMFString", "SoSFColor" },
864     { mfstring_to_sfield, "SoMFString", "SoSFEnum" },
865     { mfstring_to_sfield, "SoMFString", "SoSFFloat" },
866     { mfstring_to_sfield, "SoMFString", "SoSFInt32" },
867     { mfstring_to_sfield, "SoMFString", "SoSFMatrix" },
868     { mfstring_to_sfield, "SoMFString", "SoSFName" },
869     { mfstring_to_sfield, "SoMFString", "SoSFNode" },
870     { mfstring_to_sfield, "SoMFString", "SoSFPath" },
871     { mfstring_to_sfield, "SoMFString", "SoSFPlane" },
872     { mfstring_to_sfield, "SoMFString", "SoSFRotation" },
873     { mfstring_to_sfield, "SoMFString", "SoSFShort" },
874     { mfstring_to_sfield, "SoMFString", "SoSFTime" },
875     { mfstring_to_sfield, "SoMFString", "SoSFUInt32" },
876     { mfstring_to_sfield, "SoMFString", "SoSFUShort" },
877     { mfstring_to_sfield, "SoMFString", "SoSFVec2s" },
878     { mfstring_to_sfield, "SoMFString", "SoSFVec2f" },
879     { mfstring_to_sfield, "SoMFString", "SoSFVec3s" },
880     { mfstring_to_sfield, "SoMFString", "SoSFVec3f" },
881     { mfstring_to_sfield, "SoMFString", "SoSFVec4f" },
882     { mfstring_to_sfield, "SoMFString", "SoSFVec3d" },
883     { mfstring_to_mfield, "SoMFString", "SoMFBitMask" },
884     { mfstring_to_mfield, "SoMFString", "SoMFBool" },
885     { mfstring_to_mfield, "SoMFString", "SoMFColor" },
886     { mfstring_to_mfield, "SoMFString", "SoMFEnum" },
887     { mfstring_to_mfield, "SoMFString", "SoMFFloat" },
888     { mfstring_to_mfield, "SoMFString", "SoMFInt32" },
889     { mfstring_to_mfield, "SoMFString", "SoMFMatrix" },
890     { mfstring_to_mfield, "SoMFString", "SoMFName" },
891     { mfstring_to_mfield, "SoMFString", "SoMFNode" },
892     { mfstring_to_mfield, "SoMFString", "SoMFPath" },
893     { mfstring_to_mfield, "SoMFString", "SoMFPlane" },
894     { mfstring_to_mfield, "SoMFString", "SoMFRotation" },
895     { mfstring_to_mfield, "SoMFString", "SoMFShort" },
896     { mfstring_to_mfield, "SoMFString", "SoMFTime" },
897     { mfstring_to_mfield, "SoMFString", "SoMFUInt32" },
898     { mfstring_to_mfield, "SoMFString", "SoMFUShort" },
899     { mfstring_to_mfield, "SoMFString", "SoMFVec2f" },
900     { mfstring_to_mfield, "SoMFString", "SoMFVec3f" },
901     { mfstring_to_mfield, "SoMFString", "SoMFVec3d" },
902     { mfstring_to_mfield, "SoMFString", "SoMFVec4f" },
903     { SoSFBool_SoSFFloat, "SoSFBool", "SoSFFloat" },
904     { SoSFBool_SoMFFloat, "SoSFBool", "SoMFFloat" },
905     { SoSFFloat_SoSFBool, "SoSFFloat", "SoSFBool" },
906     { SoSFFloat_SoMFBool, "SoSFFloat", "SoMFBool" },
907     { SoSFBool_SoSFInt32, "SoSFBool", "SoSFInt32" },
908     { SoSFBool_SoMFInt32, "SoSFBool", "SoMFInt32" },
909     { SoSFInt32_SoSFBool, "SoSFInt32", "SoSFBool" },
910     { SoSFInt32_SoMFBool, "SoSFInt32", "SoMFBool" },
911     { SoSFBool_SoSFShort, "SoSFBool", "SoSFShort" },
912     { SoSFBool_SoMFShort, "SoSFBool", "SoMFShort" },
913     { SoSFShort_SoSFBool, "SoSFShort", "SoSFBool" },
914     { SoSFShort_SoMFBool, "SoSFShort", "SoMFBool" },
915     { SoSFBool_SoSFUInt32, "SoSFBool", "SoSFUInt32" },
916     { SoSFBool_SoMFUInt32, "SoSFBool", "SoMFUInt32" },
917     { SoSFUInt32_SoSFBool, "SoSFUInt32", "SoSFBool" },
918     { SoSFUInt32_SoMFBool, "SoSFUInt32", "SoMFBool" },
919     { SoSFBool_SoSFUShort, "SoSFBool", "SoSFUShort" },
920     { SoSFBool_SoMFUShort, "SoSFBool", "SoMFUShort" },
921     { SoSFUShort_SoSFBool, "SoSFUShort", "SoSFBool" },
922     { SoSFUShort_SoMFBool, "SoSFUShort", "SoMFBool" },
923     { SoSFColor_SoSFVec3f, "SoSFColor", "SoSFVec3f" },
924     { SoSFColor_SoMFVec3f, "SoSFColor", "SoMFVec3f" },
925     { SoSFVec3f_SoSFColor, "SoSFVec3f", "SoSFColor" },
926     { SoSFVec3f_SoMFColor, "SoSFVec3f", "SoMFColor" },
927     { SoSFFloat_SoSFInt32, "SoSFFloat", "SoSFInt32" },
928     { SoSFFloat_SoMFInt32, "SoSFFloat", "SoMFInt32" },
929     { SoSFInt32_SoSFFloat, "SoSFInt32", "SoSFFloat" },
930     { SoSFInt32_SoMFFloat, "SoSFInt32", "SoMFFloat" },
931     { SoSFFloat_SoSFShort, "SoSFFloat", "SoSFShort" },
932     { SoSFFloat_SoMFShort, "SoSFFloat", "SoMFShort" },
933     { SoSFShort_SoSFFloat, "SoSFShort", "SoSFFloat" },
934     { SoSFShort_SoMFFloat, "SoSFShort", "SoMFFloat" },
935     { SoSFFloat_SoSFUInt32, "SoSFFloat", "SoSFUInt32" },
936     { SoSFFloat_SoMFUInt32, "SoSFFloat", "SoMFUInt32" },
937     { SoSFUInt32_SoSFFloat, "SoSFUInt32", "SoSFFloat" },
938     { SoSFUInt32_SoMFFloat, "SoSFUInt32", "SoMFFloat" },
939     { SoSFFloat_SoSFUShort, "SoSFFloat", "SoSFUShort" },
940     { SoSFFloat_SoMFUShort, "SoSFFloat", "SoMFUShort" },
941     { SoSFUShort_SoSFFloat, "SoSFUShort", "SoSFFloat" },
942     { SoSFUShort_SoMFFloat, "SoSFUShort", "SoMFFloat" },
943     { SoSFInt32_SoSFShort, "SoSFInt32", "SoSFShort" },
944     { SoSFInt32_SoMFShort, "SoSFInt32", "SoMFShort" },
945     { SoSFShort_SoSFInt32, "SoSFShort", "SoSFInt32" },
946     { SoSFShort_SoMFInt32, "SoSFShort", "SoMFInt32" },
947     { SoSFInt32_SoSFUInt32, "SoSFInt32", "SoSFUInt32" },
948     { SoSFInt32_SoMFUInt32, "SoSFInt32", "SoMFUInt32" },
949     { SoSFUInt32_SoSFInt32, "SoSFUInt32", "SoSFInt32" },
950     { SoSFUInt32_SoMFInt32, "SoSFUInt32", "SoMFInt32" },
951     { SoSFInt32_SoSFUShort, "SoSFInt32", "SoSFUShort" },
952     { SoSFInt32_SoMFUShort, "SoSFInt32", "SoMFUShort" },
953     { SoSFUShort_SoSFInt32, "SoSFUShort", "SoSFInt32" },
954     { SoSFUShort_SoMFInt32, "SoSFUShort", "SoMFInt32" },
955     { SoSFShort_SoSFUInt32, "SoSFShort", "SoSFUInt32" },
956     { SoSFShort_SoMFUInt32, "SoSFShort", "SoMFUInt32" },
957     { SoSFUInt32_SoSFShort, "SoSFUInt32", "SoSFShort" },
958     { SoSFUInt32_SoMFShort, "SoSFUInt32", "SoMFShort" },
959     { SoSFShort_SoSFUShort, "SoSFShort", "SoSFUShort" },
960     { SoSFShort_SoMFUShort, "SoSFShort", "SoMFUShort" },
961     { SoSFUShort_SoSFShort, "SoSFUShort", "SoSFShort" },
962     { SoSFUShort_SoMFShort, "SoSFUShort", "SoMFShort" },
963     { SoSFUInt32_SoSFUShort, "SoSFUInt32", "SoSFUShort" },
964     { SoSFUInt32_SoMFUShort, "SoSFUInt32", "SoMFUShort" },
965     { SoSFUShort_SoSFUInt32, "SoSFUShort", "SoSFUInt32" },
966     { SoSFUShort_SoMFUInt32, "SoSFUShort", "SoMFUInt32" },
967     { SoSFFloat_SoSFTime, "SoSFFloat", "SoSFTime" },
968     { SoSFFloat_SoMFTime, "SoSFFloat", "SoMFTime" },
969     { SoSFTime_SoSFFloat, "SoSFTime", "SoSFFloat" },
970     { SoSFTime_SoMFFloat, "SoSFTime", "SoMFFloat" },
971     { SoMFBool_SoSFFloat, "SoMFBool", "SoSFFloat" },
972     { SoMFFloat_SoSFBool, "SoMFFloat", "SoSFBool" },
973     { SoMFBool_SoSFInt32, "SoMFBool", "SoSFInt32" },
974     { SoMFInt32_SoSFBool, "SoMFInt32", "SoSFBool" },
975     { SoMFBool_SoSFShort, "SoMFBool", "SoSFShort" },
976     { SoMFShort_SoSFBool, "SoMFShort", "SoSFBool" },
977     { SoMFBool_SoSFUInt32, "SoMFBool", "SoSFUInt32" },
978     { SoMFUInt32_SoSFBool, "SoMFUInt32", "SoSFBool" },
979     { SoMFBool_SoSFUShort, "SoMFBool", "SoSFUShort" },
980     { SoMFUShort_SoSFBool, "SoMFUShort", "SoSFBool" },
981     { SoMFColor_SoSFVec3f, "SoMFColor", "SoSFVec3f" },
982     { SoMFVec3f_SoSFColor, "SoMFVec3f", "SoSFColor" },
983     { SoMFFloat_SoSFInt32, "SoMFFloat", "SoSFInt32" },
984     { SoMFInt32_SoSFFloat, "SoMFInt32", "SoSFFloat" },
985     { SoMFFloat_SoSFShort, "SoMFFloat", "SoSFShort" },
986     { SoMFShort_SoSFFloat, "SoMFShort", "SoSFFloat" },
987     { SoMFFloat_SoSFUInt32, "SoMFFloat", "SoSFUInt32" },
988     { SoMFUInt32_SoSFFloat, "SoMFUInt32", "SoSFFloat" },
989     { SoMFFloat_SoSFUShort, "SoMFFloat", "SoSFUShort" },
990     { SoMFUShort_SoSFFloat, "SoMFUShort", "SoSFFloat" },
991     { SoMFInt32_SoSFShort, "SoMFInt32", "SoSFShort" },
992     { SoMFShort_SoSFInt32, "SoMFShort", "SoSFInt32" },
993     { SoMFInt32_SoSFUInt32, "SoMFInt32", "SoSFUInt32" },
994     { SoMFUInt32_SoSFInt32, "SoMFUInt32", "SoSFInt32" },
995     { SoMFInt32_SoSFUShort, "SoMFInt32", "SoSFUShort" },
996     { SoMFUShort_SoSFInt32, "SoMFUShort", "SoSFInt32" },
997     { SoMFShort_SoSFUInt32, "SoMFShort", "SoSFUInt32" },
998     { SoMFUInt32_SoSFShort, "SoMFUInt32", "SoSFShort" },
999     { SoMFShort_SoSFUShort, "SoMFShort", "SoSFUShort" },
1000     { SoMFUShort_SoSFShort, "SoMFUShort", "SoSFShort" },
1001     { SoMFUInt32_SoSFUShort, "SoMFUInt32", "SoSFUShort" },
1002     { SoMFUShort_SoSFUInt32, "SoMFUShort", "SoSFUInt32" },
1003     { SoMFFloat_SoSFTime, "SoMFFloat", "SoSFTime" },
1004     { SoMFTime_SoSFFloat, "SoMFTime", "SoSFFloat" },
1005     { SoMFBool_SoMFFloat, "SoMFBool", "SoMFFloat" },
1006     { SoMFFloat_SoMFBool, "SoMFFloat", "SoMFBool" },
1007     { SoMFBool_SoMFInt32, "SoMFBool", "SoMFInt32" },
1008     { SoMFInt32_SoMFBool, "SoMFInt32", "SoMFBool" },
1009     { SoMFBool_SoMFShort, "SoMFBool", "SoMFShort" },
1010     { SoMFShort_SoMFBool, "SoMFShort", "SoMFBool" },
1011     { SoMFBool_SoMFUInt32, "SoMFBool", "SoMFUInt32" },
1012     { SoMFUInt32_SoMFBool, "SoMFUInt32", "SoMFBool" },
1013     { SoMFBool_SoMFUShort, "SoMFBool", "SoMFUShort" },
1014     { SoMFUShort_SoMFBool, "SoMFUShort", "SoMFBool" },
1015     { SoMFColor_SoMFVec3f, "SoMFColor", "SoMFVec3f" },
1016     { SoMFVec3f_SoMFColor, "SoMFVec3f", "SoMFColor" },
1017     { SoMFFloat_SoMFInt32, "SoMFFloat", "SoMFInt32" },
1018     { SoMFInt32_SoMFFloat, "SoMFInt32", "SoMFFloat" },
1019     { SoMFFloat_SoMFShort, "SoMFFloat", "SoMFShort" },
1020     { SoMFShort_SoMFFloat, "SoMFShort", "SoMFFloat" },
1021     { SoMFFloat_SoMFUInt32, "SoMFFloat", "SoMFUInt32" },
1022     { SoMFUInt32_SoMFFloat, "SoMFUInt32", "SoMFFloat" },
1023     { SoMFFloat_SoMFUShort, "SoMFFloat", "SoMFUShort" },
1024     { SoMFUShort_SoMFFloat, "SoMFUShort", "SoMFFloat" },
1025     { SoMFInt32_SoMFShort, "SoMFInt32", "SoMFShort" },
1026     { SoMFShort_SoMFInt32, "SoMFShort", "SoMFInt32" },
1027     { SoMFInt32_SoMFUInt32, "SoMFInt32", "SoMFUInt32" },
1028     { SoMFUInt32_SoMFInt32, "SoMFUInt32", "SoMFInt32" },
1029     { SoMFInt32_SoMFUShort, "SoMFInt32", "SoMFUShort" },
1030     { SoMFUShort_SoMFInt32, "SoMFUShort", "SoMFInt32" },
1031     { SoMFShort_SoMFUInt32, "SoMFShort", "SoMFUInt32" },
1032     { SoMFUInt32_SoMFShort, "SoMFUInt32", "SoMFShort" },
1033     { SoMFShort_SoMFUShort, "SoMFShort", "SoMFUShort" },
1034     { SoMFUShort_SoMFShort, "SoMFUShort", "SoMFShort" },
1035     { SoMFUInt32_SoMFUShort, "SoMFUInt32", "SoMFUShort" },
1036     { SoMFUShort_SoMFUInt32, "SoMFUShort", "SoMFUInt32" },
1037     { SoMFFloat_SoMFTime, "SoMFFloat", "SoMFTime" },
1038     { SoMFTime_SoMFFloat, "SoMFTime", "SoMFFloat" },
1039     { SoSFMatrix_SoSFRotation, "SoSFMatrix", "SoSFRotation" },
1040     { SoMFMatrix_SoSFRotation, "SoMFMatrix", "SoSFRotation" },
1041     { SoSFMatrix_SoMFRotation, "SoSFMatrix", "SoMFRotation" },
1042     { SoMFMatrix_SoMFRotation, "SoMFMatrix", "SoMFRotation" },
1043     { SoSFRotation_SoSFMatrix, "SoSFRotation", "SoSFMatrix" },
1044     { SoMFRotation_SoSFMatrix, "SoMFRotation", "SoSFMatrix" },
1045     { SoSFRotation_SoMFMatrix, "SoSFRotation", "SoMFMatrix" },
1046     { SoMFRotation_SoMFMatrix, "SoMFRotation", "SoMFMatrix" },
1047     { sftime_to_sfstring, "SoSFTime", "SoSFString" },
1048     { sftime_to_mfstring, "SoSFTime", "SoMFString" },
1049     { mftime_to_sfstring, "SoMFTime", "SoSFString" },
1050     { mftime_to_mfstring, "SoMFTime", "SoMFString" },
1051     { SoSFVec2s_to_SoSFVec2f, "SoSFVec2s", "SoSFVec2f" },
1052     { SoSFVec2s_to_SoMFVec2f, "SoSFVec2s", "SoMFVec2f" },
1053     { SoSFVec2f_to_SoSFVec2s, "SoSFVec2f", "SoSFVec2s" },
1054     { SoMFVec2f_to_SoSFVec2s, "SoMFVec2f", "SoSFVec2s" },
1055     { SoSFVec3s_to_SoSFVec3f, "SoSFVec3s", "SoSFVec3f" },
1056     { SoSFVec3s_to_SoMFVec3f, "SoSFVec3s", "SoMFVec3f" },
1057     { SoSFVec3s_to_SoSFVec3d, "SoSFVec3s", "SoSFVec3d" },
1058     { SoSFVec3s_to_SoMFVec3d, "SoSFVec3s", "SoMFVec3d" },
1059     { SoSFVec3f_to_SoSFVec3s, "SoSFVec3f", "SoSFVec3s" },
1060     { SoMFVec3f_to_SoSFVec3s, "SoMFVec3f", "SoSFVec3s" },
1061     { SoSFVec3f_to_SoSFVec3d, "SoSFVec3f", "SoSFVec3d" },
1062     { SoSFVec3f_to_SoMFVec3d, "SoSFVec3f", "SoMFVec3d" },
1063     { SoMFVec3f_to_SoSFVec3d, "SoMFVec3f", "SoSFVec3d" },
1064     { SoMFVec3f_to_SoMFVec3d, "SoMFVec3f", "SoMFVec3d" },
1065     { SoSFVec3d_to_SoSFVec3s, "SoSFVec3d", "SoSFVec3s" },
1066     { SoMFVec3d_to_SoSFVec3s, "SoMFVec3d", "SoSFVec3s" },
1067     { SoSFVec3d_to_SoSFVec3f, "SoSFVec3d", "SoSFVec3f" },
1068     { SoSFVec3d_to_SoMFVec3f, "SoSFVec3d", "SoMFVec3f" },
1069     { SoMFVec3d_to_SoSFVec3f, "SoMFVec3d", "SoSFVec3f" },
1070     { SoMFVec3d_to_SoMFVec3f, "SoMFVec3d", "SoMFVec3f" }
1071   };
1072 
1073   int i;
1074   for (i = 0; i < int(sizeof(allconverters) / sizeof(allconverters[0])); i++) {
1075     register_convertfunc(allconverters[i].func,
1076                          SoType::fromName(allconverters[i].from),
1077                          SoType::fromName(allconverters[i].to));
1078     // Performance note: it may look slow to do all that
1079     // SoType::fromName()'ing, but the full loop only takes about 2
1080     // milliseconds on an 850MHz x86 CPU, so there would be little use
1081     // in trying to optimize this.
1082   }
1083 
1084   // Now add conversion to and from SoSFTrigger for all other
1085   // non-abstract field types (all conversions done by the same
1086   // function).
1087 
1088   SoTypeList allfieldtypes;
1089   int nrfieldtypes = SoType::getAllDerivedFrom(SoField::getClassTypeId(),
1090                                                allfieldtypes);
1091   for (i=0; i < nrfieldtypes; i++) {
1092     if (allfieldtypes[i].canCreateInstance() &&
1093         allfieldtypes[i] != SoSFTrigger::getClassTypeId()) {
1094       register_convertfunc(to_and_from_sftrigger,
1095                            SoSFTrigger::getClassTypeId(),
1096                            allfieldtypes[i]);
1097       register_convertfunc(to_and_from_sftrigger,
1098                            allfieldtypes[i],
1099                            SoSFTrigger::getClassTypeId());
1100     }
1101   }
1102 }
1103 
SoConvertAll(const SoType from,const SoType to)1104 SoConvertAll::SoConvertAll(const SoType from, const SoType to)
1105 {
1106 #if COIN_DEBUG && 0 // debug
1107   SoDebugError::postInfo("SoConvertAll::SoConvertAll",
1108                          "from: %s, to: %s",
1109                          from.getName().getString(),
1110                          to.getName().getString());
1111 #endif // debug
1112 
1113   // This code is instead of SO_ENGINE_CONSTRUCTOR(), which we can't
1114   // use due to the fact that we need dynamic lists of input fields
1115   // and engine outputs.
1116   { // SO_ENGINE_CONSTRUCTOR replacement start
1117     SoConvertAll::classinstances++;
1118     /* Catch attempts to use an engine class which has not been initialized. */
1119     assert(SoConvertAll::classTypeId != SoType::badType());
1120 
1121     this->inputdata_instance =
1122       new SoFieldData(SoConvertAll::parentinputdata ?
1123                       *SoConvertAll::parentinputdata : NULL);
1124 
1125     this->outputdata_instance =
1126       new SoEngineOutputData(SoConvertAll::parentoutputdata ?
1127                              *SoConvertAll::parentoutputdata : NULL);
1128 
1129     /* SoConvertAll is not considered native (doesn't really matter
1130        one way or the other). */
1131     this->isBuiltIn = FALSE;
1132   } // SO_ENGINE_CONSTRUCTOR replacement end
1133 
1134 
1135 
1136   this->input = static_cast<SoField *>(from.createInstance());
1137 
1138   this->input->setContainer(this);
1139   this->output.setContainer(this);
1140   this->outputdata_instance->addOutput(this, "output", &this->output, to);
1141 
1142   uint32_t val = (static_cast<uint32_t>(from.getKey()) << 16) + to.getKey();
1143   convert_func * ptr;
1144   if (!convertfunc_dict->get(val, ptr)) { assert(FALSE); }
1145   this->convertvalue = ptr;
1146 }
1147 
~SoConvertAll()1148 SoConvertAll::~SoConvertAll()
1149 {
1150 #if COIN_DEBUG && 0 // debug
1151   SoDebugError::postInfo("SoConvertAll::~SoConvertAll", "%p", this);
1152 #endif // debug
1153   delete this->input;
1154 
1155   delete this->inputdata_instance;
1156   delete this->outputdata_instance;
1157 }
1158 
1159 SoField *
getInput(SoType type)1160 SoConvertAll::getInput(SoType type)
1161 {
1162 #if COIN_DEBUG
1163   SoType inputtype = this->input->getTypeId();
1164   if (type != inputtype && type != SoType::badType()) {
1165     SoDebugError::postWarning("SoConvertAll::getInput",
1166                               "field is of type %s, not %s",
1167                               inputtype.getName().getString(),
1168                               type.getName().getString());
1169   }
1170 #endif // COIN_DEBUG
1171 
1172   // ignore type, as we have only a single input field
1173 
1174   return this->input;
1175 }
1176 
1177 SoEngineOutput *
getOutput(SoType type)1178 SoConvertAll::getOutput(SoType type)
1179 {
1180 #if COIN_DEBUG
1181   SoType outputtype = this->output.getConnectionType();
1182   if (type != outputtype && type != SoType::badType()) {
1183     SoDebugError::postWarning("SoConvertAll::getOutput",
1184                               "engineout is of type %s, not %s",
1185                               outputtype.getName().getString(),
1186                               type.getName().getString());
1187   }
1188 #endif // COIN_DEBUG
1189 
1190   // ignore type, as we have only a single engineoutput
1191 
1192   return &this->output;
1193 }
1194 
1195 void
evaluate(void)1196 SoConvertAll::evaluate(void)
1197 {
1198   // we cannot use the SO_ENGINE_OUTPUT macro, but this code should
1199   // do the same thing.
1200   if (this->output.isEnabled()) {
1201     for (int i = 0 ; i < this->output.getNumConnections(); i++) {
1202       SoField * f = this->output[i];
1203       if (!f->isReadOnly()) {
1204         // Convert directly from the "real" master field if possible,
1205         // to behave properly on enum fields (the this->input instance
1206         // doesn't contain the name<->value mappings in the case that
1207         // the master field is of type So[SM]FEnum or So[SM]FBitMask).
1208         SoField * masterfield = NULL;
1209         if (this->input->getConnectedField(masterfield))
1210           this->convertvalue(masterfield, f);
1211         // Couldn't get master field, this means we are connected to
1212         // an engine output (at least we _should_ be, could probably
1213         // do with an assert here).
1214         else
1215           this->convertvalue(this->input, f);
1216       }
1217     }
1218   }
1219 }
1220 
1221 #undef SOCONVERTALL_CAST_SFIELD2FIELD
1222 #undef SOCONVERTALL_CAST_MFIELD2SFIELD
1223 #undef SOCONVERTALL_CAST_MFIELD2MFIELD
1224 #undef SOCONVERTALL_CAST_SFTIME2SFFLOAT
1225 #undef SOCONVERTALL_SFMATRIX2ROTATION
1226 #undef SOCONVERTALL_SFROTATION2MATRIX
1227