Logo Search packages:      
Sourcecode: whitedune version File versions  Download package

NodeNurbsSurface.cpp

/*
 * NodeNurbsSurface.cpp
 *
 * Copyright (C) 1999 Stephen F. White
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program (see the file "COPYING" for details); if 
 * not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
 * Cambridge, MA 02139, USA.
 */

#include <stdlib.h>
#include <stdio.h>

#ifndef _WIN32
# include "stdlib.h"
#endif

#include "stdafx.h"
#include "NodeNurbsSurface.h"
#include "Scene.h"
#include "FieldValue.h"
#include "SFInt32.h"
#include "Mesh.h"
#include "MFFloat.h"
#include "MFInt32.h"
#include "MFVec2f.h"
#include "MFVec3f.h"
#include "SFNode.h"
#include "SFBool.h"
#include "SFVec3f.h"
#include "Vec2f.h"
#include "Vec3f.h"
#include "RenderState.h"
#include "DuneApp.h"
#include "NodeCoordinate.h"
#include "NodeNormal.h"
#include "NodeTextureCoordinate.h"
#include "NodeIndexedFaceSet.h"
#include "NodeNurbsGroup.h"
#include "NurbsSurfaceDegreeElevate.h"
#include "Util.h"
#include "Field.h"
#include "ExposedField.h"

ProtoNurbsSurface::ProtoNurbsSurface(Scene *scene)
  : Proto(scene, "NurbsSurface")
{
    uDimension.set(
          addField(SFINT32, "uDimension", new SFInt32(0), new SFInt32(0)));
    vDimension.set(
          addField(SFINT32, "vDimension", new SFInt32(0), new SFInt32(0)));
    uKnot.set(
          addField(MFFLOAT, "uKnot", new MFFloat()));
    vKnot.set(
          addField(MFFLOAT, "vKnot", new MFFloat()));
    uOrder.set(
          addField(SFINT32, "uOrder", new SFInt32(3), new SFInt32(2)));
    vOrder.set(
          addField(SFINT32, "vOrder", new SFInt32(3), new SFInt32(2)));

    ExposedField* cpoint = new ExposedField(MFVEC3F, "controlPoint", 
                                            new MFVec3f());
    cpoint->setFlags(EIF_RECOMMENDED);
    controlPoint.set(addExposedField(cpoint));

    weight.set(
          addExposedField(MFFLOAT, "weight", new MFFloat(), new SFFloat(0.0f)));
    uTessellation.set(
          addExposedField(SFINT32, "uTessellation", new SFInt32(0)));
    vTessellation.set(
          addExposedField(SFINT32, "vTessellation", new SFInt32(0)));
    texCoord.set(
          addExposedField(SFNODE, "texCoord", new SFNode(NULL), 
                          NURBS_TEXTURE_SURFACE_NODE | 
                          TEXTURE_COORDINATE_NODE));
    ccw.set(
          addField(SFBOOL, "ccw", new SFBool(true)));
    solid.set(
          addField(SFBOOL, "solid", new SFBool(true)));
}

Node *
ProtoNurbsSurface::create(Scene *scene)
{
    return new NodeNurbsSurface(scene, this); 
}

NodeNurbsSurface::NodeNurbsSurface(Scene *scene, Proto *proto)
  : MeshBasedNode(scene, proto)
{
}

NodeNurbsSurface::~NodeNurbsSurface()
{
    delete _mesh;
}

