summaryrefslogtreecommitdiff
path: root/CSXCAD/src/CSPrimPolyhedron.cpp
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2016-07-05 18:02:38 +0200
committerRuben Undheim <ruben.undheim@gmail.com>2016-07-05 18:02:38 +0200
commitef962f6008f25ab7cbd4ca21bcc72b97a1e2d76f (patch)
tree8149bee93d1a3f91d4503bfb3853adac4af0a85e /CSXCAD/src/CSPrimPolyhedron.cpp
Imported Upstream version 0.0.34
Diffstat (limited to 'CSXCAD/src/CSPrimPolyhedron.cpp')
-rw-r--r--CSXCAD/src/CSPrimPolyhedron.cpp357
1 files changed, 357 insertions, 0 deletions
diff --git a/CSXCAD/src/CSPrimPolyhedron.cpp b/CSXCAD/src/CSPrimPolyhedron.cpp
new file mode 100644
index 0000000..7eac505
--- /dev/null
+++ b/CSXCAD/src/CSPrimPolyhedron.cpp
@@ -0,0 +1,357 @@
+/*
+* 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <sstream>
+#include <iostream>
+#include <limits>
+#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<HalfedgeDS> 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;n<m_polyhedron->m_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;f<m_polyhedron->m_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;n<m_polyhedron->m_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;n<primPolyhedron->m_Vertices.size();++n)
+ AddVertex(primPolyhedron->m_Vertices.at(n).coord);
+ //copy all faces
+ for (size_t n=0;n<primPolyhedron->m_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;n<m_Faces.size();++n)
+ {
+ delete[] m_Faces.at(n).vertices;
+ m_Faces.at(n).vertices=NULL;
+ }
+ m_Faces.clear();
+ d_ptr->m_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<m_Vertices.size())
+ return m_Vertices.at(n).coord;
+ return NULL;
+}
+
+void CSPrimPolyhedron::AddFace(face f)
+{
+ m_Faces.push_back(f);
+}
+
+void CSPrimPolyhedron::AddFace(int numVertex, int* vertices)
+{
+ face f;
+ f.numVertex=numVertex;
+ f.vertices=new int[numVertex];
+ for (int n=0;n<numVertex;++n)
+ f.vertices[n]=vertices[n];
+ m_Faces.push_back(f);
+}
+
+void CSPrimPolyhedron::AddFace(std::vector<int> 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;n<f.numVertex;++n)
+ f.vertices[n]=vertices.at(n);
+ m_Faces.push_back(f);
+}
+
+bool CSPrimPolyhedron::BuildTree()
+{
+ Polyhedron_Builder builder(this);
+ d_ptr->m_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 (n<m_Faces.size())
+ {
+ numVertices = m_Faces.at(n).numVertex;
+ return m_Faces.at(n).vertices;
+ }
+ return NULL;
+}
+
+bool CSPrimPolyhedron::GetBoundBox(double dBoundBox[6], bool PreserveOrientation)
+{
+ UNUSED(PreserveOrientation); //has no orientation or preserved anyways
+ m_BoundBox_CoordSys=CARTESIAN;
+
+ if (m_Vertices.size()==0)
+ return true;
+
+ dBoundBox[0]=dBoundBox[1]=m_Vertices.at(0).coord[0];
+ dBoundBox[2]=dBoundBox[3]=m_Vertices.at(0).coord[1];
+ dBoundBox[4]=dBoundBox[5]=m_Vertices.at(0).coord[2];
+
+ for (size_t n=0;n<m_Vertices.size();++n)
+ {
+ dBoundBox[0]=std::min(dBoundBox[0],(double)m_Vertices.at(n).coord[0]);
+ dBoundBox[2]=std::min(dBoundBox[2],(double)m_Vertices.at(n).coord[1]);
+ dBoundBox[4]=std::min(dBoundBox[4],(double)m_Vertices.at(n).coord[2]);
+ dBoundBox[1]=std::max(dBoundBox[1],(double)m_Vertices.at(n).coord[0]);
+ dBoundBox[3]=std::max(dBoundBox[3],(double)m_Vertices.at(n).coord[1]);
+ dBoundBox[5]=std::max(dBoundBox[5],(double)m_Vertices.at(n).coord[2]);
+ }
+ return true;
+}
+
+bool CSPrimPolyhedron::IsInside(const double* Coord, double /*tol*/)
+{
+ if (m_Dimension<3)
+ return false;
+
+ double pos[3];
+ //transform incoming coordinates into cartesian coords
+ TransformCoordSystem(Coord,pos,m_MeshType,CARTESIAN);
+ if (m_Transform)
+ m_Transform->InvertTransform(pos,pos);
+
+ for (unsigned int n=0;n<3;++n)
+ {
+ if ((m_BoundBox[2*n]>pos[n]) || (m_BoundBox[2*n+1]<pos[n])) return false;
+ }
+
+ Point p(pos[0], pos[1], pos[2]);
+ Segment segment_query(p,d_ptr->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)
+{
+ //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<m_Vertices.size();++n)
+ {
+ TiXmlElement vertex("Vertex");
+ TiXmlText text(CombineArray2String(m_Vertices.at(n).coord,3,','));
+ vertex.InsertEndChild(text);
+ elem.InsertEndChild(vertex);
+ }
+ for (size_t n=0;n<m_Faces.size();++n)
+ {
+ TiXmlElement face("Face");
+ TiXmlText text(CombineArray2String(m_Faces.at(n).vertices,m_Faces.at(n).numVertex,','));
+ face.InsertEndChild(text);
+ elem.InsertEndChild(face);
+ }
+ return true;
+}
+
+bool CSPrimPolyhedron::ReadFromXML(TiXmlNode &root)
+{
+ if (!CSPrimitives::ReadFromXML(root)) return false;
+ TiXmlNode* FN=NULL;
+ TiXmlText* Text=NULL;
+
+ // read vertices
+ std::vector<double> 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<int> 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;
+}