1 /*
2 * Node.cpp
3 *
4 * Copyright (C) 1999 Stephen F. White, 2005 J. "MUFTI" Scheurich
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file "COPYING" for details); if
18 * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19 * Cambridge, MA 02139, USA.
20 */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <ctype.h>
25 #include "stdafx.h"
26
27 #ifndef FLT_MIN
28 # include <float.h>
29 #endif
30
31 #include "MeshBasedNode.h"
32 #include "Scene.h"
33 #include "Field.h"
34 #include "FieldValue.h"
35 #include "FieldCommand.h"
36 #include "Proto.h"
37 #include "Path.h"
38 #include "SFNode.h"
39 #include "MFNode.h"
40 #include "SFString.h"
41 #include "MFString.h"
42 #include "EventIn.h"
43 #include "EventOut.h"
44 #include "ExposedField.h"
45 #include "URL.h"
46 #include "DuneApp.h"
47 #include "swDebugf.h"
48 #include "MoveCommand.h"
49 #include "NodeScript.h"
50 #include "NodeIndexedFaceSet.h"
51 #include "NodeCurveAnimation.h"
52 #include "NodePositionInterpolator.h"
53 #include "NodeOrientationInterpolator.h"
54 #include "NodeTimeSensor.h"
55 #include "NodeInline.h"
56 #include "NodeComment.h"
57 #include "ScriptEventDialog.h"
58
59 void
initIdentifier(void)60 NodeData::initIdentifier(void)
61 {
62 static int identifier_source = 0;
63 identifier_source++;
64 m_identifier = identifier_source;
65 m_identifierCopy = -1;
66 }
67
NodeData(Scene * scene,Proto * proto)68 NodeData::NodeData(Scene *scene, Proto *proto)
69 {
70 m_scene = scene;
71
72 m_graphX = m_graphY = 0;
73 m_graphWidth = m_graphHeight = 0;
74
75 m_refs = 0;
76 m_flags = 1<<NODE_FLAG_COLLAPSED;
77 m_proto = proto;
78
79 bool x3d = scene->isX3d();
80
81 m_numFields = m_proto->getNumFields();
82 m_fields = new FieldValue *[m_numFields];
83 for (int i = 0; i < m_numFields; i++) {
84 if (m_proto->getField(i)) {
85 m_fields[i] = m_proto->getField(i)->getDefault(x3d);
86 if (m_fields[i]) {
87 m_fields[i] = m_fields[i]->copy();
88 m_fields[i]->ref();
89 }
90 }
91 }
92 m_numEventIns = m_proto->getNumEventIns();
93 m_inputs = new SocketList[m_numEventIns];
94 m_numEventOuts = m_proto->getNumEventOuts();
95 m_outputs = new SocketList[m_numEventOuts];
96 m_insideProto = NULL;
97 m_nodePROTO = NULL;
98 m_canDraw = true;
99 handleIs();
100 generateTreeLabel();
101 m_name = "";
102 m_variableName = "";
103 m_isConvertedInCurveAnimaton = false;
104 setCounter4SceneTreeViewToZero();
105 m_written = false;
106 m_x3domId = "";
107 m_x3domOnOutputChange = "";
108 m_x3domOnClick = "";
109 m_writtenCompleteCProcessEvent = true;
110 m_alreadyConverted = false;
111 m_scene->addNode((Node*)this);
112 }
113
NodeData(const Node & node)114 NodeData::NodeData(const Node &node) {
115 copyData(node);
116 m_written = false;
117 m_identifierCopy = node.m_identifier;
118 m_alreadyConverted = false;
119 m_writtenCompleteCProcessEvent = true;
120 }
121
122 void
copyData(const NodeData & node)123 NodeData::copyData(const NodeData &node)
124 {
125 m_identifier = node.m_identifier;// all IDs are unique, except IDs of copies
126
127 m_scene = node.m_scene;
128 m_refs = 0;
129 m_graphX = m_graphY = 0;
130 m_graphWidth = m_graphHeight = 0;
131 m_flags = node.m_flags;
132 m_proto = node.m_proto;
133 m_numFields = m_proto->getNumFields();
134 m_fields = new FieldValue *[m_numFields];
135 if (node.m_name.length() != 0) {
136 if (!m_scene->hasAlreadyName(node.m_name))
137 m_scene->def(node.m_name, (Node *)this);
138 else
139 m_scene->makeSimilarName((Node *)this, node.m_name);
140 }
141 for (int i = 0; i < m_numFields; i++)
142 if (node.m_fields[i]) {
143 m_fields[i] = node.m_fields[i]->copy();
144 m_fields[i]->ref();
145 }
146 m_numEventIns = m_proto->getNumEventIns();
147 m_inputs = new SocketList[m_numEventIns];
148 m_numEventOuts = m_proto->getNumEventOuts();
149 m_outputs = new SocketList[m_numEventOuts];
150 m_insideProto = node.m_insideProto;
151 m_nodePROTO = node.m_nodePROTO;
152 m_canDraw = node.m_canDraw;
153 handleIs();
154 generateTreeLabel();
155 m_isConvertedInCurveAnimaton = node.m_isConvertedInCurveAnimaton;
156 m_variableName = node.m_variableName;
157 for (long i = 0; i < node.m_convertedNodes.size(); i++)
158 m_convertedNodes[i] = node.m_convertedNodes[i];
159 for (long i = 0; i < node.m_isEventIns.size(); i++)
160 m_isEventIns[i] = node.m_isEventIns[i];
161 for (long i = 0; i < node.m_isEventOuts.size(); i++)
162 m_isEventOuts[i] = node.m_isEventOuts[i];
163 for (long i = 0; i < node.m_isFields.size(); i++)
164 m_isFields[i] = node.m_isFields[i];
165 for (long i = 0; i < node.m_isExposedFields.size(); i++)
166 m_isExposedFields[i] = node.m_isExposedFields[i];
167 m_x3domId = m_x3domId && node.m_x3domId ?
168 strdup(node.m_x3domId) : NULL;
169 m_x3domOnOutputChange = m_x3domOnOutputChange &&
170 node.m_x3domOnOutputChange ?
171 strdup(node.m_x3domOnOutputChange) : NULL;
172 m_x3domOnClick = m_x3domOnClick && node.m_x3domOnClick ?
173 strdup(node.m_x3domOnClick) : NULL;
174 m_writtenCompleteCProcessEvent = true;
175 m_scene->addNode((Node*)this);
176 }
177
~NodeData()178 NodeData::~NodeData()
179 {
180 unref();
181 }
182
183 void
delete_this(void)184 NodeData::delete_this(void)
185 {
186 for (int i = 0; i < m_numFields; i++) {
187 m_fields[i]->unref();
188 }
189 m_numFields = 0;
190 delete [] m_fields;
191 delete [] m_inputs;
192 delete [] m_outputs;
193 m_scene->undef(m_name);
194 m_scene->removeNode((Node *)this);
195 }
196
197 int
translateField(int field) const198 NodeData::translateField(int field) const
199 {
200 return m_proto->translateField(field);
201 }
202
203 int
repairField(int field) const204 NodeData::repairField(int field) const
205 {
206 return translateField(field);
207 }
208
209 bool
isMesh(void)210 NodeData::isMesh(void)
211 {
212 return m_proto->isMesh();
213 }
214
215
Node(Scene * scene,Proto * proto)216 Node::Node(Scene *scene, Proto *proto) : NodeData(scene,proto)
217 {
218 initIdentifier();
219 m_commentsList = new NodeList;
220 m_geometricParentIndex = -1;
221 m_numberCDataFunctions = 0;
222 m_containerField = -1;
223 m_protoParent = NULL;
224 m_isUse = false;
225 ref();
226 }
227
Node(const Node & node)228 Node::Node(const Node &node) : NodeData(node)
229 {
230 m_geometricParentIndex = node.getGeometricParentIndex();
231 m_commentsList = new NodeList;
232 ref();
233 m_numberCDataFunctions = node.m_numberCDataFunctions;
234 }
235
Node(const Node & node,Proto * proto)236 Node::Node(const Node &node, Proto *proto) : NodeData(node)
237 {
238 initIdentifier();
239 m_geometricParentIndex = node.getGeometricParentIndex();
240 m_proto = proto;
241 for (int i = 0; i < proto->getNumEventOuts(); i++)
242 m_outputs[i] = node.m_outputs[i];
243 m_commentsList = new NodeList;
244 ref();
245 m_numberCDataFunctions = 0;
246 m_containerField = -1;
247 }
248
~Node()249 Node::~Node()
250 {
251 delete m_commentsList;
252 }
253
254 bool
matchNodeClass(int childType) const255 NodeData::matchNodeClass(int childType) const
256 {
257 return m_proto->matchNodeClass(childType);
258 }
259
260 void
copyParentList(const Node & node)261 NodeData::copyParentList(const Node &node)
262 {
263 for (long i = 0; i < node.m_parents.size(); i++)
264 m_parents.append(node.m_parents[i]);
265 }
266
267 int
getType() const268 NodeData::getType() const
269 {
270 if (m_proto && isPROTO() && m_scene)
271 return m_scene->getProtoType(m_proto);
272 if (m_proto)
273 return m_proto->getType();
274 return -1;
275 }
276
277 int
getNodeClass() const278 NodeData::getNodeClass() const
279 {
280 if (m_proto)
281 return m_proto->getNodeClass();
282 return CHILD_NODE;
283 }
284
285 int
getMaskedNodeClass(void)286 NodeData::getMaskedNodeClass(void)
287 {
288 if (m_proto)
289 return ::getMaskedNodeClass(getNodeClass());
290 return 0;
291 }
292
293 bool
hasName(void)294 NodeData::hasName(void)
295 {
296 if (m_name.length() == 0)
297 return false;
298 if (m_name.length() == 0)
299 if (needsDEF())
300 m_scene->generateUniqueNodeName((Node *)this);
301 if (m_name.length() == 0)
302 return false;
303 else
304 return true;
305 }
306
307 const MyString&
getName(void)308 NodeData::getName(void)
309 {
310 if (needsDEF())
311 if (m_name.length() == 0)
312 m_scene->generateUniqueNodeName((Node *)this);
313 return m_name;
314 }
315
316 const MyString&
getNameOrNewName(void)317 NodeData::getNameOrNewName(void)
318 {
319 if (m_name.length() == 0)
320 m_scene->generateUniqueNodeName((Node *)this);
321 return m_name;
322 }
323
324 void
setName(const char * name)325 NodeData::setName(const char *name)
326 {
327 m_scene->undef(m_name);
328 m_name = name;
329 generateTreeLabel();
330 }
331
332 bool
needsDEF() const333 NodeData::needsDEF() const
334 {
335 if (m_name.length() != 0) return true;
336
337 if (((Node *)this)->getNumParents() > 1) return true;
338
339 for (int i = 0; i < m_numEventIns; i++) {
340 if (m_inputs[i].size() > 0) {
341 return true;
342 }
343 }
344
345 for (int j = 0; j < m_numEventOuts; j++) {
346 if (m_outputs[j].size() > 0) {
347 return true;
348 }
349 }
350
351 return false;
352 }
353
354 // C/C++/java keywords not possible as variable names
355 static const char *keyWords[] = {
356 "abstract",
357 "asm",
358 "auto",
359 "bool",
360 "boolean",
361 "break",
362 "byte",
363 "case",
364 "catch",
365 "char",
366 "class",
367 "const",
368 "continue",
369 "default",
370 "delete",
371 "do",
372 "double",
373 "else",
374 "enum",
375 "extends",
376 "extern",
377 "final",
378 "finally",
379 "float",
380 "for",
381 "friend",
382 "goto",
383 "if",
384 "implements",
385 "import",
386 "inline",
387 "instanceof",
388 "int",
389 "interface",
390 "long",
391 "native",
392 "new",
393 "operator",
394 "package",
395 "private",
396 "protected",
397 "public",
398 "register",
399 "return",
400 "short",
401 "signed",
402 "sizeof",
403 "static",
404 "strictfp",
405 "String",
406 "struct",
407 "super",
408 "switch",
409 "synchronized",
410 "template",
411 "this",
412 "throw",
413 "throws",
414 "transient",
415 "try",
416 "typedef",
417 "union",
418 "unsigned",
419 "virtual",
420 "void",
421 "volatile",
422 "while"
423 };
424
425 const char *
getVariableName(void)426 NodeData::getVariableName(void)
427 {
428 bool hasname = hasName();
429 bool isRoot = false;
430 if (m_variableName.length() == 0) {
431 MyString cName = "";
432 if ((m_name != NULL) && (m_name.length() > 0)) {
433 if (isalpha(m_name[0]))
434 cName += m_name[0];
435 else
436 cName += "A";
437 for (int i = 1; i < m_name.length(); i++)
438 if (isalnum(m_name[i]))
439 cName += m_name[i];
440 else
441 cName += "m_";
442 hasname = true;
443 }
444
445 if (m_scene != NULL) {
446 if (m_scene->getRoot() == this) {
447 isRoot = true;
448 m_variableName = "";
449 m_variableName += "root";
450 }
451 }
452 if ((!isRoot) && hasname) {
453 m_variableName = "";
454 bool isKeyWord = false;
455 for (unsigned int i = 0;
456 i < sizeof(keyWords)/sizeof(const char *); i++)
457 if (strcmp(m_name.getData(), keyWords[i]) == 0) {
458 isKeyWord = true;
459 m_variableName += cName;
460 swDebugf("Warning: Variablename ");
461 swDebugf("\"%s\"", m_name.getData());
462 swDebugf(" is a C++/java keyword, ");
463 swDebugf("\"%s\"", m_variableName.getData());
464 swDebugf(" used instead\n");
465 }
466 if (!isKeyWord)
467 m_variableName += cName;
468 }
469 if (m_variableName.length() == 0)
470 if (m_scene != NULL) {
471 setVariableName(m_scene->generateUniqueNodeName((Node *)this));
472 // m_variableName.sub("ColorRGBA", "Color");
473 m_name = "";
474 m_name += m_variableName;
475 }
476 }
477
478 return m_variableName;
479 }
480
481 void
setVariableName(const char * name)482 NodeData::setVariableName(const char *name)
483 {
484 m_variableName = "";
485 m_variableName += name;
486 }
487
488 const char *
getClassName(void)489 NodeData::getClassName(void)
490 {
491 if (m_proto)
492 return m_proto->getClassName();
493 return NULL;
494 }
495
496
497 FieldValue *
getField(int index) const498 NodeData::getField(int index) const
499 {
500 #ifdef DEBUG
501 assert(index >= 0 && index < m_numFields);
502 #else
503 if ((index < 0) && (index >= m_numFields)) {
504 printf("Internal error in NodeData::getField\n");
505 return NULL;
506 }
507 #endif
508 if (m_scene != NULL)
509 if (((m_scene->getWriteFlags() & (CONVERT2VRML | CONVERT2X3D)) != 0) ||
510 m_scene->isX3d())
511 return m_fields[translateField(index)];
512 return m_fields[index];
513 }
514
515 void
setField(int fieldIndex,FieldValue * value,int containerField)516 NodeData::setField(int fieldIndex, FieldValue *value, int containerField)
517 {
518 int index = fieldIndex;
519 if (m_scene != NULL)
520 if (((m_scene->getWriteFlags() & (CONVERT2VRML | CONVERT2X3D)) == 0) ||
521 m_scene->isX3d())
522 index = translateField(index);
523 assert(index >= 0 && index < m_numFields);
524 Field *field = m_proto->getField(index);
525 if ((field != NULL) && value && (value->getRefs() != 0))
526 assert(field->getType() == value->getType());
527
528 // if field is an SFNode or MFNode type, remove old values from
529 // children's parent list
530
531 bool isNode = false;
532 if (m_fields[index] && m_fields[index]->getType() == SFNODE) {
533 isNode = true;
534 Node *child = ((SFNode *) m_fields[index])->getValue();
535 if (child) child->removeParent();
536 } else if (m_fields[index] && m_fields[index]->getType() == MFNODE) {
537 isNode = true;
538 NodeList *childList = ((MFNode *) m_fields[index])->getValues();
539 if (childList) {
540 for (long i = 0; i < childList->size(); i++) {
541 Node *child = childList->get(i);
542 if (child) child->removeParent();
543 }
544 }
545 }
546
547 if (value && value->getRefs() > -1)
548 value->clamp(field->getMin(), field->getMax());
549
550 if (m_fields[index] != NULL)
551 m_fields[index]->unref();
552 m_fields[index] = value;
553 if (value)
554 m_fields[index]->ref();
555 if (value && isNode) {
556 if (containerField != -1)
557 m_fields[index]->setContainerField(containerField);
558 }
559
560 if (value && value->getType() == SFNODE) {
561 Node *child = ((SFNode *) value)->getValue();
562 if (child) child->addParent((Node*)this, index);
563 } else if (value && value->getType() == MFNODE) {
564 NodeList *childList = ((MFNode *) value)->getValues();
565 if (childList) {
566 for (long i = 0; i < childList->size(); i++) {
567 Node *child = childList->get(i);
568 if (child) child->addParent((Node*)this, index);
569 }
570 }
571 }
572 // handle IS
573 if (field && (field->getFlags() & FF_IS))
574 for (int i = 0; i < field->getNumIs(); i++) {
575 Node *isNode = getIsNode(field->getIsNodeIndex(i));
576 if (isNode)
577 isNode->setField(field->getIsField(i), value);
578 }
579 ExposedField *expField = field->getExposedField();
580 if (expField) {
581 if (expField->getFlags() & FF_IS)
582 for (int i = 0; i < expField->getNumIs(); i++) {
583 Node *isNode = getIsNode(expField->getIsNodeIndex(i));
584 if (isNode)
585 isNode->setField(expField->getIsField(i), value);
586 }
587 if (m_scene) {
588 int eventOut = expField->getEventOut();
589 SocketList::Iterator *i;
590 for (i = m_outputs[eventOut].first(); i != NULL; i = i->next()) {
591 RouteSocket s = i->item();
592 s.getNode()->receiveEvent(s.getField(), swGetCurrentTime(),
593 value);
594 }
595 }
596 }
597 if (m_scene)
598 m_scene->setNotSaved();
599 }
600
601 FieldValue *
getUntranslatedField(int index) const602 NodeData::getUntranslatedField(int index) const
603 {
604 #ifdef DEBUG
605 assert(index >= 0 && index < m_numFields);
606 #else
607 if ((index < 0) && (index >= m_numFields)) {
608 printf("Internal error in NodeData::getField\n");
609 return NULL;
610 }
611 #endif
612 return m_fields[index];
613 }
614
615 void
addFieldNodeList(int index,NodeList * childList,int containerField)616 Node::addFieldNodeList(int index, NodeList *childList, int containerField)
617 {
618 assert(index >= 0 && index < m_numFields);
619 if (((MFNode*)m_fields[index])->getSize() == 0)
620 setField(index, new MFNode(childList), containerField);
621 else {
622 for (long i = 0; i < childList->size(); i++) {
623 Node *child = childList->get(i);
624 FieldValue* newField= ((MFNode*)m_fields[index])->addNode(child);
625 ((MFNode*)m_fields[index])->setContainerField(containerField);
626 newField->clamp(m_proto->getField(index)->getMin(),
627 m_proto->getField(index)->getMax());
628
629 m_fields[index]->unref();
630 m_fields[index] = newField;
631 m_fields[index]->ref();
632 if (child) {
633 child->addParent(this, index);
634 }
635 }
636 }
637 ((MFNode*)m_fields[index])->getValues();
638 }
639
640 int
write(int f,int indent,bool avoidUse)641 Node::write(int f, int indent, bool avoidUse)
642 {
643 bool x3d = m_scene->isX3dv();
644 if (m_proto) {
645 TheApp->checkSelectionLinenumberCounting(m_scene, (Node*) this);
646 if ((!avoidUse) && getFlag(NODE_FLAG_DEFED) && (m_name.length() > 0)) {
647 RET_ONERROR( mywritestr(f, "USE ") )
648 RET_ONERROR( mywritestr(f, (const char *) m_name) )
649 RET_ONERROR( mywritestr(f, "\n") )
650 TheApp->incSelectionLinenumber();
651 } else {
652 if (avoidUse) {
653 m_scene->generateUniqueNodeName((Node*)this,
654 getProto()->getName(x3d));
655 }
656 if (((Node *)this)->needsDEF()) {
657 if (!m_name[0])
658 m_scene->generateUniqueNodeName((Node*)this);
659 RET_ONERROR( mywritestr(f, "DEF ") )
660 RET_ONERROR( mywritestr(f, (const char *) m_name) )
661 RET_ONERROR( mywritestr(f, " ") )
662 }
663 setFlag(NODE_FLAG_DEFED);
664 bool writeProtoName = true;
665 if (m_scene->isPureVRML97())
666 if ((TheApp->getCoverMode() && (!hasDefault(FF_COVER_ONLY))) ||
667 (TheApp->getKambiMode() && (!hasDefault(FF_KAMBI_ONLY)))) {
668 Proto *extension = m_scene->getExtensionProto(m_proto);
669 if (extension != NULL) {
670 writeProtoName = false;
671 RET_ONERROR( mywritestr(f, extension->getName(x3d)) )
672 }
673 }
674 if (writeProtoName) {
675 RET_ONERROR( mywritestr(f,
676 (const char *) m_proto->getName(x3d)))
677 }
678
679 if (!TheApp->GetkrFormating()) {
680 RET_ONERROR( mywritestr(f, "\n") )
681 TheApp->incSelectionLinenumber();
682 RET_ONERROR( indentf(f, indent + TheApp->GetIndent()) )
683 } else
684 RET_ONERROR( mywritestr(f, " ") )
685
686 RET_ONERROR( mywritestr(f, "{\n") )
687 TheApp->incSelectionLinenumber();
688 RET_ONERROR( writeFields(f, indent + TheApp->GetIndent()) )
689 if (!TheApp->GetkrFormating())
690 RET_ONERROR( indentf(f, indent + TheApp->GetIndent()) )
691 else
692 RET_ONERROR( indentf(f, indent) )
693 RET_ONERROR( mywritestr(f, "}\n") )
694 TheApp->incSelectionLinenumber();
695 if (indent==0) {
696 RET_ONERROR( mywritestr(f, "\n") )
697 TheApp->incSelectionLinenumber();
698 }
699 RET_ONERROR( writeRoutes(f, indent) )
700 setFlag(NODE_FLAG_TOUCHED);
701 }
702 }
703 return(0);
704 }
705
706 int
writeXml(int f,int indent,int containerField,bool avoidUse)707 Node::writeXml(int f, int indent, int containerField, bool avoidUse)
708 {
709 bool x3d = true;
710 if (getType() == VRML_COMMENT) {
711 MFString *value = ((NodeComment *)this)->comment();
712 RET_ONERROR( indentf(f, indent) )
713 RET_ONERROR( mywritestr(f, "<!--") )
714 if (value->getSize() > 1)
715 RET_ONERROR( mywritestr(f, "\n") )
716 TheApp->checkSelectionLinenumberCounting(m_scene, this);
717 for (int i = 0; i < value->getSize(); i++) {
718 if (value->getSize() > 1)
719 RET_ONERROR( indentf(f, indent + TheApp->GetIndent()) )
720 RET_ONERROR( mywritestr(f, (const char *) value->getValue(i)) )
721 if (value->getSize() > 1)
722 RET_ONERROR( mywritestr(f, "\n") )
723 TheApp->incSelectionLinenumber();
724 }
725 if (value->getSize() > 1)
726 RET_ONERROR( indentf(f, indent) )
727 RET_ONERROR( mywritestr(f, "-->\n") )
728 return 0;
729 } else if ((getType() == VRML_IMAGE_TEXTURE) &&
730 ((m_scene->getWriteFlags() & X3DOM) != 0)) {
731 NodeImageTexture *texture = (NodeImageTexture *)this;
732 Node *pixelTexture = texture->getPixelTexture();
733 return pixelTexture->writeXml(f, indent, containerField);
734 }
735
736 if (m_proto) {
737 Proto *protoToWrite = NULL;
738 TheApp->checkSelectionLinenumberCounting(m_scene, (Node*) this);
739 RET_ONERROR( indentf(f, indent) )
740 RET_ONERROR( mywritestr(f, "<") )
741 if (m_scene->isPureVRML97() &&
742 ((TheApp->getCoverMode() && (!hasDefault(FF_COVER_ONLY))) ||
743 (TheApp->getKambiMode() && (!hasDefault(FF_KAMBI_ONLY))))) {
744 protoToWrite = m_scene->getExtensionProto(m_proto);
745 } else if (isPROTO() ||
746 m_proto->isScriptedProto() ||
747 m_proto->isScriptedExternProto()) {
748 protoToWrite = m_proto;
749 }
750 bool containerFieldWritten = false;
751 if (protoToWrite == NULL) {
752 #ifdef HAVE_NO_STATIC_GROUP_X3DOM
753 if ((m_scene->getWriteFlags() & X3DOM) &&
754 strcmp(m_proto->getName(x3d), "StaticGroup") == 0)
755 RET_ONERROR( mywritestr(f, "Group") )
756 else
757 RET_ONERROR(mywritestr(f, (const char *) m_proto->getName(x3d)))
758 #else
759 RET_ONERROR( mywritestr(f, (const char *) m_proto->getName(x3d)) )
760 #endif
761 /*
762 if (hasParent()) {
763 if ((getParent()->showFields()) &&
764 (getParent()->getType() != VRML_SCRIPT)) {
765 Node *parent = getParent();
766 int cField = containerField;
767 if (cField == -1)
768 cField = getParentField();
769 if (cField != getParentField()) {
770 parent = searchParentField(cField);
771 }
772 const char *name = parent->getProto()->getField(
773 cField)->getName(x3d);
774 containerFieldWritten = true;
775 }
776 }
777 */
778 } else {
779 RET_ONERROR( mywritestr(f, "ProtoInstance name='") )
780 RET_ONERROR( mywritestr(f, protoToWrite->getName(x3d)) )
781 RET_ONERROR( mywritestr(f, "'") )
782 }
783
784 if ((!avoidUse) && getFlag(NODE_FLAG_DEFED)) {
785 RET_ONERROR( mywritestr(f, " USE='") )
786 RET_ONERROR( mywritestr(f, (const char *) m_name) )
787 RET_ONERROR( mywritestr(f, "'") )
788 if (hasParent() &&
789 (containerFieldWritten == false)) {
790 if ((getParent()->showFields()) &&
791 (getParent()->getType() != VRML_SCRIPT)) {
792 Node *parent = getParent();
793 int cField = containerField;
794 if (cField == -1)
795 cField = getParentField();
796 if (cField != getParentField()) {
797 parent = searchParentField(cField);
798 }
799 const char *name = parent->getProto()->getField(
800 cField)->getName(x3d);
801 /*
802 RET_ONERROR( mywritestr(f, " containerField='") )
803 RET_ONERROR( mywritestr(f, name) )
804 RET_ONERROR( mywritestr(f, "'") )
805 */
806 }
807 }
808 RET_ONERROR( mywritestr(f, ">\n") )
809 RET_ONERROR( indentf(f, indent) )
810 RET_ONERROR( mywritestr(f, "</") )
811 #ifdef HAVE_NO_STATIC_GROUP_X3DOM
812 if ((m_scene->getWriteFlags() & X3DOM) &&
813 strcmp(m_proto->getName(x3d), "StaticGroup") == 0)
814 RET_ONERROR( mywritestr(f, "Group") )
815 else
816 RET_ONERROR(mywritestr(f, (const char *) m_proto->getName(x3d)))
817 #else
818 RET_ONERROR( mywritestr(f, (const char *) m_proto->getName(x3d)) )
819 #endif
820 RET_ONERROR( mywritestr(f, ">\n") )
821 TheApp->incSelectionLinenumber();
822 } else {
823 if (avoidUse) {
824 m_scene->generateUniqueNodeName((Node*)this,
825 getProto()->getName(x3d));
826 }
827 if (((Node *)this)->needsDEF()) {
828 if (!m_name[0])
829 m_scene->generateUniqueNodeName((Node*)this);
830 RET_ONERROR( mywritestr(f, " DEF='") )
831 RET_ONERROR( mywritestr(f, (const char *) m_name) )
832 RET_ONERROR( mywritestr(f, "' ") )
833 setFlag(NODE_FLAG_DEFED);
834 if (m_scene->getWriteFlags() & X3DOM) {
835 RET_ONERROR( mywritestr(f, "id='") )
836 if ((m_x3domId == NULL) || strlen(m_x3domId) == 0)
837 RET_ONERROR( mywritestr(f, (const char *) m_name) )
838 else
839 RET_ONERROR( mywritestr(f,m_x3domId) )
840 RET_ONERROR( mywritestr(f, "' ") )
841 if (m_x3domOnOutputChange &&
842 strlen(m_x3domOnOutputChange) != 0) {
843 RET_ONERROR( mywritestr(f, "OnOutputChange='") )
844 RET_ONERROR( mywritestr(f,m_x3domOnOutputChange) )
845 RET_ONERROR( mywritestr(f, "' ") )
846 }
847 if (m_x3domOnClick && strlen(m_x3domOnClick) != 0) {
848 RET_ONERROR( mywritestr(f, "OnClick='") )
849 RET_ONERROR( mywritestr(f,m_x3domOnClick) )
850 RET_ONERROR( mywritestr(f, "' ") )
851 }
852 }
853 }
854 RET_ONERROR( mywritestr(f, " ") )
855 RET_ONERROR( writeXmlFields(f, indent, XML_IN_TAG,
856 containerField, avoidUse) )
857 RET_ONERROR( mywritestr(f, ">\n") )
858 TheApp->incSelectionLinenumber();
859 RET_ONERROR( writeXmlFields(f, indent, XML_NODE,
860 containerField, avoidUse) )
861 RET_ONERROR( writeXmlFields(f, indent + TheApp->GetIndent(),
862 XML_PROTO_INSTANCE_FIELD,
863 containerField, avoidUse) )
864 if (getProto()->getNumNodes() > 0)
865 RET_ONERROR( writeXmlFields(f, indent + TheApp->GetIndent(),
866 XML_IS, containerField, avoidUse) )
867 RET_ONERROR( indentf(f, indent) )
868 RET_ONERROR( mywritestr(f, "</") )
869 if (protoToWrite == NULL) {
870 #ifdef HAVE_NO_STATIC_GROUP_X3DOM
871 if ((m_scene->getWriteFlags() & X3DOM) &&
872 strcmp(m_proto->getName(x3d), "StaticGroup") == 0)
873 RET_ONERROR( mywritestr(f, "Group") )
874 else
875 RET_ONERROR( mywritestr(f,
876 (const char *) m_proto->getName(x3d)) )
877 #else
878 RET_ONERROR( mywritestr(f, (const char *) m_proto->getName(x3d)))
879 #endif
880 } else
881 RET_ONERROR( mywritestr(f, "ProtoInstance") )
882 RET_ONERROR( mywritestr(f, ">\n") )
883 TheApp->incSelectionLinenumber();
884 if (!avoidUse) {
885 RET_ONERROR( writeRoutes(f, indent) )
886 setFlag(NODE_FLAG_TOUCHED);
887 } else
888 m_scene->copyRoutesToScene(this);
889 }
890 }
891 return 0;
892 }
893
894 int
writeProto(int filedes)895 NodeData::writeProto(int filedes)
896 {
897 // used to write the EXTERNPROTO definition of extension nodes
898 return 0;
899 }
900
901 int
writeProto(int f,const char * urn,const char * directoryName,const char * haveUrl,bool nameInUrl)902 NodeData::writeProto(int f, const char *urn, const char *directoryName,
903 const char *haveUrl, bool nameInUrl)
904 {
905 if (m_scene->isX3dXml())
906 return m_proto->write(f, 0, X3D_XML);
907 const char* nodeName = m_proto->getName(m_scene->isX3d());
908 RET_ONERROR( mywritef(f, "EXTERNPROTO %s[\n", nodeName) )
909 TheApp->incSelectionLinenumber();
910 RET_ONERROR( writeProtoArguments(f) )
911 RET_ONERROR( mywritestr(f, " ]\n") )
912 TheApp->incSelectionLinenumber();
913 RET_ONERROR( mywritestr(f, "[\n") )
914 TheApp->incSelectionLinenumber();
915 if (strlen(urn) > 0) {
916 RET_ONERROR( mywritef(f, " \"%s:%s\"\n", urn, nodeName) )
917 TheApp->incSelectionLinenumber();
918 }
919 RET_ONERROR( mywritef(f, " \"%sPROTO.wrl\"\n", nodeName) )
920 TheApp->incSelectionLinenumber();
921 RET_ONERROR( mywritestr(f, " \"") )
922 char *dunedocs = getenv("DUNEDOCS");
923 if (dunedocs != NULL) {
924 RET_ONERROR( mywritestr(f, dunedocs) )
925 RET_ONERROR( mywritestr(f, "/") )
926 RET_ONERROR( mywritestr(f, directoryName) )
927 RET_ONERROR( mywritestr(f, "/") )
928 } else if (strlen(haveUrl) > 0) {
929 RET_ONERROR( mywritestr(f, haveUrl) )
930 if (nameInUrl)
931 RET_ONERROR( mywritestr(f, "/") )
932 else
933 RET_ONERROR( mywritestr(f, "\"\n") )
934 }
935 if ((dunedocs != NULL) || (nameInUrl))
936 RET_ONERROR( mywritef(f, "%sPROTO.wrl\"\n", nodeName) )
937 TheApp->incSelectionLinenumber();
938 RET_ONERROR( mywritef(f,
939 " \"%s/docs/%s/%sPROTO.wrl\"\n",
940 "http://wdune.ourproject.org/",
941 directoryName, nodeName) )
942 TheApp->incSelectionLinenumber();
943 RET_ONERROR( mywritestr(f, "]\n") )
944 TheApp->incSelectionLinenumber();
945 return 0;
946 }
947
948 int
writeX3dProto(int filedes)949 NodeData::writeX3dProto(int filedes)
950 {
951 return ((Node *)this)->writeProto(filedes,
952 "urn:web3d:x3d:node:",
953 "x3d"
954 #ifdef HAVE_X3D_PROTO_URL
955 , HAVE_X3D_PROTO_URL
956 #endif
957 );
958 }
959
960 int
writeIs(int f,int indent,const char * name,const char * isName)961 NodeData::writeIs(int f, int indent, const char *name, const char* isName)
962 {
963 RET_ONERROR( indentf(f, indent) )
964 RET_ONERROR( mywritestr(f, name) )
965 RET_ONERROR( mywritestr(f, " IS ") )
966 RET_ONERROR( mywritestr(f, isName) )
967 RET_ONERROR( mywritestr(f, "\n") )
968 TheApp->incSelectionLinenumber();
969 return 0;
970 }
971
972 int
writeXmlIs(int f,int indent,const char * name,const char * isName)973 NodeData::writeXmlIs(int f, int indent, const char *name, const char* isName)
974 {
975 RET_ONERROR( indentf(f, indent) )
976 RET_ONERROR( mywritestr(f, "<connect nodeField='") )
977 RET_ONERROR( mywritestr(f, name) )
978 RET_ONERROR( mywritestr(f, "' protoField='") )
979 RET_ONERROR( mywritestr(f, isName) )
980 RET_ONERROR( mywritestr(f, "' />\n") )
981 TheApp->incSelectionLinenumber();
982 return 0;
983 }
984
985
986 int
writeXmlProtoInstanceField(int f,int indent,const char * name,FieldValue * value)987 NodeData::writeXmlProtoInstanceField(int f, int indent, const char *name,
988 FieldValue* value)
989 {
990 bool isNode = false;
991 bool needValue = true;
992 if (value->getType() == SFNODE) {
993 if (((SFNode *)value)->getValue() == NULL)
994 needValue = false;
995 else
996 isNode = true;
997 }
998 if (value->getType() == MFNODE) {
999 if (((MFieldValue *)value)->getSFSize() == 0)
1000 needValue = false;
1001 else
1002 isNode = true;
1003 }
1004
1005 RET_ONERROR( indentf(f, indent) )
1006 RET_ONERROR( mywritestr(f, "<fieldValue name='") )
1007 RET_ONERROR( mywritestr(f, name) )
1008 RET_ONERROR( mywritestr(f, "' ") )
1009 if (isNode)
1010 RET_ONERROR( mywritestr(f, ">\n") )
1011 else if (needValue)
1012 RET_ONERROR( mywritestr(f, "value=") )
1013 RET_ONERROR( value->writeXml(f, indent) )
1014 if (isNode) {
1015 RET_ONERROR( indentf(f, indent) )
1016 RET_ONERROR( mywritestr(f, "</fieldValue>\n") )
1017 } else {
1018 RET_ONERROR( mywritestr(f, "/>\n") )
1019 }
1020 TheApp->incSelectionLinenumber();
1021 return 0;
1022 }
1023
1024 const char *
searchIsName(int i,int type)1025 NodeData::searchIsName(int i, int type)
1026 {
1027 Element *element = NULL;
1028 switch (type) {
1029 case EL_FIELD:
1030 element = m_proto->getField(i);
1031 break;
1032 case EL_EVENT_IN:
1033 element = m_proto->getEventIn(i);
1034 break;
1035 case EL_EVENT_OUT:
1036 element = m_proto->getEventOut(i);
1037 break;
1038 default:
1039 return NULL;
1040 }
1041 if (m_scene->isInvalidElement(element))
1042 return NULL;
1043 if (!isInsideProto())
1044 return NULL;
1045
1046 bool x3d = m_scene->isX3d();
1047 const char *isName = NULL;
1048 bool stopLoop = false;
1049 for (int j = 0; j < m_scene->getNumProtoNames(); j++) {
1050 const char *protoName = m_scene->getProtoName(j);
1051 Proto *proto = m_scene->getProto(protoName);
1052 int isElement = -1;
1053 ExposedField *exposedField = NULL;
1054 int field = i;
1055 int myType = type;
1056 switch (type) {
1057 case EL_EVENT_IN:
1058 exposedField = ((EventIn *)element)->getExposedField();
1059 if (exposedField) {
1060 field = exposedField->getFieldIndex();
1061 myType = EL_EXPOSED_FIELD;
1062 }
1063 isElement = proto->lookupIsEventIn((Node *)this, field, myType);
1064 if (isElement == -1)
1065 isElement = proto->lookupIsEventOut((Node *)this, field,
1066 EL_EVENT_IN);
1067 if (isElement != -1) {
1068 isName = proto->getEventIn(isElement)->getName(x3d);
1069 stopLoop = true;
1070 }
1071 break;
1072 case EL_EVENT_OUT:
1073 exposedField = ((EventOut *)element)->getExposedField();
1074 if (exposedField) {
1075 field = exposedField->getFieldIndex();
1076 myType = EL_EXPOSED_FIELD;
1077 }
1078 isElement = proto->lookupIsEventOut((Node *)this, field, myType);
1079 if (isElement == -1)
1080 isElement = proto->lookupIsEventOut((Node *)this, field,
1081 EL_EVENT_OUT);
1082 if (isElement != -1) {
1083 isName = proto->getEventOut(isElement)->getName(x3d);
1084 stopLoop = true;
1085 }
1086 break;
1087 case EL_FIELD:
1088 isElement = proto->lookupIsExposedField((Node *)this, i);
1089 if (isElement != -1) {
1090 isName = proto->getExposedField(isElement)->getName(x3d);
1091 stopLoop = true;
1092 }
1093 if ((isName == NULL) || (isName && strlen(isName) == 0)) {
1094 isElement = proto->lookupIsField((Node *)this, i);
1095 if (isElement != -1) {
1096 isName = proto->getField(isElement)->getName(x3d);
1097 stopLoop = true;
1098 }
1099 }
1100 }
1101 if (stopLoop)
1102 break;
1103 }
1104 return isName;
1105 }
1106
1107 int
writeFields(int f,int indent)1108 NodeData::writeFields(int f, int indent)
1109 {
1110 if (!m_proto) return(0);
1111
1112 // delay writing of Script.url
1113 int scriptUrlField = -1;
1114 if (getType() == VRML_SCRIPT)
1115 scriptUrlField = ((NodeScript *)this)->url_Field();
1116
1117 for (int i = 0; i < m_numFields; i++)
1118 if (i != scriptUrlField)
1119 RET_ONERROR( writeField(f, indent, i) )
1120
1121 for (int i = 0; i < m_numEventIns; i++)
1122 RET_ONERROR( writeEventIn(f, indent, i) )
1123
1124 for (int i = 0; i < m_numEventOuts; i++)
1125 RET_ONERROR( writeEventOut(f, indent, i) )
1126
1127 if ((scriptUrlField != -1) && (!isPROTO())) {
1128 RET_ONERROR( mywritestr(f, "\n[\n") )
1129 RET_ONERROR( writeField(f, indent, scriptUrlField) )
1130 RET_ONERROR( mywritestr(f, "\n]\n") )
1131 }
1132
1133 return(0);
1134 }
1135
1136 int
writeXmlFields(int f,int indent,int when,int containerField,bool avoidUse)1137 NodeData::writeXmlFields(int f, int indent, int when, int containerField,
1138 bool avoidUse)
1139 {
1140 if (isDynamicFieldsNode())
1141 TheApp->setDynamicFieldsNode();
1142
1143 if (!m_proto) return(0);
1144
1145 if (isPROTO() || (getType() == DUNE_VRML_CUT) ||
1146 (getType() == DUNE_VRML_SCENE)) {
1147 if (when != XML_PROTO_INSTANCE_FIELD)
1148 return 0;
1149 } else
1150 if (when == XML_PROTO_INSTANCE_FIELD)
1151 return 0;
1152
1153 bool writeIs = false;
1154 if (when == XML_IS) {
1155 for (int i = 0; i < m_numFields; i++)
1156 if (searchIsName(i, EL_FIELD) != NULL)
1157 writeIs = true;
1158 for (int i = 0; i < m_numEventIns; i++)
1159 if (searchIsName(i, EL_EVENT_IN) != NULL)
1160 writeIs = true;
1161 for (int i = 0; i < m_numEventOuts; i++)
1162 if (searchIsName(i, EL_EVENT_OUT) != NULL)
1163 writeIs = true;
1164 }
1165 if (avoidUse)
1166 writeIs = false;
1167 if (writeIs) {
1168 RET_ONERROR( indentf(f, indent) )
1169 RET_ONERROR( mywritestr(f, "<IS>\n") )
1170 TheApp->incSelectionLinenumber();
1171 indent += TheApp->GetIndent();
1172 }
1173
1174 bool isScript = false;
1175 int scriptMetadataField = -1;
1176 int scriptUrlField = -1;
1177 if (getType() == VRML_SCRIPT) {
1178 scriptUrlField = ((NodeScript *)this)->url_Field();
1179 scriptMetadataField = getProto()->metadata_Field();
1180 isScript = true;
1181 }
1182 for (int i = 0; i < m_numFields; i++)
1183 if ((i != scriptUrlField) && (i != scriptMetadataField))
1184 RET_ONERROR( writeXmlField(f, indent, i, when, isScript,
1185 containerField, avoidUse) )
1186
1187 if (!avoidUse) {
1188 for (int i = 0; i < m_numEventIns; i++)
1189 RET_ONERROR( writeXmlEventIn(f, indent, i, when) )
1190
1191 for (int i = 0; i < m_numEventOuts; i++)
1192 RET_ONERROR( writeXmlEventOut(f, indent, i, when) )
1193 }
1194
1195 if (scriptUrlField != -1)
1196 RET_ONERROR( writeXmlField(f, indent, scriptUrlField, when) )
1197
1198 if (when == XML_IN_TAG) {
1199 SocketList::Iterator *j;
1200
1201 for (int i = 0; i < m_numEventOuts; i++)
1202 for (j = m_outputs[i].first(); j != NULL; j = j->next()) {
1203 Node *dest = j->item().getNode();
1204 int field = j->item().getField();
1205 if ((dest->getType() == VRML_SCRIPT) &&
1206 (hasX3domOnOutputChange() || hasX3domOnclick())) {
1207 NodeScript *script = (NodeScript *)dest;
1208 for (int n = 0; n < script->url()->getSize(); n++)
1209 if (isX3domscript(script->url()->getValue(n))) {
1210 RET_ONERROR( mywritestr(f, " ") )
1211 if (hasX3domOnclick())
1212 RET_ONERROR( mywritestr(f, "onClick") )
1213 else
1214 RET_ONERROR( mywritestr(f, "onOutputChange") )
1215 RET_ONERROR( mywritestr(f, "=\'") )
1216 const char *name = script->getProto()->
1217 getEventIn(field)->getName(true);
1218 RET_ONERROR( mywritestr(f, name) )
1219 RET_ONERROR( mywritestr(f, "(event)\' ") )
1220 }
1221 }
1222 }
1223 }
1224
1225 if (writeIs) {
1226 indent -= TheApp->GetIndent();
1227 RET_ONERROR( indentf(f, indent) )
1228 RET_ONERROR( mywritestr(f, "</IS>\n") )
1229 TheApp->incSelectionLinenumber();
1230 }
1231
1232 if (isDynamicFieldsNode())
1233 TheApp->unsetDynamicFieldsNode();
1234
1235 return 0;
1236 }
1237
1238 int
writeField(int f,int indent,int i,bool script)1239 NodeData::writeField(int f, int indent, int i, bool script)
1240 {
1241 if (isDynamicFieldsNode())
1242 TheApp->setDynamicFieldsNode();
1243
1244 if (!m_proto) return(0);
1245 bool x3d = m_scene->isX3d();
1246 const char *oldBase = m_scene->getURL();
1247 const char *newBase = m_scene->getNewURL();
1248 bool tempSave = m_scene->isTempSave();
1249
1250 Field *field = m_proto->getField(i);
1251 if (m_scene->isInvalidElement(field))
1252 return 0;
1253 FieldValue *value = m_fields[i];
1254 const char *name = field->getName(x3d);
1255 bool hasIsName = false;
1256 const char *isName = searchIsName(i, EL_FIELD);
1257 if (isName)
1258 hasIsName = true;
1259 else {
1260 isName = searchIsName(i, EL_EXPOSED_FIELD);
1261 if (isName)
1262 hasIsName = true;
1263 }
1264 if (hasIsName)
1265 RET_ONERROR( writeIs(f, indent, name, isName) )
1266 else if (value) {
1267 if (script || (value->getRefs() &&
1268 (!value->equals(field->getDefault(x3d))))) {
1269 RET_ONERROR( indentf(f, indent) )
1270 RET_ONERROR( mywritestr(f , name) )
1271 RET_ONERROR( mywritestr(f ," ") )
1272 if ((field->getFlags() & FF_URL) && (!TheApp->GetKeepURLs())) {
1273 value = rewriteField(value, oldBase, newBase,
1274 m_scene->getWriteFlags());
1275 RET_ONERROR( mywritef(f, "\n[\n\"") )
1276 RET_ONERROR( value->writeRaw(f, 0) )
1277 RET_ONERROR( mywritef(f, "\"\n]\n") )
1278 if (!tempSave) {
1279 setField(i, value);
1280 FieldUpdate* fieldUpdate=new FieldUpdate((Node*)this, i);
1281 m_scene->UpdateViews(NULL, UPDATE_FIELD,
1282 (Hint *) fieldUpdate);
1283 delete fieldUpdate;
1284 } else {
1285 delete value;
1286 }
1287 } else {
1288 RET_ONERROR( value->write(f, indent) )
1289 }
1290 }
1291 }
1292 if (isDynamicFieldsNode())
1293 TheApp->unsetDynamicFieldsNode();
1294 return(0);
1295 }
1296
1297 int
writeXmlField(int f,int indent,int i,int when,bool script,int containerField,bool avoidUse)1298 NodeData::writeXmlField(int f, int indent, int i, int when, bool script,
1299 int containerField, bool avoidUse)
1300 {
1301 if (!m_proto) return(0);
1302 const char *oldBase = m_scene->getURL();
1303 const char *newBase = m_scene->getNewURL();
1304 bool tempSave = m_scene->isTempSave();
1305 bool x3d = m_scene->isX3d();
1306
1307 Field *field = m_proto->getField(i);
1308 if (m_scene->isInvalidElement(field))
1309 return 0;
1310 bool isNode = (field->getType() == SFNODE) || (field->getType() == MFNODE);
1311 bool isScript = field->getFlags() & FF_IN_SCRIPT;
1312 bool isScriptUrl = field->getFlags() & FF_SCRIPT_URL;
1313 bool inTag = (when == XML_IN_TAG);
1314 FieldValue *value = m_fields[i];
1315 const char *name = field->getName(x3d);
1316 const char *isName = searchIsName(i, EL_FIELD);
1317 if (when == XML_IS) {
1318 if (isName)
1319 RET_ONERROR( writeXmlIs(f, indent, name, isName) )
1320 else
1321 return 0;
1322 } else if (when == XML_PROTO_INSTANCE_FIELD) {
1323 if (isName)
1324 RET_ONERROR( writeXmlIs(f, indent, name, isName) )
1325 else
1326 RET_ONERROR( writeXmlProtoInstanceField(f, indent, name, value) )
1327 } else if (value) {
1328 int size = 1;
1329 MFString *urls = NULL;
1330 if (isScriptUrl) {
1331 urls = ((NodeScript *)this)->url();
1332 size = urls->getSize();
1333 }
1334 if (inTag && isScript)
1335 return 0;
1336 if (inTag && isScriptUrl) {
1337 int count = 0;
1338 for (int j = 0; j < size; j++)
1339 if (!isSortOfEcmascript(urls->getValue(j)))
1340 count++;
1341 if (count == 0)
1342 return 0;
1343 else if (size > 0) {
1344 RET_ONERROR( mywritestr(f ,"url='") )
1345 for (int j = 0; j < size; j++) {
1346 if (!isSortOfEcmascript(urls->getValue(j))) {
1347 if (j > 0)
1348 RET_ONERROR( mywritestr(f, " ") )
1349 RET_ONERROR( mywritestr(f, "\"") )
1350 RET_ONERROR( mywritestr(f, rewriteURL(urls->getValue(j),
1351 oldBase, newBase)) )
1352 RET_ONERROR( mywritestr(f, "\"") )
1353 }
1354 }
1355 RET_ONERROR( mywritestr(f, "'") )
1356 }
1357 } else if (isScriptUrl) {
1358 for (int j = 0; j < size; j++) {
1359 if (isSortOfEcmascript(urls->getValue(j))) {
1360 RET_ONERROR( indentf(f, indent + TheApp->GetIndent()) )
1361 RET_ONERROR( mywritestr(f, "<![CDATA[") )
1362 RET_ONERROR( mywritestr(f, urls->getValue(j)) )
1363 RET_ONERROR( indentf(f, indent + TheApp->GetIndent()) )
1364 RET_ONERROR( mywritestr(f, "\n") )
1365 TheApp->incSelectionLinenumber();
1366 RET_ONERROR( indentf(f, indent + TheApp->GetIndent()) )
1367 RET_ONERROR( mywritestr(f, "]]>\n") )
1368 TheApp->incSelectionLinenumber();
1369 }
1370 }
1371 } else if (isScript) {
1372 int flags = m_scene->getWriteFlags();
1373 const char *isName = searchIsName(i, EL_FIELD);
1374 if ((value->isNullNode()) && (!isName))
1375 flags |= NULL_VALUE;
1376 else if (isNode)
1377 flags |= WITHOUT_VALUE;
1378 if (isName)
1379 flags |= WITHOUT_VALUE;
1380 if (isName) {
1381 return 0;
1382 RET_ONERROR( indentf(f, indent + TheApp->GetIndent()) )
1383 RET_ONERROR( mywritef(f,
1384 "<IS> <connect nodeField=\"%s\" protoField=\"%s\"/> </IS>\n",
1385 name, isName) )
1386 TheApp->incSelectionLinenumber();
1387 } else
1388 RET_ONERROR( field->writeElementPart(f, indent, flags) )
1389 if (isName)
1390 return 0;
1391 if (flags & NULL_VALUE)
1392 if (!(flags & WITHOUT_VALUE)) {
1393 RET_ONERROR( mywritestr(f, " value='NULL'") )
1394 }
1395 int type = field->getType();
1396 bool nodeField = (type == SFNODE) || (type == MFNODE);
1397 if ((flags & NULL_VALUE) && (!(flags & WITHOUT_VALUE))) {
1398 RET_ONERROR( mywritestr(f, "></field>\n") )
1399 TheApp->incSelectionLinenumber();
1400 } else if (nodeField ) {
1401 RET_ONERROR( mywritestr(f, ">\n") )
1402 TheApp->incSelectionLinenumber();
1403 RET_ONERROR( value->writeXml(f, indent + TheApp->GetIndent()) )
1404 RET_ONERROR( indentf(f, indent + TheApp->GetIndent()) )
1405 RET_ONERROR( mywritestr(f, "</field>\n") )
1406 TheApp->incSelectionLinenumber();
1407 } else {
1408 RET_ONERROR( mywritestr(f, " value=") )
1409 RET_ONERROR( value->writeXml(f, 0) )
1410 RET_ONERROR( mywritestr(f, " ></field>\n") )
1411 TheApp->incSelectionLinenumber();
1412 }
1413 } else if (!inTag && !isNode)
1414 return 0;
1415 else if (inTag && isNode)
1416 return 0;
1417 else if (!value->equals(field->getDefault(x3d))) {
1418 if (inTag) {
1419 RET_ONERROR( mywritestr(f , name) )
1420 RET_ONERROR( mywritestr(f ,"=") )
1421 }
1422 if ((field->getFlags() & FF_URL) && (!TheApp->GetKeepURLs())) {
1423 value = rewriteField(value, oldBase, newBase,
1424 m_scene->getWriteFlags());
1425 RET_ONERROR( value->writeXml(f, indent) )
1426 if (!tempSave) {
1427 setField(i, value);
1428 FieldUpdate* fieldUpdate=new FieldUpdate((Node*)this, i);
1429 m_scene->UpdateViews(NULL, UPDATE_FIELD,
1430 (Hint *) fieldUpdate);
1431 delete fieldUpdate;
1432 } else {
1433 delete value;
1434 }
1435 } else {
1436 RET_ONERROR( value->writeXml(f, indent, containerField,
1437 avoidUse) )
1438 }
1439 if (inTag) {
1440 RET_ONERROR( mywritestr(f ," ") )
1441 }
1442 }
1443 }
1444 return(0);
1445 }
1446
1447 int
writeEventIn(int f,int indent,int i,bool eventName)1448 NodeData::writeEventIn(int f, int indent, int i, bool eventName)
1449 {
1450 if (!m_proto) return(0);
1451
1452 bool x3d = m_scene->isX3dv();
1453
1454 EventIn *eventIn = m_proto->getEventIn(i);
1455 const char *name = eventIn->getName(x3d);
1456 const char *isName = searchIsName(i, EL_EVENT_IN);
1457 if (isName)
1458 RET_ONERROR( writeIs(f, indent, name, isName) )
1459 else if (eventName) {
1460 RET_ONERROR( mywritestr(f, name) )
1461 RET_ONERROR( mywritestr(f, "\n") )
1462 TheApp->incSelectionLinenumber();
1463 }
1464 return(0);
1465 }
1466
1467 int
writeXmlEventIn(int f,int indent,int i,int when,bool eventName)1468 NodeData::writeXmlEventIn(int f, int indent, int i, int when, bool eventName)
1469 {
1470 if (!m_proto) return(0);
1471
1472 bool x3d = m_scene->isX3dv();
1473
1474 EventIn *eventIn = m_proto->getEventIn(i);
1475 bool isScript = eventIn->getFlags() & FF_IN_SCRIPT;
1476 bool inTag = (when == XML_IN_TAG);
1477 const char *name = eventIn->getName(x3d);
1478 if (when == XML_IS) {
1479 const char *isName = searchIsName(i, EL_EVENT_IN);
1480 if (isName)
1481 RET_ONERROR( writeXmlIs(f, indent, name, isName) )
1482 } else if (inTag && isScript) {
1483 return 0;
1484 } else if (isScript) {
1485 int flags = m_scene->getWriteFlags();
1486 RET_ONERROR( eventIn->write(f, indent, flags) )
1487 TheApp->incSelectionLinenumber();
1488 } else if (eventName) {
1489 RET_ONERROR( mywritestr(f, name) )
1490 RET_ONERROR( mywritestr(f, "\n") )
1491 TheApp->incSelectionLinenumber();
1492 }
1493 return(0);
1494 }
1495
1496
1497 int
writeEventInStr(int f)1498 NodeData::writeEventInStr(int f)
1499 {
1500 if (m_scene->isX3d())
1501 RET_ONERROR( mywritestr(f, "inputOnly") )
1502 else
1503 RET_ONERROR( mywritestr(f, "eventIn") )
1504 return 0;
1505 }
1506
1507 int
writeEventOutStr(int f)1508 NodeData::writeEventOutStr(int f)
1509 {
1510 if (m_scene->isX3d())
1511 RET_ONERROR( mywritestr(f, "outputOnly") )
1512 else
1513 RET_ONERROR( mywritestr(f, "eventOut") )
1514 return 0;
1515 }
1516
1517 int
writeFieldStr(int f)1518 NodeData::writeFieldStr(int f)
1519 {
1520 if (m_scene->isX3d())
1521 RET_ONERROR( mywritestr(f, "initializeOnly") )
1522 else
1523 RET_ONERROR( mywritestr(f, "field") )
1524 return 0;
1525 }
1526
1527 int
writeExposedFieldStr(int f)1528 NodeData::writeExposedFieldStr(int f)
1529 {
1530 if (m_scene->isX3d())
1531 RET_ONERROR( mywritestr(f, "inputOutput") )
1532 else
1533 RET_ONERROR( mywritestr(f, "exposedField") )
1534 return 0;
1535 }
1536
1537
1538 int
writeEventOut(int f,int indent,int i,bool eventName)1539 NodeData::writeEventOut(int f, int indent, int i, bool eventName)
1540 {
1541 if (!m_proto) return(0);
1542
1543 bool x3d = m_scene->isX3dv();
1544
1545 EventOut *eventOut = m_proto->getEventOut(i);
1546 const char *name = eventOut->getName(x3d);
1547 const char *isName = searchIsName(i, EL_EVENT_OUT);
1548 if (isName)
1549 RET_ONERROR( writeIs(f, indent, name, isName) )
1550 else if (eventName) {
1551 RET_ONERROR( mywritestr(f, name) )
1552 RET_ONERROR( mywritestr(f, "\n") )
1553 TheApp->incSelectionLinenumber();
1554 }
1555 return(0);
1556 }
1557
1558 int
writeXmlEventOut(int f,int indent,int i,int when,bool eventName)1559 NodeData::writeXmlEventOut(int f, int indent, int i, int when, bool eventName)
1560 {
1561 if (!m_proto) return(0);
1562
1563 bool x3d = m_scene->isX3dv();
1564
1565 EventOut *eventOut = m_proto->getEventOut(i);
1566 bool isScript = eventOut->getFlags() & FF_IN_SCRIPT;
1567 bool inTag = (when == XML_IN_TAG);
1568 const char *name = eventOut->getName(x3d);
1569 if (when == XML_IS) {
1570 const char *isName = searchIsName(i, EL_EVENT_OUT);
1571 if (isName)
1572 RET_ONERROR( writeXmlIs(f, indent, name, isName) )
1573 } else if (inTag && isScript) {
1574 return 0;
1575 } else if (isScript) {
1576 int flags = m_scene->getWriteFlags();
1577 RET_ONERROR( eventOut->write(f, indent, flags) )
1578 TheApp->incSelectionLinenumber();
1579 } else if (eventName) {
1580 RET_ONERROR( mywritestr(f, name) )
1581 RET_ONERROR( mywritestr(f, "\n") )
1582 TheApp->incSelectionLinenumber();
1583 }
1584 return(0);
1585 }
1586
1587 int
writeRoutes(int f,int indent) const1588 NodeData::writeRoutes(int f, int indent) const
1589 {
1590 if (!m_proto) return(0);
1591
1592 bool x3d = m_scene->isX3d();
1593
1594 SocketList::Iterator *j;
1595
1596 for (int i = 0; i < m_numEventIns; i++) {
1597 for (j = m_inputs[i].first(); j != NULL; j = j->next()) {
1598 if (j->item().getNode()->getFlag(NODE_FLAG_TOUCHED)) {
1599 Node *src = j->item().getNode();
1600 int field = j->item().getField();
1601 if ((m_scene->getWriteFlags() & X3DOM) &&
1602 (j->item().getNode()->getType() == VRML_SCRIPT)) {
1603 NodeScript *script = (NodeScript *)j->item().getNode();
1604 bool flag = false;
1605 for (int i = 0; i < script->url()->getSize(); i++)
1606 if (isX3domscript(script->url()->getValue(i)))
1607 flag = true;
1608 if (flag)
1609 continue;
1610
1611 }
1612 if (m_scene->isPureVRML() &&
1613 (matchNodeClass(PARAMETRIC_GEOMETRY_NODE) ||
1614 src->matchNodeClass(PARAMETRIC_GEOMETRY_NODE)))
1615 continue;
1616 MyString routeString = m_scene->createRouteString(
1617 src->getName(),
1618 src->getProto()->getEventOut(field)->getName(x3d),
1619 m_name, getProto()->getEventIn(i)->getName(x3d));
1620 m_scene->addRouteString(routeString);
1621 }
1622 }
1623 }
1624
1625 for (int i = 0; i < m_numEventOuts; i++) {
1626 for (j = m_outputs[i].first(); j != NULL; j = j->next()) {
1627 if (j->item().getNode()->getFlag(NODE_FLAG_TOUCHED)) {
1628 Node *dst = j->item().getNode();
1629 int field = j->item().getField();
1630 if (m_scene->isPureVRML() &&
1631 (matchNodeClass(PARAMETRIC_GEOMETRY_NODE) ||
1632 dst->matchNodeClass(PARAMETRIC_GEOMETRY_NODE)))
1633 continue;
1634 if (getProto()->getEventOut(i)->getName(x3d).length() == 0)
1635 continue;
1636 MyString routestring = m_scene->createRouteString(m_name,
1637 getProto()->getEventOut(i)->getName(x3d),
1638 dst->getName(),
1639 dst->getProto()->getEventIn(field)->getName(x3d));
1640 m_scene->addRouteString(routestring);
1641 }
1642 }
1643 }
1644
1645 #ifndef HAVE_ROUTE_AT_END
1646 if (indent==0)
1647 RET_ONERROR( m_scene->writeRouteStrings(f, indent, true) )
1648 #endif
1649 return 0;
1650 }
1651
1652 void
removeRoutes(void)1653 NodeData::removeRoutes(void)
1654 {
1655 if (!m_proto) return;
1656
1657 for (int i = 0; i < m_numEventIns; i++) {
1658 while (m_inputs[i].size() > 0) {
1659 SocketList::Iterator *j = m_inputs[i].first();
1660 Node *src = j->item().getNode();
1661 int field = j->item().getField();
1662 m_scene->deleteRoute(src, field, (Node *)this, i);
1663 }
1664 }
1665
1666 for (int i = 0; i < m_numEventOuts; i++) {
1667 while (m_outputs[i].size() > 0) {
1668 SocketList::Iterator *j = m_outputs[i].first();
1669 Node *dst = j->item().getNode();
1670 int field = j->item().getField();
1671 m_scene->deleteRoute((Node *)this, i, dst, field);
1672 }
1673 }
1674 }
1675
1676 int
writeCDataFunctionFields(int filedes,int languageFlag,bool forward,bool cont)1677 Node::writeCDataFunctionFields(int filedes, int languageFlag,
1678 bool forward, bool cont)
1679 {
1680 for (int i = 0; i < m_numFields; i++) {
1681 Field *field = m_proto->getField(i);
1682 FieldValue *value = m_fields[i];
1683
1684 if (field->getType() == SFNODE) {
1685 if (value) {
1686 Node *node = ((SFNode *)value)->getValue();
1687 if (node && (node != this)) { // avoid simple cyclic scenegraph
1688 RET_ONERROR( node->writeCDataFunction(filedes,
1689 languageFlag,
1690 forward, cont) )
1691 }
1692 }
1693 } else if (field->getType() == MFNODE) {
1694 if (value) {
1695 MFNode *nodes = (MFNode *)value;
1696 for (int i = 0; i < nodes->getSize(); i++) {
1697 Node *node = nodes->getValue(i);
1698 if (node && (node != this)) { //avoid simple cyclic scenegraph
1699 RET_ONERROR( node->writeCDataFunction(filedes,
1700 languageFlag,
1701 forward, cont) )
1702 }
1703 }
1704 }
1705 }
1706 }
1707 if ((!cont) && (!isConvertedInCurveAnimaton()))
1708 RET_ONERROR( mywritestr(filedes , " }\n") )
1709 return 0;
1710 }
1711
1712 int
writeCGetParent(int filedes,int languageFlag)1713 Node::writeCGetParent(int filedes, int languageFlag)
1714 {
1715 if (getType() == DUNE_CURVE_ANIMATION)
1716 return 0;
1717
1718 RET_ONERROR( mywritestr(filedes, " if (") )
1719 RET_ONERROR( writeCVariable(filedes, languageFlag) )
1720 if (languageFlag & JAVA_SOURCE)
1721 RET_ONERROR( mywritestr(filedes, " != null") )
1722 RET_ONERROR( mywritestr(filedes, ")\n") )
1723
1724 RET_ONERROR( mywritestr(filedes, " ") )
1725 RET_ONERROR( writeCVariable(filedes, languageFlag) )
1726 RET_ONERROR( mywritestr(filedes, ".m_parent = ") )
1727
1728 if (hasParent()) {
1729 RET_ONERROR( getParent()->writeCVariable(filedes, languageFlag) )
1730 } else {
1731 if (languageFlag & JAVA_SOURCE)
1732 RET_ONERROR( mywritestr(filedes, "null") )
1733 else
1734 RET_ONERROR( mywritestr(filedes, "NULL") )
1735 }
1736 RET_ONERROR( mywritestr(filedes, ";\n") )
1737 return 0;
1738 }
1739
1740 int
writeCDataFunction(int filedes,int languageFlag,bool forward,bool cont)1741 Node::writeCDataFunction(int filedes, int languageFlag, bool forward, bool cont)
1742 {
1743 if (getWritten())
1744 return 0;
1745
1746 if (m_convertedNodes.size() > 0) {
1747 for (long i = 0; i < m_convertedNodes.size(); i++)
1748 RET_ONERROR( m_convertedNodes[i]->writeCDataFunction(filedes,
1749 languageFlag,
1750 forward,
1751 cont) )
1752 setWritten(true);
1753 return 0;
1754 }
1755
1756 if (!isCWriteable())
1757 return 0;
1758
1759 if (forward)
1760 writeCDataFunctionFields(filedes, languageFlag, forward, cont);
1761
1762 if (m_numberCDataFunctions >= 0) {
1763 if (!cont){
1764 RET_ONERROR( mywritestr(filedes , " ") )
1765 if ((languageFlag & MANY_JAVA_CLASSES) &&
1766 !isConvertedInCurveAnimaton()) {
1767 RET_ONERROR( mywritestr(filedes , "static ") )
1768 RET_ONERROR( mywritef(filedes , "void data%sFunction%d() {\n",
1769 TheApp->getCPrefix(),
1770 m_scene->getNumDataFunctions()) )
1771 }
1772 }
1773 m_scene->increaseNumDataFunctions();
1774 if (languageFlag & MANY_JAVA_CLASSES) {
1775 if (!isPROTO()) {
1776 RET_ONERROR( mywritestr(filedes, " ") )
1777 if (languageFlag & MANY_JAVA_CLASSES)
1778 RET_ONERROR( mywritestr(filedes, " ") )
1779 RET_ONERROR( writeCVariable(filedes, languageFlag) )
1780 RET_ONERROR( mywritestr(filedes, " = new ") )
1781 RET_ONERROR( mywritestr(filedes, getClassName()) )
1782 RET_ONERROR( mywritestr(filedes, "();\n") )
1783 }
1784 }
1785
1786 if (languageFlag & JAVA_SOURCE) {
1787 if (languageFlag & MANY_JAVA_CLASSES)
1788 RET_ONERROR( mywritestr(filedes, " ") )
1789 }
1790 RET_ONERROR( mywritestr(filedes, " ") )
1791 if (languageFlag & C_SOURCE)
1792 RET_ONERROR( mywritestr(filedes, "self->") )
1793 RET_ONERROR( writeCVariable(filedes, languageFlag) )
1794 RET_ONERROR( mywritestr(filedes, ".m_parent = ") )
1795
1796 if (hasParent()) {
1797 if (languageFlag & (C_SOURCE | CC_SOURCE))
1798 RET_ONERROR( mywritestr(filedes, "&") )
1799 if (languageFlag & C_SOURCE)
1800 RET_ONERROR( mywritestr(filedes, "self->") )
1801 RET_ONERROR( getParent()->writeCVariable(filedes, languageFlag) )
1802 } else {
1803 if (languageFlag & JAVA_SOURCE)
1804 RET_ONERROR( mywritestr(filedes, "null") )
1805 else
1806 RET_ONERROR( mywritestr(filedes, "NULL") )
1807 }
1808 RET_ONERROR( mywritestr(filedes, ";\n") )
1809
1810 if ( m_numberCDataFunctions > 0) {
1811 if (languageFlag & MANY_JAVA_CLASSES)
1812 RET_ONERROR( mywritef(filedes ,
1813 " new %s%sDataClass0();\n",
1814 TheApp->getPrefix(), getVariableName()) )
1815 else
1816 RET_ONERROR( mywritef(filedes ,
1817 " %s%sDataFunction0();\n",
1818 TheApp->getPrefix(), getVariableName()) )
1819 }
1820 for (int i = 1; i < m_numberCDataFunctions; i++)
1821 if (languageFlag & MANY_JAVA_CLASSES)
1822 RET_ONERROR( mywritef(filedes ,
1823 " new %s%sDataClass%d();\n",
1824 TheApp->getPrefix(), getVariableName(),
1825 i) )
1826 else
1827 RET_ONERROR( mywritef(filedes ,
1828 " %s%sDataFunction%d();\n",
1829 TheApp->getPrefix(), getVariableName(),
1830 i) )
1831 }
1832
1833 if (!forward)
1834 writeCDataFunctionFields(filedes, languageFlag, forward, cont);
1835
1836 if (hasProtoNodes()) {
1837 Node *protoRoot = ((NodePROTO *)this)->getProtoRoot();
1838 RET_ONERROR( protoRoot->writeCDataFunction(filedes, languageFlag,
1839 forward, cont))
1840
1841 NodePROTO *nodeProto = (NodePROTO *)this;
1842 for (int i = 1; i < nodeProto->getNumProtoNodes(); i++) {
1843 RET_ONERROR( nodeProto->getProtoNode(i)->writeCDataFunction(
1844 filedes, languageFlag, cont) )
1845 }
1846 }
1847
1848 setWritten(true);
1849 return 0;
1850 }
1851
1852 int
writeC(int f,int languageFlag)1853 Node::writeC(int f, int languageFlag)
1854 {
1855 if (m_convertedNodes.size() > 0) {
1856 for (long i = 0; i < m_convertedNodes.size(); i++)
1857 RET_ONERROR( m_convertedNodes[i]->writeC(f, languageFlag) )
1858 return 0;
1859 }
1860
1861 if (getType() == VRML_COMMENT) {
1862 return 0;
1863 }
1864 if (m_proto->isMismatchingProto()) {
1865 return 0;
1866 }
1867
1868 if (isMeshBasedNode() && (!getIndexedFaceSet())) {
1869 RET_ONERROR( mywritef(f, " ") )
1870 if (languageFlag & C_SOURCE)
1871 RET_ONERROR( mywritef(f, "%sSetGlName(&self->%s, %d);\n",
1872 TheApp->getCPrefix(), getVariableName(),
1873 m_scene->getGlName()) )
1874 else {
1875 if (languageFlag & JAVA_SOURCE) {
1876 MyString className = "";
1877 className += TheApp->getCPrefix();
1878 className += getVariableName();
1879 RET_ONERROR( mywritef(f, "%s.", (const char *)className) )
1880 }
1881 RET_ONERROR( mywritef(f, "%s.setGlName(%d);\n", getVariableName(),
1882 m_scene->getGlName()) )
1883 }
1884 CGlNameData data;
1885 data.glName = m_scene->getGlName();
1886 data.node = this;
1887 data.nodeName = "";
1888 data.nodeName += getVariableName();
1889 m_scene->m_glNameData.append(data);
1890 m_scene->increaseGlName();
1891 }
1892 if (getType() == VRML_TRANSFORM) {
1893 int numRouteSources = 0;
1894 for (int i = 0; i < m_numEventIns; i++)
1895 for (SocketList::Iterator *j = m_inputs[i].first(); j != NULL;
1896 j = j->next())
1897 if (j->item().getNode()->getProto()->isCRouteSource()) {
1898 numRouteSources++;
1899 }
1900 RET_ONERROR( mywritestr(f, " ") )
1901 if (languageFlag & JAVA_SOURCE)
1902 RET_ONERROR( mywritestr(f, " ") )
1903 if (languageFlag & C_SOURCE)
1904 RET_ONERROR( mywritestr(f, "self->") )
1905 MyString className = "";
1906 if (languageFlag & JAVA_SOURCE) {
1907 className += TheApp->getCPrefix();
1908 className += getVariableName();
1909 RET_ONERROR( mywritef(f, "%s.", (const char *)className) )
1910 }
1911 RET_ONERROR( mywritef(f, "%s.route_sources = ", getVariableName()) )
1912 if (numRouteSources == 0) {
1913 if (languageFlag & JAVA_SOURCE)
1914 RET_ONERROR( mywritestr(f, " null;\n") )
1915 else
1916 RET_ONERROR( mywritestr(f, " NULL;\n") )
1917 } else {
1918 if (languageFlag & C_SOURCE)
1919 RET_ONERROR( mywritef(f,
1920 "(%sNode **)malloc(%d * sizeof(%sNode *));\n",
1921 TheApp->getCPrefix(), numRouteSources,
1922 TheApp->getCPrefix()) )
1923 else if (languageFlag & CC_SOURCE)
1924 RET_ONERROR( mywritef(f, "new %sNode*[%d];\n",
1925 TheApp->getCPrefix(), numRouteSources) )
1926 else if (languageFlag & JAVA_SOURCE)
1927 RET_ONERROR( mywritef(f, "new %sNode[%d];\n",
1928 TheApp->getCPrefix(), numRouteSources) )
1929 }
1930 numRouteSources = 0;
1931 for (int i = 0; i < m_numEventIns; i++)
1932 for (SocketList::Iterator *j = m_inputs[i].first(); j != NULL;
1933 j = j->next())
1934 if (j->item().getNode()->getProto()->isCRouteSource()) {
1935 RET_ONERROR( mywritestr(f, " ") )
1936 if (languageFlag & JAVA_SOURCE)
1937 RET_ONERROR( mywritef(f, " %s.",
1938 (const char *)className) )
1939 if (languageFlag & C_SOURCE)
1940 RET_ONERROR( mywritestr(f, "self->") )
1941 RET_ONERROR( mywritef(f, "%s.route_sources[%d] = ",
1942 getVariableName(), numRouteSources) )
1943 if (languageFlag & (C_SOURCE | CC_SOURCE))
1944 RET_ONERROR( mywritestr(f, "&") )
1945 if (languageFlag & JAVA_SOURCE)
1946 RET_ONERROR( mywritef(f, "%s%s.", TheApp->getCPrefix(),
1947 j->item().getNode()->getVariableName()) )
1948
1949 if (languageFlag & C_SOURCE)
1950 RET_ONERROR( mywritestr(f, "self->") )
1951 RET_ONERROR( mywritestr(f,
1952 j->item().getNode()->getVariableName()) )
1953 RET_ONERROR( mywritestr(f, ";\n") )
1954 numRouteSources++;
1955 }
1956
1957 RET_ONERROR( mywritef(f, " ") )
1958 if (languageFlag & C_SOURCE)
1959 RET_ONERROR( mywritestr(f, "self->") )
1960 if (languageFlag & JAVA_SOURCE) {
1961 MyString className = "";
1962 className += TheApp->getCPrefix();
1963 className += getVariableName();
1964 RET_ONERROR( mywritef(f, " %s.", (const char *)className) )
1965 }
1966 RET_ONERROR( mywritef(f, "%s.num_route_source = %d;\n",
1967 getVariableName(), numRouteSources) )
1968
1969 }
1970
1971 // allows several nodetypes to output a warning via inheritance
1972 writeCWarning();
1973
1974 bool writeInside = true;
1975 if (languageFlag & MANY_JAVA_CLASSES)
1976 if (writeJavaOutsideClass(languageFlag))
1977 writeInside = false;
1978
1979 if (languageFlag & C_SOURCE) {
1980 RET_ONERROR( mywritestr(f, " ") )
1981 RET_ONERROR( mywritestr(f, getClassName()) )
1982 RET_ONERROR( mywritestr(f, "Init(&") )
1983 RET_ONERROR( writeCVariable(f, languageFlag) )
1984 RET_ONERROR( mywritestr(f, ");\n") )
1985 }
1986
1987
1988 if (languageFlag & (C_SOURCE | CC_SOURCE)) {
1989 RET_ONERROR( mywritestr(f, " ") )
1990 if (languageFlag & C_SOURCE)
1991 RET_ONERROR( mywritestr(f, "self->") )
1992 RET_ONERROR( mywritestr(f, getVariableName()) )
1993 RET_ONERROR( mywritef(f, ".m_parent = (%sNode *)", TheApp->getCPrefix())
1994 )
1995 if (getParent() == NULL)
1996 RET_ONERROR( mywritestr(f, "NULL") )
1997 else {
1998 RET_ONERROR( mywritestr(f, "&") )
1999 if (languageFlag & C_SOURCE)
2000 RET_ONERROR( mywritestr(f, "self->") )
2001 RET_ONERROR( mywritestr(f, getParent()->getVariableName()) )
2002 }
2003 RET_ONERROR( mywritestr(f, ";\n") )
2004 }
2005 if (languageFlag & (C_SOURCE | CC_SOURCE)) {
2006 for (int i = 0; i < m_numFields; i++)
2007 RET_ONERROR( writeCElement(f, EL_FIELD, i, languageFlag, true) )
2008 for (int i = 0; i < m_numFields; i++)
2009 RET_ONERROR( writeCElement(f, EL_FIELD, i, languageFlag, false) )
2010 for (int i = 0; i < m_numEventIns; i++)
2011 RET_ONERROR( writeCElement(f, EL_EVENT_IN, i, languageFlag, true) )
2012 for (int i = 0; i < m_numEventIns; i++)
2013 RET_ONERROR( writeCElement(f, EL_EVENT_IN, i, languageFlag, false) )
2014 for (int i = 0; i < m_numEventOuts; i++)
2015 RET_ONERROR( writeCElement(f, EL_EVENT_OUT, i, languageFlag, true) )
2016 for (int i = 0; i < m_numEventOuts; i++)
2017 RET_ONERROR( writeCElement(f, EL_EVENT_OUT, i, languageFlag, false)
2018 )
2019 }
2020
2021 if (writeInside) {
2022 if (hasProtoNodes()) {
2023 if (languageFlag & JAVA_SOURCE) {
2024 RET_ONERROR( mywritestr(f, " ") )
2025 if (languageFlag & MANY_JAVA_CLASSES)
2026 RET_ONERROR( mywritestr(f, " ") )
2027 }
2028 Node *protoRoot = ((NodePROTO *)this)->getProtoRoot();
2029 RET_ONERROR( protoRoot->writeC(f, languageFlag) )
2030
2031 RET_ONERROR( mywritestr(f, " ") )
2032 RET_ONERROR( writeCVariable(f, languageFlag) )
2033 RET_ONERROR( mywritestr(f, ".m_protoRoot = ") )
2034 if (languageFlag & (C_SOURCE | CC_SOURCE))
2035 RET_ONERROR( mywritestr(f, "&") )
2036 RET_ONERROR( protoRoot->writeCVariable(f, languageFlag) )
2037 RET_ONERROR( mywritestr(f, ";\n") )
2038
2039 NodePROTO *nodeProto = (NodePROTO *)this;
2040 for (int i = 1; i < nodeProto->getNumProtoNodes(); i++)
2041 RET_ONERROR(nodeProto->getProtoNode(i)->writeC(f,
2042 languageFlag))
2043 }
2044 }
2045
2046 if (languageFlag & C_SOURCE)
2047 if (this == m_scene->getRoot())
2048 RET_ONERROR( mywritestr(f, " {\n") )
2049
2050 if (languageFlag & C_SOURCE) {
2051 RET_ONERROR( mywritestr(f, " self->") )
2052 RET_ONERROR( mywritestr(f, getVariableName()) )
2053 RET_ONERROR( mywritestr(f, ".") )
2054 RET_ONERROR( mywritestr(f, "m_") )
2055 RET_ONERROR( mywritestr(f, "type = ") )
2056 if (hasProtoNodes())
2057 RET_ONERROR( mywritef(f, "%d", m_scene->getProtoType(m_proto)) )
2058 else
2059 RET_ONERROR( mywritef(f, "%d", getType()) )
2060 RET_ONERROR( mywritestr(f, ";\n") )
2061
2062 RET_ONERROR( mywritestr(f, " self->") )
2063 RET_ONERROR( mywritestr(f, getVariableName()) )
2064 RET_ONERROR( mywritestr(f, ".") )
2065 RET_ONERROR( mywritestr(f, "m_") )
2066 RET_ONERROR( mywritestr(f, "data = NULL") )
2067 RET_ONERROR( mywritestr(f, ";\n") )
2068 }
2069
2070 return 0;
2071 }
2072
2073 int
writeCDataAsFunctions(int f,int languageFlag,bool cont)2074 Node::writeCDataAsFunctions(int f, int languageFlag, bool cont)
2075 {
2076 if (m_convertedNodes.size() > 0) {
2077 for (long i = 0; i < m_convertedNodes.size(); i++)
2078 RET_ONERROR( m_convertedNodes[i]->writeCDataAsFunctions(f,
2079 languageFlag)
2080 )
2081 return 0;
2082 }
2083
2084 if (getType() == VRML_COMMENT)
2085 return 0;
2086 if (m_proto->isMismatchingProto())
2087 return 0;
2088
2089 // do not write multiple declarations for USE'd nodes
2090 if (getFlag(NODE_FLAG_TOUCHED))
2091 return 0;
2092 setFlag(NODE_FLAG_TOUCHED);
2093
2094 if (languageFlag & (C_SOURCE | CC_SOURCE))
2095 return 0;
2096
2097 m_numberCDataFunctions = 0;
2098
2099 for (int i = 0; i < m_numFields; i++)
2100 RET_ONERROR( writeCElementFunction(f, EL_FIELD, i, languageFlag, true,
2101 cont) )
2102 for (int i = 0; i < m_numFields; i++)
2103 RET_ONERROR( writeCElementFunction(f, EL_FIELD, i, languageFlag, false,
2104 cont) )
2105 for (int i = 0; i < m_numEventIns; i++)
2106 RET_ONERROR( writeCElementFunction(f, EL_EVENT_IN, i, languageFlag,
2107 true, cont))
2108 for (int i = 0; i < m_numEventIns; i++)
2109 RET_ONERROR( writeCElementFunction(f, EL_EVENT_IN, i, languageFlag,
2110 false, cont))
2111 for (int i = 0; i < m_numEventOuts; i++)
2112 RET_ONERROR( writeCElementFunction(f, EL_EVENT_OUT, i, languageFlag,
2113 true, cont))
2114 for (int i = 0; i < m_numEventOuts; i++)
2115 RET_ONERROR( writeCElementFunction(f, EL_EVENT_OUT, i, languageFlag,
2116 false, cont))
2117
2118 if (hasProtoNodes()) {
2119 Node *protoRoot = ((NodePROTO *)this)->getProtoRoot();
2120 RET_ONERROR( protoRoot->writeCDataAsFunctions(f, languageFlag) )
2121
2122 NodePROTO *nodeProto = (NodePROTO *)this;
2123 for (int i = 1; i < nodeProto->getNumProtoNodes(); i++)
2124 RET_ONERROR( nodeProto->getProtoNode(i)->writeCDataAsFunctions(
2125 f, languageFlag, cont) )
2126 }
2127 return 0;
2128 }
2129
2130 int
writeCElementFunction(int f,int elementType,int i,int languageFlag,bool nodeFlag,bool cont)2131 Node::writeCElementFunction(int f, int elementType, int i, int languageFlag,
2132 bool nodeFlag, bool cont)
2133 {
2134 if (m_convertedNodes.size() > 0) {
2135 for (long j = 0; j < m_convertedNodes.size(); j++)
2136 RET_ONERROR( m_convertedNodes[j]->writeCElementFunction(f,
2137 elementType, i, languageFlag, nodeFlag, cont) )
2138 return 0;
2139 }
2140
2141 Element *element = m_proto->getElement(elementType, i);
2142 int type = element->getType();
2143
2144 if (m_scene->isInvalidElement(element))
2145 return 0;
2146
2147 if (nodeFlag)
2148 if ((type != SFNODE) && (type != MFNODE))
2149 return 0;
2150
2151 FieldValue *value = NULL;
2152 switch(elementType) {
2153 case EL_FIELD:
2154 value = m_fields[i];
2155 break;
2156 case EL_EVENT_IN:
2157 if (m_proto->getEventIn(i)->getExposedField() != NULL)
2158 return 0;
2159 value = typeDefaultValue(type);
2160 break;
2161 case EL_EVENT_OUT:
2162 if (m_proto->getEventOut(i)->getExposedField() != NULL)
2163 return 0;
2164 value = typeDefaultValue(type);
2165 break;
2166 default:
2167 assert(0);
2168 }
2169
2170 if (value->writeType(languageFlag)) {
2171 if ((!cont) && languageFlag & MANY_JAVA_CLASSES) {
2172 RET_ONERROR( mywritef(f, " class %s%sDataClass%d {\n",
2173 TheApp->getPrefix(), getVariableName(),
2174 m_numberCDataFunctions,
2175 (const char*)getClassName()) )
2176 RET_ONERROR( mywritef(f, " public %s%sDataClass%d() {\n",
2177 TheApp->getPrefix(), getVariableName(),
2178 m_numberCDataFunctions) )
2179 } else
2180 RET_ONERROR( mywritef(f, " void %sDataFunction%d() {\n",
2181 getVariableName(), m_numberCDataFunctions,
2182 (const char*)getClassName()) )
2183 m_numberCDataFunctions++;
2184 RET_ONERROR( writeCElement(f, elementType, i, languageFlag, nodeFlag) )
2185 if (languageFlag & MANY_JAVA_CLASSES)
2186 RET_ONERROR( mywritestr(f, " }\n") )
2187 RET_ONERROR( mywritestr(f, " }\n") )
2188 } else if (!nodeFlag) {
2189 // write long array into a series of functions to fight against the
2190 // java "code too long" (64 KB) problem
2191 MFieldValue *mvalue = (MFieldValue *)value;
2192 int javaCodeToLongLimit = 1 << 16;
2193 int javaSizeOfLine = 8;
2194 int maxNumberElements = TheApp->GetWrittenElementsPerJavaArray();
2195 if (maxNumberElements == -1)
2196 maxNumberElements = javaCodeToLongLimit / mvalue->getStride() /
2197 javaSizeOfLine / 4;
2198 int numberFunctions = mvalue->getSFSize() / maxNumberElements + 1;
2199 int offset = 0;
2200 for (int i = 0; i < numberFunctions; i++) {
2201 if ((!cont) && languageFlag & MANY_JAVA_CLASSES) {
2202 RET_ONERROR( mywritef(f, " class %s%sDataClass%d {\n",
2203 TheApp->getPrefix(), getVariableName(),
2204 m_numberCDataFunctions,
2205 (const char*)getClassName()) )
2206 RET_ONERROR( mywritef(f, " public %s%sDataClass%d() {\n",
2207 TheApp->getPrefix(), getVariableName(),
2208 m_numberCDataFunctions) )
2209 } else
2210 RET_ONERROR( mywritef(f, " void %sDataFunction%d() {\n",
2211 getVariableName(),
2212 m_numberCDataFunctions) )
2213 m_numberCDataFunctions++;
2214 const char *elementName = element->getName(true);
2215
2216 RET_ONERROR( mywritestr(f, " ") )
2217 if (languageFlag & MANY_JAVA_CLASSES)
2218 RET_ONERROR( mywritestr(f, " ") )
2219 RET_ONERROR( mywritestr(f, getClassName()) )
2220 RET_ONERROR( mywritestr(f, " v = ") )
2221 if (languageFlag & MANY_JAVA_CLASSES) {
2222 if (getIndexedFaceSet())
2223 RET_ONERROR(getIndexedFaceSet()->
2224 writeCVariable(f, languageFlag) )
2225 else
2226 RET_ONERROR( writeCVariable(f, languageFlag) )
2227 } else
2228 RET_ONERROR( writeCVariable(f, languageFlag) )
2229 RET_ONERROR( mywritestr(f, ";\n") )
2230
2231 RET_ONERROR( mvalue->writeJavaLongArray(f, languageFlag,
2232 elementName, offset, maxNumberElements,
2233 TheApp->isWonderlandModuleExport() &&
2234 (element->getFlags() & FF_WONDERLAND_ART), m_scene->getURL()) )
2235 if (languageFlag & MANY_JAVA_CLASSES)
2236 RET_ONERROR( mywritestr(f, " }\n") )
2237 RET_ONERROR( mywritestr(f, " }\n") )
2238 offset += maxNumberElements;
2239 }
2240 }
2241
2242 if (nodeFlag && (value->getType() == SFNODE)) {
2243 if (value) {
2244 Node *node = ((SFNode *)value)->getValue();
2245 if (node && (node != this)) // avoid simple cyclic scenegraph
2246 RET_ONERROR( node->writeCDataAsFunctions(f, languageFlag) )
2247 }
2248 } else if (nodeFlag && (value->getType() == MFNODE)) {
2249 if (value) {
2250 MFNode *nodes = (MFNode *)value;
2251 for (int i = 0; i < nodes->getSize(); i++) {
2252 Node *node = nodes->getValue(i);
2253 if (node && (node != this)) // avoid simple cyclic scenegraph
2254 RET_ONERROR(node->writeCDataAsFunctions(f, languageFlag) )
2255 }
2256 }
2257 }
2258
2259 return 0;
2260 }
2261
2262 int
writeCElement(int f,int elementType,int i,int languageFlag,bool nodeFlag)2263 Node::writeCElement(int f, int elementType, int i, int languageFlag,
2264 bool nodeFlag)
2265 {
2266 if (!m_proto) return(0);
2267
2268 Element *element = m_proto->getElement(elementType, i);
2269
2270 if (m_scene->isInvalidElement(element))
2271 return 0;
2272
2273 if (element->getFlags() & FF_X3DOM_ONLY)
2274 return 0;
2275
2276 int type = element->getType();
2277
2278 FieldValue *value = NULL;
2279 switch(elementType) {
2280 case EL_FIELD:
2281 value = m_fields[i];
2282 break;
2283 case EL_EVENT_IN:
2284 if (m_proto->getEventIn(i)->getExposedField() != NULL)
2285 return 0;
2286 value = typeDefaultValue(type);
2287 break;
2288 case EL_EVENT_OUT:
2289 if (m_proto->getEventOut(i)->getExposedField() != NULL)
2290 return 0;
2291 value = typeDefaultValue(type);
2292 break;
2293 default:
2294 assert(0);
2295 }
2296
2297 const char *name = element->getName(true);
2298
2299 if (nodeFlag && (value->getType() == SFNODE)) {
2300 if (value) {
2301 Node *node = ((SFNode *)value)->getValue();
2302 if (node && (node != this)) { // avoid simple cyclic scenegraph
2303 node->addToConvertedNodes(m_scene->getWriteFlags());
2304 RET_ONERROR( node->writeC(f, languageFlag) )
2305 }
2306 }
2307 } else if (nodeFlag && (value->getType() == MFNODE)) {
2308 if (value) {
2309 MFNode *nodes = (MFNode *)value;
2310 for (int i = 0; i < nodes->getSize(); i++) {
2311 Node *node = nodes->getValue(i);
2312 if (node && (node != this)) { // avoid simple cyclic scenegraph
2313 node->addToConvertedNodes(m_scene->getWriteFlags());
2314 RET_ONERROR( node->writeC(f, languageFlag) )
2315 }
2316 }
2317 }
2318 } else if (!nodeFlag) {
2319 if (value->isArrayInC()) {
2320 if (languageFlag & JAVA_SOURCE)
2321 RET_ONERROR( mywritestr(f, " ") )
2322 RET_ONERROR( mywritestr(f, " {\n") )
2323 }
2324 RET_ONERROR( mywritestr(f, " ") )
2325 if (languageFlag & JAVA_SOURCE) {
2326 RET_ONERROR( mywritestr(f, " ") )
2327 if (languageFlag & MANY_JAVA_CLASSES)
2328 RET_ONERROR( mywritestr(f, " ") )
2329 }
2330 if (value->isArrayInC()) {
2331 if (languageFlag & (C_SOURCE | CC_SOURCE))
2332 RET_ONERROR( mywritestr(f, "static ") )
2333 RET_ONERROR( mywritestr(f, value->getTypeC(languageFlag)) )
2334 RET_ONERROR( mywritestr(f, " ") )
2335 } else {
2336 RET_ONERROR( writeCVariable(f, languageFlag) )
2337 RET_ONERROR( mywritestr(f, ".") )
2338 }
2339 if (TheApp->isWonderlandModuleExport() &&
2340 (element->getFlags() & FF_WONDERLAND_ART)) {
2341 addToConvertedNodes(m_scene->getWriteFlags());
2342 RET_ONERROR( value->writeCWonderlandArt(f, name, languageFlag) )
2343 } else {
2344 addToConvertedNodes(m_scene->getWriteFlags());
2345 RET_ONERROR( value->writeC(f, name, languageFlag) )
2346 }
2347 if (value->isArrayInC()) {
2348 if (languageFlag & JAVA_SOURCE) {
2349 RET_ONERROR( mywritestr(f, " ") )
2350 if (languageFlag & MANY_JAVA_CLASSES)
2351 RET_ONERROR( mywritestr(f, " ") )
2352 }
2353 RET_ONERROR( mywritestr(f, " ") )
2354 RET_ONERROR( writeCVariable(f, languageFlag) )
2355 RET_ONERROR( mywritestr(f, ".") )
2356 RET_ONERROR( mywritestr(f, name) )
2357 RET_ONERROR( mywritestr(f, " = ") )
2358 bool isNull = false;
2359 if (languageFlag & (C_SOURCE | CC_SOURCE))
2360 if (value->isMFieldValue()) {
2361 MFieldValue *mvalue = (MFieldValue *)value;
2362 if (mvalue->getSFSize() == 0)
2363 isNull = true;
2364 }
2365 if (isNull)
2366 RET_ONERROR( mywritestr(f, "NULL") )
2367 else {
2368 RET_ONERROR( mywritestr(f, "m_") )
2369 RET_ONERROR( mywritestr(f, name) )
2370 }
2371 RET_ONERROR( mywritestr(f, ";\n") )
2372 if (languageFlag & (C_SOURCE | CC_SOURCE)) {
2373 RET_ONERROR( mywritestr(f, " ") )
2374 RET_ONERROR( writeCVariable(f, languageFlag) )
2375 RET_ONERROR( mywritestr(f, ".") )
2376 RET_ONERROR( mywritestr(f, name) )
2377 RET_ONERROR( mywritestr(f, "_length") )
2378 RET_ONERROR( mywritestr(f, " = ") )
2379 if (value->isMFieldValue() &&
2380 (((MFieldValue *)value)->getSFSize() == 0)) {
2381 RET_ONERROR( mywritestr(f, "0") )
2382 } else {
2383 RET_ONERROR( mywritestr(f, "sizeof(") )
2384 RET_ONERROR( mywritestr(f, "m_") )
2385 RET_ONERROR( mywritestr(f, name) )
2386 RET_ONERROR( mywritestr(f, ") / sizeof(") )
2387 RET_ONERROR( mywritestr(f, value->getTypeC(languageFlag)) )
2388 RET_ONERROR( mywritestr(f, ")") )
2389 }
2390 RET_ONERROR( mywritestr(f, ";\n") )
2391 }
2392 if (languageFlag & JAVA_SOURCE) {
2393 RET_ONERROR( mywritestr(f, " ") )
2394 if (languageFlag & MANY_JAVA_CLASSES)
2395 RET_ONERROR( mywritestr(f, " ") )
2396 }
2397 RET_ONERROR( mywritestr(f, " }\n") )
2398 }
2399 }
2400 return 0;
2401 }
2402
2403 int
writeCVariable(int f,int languageFlag)2404 NodeData::writeCVariable(int f, int languageFlag)
2405 {
2406 if (languageFlag & C_SOURCE)
2407 RET_ONERROR( mywritestr(f, "self->") )
2408 if (languageFlag & MANY_JAVA_CLASSES) {
2409 if (needExtraJavaClass() || isConvertedInCurveAnimaton())
2410 RET_ONERROR( mywritef(f, "%s%s.", TheApp->getCPrefix(),
2411 getVariableName()) )
2412 else if (hasName() || (m_scene->getRoot() == this))
2413 RET_ONERROR( mywritef(f, "%s.", TheApp->getCSceneGraphName()) )
2414 }
2415 RET_ONERROR( mywritestr(f, getVariableName()) )
2416 return 0;
2417 }
2418
2419 int
writeCProcessEventCallback(int f,int languageFlag)2420 Node::writeCProcessEventCallback(int f, int languageFlag)
2421 {
2422 RET_ONERROR( mywritestr(f, TheApp->getCPrefix()) )
2423 RET_ONERROR( mywritestr(f, m_proto->getCName(true)) )
2424 if (languageFlag & C_SOURCE)
2425 RET_ONERROR( mywritestr(f, "ProcessEventCallback") )
2426 else if (languageFlag & CC_SOURCE) {
2427 RET_ONERROR( mywritestr(f, "::") )
2428 RET_ONERROR( mywritestr(f, "processEventCallback") )
2429 } else if (languageFlag & JAVA_SOURCE) {
2430 RET_ONERROR( mywritestr(f, ".") )
2431 RET_ONERROR( mywritestr(f, m_proto->getProcessEventCallbackName()) )
2432 }
2433 return 0;
2434 }
2435
2436 int
writeCProcessEvent(int f,int indent,int languageFlag,const char * eventName)2437 Node::writeCProcessEvent(int f, int indent, int languageFlag,
2438 const char *eventName)
2439 {
2440 if (getType() == DUNE_CURVE_ANIMATION) {
2441 NodeCurveAnimation *curve = (NodeCurveAnimation *) this;
2442 Node *inter = curve->getPositionInterpolator();
2443 RET_ONERROR( inter->writeCProcessEvent(f, indent, languageFlag,
2444 eventName) )
2445 inter = curve->getOrientationInterpolator();
2446 RET_ONERROR( inter->writeCProcessEvent(f, indent, languageFlag,
2447 eventName) )
2448 return 0;
2449 }
2450
2451 if ((getType() == VRML_NURBS_SURFACE) && (!m_scene->isX3d()) &&
2452 (strcmp(eventName, "controlPoint") == 0)) {
2453 RET_ONERROR( indentf(f, indent) )
2454 RET_ONERROR( mywritestr(f, "nextEvent = ") )
2455 if (languageFlag & C_SOURCE)
2456 RET_ONERROR( mywritestr(f, "0;\n") )
2457 else
2458 RET_ONERROR( mywritestr(f, "false;\n") )
2459 RET_ONERROR( indentf(f, indent) )
2460 RET_ONERROR( mywritestr(f, "{\n") )
2461 } else {
2462 m_writtenCompleteCProcessEvent = false;
2463
2464 RET_ONERROR( indentf(f, indent) )
2465 if (languageFlag & JAVA_SOURCE)
2466 RET_ONERROR( mywritestr(f, " ") )
2467 RET_ONERROR( mywritestr(f, "if (") )
2468 RET_ONERROR( writeCProcessEventCallback(f, languageFlag) )
2469 RET_ONERROR( mywritestr(f, " != ") )
2470 if (languageFlag & JAVA_SOURCE)
2471 RET_ONERROR( mywritestr(f, "null") )
2472 else
2473 RET_ONERROR( mywritestr(f, "NULL") )
2474 RET_ONERROR( mywritestr(f, ") {\n") )
2475
2476 if (languageFlag & JAVA_SOURCE) {
2477 RET_ONERROR( indentf(f, indent + 8) )
2478 RET_ONERROR( mywritestr(f, "try {\n") )
2479 RET_ONERROR( mywritestr(f, " ") )
2480 }
2481
2482 RET_ONERROR( indentf(f, indent + 4) )
2483 if (languageFlag & JAVA_SOURCE)
2484 RET_ONERROR( mywritestr(f, " ") )
2485 RET_ONERROR( mywritestr(f, "nextEvent = ") )
2486 RET_ONERROR( writeCProcessEventCallback(f, languageFlag) )
2487 if (languageFlag & JAVA_SOURCE)
2488 RET_ONERROR( mywritestr(f, ".processEvent") )
2489 RET_ONERROR( mywritestr(f, "(") )
2490 if (languageFlag & (C_SOURCE | CC_SOURCE))
2491 RET_ONERROR( mywritestr(f, "&self->") )
2492 if (languageFlag & JAVA_SOURCE)
2493 RET_ONERROR( writeCVariable(f, languageFlag) )
2494 else
2495 RET_ONERROR( mywritestr(f, getVariableName()) )
2496 RET_ONERROR( mywritestr(f, ", \"") )
2497 RET_ONERROR( mywritestr(f, eventName) )
2498 RET_ONERROR( mywritestr(f, "\"") )
2499 if (languageFlag & (C_SOURCE | CC_SOURCE))
2500 RET_ONERROR( mywritestr(f, ", data") )
2501 RET_ONERROR( mywritestr(f, ");\n") )
2502
2503 if (languageFlag & JAVA_SOURCE) {
2504 RET_ONERROR( indentf(f, indent + 8) )
2505 RET_ONERROR( mywritestr(f, "} catch (Exception e) {\n") )
2506 RET_ONERROR( indentf(f, indent + 12) )
2507 RET_ONERROR( mywritestr(f, TheApp->getCPrefix()) )
2508 RET_ONERROR( mywritestr(f, "ShowError(e);\n") )
2509 RET_ONERROR( indentf(f, indent + 8) )
2510 RET_ONERROR( mywritestr(f, "}\n") )
2511 }
2512 }
2513
2514 RET_ONERROR( indentf(f, indent + 4) )
2515 if (languageFlag & JAVA_SOURCE)
2516 RET_ONERROR( mywritestr(f, " ") )
2517 RET_ONERROR( mywritestr(f, "if (nextEvent) {\n") )
2518
2519 return 0;
2520 }
2521
2522 int
writeCSendEvent(int f,int indent,int languageFlag,EventIn * target,EventOut * source,Node * sNode)2523 NodeData::writeCSendEvent(int f, int indent, int languageFlag,
2524 EventIn *target, EventOut *source, Node *sNode)
2525 {
2526 const char *sourceVariableName = source->getName(true);
2527 if (source->getExposedField() != NULL)
2528 sourceVariableName = source->getExposedField()->getName(true);
2529
2530 const char *targetVariableName = target->getName(true);
2531 if (target->getExposedField() != NULL)
2532 targetVariableName = target->getExposedField()->getName(true);
2533
2534 return writeCDowithEvent(f, indent + 4, languageFlag, targetVariableName,
2535 sourceVariableName, sNode,
2536 isArrayInC(target->getType()), target->getType());
2537 }
2538
2539 int
writeCCopyEvent(int f,int indent,int languageFlag,EventOut * target,EventOut * source,Node * sNode)2540 NodeData::writeCCopyEvent(int f, int indent, int languageFlag,
2541 EventOut *target, EventOut *source, Node *sNode)
2542 {
2543 const char *sourceVariableName = source->getName(true);
2544 if (source && source->getExposedField() != NULL)
2545 sourceVariableName = source->getExposedField()->getName(true);
2546
2547 const char *targetVariableName = target->getName(true);
2548 if (target && target->getExposedField() != NULL)
2549 targetVariableName = target->getExposedField()->getName(true);
2550
2551 return writeCDowithEvent(f, indent, languageFlag, targetVariableName,
2552 sourceVariableName, sNode,
2553 isArrayInC(target->getType()), target->getType());
2554 }
2555
2556 int
writeCCopyEvent(int f,int indent,int languageFlag,EventIn * target,EventIn * source,Node * sNode)2557 NodeData::writeCCopyEvent(int f, int indent, int languageFlag,
2558 EventIn *target, EventIn *source, Node *sNode)
2559 {
2560 const char *sourceVariableName = source->getName(true);
2561 if (source->getExposedField() != NULL)
2562 sourceVariableName = source->getExposedField()->getName(true);
2563
2564 const char *targetVariableName = target->getName(true);
2565 if (target->getExposedField() != NULL)
2566 targetVariableName = target->getExposedField()->getName(true);
2567
2568 return writeCDowithEvent(f, indent, languageFlag, targetVariableName,
2569 sourceVariableName, sNode,
2570 isArrayInC(target->getType()), target->getType());
2571 }
2572
2573 int
writeCDowithEvent(int f,int indent,int languageFlag,const char * targetVariableName,const char * sourceVariableName,Node * sNode,bool isArray,int type)2574 NodeData::writeCDowithEvent(int f, int indent, int languageFlag,
2575 const char *targetVariableName,
2576 const char *sourceVariableName,
2577 Node *sNode, bool isArray, int type)
2578 {
2579 if (!sNode->hasName())
2580 return 0;
2581 if ((languageFlag & JAVA_SOURCE) && isArray) {
2582 RET_ONERROR( indentf(f, indent + 12) )
2583 RET_ONERROR( mywritestr(f, "if ((") )
2584 RET_ONERROR( writeCVariable(f, languageFlag) )
2585 RET_ONERROR( mywritestr(f, ".") )
2586 RET_ONERROR( mywritestr(f, sourceVariableName) )
2587 RET_ONERROR( mywritestr(f, " != null) && (") )
2588 RET_ONERROR( sNode->writeCVariable(f, languageFlag) )
2589 RET_ONERROR( mywritestr(f, " != null)) {\n") )
2590
2591 RET_ONERROR( indentf(f, indent + 20) )
2592 RET_ONERROR( mywritestr(f, "if ((") )
2593 RET_ONERROR( sNode->writeCVariable(f, languageFlag) )
2594 RET_ONERROR( mywritestr(f, ".") )
2595 RET_ONERROR( mywritestr(f, targetVariableName) )
2596 RET_ONERROR( mywritestr(f, " == null) || (") )
2597 RET_ONERROR( sNode->writeCVariable(f, languageFlag) )
2598 RET_ONERROR( mywritestr(f, ".") )
2599 RET_ONERROR( mywritestr(f, targetVariableName) )
2600 RET_ONERROR( mywritestr(f, ".length != ") )
2601 RET_ONERROR( writeCVariable(f, languageFlag) )
2602 RET_ONERROR( mywritestr(f, ".") )
2603 RET_ONERROR( mywritestr(f, sourceVariableName) )
2604 RET_ONERROR( mywritestr(f, ".length))\n") )
2605
2606 RET_ONERROR( indentf(f, indent + 24) )
2607 RET_ONERROR( sNode->writeCVariable(f, languageFlag) )
2608 RET_ONERROR( mywritestr(f, ".") )
2609 RET_ONERROR( mywritestr(f, targetVariableName) )
2610 RET_ONERROR( mywritestr(f, " = new ") )
2611 RET_ONERROR( mywritestr(f, getTypeC(type, languageFlag)) )
2612 RET_ONERROR( mywritestr(f, "[") )
2613 RET_ONERROR( writeCVariable(f, languageFlag) )
2614 RET_ONERROR( mywritestr(f, ".") )
2615 RET_ONERROR( mywritestr(f, sourceVariableName) )
2616 RET_ONERROR( mywritestr(f, ".length") )
2617 RET_ONERROR( mywritestr(f, "];\n") )
2618 }
2619
2620 RET_ONERROR( indentf(f, indent + 8) )
2621 if (languageFlag & JAVA_SOURCE)
2622 RET_ONERROR( mywritestr(f, " ") )
2623 if ((languageFlag & JAVA_SOURCE) && isArray) {
2624 RET_ONERROR( mywritestr(f, " ") )
2625 }
2626 if ((languageFlag & JAVA_SOURCE) && (!isArray)) {
2627 RET_ONERROR( sNode->writeCVariable(f, languageFlag) )
2628 RET_ONERROR( mywritestr(f, ".") )
2629 RET_ONERROR( mywritestr(f, targetVariableName) )
2630 RET_ONERROR( mywritestr(f, " = ") )
2631 }
2632 RET_ONERROR( mywritestr(f, TheApp->getCPrefix()) )
2633 RET_ONERROR( mywritestr(f, typeEnumToString(type)) )
2634 RET_ONERROR( mywritestr(f, "SendEvent(") )
2635 Node *writeNode = sNode;
2636 if ((languageFlag & (C_SOURCE | CC_SOURCE)) ||
2637 ((languageFlag & JAVA_SOURCE) && isArray)) {
2638 bool nurbsSurfaceCorrection = false;
2639 if ((sNode->getType() == VRML_NURBS_SURFACE) && (!m_scene->isX3d()) &&
2640 strcmp(targetVariableName, "controlPoint") == 0) {
2641 nurbsSurfaceCorrection = true;
2642 MeshBasedNode *mesh = (MeshBasedNode *)sNode;
2643 if (mesh->getIndexedFaceSet() &&
2644 mesh->getIndexedFaceSet()->getType() == VRML_INDEXED_FACE_SET) {
2645 NodeIndexedFaceSet *face = (NodeIndexedFaceSet *)
2646 mesh->getIndexedFaceSet();
2647 writeNode = face->coord()->getValue();
2648 }
2649 }
2650 if (sNode->getType() == VRML_COORDINATE) {
2651 if (sNode->getParent()->isMeshBasedNode()) {
2652 MeshBasedNode *mesh = (MeshBasedNode *)sNode->getParent();
2653 if (mesh->getIndexedFaceSet() &&
2654 mesh->getIndexedFaceSet()->getType() ==
2655 VRML_INDEXED_FACE_SET) {
2656 NodeIndexedFaceSet *face = (NodeIndexedFaceSet *)
2657 mesh->getIndexedFaceSet();
2658 writeNode = face->coord()->getValue();
2659 }
2660 }
2661 }
2662 if (languageFlag & (C_SOURCE | CC_SOURCE)) {
2663 if (!isArrayInC(type))
2664 RET_ONERROR( mywritestr(f, "&(") )
2665 RET_ONERROR( mywritestr(f, "self->") )
2666 }
2667 if (languageFlag & JAVA_SOURCE) {
2668 RET_ONERROR( mywritestr(f, "X3d") )
2669 RET_ONERROR( mywritestr(f, writeNode->getVariableName()) )
2670 RET_ONERROR( mywritestr(f, ".") )
2671 }
2672 RET_ONERROR( mywritestr(f, writeNode->getVariableName()) )
2673 RET_ONERROR( mywritestr(f, ".") )
2674 if (nurbsSurfaceCorrection)
2675 RET_ONERROR( mywritestr(f, "point") )
2676 else
2677 RET_ONERROR( mywritestr(f, targetVariableName) )
2678 if (languageFlag & (C_SOURCE | CC_SOURCE))
2679 if (!isArray)
2680 RET_ONERROR( mywritestr(f, ")") )
2681 RET_ONERROR( mywritestr(f, ", ") )
2682 }
2683 if (languageFlag & CC_SOURCE)
2684 RET_ONERROR( mywritestr(f, "self->") )
2685 RET_ONERROR( writeCVariable(f, languageFlag) )
2686 RET_ONERROR( mywritestr(f, ".") )
2687 RET_ONERROR( mywritestr(f, sourceVariableName) )
2688 if (isMFType(type)) {
2689 RET_ONERROR( mywritestr(f, ", ") )
2690 if (languageFlag & CC_SOURCE)
2691 RET_ONERROR( mywritestr(f, "self->") )
2692 RET_ONERROR( writeCVariable(f, languageFlag) )
2693 RET_ONERROR( mywritestr(f, ".") )
2694 RET_ONERROR( mywritestr(f, sourceVariableName) )
2695 if (languageFlag & JAVA_SOURCE)
2696 RET_ONERROR( mywritestr(f, ".length") )
2697 else
2698 RET_ONERROR( mywritestr(f, "_length") )
2699 }
2700 RET_ONERROR( mywritestr(f, ");\n") )
2701
2702 if ((languageFlag & JAVA_SOURCE) && isArray) {
2703 RET_ONERROR( indentf(f, indent + 12) )
2704 RET_ONERROR( mywritestr(f, "}\n") )
2705 }
2706 return 0;
2707 }
2708
2709
2710 bool
hasRouteForProcessEvent(void)2711 NodeData::hasRouteForProcessEvent(void)
2712 {
2713 bool hasRoute = false;
2714
2715 SocketList::Iterator *j;
2716 for (int i = 0; i < getProto()->getNumEventOuts(); i++) {
2717 for (j = m_outputs[i].first(); j != NULL; j = j->next()) {
2718 RouteSocket s = j->item();
2719
2720 Node *sNode = s.getNode();
2721 if (!((sNode == NULL) || (s.getField() == -1))) {
2722 hasRoute = true;
2723 }
2724 }
2725 }
2726 return hasRoute;
2727 }
2728
2729 int
writeCAndFollowRoutes(int f,int indent,int languageFlag,bool writeSensorNodes,const char * eventName)2730 Node::writeCAndFollowRoutes(int f, int indent, int languageFlag,
2731 bool writeSensorNodes, const char *eventName)
2732 {
2733 bool x3d = m_scene->isX3d();
2734
2735 bool hasRoute = hasRouteForProcessEvent();
2736
2737 int countCloseWings = 0;
2738
2739 if (!hasName())
2740 return 0;
2741
2742 Proto *proto = getProto();
2743 if (hasRoute && !getProto()->isLoaded()) {
2744 m_writtenCompleteCProcessEvent = true;
2745 RET_ONERROR( writeCProcessEvent(f, indent + 4, languageFlag,
2746 eventName) )
2747 RET_ONERROR( indentf(f, indent + 8) )
2748 RET_ONERROR( mywritestr(f, "}\n") )
2749 countCloseWings++;
2750 }
2751
2752 if (isInsideProto() && getProtoParent()) {
2753 Node *parentNode = getProtoParent();
2754 Proto *parentProto = parentNode->getProto();
2755
2756 for (int i = 0; i < m_proto->getNumEventOuts(); i++) {
2757 int event = getOutsideProto()->lookupIsEventOut(this, i);
2758 if (event < 0)
2759 continue;
2760 EventOut *source = m_proto->getEventOut(i);
2761 int isEventOut = event;
2762 if (isEventOut != -1) {
2763 EventOut *protoTarget = parentProto->getEventOut(isEventOut);
2764 if (this->writeCCopyEvent(f, indent, languageFlag,
2765 protoTarget, source, getProtoParent()
2766 ) != 0)
2767 return -1;
2768 }
2769 }
2770 } else if (isPROTO()) {
2771 for (int i = 0; i < m_proto->getNumEventOuts(); i++) {
2772 for (int j = 0; j < m_proto->getEventOut(i)->getNumIs(); j++) {
2773 Node *isNode = m_proto->getEventOut(i)->getIsNode(j);
2774 int event = m_proto->getEventOut(i)->getIsField(j);
2775 if (event < 0)
2776 continue;
2777 EventOut *source = m_proto->getEventOut(i);
2778 int isEventOut = event;
2779 if (isEventOut != -1) {
2780 EventOut *protoTarget = isNode->getProto()->getEventOut(
2781 isEventOut);
2782 if (isNode->writeCCopyEvent(f, indent, languageFlag,
2783 source, protoTarget, this
2784 ) != 0)
2785 return -1;
2786
2787 RET_ONERROR( isNode->writeCProcessEvent(f, indent + 4,
2788 languageFlag,
2789 eventName) )
2790 RET_ONERROR( indentf(f, indent + 8) )
2791 RET_ONERROR( mywritestr(f, "}\n") )
2792 countCloseWings++;
2793 }
2794 }
2795 }
2796 }
2797 if (getProto()->isLoaded()) {
2798 for (int i = 0; i < m_proto->getNumEventIns(); i++) {
2799 bool exposed = false;
2800 int event = getProto()->lookupIsEventIn(eventName);
2801 if (event < 0) {
2802 int exf = getProto()->lookupIsExposedField(eventName);
2803 if (exf > -1) {
2804 ExposedField *exField = getProto()->getExposedField(exf);
2805 exposed = true;
2806 event = exField->getEventIn();
2807 }
2808 }
2809 if (event < 0)
2810 continue;
2811 EventIn *target = m_proto->getEventIn(i);
2812 MyString eventInName = "";
2813 if (exposed)
2814 eventInName += "set_";
2815 eventInName += eventName;
2816 if (strcmp(target->getName(true), eventInName) != 0)
2817 continue;
2818 int isEventIn = event;
2819 if (isEventIn != -1) {
2820 if (exposed)
2821 for (int j = 0;
2822 j < proto->getExposedField(isEventIn)->getNumIs();
2823 j++) {
2824 ExposedField *eF = m_proto->getExposedField(isEventIn);
2825 Node *node = eF->getIsNode(j);
2826 node = m_scene->searchProtoNodeId(node->getId());
2827 if (node) {
2828 EventIn *protoSource = node->getProto()->getEventIn(
2829 eF->getIsField(j));
2830 if (this->writeCCopyEvent(f, indent, languageFlag,
2831 protoSource, target, node
2832 ) != 0)
2833 return -1;
2834 }
2835 }
2836 else
2837 for (int j = 0;
2838 j < proto->getEventIn(isEventIn)->getNumIs();
2839 j++) {
2840 EventIn *eI = m_proto->getEventIn(isEventIn);
2841 Node *node = eI->getIsNode(j);
2842 node = m_scene->searchProtoNodeId(node->getId());
2843 EventIn *protoSource = node->getProto()->getEventIn(
2844 eI->getIsField(j));
2845 if (this->writeCCopyEvent(f, indent, languageFlag,
2846 protoSource, target, node
2847 ) != 0)
2848 return -1;
2849 }
2850 }
2851 }
2852 }
2853
2854 SocketList::Iterator *j;
2855 for (int i = 0; i < getProto()->getNumEventOuts(); i++) {
2856 int numOutput = 0;
2857 for (j = m_outputs[i].first(); j != NULL; j = j->next()) {
2858 numOutput++;
2859 RouteSocket s = j->item();
2860
2861 Node *sNode = s.getNode();
2862
2863 bool isCurveAnimation = (sNode->getType() == DUNE_CURVE_ANIMATION);
2864
2865 EventIn *target = sNode->getProto()->getEventIn(s.getField());
2866 if (isInAlreadyWrittenEventOuts(i, numOutput, m_nodePROTO))
2867 continue;
2868 EventOut *source = getProto()->getEventOut(i);
2869
2870 RET_ONERROR( indentf(f, indent + 8) )
2871 if ((languageFlag & JAVA_SOURCE) && !isCurveAnimation) {
2872 RET_ONERROR( indentf(f, indent + 4) )
2873 RET_ONERROR( mywritestr(f, "if (") )
2874 RET_ONERROR( sNode->writeCVariable(f, languageFlag) )
2875 RET_ONERROR( mywritestr(f, " != null) ") )
2876 }
2877 RET_ONERROR( mywritestr(f, "{\n") )
2878
2879 if (isInsideProto()) {
2880 sNode = m_scene->searchProtoNodeIdInNode(m_nodePROTO,
2881 sNode->getId());
2882 if (!sNode->hasName())
2883 continue;
2884
2885 bool isCurveAnimation = (sNode->getType() == DUNE_CURVE_ANIMATION);
2886
2887 if (sNode == NULL) {
2888 swDebugf("internal Error: sNode == NULL\n");
2889 return -1;
2890 }
2891 }
2892
2893 if (((getNodeClass() & SENSOR_NODE) ||
2894 (getType() == VRML_COLLISION)) &&
2895 hasOutputsOrIs()) {
2896 m_scene->addToSensorNodes(this);
2897 }
2898
2899 bool replaceEventOut = false;
2900 if (sNode->getType() == DUNE_CURVE_ANIMATION) {
2901 NodeCurveAnimation *curve = (NodeCurveAnimation *) sNode;
2902 if (s.getField() == curve->getFraction_Field()) {
2903 replaceEventOut = true;
2904 NodePositionInterpolator *inter =
2905 (NodePositionInterpolator *)(curve->
2906 getPositionInterpolator());
2907 source = inter->getProto()->getEventOut(
2908 inter->set_fraction_Field());
2909 if (getType() == VRML_TIME_SENSOR) {
2910 NodeTimeSensor *timer = (NodeTimeSensor *)this;
2911 int eventOut = timer->getProto()->lookupEventOut(
2912 "fraction_changed", true);
2913 source = timer->getProto()->getEventOut(eventOut);
2914 }
2915
2916 int eventWritten = m_writtenCompleteCProcessEvent;
2917
2918 RET_ONERROR(writeCSendEvent(f, indent, languageFlag,
2919 target, source, inter) )
2920 if (eventWritten | (!(languageFlag & JAVA_SOURCE))) {
2921 RET_ONERROR( indentf(f, indent + 8) )
2922 RET_ONERROR( mywritestr(f, "}\n") )
2923 RET_ONERROR( indentf(f, indent + 4) )
2924 RET_ONERROR( mywritestr(f, "}\n") )
2925 }
2926
2927 NodeOrientationInterpolator *inter2 =
2928 (NodeOrientationInterpolator *)(curve->
2929 getOrientationInterpolator());
2930 source = inter2->getProto()->getEventOut(
2931 inter2->set_fraction_Field());
2932 if (getType() == VRML_TIME_SENSOR) {
2933 NodeTimeSensor *timer = (NodeTimeSensor *)this;
2934 int eventOut = timer->getProto()->lookupEventOut(
2935 "fraction_changed", true);
2936 source = timer->getProto()->getEventOut(eventOut);
2937 }
2938
2939 if (writeCSendEvent(f, indent, languageFlag, target,
2940 source, inter2) != 0)
2941 return -1;
2942 }
2943 }
2944 bool replaceEventIn = false;
2945 if (getType() == DUNE_CURVE_ANIMATION) {
2946 NodeCurveAnimation *curve = (NodeCurveAnimation *) this;
2947 if (i == curve->getPosition_Field()) {
2948 replaceEventIn = true;
2949 NodePositionInterpolator *inter =
2950 (NodePositionInterpolator *)(curve->
2951 getPositionInterpolator());
2952 source = inter->getProto()->getEventOut(
2953 inter->value_changed_Field());
2954 if (inter->writeCSendEvent(f, indent, languageFlag,
2955 target, source, sNode) != 0)
2956 return -1;
2957 }
2958 if (i == curve->getOrientation_Field()) {
2959 replaceEventIn = true;
2960 NodeOrientationInterpolator *inter =
2961 (NodeOrientationInterpolator *)(curve->
2962 getOrientationInterpolator());
2963 source = inter->getProto()->getEventOut(
2964 inter->value_changed_Field());
2965 if (inter->writeCSendEvent(f, indent, languageFlag,
2966 target, source, sNode) != 0)
2967 return -1;
2968 }
2969 }
2970 if ((!replaceEventOut) && (!replaceEventIn))
2971 if (writeCSendEvent(f, indent, languageFlag,
2972 target, source, sNode) != 0)
2973 return -1;
2974
2975 const char *targetVariableName = target->getName(true);
2976 if (target->getExposedField() != NULL)
2977 targetVariableName = target->getExposedField()->getName(true);
2978 if (!isInAlreadyWrittenEventOuts(i, numOutput, m_nodePROTO))
2979 appendToAlreadyWrittenEventOuts(i, numOutput, m_nodePROTO);
2980
2981 RET_ONERROR( sNode->writeCAndFollowRoutes(f, indent + 8,
2982 languageFlag,
2983 writeSensorNodes,
2984 targetVariableName) )
2985
2986 RET_ONERROR( indentf(f, indent + 8) )
2987 if (languageFlag & JAVA_SOURCE)
2988 RET_ONERROR( mywritestr(f, " ") )
2989 RET_ONERROR( mywritestr(f, "}\n") )
2990
2991 Field *field = getProto()->getField(s.getField());
2992 if (field) {
2993 ExposedField *expField = field->getExposedField();
2994 if (expField) {
2995 int eventOut = expField->getEventOut();
2996 EventOut *source = getProto()->getEventOut(eventOut);
2997 if (source) {
2998 SocketList::Iterator *i;
2999 for (i = m_outputs[eventOut].first(); i != NULL;
3000 i = i->next()) {
3001 RouteSocket s = i->item();
3002 Node *sNode = s.getNode();
3003
3004 EventIn *target =
3005 sNode->getProto()->getEventIn(s.getField());
3006 if (writeCSendEvent(f, indent + 4, languageFlag,
3007 target, source, sNode) != 0)
3008 return -1;
3009 }
3010 }
3011 }
3012 }
3013 }
3014 }
3015 if (getProto()->isLoaded() && !hasRoute)
3016 countCloseWings++;
3017 for (int i = 0; i < countCloseWings; i++) {
3018 RET_ONERROR( indentf(f, indent + 4 - i * 4) )
3019 RET_ONERROR( mywritestr(f, "}\n") )
3020 }
3021 return 0;
3022 }
3023
3024 int
writeCInstallDynamicNodeCallback(int f,int languageFlag,Proto * proto)3025 Node::writeCInstallDynamicNodeCallback(int f, int languageFlag, Proto *proto)
3026 {
3027 if (languageFlag & C_SOURCE) {
3028 RET_ONERROR( mywritestr(f, " ") )
3029 RET_ONERROR( mywritestr(f, TheApp->getCPrefix()) )
3030 RET_ONERROR( mywritestr(f, proto->getCName(true)) )
3031 RET_ONERROR( mywritestr(f, "ProcessEventCallback = ") )
3032 RET_ONERROR( mywritestr(f, TheApp->getCPrefix()) )
3033 RET_ONERROR( mywritestr(f, proto->getCName(true)) )
3034 RET_ONERROR( mywritestr(f, "SendEventsCallback;\n") )
3035 } else if (languageFlag & CC_SOURCE) {
3036 RET_ONERROR( mywritestr(f, " ") )
3037 RET_ONERROR( mywritestr(f, TheApp->getCPrefix()) )
3038 RET_ONERROR( mywritestr(f, proto->getCName(true)) )
3039 RET_ONERROR( mywritestr(f, "::") )
3040 RET_ONERROR( mywritestr(f, "processEventCallback = ") )
3041 RET_ONERROR( mywritestr(f, TheApp->getCPrefix()) )
3042 RET_ONERROR( mywritestr(f, proto->getCName(true)) )
3043 RET_ONERROR( mywritestr(f, "SendEventsCallback;\n") )
3044 } else if (languageFlag & JAVA_SOURCE) {
3045 RET_ONERROR( mywritestr(f, " ") )
3046 RET_ONERROR( mywritestr(f, " {\n") )
3047 RET_ONERROR( mywritestr(f, " ") )
3048 RET_ONERROR( mywritestr(f, " ") )
3049 RET_ONERROR( mywritestr(f, TheApp->getCPrefix()) )
3050 RET_ONERROR( mywritestr(f, proto->getCName(true)) )
3051 RET_ONERROR( mywritestr(f, "SendEventsCallback var = new ") )
3052 RET_ONERROR( mywritestr(f, TheApp->getCPrefix()) )
3053 RET_ONERROR( mywritestr(f, proto->getCName(true)) )
3054 RET_ONERROR( mywritestr(f, "SendEventsCallback();\n") )
3055 RET_ONERROR( mywritestr(f, " ") )
3056 RET_ONERROR( mywritestr(f, " ") )
3057 RET_ONERROR( mywritestr(f, TheApp->getCPrefix()) )
3058 RET_ONERROR( mywritestr(f, proto->getCName(true)) )
3059 RET_ONERROR( mywritestr(f, ".set") )
3060 RET_ONERROR( mywritestr(f, TheApp->getCPrefix()) )
3061 RET_ONERROR( mywritestr(f, proto->getCName(true)) )
3062 RET_ONERROR( mywritestr(f, "ProcessEventCallback(var);\n") )
3063 RET_ONERROR( mywritestr(f, " }\n") )
3064 }
3065 return 0;
3066 }
3067
3068 int
lookupEventIn(const char * name,bool x3d) const3069 NodeData::lookupEventIn(const char *name, bool x3d) const
3070 {
3071 return m_proto ? m_proto->lookupEventIn(name, x3d) : INVALID_INDEX;
3072 }
3073
3074 int
lookupEventOut(const char * name,bool x3d) const3075 NodeData::lookupEventOut(const char *name, bool x3d) const
3076 {
3077 return m_proto ? m_proto->lookupEventOut(name, x3d) : INVALID_INDEX;
3078 }
3079
3080 MyString
newEventName(int typeEnum,bool out)3081 NodeData::newEventName(int typeEnum, bool out)
3082 {
3083 bool x3d = m_scene->isX3d();
3084 char name[1024];
3085 MyString eventName = "";
3086 const char *typestr = typeEnumToString(typeEnum);
3087 if (typestr[0] == 'M')
3088 eventName += "m";
3089 for (unsigned int i = 2; i < strlen(typestr); i++)
3090 eventName += tolower(typestr[i]);
3091 int counter = 0;
3092 bool foundflag;
3093 do {
3094 foundflag = false;
3095 counter++;
3096 const char *format = "%d_in";
3097 if (out)
3098 format = "%d_out";
3099 mysnprintf(name, 1023, (const char *)format, counter);
3100
3101 int numberEvents = 0;
3102 if (out)
3103 numberEvents = m_proto->getNumEventOuts();
3104 else
3105 numberEvents = m_proto->getNumEventIns();
3106 for (int i = 0; i < numberEvents; i++) {
3107 const char *oldName;
3108 if (out)
3109 oldName = (const char*) m_proto->getEventOut(i)->getName(x3d);
3110 else
3111 oldName = (const char*) m_proto->getEventIn(i)->getName(x3d);
3112 MyString cmpName = "";
3113 cmpName += eventName;
3114 cmpName += name;
3115 if (strcmp(oldName, (const char*)cmpName) == 0)
3116 foundflag = true;
3117 }
3118 } while (foundflag == true);
3119 eventName += name;
3120 return eventName;
3121 }
3122
3123 void
addInput(int eventIn,Node * src,int eventOut)3124 NodeData::addInput(int eventIn, Node *src, int eventOut)
3125 {
3126 if (eventIn >= m_numEventIns)
3127 if (isDynamicFieldsNode()) {
3128 int typeEnum = src->getProto()->getEventOut(eventOut)->getType();
3129 MyString event = "";
3130 event += newEventName(typeEnum, false);
3131 if (TheApp->mainWnd() != NULL) {
3132 ScriptEventDialog dlg(TheApp->mainWnd(), IDD_SCRIPT_EVENT,
3133 event, (Node *)this);
3134 dlg.DoModal();
3135 if (dlg.GetValue()) {
3136 event = "";
3137 event += dlg.GetValue();
3138 }
3139 }
3140 ((DynamicFieldsNode *)this)->addEventIn(typeEnum, event);
3141 update();
3142 NodeUpdate *hint= new NodeUpdate((Node *)this, NULL, 0);
3143 m_scene->UpdateViews(NULL, UPDATE_CHANGE_INTERFACE_NODE,
3144 (Hint*) hint);
3145 }
3146 m_inputs[eventIn].append(RouteSocket(src, eventOut));
3147 }
3148
3149 void
addOutput(int eventOut,Node * dst,int eventIn)3150 NodeData::addOutput(int eventOut, Node *dst, int eventIn)
3151 {
3152 if (eventOut >= m_numEventOuts)
3153 if (isNodeWithAdditionalEvents()) {
3154 int typeEnum = dst->getProto()->getEventIn(eventIn)->getType();
3155 MyString event = "";
3156 event += newEventName(typeEnum, true);
3157 if (TheApp->mainWnd() != NULL) {
3158 ScriptEventDialog dlg(TheApp->mainWnd(), IDD_SCRIPT_EVENT,
3159 event, (Node *)this);
3160 dlg.DoModal();
3161 if (dlg.GetValue()) {
3162 event = "";
3163 event += dlg.GetValue();
3164 }
3165 }
3166 ((DynamicFieldsNode *)this)->addEventOut(typeEnum, event);
3167 update();
3168 NodeUpdate *hint= new NodeUpdate((Node *)this, NULL, 0);
3169 m_scene->UpdateViews(NULL, UPDATE_CHANGE_INTERFACE_NODE,
3170 (Hint*) hint);
3171 }
3172 m_outputs[eventOut].append(RouteSocket(dst, eventIn));
3173 }
3174
3175 void
removeInput(int eventIn,Node * src,int eventOut)3176 NodeData::removeInput(int eventIn, Node *src, int eventOut)
3177 {
3178 SocketList::Iterator *j = m_inputs[eventIn].find(RouteSocket(src, eventOut));
3179 if (j)
3180 m_inputs[eventIn].remove(j);
3181 }
3182
3183 void
removeOutput(int eventOut,Node * dst,int eventIn)3184 NodeData::removeOutput(int eventOut, Node *dst, int eventIn)
3185 {
3186 SocketList::Iterator *j = m_outputs[eventOut].find(RouteSocket(dst,
3187 eventIn));
3188 if (j)
3189 m_outputs[eventOut].remove(j);
3190 }
3191
3192 void
update()3193 NodeData::update()
3194 {
3195 // used by Script to update its fields and
3196 // used by shapes to redraw after a change of a MF-field and
3197 // used by nodes to redraw parent after a change of a field
3198 }
3199
3200 void
reInit()3201 NodeData::reInit()
3202 {
3203 // used to reinitialise private data of a "copy"-ed node
3204 // e.g. to reinitialise mesh data of some geometric shapes
3205 }
3206
3207
3208 void
addParent(Node * parent,int field)3209 Node::addParent(Node *parent, int field)
3210 {
3211 for (long i = 0; i < m_parents.size(); i++)
3212 if ((m_parents[i].m_node == parent) && (m_parents[i].m_field == field)){
3213 m_geometricParentIndex = i;
3214 return; // parent already set
3215 }
3216 m_parents.append(Parent(parent, field, this));
3217 m_geometricParentIndex = m_parents.size() - 1;
3218 }
3219
3220 void
removeParent(void)3221 Node::removeParent(void)
3222 {
3223 if (m_geometricParentIndex != -1) {
3224 for (long i = m_geometricParentIndex + 1; i < m_parents.size(); i++)
3225 if (m_parents[i].m_self)
3226 m_parents[i].m_self->m_geometricParentIndex--;
3227 m_parents.remove(m_geometricParentIndex);
3228 m_geometricParentIndex = -1;
3229 }
3230 }
3231
3232
3233 int
findChild(Node * child,int field) const3234 NodeData::findChild(Node *child, int field) const
3235 {
3236 assert(field >= 0 && field < m_numFields);
3237
3238 FieldValue *value = m_fields[field];
3239
3240 if (value && value->getType() == SFNODE) {
3241 return (((SFNode *) value)->getValue() == child) ? 0 : -1;
3242 } else if (value && value->getType() == MFNODE) {
3243 NodeList *list = ((MFNode *) value)->getValues();
3244 for (long i = 0; i < list->size(); i++) {
3245 if (list->get(i) == child) return i;
3246 }
3247 return -1;
3248 } else {
3249 return -1;
3250 }
3251 }
3252
3253 bool
hasAncestor(Node * node) const3254 Node::hasAncestor(Node *node) const
3255 {
3256 if (this != m_scene->getRoot()) {
3257 if (hasParent()) {
3258 Node *parent = getParent();
3259 if (parent == node || parent->hasAncestor(node))
3260 return true;
3261 }
3262 }
3263 return false;
3264 }
3265
3266 bool
checkValid(Element * field)3267 NodeData::checkValid(Element *field)
3268 {
3269 if (m_scene != NULL) {
3270 if (m_scene->isInvalidElement(field))
3271 return false;
3272 }
3273 return true;
3274 }
3275
3276 int
findValidFieldType(int childType)3277 NodeData::findValidFieldType(int childType)
3278 {
3279 int match = -1;
3280 for (int field = 0; field < m_numFields; field++) {
3281 if (validChildType(field, childType)) {
3282 if (match != -1) {
3283 // ambiguous
3284 return - 1;
3285 }
3286 match = field;
3287 }
3288 }
3289 return match;
3290 }
3291
3292 int
findFirstValidFieldType(int childType)3293 NodeData::findFirstValidFieldType(int childType)
3294 {
3295 for (int field = 0; field < m_numFields; field++) {
3296 if (validChildType(field, childType)) {
3297 return field;
3298 }
3299 }
3300 return -1;
3301 }
3302
3303 int
findValidField(Node * child)3304 NodeData::findValidField(Node *child)
3305 {
3306 int ret = findValidFieldType(child->getNodeClass());
3307 if (ret == -1)
3308 ret = findValidFieldType(child->getType());
3309 return ret;
3310 }
3311
3312 int
findChildType(int childType)3313 NodeData::findChildType(int childType)
3314 {
3315 int match = -1;
3316 for (int field = 0; field < m_numFields; field++) {
3317 if (checkChildType(field, childType, false)) {
3318 if (match != -1) {
3319 // ambiguous
3320 return -1;
3321 }
3322 match = field;
3323 }
3324 }
3325 return match;
3326 }
3327
3328 bool
validChild(int field,Node * child)3329 NodeData::validChild(int field, Node *child)
3330 {
3331 return validChildType(field, child->getNodeClass());
3332 }
3333
3334 bool
validChildType(int field,int childType)3335 NodeData::validChildType(int field, int childType)
3336 {
3337 return checkChildType(field, childType, true);
3338 }
3339
3340 bool
checkChildType(int field,int childType,bool checkNewNode)3341 NodeData::checkChildType(int field, int childType, bool checkNewNode)
3342 {
3343 if (field < 0 || field >= m_numFields) return false;
3344
3345 Field *def = m_proto->getField(field);
3346
3347 // SFNode field already in use ?
3348 if (def->getType() == SFNODE) {
3349 SFNode *node = (SFNode *)m_fields[field];
3350 if (checkNewNode)
3351 if (node->getValue() != NULL)
3352 return false;
3353 }
3354
3355 if ((def->getType() == SFNODE) || (def->getType() == MFNODE)) {
3356 int nodeType = def->getNodeType();
3357
3358 if (childType & NOT_SELF_NODE) {
3359 int bits = ::getMaskedNodeClass(nodeType);
3360 if (bits == 0) {
3361 bits = nodeType & (~NOT_SELF_NODE);
3362 if (bits & childType)
3363 return false;
3364 } else
3365 if (bits & childType)
3366 return false;
3367 }
3368 if (nodeType == ANY_NODE) {
3369 return checkValid(def);
3370 } else if ((::getMaskedNodeClass(childType) != 0) &&
3371 (::getMaskedNodeClass(childType) ==
3372 ::getMaskedNodeClass(nodeType))) {
3373 return checkValid(def);
3374 } else if (::matchNodeClass(nodeType, childType)) {
3375 return checkValid(def);
3376 } else if ((getType() == VRML_CONTOUR_2D) &&
3377 (childType == NURBS_CONTROL_CURVE_NODE)) {
3378 return checkValid(def);
3379 } else
3380 return false;
3381 } else {
3382 return false;
3383 }
3384 return false;
3385 }
3386
3387 void
setFlagRec(int flag)3388 NodeData::setFlagRec(int flag)
3389 {
3390 setFlag(flag);
3391
3392 for (int i = 0; i < m_numFields; i++) {
3393 if (m_fields[i]->getType() == MFNODE) {
3394 MFNode *nodes = (MFNode *) m_fields[i];
3395 for (int j = 0; j < nodes->getSize(); j++)
3396 if (nodes->getValue(j) != NULL)
3397 nodes->getValue(j)->setFlagRec(flag);
3398 } else if (m_fields[i]->getType() == SFNODE) {
3399 SFNode *value = (SFNode *) m_fields[i];
3400 if (value->getValue()) value->getValue()->setFlagRec(flag);
3401 }
3402 }
3403 }
3404
3405 void
clearFlagRec(int flag)3406 NodeData::clearFlagRec(int flag)
3407 {
3408 clearFlag(flag);
3409
3410 for (int i = 0; i < m_numFields; i++) {
3411 if (m_fields[i] && m_fields[i]->getType() == MFNODE) {
3412 MFNode *nodes = (MFNode *) m_fields[i];
3413 for (int j = 0; j < nodes->getSize(); j++)
3414 if (nodes->getValue(j) != NULL)
3415 nodes->getValue(j)->clearFlagRec(flag);
3416 } else if (m_fields[i] && m_fields[i]->getType() == SFNODE) {
3417 SFNode *value = (SFNode *) m_fields[i];
3418 if (value->getValue()) value->getValue()->clearFlagRec(flag);
3419 }
3420 }
3421 }
3422
3423 class ReceiveData {
3424 public:
3425 Proto *outSideProto;
3426 int field;
3427 double timestamp;
3428 FieldValue *value;
3429 };
3430
branchReceiveEvent(Node * node,void * data)3431 static bool branchReceiveEvent(Node *node, void *data)
3432 {
3433 ReceiveData *receiveData = (ReceiveData *)data;
3434 if ((node != NULL) && (node->isPROTO()))
3435 if (strcmp(node->getProto()->getName(true),
3436 receiveData->outSideProto->getName(true)) == 0) {
3437 NodePROTO *protoNode = (NodePROTO *)node;
3438 Proto *proto = protoNode->getProto();
3439 for (int i = 0; i < proto->getNumEventOuts(); i++) {
3440 EventOut *evOut = proto->getEventOut(i);
3441 for (int j = 0; j < evOut->getNumIs(); j++) {
3442 if (evOut->getIsField(j) == receiveData->field) {
3443 for (int i = 0; i < proto->getNumEventOuts(); i++) {
3444 if (protoNode->getOutput(i).size() > 0 &&
3445 protoNode->getOutput(i).first() != NULL) {
3446 RouteSocket s =
3447 protoNode->getOutput(i).first()->item();
3448 s.getNode()->receiveEvent(s.getField(),
3449 receiveData->timestamp, receiveData->value);
3450 }
3451 }
3452 }
3453 }
3454 }
3455 }
3456 return true;
3457 }
3458
3459 void
sendEvent(int eventOut,double timestamp,FieldValue * value)3460 NodeData::sendEvent(int eventOut, double timestamp, FieldValue *value)
3461 {
3462 assert(eventOut >= 0 && eventOut <= m_numEventOuts);
3463
3464 // handle IS
3465 EventOut *evOut = m_proto->getEventOut(eventOut);
3466 if (getOutsideProto()) {
3467 for (int i = 0; i < getOutsideProto()->getNumEventOuts(); i++)
3468 if (getOutsideProto()->getEventOut(i)->getIsField(i) == eventOut)
3469 evOut = getOutsideProto()->getEventOut(i);
3470 if (evOut && (evOut->getFlags() & FF_IS))
3471 for (int i = 0; i < evOut->getNumIs(); i++) {
3472 Node *isNode = evOut->getIsNode(i);
3473
3474 ReceiveData receiveData;
3475 receiveData.outSideProto = getOutsideProto();
3476 receiveData.field = evOut->getIsField(i);
3477 receiveData.timestamp = timestamp;
3478 receiveData.value = value;
3479
3480 m_scene->getRoot()->doWithBranch(branchReceiveEvent,
3481 &receiveData, false);
3482 }
3483 }
3484 evOut = m_proto->getEventOut(eventOut);
3485 if ((m_isEventOuts.size() > 0) && (m_isEventOuts[eventOut] != NULL))
3486 evOut = m_isEventOuts[eventOut];
3487 if (evOut && (evOut->getFlags() & FF_IS))
3488 for (int i = 0; i < evOut->getNumIs(); i++)
3489 if (evOut->getFlags() & EOF_IS_HIDDEN) {
3490 Node *isNode = evOut->getIsNode(i);
3491 isNode->sendEvent(evOut->getIsField(i), timestamp, value);
3492 }
3493
3494 SocketList::Iterator *i;
3495 for (i = m_outputs[eventOut].first(); i != NULL; i = i->next()) {
3496 RouteSocket s = i->item();
3497 s.getNode()->receiveEvent(s.getField(), timestamp, value);
3498 }
3499 }
3500
3501 void
receiveEvent(int eventIn,double timestamp,FieldValue * value)3502 NodeData::receiveEvent(int eventIn, double timestamp, FieldValue *value)
3503 {
3504 if (TheApp->getDemoMode()) {
3505 if ((getType() == VRML_VIEWPOINT) && !TheApp->timeOut())
3506 return;
3507 }
3508
3509 // check to see if this eventIn is part of an exposedField or
3510 // conntected to a normal field
3511
3512 int field = -1;
3513 ExposedField *e = m_proto->getEventIn(eventIn)->getExposedField();
3514
3515 if (e) {
3516 field = e->getFieldIndex();
3517 eventIn = e->getEventIn();
3518 } else
3519 field = m_proto->getEventIn(eventIn)->getField();
3520
3521 if (field != -1) {
3522 // set the appropriate field
3523 setField(field, value);
3524 m_scene->OnFieldChange((Node*)this, field);
3525 // fire off an event here?
3526 }
3527 }
3528
3529 void
addIsElement(Node * node,int field,int elementType,Proto * origProto,int origField,int flags)3530 NodeData::addIsElement(Node *node, int field, int elementType,
3531 Proto *origProto, int origField, int flags)
3532 {
3533 switch(elementType) {
3534 case EL_EVENT_IN:
3535 if (origField < origProto->getNumEventIns()) {
3536 if (m_isEventIns.size() == 0)
3537 for (int i = 0; i < origProto->getNumEventIns(); i++)
3538 m_isEventIns[i] = NULL;
3539 m_isEventIns[origField] = new EventIn(origProto->
3540 getEventIn(origField));
3541 m_isEventIns[origField]->addIs(node, field, elementType,
3542 origProto, origField, flags);
3543 }
3544 break;
3545 case EL_EVENT_OUT:
3546 if (origField < origProto->getNumEventOuts()) {
3547 if (m_isEventOuts.size() == 0)
3548 for (int i = 0; i < origProto->getNumEventOuts(); i++)
3549 m_isEventOuts[i] = NULL;
3550 /*
3551 // hier/hier
3552 if (origProto->getExposedField(origField))
3553 m_isExposedFields[origField] = new ExposedField(origProto->
3554 getExposedField(origField));
3555 if (m_isEventOuts[origField])
3556 m_isEventOuts[origField]->addIs(node, field, elementType,
3557 origProto, origField, flags);
3558 // da/da
3559 */
3560 // hier
3561 m_isEventOuts[origField] = new EventOut(origProto->
3562 getEventOut(origField));
3563 m_isEventOuts[origField]->addIs(node, field, elementType,
3564 origProto, origField, flags);
3565 // da
3566 }
3567 break;
3568 case EL_EXPOSED_FIELD:
3569 if (origField < origProto->getNumExposedFields()) {
3570 for (int i = 0; i < origProto->getNumExposedFields(); i++)
3571 m_isExposedFields[i] = NULL;
3572 m_isExposedFields[origField] = new ExposedField(origProto->
3573 getExposedField(origField));
3574 m_isExposedFields[origField]->addIs(node, field, elementType,
3575 origProto, origField, flags);
3576 }
3577 break;
3578 case EL_FIELD:
3579 if (origField < origProto->getNumEventIns()) {
3580 for (int i = 0; i < origProto->getNumFields(); i++)
3581 m_isFields[i] = NULL;
3582 m_isFields[origField] = new Field(origProto->getField(origField));
3583 m_isFields[origField]->addIs(node, field, elementType,
3584 origProto, origField, flags);
3585 }
3586 break;
3587 }
3588 }
3589
3590 // compare content
3591 bool
isEqual(Node * node)3592 NodeData::isEqual(Node* node)
3593 {
3594 if (node == NULL) {
3595 #ifdef HAVE_NULL_COMPARE
3596 if (this == NULL)
3597 return true;
3598 else
3599 #endif
3600 return false;
3601 }
3602 if (m_identifier == node->m_identifier)
3603 return true;
3604 return false;
3605 }
3606
3607 // compare content
3608 bool
isEqualCopy(Node * node)3609 NodeData::isEqualCopy(Node* node)
3610 {
3611 if (node == NULL) {
3612 #ifdef HAVE_NULL_COMPARE
3613 if (this == NULL)
3614 return true;
3615 else
3616 #endif
3617 return false;
3618 }
3619 if (m_identifierCopy >= 0)
3620 if (m_identifierCopy == node->m_identifierCopy)
3621 return true;
3622 if (m_identifierCopy == node->m_identifier)
3623 return true;
3624 if (m_identifier == node->m_identifierCopy)
3625 return true;
3626 return false;
3627 }
3628
3629 bool
hasRoute(SocketList socketlist)3630 NodeData::hasRoute(SocketList socketlist)
3631 {
3632 if (socketlist.first() == NULL)
3633 return false;
3634 else
3635 return true;
3636 }
3637
3638 Path *
getPath() const3639 Node::getPath() const
3640 {
3641 int len = 0;
3642 const Node *node = this;
3643 const Node *protoRoot = node;
3644
3645 for (protoRoot = this; protoRoot->hasParentOrProtoParent();
3646 protoRoot = protoRoot->getParentOrProtoParent())
3647 len += 2;
3648
3649 MyArray<int> protoList;
3650 m_scene->getProtoList(&protoList, protoRoot);
3651 if (protoList.size() > 0)
3652 len += 4;
3653
3654 if (len == 0) {
3655 Path *path = new Path(NULL, 0, m_scene);
3656 return path;
3657 }
3658
3659 int *list = new int[len];
3660
3661 int i = len - 1;
3662
3663 for (node = this; node->hasParentOrProtoParent();
3664 node = node->getParentOrProtoParent()) {
3665 Node *parent = node->getParentOrProtoParent();
3666 int field = node->getParentFieldOrProtoParentField();
3667 FieldValue *value = parent->getField(field);
3668 if (value->getType() == MFNODE) {
3669 list[i--] = ((MFNode *) value)->getValues()->find((Node *) node);
3670 } else if (value->getType() == SFNODE) {
3671 list[i--] = 0;
3672 } else {
3673 assert(0);
3674 }
3675 list[i--] = field;
3676 }
3677
3678 if (protoList.size() > 0) {
3679 list[i--] = 0;
3680 list[i--] = 0;
3681 list[i--] = protoList[1];
3682 list[i--] = protoList[0];
3683 }
3684
3685 Path *path = new Path(list, len, m_scene);
3686 delete [] list;
3687 list = NULL;
3688 return path;
3689 }
3690
3691 bool
isInScene(Scene * scene) const3692 Node::isInScene(Scene* scene) const
3693 {
3694 if (scene != m_scene)
3695 return false;
3696 if (scene == NULL)
3697 return false;
3698 if (this == m_scene->getRoot())
3699 return true;
3700 if (((NodeData *)this)->isInsideProto()) {
3701 Node *node = ((NodeData *)this)->getNodePROTO();
3702 if (node)
3703 return node->isInScene(scene);
3704 else
3705 return false;
3706 }
3707 if (!hasParent())
3708 return false;
3709 return true;
3710 }
3711
3712 bool
supportAnimation(void)3713 Node::supportAnimation(void)
3714 {
3715 Proto *proto = getProto();
3716 for (int i = 0; i < proto->getNumEventIns(); i++) {
3717 int type = proto->getEventIn(i)->getType();
3718 if (m_scene->isInvalidElement(proto->getEventIn(i)))
3719 continue;
3720
3721 if (typeDefaultValue(type)->supportAnimation(m_scene->isX3d()))
3722 return true;
3723 }
3724 return false;
3725 }
3726
3727
3728 bool
supportInteraction(void)3729 Node::supportInteraction(void)
3730 {
3731 Proto *proto = getProto();
3732 for (int i = 0; i < proto->getNumEventIns(); i++) {
3733 int type = proto->getEventIn(i)->getType();
3734 if (typeDefaultValue(type)->supportInteraction())
3735 return true;
3736 }
3737 return false;
3738 }
3739
3740 bool
isInvalidChild(void)3741 Node::isInvalidChild(void)
3742 {
3743 if (this == m_scene->getRoot())
3744 return true;
3745 if (isInvalidChildNode() && hasParent())
3746 return true;
3747 return false;
3748 }
3749
3750 Vec3f
getMinBoundingBox(void)3751 Node::getMinBoundingBox(void)
3752 {
3753 return Vec3f(FLT_MAX, FLT_MAX, FLT_MAX);
3754 }
3755
3756 Vec3f
getMaxBoundingBox(void)3757 Node::getMaxBoundingBox(void)
3758 {
3759 return Vec3f(FLT_MIN, FLT_MIN, FLT_MIN);
3760 }
3761
3762 Vec3f
getBboxSize(void)3763 Node::getBboxSize(void)
3764 {
3765 Vec3f min = getMinBoundingBox();
3766 Vec3f max = getMaxBoundingBox();
3767 if ((min.x == FLT_MAX) && (min.y == FLT_MAX) && (min.y == FLT_MAX) &&
3768 (max.x == FLT_MIN) && (max.y == FLT_MIN) && (max.y == FLT_MIN))
3769 return Vec3f(0, 0, 0);
3770 return Vec3f(max.x - min.x, max.y - min.y, max.z - min.z);
3771 }
3772
3773 Vec3f
getBboxCenter(void)3774 Node::getBboxCenter(void)
3775 {
3776 Vec3f min = getMinBoundingBox();
3777 Vec3f max = getMaxBoundingBox();
3778 if ((min.x == FLT_MAX) && (min.y == FLT_MAX) && (min.y == FLT_MAX) &&
3779 (max.x == FLT_MIN) && (max.y == FLT_MIN) && (max.y == FLT_MIN))
3780 return Vec3f(0, 0, 0);
3781 return Vec3f((max.x + min.x) / 2.0f,
3782 (max.y + min.y) / 2.0f,
3783 (max.z + min.z) / 2.0f);
3784 }
3785
3786 void
appendComment(Node * node)3787 Node::appendComment(Node *node)
3788 {
3789 m_commentsList->append(node);
3790 }
3791
appendTo(NodeList * nodelist)3792 void Node::appendTo(NodeList* nodelist)
3793 {
3794 for (long i = 0;i < m_commentsList->size(); i++)
3795 nodelist->append((*m_commentsList)[i]);
3796 nodelist->append(this);
3797 m_commentsList->resize(0);
3798 }
3799
3800 void
doWithParents(DoWithNodeCallback callback,void * data,bool searchInRest,bool callSelf)3801 Node::doWithParents(DoWithNodeCallback callback, void *data,
3802 bool searchInRest, bool callSelf)
3803 {
3804 for (long i = 0; i < m_parents.size(); i++) {
3805 bool call = true;
3806 if ((long)i == m_geometricParentIndex)
3807 if (!callSelf)
3808 call = false;
3809 if (call)
3810 if (!callback(m_parents[i].m_node, data))
3811 if (!searchInRest)
3812 break;
3813 }
3814 }
3815
3816 void
doWithSiblings(DoWithNodeCallback callback,void * data,bool searchInRest,bool callSelf)3817 Node::doWithSiblings(DoWithNodeCallback callback, void *data,
3818 bool searchInRest, bool callSelf)
3819 {
3820 if (hasParent()) {
3821 Node *parent = getParent();
3822 int parentField = getParentField();
3823 FieldValue *parentValue = parent->getField(parentField);
3824 if (parentValue->getType() == MFNODE) {
3825 MFNode *value = (MFNode *)parentValue;
3826 for (int i = 0; i < value->getSize(); i++) {
3827 Node *sibling = value->getValue(i);
3828 if (sibling != NULL) {
3829 bool call = true;
3830 if (sibling == this)
3831 if (!callSelf)
3832 call = false;
3833 if (call)
3834 if (!callback(sibling, data))
3835 if (!searchInRest)
3836 break;
3837 }
3838 }
3839 }
3840 }
3841 }
3842
3843 void
doWithNextSiblings(DoWithNodeCallback callback,void * data,bool searchInRest,bool callSelf)3844 Node::doWithNextSiblings(DoWithNodeCallback callback, void *data,
3845 bool searchInRest, bool callSelf)
3846 {
3847 bool skip = true;
3848 if (hasParent()) {
3849 Node *parent = getParent();
3850 int parentField = getParentField();
3851 FieldValue *parentValue = parent->getField(parentField);
3852 if (parentValue->getType() == MFNODE) {
3853 MFNode *value = (MFNode *)parentValue;
3854 for (int i = 0; i < value->getSize(); i++) {
3855 Node *sibling = value->getValue(i);
3856 if (sibling != NULL) {
3857 bool call = true;
3858 if (sibling == this) {
3859 skip = false;
3860 if (!callSelf)
3861 call = false;
3862 }
3863 if (call && (!skip))
3864 if (!callback(sibling, data))
3865 if (!searchInRest)
3866 break;
3867 }
3868 }
3869 }
3870 }
3871 }
3872
doWithBranch(DoWithNodeCallback callback,void * data,bool searchInRest,bool skipBranch,bool skipProto,bool callSelf,bool skipInline,bool searchInConvertedNodes)3873 bool Node::doWithBranch(DoWithNodeCallback callback, void *data,
3874 bool searchInRest, bool skipBranch,
3875 bool skipProto, bool callSelf, bool skipInline,
3876 bool searchInConvertedNodes)
3877 {
3878 #ifdef HAVE_NULL_COMPARE
3879 if (this == NULL)
3880 return false;
3881 #endif
3882 if (TheApp->getSkipChecks())
3883 return false;
3884 bool searchOn = true;
3885 bool handleInline = !skipInline;
3886 if (searchOn && (!skipProto) && hasProtoNodes()) {
3887 NodePROTO *nodeProto = (NodePROTO *)this;
3888 for (int i = 0; i < nodeProto->getNumProtoNodes(); i++)
3889 if (!(nodeProto->getProtoNode(i)->doWithBranch(callback, data,
3890 false, true, false, true, skipInline,
3891 searchInConvertedNodes)))
3892 return false;
3893 }
3894 // search in current node itself
3895 if (callSelf)
3896 searchOn = callback(this, data);
3897 if (searchOn)
3898 for (int i = 0; i < getNumConvertedNodes(); i++) {
3899 searchOn = callback(getConvertedNode(i), data);
3900 if (!searchOn)
3901 break;
3902 }
3903 if (searchOn) {
3904 // search in children of of current node
3905 for (int i = 0; i < m_proto->getNumFields(); i++) {
3906 if (m_scene->isInvalidElement(m_proto->getField(i)))
3907 continue;
3908
3909 if (m_proto->getField(i) &&
3910 m_proto->getField(i)->getType() == SFNODE) {
3911 Node *child = ((SFNode *)getField(i))->getValue();
3912 if (child) {
3913 if (child == this) {
3914 swDebugf("%s %s: %s",
3915 "Warning: simple cyclic scenegraph: USE",
3916 (const char *)getName(),
3917 "invalid VRML/X3D file...\n");
3918 return false;
3919 }
3920 if (child == getParent()) {
3921 swDebugf("%s %s: %s",
3922 "Warning: simple cyclic scenegraph: USE",
3923 (const char *)getName(),
3924 "invalid VRML/X3D file...\n");
3925 return false;
3926 }
3927 if (!child->doWithBranch(callback, data, false,
3928 skipBranch, skipProto, callSelf,
3929 skipInline, searchInConvertedNodes)) {
3930 if (skipBranch)
3931 continue;
3932 else
3933 return false;
3934 }
3935 }
3936 } else {
3937 NodeList *childList = NULL;
3938 if (handleInline && ((getType() == VRML_INLINE) ||
3939 (getType() == VRML_INLINE_LOAD_CONTROL))) {
3940 NodeInline *node = (NodeInline *)this;
3941 childList = node->getLoadedNodes();
3942 handleInline = false;
3943 }
3944 if (m_proto->getField(i) &&
3945 m_proto->getField(i)->getType() == MFNODE)
3946 childList = ((MFNode *)getField(i))->getValues();
3947 if (childList) {
3948 for (long j = 0; j < childList->size(); j++) {
3949 Node *child = childList->get(j);
3950 if (child == this) {
3951 swDebugf("%s %s: %s",
3952 "Warning: simple cyclic scenegraph: USE",
3953 (const char *)getName(),
3954 "invalid VRML/X3D file...\n");
3955 return false;
3956 }
3957 if (child == getParent()) {
3958 swDebugf("%s %s: %s",
3959 "Warning: simple cyclic scenegraph: USE",
3960 (const char *)getName(),
3961 "invalid VRML/X3D file...\n");
3962 return false;
3963 }
3964 if (child) {
3965 if (!child->doWithBranch(callback, data,
3966 false, skipBranch,
3967 skipProto, callSelf,
3968 skipInline,
3969 searchInConvertedNodes)) {
3970 if (skipBranch)
3971 continue;
3972 else
3973 return false;
3974 }
3975 }
3976 }
3977 }
3978 }
3979 }
3980 if (searchInRest) {
3981 // search in next children of current parent
3982 if (this != m_scene->getRoot()) {
3983 m_scene->getNodes()->clearFlag(NODE_FLAG_TOUCHED);
3984 if (hasParent() && isInScene(m_scene)) {
3985 Node *parent = getParent();
3986 FieldValue *selfField = parent->getField(getParentField());
3987 if ((selfField != NULL) &&
3988 (selfField->getType() == MFNODE)) {
3989 int index = parent->findChild(this, getParentField());
3990 MFNode *mfNode = (MFNode *)selfField;
3991 NodeList *childList = mfNode->getValues();
3992 if (childList)
3993 for (long j = index + 1; j < childList->size();
3994 j++) {
3995 Node *child = childList->get(j);
3996 if (child) {
3997 if (child == getParent()) {
3998 swDebugf("%s %s: %s",
3999 "Warning: simple cyclic scenegraph: USE",
4000 (const char *)getName(),
4001 "invalid VRML/X3D file...\n");
4002 return false;
4003 }
4004 if (!child->doWithBranch(callback, data,
4005 false, skipBranch, skipProto,
4006 callSelf, skipInline,
4007 searchInConvertedNodes)) {
4008 if (skipBranch)
4009 continue;
4010 else
4011 return false;
4012 }
4013 }
4014 }
4015 }
4016 }
4017 }
4018 }
4019 }
4020 return searchOn;
4021 }
4022
4023 bool
doWithSimilarBranch(DoWithSimilarBranchCallback callback,Node * similarNode,void * data)4024 Node::doWithSimilarBranch(DoWithSimilarBranchCallback callback,
4025 Node *similarNode, void *data)
4026 {
4027 if (!callback(this, similarNode, data))
4028 return false;
4029 if (m_numFields != similarNode->getProto()->getNumFields())
4030 return false;
4031 for (int i = 0; i < m_numFields; i++) {
4032 if (m_fields[i]->getType() == SFNODE) {
4033 if (similarNode->getField(i)->getType() != SFNODE)
4034 return false;
4035 Node *child = ((SFNode *) m_fields[i])->getValue();
4036 Node *node = ((SFNode *) similarNode->getField(i))->getValue();
4037 if (child && node) {
4038 if (!child->doWithSimilarBranch(callback, node, data))
4039 return false;
4040 } else if (child || node)
4041 return false;
4042 } else if (m_fields[i]->getType() == MFNODE) {
4043 if (similarNode->getField(i)->getType() != MFNODE)
4044 return false;
4045 NodeList *childList = ((MFNode *) m_fields[i])->getValues();
4046 NodeList *nodeList = ((MFNode *)
4047 similarNode->getField(i))->getValues();
4048 if (childList && nodeList) {
4049 if (childList->size() != nodeList->size())
4050 return false;
4051 for (long j = 0; j < childList->size(); j++) {
4052 Node *child = childList->get(j);
4053 Node *node = nodeList->get(j);
4054 if (child && node) {
4055 if (!child->doWithSimilarBranch(callback, node, data))
4056 return false;
4057 } else if (child || node)
4058 return false;
4059 }
4060 } else if ((childList != NULL) || (nodeList != NULL))
4061 return false;
4062 }
4063 }
4064 return true;
4065 }
4066
4067 void
copyChildrenTo(Node * copyedNode,bool copyNonNodes)4068 Node::copyChildrenTo(Node *copyedNode, bool copyNonNodes)
4069 {
4070 for (int i = 0; i < m_numFields; i++) {
4071 if (m_fields[i] && m_fields[i]->getType() == SFNODE) {
4072 Node *child = ((SFNode *) m_fields[i])->getValue();
4073 if (child) {
4074 long id = getId();
4075 Node *copyChild = child->copy();
4076 copyChild->setId(id);
4077 copyChild->ref();
4078 copyedNode->unSetVariableName();
4079 copyedNode->setField(i, new SFNode(copyChild));
4080 child->copyChildrenTo(copyChild, copyNonNodes);
4081 child->copyOutputsTo(copyChild);
4082 child->copyInputsTo(copyChild);
4083 }
4084 } else if (m_fields[i] && m_fields[i]->getType() == MFNODE) {
4085 NodeList *childList = ((MFNode *) m_fields[i])->getValues();
4086 if (childList) {
4087 MFNode *field = new MFNode((MFNode *)m_fields[i]);
4088 if (field) {
4089 copyedNode->setField(i, field);
4090 MFNode *mfnode = (MFNode *) copyedNode->getField(i);
4091 for (long j = 0; j < childList->size(); j++) {
4092 Node *copyChild = mfnode->getValue(j);
4093 if (copyChild && childList->get(j)) {
4094 childList->get(j)->ref();
4095 childList->get(j)->unSetVariableName();
4096 childList->get(j)->copyChildrenTo(copyChild,
4097 copyNonNodes);
4098 childList->get(j)->copyOutputsTo(copyChild);
4099 childList->get(j)->copyInputsTo(copyChild);
4100 }
4101 }
4102 }
4103 } else if (m_fields[i] && copyNonNodes) {
4104 FieldValue *value = m_fields[i];
4105 if (value)
4106 setField(i, value->copy());
4107 }
4108 }
4109 }
4110 }
4111
4112 void
copyOutputsTo(Node * copyedNode)4113 Node::copyOutputsTo(Node *copyedNode)
4114 {
4115 for (int i = 0; i < m_proto->getNumEventOuts(); i++) {
4116 for (SocketList::Iterator *j = getOutput(i).first();
4117 j != NULL; j = j->next())
4118 copyedNode->addOutput(i, j->item().getNode(),
4119 j->item().getField());
4120 }
4121 }
4122
4123
4124 void
copyInputsTo(Node * copyedNode)4125 Node::copyInputsTo(Node *copyedNode)
4126 {
4127 for (int i = 0; i < m_proto->getNumEventIns(); i++) {
4128 for (SocketList::Iterator *j = getInput(i).first();
4129 j != NULL; j = j->next())
4130 copyedNode->addInput(i, j->item().getNode(),
4131 j->item().getField());
4132 }
4133 }
4134
4135 void
doWithAllElements(DoWithAllElementsCallback callback,void * data)4136 Node::doWithAllElements(DoWithAllElementsCallback callback, void *data)
4137 {
4138 int i = 0;
4139 for (i = 0; i < m_proto->getNumFields(); i++)
4140 callback(m_proto->getField(i), data);
4141 for (i = 0; i < m_proto->getNumEventIns(); i++)
4142 callback(m_proto->getEventIn(i), data);
4143 for (i = 0; i < m_proto->getNumEventOuts(); i++)
4144 callback(m_proto->getEventOut(i), data);
4145 for (i = 0; i < m_proto->getNumExposedFields(); i++)
4146 callback(m_proto->getExposedField(i), data);
4147 }
4148
4149 void
removeChildren(void)4150 NodeData::removeChildren(void)
4151 {
4152 for (int i = 0; i < m_numFields; i++)
4153 if (m_fields[i]->getType() == SFNODE)
4154 setField(i, new SFNode(NULL));
4155 else if (m_fields[i]->getType() == MFNODE)
4156 setField(i, new MFNode());
4157 }
4158
4159 void
handleIs(void)4160 NodeData::handleIs(void)
4161 {
4162 // PROTO initialisation ready ?
4163 if (!getProto()->isLoaded())
4164 return;
4165
4166 bool x3d = m_scene->isX3d();
4167
4168 // handle IS
4169 for (int i = 0; i < m_proto->getNumExposedFields(); i++) {
4170 m_isExposedFields[i] = NULL;
4171 ExposedField *field = m_proto->getExposedField(i);
4172 if (field && field->getFlags() & FF_IS)
4173 for (int j = 0; j < field->getNumIs(); j++)
4174 if (field->getFlags() & FF_IS) {
4175 Node *isNode = field->getIsNode(j);
4176 Proto *proto = isNode->getProto();
4177 if (field->getIsField(j) < 0)
4178 continue;
4179 FieldValue *value = field->getValue()->copy();
4180 if ((isNode != NULL))
4181 isNode->setField(field->getIsField(j), value);
4182 m_isExposedFields[i] = new ExposedField(field);
4183 isNode->addIsElement((Node *)this, i,
4184 EL_EXPOSED_FIELD, proto,
4185 field->getIsField(j),
4186 field->getIsField(j));
4187 }
4188 }
4189 for (int i = 0; i < m_proto->getNumFields(); i++) {
4190 m_isFields[i] = NULL;
4191 Field *field = m_proto->getField(i);
4192 if (field && field->getFlags() & FF_IS)
4193 for (int j = 0; j < field->getNumIs(); j++)
4194 if (field->getFlags() & FF_IS) {
4195 Node *isNode = field->getIsNode(j);
4196 Proto *proto = isNode->getProto();
4197 FieldValue *value = field->getDefault(x3d)->copy();
4198 if ((isNode != NULL)) {
4199 isNode->setField(field->getIsField(j), value);
4200 }
4201 m_isFields[i] = new Field(field);
4202 isNode->addIsElement((Node *)this, i, EL_FIELD, proto,
4203 field->getIsField(j),
4204 field->getIsField(j));
4205 }
4206 }
4207
4208 for (int i = 0; i < m_proto->getNumEventOuts(); i++) {
4209 m_isEventOuts[i] = NULL;
4210 EventOut *eventOut = m_proto->getEventOut(i);
4211 if (eventOut && eventOut->getFlags() & FF_IS)
4212 for (int j = 0; j < eventOut->getNumIs(); j++)
4213 if (eventOut->getFlags() & EOF_IS) {
4214 Node *isNode = eventOut->getIsNode(j);
4215 Proto *proto = isNode->getProto();
4216 int evOut = eventOut->getIsField(j);
4217 if (evOut < 0)
4218 continue;
4219 m_isEventOuts[i] = new EventOut(eventOut);
4220 isNode->addIsElement((Node *)this, i, EL_EVENT_OUT,
4221 proto, evOut, EOF_IS_HIDDEN);
4222 }
4223 }
4224 for (int i = 0; i < m_proto->getNumEventIns(); i++) {
4225 m_isEventIns[i] = NULL;
4226 EventIn *eventIn = m_proto->getEventIn(i);
4227 if (eventIn && eventIn->getFlags() & FF_IS)
4228 for (int j = 0; j < eventIn->getNumIs(); j++)
4229 if (eventIn->getFlags() & EIF_IS) {
4230 Node *isNode = eventIn->getIsNode(j);
4231 Proto *proto = isNode->getProto();
4232 int evIn = eventIn->getIsField(j);
4233 m_isEventIns[i] = new EventIn(eventIn);
4234 isNode->addIsElement((Node *)this, i, EL_EVENT_IN,
4235 proto, evIn, EIF_IS_HIDDEN);
4236 }
4237 }
4238 }
4239
4240 Node *
getIsNode(int nodeIndex)4241 NodeData::getIsNode(int nodeIndex)
4242 {
4243 NodePROTO *nodeProto = (NodePROTO *)this;
4244 if (nodeIndex < 0)
4245 return NULL;
4246 Node *nodeInPROTO = nodeProto->getIsNode(nodeIndex);
4247 if (nodeInPROTO)
4248 return nodeInPROTO;
4249 return NULL;
4250 }
4251
4252 bool
isDefault(int field) const4253 NodeData::isDefault(int field) const
4254 {
4255 bool x3d = m_scene->isX3d();
4256
4257 if (getProto()->getField(field) == NULL)
4258 return false;
4259 if (m_fields[field] == NULL)
4260 return false;
4261 return m_fields[field]->equals(
4262 getProto()->getField(field)->getDefault(x3d));
4263 }
4264
4265 bool
isDefaultAngle(int field) const4266 NodeData::isDefaultAngle(int field) const
4267 {
4268 bool x3d = m_scene->isX3d();
4269 double angleUnit = m_scene->getUnitAngle();
4270 if (angleUnit == 0)
4271 angleUnit = 1;
4272 return m_fields[field]->equalsAngle(
4273 getProto()->getField(field)->getDefault(x3d), angleUnit);
4274 }
4275
4276 bool
hasInputsOrIs(void)4277 NodeData::hasInputsOrIs(void)
4278 {
4279 if (hasInputs())
4280 return true;
4281 for (int i = 0; i < m_proto->getNumFields(); i++) {
4282 Field *field = getProto()->getField(i);
4283 if (field->getFlags() & FF_HIDDEN)
4284 continue;
4285 if (isInsideProto() && getOutsideProto()->lookupIsField((Node *)this, i)
4286 != -1)
4287 return true;
4288 }
4289 return false;
4290 }
4291
4292 bool
hasInputsIs(void)4293 NodeData::hasInputsIs(void)
4294 {
4295 for (int i = 0; i < m_proto->getNumEventIns(); i++) {
4296 EventIn *eventIn = getProto()->getEventIn(i);
4297 if (eventIn == NULL)
4298 continue;
4299 if (eventIn->getFlags() & FF_HIDDEN)
4300 continue;
4301 if (isPROTO() && getProto()->lookupIsEventIn((Node *)this, i) != -1)
4302 return true;
4303 }
4304 return false;
4305 }
4306
4307 bool
hasOutputsOrIs(void)4308 NodeData::hasOutputsOrIs(void)
4309 {
4310 if (hasOutputs())
4311 return true;
4312 for (int i = 0; i < m_proto->getNumEventOuts(); i++)
4313 if (isInsideProto() && getOutsideProto()->lookupIsEventOut(
4314 (Node *)this, i)
4315 != -1)
4316 return true;
4317 for (int i = 0; i < m_proto->getNumExposedFields(); i++)
4318 if (isInsideProto() && getOutsideProto()->lookupIsExposedField(
4319 (Node *)this, i)
4320 != -1)
4321 return true;
4322 return false;
4323 }
4324
4325 bool
hasInputs(void)4326 NodeData::hasInputs(void)
4327 {
4328 for (int j = 0; j < m_proto->getNumEventIns(); j++)
4329 if (getInput(j).size() > 0)
4330 return true;
4331 return false;
4332 }
4333
4334 bool
hasOutputs(void)4335 NodeData::hasOutputs(void)
4336 {
4337 for (int j = 0; j < m_proto->getNumEventOuts(); j++)
4338 if (getOutput(j).size() > 0)
4339 return true;
4340 return false;
4341 }
4342
4343 bool
hasInput(const char * routename) const4344 NodeData::hasInput(const char* routename) const
4345 {
4346 bool x3d = m_scene->isX3d();
4347 for (int i = 0; i < m_proto->getNumEventIns(); i++)
4348 if (strcmp(m_proto->getEventIn(i)->getName(x3d), routename) == 0) {
4349 if (getInput(i).size() > 0)
4350 return true;
4351 else
4352 return false;
4353 }
4354 return false;
4355 }
4356
4357 bool
hasOutput(const char * routename) const4358 NodeData::hasOutput(const char* routename) const
4359 {
4360 bool x3d = m_scene->isX3d();
4361 for (int i = 0; i < m_proto->getNumEventOuts(); i++)
4362 if (strcmp(m_proto->getEventOut(i)->getName(x3d), routename) == 0) {
4363 if (getOutput(i).size() > 0)
4364 return true;
4365 else
4366 return false;
4367 }
4368 assert(0);
4369 return false;
4370 }
4371
4372 int
writeProtoArguments(int f) const4373 NodeData::writeProtoArguments(int f) const
4374 {
4375 int flags = m_scene->getWriteFlags() | WITHOUT_VALUE;
4376 for (int i = 0; i < m_proto->getNumFields(); i++) {
4377 if (m_scene->isInvalidElement(m_proto->getField(i)))
4378 continue;
4379 RET_ONERROR( m_proto->getField(i)->write(f, 1, flags) )
4380 TheApp->incSelectionLinenumber();
4381 }
4382 for (int i = 0; i < m_proto->getNumExposedFields(); i++) {
4383 if (m_scene->isInvalidElement(m_proto->getExposedField(i)))
4384 continue;
4385 RET_ONERROR( m_proto->getExposedField(i)->write(f, 1, flags) )
4386 TheApp->incSelectionLinenumber();
4387 }
4388 for (int i = 0; i < m_proto->getNumEventIns(); i++) {
4389 if (m_scene->isInvalidElement(m_proto->getEventIn(i)))
4390 continue;
4391 RET_ONERROR( m_proto->getEventIn(i)->write(f, 1, flags) )
4392 TheApp->incSelectionLinenumber();
4393 }
4394 for (int i = 0; i < m_proto->getNumEventOuts(); i++) {
4395 if (m_scene->isInvalidElement(m_proto->getEventOut(i)))
4396 continue;
4397 RET_ONERROR( m_proto->getEventOut(i)->write(f, 1, flags) )
4398 TheApp->incSelectionLinenumber();
4399 }
4400 return 0;
4401 }
4402
4403 bool
hasDefault(int flag)4404 NodeData::hasDefault(int flag)
4405 {
4406 bool x3d = m_scene->isX3d();
4407 for (int i = 0; i < m_numFields; i++) {
4408 Field *field = m_proto->getField(i);
4409 if (field->getFlags() & flag)
4410 if (!(m_fields[i]->equals(field->getDefault(x3d))))
4411 return false;
4412 }
4413 return true;
4414 }
4415
searchInputs(Node * node,void * data)4416 static bool searchInputs(Node *node, void *data)
4417 {
4418 bool *result = (bool *)data;
4419 if (node->hasInputs()) {
4420 *result = true;
4421 return false;
4422 }
4423 return true;
4424 }
4425
4426 bool
hasBranchInputs(void)4427 Node::hasBranchInputs(void)
4428 {
4429 bool result = false;
4430 doWithBranch(searchInputs, &result);
4431 return result;
4432 }
4433
removeConvertedNode(Node * node,void * data)4434 static bool removeConvertedNode(Node *node, void *data)
4435 {
4436 if (node != NULL) {
4437 node->removeRoutes();
4438 node->getScene()->removeNode(node);
4439 node->getScene()->undef(node->getName());
4440 node->getScene()->OnRemoveNode(node, NULL, -1);
4441 }
4442 return true;
4443 }
4444
4445
4446 void
deleteConvertedNodes(void)4447 NodeData::deleteConvertedNodes(void)
4448 {
4449 for (long i = 0; i < m_convertedNodes.size(); i++)
4450 m_convertedNodes[i]->doWithBranch(removeConvertedNode, NULL,
4451 false);
4452 m_convertedNodes.resize(0);
4453 }
4454
4455 bool
needExtraJavaClass(void)4456 NodeData::needExtraJavaClass(void)
4457 {
4458 if (m_convertedNodes.size() > 0)
4459 for (long i = 0; i < m_convertedNodes.size(); i++)
4460 if (m_convertedNodes[i]->needExtraJavaClass())
4461 return true;
4462 // if (hasName() || (m_scene->getRoot() == this))
4463 if ((m_scene->getRoot() == this))
4464 return false;
4465 return true;
4466 }
4467
4468 bool
writeJavaOutsideClass(int languageFlag)4469 NodeData::writeJavaOutsideClass(int languageFlag)
4470 {
4471 return ((languageFlag & MANY_JAVA_CLASSES) &&
4472 (languageFlag & OUTSIDE_JAVA_CLASS));
4473 }
4474
4475 void
generateTreeLabel(void)4476 NodeData::generateTreeLabel(void)
4477 {
4478 m_treeLabel = "";
4479 if (TheApp->is4Catt())
4480 if (isMesh()) {
4481 if (hasTwoSides()) {
4482 if (isDoubleSided())
4483 m_treeLabel += "(2 sides) ";
4484 else
4485 m_treeLabel += "(1 side) ";
4486 } else
4487 m_treeLabel += "(only 1 side) ";
4488 }
4489 m_treeLabel += getName();
4490 if (hasName())
4491 m_treeLabel += " ";
4492 const char *protoName = m_proto->getName(m_scene->isX3d());
4493 m_treeLabel += protoName;
4494 }
4495
4496 Node *
getParentOrProtoParent(void) const4497 Node::getParentOrProtoParent(void) const
4498 {
4499 Node *parent = getParent();
4500 if (parent == NULL)
4501 if (((NodeData *)this)->isInsideProto() && (m_nodePROTO != NULL))
4502 return m_nodePROTO->getParent();
4503 return parent;
4504 }
4505
4506 int
getParentFieldOrProtoParentField(void) const4507 Node::getParentFieldOrProtoParentField(void) const
4508 {
4509 Node *parent = getParent();
4510 if (parent == NULL)
4511 if (((NodeData *)this)->isInsideProto() && (m_nodePROTO != NULL))
4512 return m_nodePROTO->getParentField();
4513 return getParentField();
4514 }
4515
4516 int
getParentIndex(void) const4517 Node::getParentIndex(void) const
4518 {
4519 FieldValue *value = getParentFieldValue();
4520 if (value == NULL)
4521 return -1;
4522 if (value->getType() == MFNODE) {
4523 MFNode *mfValue = (MFNode *)value;
4524 for (int i = 0; i < mfValue->getSize(); i++) {
4525 Node *node = mfValue->getValue(i);
4526 if (node->isEqual((Node *)this))
4527 if (m_geometricParentIndex == node->getGeometricParentIndex())
4528 return i;
4529 }
4530 }
4531 return -1;
4532 }
4533
4534 Node *
searchParent(int nodeType) const4535 Node::searchParent(int nodeType) const
4536 {
4537 for (long i = 0; i < m_parents.size(); i++) {
4538 Node *node = m_parents[i].m_node;
4539 if (node->getType() == nodeType)
4540 return node;
4541 }
4542 return getParent();
4543 }
4544
4545 Node *
searchParentField(int parentField) const4546 Node::searchParentField(int parentField) const
4547 {
4548 for (long i = 0; i < m_parents.size(); i++) {
4549 if (m_parents[i].m_field == parentField)
4550 return m_parents[i].m_node;
4551 }
4552 return getParent();
4553 }
4554
4555 FieldValue *
getParentFieldValue(void) const4556 Node::getParentFieldValue(void) const
4557 {
4558 if (!hasParent())
4559 return NULL;
4560 Node *parent = getParent();
4561 int parentField = getParentField();
4562 return parentField == -1 ? NULL : parent->getField(parentField);
4563 }
4564
4565 void
setParentFieldValue(FieldValue * value)4566 Node::setParentFieldValue(FieldValue *value)
4567 {
4568 if (!hasParent())
4569 return;
4570 Node *parent = getParent();
4571 int parentField = getParentField();
4572 if (parentField > -1)
4573 parent->setField(parentField, value);
4574 }
4575
4576 int
getSiblingIndex(void)4577 Node::getSiblingIndex(void)
4578 {
4579 int parentIndex = getParentIndex();
4580 if (parentIndex > -1)
4581 return parentIndex;
4582 return -1;
4583 }
4584
4585 int
getPrevSiblingIndex(void)4586 Node::getPrevSiblingIndex(void)
4587 {
4588 int parentIndex = getParentIndex();
4589 if (parentIndex > 0)
4590 return parentIndex - 1;
4591 return -1;
4592 }
4593
4594 int
getNextSiblingIndex(void)4595 Node::getNextSiblingIndex(void)
4596 {
4597 FieldValue *value = getParentFieldValue();
4598 if (value == NULL)
4599 return -1;
4600 if (value->getType() == MFNODE) {
4601 MFNode *mfValue = (MFNode *)value;
4602 for (int i = 0; i < mfValue->getSize() - 1; i++) {
4603 Node *node = mfValue->getValue(i);
4604 if (node->isEqual((Node *)this))
4605 if (m_geometricParentIndex == node->getGeometricParentIndex())
4606 return i + 1;
4607 }
4608 }
4609 return -1;
4610 }
4611
4612 Node *
getPrevSibling(void)4613 Node::getPrevSibling(void)
4614 {
4615 FieldValue *value = getParentFieldValue();
4616 if (value == NULL)
4617 return NULL;
4618 if (value->getType() == MFNODE) {
4619 MFNode *mfValue = (MFNode *)value;
4620 int parentIndex = getParentIndex();
4621 if (parentIndex > 0)
4622 return mfValue->getValue(parentIndex - 1);
4623 }
4624 return NULL;
4625 }
4626
4627 Node *
getNextSibling(void)4628 Node::getNextSibling(void)
4629 {
4630 FieldValue *value = getParentFieldValue();
4631 if (value == NULL)
4632 return NULL;
4633 if (value->getType() == MFNODE) {
4634 MFNode *mfValue = (MFNode *)value;
4635 for (int i = 0; i < mfValue->getSize() - 1; i++) {
4636 Node *node = mfValue->getValue(i);
4637 if (node->isEqual((Node *)this))
4638 if (m_geometricParentIndex == node->getGeometricParentIndex())
4639 return mfValue->getValue(i + 1);
4640 }
4641 }
4642 return NULL;
4643 }
4644
4645 void
setDefault(void)4646 NodeData::setDefault(void)
4647 {
4648 bool x3d = m_scene->isX3d();
4649 for (int i = 0; i < m_numFields; i++) {
4650 Field *field = m_proto->getField(i);
4651 if ((field->getType() != SFNODE) && (field->getType() != MFNODE))
4652 m_scene->setField((Node *)this, i, field->getDefault(x3d)->copy());
4653 }
4654 }
4655
4656 void
setNodePROTO(NodePROTO * node)4657 Node::setNodePROTO(NodePROTO *node)
4658 {
4659 m_nodePROTO = node;
4660 m_insideProto = ((Node *)node)->getProto();
4661 setProtoParent(node);
4662 }
4663
4664
4665 bool
isDeepInsideProto(void)4666 Node::isDeepInsideProto(void)
4667 {
4668 if (m_insideProto)
4669 return true;
4670 if (isPROTO())
4671 return true;
4672 #ifdef HAVE_NULL_COMPARE
4673 if (this == NULL)
4674 return false;
4675 #endif
4676 Node *parent = this;
4677 if (hasParent())
4678 while (parent->hasParent()) {
4679 if (parent->isInsideProto())
4680 return true;
4681 parent = parent->getParent();
4682 }
4683 else
4684 return false;
4685 return false;
4686 }
4687
4688 char*
getExportMaterialName(const char * defaultName)4689 Node::getExportMaterialName(const char *defaultName)
4690 {
4691 Node *node = this;
4692 // search for DEF name till root of scenegraph
4693 while (1) {
4694 if (node->hasName()) {
4695 char *name = strdup(node->getName());
4696 if (TheApp->SkipMaterialNameBeforeFirstUnderscore()) {
4697 char *lastPartOfName = strchr(name, '_');
4698 if (lastPartOfName) {
4699 if (strlen(lastPartOfName + 1) > 0) {
4700 name = lastPartOfName + 1;
4701 } else if (defaultName != NULL) {
4702 return buildExportMaterialName(defaultName);
4703 }
4704 }
4705 }
4706 if (TheApp->SkipMaterialNameAfterLastUnderscore()) {
4707 char *endPointer = (char *)strrchr(name, '_');
4708 if (endPointer) {
4709 endPointer[0] = 0;
4710 if ((strlen(name) == 0) && (defaultName != NULL))
4711 return buildExportMaterialName(defaultName);
4712 }
4713 }
4714 return buildExportMaterialName(name);
4715 } else {
4716 if (node->hasParent())
4717 node = node->getParent();
4718 else {
4719 if (defaultName != NULL)
4720 return buildExportMaterialName(defaultName);
4721 }
4722 }
4723 }
4724 return buildExportMaterialName(defaultName);
4725 }
4726
4727
4728 Node *
convert2X3d(void)4729 NodeData::convert2X3d(void) {
4730 if (getFlag(NODE_FLAG_CONVERTED))
4731 return NULL;
4732 setFlag(NODE_FLAG_CONVERTED);
4733 for (int i = 0; i < m_numFields; i++)
4734 if (m_fields[i] != NULL) {
4735 if (m_fields[i]->getType() == SFNODE) {
4736 if (((SFNode *) m_fields[i])->getValue())
4737 ((SFNode *) m_fields[i])->getValue()->convert2X3d();
4738 } else if (m_fields[i]->getType() == MFNODE)
4739 ((MFNode *) m_fields[i])->convert2X3d();
4740 }
4741 return NULL;
4742 }
4743
4744 Node *
convert2Vrml(void)4745 NodeData::convert2Vrml(void) {
4746 if (getFlag(NODE_FLAG_CONVERTED))
4747 return NULL;
4748 setFlag(NODE_FLAG_CONVERTED);
4749 for (int i = 0; i < m_numFields; i++)
4750 if (m_fields[i] != NULL) {
4751 if (m_fields[i]->getType() == SFNODE) {
4752 if (((SFNode *) m_fields[i])->getValue())
4753 ((SFNode *) m_fields[i])->getValue()->convert2Vrml();
4754 } else if (m_fields[i]->getType() == MFNODE)
4755 ((MFNode *) m_fields[i])->convert2Vrml();
4756 }
4757 return NULL;
4758 }
4759
4760 bool
canWriteAc3d(void)4761 NodeData::canWriteAc3d(void)
4762 {
4763 for (int i = 0; i < m_numFields; i++)
4764 if (m_fields[i] != NULL) {
4765 if (m_fields[i]->getType() == SFNODE) {
4766 Node *node = ((SFNode *)m_fields[i])->getValue();
4767 if (node && (node != this)) // avoid simple cyclic scenegraph
4768 return node->canWriteAc3d();
4769 } else if (m_fields[i]->getType() == MFNODE) {
4770 MFNode *nodes = (MFNode *) m_fields[i];
4771 for (int j = 0; j < nodes->getSize(); j++) {
4772 Node *node = nodes->getValue(j);
4773 if (node && (node != this)) // avoid simple cyclic scenegraph
4774 if (node->canWriteAc3d())
4775 return true;
4776 }
4777 }
4778 }
4779 return false;
4780 }
4781
4782 int
writeAc3d(int f,int indent)4783 NodeData::writeAc3d(int f, int indent)
4784 {
4785 for (int i = 0; i < m_numFields; i++)
4786 if (m_fields[i] != NULL) {
4787 if (m_fields[i]->getType() == SFNODE)
4788 RET_ONERROR( ((SFNode *) m_fields[i])->writeAc3d(f, indent) )
4789 else if (m_fields[i]->getType() == MFNODE)
4790 RET_ONERROR( ((MFNode *) m_fields[i])->writeAc3d(f, indent) )
4791 }
4792 return 0;
4793 }
4794
4795 int
writeRib(int f,int indent)4796 NodeData::writeRib(int f, int indent)
4797 {
4798 for (int i = 0; i < m_numFields; i++)
4799 if (m_fields[i] != NULL) {
4800 if (m_fields[i]->getType() == SFNODE)
4801 RET_ONERROR( ((SFNode *) m_fields[i])->writeRib(f, indent) )
4802 else if (m_fields[i]->getType() == MFNODE)
4803 RET_ONERROR( ((MFNode *) m_fields[i])->writeRib(f, indent) )
4804 }
4805 return 0;
4806 }
4807
4808
4809 int
writePovray(int f,int indent)4810 NodeData::writePovray(int f, int indent)
4811 {
4812 for (int i = 0; i < m_numFields; i++)
4813 if (m_fields[i] != NULL) {
4814 if (m_fields[i]->getType() == SFNODE)
4815 RET_ONERROR( ((SFNode *) m_fields[i])->writePovray(f, indent) )
4816 else if (m_fields[i]->getType() == MFNODE)
4817 RET_ONERROR( ((MFNode *) m_fields[i])->writePovray(f, indent) )
4818 }
4819 return 0;
4820 }
4821
4822 void
handleAc3dMaterial(ac3dMaterialCallback callback,Scene * scene)4823 NodeData::handleAc3dMaterial(ac3dMaterialCallback callback, Scene* scene)
4824 {
4825 for (int i = 0; i < m_numFields; i++)
4826 if (m_fields[i] != NULL) {
4827 if (m_fields[i]->getType() == SFNODE) {
4828 SFNode *field = (SFNode *) m_fields[i];
4829 field->handleAc3dMaterial(callback, scene);
4830 } else if (m_fields[i]->getType() == MFNODE) {
4831 MFNode *field = (MFNode *) m_fields[i];
4832 field->handleAc3dMaterial(callback, scene);
4833 }
4834 }
4835 }
4836
4837 long
getId(void)4838 NodeData::getId(void)
4839 {
4840 return m_identifier;
4841 }
4842
4843 void
setId(long id)4844 NodeData::setId(long id)
4845 {
4846 m_identifier = id;
4847 }
4848
4849
4850 bool
isPROTO(void) const4851 NodeData::isPROTO(void) const
4852 {
4853 return false;
4854 }
4855
4856 bool
canWriteCattGeo(void)4857 Node::canWriteCattGeo(void)
4858 {
4859 for (int i = 0; i < m_numFields; i++)
4860 if (m_fields[i] != NULL) {
4861 if (m_fields[i]->getType() == SFNODE) {
4862 Node *node = ((SFNode *)m_fields[i])->getValue();
4863 if (node && (node != this)) // avoid simple cyclic scenegraph
4864 return node->canWriteCattGeo();
4865 } else if (m_fields[i]->getType() == MFNODE) {
4866 MFNode *nodes = (MFNode *) m_fields[i];
4867 for (int j = 0; j < nodes->getSize(); j++) {
4868 Node *node = nodes->getValue(j);
4869 if (node && (node != this)) // avoid simple cyclic scenegraph
4870 if (node->canWriteCattGeo())
4871 return true;
4872 }
4873 }
4874 }
4875 return false;
4876 }
4877
4878 int
writeCattGeo(int f,int indent)4879 Node::writeCattGeo(int f, int indent)
4880 {
4881 for (int i = 0; i < m_numFields; i++)
4882 if (m_fields[i] != NULL) {
4883 if (m_fields[i]->getType() == SFNODE)
4884 RET_ONERROR( ((SFNode *) m_fields[i])->writeCattGeo(f, indent) )
4885 else if (m_fields[i]->getType() == MFNODE)
4886 RET_ONERROR( ((MFNode *) m_fields[i])->writeCattGeo((Node *)this,
4887 f, indent) )
4888 }
4889 return 0;
4890 }
4891
4892 bool
canWriteLdrawDat(void)4893 NodeData::canWriteLdrawDat(void)
4894 {
4895 for (int i = 0; i < m_numFields; i++)
4896 if (m_fields[i] != NULL) {
4897 if (m_fields[i]->getType() == SFNODE) {
4898 Node *node = ((SFNode *)m_fields[i])->getValue();
4899 if (node && (node != this)) // avoid simple cyclic scenegraph
4900 return node->canWriteLdrawDat();
4901 } else if (m_fields[i]->getType() == MFNODE) {
4902 MFNode *nodes = (MFNode *) m_fields[i];
4903 for (int j = 0; j < nodes->getSize(); j++) {
4904 Node *node = nodes->getValue(j);
4905 if (node && (node != this)) // avoid simple cyclic scenegraph
4906 if (node->canWriteLdrawDat())
4907 return true;
4908 }
4909 }
4910 }
4911 return false;
4912 }
4913
4914 int
writeLdrawDat(int f,int indent)4915 NodeData::writeLdrawDat(int f, int indent)
4916 {
4917 for (int i = 0; i < m_numFields; i++)
4918 if (m_fields[i] != NULL) {
4919 if (m_fields[i]->getType() == SFNODE)
4920 RET_ONERROR( ((SFNode *) m_fields[i])->writeLdrawDat(f, indent) )
4921 else if (m_fields[i]->getType() == MFNODE)
4922 RET_ONERROR( ((MFNode *) m_fields[i])->writeLdrawDat(f, indent) )
4923 }
4924 return 0;
4925 }
4926
4927
4928 void
addToConvertedNodes(int writeFlags)4929 NodeData::addToConvertedNodes(int writeFlags)
4930 {
4931 if (m_alreadyConverted)
4932 return;
4933 // add to "m_convertedNodes"
4934 if (isMeshBasedNode())
4935 ((MeshBasedNode *)this)->addToConvertedNodes(writeFlags);
4936 m_alreadyConverted = true;
4937 }
4938
4939 NodeHAnimHumanoid *
getHumanoid()4940 Node::getHumanoid()
4941 {
4942 NodeHAnimHumanoid *human = NULL;
4943 Node *child = this;
4944 while (child && (child != m_scene->getRoot())) {
4945 if (child->getType() == X3D_HANIM_HUMANOID) {
4946 human = (NodeHAnimHumanoid *)child;
4947 break;
4948 }
4949 child = child->getParent();
4950 }
4951 return human;
4952 }
4953
4954 bool
showFields()4955 Node::showFields()
4956 {
4957 if (m_proto->showFields())
4958 return true;
4959 return m_proto->showFields(m_scene->isX3d());
4960 }
4961
4962 int
getContainerField(void)4963 Node::getContainerField(void)
4964 {
4965 return m_containerField;
4966 }
4967
4968 void
setContainerField(int containerField)4969 Node::setContainerField(int containerField)
4970 {
4971 m_containerField = containerField;
4972 }
4973
4974 NodeList
getParents(void)4975 Node::getParents(void)
4976 {
4977 NodeList ret;
4978 for (int i = 0; i < getNumParents(); i++)
4979 ret.append(getParent(i));
4980 return ret;
4981 }
4982
4983 Node *
getIndexedFaceSet(void)4984 Node::getIndexedFaceSet(void) {
4985 if (isMeshBasedNode())
4986 return ((MeshBasedNode *)this)->getIndexedFaceSet();
4987 return NULL;
4988 }
4989
4990 void
setAlreadyConverted(void)4991 Node::setAlreadyConverted(void)
4992 {
4993 if (isMeshBasedNode())
4994 ((MeshBasedNode *)this)->setAlreadyConverted();
4995 }
4996
4997 bool
isCWriteable()4998 Node::isCWriteable()
4999 {
5000 bool x3d = getScene()->isX3d();
5001 if (getProto()->isX3dInternalProto())
5002 return true;
5003 if (getScene()->belongsToNodeWithExternProto(getProto()->getName(x3d)) ||
5004 getType() == VRML_NURBS_SURFACE || getType() == VRML_NURBS_CURVE)
5005 return false;
5006 return true;
5007 }
5008
5009