void
NodeNurbsSurface::createMesh()
{
    int           iuDimension = uDimension()->getValue();
    int           ivDimension = vDimension()->getValue();
    int           iuTess = uTessellation()->getValue();
    int           ivTess = vTessellation()->getValue();
    bool    bccw = ccw()->getValue();
    float      *weights = NULL;
    int           i, j;

    if (iuDimension == 0 || ivDimension == 0) return;

    if (uKnot()->getSize() != uOrder()->getValue() + iuDimension
     || vKnot()->getSize() != vOrder()->getValue() + ivDimension)
      return;

    if (controlPoint()->getSize() != iuDimension * ivDimension * 3)
      return;

    if (weight()->getSize() == 0) {
      weights = new float[iuDimension * ivDimension];
      for (i = 0; i < iuDimension * ivDimension; i++) {
          weights[i] = 1.0f;
      }
    } else if (weight()->getSize() != iuDimension * ivDimension) {
      return;
    }

    MFVec2f *texCoords = NULL;
    if (texCoord()->getValue()) 
        if (texCoord()->getValue()->getType() == NODE_TEXTURE_COORDINATE)
          texCoords = ((NodeTextureCoordinate *)(texCoord()->getValue()))
                         ->point();

    if (iuTess <= 0) iuTess = 32;
    if (ivTess <= 0) ivTess = 32;
    int           size = (iuTess + 1) * (ivTess + 1);
    Vec3f      *tess = new Vec3f[size];
    Vec3f      *normals = new Vec3f[size];

    const float   *uKnots = uKnot()->getValues();
    const float *vKnots = vKnot()->getValues();
    float   uInc = (uKnots[uKnot()->getSize()-1] - uKnots[0]) / iuTess;
    float   vInc = (vKnots[vKnot()->getSize()-1] - vKnots[0]) / ivTess;

    int           index = 0;
    float   u, v;
    const float *w = weights ? weights : weight()->getValues();
    for (j = 0, v = vKnots[0]; j <= ivTess; j++, v += vInc) {
      for (i = 0, u = uKnots[0]; i <= iuTess; i++, u += uInc) {
          tess[index] = surfacePoint(
                                iuDimension, uOrder()->getValue(), uKnots,
                            ivDimension, vOrder()->getValue(), vKnots,
                            (const Vec3f *) controlPoint()->getValues(),
                        w, u, v, normals[index]);
          if (!ccw()->getValue()) normals[index] = -normals[index];
          index++;
      }
    }

    index = 0;
    Vec2f          *tc = new Vec2f[size];
    float         uinv = 1.0f / iuTess;
    float         vinv = 1.0f / ivTess;
    for (j = 0; j <= ivTess; j++) {
      for (i = 0; i <= iuTess; i++) {
          tc[index++] = Vec2f(i * uinv, j * vinv);
      }
    }
    int *ci = new int[size * 5];
    index = 0;
    for (j = 0; j < ivTess; j++) {
        for (i = 0; i < iuTess; i++) {
          ci[index++] = j * (iuTess+1) + i;
          ci[index++] = j * (iuTess+1) + (i+1);
          ci[index++] = (j+1) * (iuTess+1) + (i+1);
          ci[index++] = (j+1) * (iuTess+1) + i;
            ci[index++] = -1;
        }
    }

    index = cleanDoubleVertices(ci, tess, normals, index, ccw()->getValue());

    MFVec3f *vertices = new MFVec3f((float *) tess, size * 3);
    MFVec3f *normal = new MFVec3f((float *) normals, size * 3);
    MFInt32 *coordIndex = new MFInt32(ci, index);
    if (!texCoords) texCoords = new MFVec2f((float *) tc, size * 2);

    int meshFlags = 0;
    if (ccw()->getValue())
        meshFlags |= MESH_CCW;
    if (solid()->getValue())
        meshFlags |= MESH_SOLID;
    if (_mesh)
        delete _mesh;
    _mesh = new Mesh(vertices, coordIndex, normal, NULL,
                     NULL, NULL, texCoords, NULL, 0, meshFlags);
    delete [] weights;
}

void
NodeNurbsSurface::drawHandles()
{
    int           iuDimension = uDimension()->getValue();
    int           ivDimension = vDimension()->getValue();
    RenderState   state;

    if (controlPoint()->getSize() != iuDimension * ivDimension * 3)
      return;

    if (weight()->getSize() != iuDimension * ivDimension) {
      return;
    }

    glPushName(iuDimension * ivDimension + 1);
    glDisable(GL_LIGHTING);
    Util::myGlColor3f(1.0f, 1.0f, 1.0f);
    if (TheApp->GetHandleMeshAlways() || (_scene->getSelectedHandle() == -1)) {
        for (int i = 0; i < iuDimension; i++) {
            glBegin(GL_LINE_STRIP);
            for (int j = 0; j < ivDimension; j++) {
                const float *v = controlPoint()->getValue(i + j*iuDimension);
                float        w = weight()->getValue(i + j*iuDimension);
                glVertex3f(v[0] / w, v[1] / w, v[2] / w);
            }
            glEnd();
        }
        for (int j = 0; j < ivDimension; j++) {
            glBegin(GL_LINE_STRIP);
            for (int i = 0; i < iuDimension; i++) {
                const float *v = controlPoint()->getValue(i + j*iuDimension);
                float        w = weight()->getValue(i + j*iuDimension);
                glVertex3f(v[0] / w, v[1] / w, v[2] / w);
            }
            glEnd();
        }
    }
    state.startDrawHandles();
    for (int ci = 0; ci < iuDimension * ivDimension; ci++) {
      glLoadName(ci);
      state.drawHandle(
            Vec3f(controlPoint()->getValue(ci)) / weight()->getValue(ci));
    }
    state.endDrawHandles();
    glPopName();
    glEnable(GL_LIGHTING);
}

