/* * 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 "CSPrimPolygon.h" #include "CSProperties.h" #include "CSUseful.h" CSPrimPolygon::CSPrimPolygon(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(ID,paraSet,prop) { Type=POLYGON; m_NormDir = 0; Elevation.SetParameterSet(paraSet); PrimTypeName = std::string("Polygon"); } CSPrimPolygon::CSPrimPolygon(CSPrimPolygon* primPolygon, CSProperties *prop) : CSPrimitives(primPolygon,prop) { Type=POLYGON; m_NormDir = primPolygon->m_NormDir; Elevation.Copy(&primPolygon->Elevation); PrimTypeName = std::string("Polygon"); } CSPrimPolygon::CSPrimPolygon(ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(paraSet,prop) { Type=POLYGON; m_NormDir = 0; Elevation.SetParameterSet(paraSet); PrimTypeName = std::string("Polygon"); } CSPrimPolygon::~CSPrimPolygon() { } void CSPrimPolygon::SetCoord(int index, double val) { if ((index>=0) && (index<(int)vCoords.size())) vCoords.at(index).SetValue(val); } void CSPrimPolygon::SetCoord(int index, const std::string val) { if ((index>=0) && (index<(int)vCoords.size())) vCoords.at(index).SetValue(val); } void CSPrimPolygon::AddCoord(double val) { vCoords.push_back(ParameterScalar(clParaSet,val)); } void CSPrimPolygon::AddCoord(const std::string val) { vCoords.push_back(ParameterScalar(clParaSet,val)); } void CSPrimPolygon::RemoveCoords(int /*index*/) { //not yet implemented } double CSPrimPolygon::GetCoord(int index) { if ((index>=0) && (index<(int)vCoords.size())) return vCoords.at(index).GetValue(); return 0; } ParameterScalar* CSPrimPolygon::GetCoordPS(int index) { if ((index>=0) && (index<(int)vCoords.size())) return &vCoords.at(index); return NULL; } double* CSPrimPolygon::GetAllCoords(size_t &Qty, double* array) { Qty=vCoords.size(); delete[] array; array = new double[Qty]; for (size_t i=0;ixmax) xmax=x; if (yymax) ymax=y; } int nP = (m_NormDir+1)%3; int nPP = (m_NormDir+2)%3; dBoundBox[2*m_NormDir] = dBoundBox[2*m_NormDir+1] = Elevation.GetValue(); dBoundBox[2*nP] = xmin; dBoundBox[2*nP+1] = xmax; dBoundBox[2*nPP] = ymin; dBoundBox[2*nPP+1] = ymax; m_Dimension=0; for (int n=0;n<3;++n) { if (dBoundBox[2*n]!=dBoundBox[2*n+1]) ++m_Dimension; } return accurate; } bool CSPrimPolygon::IsInside(const double* inCoord, double /*tol*/) { if (inCoord==NULL) return false; if (vCoords.size()<2) return false; double Coord[3]; //transform incoming coordinates into cartesian coords TransformCoordSystem(inCoord,Coord,m_MeshType,CARTESIAN); if (m_Transform && Type==POLYGON) TransformCoords(Coord,true, CARTESIAN); for (unsigned int n=0;n<3;++n) if ((m_BoundBox[2*n]>Coord[n]) || (m_BoundBox[2*n+1]= y ? true : false; bool endover; for (size_t i=0;iy2)) || ((y>y1) && (yx2)) || ((x>x1) && (x= y ? true : false; if (startover != endover) { if ((y2 - y)*(x2 - x1) <= (y2 - y1)*(x2 - x)) { if (endover) wn ++; } else { if (!endover) wn --; } } startover = endover; y1 = y2; x1 = x2; } // return true if polygon is inside the polygon if (wn != 0) return true; return false; } bool CSPrimPolygon::Update(std::string *ErrStr) { int EC=0; bool bOK=true; if (! ((m_PrimCoordSystem==CARTESIAN) || (m_PrimCoordSystem==UNDEFINED_CS && m_MeshType==CARTESIAN))) { std::cerr << "CSPrimPolygon::Update: Warning: CSPrimPolygon can not be defined in non Cartesian coordinate systems! Result may be unexpected..." << std::endl; ErrStr->append("Warning: CSPrimPolygon can not be defined in non Cartesian coordinate systems! Result may be unexpected...\n"); } for (size_t i=1;iappend(stream.str()); PSErrorCode2Msg(EC,ErrStr); } } EC=Elevation.Evaluate(); if (EC!=ParameterScalar::NO_ERROR) bOK=false; if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) { bOK=false; std::stringstream stream; stream << std::endl << "Error in Polygon Elevation (ID: " << uiID << "): "; ErrStr->append(stream.str()); PSErrorCode2Msg(EC,ErrStr); } //update local bounding box used to speedup IsInside() m_BoundBoxValid = GetBoundBox(m_BoundBox); return bOK; } bool CSPrimPolygon::Write2XML(TiXmlElement &elem, bool parameterised) { CSPrimitives::Write2XML(elem,parameterised); WriteTerm(Elevation,elem,"Elevation",parameterised); elem.SetAttribute("NormDir",m_NormDir); elem.SetAttribute("QtyVertices",(int)vCoords.size()/2); for (size_t i=0;iQueryIntAttribute("NormDir",&help)!=TIXML_SUCCESS) return false; m_NormDir=help; TiXmlElement *VT=root.FirstChildElement("Vertex"); if (vCoords.size()!=0) return false; int i=0; while (VT) { for (int n=0;n<2;++n) this->AddCoord(0.0); if (ReadTerm(vCoords.at(i*2),*VT,"X1")==false) return false; if (ReadTerm(vCoords.at(i*2+1),*VT,"X2")==false) return false; VT=VT->NextSiblingElement("Vertex"); ++i; }; return true; }