/*
* Copyright (C) 2008-2012 Thorsten Liebig (Thorsten.Liebig@gmx.de)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include "tinyxml.h"
#include "stdint.h"
#include "CSPrimPolyhedron.h"
#include "CSPrimPolyhedron_p.h"
#include "CSProperties.h"
#include "CSUseful.h"
void Polyhedron_Builder::operator()(HalfedgeDS &hds)
{
// Postcondition: `hds' is a valid polyhedral surface.
CGAL::Polyhedron_incremental_builder_3 B( hds, true);
B.begin_surface( m_polyhedron->m_Vertices.size(), m_polyhedron->m_Faces.size());
typedef HalfedgeDS::Vertex Vertex;
typedef Vertex::Point Point;
for (size_t n=0;nm_Vertices.size();++n)
B.add_vertex( Point( m_polyhedron->m_Vertices.at(n).coord[0], m_polyhedron->m_Vertices.at(n).coord[1], m_polyhedron->m_Vertices.at(n).coord[2]));
for (size_t f=0;fm_Faces.size();++f)
{
m_polyhedron->m_Faces.at(f).valid=false;
int *first = m_polyhedron->m_Faces.at(f).vertices, *beyond = first+m_polyhedron->m_Faces.at(f).numVertex;
if (B.test_facet(first, beyond))
{
B.add_facet(first, beyond);
if (B.error())
{
std::cerr << "Polyhedron_Builder::operator(): Error in polyhedron construction" << std::endl;
break;
}
m_polyhedron->m_Faces.at(f).valid=true;
}
else
{
std::cerr << "Polyhedron_Builder::operator(): Face " << f << ": Trying reverse order... ";
int help[m_polyhedron->m_Faces.at(f).numVertex];
for (unsigned int n=0;nm_Faces.at(f).numVertex;++n)
help[n]=m_polyhedron->m_Faces.at(f).vertices[m_polyhedron->m_Faces.at(f).numVertex-1-n];
first = help;
beyond = first+m_polyhedron->m_Faces.at(f).numVertex;
if (B.test_facet(first, beyond))
{
B.add_facet(first, beyond);
if (B.error())
{
std::cerr << "Polyhedron_Builder::operator(): Error in polyhedron construction" << std::endl;
break;
}
std::cerr << "success" << std::endl;
m_polyhedron->m_Faces.at(f).valid=true;
}
else
{
std::cerr << "failed" << std::endl;
++m_polyhedron->m_InvalidFaces;
}
}
}
B.end_surface();
}
/*********************CSPrimPolyhedron********************************************************************/
CSPrimPolyhedron::CSPrimPolyhedron(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(ID,paraSet,prop), d_ptr(new CSPrimPolyhedronPrivate)
{
Type = POLYHEDRON;
PrimTypeName = "Polyhedron";
d_ptr->m_PolyhedronTree = NULL;
m_InvalidFaces = 0;
}
CSPrimPolyhedron::CSPrimPolyhedron(CSPrimPolyhedron* primPolyhedron, CSProperties *prop) : CSPrimitives(primPolyhedron,prop), d_ptr(new CSPrimPolyhedronPrivate)
{
Type = POLYHEDRON;
PrimTypeName = "Polyhedron";
d_ptr->m_PolyhedronTree = NULL;
m_InvalidFaces = 0;
//copy all vertices
for (size_t n=0;nm_Vertices.size();++n)
AddVertex(primPolyhedron->m_Vertices.at(n).coord);
//copy all faces
for (size_t n=0;nm_Faces.size();++n)
AddFace(primPolyhedron->m_Faces.at(n).numVertex,primPolyhedron->m_Faces.at(n).vertices);
}
CSPrimPolyhedron::CSPrimPolyhedron(ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(paraSet,prop), d_ptr(new CSPrimPolyhedronPrivate)
{
Type = POLYHEDRON;
PrimTypeName = "Polyhedron";
d_ptr->m_PolyhedronTree = NULL;
m_InvalidFaces = 0;
}
CSPrimPolyhedron::~CSPrimPolyhedron()
{
Reset();
delete d_ptr;
}
void CSPrimPolyhedron::Reset()
{
m_Vertices.clear();
for (size_t n=0;nm_Polyhedron.clear();
d_ptr->m_PolyhedronTree = NULL;
m_InvalidFaces = 0;
}
void CSPrimPolyhedron::AddVertex(float px, float py, float pz)
{
vertex nv;
nv.coord[0]=px;nv.coord[1]=py;nv.coord[2]=pz;
m_Vertices.push_back(nv);
}
float* CSPrimPolyhedron::GetVertex(unsigned int n)
{
if (n vertices)
{
face f;
f.numVertex=vertices.size();
if (f.numVertex>3)
std::cerr << __func__ << ": Warning, faces other than triangles are currently not supported for discretization, expect false results!!!" << std::endl;
f.vertices=new int[f.numVertex];
for (unsigned int n=0;nm_Polyhedron.delegate(builder);
if (d_ptr->m_Polyhedron.is_closed())
m_Dimension = 3;
else
{
m_Dimension = 2;
//if structure is not closed due to invalud faces, mark it as 3D
if (m_InvalidFaces>0)
{
m_Dimension = 3;
std::cerr << "CSPrimPolyhedron::BuildTree: Warning, found polyhedron has invalud faces and is not a closed surface, setting to 3D solid anyway!" << std::endl;
}
}
//build tree
delete d_ptr->m_PolyhedronTree;
#if CGAL_VERSION_NR >= CGAL_VERSION_NUMBER(4,6,0)
d_ptr->m_PolyhedronTree = new CGAL::AABB_tree< Traits >(faces(d_ptr->m_Polyhedron).first,faces(d_ptr->m_Polyhedron).second,d_ptr->m_Polyhedron);
#else
d_ptr->m_PolyhedronTree = new CGAL::AABB_tree< Traits >(d_ptr->m_Polyhedron.facets_begin(),d_ptr->m_Polyhedron.facets_end());
#endif
//update local bounding box
GetBoundBox(m_BoundBox);
double p[3] = {m_BoundBox[1]*(1.0+(double)rand()/RAND_MAX),m_BoundBox[3]*(1.0+(double)rand()/RAND_MAX),m_BoundBox[5]*(1.0+(double)rand()/RAND_MAX)};
d_ptr->m_RandPt = Point(p[0],p[1],p[2]);
return true;
}
int* CSPrimPolyhedron::GetFace(unsigned int n, unsigned int &numVertices)
{
numVertices = 0;
if (nInvertTransform(pos,pos);
for (unsigned int n=0;n<3;++n)
{
if ((m_BoundBox[2*n]>pos[n]) || (m_BoundBox[2*n+1]m_RandPt);
// return true for an odd number of intersections
if ((d_ptr->m_PolyhedronTree->number_of_intersected_primitives(segment_query)%2)==1)
return true;
return false;
}
bool CSPrimPolyhedron::Update(std::string *ErrStr)
{
BuildTree();
//update local bounding box
m_BoundBoxValid = GetBoundBox(m_BoundBox);
return CSPrimitives::Update(ErrStr);
}
bool CSPrimPolyhedron::Write2XML(TiXmlElement &elem, bool parameterised)
{
if (CSPrimitives::Write2XML(elem,parameterised)==false)
return false;
for (size_t n=0;n coords;
TiXmlElement* vertex = root.FirstChildElement("Vertex");
while (vertex)
{
coords.clear();
FN = vertex->FirstChild();
if (FN!=NULL)
{
Text = FN->ToText();
if (Text!=NULL)
coords = SplitString2Double(std::string(Text->Value()), ',');
else
return false;
if (coords.size()!=3)
return false;
AddVertex(coords.at(0),coords.at(1),coords.at(2));
}
else
return false;
vertex = vertex->NextSiblingElement("Vertex");
}
// read faces
std::vector vertices;
TiXmlElement* face = root.FirstChildElement("Face");
while (face)
{
coords.clear();
FN = face->FirstChild();
if (FN!=NULL)
{
Text = FN->ToText();
if (Text!=NULL)
vertices = SplitString2Int(std::string(Text->Value()), ',');
else
return false;
AddFace(vertices);
}
else
return false;
face = face->NextSiblingElement("Face");
}
return BuildTree();
}
void CSPrimPolyhedron::ShowPrimitiveStatus(std::ostream& stream)
{
CSPrimitives::ShowPrimitiveStatus(stream);
stream << " Number of Vertices: " << m_Vertices.size() << std::endl;
stream << " Number of Faces: " << m_Faces.size() << std::endl;
stream << " Number of invalid Faces: " << m_InvalidFaces << std::endl;
}