Vec3f
NodeNurbsSurface::getHandle(int handle, int *constraint,
                      int *field)
{
    *constraint = CONSTRAIN_NONE;
    *field = controlPoint_Index() ;

    if (handle >= 0 && handle < controlPoint()->getSize() / 3) {
        Vec3f ret((Vec3f)controlPoint()->getValue(handle)
                         / weight()->getValue(handle));
      return ret;
    } else {
      return Vec3f(0.0f, 0.0f, 0.0f);
    }
}

void
NodeNurbsSurface::setHandle(MFVec3f *value, int handle, float newWeight,
                            const Vec3f &newV, const Vec3f &oldV,
                            bool already_changed)
{
    bool        changed = false;
    MFVec3f *newValue = (MFVec3f *) value->copy();

    if (_scene->getXSymetricNurbsMode()) {
        float       epsilon = TheApp->GetEpsilon();
        int         numPoints = newValue->getSize() / 3;     
        for (int i = 0; i < numPoints; i++) {
            if (i != handle) {
                Vec3f vPoint = controlPoint()->getValue(i);
                float wPoint = weight()->getValue(i);
                float w = wPoint;
                if (wPoint != 0)
                   vPoint = vPoint / wPoint;
                if (newWeight != 0)
                   w = w / newWeight;
                if (   (fabs(vPoint.z - oldV.z) < epsilon) 
                    && (fabs(vPoint.y - oldV.y) < epsilon)) {
                    if (fabs(vPoint.x + oldV.x) < epsilon) {
                        changed = true;
                        if (fabs(oldV.x) < epsilon)
                            newValue->setValue(i * 3,   0);
                        else
                          newValue->setValue(i * 3,   - newV.x * w);
                      newValue->setValue(i * 3+1,   newV.y * w);
                      newValue->setValue(i * 3+2,   newV.z * w);
                    } else if (fabs(vPoint.x - oldV.x) < epsilon) {
                        changed = true;
                        if (fabs(oldV.x) < epsilon)
                          newValue->setValue(i * 3,   0);
                        else
                          newValue->setValue(i * 3,   newV.x * w);
                      newValue->setValue(i * 3+1, newV.y * w);
                      newValue->setValue(i * 3+2, newV.z * w);
                    }         
                }                 
            }
        }
    }
    if (already_changed)
        changed = true;

    if (changed) {
      _meshDirty = true;
      _scene->setField(this, controlPoint_Index(), newValue);
    }
}

void
NodeNurbsSurface::setHandle(float newWeight, 
                            const Vec3f &newV, const Vec3f &oldV)
{
    setHandle(controlPoint(), -1, newWeight, newV, oldV);
}

NodeNurbsGroup *
NodeNurbsSurface::findNurbsGroup()
{
    if (hasParent()) {
        Node* parent = getParent();
        if (parent->getType() == NODE_NURBS_GROUP) {
            return (NodeNurbsGroup *) parent;
        } else if (parent->getType() == NODE_SHAPE)
            if (parent->hasParent())
                if (parent->getParent()->getType() == NODE_NURBS_GROUP) {
                    return (NodeNurbsGroup *) parent->getParent();    
               } 
    }
    return NULL;
}

