/*
* 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;
}