// // Vrml 97 library // Copyright (C) 1998 Chris Morley // // %W% %G% // VrmlNodeInline.cpp // #include "config.h" #include "VrmlNodeInline.h" #include #include "VrmlNamespace.h" #include "VrmlNodeType.h" #include "Doc.h" #include "MathUtils.h" #include "VrmlScene.h" static VrmlNode *creator( VrmlScene *scene ) { return new VrmlNodeInline(scene); } // Define the built in VrmlNodeType:: "Inline" fields VrmlNodeType *VrmlNodeInline::defineType(VrmlNodeType *t) { static VrmlNodeType *st = 0; if (! t) { if (st) return st; t = st = new VrmlNodeType("Inline", creator); } // Having Inline a subclass of Group is not right since // Groups have an exposedField "children" and eventIns // addChildren/deleteChildren that Inlines don't support... VrmlNodeGroup::defineType(t); // Parent class t->addExposedField("url", VrmlField::MFSTRING); return t; } VrmlNodeType *VrmlNodeInline::nodeType() const { return defineType(0); } VrmlNodeInline::VrmlNodeInline(VrmlScene *scene) : VrmlNodeGroup(scene), d_namespace(0), d_hasLoaded(false) { } VrmlNodeInline::~VrmlNodeInline() { delete d_namespace; } VrmlNode *VrmlNodeInline::cloneMe() const { return new VrmlNodeInline(*this); } VrmlNodeInline* VrmlNodeInline::toInline() const { return (VrmlNodeInline*) this; } // Inlines are loaded during addToScene traversal void VrmlNodeInline::addToScene(VrmlScene *s, const char *relativeUrl) { d_scene = s; load(relativeUrl); VrmlNodeGroup::addToScene(s, relativeUrl); } ostream& VrmlNodeInline::printFields(ostream& os, int indent) { if ( !FPZERO(d_bboxCenter.x()) || !FPZERO(d_bboxCenter.y()) || !FPZERO(d_bboxCenter.z()) ) PRINT_FIELD(bboxCenter); if ( !FPEQUAL(d_bboxSize.x(), -1) || !FPEQUAL(d_bboxSize.y(), -1) || !FPEQUAL(d_bboxSize.z(), -1) ) PRINT_FIELD(bboxCenter); if (d_url.get()) PRINT_FIELD(url); return os; } // Set the value of one of the node fields. void VrmlNodeInline::setField(const char *fieldName, const VrmlField &fieldValue) { if TRY_FIELD(url, MFString) else VrmlNodeGroup::setField(fieldName, fieldValue); } // Load the children from the URL void VrmlNodeInline::load(const char *relativeUrl) { // Already loaded? Need to check whether Url has been modified... if (d_hasLoaded) return; d_hasLoaded = true; // although perhaps not successfully if (d_url.size() > 0) { VrmlNamespace *ns = new VrmlNamespace(); VrmlMFNode *kids = 0; Doc url; int i, n = d_url.size(); for (i=0; idebug("Trying to read url '%s' (relative %s)\n", d_url.get(i), d_relative.get() ? d_relative.get() : ""); url.seturl( d_url.get(i), &relDoc ); kids = VrmlScene::readWrl( &url, ns ); if ( kids ) break; else if (i < n-1 && strncmp(d_url.get(i),"urn:",4)) theSystem->warn("Couldn't read url '%s': %s\n", d_url.get(i), strerror( errno)); } if ( kids ) { delete d_namespace; d_namespace = ns; d_relative.set(url.url()); // children will be relative to this url removeChildren(); addChildren( *kids ); // check for nested Inlines delete kids; } else { theSystem->warn("couldn't load Inline %s (relative %s)\n", d_url[0], d_relative.get() ? d_relative.get() : ""); delete ns; } } }