void
NodeNurbsSurface::setHandle(int handle, const Vec3f &v)
{
    MFVec3f    *newValue = new MFVec3f(*controlPoint());

    float       epsilon = TheApp->GetEpsilon();
    int         numPoints = controlPoint()->getSize() / 3;   
    if (handle >= 0 && handle < numPoints) {
        float w = weight()->getValue(handle);
        Vec3f oldV = controlPoint()->getValue(handle);
        if (w != 0)
            oldV = oldV / w;
        Vec3f newV = v * w;
        if (_scene->getXSymetricNurbsMode() && (fabs(oldV.x) < epsilon))
          newValue->setValue(handle * 3, 0);
        else
          newValue->setValue(handle * 3, newV.x);
      newValue->setValue(handle * 3+1, newV.y);
      newValue->setValue(handle * 3+2, newV.z);
        // set other handles for symetric modelling
        // which also snap handles at the same place
        setHandle(newValue, handle, w, newV, oldV, true);
        // search for NurbsGroup nodes and set handles
        if (_scene->getXSymetricNurbsMode()) {
            NodeNurbsGroup *nurbsGroup = findNurbsGroup();
            if (nurbsGroup)
               nurbsGroup->setHandle(this, w, newV, oldV);
        }
    }
}

void
NodeNurbsSurface::setField(int index, FieldValue *value)
{
    _meshDirty = true;
    Node::setField(index, value);
}

int
NodeNurbsSurface::findSpan(int dimension, int order, float u,
                     const float knots[])
{
    int           low, mid, high;
    int           n = dimension + order - 1;

    if (u >= knots[n]) {
      return n - order;
    }
    low = order - 1;    high = n - order + 1;

    mid = (low + high) / 2;

    int oldLow = low;
    int oldHigh = high;
    int oldMid = mid;
    while (u < knots[mid] || u >= knots[mid+1]) {
      if (u < knots[mid]) {
          high = mid;
      } else {
          low = mid;
      }
      mid = (low+high)/2;

        // emergency abort of loop, otherwise a endless loop can occure
        if ((low == oldLow) && (high == oldHigh) && (mid == oldMid))
            break;

        oldLow = low;
        oldHigh = high;
        oldMid = mid;
    }
    return mid;
}

void
NodeNurbsSurface::basisFuns(int span, float u, int order,
                      const float knots[], float basis[],
                      float deriv[])
{
    float      *left = (float *) malloc(order * sizeof(float));
    float      *right = (float *) malloc(order * sizeof(float));

    if ((left==NULL) || (right==NULL))
       return;
    basis[0] = 1.0f;
    for (int j = 1; j < order; j++) {
      left[j] = u - knots[span+1-j];
      right[j] = knots[span+j]-u;
      float saved = 0.0f, dsaved = 0.0f;
      for (int r = 0; r < j; r++) {
            if ((right[r+1] + left[j-r]) == 0)
                return;
          float temp = basis[r] / (right[r+1] + left[j-r]);
          basis[r] = saved + right[r+1] * temp;
          deriv[r] = dsaved - j * temp;
          saved = left[j-r] * temp;
          dsaved = j * temp;
      }
      basis[j] = saved;
      deriv[j] = dsaved;
    }
    free(left);
    free(right);
}

Vec3f
NodeNurbsSurface::surfacePoint(int uDimension, int uOrder,
                         const float uKnots[],
                         int vDimension, int vOrder,
                         const float vKnots[],
                         const Vec3f controlPoints[],
                         const float weight[], float u, float v,
                         Vec3f &normal)
{
    float      *uBasis = (float *) malloc(uOrder * sizeof(float));
    float      *vBasis = (float *) malloc(vOrder * sizeof(float));
    float      *uDeriv = (float *) malloc(uOrder * sizeof(float));
    float      *vDeriv = (float *) malloc(vOrder * sizeof(float));

    if ((uBasis==NULL) || (vBasis==NULL) || (uDeriv==NULL) || (vDeriv==NULL))
       return NULL;

    int           uSpan = findSpan(uDimension, uOrder, u, uKnots);
    int           vSpan = findSpan(vDimension, vOrder, v, vKnots);

    basisFuns(uSpan, u, uOrder, uKnots, uBasis, uDeriv);
    basisFuns(vSpan, v, vOrder, vKnots, vBasis, vDeriv);

    int           uBase = uSpan-uOrder+1;
    int           vBase = vSpan-vOrder+1;

    int           index = vBase*uDimension + uBase;
    Vec3f S(0.0f, 0.0f, 0.0f), du(0.0f, 0.0f, 0.0f), dv(0.0f, 0.0f, 0.0f);
    float w = 0.0f, duw = 0.0f, dvw = 0.0f;
    for (int j = 0; j < vOrder; j++) {
      for (int i = 0; i < uOrder; i++) {
          float   gain = uBasis[i] * vBasis[j];
          float   dugain = uDeriv[i] * vBasis[j];
          float   dvgain = uBasis[i] * vDeriv[j];
          S += controlPoints[index] * gain;
          w += weight[index] * gain;
          du += controlPoints[index] * dugain;
          dv += controlPoints[index] * dvgain;
          duw += weight[index] * dugain;
          dvw += weight[index] * dvgain;
          index++;
      }
      index += uDimension - uOrder;
    }
    S = S / w;
    Vec3f un = (du - S * duw) / w;
    Vec3f vn = (dv - S * dvw) / w;
    normal = un.cross(vn);
    normal.normalize();
    free(uBasis);
    free(vBasis);
    free(uDeriv);
    free(vDeriv);
    return S;
}

