/* * Copyright (C) 2008,2009,2010 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 "ContinuousStructure.h" #include "CSPrimPoint.h" #include "CSPrimBox.h" #include "CSPrimMultiBox.h" #include "CSPrimSphere.h" #include "CSPrimSphericalShell.h" #include "CSPrimCylinder.h" #include "CSPrimCylindricalShell.h" #include "CSPrimPolygon.h" #include "CSPrimLinPoly.h" #include "CSPrimRotPoly.h" #include "CSPrimPolyhedron.h" #include "CSPrimPolyhedronReader.h" #include "CSPrimCurve.h" #include "CSPrimWire.h" #include "CSPrimUserDefined.h" #include "CSPropUnknown.h" #include "CSPropMaterial.h" #include "CSPropDispersiveMaterial.h" #include "CSPropLorentzMaterial.h" #include "CSPropDebyeMaterial.h" #include "CSPropDiscMaterial.h" #include "CSPropLumpedElement.h" #include "CSPropMetal.h" #include "CSPropConductingSheet.h" #include "CSPropExcitation.h" #include "CSPropProbeBox.h" #include "CSPropDumpBox.h" #include "CSPropResBox.h" #include "tinyxml.h" /*********************ContinuousStructure********************************************************************/ ContinuousStructure::ContinuousStructure(void) { clParaSet = new ParameterSet(); //init datastructures... clear(); } ContinuousStructure::~ContinuousStructure(void) { clear(); delete clParaSet; clParaSet=NULL; } void ContinuousStructure::AddProperty(CSProperties* prop) { if (prop==NULL) return; prop->SetCoordInputType(m_MeshType); prop->Update(&ErrString); vProperties.push_back(prop); prop->SetUniqueID(UniqueIDCounter++); this->UpdateIDs(); } bool ContinuousStructure::ReplaceProperty(CSProperties* oldProp, CSProperties* newProp) { std::vector::iterator iter; for (iter=vProperties.begin();iterGetPrimitive(0); while (prim!=NULL) { newProp->AddPrimitive(prim); prim->SetProperty(newProp); prim=oldProp->GetPrimitive(0); } delete *iter; *iter=newProp; newProp->SetUniqueID(UniqueIDCounter++); return true; } } return false; } void ContinuousStructure::DeleteProperty(size_t index) { if (index>=vProperties.size()) return; std::vector::iterator iter=vProperties.begin(); delete vProperties.at(index); vProperties.erase(iter+index); this->UpdateIDs(); } void ContinuousStructure::DeleteProperty(CSProperties* prop) { std::vector::iterator iter; for (iter=vProperties.begin();iterUpdateIDs(); } int ContinuousStructure::GetIndex(CSProperties* prop) { if (prop==NULL) return -1; for (size_t i=0;iGetType() & type) ++count; return count; } std::vector ContinuousStructure::GetPropertyByType(CSProperties::PropertyType type) { std::vector found; for (size_t i=0;iGetType() & type) found.push_back(vProperties.at(i)); return found; } size_t ContinuousStructure::GetQtyPrimitives(CSProperties::PropertyType type) { size_t count = 0; for (size_t i=0;iGetType() & type) count+=vProperties.at(i)->GetQtyPrimitives(); return count; } bool sortPrimByPrio(CSPrimitives* a, CSPrimitives* b) { return a->GetPriority()GetPriority(); } std::vector ContinuousStructure::GetAllPrimitives(bool sorted, CSProperties::PropertyType type) { std::vector props = this->GetPropertyByType(type); std::vector vPrim; vPrim.reserve(GetQtyPrimitives(type)); for (size_t i=0;i prop_prims = props.at(i)->GetAllPrimitives(); vPrim.insert(vPrim.end(),prop_prims.begin(),prop_prims.end()); } if (sorted) sort(vPrim.rbegin(), vPrim.rend(), sortPrimByPrio); return vPrim; } CSProperties* ContinuousStructure::HasPrimitive(CSPrimitives* prim) { for (size_t i=0;iHasPrimitive(prim)) return vProperties.at(i); return NULL; } void ContinuousStructure::DeletePrimitive(CSPrimitives* prim) { // no special handling is necessary, deleted primitive will release itself from its owning property delete prim; } std::vector ContinuousStructure::GetPrimitivesByType(CSPrimitives::PrimitiveType type) { UNUSED(type); std::vector vPrim; std::cerr << __func__ << ": Error, not yet implemented!" << std::endl; return vPrim; } std::vector ContinuousStructure::GetPrimitivesByBoundBox(const double* boundbox, bool sorted, CSProperties::PropertyType type) { std::vector out_list; std::vector prims =this->GetAllPrimitives(sorted, type); for (size_t j=0;jIsInsideBox(boundbox)>=0) out_list.push_back(prims.at(j)); } return out_list; } bool ContinuousStructure::InsertEdges2Grid(int nu) { if (nu<0) return false; if (nu>2) return false; double box[6] = {0,0,0,0,0,0}; bool accBound=false; std::vector vPrimitives=GetAllPrimitives(); for (size_t i=0;iGetBoundBox(box); if (accBound) { clGrid.AddDiscLine(nu,box[2*nu]); clGrid.AddDiscLine(nu,box[2*nu+1]); } } clGrid.Sort(nu); return true; } CSPrimitives* ContinuousStructure::GetPrimitiveByID(unsigned int ID) { std::vector vPrimitives=GetAllPrimitives(); for (size_t i=0;iGetID()==ID) return vPrimitives.at(i); return NULL; } std::vector ContinuousStructure::GetPropertiesByName(std::string name) { std::vector vProp; for (size_t i=0;iGetName())==0) vProp.push_back(vProperties.at(i)); return vProp; } CSProperties* ContinuousStructure::GetProperty(size_t index) { if (indexGetType() & type)) { locPrim = vProperties.at(i)->CheckCoordInPrimitive(coord,locPrio,dDrawingTol); if (locPrim) { if (winProp==NULL) { winPrio=locPrio; winProp=vProperties.at(i); winPrim=locPrim; } else if (locPrio>winPrio) { winPrio=locPrio; winProp=vProperties.at(i); winPrim=locPrim; } } } } if ((markFoundAsUsed) && (winPrim)) winPrim->SetPrimitiveUsed(true); if (foundPrimitive) *foundPrimitive=winPrim; return winProp; } CSProperties** ContinuousStructure::GetPropertiesByCoordsPriority(const double* /*coords*/, CSProperties::PropertyType /*type*/, bool /*markFoundAsUsed*/) { std::cerr << "ContinuousStructure::GetPropertiesByCoordsPriority --> This methode has not been implemented yet!!! return NULL" << std::endl; return NULL; } CSProperties* ContinuousStructure::GetPropertyByCoordPriority(const double* coord, std::vector primList, bool markFoundAsUsed, CSPrimitives** foundPrimitive) { CSProperties* prop = NULL; // search in all given primitives if coordinate given is inside for (size_t i=0;iIsInside(coord)) { if (foundPrimitive) *foundPrimitive = primList.at(i); prop = primList.at(i)->GetProperty(); if (markFoundAsUsed) primList.at(i)->SetPrimitiveUsed(true); // break as soon as a primitive is found since it is expected that the vPrim vector is priority sorted! break; } return prop; } void ContinuousStructure::WarnUnusedPrimitves(std::ostream& stream, CSProperties::PropertyType type) { for (size_t i=0;iGetType() & type)) { vProperties.at(i)->WarnUnusedPrimitves(stream); } } } void ContinuousStructure::ShowPropertyStatus(std::ostream& stream, CSProperties::PropertyType type) { for (size_t i=0;iGetType() & type)) { stream << "-----------------------------------------" << std::endl; vProperties.at(i)->ShowPropertyStatus(stream); } } } void ContinuousStructure::SetCoordInputType(CoordinateSystem type) { m_MeshType = type; for (size_t i=0;iSetCoordInputType(type); } } bool ContinuousStructure::isGeometryValid() { if (GetQtyProperties()<=0) return false; if (GetQtyPrimitives()<=0) return false; if (clGrid.GetQtyLines(0)<=1) return false; if (clGrid.GetQtyLines(1)<=1) return false; if (clGrid.GetQtyLines(2)<=0) return false; std::vector vPrimitives=GetAllPrimitives(); for (size_t i=0;iUpdate()==false) return false; } int excit=0; for (size_t i=0;iUpdate()==false) return false; if (vProperties.at(i)->GetType()==CSProperties::EXCITATION) { if (vProperties.at(i)->GetQtyPrimitives()>0) ++excit; } } if (excit==0) return false; return true; } double* ContinuousStructure::GetObjectArea() { CSPrimitives* prim=NULL; bool AccBound; std::vector vPrimitives=GetAllPrimitives(); for (size_t i=0;iGetBoundBox(box); if (box!=NULL && AccBound) { if (i==0) for (int i=0;i<6;++i) ObjArea[i]=box[i]; else { for (int i=0;i<3;++i) { if (ObjArea[2*i]>box[2*i]) ObjArea[2*i]=box[2*i]; if (ObjArea[2*i+1]Update(&ErrString); std::vector vPrimitives=GetAllPrimitives(); for (size_t i=0;iUpdate(&ErrString); return std::string(ErrString); } void ContinuousStructure::clear() { UniqueIDCounter=0; dDrawingTol=0; maxID=0; m_BG_Mat.Reset(); for (unsigned int n=0;nclear(); clGrid.clear(); } bool ContinuousStructure::Write2XML(TiXmlNode* rootNode, bool parameterised, bool sparse) { if (rootNode==NULL) return false; TiXmlElement Struct("ContinuousStructure"); Struct.SetAttribute("CoordSystem",GetCoordInputType()); clGrid.Write2XML(Struct,false); m_BG_Mat.Write2XML(Struct, false); clParaSet->Write2XML(Struct); TiXmlElement Properties("Properties"); for (size_t i=0;iGetTypeXMLString().c_str()); vProperties.at(i)->Write2XML(PropElem,parameterised,sparse); Properties.InsertEndChild(PropElem); } Struct.InsertEndChild(Properties); rootNode->InsertEndChild(Struct); return true; } bool ContinuousStructure::Write2XML(const char* file, bool parameterised, bool sparse) { return this->Write2XML(std::string(file), parameterised, sparse); } bool ContinuousStructure::Write2XML(std::string file, bool parameterised, bool sparse) { TiXmlDocument doc(file); doc.InsertEndChild(TiXmlDeclaration("1.0","UTF-8","yes")); if (Write2XML(&doc,parameterised,sparse)==false) return false; doc.SaveFile(); return doc.SaveFile(); } const char* ContinuousStructure::ReadFromXML(TiXmlNode* rootNode) { clear(); TiXmlNode* root = rootNode->FirstChild("ContinuousStructure"); if (root==NULL) { ErrString.append("Error: No ContinuousStructure found!!!\n"); return ErrString.c_str();} TiXmlElement* rootElem = root->ToElement(); if (rootElem) { int CS_mesh = 0; if (rootElem->QueryIntAttribute("CoordSystem",&CS_mesh) == TIXML_SUCCESS) SetCoordInputType((CoordinateSystem)CS_mesh); } TiXmlNode* bg_node = root->FirstChild("BackgroundMaterial"); if (bg_node==NULL) m_BG_Mat.Reset(); //reset to default; else if (m_BG_Mat.ReadFromXML(*bg_node)==false) { ErrString.append("Error: BackgroundMaterial invalid!!!\n"); return ErrString.c_str(); } TiXmlNode* grid = root->FirstChild("RectilinearGrid"); if (grid==NULL) { ErrString.append("Error: No RectilinearGrid found!!!\n"); return ErrString.c_str();} if (clGrid.ReadFromXML(*grid)==false) { ErrString.append("Error: RectilinearGrid invalid!!!\n"); return ErrString.c_str();} TiXmlNode* paraSet = root->FirstChild("ParameterSet"); if (paraSet!=NULL) if (clParaSet->ReadFromXML(*paraSet)==false) { ErrString.append("Warning: ParameterSet reading failed!!!\n");} /***Properties***/ TiXmlNode* probs = root->FirstChild("Properties"); if (probs==NULL) { ErrString.append("Warning: Properties not found!!!\n"); return ErrString.c_str();} TiXmlElement* PropNode = probs->FirstChildElement(); CSProperties* newProp=NULL; while (PropNode!=NULL) { const char* cProp=PropNode->Value(); if (strcmp(cProp,"Unknown")==0) newProp = new CSPropUnknown(clParaSet); else if (strcmp(cProp,"Material")==0) newProp = new CSPropMaterial(clParaSet); else if (strcmp(cProp,"DiscMaterial")==0) newProp = new CSPropDiscMaterial(clParaSet); else if (strcmp(cProp,"LorentzMaterial")==0) newProp = new CSPropLorentzMaterial(clParaSet); else if (strcmp(cProp,"DebyeMaterial")==0) newProp = new CSPropDebyeMaterial(clParaSet); else if (strcmp(cProp,"LumpedElement")==0) newProp = new CSPropLumpedElement(clParaSet); else if (strcmp(cProp,"Metal")==0) newProp = new CSPropMetal(clParaSet); else if (strcmp(cProp,"ConductingSheet")==0) newProp = new CSPropConductingSheet(clParaSet); else if (strcmp(cProp,"Excitation")==0) newProp = new CSPropExcitation(clParaSet); else if (strcmp(cProp,"ProbeBox")==0) newProp = new CSPropProbeBox(clParaSet); else if (strcmp(cProp,"ChargeBox")==0) newProp = new CSPropProbeBox(clParaSet); //old version support else if (strcmp(cProp,"ResBox")==0) newProp = new CSPropResBox(clParaSet); else if (strcmp(cProp,"DumpBox")==0) newProp = new CSPropDumpBox(clParaSet); else { std::cerr << "ContinuousStructure::ReadFromXML: Property with type: " << cProp << " is unknown... " << std::endl; newProp=NULL; } if (newProp) { if (newProp->ReadFromXML(*PropNode)) { AddProperty(newProp); ReadPropertyPrimitives(PropNode,newProp); } else { delete newProp; newProp = new CSPropUnknown(clParaSet); if (newProp->ReadFromXML(*PropNode)) { AddProperty(newProp); ReadPropertyPrimitives(PropNode,newProp); ErrString.append("Warning: Unknown Property found!!!\n"); } else { ErrString.append("Warning: invalid Property found!!!\n"); delete newProp; newProp=NULL; } } } PropNode=PropNode->NextSiblingElement(); } return ErrString.c_str(); } bool ContinuousStructure::ReadPropertyPrimitives(TiXmlElement* PropNode, CSProperties* prop) { /***Primitives***/ TiXmlNode* prims = PropNode->FirstChild("Primitives"); if (prims==NULL) { ErrString.append("Warning: No primitives found in property: "); ErrString.append(prop->GetName()); ErrString.append("!\n"); return false; } TiXmlElement* PrimNode = prims->FirstChildElement(); CSPrimitives* newPrim=NULL; while (PrimNode!=NULL) { const char* cPrim=PrimNode->Value(); if (strcmp(cPrim,"Box")==0) newPrim = new CSPrimBox(clParaSet,prop); else if (strcmp(cPrim,"MultiBox")==0) newPrim = new CSPrimMultiBox(clParaSet,prop); else if (strcmp(cPrim,"Sphere")==0) newPrim = new CSPrimSphere(clParaSet,prop); else if (strcmp(cPrim,"SphericalShell")==0) newPrim = new CSPrimSphericalShell(clParaSet,prop); else if (strcmp(cPrim,"Cylinder")==0) newPrim = new CSPrimCylinder(clParaSet,prop); else if (strcmp(cPrim,"CylindricalShell")==0) newPrim = new CSPrimCylindricalShell(clParaSet,prop); else if (strcmp(cPrim,"Polygon")==0) newPrim = new CSPrimPolygon(clParaSet,prop); else if (strcmp(cPrim,"LinPoly")==0) newPrim = new CSPrimLinPoly(clParaSet,prop); else if (strcmp(cPrim,"RotPoly")==0) newPrim = new CSPrimRotPoly(clParaSet,prop); else if (strcmp(cPrim,"Polyhedron")==0) newPrim = new CSPrimPolyhedron(clParaSet,prop); else if (strcmp(cPrim,"PolyhedronReader")==0) newPrim = new CSPrimPolyhedronReader(clParaSet,prop); else if (strcmp(cPrim,"Curve")==0) newPrim = new CSPrimCurve(clParaSet,prop); else if (strcmp(cPrim,"Wire")==0) newPrim = new CSPrimWire(clParaSet,prop); else if (strcmp(cPrim,"UserDefined")==0) newPrim = new CSPrimUserDefined(clParaSet,prop); else if (strcmp(cPrim,"Point")==0) newPrim = new CSPrimPoint(clParaSet,prop); else { std::cerr << "ContinuousStructure::ReadFromXML: Primitive with type: " << cPrim << " is unknown... " << std::endl; newPrim=NULL; } if (newPrim) { if (newPrim->ReadFromXML(*PrimNode)) { newPrim->SetCoordInputType(m_MeshType, false); newPrim->Update(&ErrString); } else { delete newPrim; ErrString.append("Warning: Invalid primitive found in property: "); ErrString.append(prop->GetName()); ErrString.append("!\n"); } } PrimNode=PrimNode->NextSiblingElement(); } return true; } const char* ContinuousStructure::ReadFromXML(const char* file) { ErrString.clear(); TiXmlDocument doc(file); if (!doc.LoadFile(TIXML_ENCODING_UTF8)) { ErrString.append("Error: File-Loading failed!!! File: ");ErrString.append(file); return ErrString.c_str();} return ReadFromXML(&doc); } void ContinuousStructure::UpdateIDs() { for (size_t i=0;iSetID((unsigned int)i); } std::string ContinuousStructure::GetInfoLine(bool shortInfo) { if (shortInfo) { std::string InfoLine = std::string(_CSXCAD_LIB_NAME_SHORT_) +std::string(" -- Version: ") + std::string(_CSXCAD_VERSION_); return InfoLine; } std::string InfoLine = std::string(_CSXCAD_LIB_NAME_) +std::string("\nAuthor: ") + std::string(_CSXCAD_AUTHOR_) +std::string("\nMail: ") +std::string(_CSXCAD_AUTHOR_MAIL_) +std::string("\nVersion: ") + std::string(_CSXCAD_VERSION_) +std::string("\tBuild: ") + std::string(__DATE__) + std::string(" ") + std::string(__TIME__) +std::string("\nLicense: ") + std::string(_CSXCAD_LICENSE_); return InfoLine; }