/*
 * Project: MoleCuilder
 * Description: creates and alters molecular systems
 * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
 *
 *
 *   This file is part of MoleCuilder.
 *
 *    MoleCuilder 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.
 *
 *    MoleCuilder 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 MoleCuilder.  If not, see .
 */
/*
 * GLMoleculeObject_shape.cpp
 *
 *  Created on: Aug 3, 2012
 *      Author: ankele
 */
// include config.h
#ifdef HAVE_CONFIG_H
#include 
#endif
#include "GLMoleculeObject_shape.hpp"
#include 
#include 
#include 
#include 
#include 
#include 
#include "CodePatterns/MemDebug.hpp"
#include "CodePatterns/Assert.hpp"
#include "CodePatterns/Log.hpp"
#include "Shapes/Shape.hpp"
#include "LinearAlgebra/Vector.hpp"
#include "LinkedCell/PointCloudAdaptor.hpp"
#include "LinkedCell/linkedcell.hpp"
#include "Tesselation/tesselation.hpp"
#include "Tesselation/BoundaryLineSet.hpp"
#include "Tesselation/BoundaryTriangleSet.hpp"
#include "Tesselation/CandidateForTesselation.hpp"
#include "Atom/TesselPoint.hpp"
typedef QGLSceneNode *MeshList[GLMoleculeObject::DETAILTYPES_MAX];
QGLSceneNode *createShapeMesh(Shape &shape, QObject *parent)
{
  // Create some points on our shape.
  std::vector points = shape.getHomogeneousPointsOnSurface(200);
  // Fill the points into a tesselate-able container.
  TesselPointSTLList Corners;
  for (int i=0;isetPosition(points[i]);
    Walker->setName(toString(i));
    Walker->setNr(i);
    Corners.push_back(Walker);
  }
  // Fill the points into a Qt geometry.
  QGeometryData geo;
  for(int i=0;i cloud(&Corners, "TesselPointSTLList");
  (*T)(cloud, 2);
  // Fill the tesselated triangles into the geometry.
  for (TriangleMap::const_iterator runner = T->TrianglesOnBoundary.begin(); runner != T->TrianglesOnBoundary.end(); runner++) {
    int v[3];
    for (int i=0; i<3; i++)
      v[i] = runner->second->endpoints[i]->node->getNr();
    // Sort the vertices so the triangle is clockwise (relative to the normal vector).
    Vector cross = points[v[1]] - points[v[0]];
    cross.VectorProduct(points[v[2]] - points[v[0]]);
    if (cross.ScalarProduct(shape.getNormal(points[v[0]]) + shape.getNormal(points[v[1]]) + shape.getNormal(points[v[2]])) > 0)
      geo.appendIndices(v[0], v[1], v[2]);
    else
      geo.appendIndices(v[0], v[2], v[1]);
  }
  // Build a mesh from the geometry.
  QGLBuilder builder;
  builder.addTriangles(geo);
  QGLSceneNode *mesh = builder.finalizedSceneNode();
  return mesh;
}
GLMoleculeObject_shape::GLMoleculeObject_shape(Shape &shape, QObject *parent) :
    GLMoleculeObject(createShapeMesh(shape, parent), parent),
    m_shape(shape)
{
  // Create the material.
  QGLMaterial *material = new QGLMaterial(NULL);
  material->setAmbientColor( QColor(50, 60, 100, 255) );
  material->setDiffuseColor( QColor(150, 160, 200, 180) );
  material->setSpecularColor( QColor(60, 60, 60) );
  material->setShininess( 128 );
  setMaterial(material);
  m_enabled = false;
}
GLMoleculeObject_shape::~GLMoleculeObject_shape()
{
}
void GLMoleculeObject_shape::enable(bool enabled)
{
  m_enabled = enabled;
}
void GLMoleculeObject_shape::draw(QGLPainter *painter, const QVector4D &cameraPlane)
{
  if (!m_enabled)
    return;
  painter->modelViewMatrix().push();
  painter->setColor(m_material->diffuseColor());
  painter->setFaceMaterial(QGL::AllFaces, m_material);
  // Draw the transparent cube.
  painter->setStandardEffect(QGL::LitMaterial);
  glCullFace(GL_BACK);
  glEnable(GL_CULL_FACE);
  glEnable(GL_BLEND);
  glDepthMask(0);
  glDisable(GL_DEPTH_TEST);
  m_mesh[0]->draw(painter);
  glEnable(GL_DEPTH_TEST);
  glDepthMask(1);
  glDisable(GL_BLEND);
  glDisable(GL_CULL_FACE);
  painter->modelViewMatrix().pop();
}