bool
NodeNurbsSurface::writeEXTERNPROTO(int f)
{
    RET_ONERROR( mywritestr(f ,"EXTERNPROTO NurbsSurface[\n") )    
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," field SFInt32 uDimension\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," field SFInt32 vDimension\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," field MFFloat uKnot\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," field MFFloat vKnot\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," field SFInt32 uOrder\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," field SFInt32 vOrder\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," exposedField MFVec3f controlPoint\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," exposedField MFFloat weight\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," exposedField SFInt32 uTessellation\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," exposedField SFInt32 vTessellation\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," exposedField SFNode texCoord\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," field SFBool ccw\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," field SFBool solid\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," ]\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ,"[\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," \"urn:web3d:vrml97:node:NurbsSurface\",\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," \"urn:inet:blaxxun.com:node:NurbsSurface\",\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ," \"urn:ParaGraph:NurbsSurface\",\n") )
    TheApp->incSelectionLinenumber();
#ifdef HAVE_VRML97_AMENDMENT1_PROTO_URL
    RET_ONERROR( mywritestr(f ," \"") )
    RET_ONERROR( mywritestr(f ,HAVE_VRML97_AMENDMENT1_PROTO_URL) )
    RET_ONERROR( mywritestr(f ,"/NurbsSurfacePROTO.wrl") )
    RET_ONERROR( mywritestr(f ,"\"\n") )
    TheApp->incSelectionLinenumber();
#else
    RET_ONERROR( mywritestr(f ," \"NurbsSurfacePROTO.wrl\",\n") )
    TheApp->incSelectionLinenumber();
#endif
    RET_ONERROR( mywritestr(f ," \"http://www.csv.ica.uni-stuttgart.de/vrml/dune/docs/vrml97Amendment1/NurbsSurfacePROTO.wrl\"\n") )
    TheApp->incSelectionLinenumber();
    RET_ONERROR( mywritestr(f ,"]\n") )
    TheApp->incSelectionLinenumber();
    return true;
}

   
int             
NodeNurbsSurface::write(int filedes, int indent) 
{
    if (_scene->isPureVRML97()) {
        Node * node = toIndexedFaceSet();
        RET_ONERROR( node->write(filedes, indent) )
        node->unref();
    } else
        RET_ONERROR( NodeData::write(filedes, indent) )
    return 0;
}

void
NodeNurbsSurface::rotate(SFRotation rot)
{
    int         numPoints = controlPoint()->getSize() / 3;

    for (int i = 0; i < numPoints; i++) {
        Vec3f vPoint = controlPoint()->getValue(i);
        vPoint = rot.getQuat() * vPoint;
        controlPoint()->setSFValue(i, new SFVec3f(vPoint));
    }        
}

void
NodeNurbsSurface::flip(int index)
{
    if (controlPoint())
        controlPoint()->flip(index);
    SFBool *bccw = new SFBool(!(ccw()->getValue()));
    ccw(bccw);
    _meshDirty = true;
    
}

