vvsystems

The VV Software Environment

The set of software provided in the vvsystems suite is a complete implementatation of the vertex-vertex data structure and algebra. The components are as follows:

A list of known bugs and programming issues can be found here.

Installation

The software has been prepared such that it should compile in Linux and Windows environments. Other environements are not supported, but may still work. Some notes for FreeBSD users have been made by Andrey Mirtchovski.

  1. Ensure that the environement varialble QTDIR refers to a Qt 3.x installation. The library should be accessible using the symbol -lqt. The OpenGL options need to be enabled when Qt is installed.
  2. GNU bison and flex must be in the path. The software has been tested using bison version 1.35 and flex 2.5.4. Other versions may or may not work (bison 1.75 is confirmed to not work).
  3. An OpenGL library must be available using the symbol -lGL, the OpenGL utility (GLU) library must be available as -lGLU.
  4. Check out or export the files from the CVS repository and follow the instructions that are in readme_lin.txt for a Linux environment and in readme_win.txt for Windows environments.

A brief tutorial

This tutorial shows a sample implementation of the Dyn-Levin-Gregory curve subdivision algorithm. A Linux environment is assumed.

  1. Create a file called program.vvp with the following contents. This is the program file that is compiled and run. The particular algorithm in this example is the Dyn-Gregory-Levin subdivision curve. The code is heavily commented to indicate what the individual code segments do.
    #include <util/point.hpp>        // A point class included with vvlib
    #include <algorithms/render.hpp> // A set of rendering algorithms
    
    // Our definition of the edge properties.  As these are
    //  not used in this example program, we have an empty
    //  declaration.
    edge {};
    
    // Our definition of the vertex properties.  Here we
    //  use a geomentric position and a function to tell the
    //  the rendering algorithm how each vertex is displayed.
    vertex {
      util::Point<double> pos;
      void glRender() {
        glVertex3dv(pos.c_data());
      }
    };
    
    // Our definition of the mesh properties.  As this algorithm
    //  does not require properties global to a mesh, the statement
    //  is left empty.
    mesh {};
    
    // A function that creates a new vertex between to existing ones.
    vertex insert(vertex p, vertex q) {
      vertex x;              // A vertex x is created.
      make {p, q} nb_of x;   // x is assigned a neighbourhood
      replace p with x in q; // q is modified to include x in place of p
      replace q with x in p; // p is modified to include x in place of q
      return x;
    }
    
    void dgl(mesh& S) {
      synchronise S;  // the old state of all vertices in S is recorded.
      mesh NV;
    
      forall v in S {     // iterate over the vertices in S
        forall p in `v {  // iterate over the old neighbours of v
          if (p < v) continue;
          vertex x = insert(p, v);
          x$pos = - 1.0/16.0 * `(nextto p in `v)$pos
                  + 9.0/16.0 * `v$pos
                  + 9.0/16.0 * `p$pos
                  - 1.0/16.0 * `(nextto v in `p)$pos; // set the position of x
          add x to NV;
        }
      }
      merge S with NV; // add the vertices in NV to S
    }
    
    mesh S;
    algorithms::DrawWireframe<vertex> draw_func;
    
    start {  // This is run when the program is loaded into the interpreter
      S.readXMLFile("model.vvm"); // load the model file
      forall v in S {  // check to see if we need to extend our viewing volume
        if (v$pos.x() > proxy.view_maxx) proxy.view_maxx = v$pos.x();
        if (v$pos.y() > proxy.view_maxy) proxy.view_maxy = v$pos.y();
        if (v$pos.z() > proxy.view_maxz) proxy.view_maxz = v$pos.z();
    
        if (v$pos.x() < proxy.view_minx) proxy.view_minx = v$pos.x();
        if (v$pos.y() < proxy.view_miny) proxy.view_miny = v$pos.y();
        if (v$pos.z() < proxy.view_minz) proxy.view_minz = v$pos.z();
      }
    }
    
    step { // this is the iterated part of the program
      dgl(S);
    }
    
    render_init {
      // Extra code that is run when the rendering context is created
      //  goes here.  Any OpenGL code is valid.
      glClearColor(1.0, 1.0, 1.0, 1.0);
      glColor3f(0.0, 0.0, 0.0);
    }
    
    render {
      // Code that is run when the rendering context is refreshed
      //  goes here.  Any OpenGL code is valid.  See the vvlib
      //  documentation for the Draw function.
      Draw(S, draw_func);
    }
            
  2. Create a file called model.vvm with the following contents. This is the model that is read by the program as input. Here, the model is a simple triangle. The format used is an XML specification, any property specified for mesh or v is matched and loaded into those specified in the program's vertex definition. The exception is the nb property; it should not be defined in the program but in the data file to declare the neighbourhood of each vertex.
    <mesh>
      <v pos="-1 0"      nb="2 1" />
      <v pos=" 1 0"      nb="0 2" />
      <v pos=" 0 1.7321" nb="1 0" />
    </mesh>
            
  3. Translate the program into valid C++ code.
    vvp2cpp program.vvm program.cpp
  4. Compile the code.
    g++ program.cpp -fPIC -I$(QTDIR)/include -I$(VVLIBDIR) -I$(VVSYSTEMSDIR) -shared -Wl,-soname,vvmodel.so -o vvmodel.so
  5. Run the program. The context menu provides the execution commands, see the vvinterpreter documentation for details.
    vvinterpreter vvmodel.so

Using the software?

Email me and I'll keep you up to date when the software is updated.


Colin Smith

Valid XHTML 1.1! Valid CSS!