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 SoToVRMLAction SoToVRMLAction.h Inventor/actions/SoToVRMLAction.h
35 \brief The SoToVRMLAction class builds a new scene graph using only VRML 1.0 nodes.
36
37 \ingroup actions
38
39 This action is used for converting a scene graph of VRML2/VRML97
40 nodes to a new scene graph using only VRML1 compatible nodes.
41
42 A current limitation of this action is that nodes specific for
43 Inventor / Coin (ie neither VRML1 or VRML97 compatible nodes) is not
44 attempted converted, they are just ignored.
45
46 \sa SoToVRML2Action
47
48 \since Coin 2.0
49 \since TGS Inventor 2.5
50 */
51
52 #include <Inventor/actions/SoToVRMLAction.h>
53
54 #include <cstdio>
55 #include <cstdlib>
56 #include <cstring>
57
58 #ifdef HAVE_CONFIG_H
59 #include "config.h"
60 #endif // HAVE_CONFIG_H
61
62 #include <Inventor/SbName.h>
63 #include <Inventor/actions/SoCallbackAction.h>
64 #include <Inventor/actions/SoSearchAction.h>
65 #include <Inventor/SoDB.h>
66 #include <Inventor/nodes/SoNodes.h>
67 #include <Inventor/SoInput.h>
68 #include <Inventor/SoOutput.h>
69 #include <Inventor/SbBSPTree.h>
70 #include <Inventor/actions/SoCallbackAction.h>
71 #include <Inventor/actions/SoSearchAction.h>
72 #include <Inventor/actions/SoGetPrimitiveCountAction.h>
73 #include <Inventor/SbViewportRegion.h>
74 #include <Inventor/nodes/SoTransform.h>
75 #include <Inventor/actions/SoWriteAction.h>
76 #include <Inventor/lists/SbList.h>
77 #include <Inventor/SoPrimitiveVertex.h>
78 #include <Inventor/lists/SoPathList.h>
79 #include <Inventor/lists/SoNodeList.h>
80
81 #ifdef HAVE_NODEKITS
82 #include <Inventor/nodekits/SoBaseKit.h>
83 #endif // HAVE_NODEKITS
84
85 #ifdef HAVE_VRML97
86 #include <Inventor/VRMLnodes/SoVRMLNodes.h>
87 #include <Inventor/VRMLnodes/SoVRML.h>
88 #endif // HAVE_VRML97
89
90 #include "actions/SoSubActionP.h"
91 #include "coindefs.h"
92 #include "SbBasicP.h"
93
94 // FIXME: currently only VRML2-nodes to VRML1-nodes is
95 // supported. Inventor/Coin specific nodes must also be supported
96 // (they are just ignored for now). It's quite easy to add support new
97 // nodes though. pederb, 2002-07-17
98
99
100 // helper function needed to copy the name of a node
tovrml_new_node(SoNode * newnode,const SoNode * oldnode)101 static SoNode * tovrml_new_node(SoNode * newnode, const SoNode * oldnode)
102 {
103 const SbName name = oldnode->getName();
104 if (name != SbName::empty()) newnode->setName(name);
105 return newnode;
106 }
107
108 // We use SoType::createInstance() instead of simply new'ing to make
109 // an instance, as this makes SoType::overrideType() influence the
110 // conversion process.
111
112 #define NEW_NODE(_type_, _oldnode_) \
113 coin_assert_cast<_type_*>(tovrml_new_node(static_cast<SoNode *>(_type_::getClassTypeId().createInstance()), \
114 _oldnode_))
115
116 // *************************************************************************
117
118 SO_ACTION_SOURCE(SoToVRMLAction);
119
120 // *************************************************************************
121
122 class SoToVRMLActionP {
123 public:
SoToVRMLActionP(void)124 SoToVRMLActionP(void)
125 : master(NULL)
126 {
127 this->expandsofile = FALSE;
128 this->urlname = "";
129 this->writetexcoords = FALSE;
130 this->expandtexture2node = FALSE;
131 // FIXME: don't know if this is correct default value. 20020705 mortene.
132 this->keepunknownnodes = TRUE;
133 this->convertinlinenodes = TRUE;
134 this->conditionalconversion = FALSE;
135 // FIXME: don't know if this is correct default value. 20020705 mortene.
136 this->isverbose = FALSE;
137
138 this->nodefuse = FALSE; // for optimizing bad scene graphs
139
140 this->bsptree = NULL;
141 this->bsptreetex = NULL;
142 this->bsptreenormal = NULL;
143 this->coordidx = NULL;
144 this->normalidx = NULL;
145 this->texidx = NULL;
146 this->coloridx = NULL;
147 this->vrmlpath = NULL;
148 this->vrmlroot = NULL;
149 }
150
init(void)151 void init(void) {
152 if (this->vrmlpath) {
153 this->vrmlpath->unref();
154 }
155 this->vrmlpath = reclassify_cast<SoFullPath *>(new SoPath);
156 this->vrmlpath->ref();
157
158 if (this->vrmlroot) {
159 this->vrmlroot->unref();
160 }
161 this->vrmlroot = new SoSeparator;
162 this->vrmlroot->ref();
163 this->vrmlpath->setHead(this->vrmlroot);
164 }
165
166 SoToVRMLAction * master;
167 SbBool expandsofile;
168 SbString urlname;
169 SbBool writetexcoords;
170 SbBool expandtexture2node;
171 SbBool keepunknownnodes;
172 SbBool convertinlinenodes;
173 SbBool conditionalconversion;
174 SbBool isverbose;
175 SbBool nodefuse;
176 SoCallbackAction cbaction;
177 SoSearchAction searchaction;
178 SoFullPath * vrmlpath;
179 SoSeparator * vrmlroot;
180
181 SbBSPTree * bsptree;
182 SbBSPTree * bsptreetex;
183 SbBSPTree * bsptreenormal;
184
185 SbList <int32_t> * coordidx;
186 SbList <int32_t> * normalidx;
187 SbList <int32_t> * texidx;
188 SbList <int32_t> * coloridx;
189
190 static SoCallbackAction::Response pop_cb(void *, SoCallbackAction *, const SoNode *);
191 static SoCallbackAction::Response push_cb(void *, SoCallbackAction *, const SoNode *);
192 static SoCallbackAction::Response post_primitives_cb(void *, SoCallbackAction *, const SoNode *);
193 static void triangle_cb(void * userdata, SoCallbackAction * action,
194 const SoPrimitiveVertex * v1,
195 const SoPrimitiveVertex * v2,
196 const SoPrimitiveVertex * v3);
197 static SoCallbackAction::Response unsupported_cb(void *, SoCallbackAction *, const SoNode *);
198 SoNode * search_for_node(SoNode * root, const SbName & name, const SoType & type);
199 SoGroup * get_current_tail(void);
200 SoMaterial * find_or_create_material(void);
201 void init_gen(const SbBool color);
202
203 #ifdef HAVE_VRML97
204 static SoCallbackAction::Response vrmlshape_cb(void *, SoCallbackAction *, const SoNode *);
205 static SoCallbackAction::Response vrmltransform_cb(void *, SoCallbackAction *, const SoNode *);
206 static SoCallbackAction::Response vrmldirlight_cb(void *, SoCallbackAction *, const SoNode *);
207 static SoCallbackAction::Response vrmlpointlight_cb(void *, SoCallbackAction *, const SoNode *);
208 static SoCallbackAction::Response vrmlspotlight_cb(void *, SoCallbackAction *, const SoNode *);
209 static SoCallbackAction::Response vrmlpixeltex_cb(void *, SoCallbackAction *, const SoNode *);
210 static SoCallbackAction::Response vrmlimagetex_cb(void *, SoCallbackAction *, const SoNode *);
211 static SoCallbackAction::Response vrmllod_cb(void *, SoCallbackAction *, const SoNode *);
212 static SoCallbackAction::Response vrmlmaterial_cb(void *, SoCallbackAction *, const SoNode *);
213 static SoCallbackAction::Response vrmlswitch_cb(void *, SoCallbackAction *, const SoNode *);
214 static SoCallbackAction::Response vrmltextransform_cb(void *, SoCallbackAction *, const SoNode *);
215 static SoCallbackAction::Response vrmlviewpoint_cb(void *, SoCallbackAction *, const SoNode *);
216 static SoCallbackAction::Response vrmlbox_cb(void *, SoCallbackAction *, const SoNode *);
217 static SoCallbackAction::Response vrmlcone_cb(void *, SoCallbackAction *, const SoNode *);
218 static SoCallbackAction::Response vrmlcylinder_cb(void *, SoCallbackAction *, const SoNode *);
219 static SoCallbackAction::Response vrmlifs_cb(void *, SoCallbackAction *, const SoNode *);
220 static SoCallbackAction::Response vrmlils_cb(void *, SoCallbackAction *, const SoNode *);
221 static SoCallbackAction::Response vrmlpointset_cb(void *, SoCallbackAction *, const SoNode *);
222 static SoCallbackAction::Response vrmlsphere_cb(void *, SoCallbackAction *, const SoNode *);
223
224 static SoCallbackAction::Response vrmlelevation_cb(void *, SoCallbackAction *, const SoNode *);
225 static SoCallbackAction::Response vrmlextrusion_cb(void *, SoCallbackAction *, const SoNode *);
226 #endif // HAVE_VRML97
227 };
228
229
230
231 #define PRIVATE(obj) ((obj)->pimpl)
232 #define PUBLIC(obj) ((obj)->master)
233 #define THISP(p) (static_cast<SoToVRMLActionP *>(p))
234
235 // *************************************************************************
236
237 // Overridden from parent class.
238 void
initClass(void)239 SoToVRMLAction::initClass(void)
240 {
241 SO_ACTION_INTERNAL_INIT_CLASS(SoToVRMLAction, SoAction);
242 }
243
244
245 /*!
246 Constructor.
247 */
248
SoToVRMLAction(void)249 SoToVRMLAction::SoToVRMLAction(void)
250 {
251 PRIVATE(this)->master = this;
252
253 #define ADD_PRE_CB(_node_, _cb_) \
254 PRIVATE(this)->cbaction.addPreCallback(_node_::getClassTypeId(), SoToVRMLActionP::_cb_, &PRIVATE(this).get())
255 #define ADD_POST_CB(_node_, _cb_) \
256 PRIVATE(this)->cbaction.addPostCallback(_node_::getClassTypeId(), SoToVRMLActionP::_cb_, &PRIVATE(this).get())
257 #define ADD_UNSUPPORTED(_node_) \
258 PRIVATE(this)->cbaction.addPreCallback(_node_::getClassTypeId(), SoToVRMLActionP::unsupported_cb, &PRIVATE(this).get())
259
260 #ifdef HAVE_VRML97
261 ADD_PRE_CB(SoVRMLShape, vrmlshape_cb);
262 ADD_POST_CB(SoVRMLShape, pop_cb);
263 ADD_PRE_CB(SoVRMLGroup, push_cb);
264 ADD_POST_CB(SoVRMLGroup, pop_cb);
265 ADD_PRE_CB(SoVRMLTransform, vrmltransform_cb);
266 ADD_POST_CB(SoVRMLTransform, pop_cb);
267 ADD_PRE_CB(SoVRMLDirectionalLight, vrmldirlight_cb);
268 ADD_PRE_CB(SoVRMLPointLight, vrmlpointlight_cb);
269 ADD_PRE_CB(SoVRMLSpotLight, vrmlspotlight_cb);
270 ADD_PRE_CB(SoVRMLPixelTexture, vrmlpixeltex_cb);
271 ADD_PRE_CB(SoVRMLImageTexture, vrmlimagetex_cb);
272 ADD_PRE_CB(SoVRMLLOD, vrmllod_cb);
273 ADD_POST_CB(SoVRMLLOD, pop_cb);
274 ADD_PRE_CB(SoVRMLMaterial, vrmlmaterial_cb);
275 ADD_PRE_CB(SoVRMLSwitch, vrmlswitch_cb);
276 ADD_POST_CB(SoVRMLSwitch, pop_cb);
277 ADD_PRE_CB(SoVRMLTextureTransform, vrmltextransform_cb);
278 ADD_PRE_CB(SoVRMLViewpoint, vrmlviewpoint_cb);
279
280 // misc geometry nodes
281 ADD_PRE_CB(SoVRMLBox, vrmlbox_cb);
282 ADD_PRE_CB(SoVRMLCone, vrmlcone_cb);
283 ADD_PRE_CB(SoVRMLCylinder, vrmlcylinder_cb);
284 ADD_PRE_CB(SoVRMLIndexedFaceSet, vrmlifs_cb);
285 ADD_PRE_CB(SoVRMLIndexedLineSet, vrmlils_cb);
286 ADD_PRE_CB(SoVRMLSphere, vrmlsphere_cb);
287
288 // unsupported node
289 ADD_UNSUPPORTED(SoVRMLInline); // convert to WWWInline
290 ADD_UNSUPPORTED(SoVRMLMovieTexture);
291 ADD_UNSUPPORTED(SoVRMLAnchor); // convert to WWWAnchor
292 ADD_UNSUPPORTED(SoVRMLAudioClip);
293 ADD_UNSUPPORTED(SoVRMLBackground);
294 ADD_UNSUPPORTED(SoVRMLCylinderSensor);
295 ADD_UNSUPPORTED(SoVRMLColorInterpolator);
296 ADD_UNSUPPORTED(SoVRMLCoordinateInterpolator);
297 ADD_UNSUPPORTED(SoVRMLFog);
298 ADD_UNSUPPORTED(SoVRMLFontStyle);
299 ADD_UNSUPPORTED(SoVRMLNavigationInfo);
300 ADD_UNSUPPORTED(SoVRMLNormalInterpolator);
301 ADD_UNSUPPORTED(SoVRMLPositionInterpolator);
302 ADD_UNSUPPORTED(SoVRMLProximitySensor);
303 ADD_UNSUPPORTED(SoVRMLScalarInterpolator);
304 ADD_UNSUPPORTED(SoVRMLScript);
305 ADD_UNSUPPORTED(SoVRMLSound);
306 ADD_UNSUPPORTED(SoVRMLSphereSensor);
307 ADD_UNSUPPORTED(SoVRMLText);
308 ADD_UNSUPPORTED(SoVRMLTimeSensor);
309 ADD_UNSUPPORTED(SoVRMLTouchSensor);
310 ADD_UNSUPPORTED(SoVRMLVisibilitySensor);
311 ADD_UNSUPPORTED(SoVRMLWorldInfo); // convert to Info
312
313 // these are converted to IndexedFaceSet
314 ADD_PRE_CB(SoVRMLExtrusion, vrmlextrusion_cb);
315 ADD_POST_CB(SoVRMLExtrusion, post_primitives_cb);
316 ADD_PRE_CB(SoVRMLElevationGrid, vrmlelevation_cb);
317 ADD_POST_CB(SoVRMLElevationGrid, post_primitives_cb);
318 PRIVATE(this)->cbaction.addTriangleCallback(SoVRMLElevationGrid::getClassTypeId(),
319 SoToVRMLActionP::triangle_cb, &PRIVATE(this).get());
320 PRIVATE(this)->cbaction.addTriangleCallback(SoVRMLExtrusion::getClassTypeId(),
321 SoToVRMLActionP::triangle_cb, &PRIVATE(this).get());
322 #endif // HAVE_VRML97
323
324 #undef ADD_PRE_CB
325 #undef ADD_POST_CB
326 #undef ADD_UNSUPPORTED
327 }
328
329 /*!
330 The destructor.
331 */
332
~SoToVRMLAction(void)333 SoToVRMLAction::~SoToVRMLAction(void)
334 {
335 if (PRIVATE(this)->vrmlpath) {
336 PRIVATE(this)->vrmlpath->unref();
337 }
338 if (PRIVATE(this)->vrmlroot) {
339 PRIVATE(this)->vrmlroot->unref();
340 }
341 }
342
343 // Documented in superclass.
344 void
apply(SoNode * root)345 SoToVRMLAction::apply(SoNode * root)
346 {
347 PRIVATE(this)->init();
348 PRIVATE(this)->cbaction.apply(root);
349 }
350
351 // Documented in superclass.
352 void
apply(SoPath * path)353 SoToVRMLAction::apply(SoPath * path)
354 {
355 PRIVATE(this)->init();
356 PRIVATE(this)->cbaction.apply(path);
357 }
358
359 // Documented in superclass.
360 void
apply(const SoPathList & pathlist,SbBool obeysrules)361 SoToVRMLAction::apply(const SoPathList & pathlist, SbBool obeysrules)
362 {
363 PRIVATE(this)->init();
364 PRIVATE(this)->cbaction.apply(pathlist, obeysrules);
365 }
366
367 // Documented in superclass.
368 void
beginTraversal(SoNode * COIN_UNUSED_ARG (node))369 SoToVRMLAction::beginTraversal(SoNode * COIN_UNUSED_ARG(node))
370 {
371 assert(0 && "should never get here");
372 }
373
374 SoNode *
getVRMLSceneGraph(void) const375 SoToVRMLAction::getVRMLSceneGraph(void) const
376 {
377 return PRIVATE(this)->vrmlroot;
378 }
379
380 void
expandSoFile(SbBool flag)381 SoToVRMLAction::expandSoFile(SbBool flag)
382 {
383 PRIVATE(this)->expandsofile = flag;
384 }
385
386 SbBool
areSoFileExpanded(void) const387 SoToVRMLAction::areSoFileExpanded(void) const
388 {
389 return PRIVATE(this)->expandsofile;
390 }
391
392 void
setUrlName(const SbString name)393 SoToVRMLAction::setUrlName(const SbString name)
394 {
395 PRIVATE(this)->urlname = name;
396 }
397
398 SbString
getUrlName(void) const399 SoToVRMLAction::getUrlName(void) const
400 {
401 return PRIVATE(this)->urlname;
402 }
403
404 void
writeTexCoords(SbBool flag)405 SoToVRMLAction::writeTexCoords(SbBool flag)
406 {
407 PRIVATE(this)->writetexcoords = flag;
408 }
409
410 SbBool
areTexCoordWritten(void) const411 SoToVRMLAction::areTexCoordWritten(void) const
412 {
413 return PRIVATE(this)->writetexcoords;
414 }
415
416 void
expandTexture2Node(SbBool flag)417 SoToVRMLAction::expandTexture2Node(SbBool flag)
418 {
419 PRIVATE(this)->expandtexture2node = flag;
420 }
421
422 SbBool
areTexture2NodeExpanded(void) const423 SoToVRMLAction::areTexture2NodeExpanded(void) const
424 {
425 return PRIVATE(this)->expandtexture2node;
426 }
427
428 void
keepUnknownNodes(SbBool flag)429 SoToVRMLAction::keepUnknownNodes(SbBool flag)
430 {
431 PRIVATE(this)->keepunknownnodes = flag;
432 }
433
434 SbBool
areUnknownNodeKept(void) const435 SoToVRMLAction::areUnknownNodeKept(void) const
436 {
437 return PRIVATE(this)->keepunknownnodes;
438 }
439
440 void
convertInlineNodes(SbBool flag)441 SoToVRMLAction::convertInlineNodes(SbBool flag)
442 {
443 PRIVATE(this)->convertinlinenodes = flag;
444 }
445
446 SbBool
doConvertInlineNodes(void) const447 SoToVRMLAction::doConvertInlineNodes(void) const
448 {
449 return PRIVATE(this)->convertinlinenodes;
450 }
451
452 void
conditionalConversion(SbBool flag)453 SoToVRMLAction::conditionalConversion(SbBool flag)
454 {
455 PRIVATE(this)->conditionalconversion = flag;
456 }
457
458 SbBool
doConditionalConversion(void) const459 SoToVRMLAction::doConditionalConversion(void) const
460 {
461 return PRIVATE(this)->conditionalconversion;
462 }
463
464 void
setVerbosity(SbBool flag)465 SoToVRMLAction::setVerbosity(SbBool flag)
466 {
467 PRIVATE(this)->isverbose = flag;
468 }
469
470 SbBool
isVerbose(void) const471 SoToVRMLAction::isVerbose(void) const
472 {
473 return PRIVATE(this)->isverbose;
474 }
475
476 SoNode *
search_for_node(SoNode * root,const SbName & name,const SoType & type)477 SoToVRMLActionP::search_for_node(SoNode * root, const SbName & name, const SoType & type)
478 {
479 SoNodeList mylist;
480 if (name == SbName::empty()) return NULL;
481
482 mylist.truncate(0);
483 int num = SoNode::getByName(name, mylist);
484 int cnt = 0;
485 SoNode * retnode = NULL;
486 for (int i = 0; i < num; i++) {
487 SoNode * node = mylist[i];
488 if (node->getTypeId() == type) {
489 retnode = node;
490 cnt++;
491 }
492 }
493
494 // if there is only one node with that name, return it
495 if (retnode && cnt == 1) return retnode;
496 if (!retnode) return NULL;
497
498 this->searchaction.setSearchingAll(TRUE);
499 this->searchaction.setName(name);
500 this->searchaction.setType(type);
501 this->searchaction.setInterest(SoSearchAction::LAST);
502 this->searchaction.setFind(SoSearchAction::TYPE|SoSearchAction::NAME);
503
504 #ifdef HAVE_NODEKITS
505 SbBool old = SoBaseKit::isSearchingChildren();
506 SoBaseKit::setSearchingChildren(TRUE);
507 #endif // HAVE_NODEKITS
508
509 this->searchaction.apply(root);
510 SoNode * tail = NULL;
511 SoFullPath * path = reclassify_cast<SoFullPath*>(this->searchaction.getPath());
512 if (path) {
513 tail = path->getTail();
514 }
515 this->searchaction.reset();
516 #ifdef HAVE_NODEKITS
517 SoBaseKit::setSearchingChildren(old);
518 #endif // HAVE_NODEKITS
519 return tail;
520 }
521
522 SoGroup *
get_current_tail(void)523 SoToVRMLActionP::get_current_tail(void)
524 {
525 SoNode * node = this->vrmlpath->getTail();
526 assert(node->isOfType(SoGroup::getClassTypeId()));
527 return coin_assert_cast<SoGroup*>(node);
528 }
529
530 SoMaterial *
find_or_create_material(void)531 SoToVRMLActionP::find_or_create_material(void)
532 {
533 SoMaterial * mat = NULL;
534 SoGroup * tail = this->get_current_tail();
535
536 int num = tail->getNumChildren();
537 while (--num >= 0 && mat == NULL) {
538 SoNode * node = tail->getChild(num);
539 if (node->isOfType(SoMaterial::getClassTypeId())) {
540 mat = coin_assert_cast<SoMaterial*>(node);
541 }
542 }
543 if (mat == NULL) {
544 mat = new SoMaterial;
545 tail->addChild(mat);
546 }
547 return mat;
548 }
549
550 SoCallbackAction::Response
push_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)551 SoToVRMLActionP::push_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
552 {
553 SoToVRMLActionP * thisp = THISP(closure);
554
555 SoSeparator * newsep = NEW_NODE(SoSeparator, node);
556 SoGroup * prevgroup = THISP(closure)->get_current_tail();
557 prevgroup->addChild(newsep);
558 thisp->vrmlpath->append(newsep);
559 return SoCallbackAction::CONTINUE;
560 }
561
562 SoCallbackAction::Response
pop_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * COIN_UNUSED_ARG (node))563 SoToVRMLActionP::pop_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * COIN_UNUSED_ARG(node))
564 {
565 THISP(closure)->vrmlpath->pop();
566 return SoCallbackAction::CONTINUE;
567 }
568
569 SoCallbackAction::Response
unsupported_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)570 SoToVRMLActionP::unsupported_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
571 {
572 SoInfo * info = NEW_NODE(SoInfo, node);
573 SbString str;
574 str.sprintf("Unsupported node: %s",
575 node->getTypeId().getName().getString());
576 info->string = str;
577 THISP(closure)->get_current_tail()->addChild(info);
578 return SoCallbackAction::CONTINUE;
579 }
580
581 void
init_gen(const SbBool color)582 SoToVRMLActionP::init_gen(const SbBool color)
583 {
584 SbBool dotex = FALSE;
585 SoGroup * tail = this->get_current_tail();
586 const int n = tail->getNumChildren();
587 for (int i = 0; i < n; i++) {
588 if (tail->getChild(i)->isOfType(SoTexture2::getClassTypeId())) {
589 dotex = TRUE;
590 break;
591 }
592 }
593
594 this->bsptree = new SbBSPTree;
595 if (dotex) this->bsptreetex = new SbBSPTree;
596 this->bsptreenormal = new SbBSPTree;
597
598 this->coordidx = new SbList <int32_t>;
599 this->normalidx = new SbList <int32_t>;
600 if (dotex) this->texidx = new SbList <int32_t>;
601 if (color) this->coloridx = new SbList <int32_t>;
602 }
603
604 SoCallbackAction::Response
post_primitives_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)605 SoToVRMLActionP::post_primitives_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
606 {
607 SoToVRMLActionP * thisp = THISP(closure);
608
609 int n;
610 SoGroup * tail = thisp->get_current_tail();
611 SoCoordinate3 * coord = new SoCoordinate3;
612 coord->point.setValues(0, thisp->bsptree->numPoints(),
613 thisp->bsptree->getPointsArrayPtr());
614 tail->addChild(coord);
615
616 SoIndexedFaceSet * ifs = NEW_NODE(SoIndexedFaceSet, node);
617 SoNormal * normal = new SoNormal;
618 normal->vector.setValues(0, thisp->bsptreenormal->numPoints(),
619 thisp->bsptreenormal->getPointsArrayPtr());
620 tail->addChild(normal);
621
622 ifs->coordIndex.setValues(0, thisp->coordidx->getLength(),
623 thisp->coordidx->getArrayPtr());
624 ifs->normalIndex.setValues(0, thisp->normalidx->getLength(),
625 thisp->normalidx->getArrayPtr());
626 if (thisp->texidx) {
627 SoTextureCoordinate2 * tex = new SoTextureCoordinate2;
628 ifs->textureCoordIndex.setValues(0, thisp->texidx->getLength(),
629 thisp->texidx->getArrayPtr());
630 tail->addChild(tex);
631 n = thisp->bsptreetex->numPoints();
632 tex->point.setNum(n);
633 SbVec2f * ptr = tex->point.startEditing();
634 for (int i = 0; i < n; i++) {
635 SbVec3f p = thisp->bsptreetex->getPoint(i);
636 ptr[i] = SbVec2f(p[0], p[1]);
637 }
638 tex->point.finishEditing();
639 }
640
641 if (thisp->coloridx) {
642 SoMaterialBinding * bind = new SoMaterialBinding;
643 bind->value = SoMaterialBinding::PER_VERTEX_INDEXED;
644 tail->addChild(bind);
645 ifs->materialIndex.setValues(0, thisp->coloridx->getLength(),
646 thisp->coloridx->getArrayPtr());
647 }
648
649 tail->addChild(ifs);
650
651 delete thisp->bsptree; thisp->bsptree = NULL;
652 delete thisp->bsptreetex; thisp->bsptreetex = NULL;
653 delete thisp->bsptreenormal; thisp->bsptreenormal = NULL;
654
655 delete thisp->coordidx; thisp->coordidx = NULL;
656 delete thisp->normalidx; thisp->normalidx = NULL;
657 delete thisp->texidx; thisp->texidx = NULL;
658 delete thisp->coloridx; thisp->coloridx = NULL;
659
660 return SoCallbackAction::CONTINUE;
661 }
662
663 void
triangle_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoPrimitiveVertex * v1,const SoPrimitiveVertex * v2,const SoPrimitiveVertex * v3)664 SoToVRMLActionP::triangle_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action),
665 const SoPrimitiveVertex * v1,
666 const SoPrimitiveVertex * v2,
667 const SoPrimitiveVertex * v3)
668 {
669 SoToVRMLActionP * thisp = THISP(closure);
670 assert(thisp->bsptree);
671 assert(thisp->bsptreenormal);
672
673 SoPrimitiveVertex const * const arr[3] = {v1, v2, v3};
674 for (int i = 0; i < 3; i++) {
675 const SoPrimitiveVertex * v = arr[i];
676 thisp->coordidx->append(thisp->bsptree->addPoint(v->getPoint()));
677 thisp->normalidx->append(thisp->bsptreenormal->addPoint(v->getNormal()));
678 if (thisp->texidx) {
679 assert(thisp->bsptreetex);
680 const SbVec4f & tc = v->getTextureCoords();
681 thisp->texidx->append(thisp->bsptreetex->addPoint(SbVec3f(tc[0], tc[1], 0.0f)));
682 }
683 if (thisp->coloridx) thisp->coloridx->append(v->getMaterialIndex());
684 }
685 thisp->coordidx->append(-1);
686 thisp->normalidx->append(-1);
687 if (thisp->texidx) thisp->texidx->append(-1);
688 if (thisp->coloridx) thisp->coloridx->append(-1);
689 }
690
691 #ifdef HAVE_VRML97
692
693 SoCallbackAction::Response
vrmlshape_cb(void * closure,SoCallbackAction * action,const SoNode * node)694 SoToVRMLActionP::vrmlshape_cb(void * closure, SoCallbackAction * action, const SoNode * node)
695 {
696 push_cb(closure, action, node);
697 return SoCallbackAction::CONTINUE;
698 }
699
700 SoCallbackAction::Response
vrmltransform_cb(void * closure,SoCallbackAction * action,const SoNode * node)701 SoToVRMLActionP::vrmltransform_cb(void * closure, SoCallbackAction * action, const SoNode * node)
702 {
703 push_cb(closure, action, node);
704 const SoVRMLTransform * oldt = coin_assert_cast<const SoVRMLTransform *>(node);
705 SoTransform * newt = NEW_NODE(SoTransform, node);
706
707 newt->translation = oldt->translation.getValue();
708 newt->rotation = oldt->rotation.getValue();
709 newt->scaleFactor = oldt->scale.getValue();
710 newt->scaleOrientation = oldt->scaleOrientation.getValue();
711 newt->center = oldt->center.getValue();
712 THISP(closure)->get_current_tail()->addChild(newt);
713 return SoCallbackAction::CONTINUE;
714 }
715
716 SoCallbackAction::Response
vrmldirlight_cb(void * closure,SoCallbackAction * action,const SoNode * node)717 SoToVRMLActionP::vrmldirlight_cb(void * closure, SoCallbackAction * action, const SoNode * node)
718 {
719 return unsupported_cb(closure, action, node);
720 }
721
722 SoCallbackAction::Response
vrmlpointlight_cb(void * closure,SoCallbackAction * action,const SoNode * node)723 SoToVRMLActionP::vrmlpointlight_cb(void * closure, SoCallbackAction * action, const SoNode * node)
724 {
725 return unsupported_cb(closure, action, node);
726 }
727
728 SoCallbackAction::Response
vrmlspotlight_cb(void * closure,SoCallbackAction * action,const SoNode * node)729 SoToVRMLActionP::vrmlspotlight_cb(void * closure, SoCallbackAction * action, const SoNode * node)
730 {
731 return unsupported_cb(closure, action, node);
732 }
733
734 SoCallbackAction::Response
vrmlpixeltex_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)735 SoToVRMLActionP::vrmlpixeltex_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
736 {
737 SoTexture2 * tex = NEW_NODE(SoTexture2, node);
738 const SoVRMLPixelTexture * oldtex = coin_assert_cast<const SoVRMLPixelTexture*>(node);
739 SbVec2s size;
740 int nc;
741 const unsigned char * bytes = oldtex->image.getValue(size, nc);
742 tex->image.setValue(size, nc, bytes);
743 THISP(closure)->get_current_tail()->addChild(tex);
744 return SoCallbackAction::CONTINUE;
745 }
746
747 SoCallbackAction::Response
vrmlimagetex_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)748 SoToVRMLActionP::vrmlimagetex_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
749 {
750 SoTexture2 * tex = NEW_NODE(SoTexture2, node);
751 const SoVRMLImageTexture * oldtex = coin_assert_cast<const SoVRMLImageTexture*>(node);
752 if (oldtex->url.getNum()) {
753 tex->filename = oldtex->url[0];
754 }
755 THISP(closure)->get_current_tail()->addChild(tex);
756 return SoCallbackAction::CONTINUE;
757 }
758
759 SoCallbackAction::Response
vrmllod_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)760 SoToVRMLActionP::vrmllod_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
761 {
762 SoLOD * lod = NEW_NODE(SoLOD, node);
763 const SoVRMLLOD * oldlod = coin_assert_cast<const SoVRMLLOD*>(node);
764 lod->center = oldlod->center.getValue();
765 lod->range.setValues(0, oldlod->range.getNum(),
766 oldlod->range.getValues(0));
767 THISP(closure)->get_current_tail()->addChild(lod);
768 THISP(closure)->vrmlpath->append(lod);
769 return SoCallbackAction::CONTINUE;
770 }
771
772 SoCallbackAction::Response
vrmlmaterial_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)773 SoToVRMLActionP::vrmlmaterial_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
774 {
775 SoMaterial * mat = NEW_NODE(SoMaterial, node);
776 const SoVRMLMaterial * oldmat = coin_assert_cast<const SoVRMLMaterial *>(node);
777 SbColor diffuse = oldmat->diffuseColor.getValue();
778 mat->diffuseColor = diffuse;
779 diffuse *= oldmat->ambientIntensity.getValue();
780 mat->ambientColor = diffuse;
781
782 mat->emissiveColor = oldmat->emissiveColor.getValue();
783 mat->specularColor = oldmat->specularColor.getValue();
784 mat->shininess = oldmat->shininess.getValue();
785 mat->transparency = oldmat->transparency.getValue();
786
787 THISP(closure)->get_current_tail()->addChild(mat);
788 return SoCallbackAction::CONTINUE;
789 }
790
791 SoCallbackAction::Response
vrmlswitch_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)792 SoToVRMLActionP::vrmlswitch_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
793 {
794 SoSwitch * sw = NEW_NODE(SoSwitch, node);
795 const SoVRMLSwitch * oldsw = coin_assert_cast<const SoVRMLSwitch *>(node);
796 sw->whichChild = oldsw->whichChoice.getValue();
797 THISP(closure)->get_current_tail()->addChild(sw);
798 THISP(closure)->vrmlpath->append(sw);
799 return SoCallbackAction::CONTINUE;
800 }
801
802 SoCallbackAction::Response
vrmltextransform_cb(void * closure,SoCallbackAction * action,const SoNode * node)803 SoToVRMLActionP::vrmltextransform_cb(void * closure, SoCallbackAction * action, const SoNode * node)
804 {
805 return unsupported_cb(closure, action, node);
806 }
807
808 SoCallbackAction::Response
vrmlviewpoint_cb(void * closure,SoCallbackAction * action,const SoNode * node)809 SoToVRMLActionP::vrmlviewpoint_cb(void * closure, SoCallbackAction * action, const SoNode * node)
810 {
811 return unsupported_cb(closure, action, node);
812 }
813
814 SoCallbackAction::Response
vrmlbox_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)815 SoToVRMLActionP::vrmlbox_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
816 {
817 SoCube * cube = NEW_NODE(SoCube, node);
818 const SoVRMLBox * box = coin_assert_cast<const SoVRMLBox *>(node);
819 cube->width = box->size.getValue()[0];
820 cube->height = box->size.getValue()[1];
821 cube->depth = box->size.getValue()[2];
822 THISP(closure)->get_current_tail()->addChild(cube);
823 return SoCallbackAction::CONTINUE;
824 }
825
826 SoCallbackAction::Response
vrmlcone_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)827 SoToVRMLActionP::vrmlcone_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
828 {
829 SoCone * cone = NEW_NODE(SoCone, node);
830 const SoVRMLCone * oldcone = coin_assert_cast<const SoVRMLCone *>(node);
831 cone->bottomRadius = oldcone->bottomRadius.getValue();
832 cone->height = oldcone->height.getValue();
833
834 int parts = 0;
835 if (oldcone->bottom.getValue()) parts |= SoCone::BOTTOM;
836 if (oldcone->side.getValue()) parts |= SoCone::SIDES;
837 cone->parts = static_cast<SoCone::Part>(parts);
838 THISP(closure)->get_current_tail()->addChild(cone);
839 return SoCallbackAction::CONTINUE;
840 }
841
842 SoCallbackAction::Response
vrmlcylinder_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)843 SoToVRMLActionP::vrmlcylinder_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
844 {
845 SoCylinder * cyl = NEW_NODE(SoCylinder, node);
846 const SoVRMLCylinder * oldcyl = coin_assert_cast<const SoVRMLCylinder*>(node);
847 cyl->radius = oldcyl->radius.getValue();
848 cyl->height = oldcyl->height.getValue();
849 int parts = 0;
850 if (oldcyl->side.getValue()) parts |= SoCylinder::SIDES;
851 if (oldcyl->top.getValue()) parts |= SoCylinder::TOP;
852 if (oldcyl->bottom.getValue()) parts |= SoCylinder::BOTTOM;
853 cyl->parts = static_cast<SoCylinder::Part>(parts);
854 THISP(closure)->get_current_tail()->addChild(cyl);
855 return SoCallbackAction::CONTINUE;
856 }
857
858 SoCallbackAction::Response
vrmlifs_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)859 SoToVRMLActionP::vrmlifs_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
860 {
861 const SoVRMLIndexedFaceSet * oldifs = coin_assert_cast<const SoVRMLIndexedFaceSet *>(node);
862
863 if (oldifs->coordIndex.getNum() == 0 ||
864 oldifs->coordIndex[0] < 0)
865 return SoCallbackAction::CONTINUE;
866
867 SoToVRMLActionP * thisp = THISP(closure);
868
869 SoIndexedFaceSet * ifs = NEW_NODE(SoIndexedFaceSet, node);
870
871 SoVRMLColor * color = coin_assert_cast<SoVRMLColor*>(oldifs->color.getValue());
872 SoVRMLCoordinate * coord = coin_assert_cast<SoVRMLCoordinate *>(oldifs->coord.getValue());
873 SoVRMLNormal * normal = coin_assert_cast<SoVRMLNormal *>(oldifs->normal.getValue());
874 SoVRMLTextureCoordinate * texcoord = coin_assert_cast<SoVRMLTextureCoordinate*>(oldifs->texCoord.getValue());
875
876 SoShapeHints * sh = new SoShapeHints;
877 sh->creaseAngle = oldifs->creaseAngle.getValue();
878 sh->vertexOrdering = oldifs->ccw.getValue() ?
879 SoShapeHints::COUNTERCLOCKWISE : SoShapeHints::CLOCKWISE;
880 sh->shapeType = oldifs->solid.getValue() ?
881 SoShapeHints::SOLID : SoShapeHints::UNKNOWN_SHAPE_TYPE;
882 sh->faceType = oldifs->convex.getValue() ?
883 SoShapeHints::CONVEX : SoShapeHints::UNKNOWN_FACE_TYPE;
884
885 SoGroup * tail = thisp->get_current_tail();
886 tail->addChild(sh);
887
888 if (coord) {
889 SbName name = coord->getName();
890 SoCoordinate3 * newcoord = coin_assert_cast<SoCoordinate3*>(
891 thisp->search_for_node(thisp->vrmlpath->getHead(),
892 name,
893 SoCoordinate3::getClassTypeId()));
894 if (!newcoord) {
895 newcoord = new SoCoordinate3;
896 newcoord->setName(name);
897 newcoord->point.setValues(0, coord->point.getNum(),
898 coord->point.getValues(0));
899 }
900 tail->addChild(newcoord);
901 }
902
903 if (normal) {
904 if (oldifs->normalPerVertex.getValue() != TRUE) {
905 SoNormalBinding * bind = new SoNormalBinding;
906 if (oldifs->normalIndex.getNum()) {
907 bind->value = SoMaterialBinding::PER_FACE_INDEXED;
908 }
909 else bind->value = SoMaterialBinding::PER_FACE;
910 tail->addChild(bind);
911 }
912 SbName name = normal->getName();
913 SoNormal * newnormal =
914 coin_assert_cast<SoNormal*>(thisp->search_for_node(thisp->vrmlpath->getHead(),
915 name,
916 SoNormal::getClassTypeId())
917 );
918 if (!newnormal) {
919 newnormal = new SoNormal;
920 newnormal->setName(name);
921 newnormal->vector.setValues(0, normal->vector.getNum(),
922 normal->vector.getValues(0));
923 }
924 tail->addChild(newnormal);
925 }
926 if (color) {
927 SoMaterialBinding * bind = new SoMaterialBinding;
928 if (oldifs->colorPerVertex.getValue()) {
929 bind->value = SoMaterialBinding::PER_VERTEX_INDEXED;
930 }
931 else {
932 if (oldifs->colorIndex.getNum()) {
933 bind->value = SoMaterialBinding::PER_FACE_INDEXED;
934 }
935 else {
936 bind->value = SoMaterialBinding::PER_FACE;
937 }
938 tail->addChild(bind);
939 }
940
941 SoMaterial * mat = thisp->find_or_create_material();
942 mat->diffuseColor.setValues(0, color->color.getNum(),
943 color->color.getValues(0));
944 }
945 if (texcoord) {
946 SbName name = texcoord->getName();
947 SoTextureCoordinate2 * newtc = coin_assert_cast<SoTextureCoordinate2*>(
948 thisp->search_for_node(thisp->vrmlpath->getHead(),
949 name,
950 SoTextureCoordinate2::getClassTypeId())
951 );
952 if (!newtc) {
953 newtc = new SoTextureCoordinate2;
954 newtc->setName(name);
955 newtc->point.setValues(0, texcoord->point.getNum(),
956 texcoord->point.getValues(0));
957 }
958 tail->addChild(newtc);
959 }
960
961 ifs->coordIndex.setValues(0, oldifs->coordIndex.getNum(),
962 oldifs->coordIndex.getValues(0));
963 if (oldifs->texCoordIndex.getNum()) {
964 ifs->textureCoordIndex.setValues(0, oldifs->texCoordIndex.getNum(),
965 oldifs->texCoordIndex.getValues(0));
966 }
967 if (oldifs->colorIndex.getNum()) {
968 ifs->materialIndex.setValues(0, oldifs->colorIndex.getNum(),
969 oldifs->colorIndex.getValues(0));
970 }
971 if (oldifs->normalIndex.getNum()) {
972 ifs->normalIndex.setValues(0, oldifs->normalIndex.getNum(),
973 oldifs->normalIndex.getValues(0));
974 }
975 tail->addChild(ifs);
976 return SoCallbackAction::CONTINUE;
977 }
978
979 SoCallbackAction::Response
vrmlils_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)980 SoToVRMLActionP::vrmlils_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
981 {
982 SoToVRMLActionP * thisp = THISP(closure);
983
984 const SoVRMLIndexedLineSet * oldils = coin_assert_cast<const SoVRMLIndexedLineSet*>(node);
985
986 if (oldils->coordIndex.getNum() == 0 ||
987 oldils->coordIndex[0] < 0) return SoCallbackAction::CONTINUE;
988
989 SoIndexedLineSet * ils = NEW_NODE(SoIndexedLineSet, node);
990
991 SoVRMLColor * color = coin_assert_cast<SoVRMLColor *>(oldils->color.getValue());
992 SoVRMLCoordinate * coord = coin_assert_cast<SoVRMLCoordinate *>(oldils->coord.getValue());
993 SoGroup * tail = thisp->get_current_tail();
994
995 SoCoordinate3 * newcoord = NULL;
996
997 if (coord) {
998 if (thisp->nodefuse) {
999 newcoord = new SoCoordinate3;
1000 }
1001 else {
1002 SbName name = coord->getName();
1003 newcoord = coin_assert_cast<SoCoordinate3*>(
1004 thisp->search_for_node(thisp->vrmlpath->getHead(),
1005 name,
1006 SoCoordinate3::getClassTypeId()));
1007 if (!newcoord) {
1008 newcoord = new SoCoordinate3;
1009 newcoord->setName(name);
1010 newcoord->point.setValues(0, coord->point.getNum(),
1011 coord->point.getValues(0));
1012 }
1013 }
1014 tail->addChild(newcoord);
1015 }
1016
1017 if (color) {
1018 SoMaterialBinding * bind = new SoMaterialBinding;
1019 if (oldils->colorPerVertex.getValue()) {
1020 bind->value = SoMaterialBinding::PER_VERTEX_INDEXED;
1021 }
1022 else {
1023 if (oldils->colorIndex.getNum()) {
1024 bind->value = SoMaterialBinding::PER_FACE_INDEXED;
1025 }
1026 else {
1027 bind->value = SoMaterialBinding::PER_FACE;
1028 }
1029 tail->addChild(bind);
1030 }
1031
1032 SoMaterial * mat = thisp->find_or_create_material();
1033 mat->diffuseColor.setValues(0, color->color.getNum(),
1034 color->color.getValues(0));
1035 }
1036
1037 if (thisp->nodefuse && coord) {
1038 SbBSPTree bsp;
1039 int n = oldils->coordIndex.getNum();
1040 const int32_t * src = oldils->coordIndex.getValues(0);
1041
1042 const SbVec3f * c = coord->point.getValues(0);
1043
1044 ils->coordIndex.setNum(n);
1045 int32_t * dst = ils->coordIndex.startEditing();
1046
1047 for (int i = 0; i < n; i++) {
1048 int idx = src[i];
1049 if (idx >= 0) {
1050 dst[i] = bsp.addPoint(c[idx]);
1051 }
1052 else dst[i] = -1;
1053 }
1054 ils->coordIndex.finishEditing();
1055 newcoord->point.setValues(0, bsp.numPoints(),
1056 bsp.getPointsArrayPtr());
1057
1058 }
1059 else {
1060 ils->coordIndex.setValues(0, oldils->coordIndex.getNum(),
1061 oldils->coordIndex.getValues(0));
1062 }
1063 if (oldils->colorIndex.getNum()) {
1064 ils->materialIndex.setValues(0, oldils->colorIndex.getNum(),
1065 oldils->colorIndex.getValues(0));
1066 }
1067 tail->addChild(ils);
1068 return SoCallbackAction::CONTINUE;
1069 }
1070
1071 SoCallbackAction::Response
vrmlpointset_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)1072 SoToVRMLActionP::vrmlpointset_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
1073 {
1074 SoToVRMLActionP * thisp = THISP(closure);
1075
1076 const SoVRMLPointSet * oldps = coin_assert_cast<const SoVRMLPointSet*>(node);
1077
1078 SoPointSet * ps = NEW_NODE(SoPointSet, node);
1079 SoGroup * tail = thisp->get_current_tail();
1080
1081 SoVRMLColor * color = coin_assert_cast<SoVRMLColor*>(oldps->color.getValue());
1082 SoVRMLCoordinate * coord = coin_assert_cast<SoVRMLCoordinate*>(oldps->coord.getValue());
1083
1084 if (coord) {
1085 SbName name = coord->getName();
1086 SoCoordinate3 * newcoord = coin_assert_cast<SoCoordinate3 *> (
1087 thisp->search_for_node(thisp->vrmlpath->getHead(),
1088 name,
1089 SoCoordinate3::getClassTypeId())
1090 );
1091 if (!newcoord) {
1092 newcoord = new SoCoordinate3;
1093 newcoord->setName(name);
1094 newcoord->point.setValues(0, coord->point.getNum(),
1095 coord->point.getValues(0));
1096 }
1097 tail->addChild(newcoord);
1098 }
1099
1100 if (color) {
1101 SoMaterial * mat = thisp->find_or_create_material();
1102 mat->diffuseColor.setValues(0, color->color.getNum(),
1103 color->color.getValues(0));
1104 }
1105
1106 tail->addChild(ps);
1107 return SoCallbackAction::CONTINUE;
1108 }
1109
1110 SoCallbackAction::Response
vrmlsphere_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)1111 SoToVRMLActionP::vrmlsphere_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
1112 {
1113 SoSphere * sphere = NEW_NODE(SoSphere, node);
1114 const SoVRMLSphere * oldsphere = coin_assert_cast<const SoVRMLSphere *>(node);
1115 sphere->radius = oldsphere->radius.getValue();
1116 THISP(closure)->get_current_tail()->addChild(sphere);
1117 return SoCallbackAction::CONTINUE;
1118 }
1119
1120 SoCallbackAction::Response
vrmlelevation_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)1121 SoToVRMLActionP::vrmlelevation_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
1122 {
1123 SoToVRMLActionP * thisp = THISP(closure);
1124
1125 SoGroup * tail = thisp->get_current_tail();
1126
1127 const SoVRMLElevationGrid * grid = coin_assert_cast<const SoVRMLElevationGrid*>(node);
1128 SoShapeHints * sh = new SoShapeHints;
1129 sh->creaseAngle = grid->creaseAngle.getValue();
1130 sh->vertexOrdering = grid->ccw.getValue() ?
1131 SoShapeHints::COUNTERCLOCKWISE : SoShapeHints::CLOCKWISE;
1132 sh->shapeType = grid->solid.getValue() ?
1133 SoShapeHints::SOLID : SoShapeHints::UNKNOWN_SHAPE_TYPE;
1134 sh->faceType = SoShapeHints::CONVEX;
1135 tail->addChild(sh);
1136
1137 SoVRMLColor * color = coin_assert_cast<SoVRMLColor *>(grid->color.getValue());
1138
1139 if (color) {
1140 SoMaterial * mat = thisp->find_or_create_material();
1141 mat->diffuseColor.setValues(0, color->color.getNum(),
1142 color->color.getValues(0));
1143 }
1144
1145 thisp->init_gen(color != NULL);
1146 return SoCallbackAction::CONTINUE;
1147 }
1148
1149 SoCallbackAction::Response
vrmlextrusion_cb(void * closure,SoCallbackAction * COIN_UNUSED_ARG (action),const SoNode * node)1150 SoToVRMLActionP::vrmlextrusion_cb(void * closure, SoCallbackAction * COIN_UNUSED_ARG(action), const SoNode * node)
1151 {
1152 SoToVRMLActionP * thisp = THISP(closure);
1153
1154 SoGroup * tail = thisp->get_current_tail();
1155
1156 const SoVRMLExtrusion * ext = coin_assert_cast<const SoVRMLExtrusion*>(node);
1157 SoShapeHints * sh = new SoShapeHints;
1158 sh->creaseAngle = ext->creaseAngle.getValue();
1159 sh->vertexOrdering = ext->ccw.getValue() ?
1160 SoShapeHints::COUNTERCLOCKWISE : SoShapeHints::CLOCKWISE;
1161 sh->shapeType = ext->solid.getValue() ?
1162 SoShapeHints::SOLID : SoShapeHints::UNKNOWN_SHAPE_TYPE;
1163 sh->faceType = ext->convex.getValue() ?
1164 SoShapeHints::CONVEX : SoShapeHints::UNKNOWN_FACE_TYPE;
1165 tail->addChild(sh);
1166
1167 thisp->init_gen(FALSE);
1168 return SoCallbackAction::CONTINUE;
1169 }
1170
1171 #endif // HAVE_VRML97
1172
1173 #undef NEW_NODE
1174 #undef PRIVATE
1175 #undef PUBLIC
1176 #undef THISP
1177