Beispiel #1
0
void Branch::spawnSubBranches(const int level, const double length, const double thickness)
{
  if (level == recursiveDepth) return;

  // Spawn subbranches (make more as we get smaller)
  int numBranches = rand(0.2, 0.8, (level == 0 ? 2 : level) * initialBranches);
  for (int i = 0; i < numBranches; i++) {
    add_child(new Branch("SubBranch", level + 1,
                         nextThickness(thickness, level),
                         nextLength(length, level)));
    totalBranches++;
  }

  // Tree branches seem to split in two at the ends so simulate that.

  add_child(new Branch("SplitBranch", level + 1, nextThickness(thickness, level), 
                       nextLength(length, level), length, -30.0, 0.0));
  add_child(new Branch("SplitBranch", level + 1, nextThickness(thickness, level), 
                       nextLength(length, level), length, 30.0, 0.0));
  // Two branches coming out of the top looks a little weird so add a sphere.
  Sphere* p_sphere = new Sphere();
  GeometryNode* sphere = new GeometryNode("BranchTop", p_sphere);
  sphere->set_material(&wood);

  sphere->translate(Vector3D(0.0, 0.0, length));
  sphere->scale(Vector3D(thickness, thickness, thickness));

  add_child(sphere);

  totalBranches += 3;
}
Beispiel #2
0
void SceneGraph::recomputeBoundingBox() 
{
	Node	*node;
	float	center[3];
	float	size[3];

	BoundingBox bbox;

	for (node=getNodes(); node; node=node->nextTraversal()) {
		if (node->isGroupingNode()) {
			GroupingNode *gnode = (GroupingNode *)node;
			gnode->getBoundingBoxCenter(center);
			gnode->getBoundingBoxSize(size);
			bbox.addBoundingBox(center, size);
		}
		else if (node->isGeometryNode()) { 
			GeometryNode *gnode = (GeometryNode *)node; 
			gnode->getBoundingBoxCenter(center); 
			gnode->getBoundingBoxSize(size); 
			bbox.addBoundingBox(center, size); 
		} 
	}

	setBoundingBox(&bbox);
}
Beispiel #3
0
void GBufferPass::update_ubershader_from_scene(SerializedScene const& scene,
                                               SceneGraph const& graph) {
  bool ubershader_available = true;
  for (auto const& geometry_pair : scene.geometrynodes_) {
    ubershader_available =
        ubershader_available && ubershaders_.count(geometry_pair.first);
  }

  if (!ubershader_available) {
    auto get_ubershader = [&](Node * n) {
      GeometryNode* geode = dynamic_cast<GeometryNode*>(n);
      if (geode) {
        std::type_index type(typeid(*geode));
        if (!ubershaders_.count(type)) {
          auto const& ressource =
              GeometryDatabase::instance()->lookup(geode->get_filename());
          if (ressource) {
            auto ubershader = ressource->get_ubershader();
            ubershader->create(materials_);
            ubershaders_[type] = ubershader;
          }
        }
      }
    }
    ;
    gua::dfs_traverse(graph.get_root().get(), get_ubershader);
  }
}
void BallAndStick::process(const Molecule &molecule,
                           Rendering::GroupNode &node)
{
  // Add a sphere node to contain all of the spheres.
  GeometryNode *geometry = new GeometryNode;
  node.addChild(geometry);
  SphereGeometry *spheres = new SphereGeometry;
  spheres->identifier().molecule = &molecule;
  spheres->identifier().type = Rendering::AtomType;
  geometry->addDrawable(spheres);

  for (Index i = 0; i < molecule.atomCount(); ++i) {
    Core::Atom atom = molecule.atom(i);
    unsigned char atomicNumber = atom.atomicNumber();
    const unsigned char *c = Elements::color(atomicNumber);
    Vector3ub color(c[0], c[1], c[2]);
    spheres->addSphere(atom.position3d().cast<float>(), color,
                       static_cast<float>(Elements::radiusVDW(atomicNumber))
                       * 0.3f);
  }

  float bondRadius = 0.1f;
  CylinderGeometry *cylinders = new CylinderGeometry;
  cylinders->identifier().molecule = &molecule;
  cylinders->identifier().type = Rendering::BondType;
  geometry->addDrawable(cylinders);
  for (Index i = 0; i < molecule.bondCount(); ++i) {
    Core::Bond bond = molecule.bond(i);
    Vector3f pos1 = bond.atom1().position3d().cast<float>();
    Vector3f pos2 = bond.atom2().position3d().cast<float>();
    Vector3ub color1(Elements::color(bond.atom1().atomicNumber()));
    Vector3ub color2(Elements::color(bond.atom2().atomicNumber()));
    Vector3f bondVector = pos2 - pos1;
    float bondLength = bondVector.norm();
    bondVector /= bondLength;
    switch (bond.order()) {
    case 3: {
      Vector3f delta = bondVector.unitOrthogonal() * (2.0f * bondRadius);
      cylinders->addCylinder(pos1 + delta, bondVector, bondLength, bondRadius,
                             color1, color2, i);
      cylinders->addCylinder(pos1 - delta, bondVector, bondLength, bondRadius,
                             color1, color2, i);
    }
    default:
    case 1:
      cylinders->addCylinder(pos1, bondVector, bondLength, bondRadius,
                             color1, color2, i);
      break;
    case 2: {
      Vector3f delta = bondVector.unitOrthogonal() * bondRadius;
      cylinders->addCylinder(pos1 + delta, bondVector, bondLength, bondRadius,
                             color1, color2, i);
      cylinders->addCylinder(pos1 - delta, bondVector, bondLength, bondRadius,
                             color1, color2, i);
    }
    }
  }
}
		// ---|> NodeVisitor
		NodeVisitor::status enter(Node * node) override {
			GeometryNode * geometry = dynamic_cast<GeometryNode*>(node);
			if (geometry != nullptr) {
				currentTriangleCount += geometry->getTriangleCount();
				++currentNodeCount;
			}

			if (currentTriangleCount > maxTriangleCount || currentNodeCount > maxNodeCount) {
				return BREAK_TRAVERSAL;
			}
			return CONTINUE_TRAVERSAL;
		}