Node*
NodeNurbsSurface::degreeElevate(int newUDegree, int newVDegree)
{
  
  //degree elevate a nurbs surface,
  
  if(newUDegree < ((uOrder()->getValue())-1)){
    return NULL;
  }
  if(newVDegree < ((vOrder()->getValue())-1)){
    return NULL;
  }
  
  NodeNurbsSurface *node = (NodeNurbsSurface *)
                         _scene->createNode("NurbsSurface");

  if((newUDegree >= ((uOrder()->getValue())-1)) && 
     (newVDegree >= ((vOrder()->getValue())-1))){
    
    //load old values
    int i;
    int tuDimension = uDimension()->getValue();
    int tvDimension = vDimension()->getValue();
    Vec3f *tPoints = new Vec3f[tuDimension * tvDimension];
    float *tWeights = new float[tuDimension * tvDimension];
    int tuOrder = uOrder()->getValue();
    int tvOrder = vOrder()->getValue();
    int uKnotSize = uKnot()->getSize();
    int vKnotSize = vKnot()->getSize();
    Array<float> tuKnots(uKnotSize);
    Array<float> tvKnots(vKnotSize);
    int tuDegree = tuOrder - 1;
    int tvDegree = tvOrder - 1;
    int tuUpDegree = newUDegree - tuDegree;
    int tvUpDegree = newVDegree - tvDegree;
    
    for (i=0; i<(tuDimension*tvDimension); i++){
      tPoints[i] = controlPoint()->getValue(i);
      tWeights[i] =weight()->getValue(i);
    }

    for (i=0; i<uKnotSize; i++){
      tuKnots[i] = uKnot()->getValue(i);
    }
    for (i=0; i<vKnotSize; i++){
      tvKnots[i] = vKnot()->getValue(i);
    }

    //elevate surface
    NurbsSurfaceDegreeElevate elevatedSurface(tPoints, tWeights, 
          tuKnots, tvKnots, tuDimension, tvDimension, tuDegree, tvDegree, 
          tuUpDegree, tvUpDegree);

    //load new node
    
    int newUDimension = elevatedSurface.getUDimension();
    int newVDimension = elevatedSurface.getVDimension();
    float *newControlPoints = new float[newUDimension * newVDimension *3];
    float *newWeights = new float[newUDimension * newVDimension];
    float *newUKnots = new float[elevatedSurface.getUKnotSize()];
    float *newVKnots = new float[elevatedSurface.getVKnotSize()];
    int newUOrder = newUDegree + 1;
    int newVOrder = newVDegree + 1;
    
    for(i=0; i<(newUDimension * newVDimension); i++){
      newControlPoints[(i*3)] = elevatedSurface.getControlPoints(i).x;
      newControlPoints[(i*3)+1] = elevatedSurface.getControlPoints(i).y;
      newControlPoints[(i*3)+2] = elevatedSurface.getControlPoints(i).z;
      newWeights[i] = elevatedSurface.getWeights(i);
    }
    for(i=0; i<(elevatedSurface.getUKnotSize()); i++){
      newUKnots[i] = elevatedSurface.getUKnots(i);
    }
    for(i=0; i<(elevatedSurface.getVKnotSize()); i++){
      newVKnots[i] = elevatedSurface.getVKnots(i);
    }

   
    node->setField(node->uDimension_Index(), new SFInt32(newUDimension));
    node->setField(node->vDimension_Index(), new SFInt32(newVDimension));
    node->uKnot(new MFFloat(newUKnots, newUDimension + newUOrder));
    node->vKnot(new MFFloat(newVKnots, newVDimension + newVOrder));
    node->setField(node->uOrder_Index(), new SFInt32(newUOrder));
    node->setField(node->vOrder_Index(), new SFInt32(newVOrder));
    node->controlPoint(new MFVec3f(newControlPoints, newUDimension * newVDimension * 3));
    node->weight(new MFFloat(newWeights, newUDimension * newVDimension));
    node->uTessellation(new SFInt32(uTessellation()->getValue()));
    node->vTessellation(new SFInt32(vTessellation()->getValue()));
    node->texCoord(new SFNode(texCoord()->getValue()));
    node->solid(new SFBool(solid()->getValue()));
    node->ccw(new SFBool(ccw()->getValue()));
    
    return node;
  }
  return NULL;
}

Generated by  Doxygen 1.6.0   Back to index