Beispiel #6
0
void Branch::createGeometryNode(const double length, const double thickness, const double upDist,
                                const double upAngle, const double zAngle)
{  
  Cylinder* c_branch= new Cylinder;
  GeometryNode* branch = new GeometryNode("TreeTrunk", c_branch);
  branch->set_material(&wood);

  this->rotate('z', zAngle);
  this->translate(Vector3D(0.0, 0.0, upDist));
  this->rotate('y', upAngle);
  branch->scale(Vector3D(thickness, thickness, length));

  add_child(branch);
}
Beispiel #7
0
int gr_node_set_bump_cmd(lua_State* L)
{
  GRLUA_DEBUG_CALL;
  
  gr_node_ud* selfdata = (gr_node_ud*)luaL_checkudata(L, 1, "gr.node");
  luaL_argcheck(L, selfdata != 0, 1, "Node expected");

  GeometryNode* self = dynamic_cast<GeometryNode*>(selfdata->node);

  luaL_argcheck(L, self != 0, 1, "Geometry node expected");
  const char* filename = luaL_checkstring(L, 2);
  self->set_bump(filename);
  return 0;
}
Beispiel #8
0
//Render meshes as they are traversed in the scene graph
void NMS_SceneRenderer::sg_before(Matrix transform, SceneGraphNode * node)
{
	GeometryNode * geomNode = (GeometryNode *) node;
	NMS_Mesh* model = geomNode->getModel();
	btRigidBody *b = geomNode->getCollisionBody();

	glLoadIdentity();
	Matrix t_transposed = ~transform;
	glMultMatrixf(t_transposed.getElements());
	if(b != NULL)
		applyPhysics(b);
	setWireframeModeGL(wireframe);
	(*model).setMaterialGL();
	(*model).render(currentTime);
}
Beispiel #9
0
int gr_node_set_texture_scale_cmd(lua_State* L)
{
  GRLUA_DEBUG_CALL;
  
  gr_node_ud* selfdata = (gr_node_ud*)luaL_checkudata(L, 1, "gr.node");
  luaL_argcheck(L, selfdata != 0, 1, "Node expected");

  GeometryNode* self = dynamic_cast<GeometryNode*>(selfdata->node);

  luaL_argcheck(L, self != 0, 1, "Geometry node expected");
  int scale_x = luaL_checknumber(L, 2);
  int scale_y = luaL_checknumber(L, 3);

  self->set_texture_scale(scale_x, scale_y);
  return 0;
}
Beispiel #10
0
Leaf::Leaf(const std::string& name, const double branchThickness, const double branchLength)
  : SceneNode(name)
{
  ImagePrimitive* i_leaf = new ImagePrimitive();
  GeometryNode* leaf = new GeometryNode("Leaf", i_leaf);
  leaf->set_material(&leafTexture);

  double upDist = rand(1.0/3.0, 1.0, branchLength);
  double zAngle = rand(0.0, 1.0, 360.0);

  double diagonalDist = branchThickness + sqrt(2.0) - 0.25;
  double xyDist = -diagonalDist * sqrt(2.0) / 2.0;

  leaf->rotate('z', zAngle); 
  leaf->translate(Vector3D(xyDist, xyDist, upDist));

  add_child(leaf);
}
Beispiel #11
0
int gr_node_set_refractionIndex_cmd(lua_State* L)
{
  GRLUA_DEBUG_CALL;
  
  gr_node_ud* selfdata = (gr_node_ud*)luaL_checkudata(L, 1, "gr.node");
  luaL_argcheck(L, selfdata != 0, 1, "Node expected");

  GeometryNode* self = dynamic_cast<GeometryNode*>(selfdata->node);
  luaL_argcheck(L, self != 0, 1, "Geometry node expected");

  double index = luaL_checknumber(L, 2);

  PhongMaterial * pM = (PhongMaterial*)self->get_material();
  if (pM == NULL) { std::cerr << "LUA:You are using a non-phong Material!" << std::endl; return 0; }
  pM->setRefractiveIndex(index);

  return 0;
}
Beispiel #12
0
void VanDerWaals::process(const Core::Molecule &molecule,
                          Rendering::GroupNode &node)
{
  // Add a sphere node to contain all of the VdW spheres.
  GeometryNode *geometry = new GeometryNode;
  node.addChild(geometry);
  SphereGeometry *spheres = new SphereGeometry;
  spheres->identifier().molecule = &molecule;
  spheres->identifier().type = Rendering::AtomType;
  geometry->addDrawable(spheres);

  for (size_t i = 0; i < molecule.atomCount(); ++i) {
    Core::Atom atom = molecule.atom(i);
    unsigned char atomicNumber = atom.atomicNumber();
    const unsigned char *c = Elements::color(atomicNumber);
    Vector3ub color(c[0], c[1], c[2]);
    spheres->addSphere(atom.position3d().cast<float>(), color,
                       static_cast<float>(Elements::radiusVDW(atomicNumber)));
  }
}
Beispiel #13
0
int gr_node_set_material_cmd(lua_State* L)
{
  GRLUA_DEBUG_CALL;
  
  gr_node_ud* selfdata = (gr_node_ud*)luaL_checkudata(L, 1, "gr.node");
  luaL_argcheck(L, selfdata != 0, 1, "Node expected");

  GeometryNode* self = dynamic_cast<GeometryNode*>(selfdata->node);

  luaL_argcheck(L, self != 0, 1, "Geometry node expected");
  
  gr_material_ud* matdata = (gr_material_ud*)luaL_checkudata(L, 2, "gr.material");
  luaL_argcheck(L, matdata != 0, 2, "Material expected");

  Material* material = matdata->material;

  self->set_material(material);

  return 0;
}
Beispiel #14
0
int gr_node_set_km_cmd(lua_State* L)
{
  GRLUA_DEBUG_CALL;
  
  gr_node_ud* selfdata = (gr_node_ud*)luaL_checkudata(L, 1, "gr.node");
  luaL_argcheck(L, selfdata != 0, 1, "Node expected");

  GeometryNode* self = dynamic_cast<GeometryNode*>(selfdata->node);
  luaL_argcheck(L, self != 0, 1, "Geometry node expected");

  double km[3];
  for (int i = 0; i < 3; i++) {
    km[i] = luaL_checknumber(L, i + 2);
  }

  PhongMaterial * pM = (PhongMaterial*)self->get_material();
  if (pM == NULL) { std::cerr << "LUA:You are using a non-phong Material!" << std::endl; return 0; }
  pM->setKM(Colour(km[0], km[1], km[2]));

  return 0;
}
Beispiel #15
0
int gr_node_set_bump_cmd(lua_State* L)
{
  GRLUA_DEBUG_CALL;
  
  gr_node_ud* selfdata = (gr_node_ud*)luaL_checkudata(L, 1, "gr.node");
  luaL_argcheck(L, selfdata != 0, 1, "Node expected");

  GeometryNode* self = dynamic_cast<GeometryNode*>(selfdata->node);

  luaL_argcheck(L, self != 0, 1, "Geometry node expected");
  
  const char* name = luaL_checkstring(L, 2);
  
  Image * bump = new Image();
  if (!bump->loadPng(name)) { std::cerr << "LUA:Loading PNG Failed!!" << std::endl; return -1; }
  
  self->apply_bump(bump);
  
  
  return 0;
}
int glwidgettest(int argc, char* argv[])
{
  // Set up the default format for our GL contexts.
  QSurfaceFormat defaultFormat = QSurfaceFormat::defaultFormat();
  defaultFormat.setSamples(4);
  QSurfaceFormat::setDefaultFormat(defaultFormat);

  QApplication app(argc, argv);
  GLWidget widget;
  widget.setGeometry(10, 10, 250, 250);
  widget.show();

  GeometryNode* geometry = new GeometryNode;
  SphereGeometry* spheres = new SphereGeometry;
  geometry->addDrawable(spheres);
  spheres->addSphere(Vector3f(0, 0, 0), Vector3ub(255, 0, 0), 0.5);
  spheres->addSphere(Vector3f(2, 0, 0), Vector3ub(0, 255, 0), 1.5);
  spheres->addSphere(Vector3f(0, 2, 1), Vector3ub(0, 0, 255), 1.0);
  widget.renderer().scene().rootNode().addChild(geometry);

  // Make sure the widget renders the scene, and store it in a QImage.
  widget.raise();
  widget.repaint();

  // Run the application for a while, and then quit so we can save an image.
  QTimer timer;
  timer.setSingleShot(true);
  app.connect(&timer, SIGNAL(timeout()), SLOT(quit()));
  timer.start(200);
  app.exec();

  // Grab the frame buffer of the GLWidget and save it to a QImage.
  QImage image = widget.grabFramebuffer();

  // Set up the image regression test.
  ImageRegressionTest test(argc, argv);

  // Do the image threshold test, printing output to the std::cout for ctest.
  return test.imageThresholdTest(image, std::cout);
}
Beispiel #17
0
static void describeGeometryNode(ExporterContext & /*ctxt*/,DescriptionMap & desc, Node * node) {
	desc.setString(Consts::ATTR_NODE_TYPE, Consts::NODE_TYPE_GEOMETRY);

	std::unique_ptr<DescriptionMap> dataDesc(new DescriptionMap);

	GeometryNode * gn = dynamic_cast<GeometryNode*>(node);

	// annotate with bounding box
	const Geometry::Box bb = gn->getBB();
	const Geometry::Vec3 center = bb.getCenter();
	std::stringstream s;
	s << center.getX() << " " << center.getY() << " " << center.getZ() << " " << bb.getExtentX() << " " << bb.getExtentY() << " " << bb.getExtentZ();
	dataDesc->setString(Consts::ATTR_MESH_BB, s.str());

	Rendering::Mesh * m = gn->getMesh();
	if(m!=nullptr) { // mesh present?
		// no filename -> store data in .minsg
		if(m->getFileName().empty()) {
			std::ostringstream meshStream;
			if(Rendering::Serialization::saveMesh(gn->getMesh(), "mmf", meshStream)) {
				dataDesc->setString(Consts::ATTR_DATA_TYPE,"mesh");
				dataDesc->setString(Consts::ATTR_DATA_ENCODING,"base64");
				const std::string streamString = meshStream.str();
				const std::string meshString = Util::encodeBase64(std::vector<uint8_t>(streamString.begin(), streamString.end()));
				dataDesc->setString(Consts::DATA_BLOCK,meshString);
			}
		} else { // filename given?
			Util::FileName meshFilename(m->getFileName());

//			// make path to mesh relative to scene (if mesh lies below the scene)
//			Util::FileUtils::makeRelativeIfPossible(ctxt.sceneFile, meshFilename);

			dataDesc->setString(Consts::ATTR_DATA_TYPE,"mesh");
			dataDesc->setString(Consts::ATTR_MESH_FILENAME,meshFilename.toShortString());
		}
		ExporterTools::addDataEntry(desc, std::move(dataDesc));
	}

}
  void QTAIMEngine::process(const Core::Molecule &coreMolecule,
                            Rendering::GroupNode &node)
  {
    const QtGui::Molecule *molecule =
        dynamic_cast<const QtGui::Molecule*>(&coreMolecule);
    if (!molecule)
      return;

    // Create sphere/cylinder nodes.
    GeometryNode *geometry = new GeometryNode;
    node.addChild(geometry);
    SphereGeometry *spheres = new SphereGeometry;
    geometry->addDrawable(spheres);
    CylinderGeometry *cylinders = new CylinderGeometry;
    geometry->addDrawable(cylinders);

    // Render the bond paths
    if(
        molecule->property("QTAIMFirstNCPIndexVariantList").isValid() &&
        molecule->property("QTAIMSecondNCPIndexVariantList").isValid() &&
        molecule->property("QTAIMLaplacianAtBondCriticalPoints").isValid() &&
        molecule->property("QTAIMEllipticityAtBondCriticalPoints").isValid() &&
        molecule->property("QTAIMBondPathSegmentStartIndex").isValid() &&
        molecule->property("QTAIMBondPathSegmentEndIndex").isValid() &&
        molecule->property("QTAIMXBondPaths").isValid() &&
        molecule->property("QTAIMYBondPaths").isValid() &&
        molecule->property("QTAIMZBondPaths").isValid()
        )
    {
      QVariant firstNCPIndexVariant=molecule->property("QTAIMFirstNCPIndexVariantList");
      QVariant secondNCPIndexVariant=molecule->property("QTAIMSecondNCPIndexVariantList");
      QVariant laplacianAtBondCriticalPointsVariant=molecule->property("QTAIMLaplacianAtBondCriticalPoints");
      QVariant ellipticityAtBondCriticalPointsVariant=molecule->property("QTAIMEllipticityAtBondCriticalPoints");
      QVariant bondPathSegmentStartIndexVariant=molecule->property("QTAIMBondPathSegmentStartIndex");
      QVariant bondPathSegmentEndIndexVariant=molecule->property("QTAIMBondPathSegmentEndIndex");
      QVariant xBondPathsVariant=molecule->property("QTAIMXBondPaths");
      QVariant yBondPathsVariant=molecule->property("QTAIMYBondPaths");
      QVariant zBondPathsVariant=molecule->property("QTAIMZBondPaths");

      QVariantList firstNCPIndexVariantList=firstNCPIndexVariant.toList();
      QVariantList secondNCPIndexVariantList=secondNCPIndexVariant.toList();
      QVariantList laplacianAtBondCriticalPointsVariantList=laplacianAtBondCriticalPointsVariant.toList();
      QVariantList ellipticityAtBondCriticalPointsVariantList=ellipticityAtBondCriticalPointsVariant.toList();
      QVariantList bondPathSegmentStartIndexVariantList=bondPathSegmentStartIndexVariant.toList();
      QVariantList bondPathSegmentEndIndexVariantList=bondPathSegmentEndIndexVariant.toList();
      QVariantList xBondPathsVariantList=xBondPathsVariant.toList();
      QVariantList yBondPathsVariantList=yBondPathsVariant.toList();
      QVariantList zBondPathsVariantList=zBondPathsVariant.toList();

      for( qint64 i=0 ;  i < firstNCPIndexVariantList.length() ; ++i )
      {

        qint64 start=bondPathSegmentStartIndexVariantList.at(i).toLongLong();
        qint64 end=bondPathSegmentEndIndexVariantList.at(i).toLongLong();

        if( laplacianAtBondCriticalPointsVariantList.at(i).toReal() > 0.0 )
        {

          const qint64 step=4;

          Vector3f xyz;
          Vector3ub color(255, 255, 255);
          for( qint64 j=start ; j < end-1 ; j=j+step )
          {
            xyz << xBondPathsVariantList.at(j).toFloat(),
                   yBondPathsVariantList.at(j).toFloat(),
                   zBondPathsVariantList.at(j).toFloat();
            spheres->addSphere(xyz, color, 0.025f);
          }
        }
        else
        {

          const qint64 step=1;

          Vector3ub color(255, 255, 255);
          double radius=0.025;

          Vector3f v1;
          Vector3f v2;
          Vector3f direction;
          for( qint64 j=start ; j < end-1 ; j=j+step )
          {

            v1 << xBondPathsVariantList.at(j).toFloat(),
                  yBondPathsVariantList.at(j).toFloat(),
                  zBondPathsVariantList.at(j).toFloat();
            v2 << xBondPathsVariantList.at(j+1).toFloat(),
                  yBondPathsVariantList.at(j+1).toFloat(),
                  zBondPathsVariantList.at(j+1).toFloat();

            direction = v2 - v1;
            float length = direction.norm();
            direction /= length;

            cylinders->addCylinder(v1, direction, length, radius, color);
          }
        }
      }  // bond path
    }

    if( molecule->property("QTAIMXNuclearCriticalPoints").isValid() &&
        molecule->property("QTAIMYNuclearCriticalPoints").isValid() &&
        molecule->property("QTAIMZNuclearCriticalPoints").isValid() )
    {
      QVariant xNuclearCriticalPointsVariant=molecule->property("QTAIMXNuclearCriticalPoints");
      QVariant yNuclearCriticalPointsVariant=molecule->property("QTAIMYNuclearCriticalPoints");
      QVariant zNuclearCriticalPointsVariant=molecule->property("QTAIMZNuclearCriticalPoints");
      QVariantList xNuclearCriticalPointsVariantList=xNuclearCriticalPointsVariant.toList();
      QVariantList yNuclearCriticalPointsVariantList=yNuclearCriticalPointsVariant.toList();
      QVariantList zNuclearCriticalPointsVariantList=zNuclearCriticalPointsVariant.toList();
      if( xNuclearCriticalPointsVariantList.length() == yNuclearCriticalPointsVariantList.length() &&
          xNuclearCriticalPointsVariantList.length() == zNuclearCriticalPointsVariantList.length() )
      {
        Vector3f xyz;
        Vector3ub color(255, 64, 255);
        for( qint64 i=0 ; i < xNuclearCriticalPointsVariantList.length() ; ++i )
        {
          xyz << xNuclearCriticalPointsVariantList.at(i).toFloat(),
                 yNuclearCriticalPointsVariantList.at(i).toFloat(),
                 zNuclearCriticalPointsVariantList.at(i).toFloat();

          // map->setFromPrimitive(ncp);

          spheres->addSphere(xyz, color, 0.1f);
        }
      }
    }


    if( molecule->property("QTAIMXBondCriticalPoints").isValid() &&
        molecule->property("QTAIMYBondCriticalPoints").isValid() &&
        molecule->property("QTAIMZBondCriticalPoints").isValid() )
    {
      QVariant xBondCriticalPointsVariant=molecule->property("QTAIMXBondCriticalPoints");
      QVariant yBondCriticalPointsVariant=molecule->property("QTAIMYBondCriticalPoints");
      QVariant zBondCriticalPointsVariant=molecule->property("QTAIMZBondCriticalPoints");
      QVariantList xBondCriticalPointsVariantList=xBondCriticalPointsVariant.toList();
      QVariantList yBondCriticalPointsVariantList=yBondCriticalPointsVariant.toList();
      QVariantList zBondCriticalPointsVariantList=zBondCriticalPointsVariant.toList();
      if( xBondCriticalPointsVariantList.length() == yBondCriticalPointsVariantList.length() &&
          xBondCriticalPointsVariantList.length() == zBondCriticalPointsVariantList.length() )
      {
        Vector3ub color(255, 255, 32);
        Vector3f xyz;
        for( qint64 i=0 ; i < xBondCriticalPointsVariantList.length() ; ++i )
        {
          xyz << xBondCriticalPointsVariantList.at(i).toFloat(),
                 yBondCriticalPointsVariantList.at(i).toFloat(),
                 zBondCriticalPointsVariantList.at(i).toFloat();

          // map->setFromPrimitive(ncp);

          spheres->addSphere(xyz, color, 0.1f);
        }
      }
    }

    if( molecule->property("QTAIMXElectronDensitySources").isValid() &&
        molecule->property("QTAIMYElectronDensitySources").isValid() &&
        molecule->property("QTAIMZElectronDensitySources").isValid() )
    {
      QVariant xElectronDensitySourcesVariant=molecule->property("QTAIMXElectronDensitySources");
      QVariant yElectronDensitySourcesVariant=molecule->property("QTAIMYElectronDensitySources");
      QVariant zElectronDensitySourcesVariant=molecule->property("QTAIMZElectronDensitySources");
      QVariantList xElectronDensitySourcesVariantList=xElectronDensitySourcesVariant.toList();
      QVariantList yElectronDensitySourcesVariantList=yElectronDensitySourcesVariant.toList();
      QVariantList zElectronDensitySourcesVariantList=zElectronDensitySourcesVariant.toList();
      if( xElectronDensitySourcesVariantList.length() == yElectronDensitySourcesVariantList.length() &&
          xElectronDensitySourcesVariantList.length() == zElectronDensitySourcesVariantList.length() )
      {
        Vector3ub color(64, 64, 255);
        Vector3f xyz;
        for( qint64 i=0 ; i < xElectronDensitySourcesVariantList.length() ; ++i )
        {
          xyz << xElectronDensitySourcesVariantList.at(i).toFloat(),
                 yElectronDensitySourcesVariantList.at(i).toFloat(),
                 zElectronDensitySourcesVariantList.at(i).toFloat();

          // map->setFromPrimitive(ncp);

          spheres->addSphere(xyz, color, 0.1f);
        }
      }
    }
  }
int qttextlabeltest(int argc, char *argv[])
{
  // Set up the default format for our GL contexts.
  QGLFormat defaultFormat = QGLFormat::defaultFormat();
  defaultFormat.setSampleBuffers(true);
  QGLFormat::setDefaultFormat(defaultFormat);

  // Create and show widget
  QApplication app(argc, argv);
  GLWidget widget;
  widget.setGeometry(10, 10, 500, 500);
  widget.show();

  // Create scene
  GeometryNode *geometry = new GeometryNode;
  widget.renderer().scene().rootNode().addChild(geometry);

  // Add a small sphere at the origin for reference:
  SphereGeometry *spheres = new SphereGeometry;
  spheres->addSphere(Vector3f::Zero(), Vector3ub(128, 128, 128), 0.1f);
  geometry->addDrawable(spheres);

  // Default text property:
  TextProperties tprop;

  // Test alignment:
  TextLabel3D *l3 = NULL;
  TextLabel2D *l2 = NULL;

  // 3D:
  tprop.setColorRgb(255, 0, 0);
  tprop.setAlign(TextProperties::HLeft, TextProperties::VTop);
  l3 = new TextLabel3D;
  l3->setText("Upper Left Anchor");
  l3->setAnchor(Vector3f::Zero());
  l3->setTextProperties(tprop);
  geometry->addDrawable(l3);

  tprop.setColorRgb(0, 255, 0);
  tprop.setAlign(TextProperties::HLeft, TextProperties::VBottom);
  l3 = new TextLabel3D;
  l3->setText("Bottom Left Anchor");
  l3->setAnchor(Vector3f::Zero());
  l3->setTextProperties(tprop);
  geometry->addDrawable(l3);

  tprop.setColorRgb(0, 0, 255);
  tprop.setAlign(TextProperties::HRight, TextProperties::VTop);
  l3 = new TextLabel3D;
  l3->setText("Upper Right Anchor");
  l3->setAnchor(Vector3f::Zero());
  l3->setTextProperties(tprop);
  geometry->addDrawable(l3);

  tprop.setColorRgb(255, 255, 0);
  tprop.setAlign(TextProperties::HRight, TextProperties::VBottom);
  l3 = new TextLabel3D;
  l3->setText("Bottom Right Anchor");
  l3->setAnchor(Vector3f::Zero());
  l3->setTextProperties(tprop);
  geometry->addDrawable(l3);

  tprop.setColorRgba(255, 255, 255, 220);
  tprop.setRotationDegreesCW(90.f);
  tprop.setAlign(TextProperties::HCenter, TextProperties::VCenter);
  l3 = new TextLabel3D;
  l3->setText("Centered Anchor (3D)");
  l3->setAnchor(Vector3f::Zero());
  l3->setTextProperties(tprop);
  l3->setRenderPass(Avogadro::Rendering::TranslucentPass);
  geometry->addDrawable(l3);
  tprop.setRotationDegreesCW(0.f);
  tprop.setAlpha(255);

  // 2D:
  tprop.setColorRgb(255, 0, 0);
  tprop.setAlign(TextProperties::HLeft, TextProperties::VTop);
  l2 = new TextLabel2D;
  l2->setText("Upper Left Corner");
  l2->setAnchor(Vector2i(0, widget.height()));
  l2->setTextProperties(tprop);
  geometry->addDrawable(l2);

  tprop.setColorRgb(0, 255, 0);
  tprop.setAlign(TextProperties::HLeft, TextProperties::VBottom);
  l2 = new TextLabel2D;
  l2->setText("Bottom Left Corner");
  l2->setAnchor(Vector2i(0, 0));
  l2->setTextProperties(tprop);
  geometry->addDrawable(l2);

  tprop.setColorRgb(0, 0, 255);
  tprop.setAlign(TextProperties::HRight, TextProperties::VTop);
  l2 = new TextLabel2D;
  l2->setText("Upper Right Corner");
  l2->setAnchor(Vector2i(widget.width(), widget.height()));
  l2->setTextProperties(tprop);
  geometry->addDrawable(l2);

  tprop.setColorRgb(255, 255, 0);
  tprop.setAlign(TextProperties::HRight, TextProperties::VBottom);
  l2 = new TextLabel2D;
  l2->setText("Bottom Right Corner");
  l2->setAnchor(Vector2i(widget.width(), 0));
  l2->setTextProperties(tprop);
  geometry->addDrawable(l2);

  tprop.setColorRgba(255, 255, 255, 220);
  tprop.setAlign(TextProperties::HCenter, TextProperties::VCenter);
  l2 = new TextLabel2D;
  l2->setText("Centered Anchor (2D)");
  l2->setAnchor(Vector2i(widget.width() / 2, widget.height() / 2));
  l2->setTextProperties(tprop);
  geometry->addDrawable(l2);

  // Test the TextLabel3D's radius feature:
  spheres->addSphere(Vector3f(0.f, 6.f, 0.f), Vector3ub(255, 255, 255), 1.f);

  tprop.setColorRgba(255, 128, 64, 255);
  tprop.setRotationDegreesCW(90.f);
  l3 = new TextLabel3D;
  l3->setText("Clipped");
  l3->setAnchor(Vector3f(0.f, 6.f, 0.f));
  l3->setTextProperties(tprop);
  geometry->addDrawable(l3);

  tprop.setColorRgba(64, 128, 255, 255);
  tprop.setRotationDegreesCW(45.f);
  l3 = new TextLabel3D;
  l3->setText("Projected");
  l3->setAnchor(Vector3f(0.f, 6.f, 0.f));
  l3->setTextProperties(tprop);
  l3->setRadius(1.f);
  geometry->addDrawable(l3);

  // Make sure the widget renders the scene, and store it in a QImage.
  widget.raise();
  widget.repaint();

  // Run the application for a while, and then quit so we can save an image.
  QTimer timer;
  timer.setSingleShot(true);
  app.connect(&timer, SIGNAL(timeout()), SLOT(quit()));
  timer.start(200);
  app.exec();

  // Grab the frame buffer of the GLWidget and save it to a QImage.
  QImage image = widget.grabFrameBuffer(false);

  // Set up the image regression test.
  ImageRegressionTest test(argc, argv);

  // Do the image threshold test, printing output to the std::cout for ctest.
  return test.imageThresholdTest(image, std::cout);
}