diff options
Diffstat (limited to 'CSXCAD/src')
79 files changed, 12828 insertions, 0 deletions
diff --git a/CSXCAD/src/CMakeLists.txt b/CSXCAD/src/CMakeLists.txt new file mode 100644 index 0000000..676546a --- /dev/null +++ b/CSXCAD/src/CMakeLists.txt @@ -0,0 +1,104 @@ + +set( PUB_HEADERS + ContinuousStructure.h + CSPrimitives.h + CSProperties.h + CSRectGrid.h + CSXCAD_Global.h + ParameterObjects.h + CSFunctionParser.h + CSUseful.h + ParameterCoord.h + CSTransform.h + CSBackgroundMaterial.h + CSPrimPoint.h + CSPrimBox.h + CSPrimMultiBox.h + CSPrimSphere.h + CSPrimSphericalShell.h + CSPrimCylinder.h + CSPrimCylindricalShell.h + CSPrimPolygon.h + CSPrimLinPoly.h + CSPrimRotPoly.h + CSPrimPolyhedron.h + CSPrimPolyhedronReader.h + CSPrimCurve.h + CSPrimWire.h + CSPrimUserDefined.h + CSPropUnknown.h + CSPropMaterial.h + CSPropDispersiveMaterial.h + CSPropLorentzMaterial.h + CSPropDebyeMaterial.h + CSPropDiscMaterial.h + CSPropLumpedElement.h + CSPropMetal.h + CSPropConductingSheet.h + CSPropExcitation.h + CSPropProbeBox.h + CSPropDumpBox.h + CSPropResBox.h +) + +set(SOURCES + ContinuousStructure.cpp + CSPrimitives.cpp + CSProperties.cpp + CSRectGrid.cpp + ParameterObjects.cpp + CSFunctionParser.cpp + CSUseful.cpp + ParameterCoord.cpp + CSTransform.cpp + CSPrimPoint.cpp + CSPrimBox.cpp + CSPrimMultiBox.cpp + CSPrimSphere.cpp + CSPrimSphericalShell.cpp + CSPrimCylinder.cpp + CSPrimCylindricalShell.cpp + CSPrimPolygon.cpp + CSPrimLinPoly.cpp + CSPrimRotPoly.cpp + CSPrimPolyhedron.cpp + CSPrimPolyhedronReader.cpp + CSPrimCurve.cpp + CSPrimWire.cpp + CSPrimUserDefined.cpp + CSPropUnknown.cpp + CSPropMaterial.cpp + CSPropDispersiveMaterial.cpp + CSPropLorentzMaterial.cpp + CSPropDebyeMaterial.cpp + CSPropDiscMaterial.cpp + CSPropLumpedElement.cpp + CSPropMetal.cpp + CSPropConductingSheet.cpp + CSPropExcitation.cpp + CSPropProbeBox.cpp + CSPropDumpBox.cpp + CSPropResBox.cpp + CSBackgroundMaterial.cpp +) + +# CSXCAD library +add_library( CSXCAD SHARED ${SOURCES} ) + +TARGET_LINK_LIBRARIES( CSXCAD + ${fparser_LIBRARIES} + ${TinyXML_LIBRARIES} + ${HDF5_LIBRARIES} + CGAL + ${Boost_LIBRARIES} + ${vtk_LIBS} +) + +set_target_properties(CSXCAD PROPERTIES VERSION ${LIB_VERSION_STRING} + SOVERSION ${LIB_VERSION_MAJOR}) + +INSTALL(TARGETS CSXCAD DESTINATION lib${LIB_SUFFIX}) + +INSTALL(FILES ${PUB_HEADERS} DESTINATION include/CSXCAD) + + diff --git a/CSXCAD/src/CSBackgroundMaterial.cpp b/CSXCAD/src/CSBackgroundMaterial.cpp new file mode 100644 index 0000000..02067fe --- /dev/null +++ b/CSXCAD/src/CSBackgroundMaterial.cpp @@ -0,0 +1,115 @@ +/* +* Copyright (C) 2013 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 "CSBackgroundMaterial.h" + +#include "tinyxml.h" +#include <stdio.h> +#include <stdlib.h> +#include <iostream> +#include <string> + +CSBackgroundMaterial::CSBackgroundMaterial() +{ + // init material + Reset(); +} + +void CSBackgroundMaterial::Reset() +{ + SetEpsilon(1); + SetMue(1); + SetKappa(0); + SetSigma(0); +} + +void CSBackgroundMaterial::SetEpsilon(double val) +{ + if (val<1) + { + std::cerr << __func__ << ": Error, a relative electric permittivity smaller 1 is not allowed! Skipping. " << std::endl; + return; + } + m_epsR=val; +} + +void CSBackgroundMaterial::SetMue(double val) +{ + if (val<1) + { + std::cerr << __func__ << ": Error, a relative magnetic permeability smaller 1 is not allowed! Skipping. " << std::endl; + return; + } + m_mueR=val; +} + +void CSBackgroundMaterial::SetKappa(double val) +{ + if (val<0) + { + std::cerr << __func__ << ": Error, a negative electric conductivity is not allowed! Skipping. " << std::endl; + return; + } + m_kappa=val; +} + +void CSBackgroundMaterial::SetSigma(double val) +{ + if (val<0) + { + std::cerr << __func__ << ": Error, a negative (artificial) magnetic conductivity is not allowed! Skipping. " << std::endl; + return; + } + m_sigma=val; +} + +bool CSBackgroundMaterial::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + UNUSED(parameterised); + UNUSED(sparse); + TiXmlElement bg_elem("BackgroundMaterial"); + + bg_elem.SetDoubleAttribute("Epsilon", GetEpsilon()); + bg_elem.SetDoubleAttribute("Mue", GetMue()); + bg_elem.SetDoubleAttribute("Kappa", GetKappa()); + bg_elem.SetDoubleAttribute("Sigma", GetSigma()); + + root.InsertEndChild(bg_elem); + + return true; +} + +bool CSBackgroundMaterial::ReadFromXML(TiXmlNode &root) +{ + Reset(); + TiXmlElement* rootElem=root.ToElement(); + + if (rootElem==NULL) + return false; + + double val; + if (rootElem->QueryDoubleAttribute("Epsilon",&val) == TIXML_SUCCESS) + SetEpsilon(val); + if (rootElem->QueryDoubleAttribute("Mue",&val) == TIXML_SUCCESS) + SetMue(val); + if (rootElem->QueryDoubleAttribute("Kappa",&val) == TIXML_SUCCESS) + SetKappa(val); + if (rootElem->QueryDoubleAttribute("Sigma",&val) == TIXML_SUCCESS) + SetSigma(val); + + return true; +} diff --git a/CSXCAD/src/CSBackgroundMaterial.h b/CSXCAD/src/CSBackgroundMaterial.h new file mode 100644 index 0000000..8a54f54 --- /dev/null +++ b/CSXCAD/src/CSBackgroundMaterial.h @@ -0,0 +1,63 @@ +/* +* Copyright (C) 2013 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/>. +*/ + +#ifndef CSBACKGROUNDMATERIAL_H +#define CSBACKGROUNDMATERIAL_H + +#include "CSXCAD_Global.h" + +class TiXmlNode; + +class CSBackgroundMaterial +{ +public: + CSBackgroundMaterial(); + + //! Get the rel. electric permittivity + double GetEpsilon() const {return m_epsR;} + //! Set the rel. electric permittivity + void SetEpsilon(double val); + + //! Get the rel. magnetic permeability + double GetMue() const {return m_mueR;} + //! Set the rel. magnetic permeability + void SetMue(double val); + + //! Get the electric conductivity + double GetKappa() const {return m_kappa;} + //! Set the electric conductivity + void SetKappa(double val); + + //! Get the (artificial) magnetic conductivity + double GetSigma() const {return m_sigma;} + //! Set the (artificial) magnetic conductivity + void SetSigma(double val); + + //! Reset all values to default + void Reset(); + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); + +protected: + double m_epsR; + double m_mueR; + double m_kappa; + double m_sigma; +}; + +#endif // CSBACKGROUNDMATERIAL_H diff --git a/CSXCAD/src/CSFunctionParser.cpp b/CSXCAD/src/CSFunctionParser.cpp new file mode 100644 index 0000000..c8741ff --- /dev/null +++ b/CSXCAD/src/CSFunctionParser.cpp @@ -0,0 +1,76 @@ +/* +* Copyright (C) 2010,2011 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 "CSFunctionParser.h" +#include <math.h> +#include <iostream> + +double bessel_first_kind_0(const double* p) +{ + return j0(p[0]); +} +double bessel_first_kind_1(const double* p) +{ + return j1(p[0]); +} +double bessel_first_kind_n(const double* p) +{ + int n=p[0]; + if (n<0) + { + std::cerr << "CSFunctionParser::bessel_first_kind_n (jn): first argument must be integer larger than zero! found: " << p[0] << std::endl; + return 0; + } + return jn(n,p[1]); +} + +double bessel_second_kind_0(const double* p) +{ + return y0(p[0]); +} +double bessel_second_kind_1(const double* p) +{ + return y1(p[0]); +} +double bessel_second_kind_n(const double* p) +{ + int n=p[0]; + if (n<0) + { + std::cerr << "CSFunctionParser::bessel_second_kind_n (yn): first argument must be integer larger than zero! found: " << p[0] << std::endl; + return 0; + } + return yn(n,p[1]); +} + + +CSFunctionParser::CSFunctionParser() +{ + //some usefull constants + AddConstant("pi", 3.14159265358979323846); + AddConstant("e", 2.71828182845904523536); + + //some bessel functions of first kind + AddFunction("j0",bessel_first_kind_0,1); + AddFunction("j1",bessel_first_kind_1,1); + AddFunction("jn",bessel_first_kind_n,2); + + //some bessel functions of second kind + AddFunction("y0",bessel_second_kind_0,1); + AddFunction("y1",bessel_second_kind_1,1); + AddFunction("yn",bessel_second_kind_n,2); +} diff --git a/CSXCAD/src/CSFunctionParser.h b/CSXCAD/src/CSFunctionParser.h new file mode 100644 index 0000000..06304fc --- /dev/null +++ b/CSXCAD/src/CSFunctionParser.h @@ -0,0 +1,34 @@ +/* +* Copyright (C) 2010,2011 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/>. +*/ + +#ifndef CSFUNCTIONPARSER_H +#define CSFUNCTIONPARSER_H + +#include "CSXCAD_Global.h" +#include "fparser.hh" + +//! Extended FunctionParser using some additional constants (pi,e) and functions +/*! + This is an extended FunctionParser with the additional constants, "pi" and "e", as well as severel bessel functions of first (j0, j1, jn) and second kind (y0, y1, yn). +*/ +class CSXCAD_EXPORT CSFunctionParser : public FunctionParser +{ +public: + CSFunctionParser(); +}; + +#endif // CSFUNCTIONPARSER_H diff --git a/CSXCAD/src/CSPrimBox.cpp b/CSXCAD/src/CSPrimBox.cpp new file mode 100644 index 0000000..de31b31 --- /dev/null +++ b/CSXCAD/src/CSPrimBox.cpp @@ -0,0 +1,149 @@ +/* +* 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 "CSPrimBox.h" +#include "CSProperties.h" +#include "CSUseful.h" + +CSPrimBox::CSPrimBox(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(ID,paraSet,prop) +{ + Type=BOX; + m_Coords[0].SetParameterSet(paraSet); + m_Coords[1].SetParameterSet(paraSet); + PrimTypeName = std::string("Box"); +} + +CSPrimBox::CSPrimBox(CSPrimBox* primBox, CSProperties *prop) : CSPrimitives(primBox,prop) +{ + Type=BOX; + m_Coords[0].Copy(&primBox->m_Coords[0]); + m_Coords[1].Copy(&primBox->m_Coords[1]); + PrimTypeName = std::string("Box"); +} + +CSPrimBox::CSPrimBox(ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(paraSet,prop) +{ + Type=BOX; + m_Coords[0].SetParameterSet(paraSet); + m_Coords[1].SetParameterSet(paraSet); + PrimTypeName = std::string("Box"); +} + + +CSPrimBox::~CSPrimBox() +{ +} + +bool CSPrimBox::GetBoundBox(double dBoundBox[6], bool PreserveOrientation) +{ +// if ( (m_MeshType!=m_PrimCoordSystem) && (m_PrimCoordSystem!=UNDEFINED_CS)) +// std::cerr << "GetBoundBox::GetBoundBox: Warning: The bounding box for this object is not calculated properly... " << std::endl; + + const double* start = m_Coords[0].GetCoords(m_MeshType); + const double* stop = m_Coords[1].GetCoords(m_MeshType); + + m_BoundBox_CoordSys = m_MeshType; + m_Dimension=0; + for (int i=0;i<3;++i) + { + dBoundBox[2*i] = start[i]; + dBoundBox[2*i+1]= stop[i]; + + if (start[i]!=stop[i]) + ++m_Dimension; + } + if (PreserveOrientation) + return true; + for (int i=0;i<3;++i) + if (dBoundBox[2*i]>dBoundBox[2*i+1]) + { + double help=dBoundBox[2*i]; + dBoundBox[2*i]=dBoundBox[2*i+1]; + dBoundBox[2*i+1]=help; + } + return true; +} + +bool CSPrimBox::IsInside(const double* Coord, double /*tol*/) +{ + if (Coord==NULL) return false; + + const double* start = m_Coords[0].GetCoords(m_PrimCoordSystem); + const double* stop = m_Coords[1].GetCoords(m_PrimCoordSystem); + double pos[3] = {Coord[0],Coord[1],Coord[2]}; + + TransformCoords(pos, true, m_MeshType); + //transform incoming coordinates into the coorindate system of the primitive + TransformCoordSystem(pos,pos,m_MeshType,m_PrimCoordSystem); + + if (m_PrimCoordSystem!=UNDEFINED_CS) + return CoordInRange(pos, start, stop, m_PrimCoordSystem); + else + return CoordInRange(pos, start, stop, m_MeshType); +} + + +bool CSPrimBox::Update(std::string *ErrStr) +{ + bool bOK=m_Coords[0].Evaluate(ErrStr) && m_Coords[1].Evaluate(ErrStr); + if (bOK==false) + { + std::stringstream stream; + stream << std::endl << "Error in Box (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + } + m_Coords[0].SetCoordinateSystem(m_PrimCoordSystem, m_MeshType); + m_Coords[1].SetCoordinateSystem(m_PrimCoordSystem, m_MeshType); + //update local bounding box + m_BoundBoxValid = GetBoundBox(m_BoundBox); + return bOK; +} + +bool CSPrimBox::Write2XML(TiXmlElement &elem, bool parameterised) +{ + CSPrimitives::Write2XML(elem,parameterised); + + TiXmlElement P1("P1"); + m_Coords[0].Write2XML(&P1,parameterised); + elem.InsertEndChild(P1); + + TiXmlElement P2("P2"); + m_Coords[1].Write2XML(&P2,parameterised); + elem.InsertEndChild(P2); + return true; +} + +bool CSPrimBox::ReadFromXML(TiXmlNode &root) +{ + if (CSPrimitives::ReadFromXML(root)==false) return false; + if (m_Coords[0].ReadFromXML(root.FirstChildElement("P1")) == false) return false; + if (m_Coords[1].ReadFromXML(root.FirstChildElement("P2")) == false) return false; + return true; +} + +void CSPrimBox::ShowPrimitiveStatus(std::ostream& stream) +{ + CSPrimitives::ShowPrimitiveStatus(stream); + stream << " Start: " << m_Coords[0].GetValueString(0) << "," << m_Coords[0].GetValueString(1) << "," << m_Coords[0].GetValueString(2) << std::endl; + stream << " Stop : " << m_Coords[1].GetValueString(0) << "," << m_Coords[1].GetValueString(1) << "," << m_Coords[1].GetValueString(2) << std::endl; +} diff --git a/CSXCAD/src/CSPrimBox.h b/CSXCAD/src/CSPrimBox.h new file mode 100644 index 0000000..972602f --- /dev/null +++ b/CSXCAD/src/CSPrimBox.h @@ -0,0 +1,59 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" + +//! Box Primitive (Cube) +/*! + This is a cube primitive defined by its start-, end-coordinates. + */ +class CSXCAD_EXPORT CSPrimBox : public CSPrimitives +{ +public: + CSPrimBox(ParameterSet* paraSet, CSProperties* prop); + CSPrimBox(CSPrimBox* primBox, CSProperties *prop=NULL); + CSPrimBox(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimBox(); + + virtual CSPrimitives* GetCopy(CSProperties *prop=NULL) {return new CSPrimBox(this,prop);} + + void SetCoord(int index, double val) {if ((index>=0) && (index<6)) m_Coords[index%2].SetValue(index/2,val);} + void SetCoord(int index, const char* val) {if ((index>=0) && (index<6)) m_Coords[index%2].SetValue(index/2,val);} + void SetCoord(int index, std::string val) {if ((index>=0) && (index<6)) m_Coords[index%2].SetValue(index/2,val);} + + double GetCoord(int index) {if ((index>=0) && (index<6)) return m_Coords[index%2].GetValue(index/2); else return 0;} + ParameterScalar* GetCoordPS(int index) {if ((index>=0) && (index<6)) return m_Coords[index%2].GetCoordPS(index/2); else return NULL;} + + ParameterCoord* GetStartCoord() {return &m_Coords[0];} + ParameterCoord* GetStopCoord() {return &m_Coords[1];} + + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false); + virtual bool IsInside(const double* Coord, double tol=0); + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual void ShowPrimitiveStatus(std::ostream& stream); + +protected: + //start and stop coords defining the box + ParameterCoord m_Coords[2]; +}; + diff --git a/CSXCAD/src/CSPrimCurve.cpp b/CSXCAD/src/CSPrimCurve.cpp new file mode 100644 index 0000000..4a1d5ba --- /dev/null +++ b/CSXCAD/src/CSPrimCurve.cpp @@ -0,0 +1,188 @@ +/* +* 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 "CSPrimCurve.h" +#include "CSProperties.h" +#include "CSUseful.h" + +CSPrimCurve::CSPrimCurve(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(ID,paraSet,prop) +{ + Type=CURVE; + PrimTypeName = std::string("Curve"); +} + +CSPrimCurve::CSPrimCurve(CSPrimCurve* primCurve, CSProperties *prop) : CSPrimitives(primCurve,prop) +{ + Type=CURVE; + for (size_t i=0;i<primCurve->points.size();++i) + points.push_back(new ParameterCoord(primCurve->points.at(i))); + PrimTypeName = std::string("Curve"); +} + +CSPrimCurve::CSPrimCurve(ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(paraSet,prop) +{ + Type=CURVE; + PrimTypeName = std::string("Curve"); +} + + +CSPrimCurve::~CSPrimCurve() +{ + points.clear(); +} + +size_t CSPrimCurve::AddPoint(double coords[]) +{ + points.push_back(new ParameterCoord(clParaSet,coords)); + return points.size(); +} + +void CSPrimCurve::SetCoord(size_t point_index, int nu, double val) +{ + if (point_index>=GetNumberOfPoints()) return; + if ((nu<0) || (nu>2)) return; + points.at(point_index)->SetValue(nu,val); +} + +void CSPrimCurve::SetCoord(size_t point_index, int nu, std::string val) +{ + if (point_index>=GetNumberOfPoints()) return; + if ((nu<0) || (nu>2)) return; + points.at(point_index)->SetValue(nu,val); +} + +bool CSPrimCurve::GetPoint(size_t point_index, double point[3]) +{ + if (point_index>=GetNumberOfPoints()) return false; + point[0] = points.at(point_index)->GetValue(0); + point[1] = points.at(point_index)->GetValue(1); + point[2] = points.at(point_index)->GetValue(2); + return true; +} + +bool CSPrimCurve::GetPoint(size_t point_index, double* point, CoordinateSystem c_system, bool transform) +{ + if (point_index>=GetNumberOfPoints()) return false; + point[0] = points.at(point_index)->GetCoordValue(0,c_system); + point[1] = points.at(point_index)->GetCoordValue(1,c_system); + point[2] = points.at(point_index)->GetCoordValue(2,c_system); + if (transform) + TransformCoords(point, false, c_system); + return true; +} + +void CSPrimCurve::ClearPoints() +{ + points.clear(); +} + +bool CSPrimCurve::GetBoundBox(double dBoundBox[6], bool /*PreserveOrientation*/) +{ +// cerr << "CSPrimCurve::GetBoundBox: Warning: The bounding box for this object is not calculated properly... " << std::endl; + bool accurate=false; + m_BoundBox_CoordSys = CARTESIAN; + for (int n=0;n<6;++n) dBoundBox[n] = 0; + for (size_t i=0;i<points.size();++i) + { + if (i==0) + { + for (int n=0;n<3;++n) + { + dBoundBox[2*n]=points.at(0)->GetCoordValue(n,CARTESIAN); + dBoundBox[2*n+1]=dBoundBox[2*n]; + } + } + for (int n=0;n<3;++n) + { + if (points.at(i)->GetValue(n)<dBoundBox[2*n]) + dBoundBox[2*n]=points.at(i)->GetCoordValue(n,CARTESIAN); + else if (points.at(i)->GetValue(n)>dBoundBox[2*n+1]) + dBoundBox[2*n+1]=points.at(i)->GetCoordValue(n,CARTESIAN); + } + } + if (points.size()<=1) + m_Dimension=0; + else + m_Dimension=1; + return accurate; +} + +bool CSPrimCurve::IsInside(const double* /*Coord*/, double /*tol*/) +{ + //this is a 1D-object, you can never be inside... + return false; +} + + +bool CSPrimCurve::Update(std::string *ErrStr) +{ + bool bOK=true; + for (size_t i=0;i<GetNumberOfPoints();++i) + { + bool isOK = points.at(i)->Evaluate(ErrStr); + if (isOK==false) + { + std::stringstream stream; + stream << std::endl << "Error in " << PrimTypeName << " (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + } + points.at(i)->SetCoordinateSystem(m_PrimCoordSystem, m_MeshType); + bOK &= isOK; + } + + //update local bounding box + m_BoundBoxValid = GetBoundBox(m_BoundBox); + + return bOK; +} + +bool CSPrimCurve::Write2XML(TiXmlElement &elem, bool parameterised) +{ + CSPrimitives::Write2XML(elem,parameterised); + + for (size_t i=0;i<points.size();++i) + { + TiXmlElement VT("Vertex"); + points.at(i)->Write2XML(&VT,parameterised); + elem.InsertEndChild(VT); + } + return true; +} + +bool CSPrimCurve::ReadFromXML(TiXmlNode &root) +{ + if (CSPrimitives::ReadFromXML(root)==false) return false; + + TiXmlElement *VT=root.FirstChildElement("Vertex"); + if (points.size()!=0) return false; + ParameterCoord *newPoint; + while (VT) + { + newPoint = new ParameterCoord(clParaSet); + if (newPoint->ReadFromXML(VT)) + points.push_back(newPoint); + VT=VT->NextSiblingElement("Vertex"); + }; + + return true; +} diff --git a/CSXCAD/src/CSPrimCurve.h b/CSXCAD/src/CSPrimCurve.h new file mode 100644 index 0000000..40caafb --- /dev/null +++ b/CSXCAD/src/CSPrimCurve.h @@ -0,0 +1,56 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" + +//! Curve Primitive (Polygonal chain) +/*! + This is a curve primitive defined by a number of 3D points + */ +class CSXCAD_EXPORT CSPrimCurve : public CSPrimitives +{ +public: + CSPrimCurve(ParameterSet* paraSet, CSProperties* prop); + CSPrimCurve(CSPrimCurve* primCurve, CSProperties *prop=NULL); + CSPrimCurve(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimCurve(); + + virtual CSPrimitives* GetCopy(CSProperties *prop=NULL) {return new CSPrimCurve(this,prop);} + + virtual size_t AddPoint(double coords[]); + virtual void SetCoord(size_t point_index, int nu, double val); + virtual void SetCoord(size_t point_index, int nu, std::string val); + + virtual size_t GetNumberOfPoints() {return points.size();} + virtual bool GetPoint(size_t point_index, double point[3]); + //! Get the point coordinates for the given index in the specified coordinate system + virtual bool GetPoint(size_t point_index, double* point, CoordinateSystem c_system, bool transform=true); + + virtual void ClearPoints(); + + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false); + virtual bool IsInside(const double* Coord, double tol=0); + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + +protected: + std::vector<ParameterCoord*> points; +}; diff --git a/CSXCAD/src/CSPrimCylinder.cpp b/CSXCAD/src/CSPrimCylinder.cpp new file mode 100644 index 0000000..fb16262 --- /dev/null +++ b/CSXCAD/src/CSPrimCylinder.cpp @@ -0,0 +1,210 @@ +/* +* 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 "CSPrimCylinder.h" +#include "CSProperties.h" +#include "CSUseful.h" + +CSPrimCylinder::CSPrimCylinder(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(ID,paraSet,prop) +{ + Type=CYLINDER; + m_AxisCoords[0].SetParameterSet(paraSet); + m_AxisCoords[1].SetParameterSet(paraSet); + psRadius.SetParameterSet(paraSet); + PrimTypeName = std::string("Cylinder"); +} + +CSPrimCylinder::CSPrimCylinder(CSPrimCylinder* cylinder, CSProperties *prop) : CSPrimitives(cylinder,prop) +{ + Type=CYLINDER; + m_AxisCoords[0].Copy(&cylinder->m_AxisCoords[0]); + m_AxisCoords[1].Copy(&cylinder->m_AxisCoords[1]); + psRadius.Copy(&cylinder->psRadius); + PrimTypeName = std::string("Cylinder"); +} + +CSPrimCylinder::CSPrimCylinder(ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(paraSet,prop) +{ + Type=CYLINDER; + m_AxisCoords[0].SetParameterSet(paraSet); + m_AxisCoords[1].SetParameterSet(paraSet); + psRadius.SetParameterSet(paraSet); + PrimTypeName = std::string("Cylinder"); +} + + +CSPrimCylinder::~CSPrimCylinder() +{ +} + +bool CSPrimCylinder::GetBoundBox(double dBoundBox[6], bool PreserveOrientation) +{ +// cerr << "CSPrimCylinder::GetBoundBox: Warning: The bounding box for this object is not calculated properly... " << std::endl; + UNUSED(PreserveOrientation); //has no orientation or preserved anyways + bool accurate=false; + int Direction=0; + const double* start=m_AxisCoords[0].GetCartesianCoords(); + const double* stop =m_AxisCoords[1].GetCartesianCoords(); + m_BoundBox_CoordSys=CARTESIAN; + + double rad=psRadius.GetValue(); + for (unsigned int i=0;i<3;++i) + { + double min=start[i]; + double max=stop[i]; + if (min<max) + { + dBoundBox[2*i]=min-rad; + dBoundBox[2*i+1]=max+rad; + } + else + { + dBoundBox[2*i+1]=min+rad; + dBoundBox[2*i]=max-rad; + } + if (min==max) Direction+=pow(2,i); + } + switch (Direction) + { + case 3: //orientaion in z-direction + dBoundBox[4]=dBoundBox[4]+rad; + dBoundBox[5]=dBoundBox[5]-rad; + accurate=true; + break; + case 5: //orientaion in y-direction + dBoundBox[2]=dBoundBox[2]+rad; + dBoundBox[3]=dBoundBox[3]-rad; + accurate=true; + break; + case 6: //orientaion in x-direction + dBoundBox[1]=dBoundBox[1]+rad; + dBoundBox[2]=dBoundBox[2]-rad; + accurate=true; + break; + } + if (rad>0) + m_Dimension=3; + else if (Direction==7) + m_Dimension=0; + else + m_Dimension=1; + return accurate; +} + +bool CSPrimCylinder::IsInside(const double* Coord, double /*tol*/) +{ + if (Coord==NULL) return false; + + const double* start=m_AxisCoords[0].GetCartesianCoords(); + const double* stop =m_AxisCoords[1].GetCartesianCoords(); + double pos[3]; + //transform incoming coordinates into cartesian coords + TransformCoordSystem(Coord,pos,m_MeshType,CARTESIAN); + if (m_Transform) + m_Transform->InvertTransform(pos,pos); + + for (int n=0;n<3;++n) + if (pos[n]<m_BoundBox[2*n] || pos[n]>m_BoundBox[2*n+1]) + return false; + + double foot,dist; + Point_Line_Distance(pos,start,stop,foot,dist); + + if ((foot<0) || (foot>1)) //the foot point is not on the axis + return false; + if (dist>psRadius.GetValue()) + return false; + + return true; +} + +bool CSPrimCylinder::Update(std::string *ErrStr) +{ + int EC=0; + bool bOK=m_AxisCoords[0].Evaluate(ErrStr) && m_AxisCoords[1].Evaluate(ErrStr); + if (bOK==false) + { + std::stringstream stream; + stream << std::endl << "Error in " << PrimTypeName << " Coord (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + } + m_AxisCoords[0].SetCoordinateSystem(m_PrimCoordSystem, m_MeshType); + m_AxisCoords[1].SetCoordinateSystem(m_PrimCoordSystem, m_MeshType); + + + EC=psRadius.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 " << PrimTypeName << " Radius (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + //update local bounding box + m_BoundBoxValid = GetBoundBox(m_BoundBox); + + return bOK; +} + +bool CSPrimCylinder::Write2XML(TiXmlElement &elem, bool parameterised) +{ + CSPrimitives::Write2XML(elem,parameterised); + + WriteTerm(psRadius,elem,"Radius",parameterised); + + TiXmlElement Start("P1"); + m_AxisCoords[0].Write2XML(&Start,parameterised); + elem.InsertEndChild(Start); + + TiXmlElement Stop("P2"); + m_AxisCoords[1].Write2XML(&Stop,parameterised); + elem.InsertEndChild(Stop); + + return true; +} + +bool CSPrimCylinder::ReadFromXML(TiXmlNode &root) +{ + if (CSPrimitives::ReadFromXML(root)==false) return false; + + TiXmlElement *elem = root.ToElement(); + if (elem==NULL) return false; + if (ReadTerm(psRadius,*elem,"Radius")==false) return false; + + if (m_AxisCoords[0].ReadFromXML(root.FirstChildElement("P1")) == false) return false; + if (m_AxisCoords[1].ReadFromXML(root.FirstChildElement("P2")) == false) return false; + + return true; +} + +void CSPrimCylinder::ShowPrimitiveStatus(std::ostream& stream) +{ + CSPrimitives::ShowPrimitiveStatus(stream); + stream << " Axis-Start: " << m_AxisCoords[0].GetValueString(0) << "," << m_AxisCoords[0].GetValueString(1) << "," << m_AxisCoords[0].GetValueString(2) << std::endl; + stream << " Axis-Stop : " << m_AxisCoords[1].GetValueString(0) << "," << m_AxisCoords[1].GetValueString(1) << "," << m_AxisCoords[1].GetValueString(2) << std::endl; + stream << " Radius: " << psRadius.GetValueString() << std::endl; +} + diff --git a/CSXCAD/src/CSPrimCylinder.h b/CSXCAD/src/CSPrimCylinder.h new file mode 100644 index 0000000..21e6c05 --- /dev/null +++ b/CSXCAD/src/CSPrimCylinder.h @@ -0,0 +1,65 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" + +//! Cylinder Primitive +/*! + This is a cylindrical primitive defined by its axis start-, end-coordinates and a radius. + */ +class CSXCAD_EXPORT CSPrimCylinder : public CSPrimitives +{ +public: + CSPrimCylinder(ParameterSet* paraSet, CSProperties* prop); + CSPrimCylinder(CSPrimCylinder* cylinder, CSProperties *prop=NULL); + CSPrimCylinder(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimCylinder(); + + virtual CSPrimitives* GetCopy(CSProperties *prop=NULL) {return new CSPrimCylinder(this,prop);} + + void SetCoord(int index, double val) {if ((index>=0) && (index<6)) m_AxisCoords[index%2].SetValue(index/2,val);} + void SetCoord(int index, const char* val) {if ((index>=0) && (index<6)) m_AxisCoords[index%2].SetValue(index/2,val);} + void SetCoord(int index, std::string val) {if ((index>=0) && (index<6)) m_AxisCoords[index%2].SetValue(index/2,val);} + + double GetCoord(int index) {if ((index>=0) && (index<6)) return m_AxisCoords[index%2].GetValue(index/2); else return 0;} + ParameterScalar* GetCoordPS(int index) {if ((index>=0) && (index<6)) return m_AxisCoords[index%2].GetCoordPS(index/2); else return NULL;} + + ParameterCoord* GetAxisStartCoord() {return &m_AxisCoords[0];} + ParameterCoord* GetAxisStopCoord() {return &m_AxisCoords[1];} + + void SetRadius(double val) {psRadius.SetValue(val);} + void SetRadius(const char* val) {psRadius.SetValue(val);} + + double GetRadius() {return psRadius.GetValue();} + ParameterScalar* GetRadiusPS() {return &psRadius;} + + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false); + virtual bool IsInside(const double* Coord, double tol=0); + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual void ShowPrimitiveStatus(std::ostream& stream); + +protected: + ParameterCoord m_AxisCoords[2]; + ParameterScalar psRadius; +}; + diff --git a/CSXCAD/src/CSPrimCylindricalShell.cpp b/CSXCAD/src/CSPrimCylindricalShell.cpp new file mode 100644 index 0000000..0ca1701 --- /dev/null +++ b/CSXCAD/src/CSPrimCylindricalShell.cpp @@ -0,0 +1,177 @@ +/* +* 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 "CSPrimCylindricalShell.h" +#include "CSProperties.h" +#include "CSUseful.h" + +CSPrimCylindricalShell::CSPrimCylindricalShell(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimCylinder(ID,paraSet,prop) +{ + Type=CYLINDRICALSHELL; + PrimTypeName = std::string("CylindricalShell"); + psShellWidth.SetParameterSet(paraSet); +} + +CSPrimCylindricalShell::CSPrimCylindricalShell(CSPrimCylindricalShell* cylinder, CSProperties *prop) : CSPrimCylinder(cylinder,prop) +{ + Type=CYLINDRICALSHELL; + PrimTypeName = std::string("CylindricalShell"); + psShellWidth.Copy(&cylinder->psShellWidth); +} + +CSPrimCylindricalShell::CSPrimCylindricalShell(ParameterSet* paraSet, CSProperties* prop) : CSPrimCylinder(paraSet,prop) +{ + Type=CYLINDRICALSHELL; + PrimTypeName = std::string("CylindricalShell"); + psShellWidth.SetParameterSet(paraSet); +} + +CSPrimCylindricalShell::~CSPrimCylindricalShell() +{ +} + +bool CSPrimCylindricalShell::GetBoundBox(double dBoundBox[6], bool PreserveOrientation) +{ +// cerr << "CSPrimCylindricalShell::GetBoundBox: Warning: The bounding box for this object is not calculated properly... " << std::endl; + UNUSED(PreserveOrientation); //has no orientation or preserved anyways + bool accurate=false; + int Direction=0; + const double* start=m_AxisCoords[0].GetCartesianCoords(); + const double* stop =m_AxisCoords[1].GetCartesianCoords(); + m_BoundBox_CoordSys=CARTESIAN; + double rad=psRadius.GetValue()+psShellWidth.GetValue()/2.0; + for (unsigned int i=0;i<3;++i) + { + double min=start[i]; + double max=stop[i]; + if (min<max) + { + dBoundBox[2*i]=min-rad; + dBoundBox[2*i+1]=max+rad; + } + else + { + dBoundBox[2*i+1]=min+rad; + dBoundBox[2*i]=max-rad; + } + if (min==max) Direction+=pow(2,i); + } + switch (Direction) + { + case 3: //orientaion in z-direction + dBoundBox[4]=dBoundBox[4]+rad; + dBoundBox[5]=dBoundBox[5]-rad; + accurate=true; + break; + case 5: //orientaion in y-direction + dBoundBox[2]=dBoundBox[2]+rad; + dBoundBox[3]=dBoundBox[3]-rad; + accurate=true; + break; + case 6: //orientaion in x-direction + dBoundBox[1]=dBoundBox[1]+rad; + dBoundBox[2]=dBoundBox[2]-rad; + accurate=true; + break; + } + + if (rad>0) + m_Dimension=3; + else if (Direction==7) + m_Dimension=0; + else + m_Dimension=1; + return accurate; +} + +bool CSPrimCylindricalShell::IsInside(const double* Coord, double /*tol*/) +{ + if (Coord==NULL) return false; + const double* start=m_AxisCoords[0].GetCartesianCoords(); + const double* stop =m_AxisCoords[1].GetCartesianCoords(); + double pos[3]; + //transform incoming coordinates into cartesian coords + TransformCoordSystem(Coord,pos,m_MeshType,CARTESIAN); + if (m_Transform) + m_Transform->InvertTransform(pos,pos); + + for (int n=0;n<3;++n) + if (pos[n]<m_BoundBox[2*n] || pos[n]>m_BoundBox[2*n+1]) + return false; + + double foot,dist; + Point_Line_Distance(pos,start,stop,foot,dist); + + if ((foot<0) || (foot>1)) //the foot point is not on the axis + return false; + if (fabs(dist-psRadius.GetValue())>psShellWidth.GetValue()/2.0) + return false; + + return true; +} + +bool CSPrimCylindricalShell::Update(std::string *ErrStr) +{ + int EC=0; + bool bOK=CSPrimCylinder::Update(ErrStr); + + EC=psShellWidth.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 " << PrimTypeName << " shell-width (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + //update local bounding box + m_BoundBoxValid = GetBoundBox(m_BoundBox); + + return bOK; +} + +bool CSPrimCylindricalShell::Write2XML(TiXmlElement &elem, bool parameterised) +{ + CSPrimCylinder::Write2XML(elem,parameterised); + + WriteTerm(psShellWidth,elem,"ShellWidth",parameterised); + return true; +} + +bool CSPrimCylindricalShell::ReadFromXML(TiXmlNode &root) +{ + if (CSPrimCylinder::ReadFromXML(root)==false) return false; + + TiXmlElement *elem = root.ToElement(); + if (elem==NULL) return false; + if (ReadTerm(psShellWidth,*elem,"ShellWidth")==false) return false; + return true; +} + +void CSPrimCylindricalShell::ShowPrimitiveStatus(std::ostream& stream) +{ + CSPrimCylinder::ShowPrimitiveStatus(stream); + stream << " Shell width: " << psShellWidth.GetValueString() << std::endl; +} diff --git a/CSXCAD/src/CSPrimCylindricalShell.h b/CSXCAD/src/CSPrimCylindricalShell.h new file mode 100644 index 0000000..ef76897 --- /dev/null +++ b/CSXCAD/src/CSPrimCylindricalShell.h @@ -0,0 +1,56 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" +#include "CSPrimCylinder.h" + +//! CylindicalShell Primitive +/*! + This is a cylindrical shell primitive derived from the cylinder primitive, adding a shell width which is centered around the cylinder radius. + \sa CSPrimCylinder + */ +class CSXCAD_EXPORT CSPrimCylindricalShell : public CSPrimCylinder +{ +public: + CSPrimCylindricalShell(ParameterSet* paraSet, CSProperties* prop); + CSPrimCylindricalShell(CSPrimCylindricalShell* cylinder, CSProperties *prop=NULL); + CSPrimCylindricalShell(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimCylindricalShell(); + + virtual CSPrimitives* GetCopy(CSProperties *prop=NULL) {return new CSPrimCylindricalShell(this,prop);} + + void SetShellWidth(double val) {psShellWidth.SetValue(val);} + void SetShellWidth(const char* val) {psShellWidth.SetValue(val);} + + double GetShellWidth() {return psShellWidth.GetValue();} + ParameterScalar* GetShellWidthPS() {return &psShellWidth;} + + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false); + virtual bool IsInside(const double* Coord, double tol=0); + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual void ShowPrimitiveStatus(std::ostream& stream); + +protected: + ParameterScalar psShellWidth; +}; + diff --git a/CSXCAD/src/CSPrimLinPoly.cpp b/CSXCAD/src/CSPrimLinPoly.cpp new file mode 100644 index 0000000..5ca3201 --- /dev/null +++ b/CSXCAD/src/CSPrimLinPoly.cpp @@ -0,0 +1,131 @@ +/* +* 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 "CSPrimLinPoly.h" +#include "CSProperties.h" +#include "CSUseful.h" + +CSPrimLinPoly::CSPrimLinPoly(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimPolygon(ID,paraSet,prop) +{ + Type=LINPOLY; + extrudeLength.SetParameterSet(paraSet); + PrimTypeName = std::string("LinPoly"); +} + +CSPrimLinPoly::CSPrimLinPoly(CSPrimLinPoly* primLinPoly, CSProperties *prop) : CSPrimPolygon(primLinPoly,prop) +{ + Type=LINPOLY; + extrudeLength.Copy(&primLinPoly->extrudeLength); + PrimTypeName = std::string("LinPoly"); +} + +CSPrimLinPoly::CSPrimLinPoly(ParameterSet* paraSet, CSProperties* prop) : CSPrimPolygon(paraSet,prop) +{ + Type=LINPOLY; + extrudeLength.SetParameterSet(paraSet); + PrimTypeName = std::string("LinPoly"); +} + + +CSPrimLinPoly::~CSPrimLinPoly() +{ +} + +bool CSPrimLinPoly::GetBoundBox(double dBoundBox[6], bool PreserveOrientation) +{ + UNUSED(PreserveOrientation); //has no orientation or preserved anyways + bool accurate; + accurate = CSPrimPolygon::GetBoundBox(dBoundBox); + + double len = extrudeLength.GetValue(); + + if (len>0) + { + dBoundBox[2*m_NormDir] = Elevation.GetValue(); + dBoundBox[2*m_NormDir+1] = dBoundBox[2*m_NormDir] + len; + } + else + { + dBoundBox[2*m_NormDir+1] = Elevation.GetValue(); + dBoundBox[2*m_NormDir] = dBoundBox[2*m_NormDir+1] + len; + } + m_Dimension=0; + for (int n=0;n<3;++n) + { + if (dBoundBox[2*n]!=dBoundBox[2*n+1]) + ++m_Dimension; + } + return accurate; +} + +bool CSPrimLinPoly::IsInside(const double* Coord, double tol) +{ + if (Coord==NULL) return false; + double coords[3]={Coord[0],Coord[1],Coord[2]}; + if (m_Transform && Type==LINPOLY) + TransformCoords(coords,true, m_MeshType); + return CSPrimPolygon::IsInside(coords, tol); +} + + +bool CSPrimLinPoly::Update(std::string *ErrStr) +{ + int EC=0; + + bool bOK = CSPrimPolygon::Update(ErrStr); + + EC=extrudeLength.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 + m_BoundBoxValid = GetBoundBox(m_BoundBox); + + return bOK; +} + +bool CSPrimLinPoly::Write2XML(TiXmlElement &elem, bool parameterised) +{ + CSPrimPolygon::Write2XML(elem,parameterised); + + WriteTerm(extrudeLength,elem,"Length",parameterised); + return true; +} + +bool CSPrimLinPoly::ReadFromXML(TiXmlNode &root) +{ + if (CSPrimPolygon::ReadFromXML(root)==false) return false; + + TiXmlElement *elem = root.ToElement(); + if (elem==NULL) return false; + if (ReadTerm(extrudeLength,*elem,"Length")==false) return false; + + return true; +} diff --git a/CSXCAD/src/CSPrimLinPoly.h b/CSXCAD/src/CSPrimLinPoly.h new file mode 100644 index 0000000..25dce21 --- /dev/null +++ b/CSXCAD/src/CSPrimLinPoly.h @@ -0,0 +1,53 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" +#include "CSPrimPolygon.h" + +//! Linear extruded polygon Primitive +/*! + This is a linear extruded area polygon primitive defined by a number of points in space and an extrude vector. + Warning: This primitive currently can only be defined in Cartesian coordinates. + */ +class CSXCAD_EXPORT CSPrimLinPoly : public CSPrimPolygon +{ +public: + CSPrimLinPoly(ParameterSet* paraSet, CSProperties* prop); + CSPrimLinPoly(CSPrimLinPoly* primPolygon, CSProperties *prop=NULL); + CSPrimLinPoly(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimLinPoly(); + + virtual CSPrimLinPoly* GetCopy(CSProperties *prop=NULL) {return new CSPrimLinPoly(this,prop);} + + void SetLength(double val) {extrudeLength.SetValue(val);} + void SetLength(const std::string val) {extrudeLength.SetValue(val);} + + double GetLength() {return extrudeLength.GetValue();} + ParameterScalar* GetLengthPS() {return &extrudeLength;} + + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false); + virtual bool IsInside(const double* Coord, double tol=0); + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + +protected: + ParameterScalar extrudeLength; +}; diff --git a/CSXCAD/src/CSPrimMultiBox.cpp b/CSXCAD/src/CSPrimMultiBox.cpp new file mode 100644 index 0000000..e5547f0 --- /dev/null +++ b/CSXCAD/src/CSPrimMultiBox.cpp @@ -0,0 +1,279 @@ +/* +* 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 "CSPrimMultiBox.h" +#include "CSProperties.h" +#include "CSUseful.h" + +CSPrimMultiBox::CSPrimMultiBox(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(ID,paraSet,prop) +{ + Type=MULTIBOX; + PrimTypeName = std::string("Multi Box"); +} + +CSPrimMultiBox::CSPrimMultiBox(CSPrimMultiBox* multiBox, CSProperties *prop) : CSPrimitives(multiBox, prop) +{ + Type=MULTIBOX; + for (size_t i=0;i<multiBox->vCoords.size();++i) + vCoords.push_back(new ParameterScalar(multiBox->vCoords.at(i))); + PrimTypeName = std::string("Multi Box"); +} + +CSPrimMultiBox::CSPrimMultiBox(ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(paraSet,prop) +{ + Type=MULTIBOX; + PrimTypeName = std::string("Multi Box"); +} + +CSPrimMultiBox::~CSPrimMultiBox() +{ +} + +void CSPrimMultiBox::SetCoord(int index, double val) +{ + if ((index>=0) && (index<(int)vCoords.size())) + vCoords.at(index)->SetValue(val); +} + +void CSPrimMultiBox::SetCoord(int index, const char* val) +{ + if ((index>=0) && (index<(int)vCoords.size())) + vCoords.at(index)->SetValue(val); +} + +void CSPrimMultiBox::AddCoord(double val) +{ + vCoords.push_back(new ParameterScalar(clParaSet,val)); +} + +void CSPrimMultiBox::AddCoord(const char* val) +{ + vCoords.push_back(new ParameterScalar(clParaSet,val)); +} + +void CSPrimMultiBox::AddBox(int initBox) +{ + ClearOverlap(); + if ((initBox<0) || (((initBox+1)*6)>(int)vCoords.size())) + { + for (unsigned int i=0;i<6;++i) + AddCoord(0.0); + } + else for (unsigned int i=0;i<6;++i) + vCoords.push_back(new ParameterScalar(vCoords.at(6*initBox+i))); +} + +void CSPrimMultiBox::DeleteBox(size_t box) +{ + if ((box+1)*6>vCoords.size()) return; + std::vector<ParameterScalar*>::iterator start=vCoords.begin()+(box*6); + std::vector<ParameterScalar*>::iterator end=vCoords.begin()+(box*6+6); + + vCoords.erase(start,end); +} + + +double CSPrimMultiBox::GetCoord(int index) +{ + if ((index>=0) && (index<(int)vCoords.size())) + return vCoords.at(index)->GetValue(); + return 0; +} + +ParameterScalar* CSPrimMultiBox::GetCoordPS(int index) +{ + if ((index>=0) && (index<(int)vCoords.size())) + return vCoords.at(index); + return NULL; +} + +double* CSPrimMultiBox::GetAllCoords(size_t &Qty, double* array) +{ + Qty=vCoords.size(); + delete[] array; + array = new double[Qty]; + for (size_t i=0;i<Qty;++i) + array[i]=vCoords.at(i)->GetValue(); + return array; +} + +void CSPrimMultiBox::ClearOverlap() +{ + if (vCoords.size()%6==0) return; //no work to be done + + vCoords.resize(vCoords.size()-vCoords.size()%6); +} + +bool CSPrimMultiBox::GetBoundBox(double dBoundBox[6], bool PreserveOrientation) +{ + UNUSED(PreserveOrientation); //has no orientation or preserved anyways + for (int n=0;n<6;++n) dBoundBox[n] = 0; + //Update(); + for (unsigned int i=0;i<vCoords.size()/6;++i) + { + for (unsigned int n=0;n<3;++n) + { + if (vCoords.at(6*i+2*n)->GetValue()<=vCoords.at(6*i+2*n+1)->GetValue()) + { + if (i==0) + { + dBoundBox[2*n]=vCoords.at(6*i+2*n)->GetValue(); + dBoundBox[2*n+1]=vCoords.at(6*i+2*n+1)->GetValue(); + } + else + { + if (vCoords.at(6*i+2*n)->GetValue()<dBoundBox[2*n]) dBoundBox[2*n]=vCoords.at(6*i+2*n)->GetValue(); + if (vCoords.at(6*i+2*n+1)->GetValue()>dBoundBox[2*n+1]) dBoundBox[2*n+1]=vCoords.at(6*i+2*n+1)->GetValue(); + } + + } + else + { + if (i==0) + { + dBoundBox[2*n]=vCoords.at(6*i+2*n+1)->GetValue(); + dBoundBox[2*n+1]=vCoords.at(6*i+2*n)->GetValue(); + } + else + { + if (vCoords.at(6*i+2*n+1)->GetValue()<dBoundBox[2*n]) dBoundBox[2*n]=vCoords.at(6*i+2*n+1)->GetValue(); + if (vCoords.at(6*i+2*n)->GetValue()>dBoundBox[2*n+1]) dBoundBox[2*n+1]=vCoords.at(6*i+2*n)->GetValue(); + } + } + } + } + m_Dimension=0; + m_BoundBox_CoordSys = m_MeshType; + for (int n=0;n<3;++n) + { + if (dBoundBox[2*n]!=dBoundBox[2*n+1]) + ++m_Dimension; + } + return false; +} + +bool CSPrimMultiBox::IsInside(const double* Coord, double /*tol*/) +{ + if (Coord==NULL) return false; + bool in=false; + double UpVal,DownVal; + double coords[3]={Coord[0],Coord[1],Coord[2]}; + TransformCoords(coords, true, m_MeshType); + //fprintf(stderr,"here\n"); + for (unsigned int i=0;i<vCoords.size()/6;++i) + { + in=true; + for (unsigned int n=0;n<3;++n) + { + //fprintf(stderr,"%e %e %e \n",vCoords.at(6*i+2*n)->GetValue(),vCoords.at(6*i+2*n+1)->GetValue()); + UpVal=vCoords.at(6*i+2*n+1)->GetValue(); + DownVal=vCoords.at(6*i+2*n)->GetValue(); + if (DownVal<UpVal) + { + if (DownVal>coords[n]) {in=false;break;} + if (UpVal<coords[n]) {in=false;break;} + } + else + { + if (DownVal<coords[n]) {in=false;break;} + if (UpVal>coords[n]) {in=false;break;} + } + } + if (in==true) { return true;} + } + return false; +} + +bool CSPrimMultiBox::Update(std::string *ErrStr) +{ + int EC=0; + bool bOK=true; + for (size_t i=0;i<vCoords.size();++i) + { + EC=vCoords.at(i)->Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=0) && (ErrStr!=NULL)) + { + bOK=false; + std::stringstream stream; + stream << std::endl << "Error in MultiBox (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + } + //update local bounding box + m_BoundBoxValid = GetBoundBox(m_BoundBox); + return bOK; +} + +bool CSPrimMultiBox::Write2XML(TiXmlElement &elem, bool parameterised) +{ + CSPrimitives::Write2XML(elem,parameterised); + elem.SetAttribute("QtyBox",(int)vCoords.size()/6); + + for (size_t i=0;i<vCoords.size()/6;++i) + { + TiXmlElement SP("StartP"); + WriteTerm(*vCoords.at(i*6),SP,"X",parameterised); + WriteTerm(*vCoords.at(i*6+2),SP,"Y",parameterised); + WriteTerm(*vCoords.at(i*6+4),SP,"Z",parameterised); + elem.InsertEndChild(SP); + + TiXmlElement EP("EndP"); + WriteTerm(*vCoords.at(i*6+1),EP,"X",parameterised); + WriteTerm(*vCoords.at(i*6+3),EP,"Y",parameterised); + WriteTerm(*vCoords.at(i*6+5),EP,"Z",parameterised); + elem.InsertEndChild(EP); + } + return true; +} + +bool CSPrimMultiBox::ReadFromXML(TiXmlNode &root) +{ + if (CSPrimitives::ReadFromXML(root)==false) return false;; + + TiXmlElement *SP=root.FirstChildElement("StartP"); + TiXmlElement *EP=root.FirstChildElement("EndP"); + if (vCoords.size()!=0) return false; + int i=0; + while ((SP!=NULL) && (EP!=NULL)) + { + for (int n=0;n<6;++n) this->AddCoord(0.0); + + if (ReadTerm(*vCoords.at(i*6),*SP,"X")==false) return false; + if (ReadTerm(*vCoords.at(i*6+2),*SP,"Y")==false) return false; + if (ReadTerm(*vCoords.at(i*6+4),*SP,"Z")==false) return false; + + if (ReadTerm(*vCoords.at(i*6+1),*EP,"X")==false) return false; + if (ReadTerm(*vCoords.at(i*6+3),*EP,"Y")==false) return false; + if (ReadTerm(*vCoords.at(i*6+5),*EP,"Z")==false) return false; + +// for (int n=0;n<6;++n) fprintf(stderr,"%e ",vCoords.at(i*6+n)->GetValue()); +// fprintf(stderr,"\n"); + + SP=SP->NextSiblingElement("StartP"); + EP=EP->NextSiblingElement("EndP"); + ++i; + }; + return true; +} diff --git a/CSXCAD/src/CSPrimMultiBox.h b/CSXCAD/src/CSPrimMultiBox.h new file mode 100644 index 0000000..d2d204a --- /dev/null +++ b/CSXCAD/src/CSPrimMultiBox.h @@ -0,0 +1,64 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" + +//! Multi-Box Primitive (Multi-Cube) +/*! + This is a primitive defined by multiple cubes. Mostly used for already discretized objects. + */ +class CSXCAD_EXPORT CSPrimMultiBox : public CSPrimitives +{ +public: + CSPrimMultiBox(ParameterSet* paraSet, CSProperties* prop); + CSPrimMultiBox(CSPrimMultiBox* multiBox,CSProperties *prop=NULL); + CSPrimMultiBox(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimMultiBox(); + + virtual CSPrimitives* GetCopy(CSProperties *prop=NULL) {return new CSPrimMultiBox(this,prop);} + + void SetCoord(int index, double val); + void SetCoord(int index, const char* val); + + void AddCoord(double val); + void AddCoord(const char* val); + + void AddBox(int initBox=-1); + void DeleteBox(size_t box); + + double GetCoord(int index); + ParameterScalar* GetCoordPS(int index); + + double* GetAllCoords(size_t &Qty, double* array); + + void ClearOverlap(); + + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false); + virtual bool IsInside(const double* Coord, double tol=0); + + unsigned int GetQtyBoxes() {return (unsigned int) vCoords.size()/6;} + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + +protected: + std::vector<ParameterScalar*> vCoords; +}; + diff --git a/CSXCAD/src/CSPrimPoint.cpp b/CSXCAD/src/CSPrimPoint.cpp new file mode 100644 index 0000000..8ed258d --- /dev/null +++ b/CSXCAD/src/CSPrimPoint.cpp @@ -0,0 +1,126 @@ +/* +* 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 "CSPrimPoint.h" +#include "CSProperties.h" +#include "CSUseful.h" + +CSPrimPoint::CSPrimPoint(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(ID,paraSet,prop) +{ + Type = POINT; + m_Coords.SetParameterSet(paraSet); + PrimTypeName = "Point"; +} + +CSPrimPoint::CSPrimPoint(CSPrimPoint* primPoint, CSProperties *prop) : CSPrimitives(primPoint,prop) +{ + Type = POINT; + m_Coords.Copy(&primPoint->m_Coords); + PrimTypeName = "Point"; +} + +CSPrimPoint::CSPrimPoint(ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(paraSet,prop) +{ + Type = POINT; + m_Coords.SetParameterSet(paraSet); + PrimTypeName = "Point"; +} + +CSPrimPoint::~CSPrimPoint() +{ +} + +void CSPrimPoint::SetCoord(int index, double val) +{ + m_Coords.SetValue(index,val); +} + +void CSPrimPoint::SetCoord(int index, const std::string val) +{ + m_Coords.SetValue(index,val); +} + +double CSPrimPoint::GetCoord(int index) +{ + return m_Coords.GetCoordValue(index,m_MeshType); +} + +ParameterScalar* CSPrimPoint::GetCoordPS(int index) +{ + return m_Coords.GetCoordPS(index); +} + +bool CSPrimPoint::GetBoundBox(double dBoundBox[6], bool PreserveOrientation) +{ + UNUSED(PreserveOrientation); //has no orientation or preserved anyways + const double *coord = m_Coords.GetCoords(m_MeshType); + for (int i=0; i<3; i++) + { + dBoundBox[2*i] = coord[i]; + dBoundBox[2*i+1] = coord[i]; + } + m_Dimension=0; + m_BoundBox_CoordSys = m_PrimCoordSystem; + return true; +} + +bool CSPrimPoint::IsInside(const double* /*Coord*/, double /*tol*/) +{ + // this is a 0D-object, you can never be inside... + return false; +} + + +bool CSPrimPoint::Update(std::string *ErrStr) +{ + bool bOK=m_Coords.Evaluate(ErrStr); + if (bOK==false) + { + std::stringstream stream; + stream << std::endl << "Error in Point (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + } + m_Coords.SetCoordinateSystem(m_PrimCoordSystem, m_MeshType); + //update local bounding box + m_BoundBoxValid = GetBoundBox(m_BoundBox); + return bOK; +} + +bool CSPrimPoint::Write2XML(TiXmlElement &elem, bool parameterised) +{ + CSPrimitives::Write2XML(elem,parameterised); + return m_Coords.Write2XML(&elem,parameterised); +} + +bool CSPrimPoint::ReadFromXML(TiXmlNode &root) +{ + if (!CSPrimitives::ReadFromXML(root)) return false; + return m_Coords.ReadFromXML(dynamic_cast<TiXmlElement*>(&root)); +} + + +void CSPrimPoint::ShowPrimitiveStatus(std::ostream& stream) +{ + CSPrimitives::ShowPrimitiveStatus(stream); + stream << " Coordinate: " << m_Coords.GetValueString(0) << "," << m_Coords.GetValueString(1) << "," << m_Coords.GetValueString(2) << std::endl; +} diff --git a/CSXCAD/src/CSPrimPoint.h b/CSXCAD/src/CSPrimPoint.h new file mode 100644 index 0000000..890b45c --- /dev/null +++ b/CSXCAD/src/CSPrimPoint.h @@ -0,0 +1,59 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" + +//! Point Primitive +/*! + This is a point primitive (useful for field probes). + */ +class CSXCAD_EXPORT CSPrimPoint : public CSPrimitives +{ +public: + CSPrimPoint(ParameterSet* paraSet, CSProperties* prop); + CSPrimPoint(CSPrimPoint* primPoint, CSProperties *prop=NULL); + CSPrimPoint(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimPoint(); + + virtual CSPrimPoint* GetCopy(CSProperties *prop=NULL) {return new CSPrimPoint(this,prop);} + + void SetCoord(int index, double val); + void SetCoord(int index, const std::string val); + void SetCoords( double c1, double c2, double c3 ); + + //! Get the point coordinates according to the input mesh type + double GetCoord(int index); + ParameterScalar* GetCoordPS(int index); + + const ParameterCoord* GetCoords() const {return &m_Coords;} + + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false); + virtual bool IsInside(const double* Coord, double tol=0); + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual void ShowPrimitiveStatus(std::ostream& stream); + +protected: + //! Vector describing the point: x,y,z + ParameterCoord m_Coords; +}; + diff --git a/CSXCAD/src/CSPrimPolygon.cpp b/CSXCAD/src/CSPrimPolygon.cpp new file mode 100644 index 0000000..733fb0a --- /dev/null +++ b/CSXCAD/src/CSPrimPolygon.cpp @@ -0,0 +1,294 @@ +/* +* 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 "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;i<Qty;++i) array[i]=vCoords.at(i).GetValue(); + return array; +} + + +bool CSPrimPolygon::GetBoundBox(double dBoundBox[6], bool PreserveOrientation) +{ + UNUSED(PreserveOrientation); //has no orientation or preserved anyways + bool accurate=false; + m_BoundBox_CoordSys = CARTESIAN; + if (vCoords.size()<2) + { + for (int i=0;i<6;++i) dBoundBox[i]=0; + return dBoundBox; + } + double xmin = vCoords.at(0).GetValue(), xmax = vCoords.at(0).GetValue(); + double ymin = vCoords.at(1).GetValue(), ymax = vCoords.at(1).GetValue(); + for (size_t i=1;i<vCoords.size()/2;++i) + { + double x = vCoords.at(2*i).GetValue(); + double y = vCoords.at(2*i+1).GetValue(); + if (x<xmin) xmin=x; + else if (x>xmax) xmax=x; + if (y<ymin) ymin=y; + else if (y>ymax) 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]<Coord[n])) return false; + + double x=0,y=0; + int nP = (m_NormDir+1)%3; + int nPP = (m_NormDir+2)%3; + x = Coord[nP]; + y = Coord[nPP]; + + int wn = 0; + + size_t np = vCoords.size()/2; + double x1 = vCoords[2*np-2].GetValue(); + double y1 = vCoords[2*np-1].GetValue(); + double x2 = vCoords[0].GetValue(); + double y2 = vCoords[1].GetValue(); + bool startover = y1 >= y ? true : false; + bool endover; + + for (size_t i=0;i<np;++i) + { + x2 = vCoords[2*i].GetValue(); + y2 = vCoords[2*i+1].GetValue(); + + //check if coord is on a cartesian edge exactly + if ((x2==x1) && (x1==x) && ( ((y<y1) && (y>y2)) || ((y>y1) && (y<y2)) )) + return true; + if ((y2==y1) && (y1==y) && ( ((x<x1) && (x>x2)) || ((x>x1) && (x<x2)) )) + return true; + + endover = y2 >= 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;i<vCoords.size();++i) + { + EC=vCoords[i].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 (ID: " << uiID << "): "; + ErrStr->append(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;i<vCoords.size()/2;++i) + { + TiXmlElement VT("Vertex"); + WriteTerm(vCoords.at(i*2),VT,"X1",parameterised); + WriteTerm(vCoords.at(i*2+1),VT,"X2",parameterised); + elem.InsertEndChild(VT); + } + return true; +} + +bool CSPrimPolygon::ReadFromXML(TiXmlNode &root) +{ + if (CSPrimitives::ReadFromXML(root)==false) return false; + + TiXmlElement *elem = root.ToElement(); + if (elem==NULL) return false; + if (ReadTerm(Elevation,*elem,"Elevation")==false) + Elevation.SetValue(0); + + int help; + if (elem->QueryIntAttribute("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; +} diff --git a/CSXCAD/src/CSPrimPolygon.h b/CSXCAD/src/CSPrimPolygon.h new file mode 100644 index 0000000..f7bb371 --- /dev/null +++ b/CSXCAD/src/CSPrimPolygon.h @@ -0,0 +1,77 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" + +//! 2D Polygon Primitive +/*! + This is an area polygon primitive defined by a number of points in space. + Warning: This primitive currently can only be defined in Cartesian coordinates. + */ +class CSXCAD_EXPORT CSPrimPolygon : public CSPrimitives +{ +public: + CSPrimPolygon(ParameterSet* paraSet, CSProperties* prop); + CSPrimPolygon(CSPrimPolygon* primPolygon, CSProperties *prop=NULL); + CSPrimPolygon(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimPolygon(); + + virtual CSPrimPolygon* GetCopy(CSProperties *prop=NULL) {return new CSPrimPolygon(this,prop);} + + void SetCoord(int index, double val); + void SetCoord(int index, const std::string val); + + void AddCoord(double val); + void AddCoord(const std::string val); + + void RemoveCoords(int index); + void ClearCoords() {vCoords.clear();} + + double GetCoord(int index); + ParameterScalar* GetCoordPS(int index); + + size_t GetQtyCoords() {return vCoords.size()/2;} + double* GetAllCoords(size_t &Qty, double* array); + + void SetNormDir(int dir) {if ((dir>=0) && (dir<3)) m_NormDir=dir;} + + int GetNormDir() {return m_NormDir;} + + void SetElevation(double val) {Elevation.SetValue(val);} + void SetElevation(const char* val) {Elevation.SetValue(val);} + + double GetElevation() {return Elevation.GetValue();} + ParameterScalar* GetElevationPS() {return &Elevation;} + + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false); + virtual bool IsInside(const double* Coord, double tol=0); + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + +protected: + ///Vector describing the polygon, x1,y1,x2,y2 ... xn,yn + std::vector<ParameterScalar> vCoords; + ///The polygon plane normal direction + int m_NormDir; + ///The polygon plane elevation in direction of the normal vector + ParameterScalar Elevation; +}; + 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; +} diff --git a/CSXCAD/src/CSPrimPolyhedron.h b/CSXCAD/src/CSPrimPolyhedron.h new file mode 100644 index 0000000..25c2add --- /dev/null +++ b/CSXCAD/src/CSPrimPolyhedron.h @@ -0,0 +1,83 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" + +struct CSPrimPolyhedronPrivate; + +//! Polyhedron Primitive +/*! + This is a polyhedron primitive. A 3D solid object, defined by vertices and faces + */ +class CSXCAD_EXPORT CSPrimPolyhedron : public CSPrimitives +{ + friend class Polyhedron_Builder; +public: + struct face + { + unsigned int numVertex; + int* vertices; + bool valid; + }; + struct vertex + { + float coord[3]; + }; + + CSPrimPolyhedron(ParameterSet* paraSet, CSProperties* prop); + CSPrimPolyhedron(CSPrimPolyhedron* primPolyhedron, CSProperties *prop=NULL); + CSPrimPolyhedron(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimPolyhedron(); + + virtual void Reset(); + + virtual void AddVertex(float p[3]) {AddVertex(p[0],p[1],p[2]);} + virtual void AddVertex(double p[3]) {AddVertex(p[0],p[1],p[2]);} + virtual void AddVertex(float px, float py, float pz); + + virtual unsigned int GetNumVertices() const {return m_Vertices.size();} + virtual float* GetVertex(unsigned int n); + + virtual void AddFace(face f); + virtual void AddFace(int numVertex, int* vertices); + virtual void AddFace(std::vector<int> vertices); + + virtual bool BuildTree(); + + virtual unsigned int GetNumFaces() const {return m_Faces.size();} + virtual int* GetFace(unsigned int n, unsigned int &numVertices); + virtual bool GetFaceValid(unsigned int n) const {return m_Faces.at(n).valid;} + + virtual CSPrimPolyhedron* GetCopy(CSProperties *prop=NULL) {return new CSPrimPolyhedron(this,prop);} + + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false); + virtual bool IsInside(const double* Coord, double tol=0); + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual void ShowPrimitiveStatus(std::ostream& stream); + +protected: + unsigned int m_InvalidFaces; + std::vector<vertex> m_Vertices; + std::vector<face> m_Faces; + CSPrimPolyhedronPrivate *d_ptr; //!< pointer to private data structure, to hide the CGAL dependency from applications +}; diff --git a/CSXCAD/src/CSPrimPolyhedronReader.cpp b/CSXCAD/src/CSPrimPolyhedronReader.cpp new file mode 100644 index 0000000..ed224fd --- /dev/null +++ b/CSXCAD/src/CSPrimPolyhedronReader.cpp @@ -0,0 +1,177 @@ +/* +* 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 <vtkSTLReader.h> +#include <vtkPLYReader.h> +#include <vtkPolyData.h> +#include <vtkCellArray.h> + +#include "CSPrimPolyhedronReader.h" +#include "CSProperties.h" +#include "CSUseful.h" + +CSPrimPolyhedronReader::CSPrimPolyhedronReader(ParameterSet* paraSet, CSProperties* prop): CSPrimPolyhedron(paraSet,prop) +{ + Type = POLYHEDRONREADER; + PrimTypeName = "PolyhedronReader"; + m_filetype = UNKNOWN; + m_filename = std::string(); +} + +CSPrimPolyhedronReader::CSPrimPolyhedronReader(CSPrimPolyhedronReader* primPHReader, CSProperties *prop) : CSPrimPolyhedron(primPHReader, prop) +{ + Type = POLYHEDRONREADER; + PrimTypeName = "PolyhedronReader"; + + m_filename = primPHReader->m_filename; + m_filetype = primPHReader->m_filetype; +} + +CSPrimPolyhedronReader::CSPrimPolyhedronReader(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimPolyhedron(ID, paraSet, prop) +{ + Type = POLYHEDRONREADER; + PrimTypeName = "PolyhedronReader"; + m_filetype = UNKNOWN; + m_filename = std::string(); +} + +CSPrimPolyhedronReader::~CSPrimPolyhedronReader() +{ +} + +bool CSPrimPolyhedronReader::Update(std::string *ErrStr) +{ + return CSPrimPolyhedron::Update(ErrStr); +} + +bool CSPrimPolyhedronReader::Write2XML(TiXmlElement &elem, bool parameterised) +{ + elem.SetAttribute("Filename",m_filename); + + switch (m_filetype) + { + case STL_FILE: + elem.SetAttribute("FileType","STL"); + break; + case PLY_FILE: + elem.SetAttribute("FileType","PLY"); + break; + default: + elem.SetAttribute("FileType","Unkown"); + break; + } + return CSPrimitives::Write2XML(elem,parameterised); +} + +bool CSPrimPolyhedronReader::ReadFromXML(TiXmlNode &root) +{ + if (!CSPrimitives::ReadFromXML(root)) return false; + + TiXmlElement* elem=root.ToElement(); + if (elem==NULL) return false; + if (elem->QueryStringAttribute("FileName",&m_filename)!=TIXML_SUCCESS) + { + std::cerr << "CSPrimPolyhedronReader::ReadFromXML: Error, can't read filename!" << std::endl; + return false; + } + std::string type; + if (elem->QueryStringAttribute("FileType",&type)!=TIXML_SUCCESS) + { + std::cerr << "CSPrimPolyhedronReader::ReadFromXML: Error, can't read file type!" << std::endl; + return false; + } + if (type.compare("STL")==0) + m_filetype=STL_FILE; + else if (type.compare("PLY")==0) + m_filetype=PLY_FILE; + else + m_filetype=UNKNOWN; + + if (ReadFile()==false) + { + std::cerr << "CSPrimPolyhedronReader::ReadFromXML: Failed to read file." << std::endl; + return false; + } + + return BuildTree(); +} + +bool CSPrimPolyhedronReader::ReadFile() +{ + vtkPolyData *polydata = NULL; + switch (m_filetype) + { + case STL_FILE: + { + vtkSTLReader* reader = vtkSTLReader::New(); + reader->SetFileName(m_filename.c_str()); + reader->SetMerging(1); + polydata = reader->GetOutput(0); + reader->Update(); + break; + } + case PLY_FILE: + { + vtkPLYReader* reader = vtkPLYReader::New(); + reader->SetFileName(m_filename.c_str()); + polydata = reader->GetOutput(0); + reader->Update(); + break; + } + case UNKNOWN: + default: + { + std::cerr << "CSPrimPolyhedronReader::ReadFile: unknown filetype, skipping..." << std::endl; + return false; + break; + } + } + //polydata->Update(); // not availabe for vtk 6.x, now done only on reader? + if ((polydata->GetNumberOfPoints()==0) || (polydata->GetNumberOfCells()==0)) + { + std::cerr << "CSPrimPolyhedronReader::ReadFile: file invalid or empty, skipping ..." << std::endl; + return false; + } + vtkCellArray *verts = polydata->GetPolys(); + if (verts->GetNumberOfCells()==0) + { + std::cerr << "CSPrimPolyhedronReader::ReadFile: file invalid or empty, skipping ..." << std::endl; + return false; + } + + for (int n=0;n<polydata->GetNumberOfPoints();++n) + AddVertex(polydata->GetPoint(n)); + + vtkIdType numP; + vtkIdType *vertices = new vtkIdType[10]; + while (verts->GetNextCell(numP, vertices)) + { + face f; + f.numVertex=numP; + f.vertices = new int[f.numVertex]; + for (unsigned int np=0;np<f.numVertex;++np) + f.vertices[np]=vertices[np]; + AddFace(f); + } + return true; +} diff --git a/CSXCAD/src/CSPrimPolyhedronReader.h b/CSXCAD/src/CSPrimPolyhedronReader.h new file mode 100644 index 0000000..60e8c52 --- /dev/null +++ b/CSXCAD/src/CSPrimPolyhedronReader.h @@ -0,0 +1,55 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" +#include "CSPrimPolyhedron.h" + +//! STL/PLY import primitive +class CSXCAD_EXPORT CSPrimPolyhedronReader : public CSPrimPolyhedron +{ +public: + //! Import file type + enum FileType + { + UNKNOWN, STL_FILE, PLY_FILE + }; + + CSPrimPolyhedronReader(ParameterSet* paraSet, CSProperties* prop); + CSPrimPolyhedronReader(CSPrimPolyhedronReader* primPHReader, CSProperties *prop=NULL); + CSPrimPolyhedronReader(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimPolyhedronReader(); + + virtual CSPrimPolyhedronReader* GetCopy(CSProperties *prop=NULL) {return new CSPrimPolyhedronReader(this,prop);} + + virtual void SetFilename(std::string name) {m_filename=name;} + virtual std::string GetFilename() const {return m_filename;} + + virtual void SetFileType(FileType ft) {m_filetype=ft;} + virtual FileType GetFileType() const {return m_filetype;} + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual bool ReadFile(); + +protected: + std::string m_filename; + FileType m_filetype; +}; diff --git a/CSXCAD/src/CSPrimPolyhedron_p.h b/CSXCAD/src/CSPrimPolyhedron_p.h new file mode 100644 index 0000000..e2877cc --- /dev/null +++ b/CSXCAD/src/CSPrimPolyhedron_p.h @@ -0,0 +1,48 @@ +#ifndef CSPRIMPOLYHEDRON_P_H +#define CSPRIMPOLYHEDRON_P_H + +#include <CGAL/Simple_cartesian.h> +#include <CGAL/Polyhedron_incremental_builder_3.h> +#include <CGAL/Polyhedron_3.h> +#include <CGAL/AABB_tree.h> +#include <CGAL/AABB_traits.h> +#if CGAL_VERSION_NR >= CGAL_VERSION_NUMBER(4,6,0) + #include <CGAL/AABB_face_graph_triangle_primitive.h> +#else + #include <CGAL/AABB_polyhedron_triangle_primitive.h> + #include <CGAL/AABB_polyhedron_segment_primitive.h> +#endif + +typedef CGAL::Simple_cartesian<double> Kernel; +typedef CGAL::Polyhedron_3<Kernel> Polyhedron; +typedef Polyhedron::HalfedgeDS HalfedgeDS; + +class Polyhedron_Builder : public CGAL::Modifier_base<HalfedgeDS> +{ +public: + Polyhedron_Builder(CSPrimPolyhedron* polyhedron) {m_polyhedron=polyhedron;} + void operator()(HalfedgeDS &hds); + +protected: + CSPrimPolyhedron* m_polyhedron; +}; + +typedef Kernel::Point_3 Point; +#if CGAL_VERSION_NR >= CGAL_VERSION_NUMBER(4,6,0) +typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive; +#else +typedef CGAL::AABB_polyhedron_triangle_primitive<Kernel,Polyhedron> Primitive; +#endif +typedef CGAL::AABB_traits<Kernel, Primitive> Traits; +typedef CGAL::Simple_cartesian<double>::Ray_3 Ray; +typedef Kernel::Segment_3 Segment; + +struct CSPrimPolyhedronPrivate +{ + Polyhedron m_Polyhedron; + Point m_RandPt; + CGAL::AABB_tree<Traits> *m_PolyhedronTree; +}; + + +#endif // CSPRIMPOLYHEDRON_P_H diff --git a/CSXCAD/src/CSPrimRotPoly.cpp b/CSXCAD/src/CSPrimRotPoly.cpp new file mode 100644 index 0000000..705b08e --- /dev/null +++ b/CSXCAD/src/CSPrimRotPoly.cpp @@ -0,0 +1,191 @@ +/* +* 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 <math.h> + +#include "CSPrimRotPoly.h" +#include "CSProperties.h" +#include "CSUseful.h" + +CSPrimRotPoly::CSPrimRotPoly(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimPolygon(ID,paraSet,prop) +{ + Type=ROTPOLY; + m_RotAxisDir=0; + PrimTypeName = std::string("RotPoly"); +} + +CSPrimRotPoly::CSPrimRotPoly(CSPrimRotPoly* primRotPoly, CSProperties *prop) : CSPrimPolygon(primRotPoly,prop) +{ + Type=ROTPOLY; + m_RotAxisDir=primRotPoly->m_RotAxisDir; + PrimTypeName = std::string("RotPoly"); +} + +CSPrimRotPoly::CSPrimRotPoly(ParameterSet* paraSet, CSProperties* prop) : CSPrimPolygon(paraSet,prop) +{ + Type=ROTPOLY; + m_RotAxisDir=0; + PrimTypeName = std::string("RotPoly"); +} + +CSPrimRotPoly::~CSPrimRotPoly() +{ +} + +bool CSPrimRotPoly::IsInside(const double* inCoord, double /*tol*/) +{ + if (inCoord==NULL) return false; + + double Coord[3]; + //transform incoming coordinates into cartesian coords + TransformCoordSystem(inCoord,Coord,m_MeshType,CARTESIAN); + if (m_Transform && Type==ROTPOLY) + TransformCoords(Coord,true, CARTESIAN); + + double origin[3]={0,0,0}; + double dir[3]={0,0,0}; + dir[m_RotAxisDir] = 1; + double foot; + double dist; + Point_Line_Distance(Coord, origin, dir, foot, dist); + + int raP = (m_RotAxisDir+1)%3; + int raPP = (m_RotAxisDir+2)%3; + double alpha = atan2(Coord[raPP],Coord[raP]); + if (raP == m_NormDir) + alpha=alpha-M_PI/2; + if (alpha<0) + alpha+=2*M_PI; + + origin[0] = dist;origin[1] = dist;origin[2] = dist; + origin[m_NormDir] = 0; + origin[m_RotAxisDir] = foot; + + if (alpha<m_StartStopAng[0]) + alpha+=2*M_PI; + + if ((CSPrimPolygon::IsInside(origin)) && (alpha<m_StartStopAng[1])) + return true; + + dist*=-1; + alpha=alpha+M_PI; + if (alpha>2*M_PI) + alpha-=2*M_PI; + + if (alpha<m_StartStopAng[0]) + alpha+=2*M_PI; + + if (alpha>m_StartStopAng[1]) + return false; + + origin[0] = dist;origin[1] = dist;origin[2] = dist; + origin[m_NormDir] = 0; + origin[m_RotAxisDir] = foot; + return CSPrimPolygon::IsInside(origin); +} + + +bool CSPrimRotPoly::Update(std::string *ErrStr) +{ + int EC=0; + bool bOK = CSPrimPolygon::Update(ErrStr); + + EC=StartStopAngle[0].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 RotPoly Start Angle (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + EC=StartStopAngle[1].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 RotPoly Stop Angle (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + // make angle range to 0..2*M_PI & stop > start! + m_StartStopAng[0]=StartStopAngle[0].GetValue(); + m_StartStopAng[1]=StartStopAngle[1].GetValue(); + if (m_StartStopAng[0]>m_StartStopAng[1]) + m_StartStopAng[1]+=2*M_PI; + if (m_StartStopAng[0]>2*M_PI) + { + m_StartStopAng[0]-=2*M_PI; + m_StartStopAng[1]-=2*M_PI; + } + if (m_StartStopAng[0]<0) + { + m_StartStopAng[0]+=2*M_PI; + m_StartStopAng[1]+=2*M_PI; + } + + //update local bounding box + m_BoundBoxValid = GetBoundBox(m_BoundBox); + + return bOK; +} + +bool CSPrimRotPoly::Write2XML(TiXmlElement &elem, bool parameterised) +{ + CSPrimPolygon::Write2XML(elem,parameterised); + + elem.SetAttribute("RotAxisDir",m_RotAxisDir); + + TiXmlElement Ang("Angles"); + WriteTerm(StartStopAngle[0],Ang,"Start",parameterised); + WriteTerm(StartStopAngle[1],Ang,"Stop",parameterised); + elem.InsertEndChild(Ang); + return true; +} + +bool CSPrimRotPoly::ReadFromXML(TiXmlNode &root) +{ + if (CSPrimPolygon::ReadFromXML(root)==false) return false; + + if (Elevation.GetValue()!=0) + std::cerr << __func__ << ": Warning: An elevation for a rotational poly is not supported! Skipping!" << std::endl; + Elevation.SetValue(0); + + TiXmlElement *elem = root.ToElement(); + if (elem==NULL) return false; + + int help; + if (elem->QueryIntAttribute("RotAxisDir",&help)!=TIXML_SUCCESS) + return false; + m_RotAxisDir=help; + + TiXmlElement *NV=elem->FirstChildElement("Angles"); + if (NV==NULL) return false; + if (ReadTerm(StartStopAngle[0],*NV,"Start")==false) return false; + if (ReadTerm(StartStopAngle[1],*NV,"Stop")==false) return false; + + return true; +} diff --git a/CSXCAD/src/CSPrimRotPoly.h b/CSXCAD/src/CSPrimRotPoly.h new file mode 100644 index 0000000..174e887 --- /dev/null +++ b/CSXCAD/src/CSPrimRotPoly.h @@ -0,0 +1,61 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" +#include "CSPrimPolygon.h" + +//! Rotational extruded polygon Primitive +/*! + This is a rotation extruded area polygon primitive defined by a number of points in space, an extrude axis and start-, stop-angle. + Warning: This primitive currently can only be defined in Cartesian coordinates. + */ +class CSXCAD_EXPORT CSPrimRotPoly : public CSPrimPolygon +{ +public: + CSPrimRotPoly(ParameterSet* paraSet, CSProperties* prop); + CSPrimRotPoly(CSPrimRotPoly* primPolygon, CSProperties *prop=NULL); + CSPrimRotPoly(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimRotPoly(); + + virtual CSPrimRotPoly* GetCopy(CSProperties *prop=NULL) {return new CSPrimRotPoly(this,prop);} + + void SetRotAxisDir(int dir) {if ((dir>=0) && (dir<3)) m_RotAxisDir=dir;} + + int GetRotAxisDir() const {return m_RotAxisDir;} + + void SetAngle(int index, double val) {if ((index>=0) && (index<2)) StartStopAngle[index].SetValue(val);} + void SetAngle(int index, const std::string val) {if ((index>=0) && (index<2)) StartStopAngle[index].SetValue(val);} + + double GetAngle(int index) const {if ((index>=0) && (index<2)) return StartStopAngle[index].GetValue(); else return 0;} + ParameterScalar* GetAnglePS(int index) {if ((index>=0) && (index<2)) return &StartStopAngle[index]; else return NULL;} + + virtual bool IsInside(const double* Coord, double tol=0); + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + +protected: + //start-stop angle + ParameterScalar StartStopAngle[2]; + //sorted and pre evaluated angles + double m_StartStopAng[2]; + //rot axis direction + int m_RotAxisDir; +}; diff --git a/CSXCAD/src/CSPrimSphere.cpp b/CSXCAD/src/CSPrimSphere.cpp new file mode 100644 index 0000000..a372fe3 --- /dev/null +++ b/CSXCAD/src/CSPrimSphere.cpp @@ -0,0 +1,176 @@ +/* +* 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 "CSPrimSphere.h" +#include "CSProperties.h" +#include "CSUseful.h" + +CSPrimSphere::CSPrimSphere(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(ID,paraSet,prop) +{ + Type=SPHERE; + m_Center.SetParameterSet(paraSet); + psRadius.SetParameterSet(paraSet); + PrimTypeName = std::string("Sphere"); +} + +CSPrimSphere::CSPrimSphere(CSPrimSphere* sphere, CSProperties *prop) : CSPrimitives(sphere,prop) +{ + Type=SPHERE; + m_Center.Copy(&sphere->m_Center); + psRadius.Copy(&sphere->psRadius); + PrimTypeName = std::string("Sphere"); +} + +CSPrimSphere::CSPrimSphere(ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(paraSet,prop) +{ + Type=SPHERE; + m_Center.SetParameterSet(paraSet); + psRadius.SetParameterSet(paraSet); + PrimTypeName = std::string("Sphere"); +} + + +CSPrimSphere::~CSPrimSphere() +{ +} + +void CSPrimSphere::SetCenter(double x1, double x2, double x3) +{ + SetCoord(0,x1); + SetCoord(1,x2); + SetCoord(2,x3); +} + +void CSPrimSphere::SetCenter(double x[3]) +{ + for (int n=0;n<3;++n) + SetCoord(n, x[n]); +} + +void CSPrimSphere::SetCenter(std::string x1, std::string x2, std::string x3) +{ + SetCoord(0,x1); + SetCoord(1,x2); + SetCoord(2,x3); +} + +void CSPrimSphere::SetCenter(std::string x[3]) +{ + for (int n=0;n<3;++n) + SetCoord(n, x[n]); +} + + +bool CSPrimSphere::GetBoundBox(double dBoundBox[6], bool PreserveOrientation) +{ + UNUSED(PreserveOrientation); //has no orientation or preserved anyways + const double* center = m_Center.GetCartesianCoords(); + m_BoundBox_CoordSys=CARTESIAN; + double radius = psRadius.GetValue(); + for (unsigned int i=0;i<3;++i) + { + dBoundBox[2*i]=center[i]-radius; + dBoundBox[2*i+1]=center[i]+radius; + } + if (radius>0) + m_Dimension=3; + else + m_Dimension=0; + return true; +} + +bool CSPrimSphere::IsInside(const double* Coord, double /*tol*/) +{ + if (Coord==NULL) return false; + double out[3]; + const double* center = m_Center.GetCartesianCoords(); + TransformCoordSystem(Coord,out,m_MeshType,CARTESIAN); + if (m_Transform) + m_Transform->InvertTransform(out,out); + double dist=sqrt(pow(out[0]-center[0],2)+pow(out[1]-center[1],2)+pow(out[2]-center[2],2)); + if (dist<psRadius.GetValue()) + return true; + return false; +} + +bool CSPrimSphere::Update(std::string *ErrStr) +{ + int EC=0; + bool bOK=m_Center.Evaluate(ErrStr); + if (bOK==false) + { + std::stringstream stream; + stream << std::endl << "Error in " << PrimTypeName << " Center Point (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + } + m_Center.SetCoordinateSystem(m_PrimCoordSystem, m_MeshType); + + EC=psRadius.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 " << PrimTypeName << " Radius (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + //update local bounding box + m_BoundBoxValid = GetBoundBox(m_BoundBox); + + return bOK; +} + +bool CSPrimSphere::Write2XML(TiXmlElement &elem, bool parameterised) +{ + CSPrimitives::Write2XML(elem,parameterised); + + WriteTerm(psRadius,elem,"Radius",parameterised); + + TiXmlElement Center("Center"); + m_Center.Write2XML(&Center,parameterised); + elem.InsertEndChild(Center); + return true; +} + +bool CSPrimSphere::ReadFromXML(TiXmlNode &root) +{ + if (CSPrimitives::ReadFromXML(root)==false) return false; + + TiXmlElement *elem = root.ToElement(); + if (elem==NULL) return false; + if (ReadTerm(psRadius,*elem,"Radius")==false) return false; + + TiXmlElement* Center=root.FirstChildElement("Center"); + if (m_Center.ReadFromXML(Center) == false) return false; + + return true; +} + +void CSPrimSphere::ShowPrimitiveStatus(std::ostream& stream) +{ + CSPrimitives::ShowPrimitiveStatus(stream); + stream << " Center: " << m_Center.GetValueString(0) << "," << m_Center.GetValueString(1) << "," << m_Center.GetValueString(2) << std::endl; + stream << " Radius: " << psRadius.GetValueString() << std::endl; +} diff --git a/CSXCAD/src/CSPrimSphere.h b/CSXCAD/src/CSPrimSphere.h new file mode 100644 index 0000000..d7fb071 --- /dev/null +++ b/CSXCAD/src/CSPrimSphere.h @@ -0,0 +1,72 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" + +//! Sphere Primitive +/*! + This is a spherical primitive defined by its center coordinates and a radius. + */ +class CSXCAD_EXPORT CSPrimSphere : public CSPrimitives +{ +public: + CSPrimSphere(ParameterSet* paraSet, CSProperties* prop); + CSPrimSphere(CSPrimSphere* sphere, CSProperties *prop=NULL); + CSPrimSphere(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimSphere(); + + virtual CSPrimitives* GetCopy(CSProperties *prop=NULL) {return new CSPrimSphere(this,prop);} + + //! Set the center point coordinate + void SetCoord(int index, double val) {m_Center.SetValue(index,val);} + //! Set the center point coordinate as paramater string + void SetCoord(int index, const char* val) {m_Center.SetValue(index,val);} + //! Set the center point coordinate as paramater string + void SetCoord(int index, std::string val) {m_Center.SetValue(index,val);} + + void SetCenter(double x1, double x2, double x3); + void SetCenter(double x[3]); + + void SetCenter(std::string x1, std::string x2, std::string x3); + void SetCenter(std::string x[3]); + + double GetCoord(int index) {return m_Center.GetValue(index);} + ParameterScalar* GetCoordPS(int index) {return m_Center.GetCoordPS(index);} + ParameterCoord* GetCenter() {return &m_Center;} + + void SetRadius(double val) {psRadius.SetValue(val);} + void SetRadius(const char* val) {psRadius.SetValue(val);} + + double GetRadius() {return psRadius.GetValue();} + ParameterScalar* GetRadiusPS() {return &psRadius;} + + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false); + virtual bool IsInside(const double* Coord, double tol=0); + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual void ShowPrimitiveStatus(std::ostream& stream); + +protected: + ParameterCoord m_Center; + ParameterScalar psRadius; +}; + diff --git a/CSXCAD/src/CSPrimSphericalShell.cpp b/CSXCAD/src/CSPrimSphericalShell.cpp new file mode 100644 index 0000000..73f2d82 --- /dev/null +++ b/CSXCAD/src/CSPrimSphericalShell.cpp @@ -0,0 +1,134 @@ +/* +* 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 "CSPrimSphericalShell.h" +#include "CSProperties.h" +#include "CSUseful.h" + +CSPrimSphericalShell::CSPrimSphericalShell(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimSphere(ID,paraSet,prop) +{ + Type=SPHERICALSHELL; + PrimTypeName = std::string("SphericalShell"); + psShellWidth.SetParameterSet(paraSet); +} + +CSPrimSphericalShell::CSPrimSphericalShell(CSPrimSphericalShell* sphere, CSProperties *prop) : CSPrimSphere(sphere,prop) +{ + Type=SPHERICALSHELL; + PrimTypeName = std::string("SphericalShell"); + psShellWidth.Copy(&sphere->psShellWidth); +} + +CSPrimSphericalShell::CSPrimSphericalShell(ParameterSet* paraSet, CSProperties* prop) : CSPrimSphere(paraSet,prop) +{ + Type=SPHERICALSHELL; + PrimTypeName = std::string("SphericalShell"); + psShellWidth.SetParameterSet(paraSet); +} + + +CSPrimSphericalShell::~CSPrimSphericalShell() +{ +} + +bool CSPrimSphericalShell::GetBoundBox(double dBoundBox[6], bool PreserveOrientation) +{ + UNUSED(PreserveOrientation); //has no orientation or preserved anyways + const double* center = m_Center.GetCartesianCoords(); + m_BoundBox_CoordSys=CARTESIAN; + double radius = psRadius.GetValue(); + double shellwidth = psShellWidth.GetValue(); + for (unsigned int i=0;i<3;++i) + { + dBoundBox[2*i]=center[i]-radius-shellwidth/2.0; + dBoundBox[2*i+1]=center[i]+radius+shellwidth/2.0; + } + if (shellwidth>0) + m_Dimension=3; + else if (radius>0) + m_Dimension=1; + else + m_Dimension=0; + return true; +} + +bool CSPrimSphericalShell::IsInside(const double* Coord, double /*tol*/) +{ + if (Coord==NULL) return false; + double out[3]; + const double* center = m_Center.GetCartesianCoords(); + TransformCoordSystem(Coord,out,m_MeshType,CARTESIAN); + if (m_Transform) + m_Transform->InvertTransform(out,out); + double dist=sqrt(pow(out[0]-center[0],2)+pow(out[1]-center[1],2)+pow(out[2]-center[2],2)); + if (fabs(dist-psRadius.GetValue())< psShellWidth.GetValue()/2.0) + return true; + return false; +} + +bool CSPrimSphericalShell::Update(std::string *ErrStr) +{ + int EC=0; + bool bOK=CSPrimSphere::Update(ErrStr); + + EC=psShellWidth.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 " << PrimTypeName << " shell-width (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + //update local bounding box + m_BoundBoxValid = GetBoundBox(m_BoundBox); + + return bOK; +} + +bool CSPrimSphericalShell::Write2XML(TiXmlElement &elem, bool parameterised) +{ + CSPrimSphere::Write2XML(elem,parameterised); + + WriteTerm(psShellWidth,elem,"ShellWidth",parameterised); + return true; +} + +bool CSPrimSphericalShell::ReadFromXML(TiXmlNode &root) +{ + if (CSPrimSphere::ReadFromXML(root)==false) return false; + + TiXmlElement *elem = root.ToElement(); + if (elem==NULL) return false; + if (ReadTerm(psShellWidth,*elem,"ShellWidth")==false) return false; + + return true; +} + +void CSPrimSphericalShell::ShowPrimitiveStatus(std::ostream& stream) +{ + CSPrimSphere::ShowPrimitiveStatus(stream); + stream << " Shell width: " << psShellWidth.GetValueString() << std::endl; +} diff --git a/CSXCAD/src/CSPrimSphericalShell.h b/CSXCAD/src/CSPrimSphericalShell.h new file mode 100644 index 0000000..f1f1e17 --- /dev/null +++ b/CSXCAD/src/CSPrimSphericalShell.h @@ -0,0 +1,57 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" +#include "CSPrimSphere.h" + +//! SphericalShell Primitive +/*! + This is a spherical shell primitive derived from the sphere primitive, adding a shell width which is centered around the sphere radius. + \sa CSPrimSphere + */ +class CSXCAD_EXPORT CSPrimSphericalShell : public CSPrimSphere +{ +public: + CSPrimSphericalShell(ParameterSet* paraSet, CSProperties* prop); + CSPrimSphericalShell(CSPrimSphericalShell* sphereshell, CSProperties *prop=NULL); + CSPrimSphericalShell(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimSphericalShell(); + + virtual CSPrimitives* GetCopy(CSProperties *prop=NULL) {return new CSPrimSphericalShell(this,prop);} + + void SetShellWidth(double val) {psShellWidth.SetValue(val);} + void SetShellWidth(const char* val) {psShellWidth.SetValue(val);} + + double GetShellWidth() {return psShellWidth.GetValue();} + ParameterScalar* GetShellWidthPS() {return &psShellWidth;} + + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false); + virtual bool IsInside(const double* Coord, double tol=0); + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual void ShowPrimitiveStatus(std::ostream& stream); + +protected: + ParameterScalar psShellWidth; +}; + + diff --git a/CSXCAD/src/CSPrimUserDefined.cpp b/CSXCAD/src/CSPrimUserDefined.cpp new file mode 100644 index 0000000..2cd5219 --- /dev/null +++ b/CSXCAD/src/CSPrimUserDefined.cpp @@ -0,0 +1,252 @@ +/* +* 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 "CSPrimUserDefined.h" +#include "CSProperties.h" +#include "CSFunctionParser.h" +#include "CSUseful.h" + +CSPrimUserDefined::CSPrimUserDefined(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(ID,paraSet,prop) +{ + Type=USERDEFINED; + fParse = new CSFunctionParser(); + stFunction = std::string(); + CoordSystem=CARESIAN_SYSTEM; + for (int i=0;i<3;++i) {dPosShift[i].SetParameterSet(paraSet);} + PrimTypeName = std::string("User-Defined"); +} + +CSPrimUserDefined::CSPrimUserDefined(CSPrimUserDefined* primUDef, CSProperties *prop) : CSPrimitives(primUDef,prop) +{ + Type=USERDEFINED; + fParse = new CSFunctionParser(*primUDef->fParse); + stFunction = std::string(primUDef->stFunction); + CoordSystem = primUDef->CoordSystem; + for (int i=0;i<3;++i) + dPosShift[i].Copy(&primUDef->dPosShift[i]); + PrimTypeName = std::string("User-Defined"); +} + +CSPrimUserDefined::CSPrimUserDefined(ParameterSet* paraSet, CSProperties* prop) : CSPrimitives(paraSet,prop) +{ + Type=USERDEFINED; + fParse = new CSFunctionParser(); + stFunction = std::string(); + CoordSystem=CARESIAN_SYSTEM; + for (int i=0;i<3;++i) + dPosShift[i].SetParameterSet(paraSet); + PrimTypeName = std::string("User-Defined"); +} + + +CSPrimUserDefined::~CSPrimUserDefined() +{ + delete fParse;fParse=NULL; +} + +void CSPrimUserDefined::SetCoordSystem(UserDefinedCoordSystem newSystem) +{ + CoordSystem=newSystem; +} + +void CSPrimUserDefined::SetFunction(const char* func) +{ + if (func==NULL) return; + stFunction = std::string(func); +} + +bool CSPrimUserDefined::GetBoundBox(double dBoundBox[6], bool PreserveOrientation) +{ + UNUSED(PreserveOrientation); //has no orientation or preserved anyways + //this type has no simple bound box + double max=std::numeric_limits<double>::max(); + dBoundBox[0]=dBoundBox[2]=dBoundBox[4]=-max; + dBoundBox[1]=dBoundBox[3]=dBoundBox[5]=max; + bool accurate=false; + return accurate; +} + +bool CSPrimUserDefined::IsInside(const double* Coord, double /*tol*/) +{ + if (Coord==NULL) return false; + + int NrPara=clParaSet->GetQtyParameter(); + if (NrPara!=iQtyParameter) return false; + double *vars = new double[NrPara+6]; + + vars=clParaSet->GetValueArray(vars); + + double inCoord[3] = {Coord[0],Coord[1],Coord[2]}; + //transform incoming coordinates into cartesian coords + TransformCoordSystem(Coord,inCoord,m_MeshType,CARTESIAN); + if (m_Transform) + m_Transform->InvertTransform(inCoord,inCoord); + + double x=inCoord[0]-dPosShift[0].GetValue(); + double y=inCoord[1]-dPosShift[1].GetValue(); + double z=inCoord[2]-dPosShift[2].GetValue(); + double rxy=sqrt(x*x+y*y); + vars[NrPara]=x; + vars[NrPara+1]=y; + vars[NrPara+2]=z; + + switch (CoordSystem) + { + case CARESIAN_SYSTEM: //uses x,y,z + vars[NrPara+3]=0; + vars[NrPara+4]=0; + vars[NrPara+5]=0; break; + case CYLINDER_SYSTEM: //uses x,y,z,r,a,0 + vars[NrPara+3]=rxy; + vars[NrPara+4]=atan2(y,x); + vars[NrPara+5]=0; + break; + case SPHERE_SYSTEM: //uses x,y,z,r,a,t + vars[NrPara+3]=sqrt(x*x+y*y+z*z); + vars[NrPara+4]=atan2(y,x); + vars[NrPara+5]=asin(1)-atan(z/rxy); + //cout << "x::" << x << "y::" << y << "z::" << z << "r::" << vars[NrPara] << "a::" << vars[NrPara+1] << "t::" << vars[NrPara+2] << std::endl; + break; + default: + //unknown System + return false; + break; + } + double dValue=0; + + if (fParse->GetParseErrorType()==FunctionParser::FP_NO_ERROR) dValue=fParse->Eval(vars); + else dValue=0; + delete[] vars;vars=NULL; + + if (dValue==1) + return true; + return false; +} + + +bool CSPrimUserDefined::Update(std::string *ErrStr) +{ + int EC=0; + bool bOK=true; + std::string vars; + switch (CoordSystem) + { + case CARESIAN_SYSTEM: + vars=std::string("x,y,z"); + break; + case CYLINDER_SYSTEM: + vars=std::string("x,y,z,r,a"); + break; + case SPHERE_SYSTEM: + vars=std::string("x,y,z,r,a,t"); + break; + default: + //unknown System + return false; + break; + } + iQtyParameter=clParaSet->GetQtyParameter(); + if (iQtyParameter>0) + { + fParameter=std::string(clParaSet->GetParameterString()); + vars = fParameter + "," + vars; + } + + fParse->Parse(stFunction,vars); + + EC=fParse->GetParseErrorType(); + //cout << fParse.ErrorMsg(); + + if (EC!=FunctionParser::FP_NO_ERROR) bOK=false; + + if ((EC!=FunctionParser::FP_NO_ERROR) && (ErrStr!=NULL)) + { + std::ostringstream oss; + oss << "\nError in User Defined Primitive Function (ID: " << uiID << "): " << fParse->ErrorMsg(); + ErrStr->append(oss.str()); + bOK=false; + } + + for (int i=0;i<3;++i) + { + EC=dPosShift[i].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + bOK=false; + std::ostringstream oss; + oss << "\nError in User Defined Primitive Coord (ID: " << uiID << "): "; + ErrStr->append(oss.str()); + PSErrorCode2Msg(EC,ErrStr); + } + } + + //update local bounding box + m_BoundBoxValid = GetBoundBox(m_BoundBox); + + return bOK; +} + +bool CSPrimUserDefined::Write2XML(TiXmlElement &elem, bool parameterised) +{ + CSPrimitives::Write2XML(elem,parameterised); + + elem.SetAttribute("CoordSystem",CoordSystem); + + TiXmlElement P1("CoordShift"); + WriteTerm(dPosShift[0],P1,"X",parameterised); + WriteTerm(dPosShift[1],P1,"Y",parameterised); + WriteTerm(dPosShift[2],P1,"Z",parameterised); + elem.InsertEndChild(P1); + + TiXmlElement FuncElem("Function"); + TiXmlText FuncText(GetFunction()); + FuncElem.InsertEndChild(FuncText); + + elem.InsertEndChild(FuncElem); + return true; +} + +bool CSPrimUserDefined::ReadFromXML(TiXmlNode &root) +{ + if (CSPrimitives::ReadFromXML(root)==false) return false; + + int value; + TiXmlElement* elem=root.ToElement(); + if (elem==NULL) return false; + if (elem->QueryIntAttribute("CoordSystem",&value)!=TIXML_SUCCESS) return false; + SetCoordSystem((UserDefinedCoordSystem)value); + + //P1 + TiXmlElement* P1=root.FirstChildElement("CoordShift"); + if (P1==NULL) return false; + if (ReadTerm(dPosShift[0],*P1,"X")==false) return false; + if (ReadTerm(dPosShift[1],*P1,"Y")==false) return false; + if (ReadTerm(dPosShift[2],*P1,"Z")==false) return false; + + TiXmlElement* FuncElem=root.FirstChildElement("Function"); + if (FuncElem==NULL) return false; + SetFunction(FuncElem->GetText()); + + return true; +} diff --git a/CSXCAD/src/CSPrimUserDefined.h b/CSXCAD/src/CSPrimUserDefined.h new file mode 100644 index 0000000..047ed66 --- /dev/null +++ b/CSXCAD/src/CSPrimUserDefined.h @@ -0,0 +1,66 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" + +//! User defined Primitive given by an analytic formula +/*! + This primitive is defined by a boolean result analytic formula. If a given coordinate results in a true result the primitive is assumed existing at these coordinate. + */ +class CSXCAD_EXPORT CSPrimUserDefined: public CSPrimitives +{ +public: + enum UserDefinedCoordSystem + { + CARESIAN_SYSTEM,CYLINDER_SYSTEM,SPHERE_SYSTEM + }; + CSPrimUserDefined(ParameterSet* paraSet, CSProperties* prop); + CSPrimUserDefined(CSPrimUserDefined* primUDef, CSProperties *prop=NULL); + CSPrimUserDefined(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimUserDefined(); + + virtual CSPrimUserDefined* GetCopy(CSProperties *prop=NULL) {return new CSPrimUserDefined(this,prop);} + + void SetCoordSystem(UserDefinedCoordSystem newSystem); + UserDefinedCoordSystem GetCoordSystem() {return CoordSystem;} + + void SetCoordShift(int index, double val) {if ((index>=0) && (index<3)) dPosShift[index].SetValue(val);} + void SetCoordShift(int index, const char* val) {if ((index>=0) && (index<3)) dPosShift[index].SetValue(val);} + + double GetCoordShift(int index) {if ((index>=0) && (index<3)) return dPosShift[index].GetValue(); else return 0;} + ParameterScalar* GetCoordShiftPS(int index) {if ((index>=0) && (index<3)) return &dPosShift[index]; else return NULL;} + + void SetFunction(const char* func); + const char* GetFunction() {return stFunction.c_str();} + + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false); + virtual bool IsInside(const double* Coord, double tol=0); + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + +protected: + std::string stFunction; + UserDefinedCoordSystem CoordSystem; + CSFunctionParser* fParse; + std::string fParameter; + int iQtyParameter; + ParameterScalar dPosShift[3]; +}; diff --git a/CSXCAD/src/CSPrimWire.cpp b/CSXCAD/src/CSPrimWire.cpp new file mode 100644 index 0000000..a182400 --- /dev/null +++ b/CSXCAD/src/CSPrimWire.cpp @@ -0,0 +1,149 @@ +/* +* 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 "CSPrimWire.h" +#include "CSProperties.h" +#include "CSUseful.h" + +CSPrimWire::CSPrimWire(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) : CSPrimCurve(ID,paraSet,prop) +{ + Type=WIRE; + PrimTypeName = std::string("Wire"); + wireRadius.SetParameterSet(paraSet); +} + +CSPrimWire::CSPrimWire(CSPrimWire* primCurve, CSProperties *prop) : CSPrimCurve(primCurve,prop) +{ + Type=WIRE; + PrimTypeName = std::string("Wire"); + wireRadius.Copy(&primCurve->wireRadius); +} + +CSPrimWire::CSPrimWire(ParameterSet* paraSet, CSProperties* prop) : CSPrimCurve(paraSet,prop) +{ + Type=WIRE; + PrimTypeName = std::string("Wire"); + wireRadius.SetParameterSet(paraSet); +} + + +CSPrimWire::~CSPrimWire() +{ +} + + +bool CSPrimWire::GetBoundBox(double dBoundBox[6], bool PreserveOrientation) +{ + bool accurate; + accurate = CSPrimCurve::GetBoundBox(dBoundBox,PreserveOrientation); + double rad = wireRadius.GetValue(); + for (int n=0;n<3;++n) + { + dBoundBox[2*n]-=rad; + dBoundBox[2*n+1]+=rad; + } + if (rad>0) + m_Dimension+=2; + return accurate; +} + +bool CSPrimWire::IsInside(const double* Coord, double /*tol*/) +{ + if (Coord==NULL) return false; + double rad = wireRadius.GetValue(); + const double* p0; + const double* p1; + 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; + } + + double foot,dist,distPP; + for (size_t i=0;i<GetNumberOfPoints();++i) + { + p0 = points.at(i)->GetCartesianCoords(); + + dist = sqrt(pow(pos[0]-p0[0],2)+pow(pos[1]-p0[1],2)+pow(pos[2]-p0[2],2)); + if (dist<rad) + return true; + + if (i<GetNumberOfPoints()-1) + { + p1 = points.at(i+1)->GetCartesianCoords(); + distPP = sqrt(pow(p1[0]-p0[0],2)+pow(p1[1]-p0[1],2)+pow(p1[2]-p0[2],2))+rad; + if (dist<distPP) + { + Point_Line_Distance(pos ,p0 ,p1 ,foot ,dist); + if ((foot>0) && (foot<1) && (dist<rad)) + return true; + } + } + } + + return false; +} + +bool CSPrimWire::Update(std::string *ErrStr) +{ + int EC=0; + bool bOK=true; + CSPrimCurve::Update(ErrStr); + + EC=wireRadius.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 " << PrimTypeName << " (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 CSPrimWire::Write2XML(TiXmlElement &elem, bool parameterised) +{ + CSPrimCurve::Write2XML(elem,parameterised); + + WriteTerm(wireRadius,elem,"WireRadius",parameterised); + return true; +} + +bool CSPrimWire::ReadFromXML(TiXmlNode &root) +{ + if (CSPrimCurve::ReadFromXML(root)==false) return false; + + TiXmlElement *elem = root.ToElement(); + if (elem==NULL) return false; + if (ReadTerm(wireRadius,*elem,"WireRadius")==false) return false; + return true; +} diff --git a/CSXCAD/src/CSPrimWire.h b/CSXCAD/src/CSPrimWire.h new file mode 100644 index 0000000..c5c6e76 --- /dev/null +++ b/CSXCAD/src/CSPrimWire.h @@ -0,0 +1,53 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPrimitives.h" +#include "CSPrimCurve.h" + +//! Wire Primitive (Polygonal chain with finite radius) +/*! + This is a wire primitive derived from a curve with an additional wire radius + \sa CSPrimCurve + */ +class CSXCAD_EXPORT CSPrimWire : public CSPrimCurve +{ +public: + CSPrimWire(ParameterSet* paraSet, CSProperties* prop); + CSPrimWire(CSPrimWire* primCurve, CSProperties *prop=NULL); + CSPrimWire(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + virtual ~CSPrimWire(); + + virtual CSPrimitives* GetCopy(CSProperties *prop=NULL) {return new CSPrimWire(this,prop);} + + void SetWireRadius(double val) {wireRadius.SetValue(val);} + void SetWireRadius(const char* val) {wireRadius.SetValue(val);} + + double GetWireRadius() {return wireRadius.GetValue();} + ParameterScalar* GetWireRadiusPS() {return &wireRadius;} + + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false); + virtual bool IsInside(const double* Coord, double tol=0); + + virtual bool Update(std::string *ErrStr=NULL); + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + virtual bool ReadFromXML(TiXmlNode &root); + +protected: + ParameterScalar wireRadius; +}; diff --git a/CSXCAD/src/CSPrimitives.cpp b/CSXCAD/src/CSPrimitives.cpp new file mode 100644 index 0000000..e15d2cb --- /dev/null +++ b/CSXCAD/src/CSPrimitives.cpp @@ -0,0 +1,219 @@ +/* +* 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 <http://www.gnu.org/licenses/>. +*/ + +#include <sstream> +#include <iostream> +#include <limits> +#include "tinyxml.h" +#include "stdint.h" + +#include "CSPrimitives.h" + +#include "CSProperties.h" +#include "CSFunctionParser.h" +#include "CSUseful.h" + +#include <math.h> + +#define PI acos(-1) + +int g_PrimUniqueIDCounter=0; + +void Point_Line_Distance(const double P[], const double start[], const double stop[], double &foot, double &dist, CoordinateSystem c_system) +{ + double l_P[3],l_start[3],l_stop[3]; + TransformCoordSystem(P,l_P,c_system,CARTESIAN); + TransformCoordSystem(start,l_start,c_system,CARTESIAN); + TransformCoordSystem(stop,l_stop,c_system,CARTESIAN); + + double dir[] = {l_stop[0]-l_start[0],l_stop[1]-l_start[1],l_stop[2]-l_start[2]}; + + double LL = pow(dir[0],2)+pow(dir[1],2)+pow(dir[2],2); //Line length^2 + foot = (l_P[0]-l_start[0])*dir[0] + (l_P[1]-l_start[1])*dir[1] + (l_P[2]-l_start[2])*dir[2]; + foot /= LL; + + double footP[] = {l_start[0] + foot*dir[0], l_start[1] + foot*dir[1], l_start[2] + foot*dir[2]}; + + dist = sqrt(pow(l_P[0]-footP[0],2)+pow(l_P[1]-footP[1],2)+pow(l_P[2]-footP[2],2)); +} + +bool CSXCAD_EXPORT CoordInRange(const double* coord, const double* start, const double* stop, CoordinateSystem cs_in) +{ + double p[] = {coord[0],coord[1],coord[2]}; + switch (cs_in) + { + case CYLINDRICAL: + if (p[1]<std::min(start[1],stop[1])) + while (p[1]<std::min(start[1],stop[1])) + p[1]+=2*PI; + else if (p[1]>std::max(start[1],stop[1])) + while (p[1]>std::max(start[1],stop[1])) + p[1]-=2*PI; + case CARTESIAN: + default: + for (int n=0;n<3;++n) + if ((p[n]<std::min(start[n],stop[n])) || (p[n]>std::max(start[n],stop[n]))) + return false; + return true; + break; + } + return true; +} + +/*********************CSPrimitives********************************************************************/ +CSPrimitives::CSPrimitives(unsigned int ID, ParameterSet* paraSet, CSProperties* prop) +{ + this->Init(); + SetProperty(prop); + uiID=ID; + clParaSet=paraSet; +} + +CSPrimitives::CSPrimitives(CSPrimitives* prim, CSProperties *prop) +{ + this->Init(); + if (prop==NULL) + SetProperty(prim->clProperty); + else + SetProperty(prop); + clParaSet=prim->clParaSet; + m_Transform=CSTransform::New(prim->m_Transform); + iPriority=prim->iPriority; + m_MeshType = prim->m_MeshType; + m_PrimCoordSystem = prim->m_PrimCoordSystem; + m_Dimension = prim->m_Dimension; +} + +CSPrimitives::CSPrimitives(ParameterSet* paraSet, CSProperties* prop) +{ + this->Init(); + SetProperty(prop); + clParaSet=paraSet; +} + +void CSPrimitives::Init() +{ + clProperty=NULL; + clParaSet=NULL; + m_Transform=NULL; + uiID=g_PrimUniqueIDCounter++; + iPriority=0; + PrimTypeName = std::string("Base Type"); + m_Primtive_Used = false; + m_MeshType = CARTESIAN; + m_PrimCoordSystem = UNDEFINED_CS; + m_BoundBox_CoordSys = UNDEFINED_CS; + m_Dimension = 0; + for (int n=0;n<6;++n) + m_BoundBox[n]=0; + m_BoundBoxValid = false; +} + +void CSPrimitives::SetProperty(CSProperties *prop) +{ + if ((clProperty!=NULL) && (clProperty!=prop)) + clProperty->RemovePrimitive(this); + clProperty=prop; + if ((prop!=NULL) && (!prop->HasPrimitive(this))) + prop->AddPrimitive(this); +} + +CSPrimitives::~CSPrimitives() +{ + if (clProperty!=NULL) + clProperty->RemovePrimitive(this); + delete m_Transform; + m_Transform=NULL; +} + +int CSPrimitives::IsInsideBox(const double *boundbox) +{ + if (m_BoundBoxValid==false) + return 0; // unable to decide with an invalid bounding box + if ((this->GetBoundBoxCoordSystem()!=UNDEFINED_CS) && (this->GetBoundBoxCoordSystem()!=this->GetCoordInputType())) + return 0; // unable to decide if coordinate system do not match + if (this->GetTransform()!=NULL) + return 0; // unable to decide if a transformation is used + + for (int i=0;i<3;++i) + { + int d_l = 2*i; + int d_u = d_l+1; + if ((boundbox[d_l]<m_BoundBox[d_l]) && (boundbox[d_l]<m_BoundBox[d_u]) && (boundbox[d_u]<m_BoundBox[d_l]) && (boundbox[d_u]<m_BoundBox[d_u])) + return -1; + if ((boundbox[d_l]>m_BoundBox[d_l]) && (boundbox[d_l]>m_BoundBox[d_u]) && (boundbox[d_u]>m_BoundBox[d_l]) && (boundbox[d_u]>m_BoundBox[d_u])) + return -1; + } + return 1; +} + +bool CSPrimitives::Write2XML(TiXmlElement &elem, bool /*parameterised*/) +{ + elem.SetAttribute("Priority",iPriority); + + if (m_PrimCoordSystem!=UNDEFINED_CS) + elem.SetAttribute("CoordSystem",(int)m_PrimCoordSystem); + + if (m_Transform) + m_Transform->Write2XML(&elem); + + return true; +} + +bool CSPrimitives::ReadFromXML(TiXmlNode &root) +{ + int help; + TiXmlElement* elem=root.ToElement(); + if (elem==NULL) return false; + if (elem->QueryIntAttribute("Priority",&iPriority)!=TIXML_SUCCESS) return false; + + if (elem->QueryIntAttribute("CoordSystem",&help)==TIXML_SUCCESS) + m_PrimCoordSystem = (CoordinateSystem)help; + + delete m_Transform; + m_Transform = CSTransform::New(elem, clParaSet); + + return true; +} + +void CSPrimitives::ShowPrimitiveStatus(std::ostream& stream) +{ + stream << " Primitive #" << GetID() << " Type: \"" << GetTypeName() << "\" Priority: " << GetPriority() << std::endl; + stream << " Primary Coord-System: " << m_PrimCoordSystem << " Mesh Coord-System: " << m_MeshType << " Bound-Box Coord-System: " << m_BoundBox_CoordSys << std::endl; + stream << " Bounding Box (Valid: " << m_BoundBoxValid << "): P1: (" << m_BoundBox[0] << "," << m_BoundBox[2] << "," << m_BoundBox[4] << ") P2: (" << m_BoundBox[1] << "," << m_BoundBox[3] << "," << m_BoundBox[5] << ")" << std::endl; + if (m_Transform) + { + stream << " Transform: " << std::endl; + m_Transform->PrintTransformations(stream, "\t* "); + } + else + stream << " Transform: None" << std::endl; +} + +void CSPrimitives::TransformCoords(double* Coord, bool invers, CoordinateSystem cs_in) const +{ + if (m_Transform==NULL) + return; + // transform to Cartesian for transformation + TransformCoordSystem(Coord,Coord,cs_in,CARTESIAN); + if (invers) + m_Transform->InvertTransform(Coord,Coord); + else + m_Transform->Transform(Coord,Coord); + // transform back from Cartesian to incoming coordinate system + TransformCoordSystem(Coord,Coord,CARTESIAN,cs_in); +} diff --git a/CSXCAD/src/CSPrimitives.h b/CSXCAD/src/CSPrimitives.h new file mode 100644 index 0000000..4f68a96 --- /dev/null +++ b/CSXCAD/src/CSPrimitives.h @@ -0,0 +1,212 @@ +/* +* 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 <http://www.gnu.org/licenses/>. +*/ + +#pragma once +/* + * Author: Thorsten Liebig + * Date: 03-12-2008 + * Lib: CSXCAD + * Version: 0.1a + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string> + +#include "ParameterObjects.h" +#include "ParameterCoord.h" +#include "CSXCAD_Global.h" + +class CSPrimPoint; +class CSPrimBox; +class CSPrimMultiBox; +class CSPrimSphere; + class CSPrimSphericalShell; +class CSPrimCylinder; + class CSPrimCylindricalShell; +class CSPrimPolygon; + class CSPrimLinPoly; + class CSPrimRotPoly; +class CSPrimPolyhedron; + class CSPrimPolyhedronReader; +class CSPrimCurve; + class CSPrimWire; +class CSPrimUserDefined; + +class CSProperties; //include VisualProperties + +class TiXmlNode; +class CSFunctionParser; +class CSTransform; + +/*! + Calculate the distance of a point to a line (defined by start/stop coordinates). + Foot will return the normalized foot-point on the line. A value between 0..1 means the foot-point is one the given line. + foot == 0 --> foot-point is on start, foot == 1 --> foot-point is on stop +*/ +void CSXCAD_EXPORT Point_Line_Distance(const double P[], const double start[], const double stop[], double &foot, double &dist, CoordinateSystem c_system=UNDEFINED_CS); + +bool CSXCAD_EXPORT CoordInRange(const double* p, const double* start, const double* stop, CoordinateSystem cs_in); + +//! Abstract base class for different geometrical primitives. +/*! + This is an abstract base class for different geometrical primitives like boxes, spheres, cylinders etc. + !!! Tolerances not yet obeyed !!! + */ +class CSXCAD_EXPORT CSPrimitives +{ +public: + virtual ~CSPrimitives(); + + virtual void Init(); + + //! Primitive type definitions. + enum PrimitiveType + { + POINT,BOX,MULTIBOX,SPHERE,SPHERICALSHELL,CYLINDER,CYLINDRICALSHELL,POLYGON,LINPOLY,ROTPOLY,POLYHEDRON,CURVE,WIRE,USERDEFINED, + POLYHEDRONREADER + }; + + //! Set or change the property for this primitive. + void SetProperty(CSProperties *prop); + //! Get the property for this primitive. + CSProperties* GetProperty() {return clProperty;} + + //! Getthe unique ID for this primitive. + unsigned int GetID() {return uiID;} + //! Change the unique ID for this primitive. This is not recommended! Be sure what you are doing! + void SetID(unsigned int ID) {uiID=ID;} + + //! Get the type of this primitive. \sa PrimitiveType + int GetType() {return Type;} + + std::string GetTypeName() {return PrimTypeName;} + + //! Create a copy of ths primitive with different property. + virtual CSPrimitives* GetCopy(CSProperties *prop=NULL) {return new CSPrimitives(this,prop);} + + //! Get the bounding box (for the given mesh type) for this special primitive. \sa GetBoundBoxCoordSystem + virtual bool GetBoundBox(double dBoundBox[6], bool PreserveOrientation=false) {UNUSED(PreserveOrientation);UNUSED(dBoundBox);return false;} + + virtual CoordinateSystem GetBoundBoxCoordSystem() const {return m_BoundBox_CoordSys;} + + //! Get the dimension of this primitive + virtual int GetDimension() {return m_Dimension;} + + //! Check if given Coordinate (in the given mesh type) is inside the Primitive. + virtual bool IsInside(const double* Coord, double tol=0) {UNUSED(Coord);UNUSED(tol);return false;} + + //! Check if the primitive is inside a given box (box must be specified in the bounding box coordinate system) + //! @return -1 if not, +1 if it is, 0 if unknown + virtual int IsInsideBox(const double* boundbox); + + //! Check whether this primitive was used. (--> IsInside() return true) \sa SetPrimitiveUsed + bool GetPrimitiveUsed() {return m_Primtive_Used;} + //! Set the primitve uses flag. \sa GetPrimitiveUsed + void SetPrimitiveUsed(bool val) {m_Primtive_Used=val;} + + //! Set or change the priotity for this primitive. + void SetPriority(int val) {iPriority=val;} + //! Get the priotity for this primitive. + int GetPriority() {return iPriority;} + + //! Update this primitive with respect to the parameters set. + virtual bool Update(std::string *ErrStr=NULL) {UNUSED(ErrStr);return true;} + //! Write this primitive to a XML-node. + virtual bool Write2XML(TiXmlElement &elem, bool parameterised=true); + //! Read this primitive from a XML-node. + virtual bool ReadFromXML(TiXmlNode &root); + + //! Get the corresponing Box-Primitive or NULL in case of different type. + CSPrimBox* ToBox() { return ( this && Type == BOX ) ? (CSPrimBox*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing MultiBox-Primitive or NULL in case of different type. + CSPrimMultiBox* ToMultiBox() { return ( this && Type == MULTIBOX ) ? (CSPrimMultiBox*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing Sphere-Primitive or NULL in case of different type. + CSPrimSphere* ToSphere() { return ( this && Type == SPHERE ) ? (CSPrimSphere*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing SphereicalShell-Primitive or NULL in case of different type. + CSPrimSphericalShell* ToSphericalShell() { return ( this && Type == SPHERICALSHELL ) ? (CSPrimSphericalShell*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing Cylinder-Primitive or NULL in case of different type. + CSPrimCylinder* ToCylinder() { return ( this && Type == CYLINDER ) ? (CSPrimCylinder*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing CylindricalShell-Primitive or NULL in case of different type. + CSPrimCylindricalShell* ToCylindricalShell() { return ( this && Type == CYLINDRICALSHELL ) ? (CSPrimCylindricalShell*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing Polygon-Primitive or NULL in case of different type. + CSPrimPolygon* ToPolygon() { return ( this && Type == POLYGON ) ? (CSPrimPolygon*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing LinPoly-Primitive or NULL in case of different type. + CSPrimLinPoly* ToLinPoly() { return ( this && Type == LINPOLY ) ? (CSPrimLinPoly*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing Cylinder-Primitive or NULL in case of different type. + CSPrimRotPoly* ToRotPoly() { return ( this && Type == ROTPOLY ) ? (CSPrimRotPoly*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing Polyhedron-Primitive or NULL in case of different type. + CSPrimPolyhedron* ToPolyhedron() { return ( this && Type == POLYHEDRON ) ? (CSPrimPolyhedron*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing Polyhedron-Import-Primitive or NULL in case of different type. + CSPrimPolyhedronReader* ToPolyhedronReader() { return ( this && Type == POLYHEDRONREADER ) ? (CSPrimPolyhedronReader*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing Curve-Primitive or NULL in case of different type. + CSPrimCurve* ToCurve() { return ( this && Type == CURVE ) ? (CSPrimCurve*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing Wire-Primitive or NULL in case of different type. + CSPrimWire* ToWire() { return ( this && Type == WIRE ) ? (CSPrimWire*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing UserDefined-Primitive or NULL in case of different type. + CSPrimUserDefined* ToUserDefined() { return ( this && Type == USERDEFINED ) ? (CSPrimUserDefined*) this : 0; } /// Cast Primitive to a more defined type. Will return null if not of the requested type. + //! Get the corresponing Point-Primitive or 0 in case of different type. + CSPrimPoint* ToPoint() { return ( this && Type == POINT ) ? (CSPrimPoint*) this : 0; } //!< Cast Primitive to a more defined type. Will return 0 if not of the requested type. + + bool operator<(CSPrimitives& vgl) { return iPriority<vgl.GetPriority();} + bool operator>(CSPrimitives& vgl) { return iPriority>vgl.GetPriority();} + bool operator==(CSPrimitives& vgl) { return iPriority==vgl.GetPriority();} + bool operator!=(CSPrimitives& vgl) { return iPriority!=vgl.GetPriority();} + + //! Define the input type for the weighting coordinate system 0=cartesian, 1=cylindrical, 2=spherical + void SetCoordInputType(CoordinateSystem type, bool doUpdate=true) {m_MeshType=type; if (doUpdate) Update();} + //! Get the input type for the weighting coordinate system 0=cartesian, 1=cylindrical, 2=spherical + CoordinateSystem GetCoordInputType() const {return m_MeshType;} + + //! Define the coordinate system this primitive is defined in (may be different to the input mesh type) \sa SetCoordInputType + void SetCoordinateSystem(CoordinateSystem cs) {m_PrimCoordSystem=cs;} + //! Read the coordinate system for this primitive (may be different to the input mesh type) \sa GetCoordInputType + CoordinateSystem GetCoordinateSystem() const {return m_PrimCoordSystem;} + + CSTransform* GetTransform() const {return m_Transform;} + + //! Show status of this primitve + virtual void ShowPrimitiveStatus(std::ostream& stream); + +protected: + CSPrimitives(ParameterSet* paraSet, CSProperties* prop); + CSPrimitives(CSPrimitives* prim, CSProperties *prop=NULL); + CSPrimitives(unsigned int ID, ParameterSet* paraSet, CSProperties* prop); + + //! Apply (invers) transformation to the given coordinate in the given coordinate system + void TransformCoords(double* Coord, bool invers, CoordinateSystem cs_in) const; + + unsigned int uiID; + int iPriority; + CoordinateSystem m_PrimCoordSystem; + CoordinateSystem m_MeshType; + PrimitiveType Type; + ParameterSet* clParaSet; + CSProperties* clProperty; + CSTransform* m_Transform; + std::string PrimTypeName; + bool m_Primtive_Used; + + //internal bounding box, updated by Update(), can be used to speedup IsInside + bool m_BoundBoxValid; + double m_BoundBox[6]; + CoordinateSystem m_BoundBox_CoordSys; + + int m_Dimension; +}; + + diff --git a/CSXCAD/src/CSPropConductingSheet.cpp b/CSXCAD/src/CSPropConductingSheet.cpp new file mode 100644 index 0000000..adce7fd --- /dev/null +++ b/CSXCAD/src/CSPropConductingSheet.cpp @@ -0,0 +1,97 @@ +/* +* 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 "tinyxml.h" + +#include "CSPropConductingSheet.h" + +CSPropConductingSheet::CSPropConductingSheet(ParameterSet* paraSet) : CSPropMetal(paraSet) {Type=(CSProperties::PropertyType)(CONDUCTINGSHEET | METAL);Init();} +CSPropConductingSheet::CSPropConductingSheet(CSProperties* prop) : CSPropMetal(prop) {Type=(CSProperties::PropertyType)(CONDUCTINGSHEET | METAL);Init();} +CSPropConductingSheet::CSPropConductingSheet(unsigned int ID, ParameterSet* paraSet) : CSPropMetal(ID,paraSet) {Type=(CSProperties::PropertyType)(CONDUCTINGSHEET | METAL);Init();} + +CSPropConductingSheet::~CSPropConductingSheet() +{ +} + + +void CSPropConductingSheet::Init() +{ + Conductivity.SetValue(0); + Thickness.SetValue(0); +} + + +bool CSPropConductingSheet::Update(std::string *ErrStr) +{ + int EC=Conductivity.Evaluate(); + bool bOK=true; + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in ConductingSheet-Property Conductivity-Value"; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + EC=Thickness.Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in ConductingSheet-Property Thickness-Value"; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + return bOK & CSPropMetal::Update(ErrStr); +} + +bool CSPropConductingSheet::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + if (CSPropMetal::Write2XML(root,parameterised,sparse) == false) return false; + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + WriteTerm(Conductivity,*prop,"Conductivity",parameterised); + WriteTerm(Thickness,*prop,"Thickness",parameterised); + + return true; +} + +bool CSPropConductingSheet::ReadFromXML(TiXmlNode &root) +{ + if (CSProperties::ReadFromXML(root)==false) return false; + + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + if (ReadTerm(Conductivity,*prop,"Conductivity")==false) + std::cerr << "CSPropConductingSheet::ReadFromXML: Warning: Failed to read Conductivity. Set to 0." << std::endl; + if (ReadTerm(Thickness,*prop,"Thickness")==false) + std::cerr << "CSPropConductingSheet::ReadFromXML: Warning: Failed to read Thickness. Set to 0." << std::endl; + + return true; +} + +void CSPropConductingSheet::ShowPropertyStatus(std::ostream& stream) +{ + CSPropMetal::ShowPropertyStatus(stream); + stream << " --- Conducting Sheet Properties --- " << std::endl; + stream << " Conductivity: " << Conductivity.GetValueString() << std::endl; + stream << " Thickness: " << Thickness.GetValueString() << std::endl; +} diff --git a/CSXCAD/src/CSPropConductingSheet.h b/CSXCAD/src/CSPropConductingSheet.h new file mode 100644 index 0000000..6f3e96a --- /dev/null +++ b/CSXCAD/src/CSPropConductingSheet.h @@ -0,0 +1,67 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPropMetal.h" + +//! Continuous Structure Conductive Sheet Material Property +/*! + This is a condiction sheet dispersive model for an efficient wide band Analysis of planar waveguides and circuits. + */ +class CSXCAD_EXPORT CSPropConductingSheet : public CSPropMetal +{ +public: + CSPropConductingSheet(ParameterSet* paraSet); + CSPropConductingSheet(CSProperties* prop); + CSPropConductingSheet(unsigned int ID, ParameterSet* paraSet); + virtual ~CSPropConductingSheet(); + + virtual void Init(); + + //! Get PropertyType as a xml element name \sa PropertyType and GetType + virtual const std::string GetTypeXMLString() const {return std::string("ConductingSheet");} + + //! Set the Conductivity + void SetConductivity(double val) {Conductivity.SetValue(val);} + //! Set the Conductivity + int SetConductivity(const std::string val) {return Conductivity.SetValue(val);} + //! Get the Conductivity + double GetConductivity() {return Conductivity.GetValue();} + //! Get the Conductivity as a string + const std::string GetConductivityTerm() {return Conductivity.GetString();} + + //! Set the Thickness + void SetThickness(double val) {Thickness.SetValue(val);} + //! Set the Thickness + int SetThickness(const std::string val) {return Thickness.SetValue(val);} + //! Get the Thickness + double GetThickness() {return Thickness.GetValue();} + //! Get the Thickness as a string + const std::string GetThicknessTerm() {return Thickness.GetString();} + + virtual bool Update(std::string *ErrStr=NULL); + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual void ShowPropertyStatus(std::ostream& stream); + +protected: + ParameterScalar Conductivity; + ParameterScalar Thickness; +}; diff --git a/CSXCAD/src/CSPropDebyeMaterial.cpp b/CSXCAD/src/CSPropDebyeMaterial.cpp new file mode 100644 index 0000000..f12c261 --- /dev/null +++ b/CSXCAD/src/CSPropDebyeMaterial.cpp @@ -0,0 +1,238 @@ +/* +* Copyright (C) 2013 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 "tinyxml.h" + +#include "CSPropDebyeMaterial.h" + +CSPropDebyeMaterial::CSPropDebyeMaterial(ParameterSet* paraSet) : CSPropDispersiveMaterial(paraSet) {Type=(CSProperties::PropertyType)(DEBYEMATERIAL | DISPERSIVEMATERIAL | MATERIAL);Init();} +CSPropDebyeMaterial::CSPropDebyeMaterial(CSProperties* prop) : CSPropDispersiveMaterial(prop) {Type=(CSProperties::PropertyType)(DEBYEMATERIAL | DISPERSIVEMATERIAL | MATERIAL);Init();} +CSPropDebyeMaterial::CSPropDebyeMaterial(unsigned int ID, ParameterSet* paraSet) : CSPropDispersiveMaterial(ID,paraSet) {Type=(CSProperties::PropertyType)(DEBYEMATERIAL | DISPERSIVEMATERIAL | MATERIAL);Init();} + +CSPropDebyeMaterial::~CSPropDebyeMaterial() +{ + DeleteValues(); + m_Order = 0; +} + +void CSPropDebyeMaterial::Init() +{ + m_Order = 0; + EpsDelta=NULL; + WeightEpsDelta=NULL; + EpsRelaxTime=NULL; + WeightEpsRelaxTime=NULL; + InitValues(); + CSPropDispersiveMaterial::Init(); +} + +void CSPropDebyeMaterial::DeleteValues() +{ + for (int o=0;o<m_Order;++o) + { + delete[] EpsDelta[o]; + delete[] WeightEpsDelta[o]; + delete[] EpsRelaxTime[o]; + delete[] WeightEpsRelaxTime[o]; + } + delete[] EpsDelta; + delete[] WeightEpsDelta; + delete[] EpsRelaxTime; + delete[] WeightEpsRelaxTime; + + EpsDelta=NULL; + WeightEpsDelta=NULL; + EpsRelaxTime=NULL; + WeightEpsRelaxTime=NULL; +} + +void CSPropDebyeMaterial::InitValues() +{ +// DeleteValues(); + EpsDelta=new ParameterScalar*[m_Order]; + WeightEpsDelta=new ParameterScalar*[m_Order]; + EpsRelaxTime=new ParameterScalar*[m_Order]; + WeightEpsRelaxTime=new ParameterScalar*[m_Order]; + + for (int o=0;o<m_Order;++o) + { + EpsDelta[o] = new ParameterScalar[3]; + WeightEpsDelta[o] = new ParameterScalar[3]; + EpsRelaxTime[o] = new ParameterScalar[3]; + WeightEpsRelaxTime[o] = new ParameterScalar[3]; + + for (int n=0;n<3;++n) + { + EpsDelta[o][n].SetValue(0); + EpsDelta[o][n].SetParameterSet(clParaSet); + WeightEpsDelta[o][n].SetValue(1); + WeightEpsDelta[o][n].SetParameterSet(coordParaSet); + EpsRelaxTime[o][n].SetValue(0); + EpsRelaxTime[o][n].SetParameterSet(clParaSet); + WeightEpsRelaxTime[o][n].SetValue(1); + WeightEpsRelaxTime[o][n].SetParameterSet(coordParaSet); + } + } +} + + +bool CSPropDebyeMaterial::Update(std::string *ErrStr) +{ + bool bOK=true; + int EC=0; + for (int o=0;o<m_Order;++o) + { + for (int n=0;n<3;++n) + { + EC=EpsDelta[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Debye Material-Property epsilon Delta frequency value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + EC=WeightEpsDelta[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Debye Material-Property epsilon Delta frequency weighting function (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + EC=EpsRelaxTime[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Debye Material-Property epsilon relaxation time value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + EC=WeightEpsRelaxTime[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Debye Material-Property epsilon relaxation time weighting function (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + } + } + return bOK & CSPropDispersiveMaterial::Update(ErrStr); +} + +bool CSPropDebyeMaterial::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + if (CSPropDispersiveMaterial::Write2XML(root,parameterised,sparse) == false) return false; + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + std::string suffix; + for (int o=0;o<m_Order;++o) + { + suffix = ConvertInt(o+1); + TiXmlElement* value=prop->FirstChildElement("Property"); + if (value==NULL) + return false; + WriteVectorTerm(EpsDelta[o],*value,"EpsilonDelta_"+suffix,parameterised); + WriteVectorTerm(EpsRelaxTime[o],*value,"EpsilonRelaxTime_"+suffix,parameterised); + + TiXmlElement* weight=prop->FirstChildElement("Weight"); + if (weight==NULL) + return false; + WriteVectorTerm(WeightEpsDelta[o],*weight,"EpsilonDelta_"+suffix,parameterised); + WriteVectorTerm(WeightEpsRelaxTime[o],*weight,"EpsilonRelaxTime_"+suffix,parameterised); + } + return true; +} + +bool CSPropDebyeMaterial::ReadFromXML(TiXmlNode &root) +{ + if (CSPropDispersiveMaterial::ReadFromXML(root)==false) return false; + TiXmlElement* prop=root.ToElement(); + + if (prop==NULL) return false; + + // count m_Order + TiXmlElement* matProp=prop->FirstChildElement("Property"); + if (matProp!=NULL) + { + m_Order=1; + while (1) + { + if (matProp->Attribute("EpsilonDelta_"+ConvertInt(m_Order+1))) + ++m_Order; + else if (matProp->Attribute("MueDelta_"+ConvertInt(m_Order+1))) + ++m_Order; + else + break; + } + } + else + return false; + + InitValues(); + + if (ReadVectorTerm(EpsDelta[0],*matProp,"EpsilonDelta_1",0.0)==false) + ReadVectorTerm(EpsDelta[0],*matProp,"EpsilonDelta",0.0); + + if (ReadVectorTerm(EpsRelaxTime[0],*matProp,"EpsilonRelaxTime_1",0.0)==false) + ReadVectorTerm(EpsRelaxTime[0],*matProp,"EpsilonRelaxTime",0.0); + + TiXmlElement* weightProp=prop->FirstChildElement("Weight"); + if (weightProp) + { + if (ReadVectorTerm(WeightEpsDelta[0],*weightProp,"EpsilonDelta_1",1.0)==false) + ReadVectorTerm(WeightEpsDelta[0],*weightProp,"EpsilonDelta",1.0); + + if (ReadVectorTerm(WeightEpsRelaxTime[0],*weightProp,"EpsilonRelaxTime_1",1.0)==false) + ReadVectorTerm(WeightEpsRelaxTime[0],*weightProp,"EpsilonRelaxTime",1.0); + } + + for (int o=1;o<m_Order;++o) + { + ReadVectorTerm(EpsDelta[o],*matProp,"EpsilonDelta_"+ConvertInt(o+1),0.0); + + ReadVectorTerm(EpsRelaxTime[o],*matProp,"EpsilonRelaxTime_"+ConvertInt(o+1),0.0); + + if (weightProp) + { + ReadVectorTerm(WeightEpsDelta[o],*weightProp,"EpsilonDelta_"+ConvertInt(o+1),1.0); + + ReadVectorTerm(WeightEpsRelaxTime[o],*weightProp,"EpsilonRelaxTime_"+ConvertInt(o+1),1.0); + } + } + return true; +} + +void CSPropDebyeMaterial::ShowPropertyStatus(std::ostream& stream) +{ + CSPropDispersiveMaterial::ShowPropertyStatus(stream); + stream << " Debye model order:\t" << m_Order << std::endl; + for (int o=0;o<m_Order;++o) + { + stream << " Epsilon Delta #" << o << ":\t" << GetEpsDelta(o,0) << "," << GetEpsDelta(o,1) << "," << GetEpsDelta(o,2) << std::endl; + stream << " Epsilon Relax Time #" << o << ":\t" << GetEpsRelaxTime(o,0) << "," << GetEpsRelaxTime(o,1) << "," << GetEpsRelaxTime(o,2) << std::endl; + } +} diff --git a/CSXCAD/src/CSPropDebyeMaterial.h b/CSXCAD/src/CSPropDebyeMaterial.h new file mode 100644 index 0000000..700c439 --- /dev/null +++ b/CSXCAD/src/CSPropDebyeMaterial.h @@ -0,0 +1,91 @@ +/* +* Copyright (C) 2013 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/>. +*/ + +#pragma once + +#include "CSProperties.h" +#include "CSPropDispersiveMaterial.h" + +//! Continuous Structure Debye Dispersive Material Property +/*! + This Property can hold information about the special properties of Debye dispersive materials. + \todo Add all the other parameter needed by this model + */ +class CSXCAD_EXPORT CSPropDebyeMaterial : public CSPropDispersiveMaterial +{ +public: + CSPropDebyeMaterial(ParameterSet* paraSet); + CSPropDebyeMaterial(CSProperties* prop); + CSPropDebyeMaterial(unsigned int ID, ParameterSet* paraSet); + virtual ~CSPropDebyeMaterial(); + + //! Get PropertyType as a xml element name \sa PropertyType and GetType + virtual const std::string GetTypeXMLString() const {return std::string("DebyeMaterial");} + + //! Set the epsilon plasma frequency + void SetEpsDelta(int order, double val, int ny=0) {SetValue(val,EpsDelta[order],ny);} + //! Set the epsilon plasma frequency + int SetEpsDelta(int order, const std::string val, int ny=0) {return SetValue(val,EpsDelta[order],ny);} + //! Get the epsilon plasma frequency + double GetEpsDelta(int order, int ny=0) {return GetValue(EpsDelta[order],ny);} + //! Get the epsilon plasma frequency as a string + const std::string GetEpsDeltaTerm(int order, int ny=0) {return GetTerm(EpsDelta[order],ny);} + + //! Set the epsilon plasma frequency weighting + int SetEpsDeltaWeightFunction(int order, const std::string val, int ny) {return SetValue(val,WeightEpsDelta[order],ny);} + //! Get the epsilon plasma frequency weighting string + const std::string GetEpsDeltaWeightFunction(int order, int ny) {return GetTerm(WeightEpsDelta[order],ny);} + //! Get the epsilon plasma frequency weighting + double GetEpsDeltaWeighted(int order, int ny, const double* coords) {return GetWeight(WeightEpsDelta[order],ny,coords)*GetEpsDelta(order,ny);} + + //! Set the epsilon relaxation time + void SetEpsRelaxTime(int order, double val, int ny=0) {SetValue(val,EpsRelaxTime[order],ny);} + //! Set the epsilon relaxation time + int SetEpsRelaxTime(int order, const std::string val, int ny=0) {return SetValue(val,EpsRelaxTime[order],ny);} + //! Get the epsilon relaxation time + double GetEpsRelaxTime(int order, int ny=0) {return GetValue(EpsRelaxTime[order],ny);} + //! Get the epsilon relaxation time as a string + const std::string GetEpsRelaxTimeTerm(int order, int ny=0) {return GetTerm(EpsRelaxTime[order],ny);} + + //! Set the epsilon relaxation time weighting + int SetEpsRelaxTimeWeightFunction(int order, const std::string val, int ny) {return SetValue(val,WeightEpsRelaxTime[order],ny);} + //! Get the epsilon relaxation time weighting string + const std::string GetEpsRelaxTimeWeightFunction(int order, int ny) {return GetTerm(WeightEpsRelaxTime[order],ny);} + //! Get the epsilon relaxation time weighting + double GetEpsRelaxTimeWeighted(int order, int ny, const double* coords) {return GetWeight(WeightEpsRelaxTime[order],ny,coords)*GetEpsRelaxTime(order,ny);} + + virtual void Init(); + virtual bool Update(std::string *ErrStr=NULL); + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual void ShowPropertyStatus(std::ostream& stream); + +protected: + virtual void InitValues(); + virtual void DeleteValues(); + //! Epsilon delta + ParameterScalar** EpsDelta; + //! Epsilon delta weighting functions + ParameterScalar** WeightEpsDelta; + + //! Relaxation times for epsilon + ParameterScalar** EpsRelaxTime; + //! Relaxation times for epsilon weighting functions + ParameterScalar** WeightEpsRelaxTime; +}; diff --git a/CSXCAD/src/CSPropDiscMaterial.cpp b/CSXCAD/src/CSPropDiscMaterial.cpp new file mode 100644 index 0000000..12f565a --- /dev/null +++ b/CSXCAD/src/CSPropDiscMaterial.cpp @@ -0,0 +1,619 @@ +/* +* 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 "tinyxml.h" +#include <hdf5.h> +#include <hdf5_hl.h> + +#include "vtkPolyData.h" +#include "vtkCellArray.h" +#include "vtkPoints.h" + +#include "ParameterCoord.h" +#include "CSPropDiscMaterial.h" + +CSPropDiscMaterial::CSPropDiscMaterial(ParameterSet* paraSet) : CSPropMaterial(paraSet) +{ + Type=(CSProperties::PropertyType)(DISCRETE_MATERIAL | MATERIAL); + Init(); +} + +CSPropDiscMaterial::CSPropDiscMaterial(CSProperties* prop) : CSPropMaterial(prop) +{ + Type=(CSProperties::PropertyType)(DISCRETE_MATERIAL | MATERIAL); + Init(); +} + +CSPropDiscMaterial::CSPropDiscMaterial(unsigned int ID, ParameterSet* paraSet) : CSPropMaterial(ID, paraSet) +{ + Type=(CSProperties::PropertyType)(DISCRETE_MATERIAL | MATERIAL); + Init(); +} + +CSPropDiscMaterial::~CSPropDiscMaterial() +{ + for (int n=0;n<3;++n) + { + delete[] m_mesh[n]; + m_mesh[n]=NULL; + } + delete[] m_Disc_Ind; + m_Disc_Ind=NULL; + delete[] m_Disc_epsR; + m_Disc_epsR=NULL; + delete[] m_Disc_kappa; + m_Disc_kappa=NULL; + delete[] m_Disc_mueR; + m_Disc_mueR=NULL; + delete[] m_Disc_sigma; + m_Disc_sigma=NULL; + delete[] m_Disc_Density; + m_Disc_Density=NULL; + + delete m_Transform; + m_Transform=NULL; +} + +unsigned int CSPropDiscMaterial::GetWeightingPos(const double* inCoords) +{ + double coords[3]; + TransformCoordSystem(inCoords, coords, coordInputType, CARTESIAN); + if (m_Transform) + m_Transform->InvertTransform(coords,coords); + for (int n=0;n<3;++n) + coords[n]/=m_Scale; + unsigned int pos[3]; + if (!(m_mesh[0] && m_mesh[1] && m_mesh[2])) + return -1; + for (int n=0;n<3;++n) + { + if (coords[n]<m_mesh[n][0]) + return -1; + if (coords[n]>m_mesh[n][m_Size[n]-1]) + return -1; + pos[n]=0; + for (unsigned int i=1;i<m_Size[n];++i) + { + if (coords[n]<m_mesh[n][i]) + { + pos[n]=i-1; + break; + } + } + } + return pos[0] + pos[1]*(m_Size[0]-1) + pos[2]*(m_Size[0]-1)*(m_Size[1]-1); +} + +int CSPropDiscMaterial::GetDBPos(const double* coords) +{ + if (m_Disc_Ind==NULL) + return -1; + unsigned int pos = GetWeightingPos(coords); + if (pos==(unsigned int)-1) + return -1; + // material with index 0 is assumed to be background material + if ((m_DB_Background==false) && (m_Disc_Ind[pos]==0)) + return -1; + int db_pos = (int)m_Disc_Ind[pos]; + if (db_pos>=(int)m_DB_size) + { + //sanity check, this should not happen!!! + std::cerr << __func__ << ": Error, false DB position!" << std::endl; + return -1; + } + return db_pos; +} + +double CSPropDiscMaterial::GetEpsilonWeighted(int ny, const double* inCoords) +{ + if (m_Disc_epsR==NULL) + return CSPropMaterial::GetEpsilonWeighted(ny,inCoords); + int pos = GetDBPos(inCoords); + if (pos<0) + return CSPropMaterial::GetEpsilonWeighted(ny,inCoords); + return m_Disc_epsR[pos]; +} + +double CSPropDiscMaterial::GetKappaWeighted(int ny, const double* inCoords) +{ + if (m_Disc_kappa==NULL) + return CSPropMaterial::GetKappaWeighted(ny,inCoords); + int pos = GetDBPos(inCoords); + if (pos<0) + return CSPropMaterial::GetKappaWeighted(ny,inCoords); + return m_Disc_kappa[pos]; +} + +double CSPropDiscMaterial::GetMueWeighted(int ny, const double* inCoords) +{ + if (m_Disc_mueR==NULL) + return CSPropMaterial::GetMueWeighted(ny,inCoords); + int pos = GetDBPos(inCoords); + if (pos<0) + return CSPropMaterial::GetMueWeighted(ny,inCoords); + return m_Disc_mueR[pos]; +} + +double CSPropDiscMaterial::GetSigmaWeighted(int ny, const double* inCoords) +{ + if (m_Disc_sigma==NULL) + return CSPropMaterial::GetSigmaWeighted(ny,inCoords); + int pos = GetDBPos(inCoords); + if (pos<0) + return CSPropMaterial::GetSigmaWeighted(ny,inCoords); + return m_Disc_sigma[pos]; +} + +double CSPropDiscMaterial::GetDensityWeighted(const double* inCoords) +{ + if (m_Disc_Density==NULL) + return CSPropMaterial::GetDensityWeighted(inCoords); + int pos = GetDBPos(inCoords); + if (pos<0) + return CSPropMaterial::GetDensityWeighted(inCoords); + return m_Disc_Density[pos]; +} + +void CSPropDiscMaterial::Init() +{ + m_Filename.clear(); + m_FileType=-1; + + m_DB_size = 0; + m_DB_Background = true; + + for (int n=0;n<3;++n) + m_mesh[n]=NULL; + m_Disc_Ind=NULL; + m_Disc_epsR=NULL; + m_Disc_kappa=NULL; + m_Disc_mueR=NULL; + m_Disc_sigma=NULL; + m_Disc_Density=NULL; + + m_Scale=1; + m_Transform=NULL; + + CSPropMaterial::Init(); +} + +bool CSPropDiscMaterial::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + if (CSPropMaterial::Write2XML(root,parameterised,sparse) == false) return false; + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + TiXmlElement filename("DiscFile"); + filename.SetAttribute("Type",m_FileType); + filename.SetAttribute("File",m_Filename.c_str()); + filename.SetAttribute("UseDBBackground",m_DB_Background); + filename.SetAttribute("Scale",m_Scale); + + if (m_Transform) + m_Transform->Write2XML(prop); + + prop->InsertEndChild(filename); + + return true; +} + +bool CSPropDiscMaterial::ReadFromXML(TiXmlNode &root) +{ + if (CSPropMaterial::ReadFromXML(root)==false) return false; + TiXmlElement* prop=root.ToElement(); + + if (prop==NULL) return false; + + m_FileType = 0; + prop->QueryIntAttribute("Type",&m_FileType); + const char* c_filename = prop->Attribute("File"); + + int help; + if (prop->QueryIntAttribute("UseDBBackground",&help)==TIXML_SUCCESS) + SetUseDataBaseForBackground(help!=0); + + delete m_Transform; + m_Transform = CSTransform::New(prop, clParaSet); + + if (prop->QueryDoubleAttribute("Scale",&m_Scale)!=TIXML_SUCCESS) + m_Scale=1; + + if (c_filename==NULL) + return true; + + if ((m_FileType==0) && (c_filename!=NULL)) + return ReadHDF5(c_filename); + else + std::cerr << "CSPropDiscMaterial::ReadFromXML: Unknown file type or no filename given." << std::endl; + + return true; +} + +void *CSPropDiscMaterial::ReadDataSet(std::string filename, std::string d_name, int type_id, int &rank, unsigned int &size, bool debug) +{ + herr_t status; + H5T_class_t class_id; + size_t type_size; + rank = -1; + + // open hdf5 file + hid_t file_id = H5Fopen( filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT ); + if (file_id < 0) + { + if (debug) + std::cerr << __func__ << ": Failed to open file, skipping..." << std::endl; + H5Fclose(file_id); + return NULL; + } + + if (H5Lexists(file_id, d_name.c_str(), H5P_DEFAULT)<=0) + { + if (debug) + std::cerr << __func__ << ": Warning, dataset: \"" << d_name << "\" not found... skipping" << std::endl; + H5Fclose(file_id); + return NULL; + } + + status = H5LTget_dataset_ndims(file_id, d_name.c_str(), &rank); + if (status < 0) + { + if (debug) + std::cerr << __func__ << ": Warning, failed to read dimension for dataset: \"" << d_name << "\" skipping..." << std::endl; + H5Fclose(file_id); + return NULL; + } + + hsize_t dims[rank]; + status = H5LTget_dataset_info( file_id, d_name.c_str(), dims, &class_id, &type_size); + if (status < 0) + { + if (debug) + std::cerr << __func__ << ": Warning, failed to read dataset info: \"" << d_name << "\" skipping..." << std::endl; + H5Fclose(file_id); + return NULL; + } + + size = 1; + for (int n=0;n<rank;++n) + size*=dims[n]; + + void* data; + if (type_id==H5T_NATIVE_FLOAT) + data = (void*) new float[size]; + else if (type_id==H5T_NATIVE_INT) + data = (void*) new int[size]; + else if (type_id==H5T_NATIVE_UINT8) + data = (void*) new uint8[size]; + else + { + std::cerr << __func__ << ": Error, unknown data type" << std::endl; + H5Fclose(file_id); + return NULL; + } + + status = H5LTread_dataset( file_id, d_name.c_str(), type_id, data ); + if (status < 0) + { + if (debug) + std::cerr << __func__ << ": Warning, failed to read dataset: \"" << d_name << "\" skipping..." << std::endl; + if (type_id==H5T_NATIVE_FLOAT) + delete[] (float*)data; + else if (type_id==H5T_NATIVE_INT) + delete[] (int*)data; + else if (type_id==H5T_NATIVE_UINT8) + delete[] (uint8*)data; + H5Fclose(file_id); + return NULL; + } + + H5Fclose(file_id); + return data; +} + +bool CSPropDiscMaterial::ReadHDF5( std::string filename ) +{ + cout << __func__ << ": Reading \"" << filename << "\"" << std::endl; + + // open hdf5 file + hid_t file_id = H5Fopen( filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT ); + if (file_id < 0) + { + std::cerr << __func__ << ": Error, failed to open file, abort..." << std::endl; + return false; + } + + double ver; + herr_t status = H5LTget_attribute_double(file_id, "/", "Version", &ver); + if (status < 0) + ver = 1.0; + + if (ver<2.0) + { + std::cerr << __func__ << ": Error, older file versions are no longer supported, abort..." << std::endl; + H5Fclose(file_id); + return false; + } + + int db_size; + status = H5LTget_attribute_int(file_id, "/DiscData", "DB_Size", &db_size); + if (status<0) + { + std::cerr << __func__ << ": Error, can't read database size, abort..." << std::endl; + H5Fclose(file_id); + return false; + } + + m_DB_size = db_size; + if (H5Lexists(file_id, "/DiscData", H5P_DEFAULT)<=0) + { + std::cerr << __func__ << ": Error, can't read database, abort..." << std::endl; + H5Fclose(file_id); + return false; + } + + hid_t dataset = H5Dopen2(file_id, "/DiscData", H5P_DEFAULT); + if (dataset<0) + { + std::cerr << __func__ << ": Error, can't open database" << std::endl; + H5Fclose(file_id); + return 0; + } + + // read database + if (H5LTfind_attribute(dataset, "epsR")==1) + { + m_Disc_epsR = new float[db_size]; + status = H5LTget_attribute_float(file_id, "/DiscData", "epsR", m_Disc_epsR); + } + else + { + std::cerr << __func__ << ": No \"/DiscData/epsR\" found, skipping..." << std::endl; + m_Disc_epsR=NULL; + } + + delete[] m_Disc_kappa; + if (H5LTfind_attribute(dataset, "kappa")==1) + { + m_Disc_kappa = new float[db_size]; + status = H5LTget_attribute_float(file_id, "/DiscData", "kappa", m_Disc_kappa); + } + else + { + std::cerr << __func__ << ": No \"/DiscData/kappa\" found, skipping..." << std::endl; + m_Disc_kappa=NULL; + } + + delete[] m_Disc_mueR; + if (H5LTfind_attribute(dataset, "mueR")==1) + { + m_Disc_mueR = new float[db_size]; + status = H5LTget_attribute_float(file_id, "/DiscData", "mueR", m_Disc_mueR); + } + else + { + std::cerr << __func__ << ": No \"/DiscData/mueR\" found, skipping..." << std::endl; + m_Disc_mueR=NULL; + } + + delete[] m_Disc_sigma; + if (H5LTfind_attribute(dataset, "sigma")==1) + { + m_Disc_sigma = new float[db_size]; + status = H5LTget_attribute_float(file_id, "/DiscData", "sigma", m_Disc_sigma); + } + else + { + std::cerr << __func__ << ": No \"/DiscData/sigma\" found, skipping..." << std::endl; + m_Disc_sigma=NULL; + } + + delete[] m_Disc_Density; + if (H5LTfind_attribute(dataset, "density")==1) + { + m_Disc_Density = new float[db_size]; + status = H5LTget_attribute_float(file_id, "/DiscData", "density", m_Disc_Density); + } + else + { + std::cerr << __func__ << ": no \"/DiscData/density\" found, skipping..." << std::endl; + m_Disc_Density=NULL; + } + + H5Fclose(file_id); + + // read mesh + unsigned int size; + int rank; + unsigned int numCells = 1; + std::string names[] = {"/mesh/x","/mesh/y","/mesh/z"}; + for (int n=0; n<3; ++n) + { + m_mesh[n] = (float*)ReadDataSet(filename, names[n], H5T_NATIVE_FLOAT, rank, size); + if ((m_mesh[n]==NULL) || (rank!=1) || (size<=1)) + { + std::cerr << __func__ << ": Error, failed to read or invalid mesh, abort..." << std::endl; + H5Fclose(file_id); + return false; + } + m_Size[n]=size; + numCells*=(m_Size[n]-1); + } + + delete[] m_Disc_Ind; + m_Disc_Ind = (uint8*)ReadDataSet(filename, "/DiscData", H5T_NATIVE_UINT8, rank, size, true); + + if ((m_Disc_Ind==NULL) || (rank!=3) || (size!=numCells)) + { + std::cerr << __func__ << ": Error, can't read database indizies or size/rank is invalid, abort..." << std::endl; + delete[] m_Disc_Ind; + m_Disc_Ind = NULL; + return false; + } + return true; +} + +void CSPropDiscMaterial::ShowPropertyStatus(std::ostream& stream) +{ + CSProperties::ShowPropertyStatus(stream); + stream << " --- Discrete Material Properties --- " << std::endl; + stream << " Data-Base Size:\t: " << m_DB_size << std::endl; + stream << " Number of Voxels:\t: " << m_Size[0] << "x" << m_Size[1] << "x" << m_Size[2] << std::endl; + stream << " Background Material Properties: " << std::endl; + stream << " Isotropy\t: " << bIsotropy << std::endl; + stream << " Epsilon_R\t: " << Epsilon[0].GetValueString() << ", " << Epsilon[1].GetValueString() << ", " << Epsilon[2].GetValueString() << std::endl; + stream << " Kappa\t\t: " << Kappa[0].GetValueString() << ", " << Kappa[1].GetValueString() << ", " << Kappa[2].GetValueString() << std::endl; + stream << " Mue_R\t\t: " << Mue[0].GetValueString() << ", " << Mue[1].GetValueString() << ", " << Mue[2].GetValueString() << std::endl; + stream << " Sigma\t\t: " << Sigma[0].GetValueString() << ", " << Sigma[1].GetValueString() << ", " << Sigma[2].GetValueString() << std::endl; + stream << " Density\t: " << Density.GetValueString() << std::endl; +} + +vtkPolyData* CSPropDiscMaterial::CreatePolyDataModel() const +{ + vtkPolyData* polydata = vtkPolyData::New(); + vtkCellArray *poly = vtkCellArray::New(); + vtkPoints *points = vtkPoints::New(); + + + int* pointIdx[2]; + pointIdx[0] = new int[m_Size[0]*m_Size[1]]; + pointIdx[1] = new int[m_Size[0]*m_Size[1]]; + // init point idx + for (unsigned int n=0;n<m_Size[0]*m_Size[1];++n) + { + pointIdx[0][n]=-1; + pointIdx[1][n]=-1; + } + + unsigned int mat_idx, mat_idx_down; + unsigned int mesh_idx=0; + bool bd, bu; + int nP, nPP; + unsigned int pos[3],rpos[3]; + for (pos[2]=0;pos[2]<m_Size[2]-1;++pos[2]) + { // each xy-plane + for (unsigned int n=0;n<m_Size[0]*m_Size[1];++n) + { + pointIdx[0][n]=pointIdx[1][n]; + pointIdx[1][n]=-1; + } + for (pos[0]=0;pos[0]<m_Size[0]-1;++pos[0]) + for (pos[1]=0;pos[1]<m_Size[1]-1;++pos[1]) + { + mat_idx = pos[0] + pos[1]*(m_Size[0]-1) + pos[2]*(m_Size[0]-1)*(m_Size[1]-1); + for (int n=0;n<3;++n) + { + // reset relative pos + rpos[0]=pos[0]; + rpos[1]=pos[1]; + rpos[2]=pos[2]; + bd = false; + bu = false; + if (pos[n]==0) + { + if (m_Disc_Ind[mat_idx]>0) + bd=true; + } + else if (pos[n]==m_Size[n]-2) + { + if (m_Disc_Ind[mat_idx]>0) + bu=true; + } + else + { + rpos[n] = pos[n]-1; // set relative pos + mat_idx_down = rpos[0] + rpos[1]*(m_Size[0]-1) + rpos[2]*(m_Size[0]-1)*(m_Size[1]-1); + rpos[n] = pos[n]; // reset relative pos + if ((m_Disc_Ind[mat_idx]>0) && (m_Disc_Ind[mat_idx_down]==0)) + bd=true; + else if (m_Disc_Ind[mat_idx]==0 && (m_Disc_Ind[mat_idx_down]>0)) + bu=true; + } + + rpos[0]=pos[0]; + rpos[1]=pos[1]; + rpos[2]=0; + + if (bu) // draw poly for surface up + { + nP = (n+1)%3; + nPP = (n+2)%3; + poly->InsertNextCell(4); + + mesh_idx = rpos[0] + rpos[1]*m_Size[0]; + if (pointIdx[rpos[2]][mesh_idx]<0) + pointIdx[rpos[2]][mesh_idx] = (int)points->InsertNextPoint(m_mesh[0][rpos[0]],m_mesh[1][rpos[1]],m_mesh[2][pos[2]+rpos[2]]); + poly->InsertCellPoint(pointIdx[rpos[2]][mesh_idx]); + + ++rpos[nP]; + mesh_idx = rpos[0] + rpos[1]*m_Size[0]; + if (pointIdx[rpos[2]][mesh_idx]<0) + pointIdx[rpos[2]][mesh_idx] = (int)points->InsertNextPoint(m_mesh[0][rpos[0]],m_mesh[1][rpos[1]],m_mesh[2][pos[2]+rpos[2]]); + poly->InsertCellPoint(pointIdx[rpos[2]][mesh_idx]); + + ++rpos[nPP]; + mesh_idx = rpos[0] + rpos[1]*m_Size[0]; + if (pointIdx[rpos[2]][mesh_idx]<0) + pointIdx[rpos[2]][mesh_idx] = (int)points->InsertNextPoint(m_mesh[0][rpos[0]],m_mesh[1][rpos[1]],m_mesh[2][pos[2]+rpos[2]]); + poly->InsertCellPoint(pointIdx[rpos[2]][mesh_idx]); + + --rpos[nP]; + mesh_idx = rpos[0] + rpos[1]*m_Size[0]; + if (pointIdx[rpos[2]][mesh_idx]<0) + pointIdx[rpos[2]][mesh_idx] = (int)points->InsertNextPoint(m_mesh[0][rpos[0]],m_mesh[1][rpos[1]],m_mesh[2][pos[2]+rpos[2]]); + poly->InsertCellPoint(pointIdx[rpos[2]][mesh_idx]); + } + else if (bd) // draw poly for surface down + { + nP = (n+1)%3; + nPP = (n+2)%3; + poly->InsertNextCell(4); + mesh_idx = rpos[0] + rpos[1]*m_Size[0]; + if (pointIdx[rpos[2]][mesh_idx]<0) + pointIdx[rpos[2]][mesh_idx] = (int)points->InsertNextPoint(m_mesh[0][rpos[0]],m_mesh[1][rpos[1]],m_mesh[2][pos[2]+rpos[2]]); + poly->InsertCellPoint(pointIdx[rpos[2]][mesh_idx]); + + ++rpos[nPP]; + mesh_idx = rpos[0] + rpos[1]*m_Size[0]; + if (pointIdx[rpos[2]][mesh_idx]<0) + pointIdx[rpos[2]][mesh_idx] = (int)points->InsertNextPoint(m_mesh[0][rpos[0]],m_mesh[1][rpos[1]],m_mesh[2][pos[2]+rpos[2]]); + poly->InsertCellPoint(pointIdx[rpos[2]][mesh_idx]); + + ++rpos[nP]; + mesh_idx = rpos[0] + rpos[1]*m_Size[0]; + if (pointIdx[rpos[2]][mesh_idx]<0) + pointIdx[rpos[2]][mesh_idx] = (int)points->InsertNextPoint(m_mesh[0][rpos[0]],m_mesh[1][rpos[1]],m_mesh[2][pos[2]+rpos[2]]); + poly->InsertCellPoint(pointIdx[rpos[2]][mesh_idx]); + + --rpos[nPP]; + mesh_idx = rpos[0] + rpos[1]*m_Size[0]; + if (pointIdx[rpos[2]][mesh_idx]<0) + pointIdx[rpos[2]][mesh_idx] = (int)points->InsertNextPoint(m_mesh[0][rpos[0]],m_mesh[1][rpos[1]],m_mesh[2][pos[2]+rpos[2]]); + poly->InsertCellPoint(pointIdx[rpos[2]][mesh_idx]); + } + } + } + } + delete[] pointIdx[0]; + delete[] pointIdx[1]; + + polydata->SetPoints(points); + points->Delete(); + polydata->SetPolys(poly); + poly->Delete(); + + return polydata; +} diff --git a/CSXCAD/src/CSPropDiscMaterial.h b/CSXCAD/src/CSPropDiscMaterial.h new file mode 100644 index 0000000..5317ac7 --- /dev/null +++ b/CSXCAD/src/CSPropDiscMaterial.h @@ -0,0 +1,88 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSProperties.h" +#include "CSPropMaterial.h" + +typedef unsigned char uint8; + +class vtkPolyData; + +//! Continuous Structure Discrete Material Property +/*! + This Property reads a discrete material distribution from a file. (currently only HDF5) + */ +class CSXCAD_EXPORT CSPropDiscMaterial : public CSPropMaterial +{ +public: + CSPropDiscMaterial(ParameterSet* paraSet); + CSPropDiscMaterial(CSProperties* prop); + CSPropDiscMaterial(unsigned int ID, ParameterSet* paraSet); + virtual ~CSPropDiscMaterial(); + + virtual const std::string GetTypeXMLString() const {return std::string("Discrete-Material");} + + virtual double GetEpsilonWeighted(int ny, const double* coords); + virtual double GetMueWeighted(int ny, const double* coords); + virtual double GetKappaWeighted(int ny, const double* coords); + virtual double GetSigmaWeighted(int ny, const double* coords); + + virtual double GetDensityWeighted(const double* coords); + + //! Set true if database index 0 is used as background material (default), or false if CSPropMaterial should be used as index 0 + virtual void SetUseDataBaseForBackground(bool val) {m_DB_Background=val;} + + CSTransform* GetTransform() {return m_Transform;} + + double GetScale() {return m_Scale;} + + virtual void Init(); + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); + + bool ReadHDF5(std::string filename); + + virtual void ShowPropertyStatus(std::ostream& stream); + + //! Create a vtkPolyData surface that separates the discrete material from background material + virtual vtkPolyData* CreatePolyDataModel() const; + +protected: + unsigned int GetWeightingPos(const double* coords); + int GetDBPos(const double* coords); + + int m_FileType; + std::string m_Filename; + unsigned int m_Size[3]; + unsigned int m_DB_size; + uint8* m_Disc_Ind; + float *m_mesh[3]; + float *m_Disc_epsR; + float *m_Disc_kappa; + float *m_Disc_mueR; + float *m_Disc_sigma; + float *m_Disc_Density; + double m_Scale; + bool m_DB_Background; + CSTransform* m_Transform; + + void* ReadDataSet(std::string filename, std::string d_name, int type_id, int &rank, unsigned int &size, bool debug=false); +}; + diff --git a/CSXCAD/src/CSPropDispersiveMaterial.cpp b/CSXCAD/src/CSPropDispersiveMaterial.cpp new file mode 100644 index 0000000..43922f6 --- /dev/null +++ b/CSXCAD/src/CSPropDispersiveMaterial.cpp @@ -0,0 +1,40 @@ +/* +* 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 "tinyxml.h" + +#include "CSPropDispersiveMaterial.h" + +CSPropDispersiveMaterial::CSPropDispersiveMaterial(ParameterSet* paraSet) : CSPropMaterial(paraSet) {m_Order=0;Type=(CSProperties::PropertyType)(DISPERSIVEMATERIAL | MATERIAL);} +CSPropDispersiveMaterial::CSPropDispersiveMaterial(CSProperties* prop) : CSPropMaterial(prop) {m_Order=0;Type=(CSProperties::PropertyType)(DISPERSIVEMATERIAL | MATERIAL);} +CSPropDispersiveMaterial::CSPropDispersiveMaterial(unsigned int ID, ParameterSet* paraSet) : CSPropMaterial(ID,paraSet) {m_Order=0;Type=(CSProperties::PropertyType)(DISPERSIVEMATERIAL | MATERIAL);} +CSPropDispersiveMaterial::~CSPropDispersiveMaterial() {} + +bool CSPropDispersiveMaterial::Update(std::string *ErrStr) +{ + return CSPropMaterial::Update(ErrStr); +} + +bool CSPropDispersiveMaterial::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + return CSPropMaterial::Write2XML(root,parameterised,sparse); +} + +bool CSPropDispersiveMaterial::ReadFromXML(TiXmlNode &root) +{ + return CSPropMaterial::ReadFromXML(root); +} diff --git a/CSXCAD/src/CSPropDispersiveMaterial.h b/CSXCAD/src/CSPropDispersiveMaterial.h new file mode 100644 index 0000000..196653f --- /dev/null +++ b/CSXCAD/src/CSPropDispersiveMaterial.h @@ -0,0 +1,49 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSProperties.h" +#include "CSPropMaterial.h" + +//! Continuous Structure Dispersive Material Property +/*! + This abstarct Property can hold information about the special properties of dispersive materials. + */ +class CSXCAD_EXPORT CSPropDispersiveMaterial : public CSPropMaterial +{ +public: + virtual ~CSPropDispersiveMaterial(); + + //! Get the dispersion order + virtual int GetDispersionOrder() {return m_Order;} + + //! Get PropertyType as a xml element name \sa PropertyType and GetType + virtual const std::string GetTypeXMLString() const {return std::string("DispersiveMaterial");} + +protected: + int m_Order; + + virtual bool Update(std::string *ErrStr=NULL); + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); + + CSPropDispersiveMaterial(ParameterSet* paraSet); + CSPropDispersiveMaterial(CSProperties* prop); + CSPropDispersiveMaterial(unsigned int ID, ParameterSet* paraSet); +}; diff --git a/CSXCAD/src/CSPropDumpBox.cpp b/CSXCAD/src/CSPropDumpBox.cpp new file mode 100644 index 0000000..6cccce6 --- /dev/null +++ b/CSXCAD/src/CSPropDumpBox.cpp @@ -0,0 +1,158 @@ +/* +* 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 "tinyxml.h" + +#include "CSPropDumpBox.h" + +CSPropDumpBox::CSPropDumpBox(ParameterSet* paraSet) : CSPropProbeBox(paraSet) {Type=DUMPBOX;Init();} +CSPropDumpBox::CSPropDumpBox(CSProperties* prop) : CSPropProbeBox(prop) {Type=DUMPBOX;Init();} +CSPropDumpBox::CSPropDumpBox(unsigned int ID, ParameterSet* paraSet) : CSPropProbeBox(ID,paraSet) {Type=DUMPBOX;Init();} +CSPropDumpBox::~CSPropDumpBox() {} + +void CSPropDumpBox::Init() +{ + DumpType = 0; + DumpMode = 0; + FileType = 0; + MultiGridLevel = 0; + m_SubSampling=false; + SubSampling[0]=1; + SubSampling[1]=1; + SubSampling[2]=1; + m_OptResolution=false; + OptResolution[0]=1; + OptResolution[1]=1; + OptResolution[2]=1; +} + +void CSPropDumpBox::SetSubSampling(int ny, unsigned int val) +{ + if ((ny<0) || (ny>2)) return; + if (val<1) return; + SubSampling[ny] = val; +} + +void CSPropDumpBox::SetSubSampling(unsigned int val[]) +{ + for (int ny=0;ny<3;++ny) + SetSubSampling(ny,val[ny]); +} + +void CSPropDumpBox::SetSubSampling(const char* vals) +{ + if (vals==NULL) return; + m_SubSampling=true; + std::vector<int> values = SplitString2Int(std::string(vals),','); + for (int ny=0;ny<3 && ny<(int)values.size();++ny) + SetSubSampling(ny,values.at(ny)); +} + +unsigned int CSPropDumpBox::GetSubSampling(int ny) +{ + if ((ny<0) || (ny>2)) return 1; + return SubSampling[ny]; +} + +void CSPropDumpBox::SetOptResolution(int ny, double val) +{ + if ((ny<0) || (ny>2)) return; + if (val<0) return; + OptResolution[ny] = val; +} + +void CSPropDumpBox::SetOptResolution(double val[]) +{ + for (int ny=0;ny<3;++ny) + SetOptResolution(ny,val[ny]); +} + +void CSPropDumpBox::SetOptResolution(const char* vals) +{ + if (vals==NULL) return; + m_OptResolution=true; + std::vector<double> values = SplitString2Double(std::string(vals),','); + if (values.size()==1) //allow one resolution for all directions + { + for (int ny=0;ny<3;++ny) + SetOptResolution(ny,values.at(0)); + return; + } + for (int ny=0;ny<3 && ny<(int)values.size();++ny) + SetOptResolution(ny,values.at(ny)); +} + +double CSPropDumpBox::GetOptResolution(int ny) +{ + if ((ny<0) || (ny>2)) return 1; + return OptResolution[ny]; +} + +bool CSPropDumpBox::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + if (CSPropProbeBox::Write2XML(root,parameterised,sparse) == false) return false; + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + prop->SetAttribute("DumpType",DumpType); + prop->SetAttribute("DumpMode",DumpMode); + prop->SetAttribute("FileType",FileType); + prop->SetAttribute("MultiGridLevel",MultiGridLevel); + + if (m_SubSampling) + { + std::stringstream ss; + ss << GetSubSampling(0) << "," << GetSubSampling(1) << "," << GetSubSampling(2) ; + prop->SetAttribute("SubSampling",ss.str().c_str()); + } + if (m_OptResolution) + { + std::stringstream ss; + ss << GetOptResolution(0) << "," << GetOptResolution(1) << "," << GetOptResolution(2) ; + prop->SetAttribute("OptResolution",ss.str().c_str()); + } + + return true; +} + +bool CSPropDumpBox::ReadFromXML(TiXmlNode &root) +{ + if (CSPropProbeBox::ReadFromXML(root)==false) return false; + + TiXmlElement *prop = root.ToElement(); + if (prop==NULL) return false; + + if (prop->QueryIntAttribute("DumpType",&DumpType)!=TIXML_SUCCESS) DumpType=0; + if (prop->QueryIntAttribute("DumpMode",&DumpMode)!=TIXML_SUCCESS) DumpMode=0; + if (prop->QueryIntAttribute("FileType",&FileType)!=TIXML_SUCCESS) FileType=0; + if (prop->QueryIntAttribute("MultiGridLevel",&MultiGridLevel)!=TIXML_SUCCESS) MultiGridLevel=0; + + SetSubSampling(prop->Attribute("SubSampling")); + SetOptResolution(prop->Attribute("OptResolution")); + + return true; +} + +void CSPropDumpBox::ShowPropertyStatus(std::ostream& stream) +{ + //skip output of prarent CSPropProbeBox + CSProperties::ShowPropertyStatus(stream); + stream << " --- Dump Properties --- " << std::endl; + stream << " DumpType: " << DumpType << " DumpMode: " << DumpMode << " FileType: " << FileType << " MultiGridLevel: " << MultiGridLevel << std::endl; + if (m_FD_Samples.size()>0) + stream << " Dump Frequencies: " << CombineVector2String(m_FD_Samples,',') << std::endl; +} diff --git a/CSXCAD/src/CSPropDumpBox.h b/CSXCAD/src/CSPropDumpBox.h new file mode 100644 index 0000000..424be2b --- /dev/null +++ b/CSXCAD/src/CSPropDumpBox.h @@ -0,0 +1,98 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSPropProbeBox.h" + + +//! Continuous Structure Dump Property +/*! + This Property defines an area (box) designated for field dumps. + */ +class CSXCAD_EXPORT CSPropDumpBox : public CSPropProbeBox +{ +public: + CSPropDumpBox(ParameterSet* paraSet); + CSPropDumpBox(CSProperties* prop); + CSPropDumpBox(unsigned int ID, ParameterSet* paraSet); + virtual ~CSPropDumpBox(); + + //! Get PropertyType as a xml element name \sa PropertyType and GetType + virtual const std::string GetTypeXMLString() const {return std::string("DumpBox");} + + //! Define an arbitrary dump-type \sa GetDumpType + void SetDumpType(int type) {DumpType=type;} + //! Get the arbitrary dump-type \sa SetDumpType + int GetDumpType() {return DumpType;} + + //! Define an arbitrary dump-mode \sa GetDumpMode + void SetDumpMode(int mode) {DumpMode=mode;} + //! Get the arbitrary dump-mode \sa SetDumpMode + int GetDumpMode() {return DumpMode;} + + //! Define an arbitrary file-type \sa GetFileType + void SetFileType(int ftype) {FileType=ftype;} + //! Get the arbitrary file-type \sa SetFileType + int GetFileType() {return FileType;} + + //! Set the multi grid level to use (default is 0) \sa GetMultiGridLevel + void SetMultiGridLevel(int mgl) {MultiGridLevel=mgl;} + //! Get the multi grid level to use \sa SetMultiGridLevel + int GetMultiGridLevel() {return MultiGridLevel;} + + bool GetSubSampling() {return m_SubSampling;} + void SetSubSampling(bool val) {m_SubSampling=val;} + void SetSubSampling(int ny, unsigned int val); + void SetSubSampling(unsigned int val[]); + void SetSubSampling(const char* vals); + unsigned int GetSubSampling(int ny); + + //! Get status of opt resolution flag + bool GetOptResolution() {return m_OptResolution;} + //! Set status of opt resolution flag + void SetOptResolution(bool val) {m_OptResolution=val;} + //! Set the opt resoultion for a given direction + void SetOptResolution(int ny, double val); + //! Set the opt resoultion for all directions + void SetOptResolution(double val[]); + //! Set the opt resoultion for all directions as string + void SetOptResolution(const char* vals); + //! Get the optimal resolution for a given direction + double GetOptResolution(int ny); + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual void Init(); + + virtual void ShowPropertyStatus(std::ostream& stream); + +protected: + int DumpType; + int DumpMode; + int FileType; + int MultiGridLevel; + + //sub-sampling + bool m_SubSampling; + unsigned int SubSampling[3]; + + //sub-sampling + bool m_OptResolution; + double OptResolution[3]; +}; diff --git a/CSXCAD/src/CSPropExcitation.cpp b/CSXCAD/src/CSPropExcitation.cpp new file mode 100644 index 0000000..8d498ad --- /dev/null +++ b/CSXCAD/src/CSPropExcitation.cpp @@ -0,0 +1,278 @@ +/* +* 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 "tinyxml.h" + +#include "CSPropExcitation.h" + +CSPropExcitation::CSPropExcitation(ParameterSet* paraSet,unsigned int number) : CSProperties(paraSet) {Type=EXCITATION;Init();uiNumber=number;} +CSPropExcitation::CSPropExcitation(CSProperties* prop) : CSProperties(prop) {Type=EXCITATION;Init();} +CSPropExcitation::CSPropExcitation(unsigned int ID, ParameterSet* paraSet) : CSProperties(ID,paraSet) {Type=EXCITATION;Init();} +CSPropExcitation::~CSPropExcitation() {} + +void CSPropExcitation::SetNumber(unsigned int val) {uiNumber=val;} +unsigned int CSPropExcitation::GetNumber() {return uiNumber;} + +void CSPropExcitation::SetExcitType(int val) {iExcitType=val;} +int CSPropExcitation::GetExcitType() {return iExcitType;} + +void CSPropExcitation::SetExcitation(double val, int Component) +{ + if ((Component<0) || (Component>=3)) return; + Excitation[Component].SetValue(val); +} + +void CSPropExcitation::SetExcitation(const std::string val, int Component) +{ + if ((Component<0) || (Component>=3)) return; + Excitation[Component].SetValue(val); +} + +double CSPropExcitation::GetExcitation(int Component) +{ + if ((Component<0) || (Component>=3)) return 0; + return Excitation[Component].GetValue(); +} + +const std::string CSPropExcitation::GetExcitationString(int Comp) +{ + if ((Comp<0) || (Comp>=3)) return NULL; + return Excitation[Comp].GetString(); +} + +void CSPropExcitation::SetActiveDir(bool active, int Component) +{ + if ((Component<0) || (Component>=3)) return; + ActiveDir[Component]=active; +} + +bool CSPropExcitation::GetActiveDir(int Component) +{ + if ((Component<0) || (Component>=3)) return false; + return ActiveDir[Component]; +} + +int CSPropExcitation::SetWeightFunction(const std::string fct, int ny) +{ + if ((ny>=0) && (ny<3)) + return WeightFct[ny].SetValue(fct); + return 0; +} + +const std::string CSPropExcitation::GetWeightFunction(int ny) {if ((ny>=0) && (ny<3)) {return WeightFct[ny].GetString();} else return std::string();} + +double CSPropExcitation::GetWeightedExcitation(int ny, const double* coords) +{ + if ((ny<0) || (ny>=3)) return 0; + //Warning: this is not reentrant....!!!! + double loc_coords[3] = {coords[0],coords[1],coords[2]}; + double r,rho,alpha,theta; + if (coordInputType==1) + { + loc_coords[0] = coords[0]*cos(coords[1]); + loc_coords[1] = coords[0]*sin(coords[1]); + rho = coords[0]; + alpha=coords[1]; + r = sqrt(pow(coords[0],2)+pow(coords[2],2)); + theta=asin(1)-atan(coords[2]/rho); + } + else + { + alpha=atan2(coords[1],coords[0]); + rho = sqrt(pow(coords[0],2)+pow(coords[1],2)); + r = sqrt(pow(coords[0],2)+pow(coords[1],2)+pow(coords[2],2)); + theta=asin(1)-atan(coords[2]/rho); + } + coordPara[0]->SetValue(loc_coords[0]); + coordPara[1]->SetValue(loc_coords[1]); + coordPara[2]->SetValue(loc_coords[2]); + coordPara[3]->SetValue(rho); //rho + coordPara[4]->SetValue(r); //r + coordPara[5]->SetValue(alpha); + coordPara[6]->SetValue(theta); //theta + int EC = WeightFct[ny].Evaluate(); + if (EC) + { + std::cerr << "CSPropExcitation::GetWeightedExcitation: Error evaluating the weighting function (ID: " << this->GetID() << ", n=" << ny << "): " << PSErrorCode2Msg(EC) << std::endl; + } + + return WeightFct[ny].GetValue()*GetExcitation(ny); +} + +void CSPropExcitation::SetDelay(double val) {Delay.SetValue(val);} + +void CSPropExcitation::SetDelay(const std::string val) {Delay.SetValue(val);} + +double CSPropExcitation::GetDelay(){return Delay.GetValue();} + +const std::string CSPropExcitation::GetDelayString(){return Delay.GetString();} + +void CSPropExcitation::Init() +{ + uiNumber=0; + iExcitType=1; + coordInputType=UNDEFINED_CS; + m_Frequency.SetValue(0.0); + for (unsigned int i=0;i<3;++i) + { + ActiveDir[i]=true; + Excitation[i].SetValue(0.0); + Excitation[i].SetParameterSet(clParaSet); + WeightFct[i].SetValue(1.0); + WeightFct[i].SetParameterSet(coordParaSet); + Delay.SetValue(0.0); + Delay.SetParameterSet(clParaSet); + } +} + +void CSPropExcitation::SetPropagationDir(double val, int Component) +{ + if ((Component<0) || (Component>=3)) return; + PropagationDir[Component].SetValue(val); +} + +void CSPropExcitation::SetPropagationDir(const std::string val, int Component) +{ + if ((Component<0) || (Component>=3)) return; + PropagationDir[Component].SetValue(val); +} + +double CSPropExcitation::GetPropagationDir(int Component) +{ + if ((Component<0) || (Component>=3)) return 0; + return PropagationDir[Component].GetValue(); +} + +const std::string CSPropExcitation::GetPropagationDirString(int Comp) +{ + if ((Comp<0) || (Comp>=3)) return NULL; + return PropagationDir[Comp].GetString(); +} + + +bool CSPropExcitation::Update(std::string *ErrStr) +{ + bool bOK=true; + int EC=0; + for (unsigned int i=0;i<3;++i) + { + EC=Excitation[i].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Excitation-Property Excitaion-Value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=PropagationDir[i].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Excitation-Property PropagationDir-Value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + } + EC=m_Frequency.Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Excitation-Property Frequency-Value"; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=Delay.Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Excitation-Property Delay-Value"; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + return bOK; +} + +bool CSPropExcitation::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + if (CSProperties::Write2XML(root,parameterised,sparse) == false) return false; + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + prop->SetAttribute("Number",(int)uiNumber); + WriteTerm(m_Frequency,*prop,"Frequency",parameterised); + WriteTerm(Delay,*prop,"Delay",parameterised); + + prop->SetAttribute("Type",iExcitType); + WriteVectorTerm(Excitation,*prop,"Excite",parameterised); + + TiXmlElement Weight("Weight"); + WriteTerm(WeightFct[0],Weight,"X",parameterised); + WriteTerm(WeightFct[1],Weight,"Y",parameterised); + WriteTerm(WeightFct[2],Weight,"Z",parameterised); + prop->InsertEndChild(Weight); + + WriteVectorTerm(PropagationDir,*prop,"PropDir",parameterised); + + return true; +} + +bool CSPropExcitation::ReadFromXML(TiXmlNode &root) +{ + if (CSProperties::ReadFromXML(root)==false) return false; + + TiXmlElement *prop = root.ToElement(); + if (prop==NULL) return false; + + int iHelp; + if (prop->QueryIntAttribute("Number",&iHelp)!=TIXML_SUCCESS) uiNumber=0; + else uiNumber=(unsigned int)iHelp; + + if (prop->QueryIntAttribute("Type",&iExcitType)!=TIXML_SUCCESS) return false; + + if (ReadVectorTerm(Excitation,*prop,"Excite",0.0)==false) return false; + + ReadTerm(m_Frequency,*prop,"Frequency"); + ReadTerm(Delay,*prop,"Delay"); + + TiXmlElement *weight = prop->FirstChildElement("Weight"); + if (weight!=NULL) + { + ReadTerm(WeightFct[0],*weight,"X"); + ReadTerm(WeightFct[1],*weight,"Y"); + ReadTerm(WeightFct[2],*weight,"Z"); + } + + ReadVectorTerm(PropagationDir,*prop,"PropDir",0.0); + + return true; +} + +void CSPropExcitation::ShowPropertyStatus(std::ostream& stream) +{ + CSProperties::ShowPropertyStatus(stream); + stream << " --- Excitation Properties --- " << std::endl; + stream << " Type: " << iExcitType << std::endl; + stream << " Active directions: " << ActiveDir[0] << "," << ActiveDir[1] << "," << ActiveDir[2] << std::endl; + stream << " Excitation\t: " << Excitation[0].GetValueString() << ", " << Excitation[1].GetValueString() << ", " << Excitation[2].GetValueString() << std::endl; + stream << " Weighting\t: " << WeightFct[0].GetValueString() << ", " << WeightFct[1].GetValueString() << ", " << WeightFct[2].GetValueString() << std::endl; + stream << " Propagation Dir: " << PropagationDir[0].GetValueString() << ", " << PropagationDir[1].GetValueString() << ", " << PropagationDir[2].GetValueString() << std::endl; + stream << " Delay\t\t: " << Delay.GetValueString() << std::endl; +} diff --git a/CSXCAD/src/CSPropExcitation.h b/CSXCAD/src/CSPropExcitation.h new file mode 100644 index 0000000..5cd166c --- /dev/null +++ b/CSXCAD/src/CSPropExcitation.h @@ -0,0 +1,114 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSProperties.h" + +//! Continuous Structure Excitation Property +/*! + This Property defines an excitation which can be location and direction dependent. + */ +class CSXCAD_EXPORT CSPropExcitation : public CSProperties +{ +public: + CSPropExcitation(ParameterSet* paraSet,unsigned int number=0); + CSPropExcitation(CSProperties* prop); + CSPropExcitation(unsigned int ID, ParameterSet* paraSet); + virtual ~CSPropExcitation(); + + //! Get PropertyType as a xml element name \sa PropertyType and GetType + virtual const std::string GetTypeXMLString() const {return std::string("Excitation");} + + //! Set the number for this excitation + void SetNumber(unsigned int val); + //! Get the number for this excitation + unsigned int GetNumber(); + + //! Set the excitation type + void SetExcitType(int val); + //! Get the excitation type + int GetExcitType(); + + //! Set the active direction for the source, only necessary with hard sources (by default all active) + void SetActiveDir(bool active, int Component=0); + //! Get the active direction for the source, only necessary with hard sources (by default all active) + bool GetActiveDir(int Component=0); + + //! Set the excitation frequency + void SetFrequency(double val) {m_Frequency.SetValue(val);} + //! Set the excitation frequency + void SetFrequency(const std::string val) {m_Frequency.SetValue(val);} + //! Get the excitation frequency + double GetFrequency() {return m_Frequency.GetValue();} + //! Get the excitation frequency as a string + const std::string GetFrequencyString() {return m_Frequency.GetValueString();} + + //! Set the excitation amplitude for a given component + void SetExcitation(double val, int Component=0); + //! Set the excitation amplitude for a given component + void SetExcitation(const std::string val, int Component=0); + //! Get the excitation amplitude for a given component + double GetExcitation(int Component=0); + //! Get the excitation amplitude as a string for a given component + const std::string GetExcitationString(int Comp=0); + + //! Set a weighting factor for the given component. This will override the weighting function! + void SetWeight(double val, int ny); + //! Set a weighting function for the given excitation component + int SetWeightFunction(const std::string fct, int ny); + //! Get the weighting function for the given excitation component + const std::string GetWeightFunction(int ny); + + double GetWeightedExcitation(int ny, const double* coords); + + //! Set the propagation direction for a given component + void SetPropagationDir(double val, int Component=0); + //! Set the propagation direction for a given component + void SetPropagationDir(const std::string val, int Component=0); + //! Get the propagation direction for a given component + double GetPropagationDir(int Component=0); + //! Get the propagation direction as a string for a given component + const std::string GetPropagationDirString(int Comp=0); + + //! Set the excitation delay + void SetDelay(double val); + //! Set the excitation delay + void SetDelay(const std::string val); + //! Get the excitation delay + double GetDelay(); + //! Get the excitation delay as a string + const std::string GetDelayString(); + + virtual void Init(); + virtual bool Update(std::string *ErrStr=NULL); + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual void ShowPropertyStatus(std::ostream& stream); + +protected: + unsigned int uiNumber; + int iExcitType; + bool ActiveDir[3]; + ParameterScalar m_Frequency; + ParameterScalar Excitation[3]; // excitation amplitude vector + ParameterScalar WeightFct[3]; // excitation amplitude weighting function + ParameterScalar PropagationDir[3]; // direction of propagation (should be a unit vector), needed for plane wave excitations + ParameterScalar Delay; // excitation delay only, for time-domain solver e.g. FDTD +}; diff --git a/CSXCAD/src/CSPropLorentzMaterial.cpp b/CSXCAD/src/CSPropLorentzMaterial.cpp new file mode 100644 index 0000000..73cda4a --- /dev/null +++ b/CSXCAD/src/CSPropLorentzMaterial.cpp @@ -0,0 +1,416 @@ +/* +* 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 "tinyxml.h" + +#include "CSPropLorentzMaterial.h" + +CSPropLorentzMaterial::CSPropLorentzMaterial(ParameterSet* paraSet) : CSPropDispersiveMaterial(paraSet) {Type=(CSProperties::PropertyType)(LORENTZMATERIAL | DISPERSIVEMATERIAL | MATERIAL);Init();} +CSPropLorentzMaterial::CSPropLorentzMaterial(CSProperties* prop) : CSPropDispersiveMaterial(prop) {Type=(CSProperties::PropertyType)(LORENTZMATERIAL | DISPERSIVEMATERIAL | MATERIAL);Init();} +CSPropLorentzMaterial::CSPropLorentzMaterial(unsigned int ID, ParameterSet* paraSet) : CSPropDispersiveMaterial(ID,paraSet) {Type=(CSProperties::PropertyType)(LORENTZMATERIAL | DISPERSIVEMATERIAL | MATERIAL);Init();} + +CSPropLorentzMaterial::~CSPropLorentzMaterial() +{ + DeleteValues(); + m_Order = 0; +} + +void CSPropLorentzMaterial::Init() +{ + m_Order = 0; + EpsPlasma=NULL; + MuePlasma=NULL; + WeightEpsPlasma=NULL; + WeightMuePlasma=NULL; + EpsLorPole=NULL; + MueLorPole=NULL; + WeightEpsLorPole=NULL; + WeightMueLorPole=NULL; + EpsRelaxTime=NULL; + MueRelaxTime=NULL; + WeightEpsRelaxTime=NULL; + WeightMueRelaxTime=NULL; + InitValues(); + CSPropDispersiveMaterial::Init(); +} + +void CSPropLorentzMaterial::DeleteValues() +{ + for (int o=0;o<m_Order;++o) + { + delete[] EpsPlasma[o]; + delete[] MuePlasma[o]; + delete[] WeightEpsPlasma[o]; + delete[] WeightMuePlasma[o]; + delete[] EpsLorPole[o]; + delete[] MueLorPole[o]; + delete[] WeightEpsLorPole[o]; + delete[] WeightMueLorPole[o]; + delete[] EpsRelaxTime[o]; + delete[] MueRelaxTime[o]; + delete[] WeightEpsRelaxTime[o]; + delete[] WeightMueRelaxTime[o]; + } + delete[] EpsPlasma; + delete[] MuePlasma; + delete[] WeightEpsPlasma; + delete[] WeightMuePlasma; + delete[] EpsLorPole; + delete[] MueLorPole; + delete[] WeightEpsLorPole; + delete[] WeightMueLorPole; + delete[] EpsRelaxTime; + delete[] MueRelaxTime; + delete[] WeightEpsRelaxTime; + delete[] WeightMueRelaxTime; + + EpsPlasma=NULL; + MuePlasma=NULL; + WeightEpsPlasma=NULL; + WeightMuePlasma=NULL; + EpsLorPole=NULL; + MueLorPole=NULL; + WeightEpsLorPole=NULL; + WeightMueLorPole=NULL; + EpsRelaxTime=NULL; + MueRelaxTime=NULL; + WeightEpsRelaxTime=NULL; + WeightMueRelaxTime=NULL; +} + +void CSPropLorentzMaterial::InitValues() +{ +// DeleteValues(); + EpsPlasma=new ParameterScalar*[m_Order]; + MuePlasma=new ParameterScalar*[m_Order]; + WeightEpsPlasma=new ParameterScalar*[m_Order]; + WeightMuePlasma=new ParameterScalar*[m_Order]; + EpsLorPole=new ParameterScalar*[m_Order]; + MueLorPole=new ParameterScalar*[m_Order]; + WeightEpsLorPole=new ParameterScalar*[m_Order]; + WeightMueLorPole=new ParameterScalar*[m_Order]; + EpsRelaxTime=new ParameterScalar*[m_Order]; + MueRelaxTime=new ParameterScalar*[m_Order]; + WeightEpsRelaxTime=new ParameterScalar*[m_Order]; + WeightMueRelaxTime=new ParameterScalar*[m_Order]; + + for (int o=0;o<m_Order;++o) + { + EpsPlasma[o] = new ParameterScalar[3]; + MuePlasma[o] = new ParameterScalar[3]; + WeightEpsPlasma[o] = new ParameterScalar[3]; + WeightMuePlasma[o] = new ParameterScalar[3]; + EpsLorPole[o] = new ParameterScalar[3]; + MueLorPole[o] = new ParameterScalar[3]; + WeightEpsLorPole[o] = new ParameterScalar[3]; + WeightMueLorPole[o] = new ParameterScalar[3]; + EpsRelaxTime[o] = new ParameterScalar[3]; + MueRelaxTime[o] = new ParameterScalar[3]; + WeightEpsRelaxTime[o] = new ParameterScalar[3]; + WeightMueRelaxTime[o] = new ParameterScalar[3]; + + for (int n=0;n<3;++n) + { + EpsPlasma[o][n].SetValue(0); + EpsPlasma[o][n].SetParameterSet(clParaSet); + MuePlasma[o][n].SetValue(0); + MuePlasma[o][n].SetParameterSet(clParaSet); + WeightEpsPlasma[o][n].SetValue(1); + WeightEpsPlasma[o][n].SetParameterSet(coordParaSet); + WeightMuePlasma[o][n].SetValue(1); + WeightMuePlasma[o][n].SetParameterSet(coordParaSet); + EpsLorPole[o][n].SetValue(0); + EpsLorPole[o][n].SetParameterSet(clParaSet); + MueLorPole[o][n].SetValue(0); + MueLorPole[o][n].SetParameterSet(clParaSet); + WeightEpsLorPole[o][n].SetValue(1); + WeightEpsLorPole[o][n].SetParameterSet(coordParaSet); + WeightMueLorPole[o][n].SetValue(1); + WeightMueLorPole[o][n].SetParameterSet(coordParaSet); + EpsRelaxTime[o][n].SetValue(0); + EpsRelaxTime[o][n].SetParameterSet(clParaSet); + MueRelaxTime[o][n].SetValue(0); + MueRelaxTime[o][n].SetParameterSet(clParaSet); + WeightEpsRelaxTime[o][n].SetValue(1); + WeightEpsRelaxTime[o][n].SetParameterSet(coordParaSet); + WeightMueRelaxTime[o][n].SetValue(1); + WeightMueRelaxTime[o][n].SetParameterSet(coordParaSet); + } + } +} + + +bool CSPropLorentzMaterial::Update(std::string *ErrStr) +{ + bool bOK=true; + int EC=0; + for (int o=0;o<m_Order;++o) + { + for (int n=0;n<3;++n) + { + EC=EpsPlasma[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Lorentz Material-Property epsilon plasma frequency value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=MuePlasma[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Lorentz Material-Property mue plasma frequency value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + EC=WeightEpsPlasma[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Lorentz Material-Property epsilon plasma frequency weighting function (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=WeightMuePlasma[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Lorentz Material-Property mue plasma frequency value weighting function (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + EC=EpsLorPole[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Lorentz Material-Property epsilon lorentz pole frequency value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=MueLorPole[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Lorentz Material-Property mue lorentz pole frequency value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + EC=WeightEpsLorPole[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Lorentz Material-Property epsilon lorentz pole frequency weighting function (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=WeightMueLorPole[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Lorentz Material-Property mue lorentz pole frequency value weighting function (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + EC=EpsRelaxTime[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Lorentz Material-Property epsilon relaxation time value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=MueRelaxTime[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Lorentz Material-Property mue relaxation time value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + EC=WeightEpsRelaxTime[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Lorentz Material-Property epsilon relaxation time weighting function (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=WeightMueRelaxTime[o][n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Lorentz Material-Property mue relaxation time value weighting function (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + } + } + return bOK & CSPropDispersiveMaterial::Update(ErrStr); +} + +bool CSPropLorentzMaterial::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + if (CSPropDispersiveMaterial::Write2XML(root,parameterised,sparse) == false) return false; + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + std::string suffix; + for (int o=0;o<m_Order;++o) + { + suffix = ConvertInt(o+1); + TiXmlElement* value=prop->FirstChildElement("Property"); + if (value==NULL) + return false; + WriteVectorTerm(EpsPlasma[o],*value,"EpsilonPlasmaFrequency_"+suffix,parameterised); + WriteVectorTerm(MuePlasma[o],*value,"MuePlasmaFrequency_"+suffix,parameterised); + WriteVectorTerm(EpsLorPole[o],*value,"EpsilonLorPoleFrequency_"+suffix,parameterised); + WriteVectorTerm(MueLorPole[o],*value,"MueLorPoleFrequency_"+suffix,parameterised); + WriteVectorTerm(EpsRelaxTime[o],*value,"EpsilonRelaxTime_"+suffix,parameterised); + WriteVectorTerm(MueRelaxTime[o],*value,"MueRelaxTime_"+suffix,parameterised); + + TiXmlElement* weight=prop->FirstChildElement("Weight"); + if (weight==NULL) + return false; + WriteVectorTerm(WeightEpsPlasma[o],*weight,"EpsilonPlasmaFrequency_"+suffix,parameterised); + WriteVectorTerm(WeightMuePlasma[o],*weight,"MuePlasmaFrequency_"+suffix,parameterised); + WriteVectorTerm(WeightEpsLorPole[o],*weight,"EpsilonLorPoleFrequency_"+suffix,parameterised); + WriteVectorTerm(WeightMueLorPole[o],*weight,"MueLorPoleFrequency_"+suffix,parameterised); + WriteVectorTerm(WeightEpsRelaxTime[o],*weight,"EpsilonRelaxTime_"+suffix,parameterised); + WriteVectorTerm(WeightMueRelaxTime[o],*weight,"MueRelaxTime_"+suffix,parameterised); + } + return true; +} + +bool CSPropLorentzMaterial::ReadFromXML(TiXmlNode &root) +{ + if (CSPropDispersiveMaterial::ReadFromXML(root)==false) return false; + TiXmlElement* prop=root.ToElement(); + + if (prop==NULL) return false; + + // count m_Order + TiXmlElement* matProp=prop->FirstChildElement("Property"); + if (matProp!=NULL) + { + m_Order=1; + while (1) + { + if (matProp->Attribute("EpsilonPlasmaFrequency_"+ConvertInt(m_Order+1))) + ++m_Order; + else if (matProp->Attribute("MuePlasmaFrequency_"+ConvertInt(m_Order+1))) + ++m_Order; + else + break; + } + } + else + return false; + + InitValues(); + + if (ReadVectorTerm(EpsPlasma[0],*matProp,"EpsilonPlasmaFrequency_1",0.0)==false) + ReadVectorTerm(EpsPlasma[0],*matProp,"EpsilonPlasmaFrequency",0.0); + if (ReadVectorTerm(MuePlasma[0],*matProp,"MuePlasmaFrequency_1",0.0)==false) + ReadVectorTerm(MuePlasma[0],*matProp,"MuePlasmaFrequency",0.0); + + if (ReadVectorTerm(EpsLorPole[0],*matProp,"EpsilonLorPoleFrequency_1",0.0)==false) + ReadVectorTerm(EpsLorPole[0],*matProp,"EpsilonLorPoleFrequency",0.0); + if (ReadVectorTerm(MueLorPole[0],*matProp,"MueLorPoleFrequency_1",0.0)==false) + ReadVectorTerm(MueLorPole[0],*matProp,"MueLorPoleFrequency",0.0); + + if (ReadVectorTerm(EpsRelaxTime[0],*matProp,"EpsilonRelaxTime_1",0.0)==false) + ReadVectorTerm(EpsRelaxTime[0],*matProp,"EpsilonRelaxTime",0.0); + if (ReadVectorTerm(MueRelaxTime[0],*matProp,"MueRelaxTime_1",0.0)==false) + ReadVectorTerm(MueRelaxTime[0],*matProp,"MueRelaxTime",0.0); + + TiXmlElement* weightProp=prop->FirstChildElement("Weight"); + if (weightProp) + { + if (ReadVectorTerm(WeightEpsPlasma[0],*weightProp,"EpsilonPlasmaFrequency_1",1.0)==false) + ReadVectorTerm(WeightEpsPlasma[0],*weightProp,"EpsilonPlasmaFrequency",1.0); + if (ReadVectorTerm(WeightMuePlasma[0],*weightProp,"MuePlasmaFrequency_1",1.0)==false) + ReadVectorTerm(WeightMuePlasma[0],*weightProp,"MuePlasmaFrequency",1.0); + + if (ReadVectorTerm(WeightEpsLorPole[0],*weightProp,"EpsilonLorPoleFrequency_1",1.0)==false) + ReadVectorTerm(WeightEpsLorPole[0],*weightProp,"EpsilonLorPoleFrequency",1.0); + if (ReadVectorTerm(WeightMueLorPole[0],*weightProp,"MueLorPoleFrequency_1",1.0)==false) + ReadVectorTerm(WeightMueLorPole[0],*weightProp,"MueLorPoleFrequency",1.0); + + if (ReadVectorTerm(WeightEpsRelaxTime[0],*weightProp,"EpsilonRelaxTime_1",1.0)==false) + ReadVectorTerm(WeightEpsRelaxTime[0],*weightProp,"EpsilonRelaxTime",1.0); + if (ReadVectorTerm(WeightMueRelaxTime[0],*weightProp,"MueRelaxTime_1",1.0)==false) + ReadVectorTerm(WeightMueRelaxTime[0],*weightProp,"MueRelaxTime",1.0); + } + + for (int o=1;o<m_Order;++o) + { + ReadVectorTerm(EpsPlasma[o],*matProp,"EpsilonPlasmaFrequency_"+ConvertInt(o+1),0.0); + ReadVectorTerm(MuePlasma[o],*matProp,"MuePlasmaFrequency_"+ConvertInt(o+1),0.0); + + ReadVectorTerm(EpsLorPole[o],*matProp,"EpsilonLorPoleFrequency_"+ConvertInt(o+1),0.0); + ReadVectorTerm(MueLorPole[o],*matProp,"MueLorPoleFrequency_"+ConvertInt(o+1),0.0); + + ReadVectorTerm(EpsRelaxTime[o],*matProp,"EpsilonRelaxTime_"+ConvertInt(o+1),0.0); + ReadVectorTerm(MueRelaxTime[o],*matProp,"MueRelaxTime_"+ConvertInt(o+1),0.0); + + if (weightProp) + { + ReadVectorTerm(WeightEpsPlasma[o],*weightProp,"EpsilonPlasmaFrequency_"+ConvertInt(o+1),1.0); + ReadVectorTerm(WeightMuePlasma[o],*weightProp,"MuePlasmaFrequency_"+ConvertInt(o+1),1.0); + + ReadVectorTerm(WeightEpsLorPole[o],*weightProp,"EpsilonLorPoleFrequency_"+ConvertInt(o+1),1.0); + ReadVectorTerm(WeightMueLorPole[o],*weightProp,"MueLorPoleFrequency_"+ConvertInt(o+1),1.0); + + ReadVectorTerm(WeightEpsRelaxTime[o],*weightProp,"EpsilonRelaxTime_"+ConvertInt(o+1),1.0); + ReadVectorTerm(WeightMueRelaxTime[o],*weightProp,"MueRelaxTime_"+ConvertInt(o+1),1.0); + } + } + return true; +} + +void CSPropLorentzMaterial::ShowPropertyStatus(std::ostream& stream) +{ + CSPropDispersiveMaterial::ShowPropertyStatus(stream); + stream << " Lorentz model order:\t" << m_Order << std::endl; + for (int o=0;o<m_Order;++o) + { + stream << " Epsilon Plasma Frequency #" << o << ":\t" << GetEpsPlasmaFreq(o,0) << "," << GetEpsPlasmaFreq(o,1) << "," << GetEpsPlasmaFreq(o,2) << std::endl; + stream << " Mue Plasma Frequency #" << o << ":\t" << GetMuePlasmaFreq(o,0) << "," << GetMuePlasmaFreq(o,1) << "," << GetMuePlasmaFreq(o,2) << std::endl; + stream << " Epsilon Lorentz Pole Frequency #" << o << ":\t" << GetEpsLorPoleFreq(o,0) << "," << GetEpsLorPoleFreq(o,1) << "," << GetEpsLorPoleFreq(o,2) << std::endl; + stream << " Mue Lorentz Pole Frequency #" << o << ":\t" << GetMueLorPoleFreq(o,0) << "," << GetMueLorPoleFreq(o,1) << "," << GetMueLorPoleFreq(o,2) << std::endl; + stream << " Epsilon Relax Time #" << o << ":\t" << GetEpsRelaxTime(o,0) << "," << GetEpsRelaxTime(o,1) << "," << GetEpsRelaxTime(o,2) << std::endl; + stream << " Mue Relax Time #" << o << ":\t" << GetMueRelaxTime(o,0) << "," << GetMueRelaxTime(o,1) << "," << GetMueRelaxTime(o,2) << std::endl; + } +} diff --git a/CSXCAD/src/CSPropLorentzMaterial.h b/CSXCAD/src/CSPropLorentzMaterial.h new file mode 100644 index 0000000..e25ce5b --- /dev/null +++ b/CSXCAD/src/CSPropLorentzMaterial.h @@ -0,0 +1,167 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSProperties.h" +#include "CSPropDispersiveMaterial.h" + +//! Continuous Structure Lorentz/ Drude Dispersive Material Property +/*! + This Property can hold information about the special properties of Lorentz or Drude dispersive materials. + The Drude material model is a special case of the Lorentz material model. + \todo Add all the other parameter needed by this model + */ +class CSXCAD_EXPORT CSPropLorentzMaterial : public CSPropDispersiveMaterial +{ +public: + CSPropLorentzMaterial(ParameterSet* paraSet); + CSPropLorentzMaterial(CSProperties* prop); + CSPropLorentzMaterial(unsigned int ID, ParameterSet* paraSet); + virtual ~CSPropLorentzMaterial(); + + //! Get PropertyType as a xml element name \sa PropertyType and GetType + virtual const std::string GetTypeXMLString() const {return std::string("LorentzMaterial");} + + //! Set the epsilon plasma frequency + void SetEpsPlasmaFreq(int order, double val, int ny=0) {SetValue(val,EpsPlasma[order],ny);} + //! Set the epsilon plasma frequency + int SetEpsPlasmaFreq(int order, const std::string val, int ny=0) {return SetValue(val,EpsPlasma[order],ny);} + //! Get the epsilon plasma frequency + double GetEpsPlasmaFreq(int order, int ny=0) {return GetValue(EpsPlasma[order],ny);} + //! Get the epsilon plasma frequency as a string + const std::string GetEpsPlasmaFreqTerm(int order, int ny=0) {return GetTerm(EpsPlasma[order],ny);} + + //! Set the epsilon plasma frequency weighting + int SetEpsPlasmaFreqWeightFunction(int order, const std::string val, int ny) {return SetValue(val,WeightEpsPlasma[order],ny);} + //! Get the epsilon plasma frequency weighting string + const std::string GetEpsPlasmaFreqWeightFunction(int order, int ny) {return GetTerm(WeightEpsPlasma[order],ny);} + //! Get the epsilon plasma frequency weighting + double GetEpsPlasmaFreqWeighted(int order, int ny, const double* coords) {return GetWeight(WeightEpsPlasma[order],ny,coords)*GetEpsPlasmaFreq(order,ny);} + + //! Set the epsilon lorentz pole frequency + void SetEpsLorPoleFreq(int order, double val, int ny=0) {SetValue(val,EpsLorPole[order],ny);} + //! Set the epsilon lorentz pole frequency + int SetEpsLorPoleFreq(int order, const std::string val, int ny=0) {return SetValue(val,EpsLorPole[order],ny);} + //! Get the epsilon lorentz pole frequency + double GetEpsLorPoleFreq(int order, int ny=0) {return GetValue(EpsLorPole[order],ny);} + //! Get the epsilon lorentz pole frequency as a string + const std::string GetEpsLorPoleFreqTerm(int order, int ny=0) {return GetTerm(EpsLorPole[order],ny);} + + //! Set the epsilon lorentz pole frequency weighting + int SetEpsLorPoleFreqWeightFunction(int order, const std::string val, int ny) {return SetValue(val,WeightEpsLorPole[order],ny);} + //! Get the epsilon lorentz pole frequency weighting string + const std::string GetEpsLorPoleFreqWeightFunction(int order, int ny) {return GetTerm(WeightEpsLorPole[order],ny);} + //! Get the epsilon lorentz pole frequency weighting + double GetEpsLorPoleFreqWeighted(int order, int ny, const double* coords) {return GetWeight(WeightEpsLorPole[order],ny,coords)*GetEpsLorPoleFreq(order,ny);} + + //! Set the epsilon relaxation time + void SetEpsRelaxTime(int order, double val, int ny=0) {SetValue(val,EpsRelaxTime[order],ny);} + //! Set the epsilon relaxation time + int SetEpsRelaxTime(int order, const std::string val, int ny=0) {return SetValue(val,EpsRelaxTime[order],ny);} + //! Get the epsilon relaxation time + double GetEpsRelaxTime(int order, int ny=0) {return GetValue(EpsRelaxTime[order],ny);} + //! Get the epsilon relaxation time as a string + const std::string GetEpsRelaxTimeTerm(int order, int ny=0) {return GetTerm(EpsRelaxTime[order],ny);} + + //! Set the epsilon relaxation time weighting + int SetEpsRelaxTimeWeightFunction(int order, const std::string val, int ny) {return SetValue(val,WeightEpsRelaxTime[order],ny);} + //! Get the epsilon relaxation time weighting string + const std::string GetEpsRelaxTimeWeightFunction(int order, int ny) {return GetTerm(WeightEpsRelaxTime[order],ny);} + //! Get the epsilon relaxation time weighting + double GetEpsRelaxTimeWeighted(int order, int ny, const double* coords) {return GetWeight(WeightEpsRelaxTime[order],ny,coords)*GetEpsRelaxTime(order,ny);} + + //! Set the mue plasma frequency + void SetMuePlasmaFreq(int order, double val, int ny=0) {SetValue(val,MuePlasma[order],ny);} + //! Set the mue plasma frequency + int SetMuePlasmaFreq(int order, const std::string val, int ny=0) {return SetValue(val,MuePlasma[order],ny);} + //! Get the mue plasma frequency + double GetMuePlasmaFreq(int order, int ny=0) {return GetValue(MuePlasma[order],ny);} + //! Get the mue plasma frequency string + const std::string GetMueTermPlasmaFreq(int order, int ny=0) {return GetTerm(MuePlasma[order],ny);} + + //! Set the mue plasma frequency weighting + int SetMuePlasmaFreqWeightFunction(int order, const std::string val, int ny) {return SetValue(val,WeightMuePlasma[order],ny);} + //! Get the mue plasma frequency weighting string + const std::string GetMuePlasmaFreqWeightFunction(int order, int ny) {return GetTerm(WeightMuePlasma[order],ny);} + //! Get the mue plasma frequency weighting + double GetMuePlasmaFreqWeighted(int order, int ny, const double* coords) {return GetWeight(WeightMuePlasma[order],ny,coords)*GetMuePlasmaFreq(order,ny);} + + //! Set the mue lorentz pole frequency + void SetMueLorPoleFreq(int order, double val, int ny=0) {SetValue(val,MueLorPole[order],ny);} + //! Set the mue lorentz pole frequency + int SetMueLorPoleFreq(int order, const std::string val, int ny=0) {return SetValue(val,MueLorPole[order],ny);} + //! Get the mue lorentz pole frequency + double GetMueLorPoleFreq(int order, int ny=0) {return GetValue(MueLorPole[order],ny);} + //! Get the mue lorentz pole frequency string + const std::string GetMueTermLorPoleFreq(int order, int ny=0) {return GetTerm(MueLorPole[order],ny);} + + //! Set the mue lorentz pole frequency weighting + int SetMueLorPoleFreqWeightFunction(int order, const std::string val, int ny) {return SetValue(val,WeightMueLorPole[order],ny);} + //! Get the mue lorentz pole frequency weighting string + const std::string GetMueLorPoleFreqWeightFunction(int order, int ny) {return GetTerm(WeightMueLorPole[order],ny);} + //! Get the mue lorentz pole frequency weighting + double GetMueLorPoleFreqWeighted(int order, int ny, const double* coords) {return GetWeight(WeightMueLorPole[order],ny,coords)*GetMueLorPoleFreq(order,ny);} + + //! Set the mue relaxation time + void SetMueRelaxTime(int order, double val, int ny=0) {SetValue(val,MueRelaxTime[order],ny);} + //! Set the mue relaxation time + int SetMueRelaxTime(int order, const std::string val, int ny=0) {return SetValue(val,MueRelaxTime[order],ny);} + //! Get the mue relaxation time + double GetMueRelaxTime(int order, int ny=0) {return GetValue(MueRelaxTime[order],ny);} + //! Get the mue relaxation time string + const std::string GetMueTermRelaxTime(int order, int ny=0) {return GetTerm(MueRelaxTime[order],ny);} + + //! Set the mue relaxation time weighting + int SetMueRelaxTimeWeightFunction(int order, const std::string val, int ny) {return SetValue(val,WeightMueRelaxTime[order],ny);} + //! Get the mue relaxation time weighting string + const std::string GetMueRelaxTimeWeightFunction(int order, int ny) {return GetTerm(WeightMueRelaxTime[order],ny);} + //! Get the mue relaxation time weighting + double GetMueRelaxTimeWeighted(int order, int ny, const double* coords) {return GetWeight(WeightMueRelaxTime[order],ny,coords)*GetMueRelaxTime(order,ny);} + + virtual void Init(); + virtual bool Update(std::string *ErrStr=NULL); + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual void ShowPropertyStatus(std::ostream& stream); + +protected: + virtual void InitValues(); + virtual void DeleteValues(); + //! Epsilon and mue plasma frequncies + ParameterScalar** EpsPlasma; + ParameterScalar** MuePlasma; + //! Epsilon and mue plasma frequncies weighting functions + ParameterScalar** WeightEpsPlasma; + ParameterScalar** WeightMuePlasma; + + //! Epsilon and mue lorentz pole frequncies + ParameterScalar** EpsLorPole; + ParameterScalar** MueLorPole; + //! Epsilon and mue lorentz pole frequncies weighting functions + ParameterScalar** WeightEpsLorPole; + ParameterScalar** WeightMueLorPole; + + //! Relaxation times for epsilon and mue + ParameterScalar** EpsRelaxTime; + ParameterScalar** MueRelaxTime; + //! Relaxation times for epsilon and mue weighting functions + ParameterScalar** WeightEpsRelaxTime; + ParameterScalar** WeightMueRelaxTime; +}; diff --git a/CSXCAD/src/CSPropLumpedElement.cpp b/CSXCAD/src/CSPropLumpedElement.cpp new file mode 100644 index 0000000..f4dc602 --- /dev/null +++ b/CSXCAD/src/CSPropLumpedElement.cpp @@ -0,0 +1,128 @@ +/* +* 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 "tinyxml.h" + +#include "CSPropLumpedElement.h" + +CSPropLumpedElement::CSPropLumpedElement(ParameterSet* paraSet) : CSProperties(paraSet) {Type=LUMPED_ELEMENT;Init();} +CSPropLumpedElement::CSPropLumpedElement(CSProperties* prop) : CSProperties(prop) {Type=LUMPED_ELEMENT;Init();} +CSPropLumpedElement::CSPropLumpedElement(unsigned int ID, ParameterSet* paraSet) : CSProperties(ID,paraSet) {Type=LUMPED_ELEMENT;Init();} +CSPropLumpedElement::~CSPropLumpedElement() {} + +void CSPropLumpedElement::Init() +{ + m_ny=-1; + m_Caps=true; + m_R.SetValue(NAN); + m_C.SetValue(NAN); + m_L.SetValue(NAN); +} + +bool CSPropLumpedElement::Update(std::string *ErrStr) +{ + int EC=m_R.Evaluate(); + bool bOK=true; + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in LumpedElement-Property Resistance-Value"; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + //cout << EC << std::endl; + } + + EC=m_C.Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in LumpedElement-Property Capacitor-Value"; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + //cout << EC << std::endl; + } + + EC=m_L.Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in LumpedElement-Property Inductance-Value"; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + //cout << EC << std::endl; + } + + return bOK & CSProperties::Update(ErrStr); +} + +void CSPropLumpedElement::SetDirection(int ny) +{ + if ((ny<0) || (ny>2)) return; + m_ny = ny; +} + +bool CSPropLumpedElement::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + if (CSProperties::Write2XML(root,parameterised,sparse)==false) return false; + + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + prop->SetAttribute("Direction",m_ny); + prop->SetAttribute("Caps",(int)m_Caps); + + WriteTerm(m_R,*prop,"R",parameterised); + WriteTerm(m_C,*prop,"C",parameterised); + WriteTerm(m_L,*prop,"L",parameterised); + + return true; +} + +bool CSPropLumpedElement::ReadFromXML(TiXmlNode &root) +{ + if (CSProperties::ReadFromXML(root)==false) return false; + + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + if (prop->QueryIntAttribute("Direction",&m_ny)!=TIXML_SUCCESS) m_ny=-1; + int caps=0; + if (prop->QueryIntAttribute("Caps",&caps)!=TIXML_SUCCESS) m_Caps=true; + else + m_Caps = (bool)caps; + + if (ReadTerm(m_R,*prop,"R")==false) + m_R.SetValue(NAN); + if (ReadTerm(m_C,*prop,"C")==false) + m_C.SetValue(NAN); + if (ReadTerm(m_L,*prop,"L")==false) + m_L.SetValue(NAN); + return true; +} + +void CSPropLumpedElement::ShowPropertyStatus(std::ostream& stream) +{ + CSProperties::ShowPropertyStatus(stream); + stream << " --- Lumped Element Properties --- " << std::endl; + stream << " Direction: " << m_ny << std::endl; + stream << " Resistance: " << m_R.GetValueString() << std::endl; + stream << " Capacity: " << m_C.GetValueString() << std::endl; + stream << " Inductance: " << m_L.GetValueString() << std::endl; +} diff --git a/CSXCAD/src/CSPropLumpedElement.h b/CSXCAD/src/CSPropLumpedElement.h new file mode 100644 index 0000000..6ce61e3 --- /dev/null +++ b/CSXCAD/src/CSPropLumpedElement.h @@ -0,0 +1,71 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSProperties.h" + +//! Continuous Structure Lumped Element Property +/*! + This property represents lumped elements, e.g. smd capacitors etc. + */ +class CSXCAD_EXPORT CSPropLumpedElement : public CSProperties +{ +public: + CSPropLumpedElement(ParameterSet* paraSet); + CSPropLumpedElement(CSProperties* prop); + CSPropLumpedElement(unsigned int ID, ParameterSet* paraSet); + virtual ~CSPropLumpedElement(); + + virtual void Init(); + + void SetResistance(double val) {m_R.SetValue(val);} + int SetResistance(const std::string val) {return m_R.SetValue(val);} + double GetResistance() const {return m_R.GetValue();} + const std::string GetResistanceTerm() const {return m_R.GetString();} + + void SetCapacity(double val) {m_C.SetValue(val);} + int SetCapacity(const std::string val) {return m_C.SetValue(val);} + double GetCapacity() const {return m_C.GetValue();} + const std::string GetCapacityTerm() const {return m_C.GetString();} + + void SetInductance(double val) {m_L.SetValue(val);} + int SetInductance(const std::string val) {return m_L.SetValue(val);} + double GetInductance() const {return m_L.GetValue();} + const std::string GetInductanceTerm() const {return m_L.GetString();} + + void SetDirection(int ny); + int GetDirection() const {return m_ny;} + + void SetCaps(bool val) {m_Caps=val;} + int GetCaps() const {return m_Caps;} + + virtual void ShowPropertyStatus(std::ostream& stream); + + //! Get PropertyType as a xml element name \sa PropertyType and GetType + virtual const std::string GetTypeXMLString() const {return std::string("LumpedElement");} + +protected: + int m_ny; + bool m_Caps; + ParameterScalar m_R,m_C,m_L; + virtual bool Update(std::string *ErrStr=NULL); + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); +}; + diff --git a/CSXCAD/src/CSPropMaterial.cpp b/CSXCAD/src/CSPropMaterial.cpp new file mode 100644 index 0000000..7fd2415 --- /dev/null +++ b/CSXCAD/src/CSPropMaterial.cpp @@ -0,0 +1,304 @@ +/* +* 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 "tinyxml.h" + +#include "CSPropMaterial.h" + +CSPropMaterial::CSPropMaterial(ParameterSet* paraSet) : CSProperties(paraSet) {Type=MATERIAL;Init();} +CSPropMaterial::CSPropMaterial(CSProperties* prop) : CSProperties(prop) {Type=MATERIAL;Init();} +CSPropMaterial::CSPropMaterial(unsigned int ID, ParameterSet* paraSet) : CSProperties(ID,paraSet) {Type=MATERIAL;Init();} +CSPropMaterial::~CSPropMaterial() {} + +double CSPropMaterial::GetValue(ParameterScalar *ps, int ny) +{ + if (bIsotropy) ny=0; + if ((ny>2) || (ny<0)) return 0; + return ps[ny].GetValue(); +} + +std::string CSPropMaterial::GetTerm(ParameterScalar *ps, int ny) +{ + if (bIsotropy) ny=0; + if ((ny>2) || (ny<0)) return 0; + return ps[ny].GetString(); +} + +void CSPropMaterial::SetValue(double val, ParameterScalar *ps, int ny) +{ + if ((ny>2) || (ny<0)) return; + ps[ny].SetValue(val); +} + +int CSPropMaterial::SetValue(std::string val, ParameterScalar *ps, int ny) +{ + if ((ny>2) || (ny<0)) return 0; + return ps[ny].SetValue(val); +} + +double CSPropMaterial::GetWeight(ParameterScalar *ps, int ny, const double* coords) +{ + if (bIsotropy) ny=0; + if ((ny>2) || (ny<0)) return 0; + return GetWeight(ps[ny],coords); +} + +double CSPropMaterial::GetWeight(ParameterScalar &ps, const double* coords) +{ + double paraVal[7]; + if (coordInputType==1) + { + double rho = coords[0]; + double alpha=coords[1]; + paraVal[0] = rho*cos(alpha); + paraVal[1] = rho*sin(alpha); + paraVal[2] = coords[2]; //z + paraVal[3] = rho; + paraVal[4] = sqrt(pow(rho,2)+pow(coords[2],2)); // r + paraVal[5] = alpha; //alpha + paraVal[6] = asin(1)-atan(coords[2]/rho); //theta + } + else + { + paraVal[0] = coords[0]; //x + paraVal[1] = coords[1]; //y + paraVal[2] = coords[2]; //z + paraVal[3] = sqrt(pow(coords[0],2)+pow(coords[1],2)); //rho + paraVal[4] = sqrt(pow(coords[0],2)+pow(coords[1],2)+pow(coords[2],2)); // r + paraVal[5] = atan2(coords[1],coords[0]); //alpha + paraVal[6] = asin(1)-atan(coords[2]/paraVal[3]); //theta + } + + int EC=0; + double value = ps.GetEvaluated(paraVal,EC); + if (EC) + { + std::cerr << "CSPropMaterial::GetWeight: Error evaluating the weighting function (ID: " << this->GetID() << "): " << PSErrorCode2Msg(EC) << std::endl; + } + return value; +} + +void CSPropMaterial::Init() +{ + bIsotropy = true; + bMaterial=true; + for (int n=0;n<3;++n) + { + Epsilon[n].SetValue(1); + Epsilon[n].SetParameterSet(clParaSet); + Mue[n].SetValue(1); + Mue[n].SetParameterSet(clParaSet); + Kappa[n].SetValue(0.0); + Kappa[n].SetParameterSet(clParaSet); + Sigma[n].SetValue(0.0); + Sigma[n].SetParameterSet(clParaSet); + WeightEpsilon[n].SetValue(1); + WeightEpsilon[n].SetParameterSet(coordParaSet); + WeightMue[n].SetValue(1); + WeightMue[n].SetParameterSet(coordParaSet); + WeightKappa[n].SetValue(1.0); + WeightKappa[n].SetParameterSet(coordParaSet); + WeightSigma[n].SetValue(1.0); + WeightSigma[n].SetParameterSet(coordParaSet); + } + Density.SetValue(0); + WeightDensity.SetValue(1.0); + FillColor.a=EdgeColor.a=123; + bVisisble=true; +} + +bool CSPropMaterial::Update(std::string *ErrStr) +{ + bool bOK=true; + int EC=0; + for (int n=0;n<3;++n) + { + EC=Epsilon[n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Material-Property Epsilon-Value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=Mue[n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Material-Property Mue-Value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=Kappa[n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Material-Property Kappa-Value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=Sigma[n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Material-Property Sigma-Value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=WeightEpsilon[n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Material-Property Epsilon-Value weighting function (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=WeightMue[n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Material-Property Mue-Value weighting function (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=WeightKappa[n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Material-Property Kappa-Value weighting function (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=WeightSigma[n].Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Material-Property Sigma-Value weighting function (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + } + + EC=Density.Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Material-Property Density-Value (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + EC=WeightDensity.Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in Material-Property Density weighting function (ID: " << uiID << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + + return bOK; +} + +bool CSPropMaterial::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + if (CSProperties::Write2XML(root,parameterised,sparse) == false) return false; + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + prop->SetAttribute("Isotropy",bIsotropy); + + /*************** 3D - Properties *****************/ + TiXmlElement value("Property"); + WriteVectorTerm(Epsilon,value,"Epsilon",parameterised); + WriteVectorTerm(Mue,value,"Mue",parameterised); + WriteVectorTerm(Kappa,value,"Kappa",parameterised); + WriteVectorTerm(Sigma,value,"Sigma",parameterised); + /*************** 1D - Properties *****************/ + WriteTerm(Density,value,"Density",parameterised); + prop->InsertEndChild(value); + + /********** 3D - Properties Weight **************/ + TiXmlElement Weight("Weight"); + WriteVectorTerm(WeightEpsilon,Weight,"Epsilon",parameterised); + WriteVectorTerm(WeightMue,Weight,"Mue",parameterised); + WriteVectorTerm(WeightKappa,Weight,"Kappa",parameterised); + WriteVectorTerm(WeightSigma,Weight,"Sigma",parameterised); + /********** 1D - Properties Weight **************/ + WriteTerm(WeightDensity,Weight,"Density",parameterised); + prop->InsertEndChild(Weight); + + return true; +} + +bool CSPropMaterial::ReadFromXML(TiXmlNode &root) +{ + if (CSProperties::ReadFromXML(root)==false) return false; + TiXmlElement* prop=root.ToElement(); + + if (prop==NULL) return false; + + int attr=1; + prop->QueryIntAttribute("Isotropy",&attr); + bIsotropy = attr>0; + + /*************** 3D - Properties *****************/ + TiXmlElement* matProp=prop->FirstChildElement("Property"); + if (matProp!=NULL) + { + ReadVectorTerm(Epsilon,*matProp,"Epsilon",1.0); + ReadVectorTerm(Mue,*matProp,"Mue",1.0); + ReadVectorTerm(Kappa,*matProp,"Kappa"); + ReadVectorTerm(Sigma,*matProp,"Sigma"); + ReadTerm(Density,*matProp,"Density",0.0); + } + + /********** 3D - Properties Weight **************/ + TiXmlElement *weight = prop->FirstChildElement("Weight"); + if (weight!=NULL) + { + ReadVectorTerm(WeightEpsilon,*weight,"Epsilon",1.0); + ReadVectorTerm(WeightMue,*weight,"Mue",1.0); + ReadVectorTerm(WeightKappa,*weight,"Kappa",1.0); + ReadVectorTerm(WeightSigma,*weight,"Sigma",1.0); + ReadTerm(WeightDensity,*weight,"Density",1.0); + } + + return true; +} + +void CSPropMaterial::ShowPropertyStatus(std::ostream& stream) +{ + CSProperties::ShowPropertyStatus(stream); + stream << " --- " << GetTypeString() << " --- " << std::endl; + stream << " Isotropy\t: " << bIsotropy << std::endl; + stream << " Epsilon_R\t: " << Epsilon[0].GetValueString() << ", " << Epsilon[1].GetValueString() << ", " << Epsilon[2].GetValueString() << std::endl; + stream << " Kappa\t\t: " << Kappa[0].GetValueString() << ", " << Kappa[1].GetValueString() << ", " << Kappa[2].GetValueString() << std::endl; + stream << " Mue_R\t\t: " << Mue[0].GetValueString() << ", " << Mue[1].GetValueString() << ", " << Mue[2].GetValueString() << std::endl; + stream << " Sigma\t\t: " << Sigma[0].GetValueString() << ", " << Sigma[1].GetValueString() << ", " << Sigma[2].GetValueString() << std::endl; + stream << " Density\t: " << Density.GetValueString() << std::endl; + +} diff --git a/CSXCAD/src/CSPropMaterial.h b/CSXCAD/src/CSPropMaterial.h new file mode 100644 index 0000000..0201f3c --- /dev/null +++ b/CSXCAD/src/CSPropMaterial.h @@ -0,0 +1,111 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSProperties.h" + + +//! Continuous Structure Material Property +/*! + This Property can hold information about the properties of materials, such as epsilon, mue, kappa or sigma (aka. magnetic losses in FDTD). + The material can be location dependent and unisotropic. + */ +class CSXCAD_EXPORT CSPropMaterial : public CSProperties +{ +public: + CSPropMaterial(ParameterSet* paraSet); + CSPropMaterial(CSProperties* prop); + CSPropMaterial(unsigned int ID, ParameterSet* paraSet); + virtual ~CSPropMaterial(); + + //! Get PropertyType as a xml element name \sa PropertyType and GetType + virtual const std::string GetTypeXMLString() const {return std::string("Material");} + + void SetEpsilon(double val, int ny=0) {SetValue(val,Epsilon,ny);} + int SetEpsilon(const std::string val, int ny=0) {return SetValue(val,Epsilon,ny);} + double GetEpsilon(int ny=0) {return GetValue(Epsilon,ny);} + const std::string GetEpsilonTerm(int ny=0) {return GetTerm(Epsilon,ny);} + + int SetEpsilonWeightFunction(const std::string fct, int ny) {return SetValue(fct,WeightEpsilon,ny);} + const std::string GetEpsilonWeightFunction(int ny) {return GetTerm(WeightEpsilon,ny);} + virtual double GetEpsilonWeighted(int ny, const double* coords) {return GetWeight(WeightEpsilon,ny,coords)*GetEpsilon(ny);} + + void SetMue(double val, int ny=0) {SetValue(val,Mue,ny);} + int SetMue(const std::string val, int ny=0) {return SetValue(val,Mue,ny);} + double GetMue(int ny=0) {return GetValue(Mue,ny);} + const std::string GetMueTerm(int ny=0) {return GetTerm(Mue,ny);} + + int SetMueWeightFunction(const std::string fct, int ny) {return SetValue(fct,WeightMue,ny);} + const std::string GetMueWeightFunction(int ny) {return GetTerm(WeightMue,ny);} + virtual double GetMueWeighted(int ny, const double* coords) {return GetWeight(WeightMue,ny,coords)*GetMue(ny);} + + void SetKappa(double val, int ny=0) {SetValue(val,Kappa,ny);} + int SetKappa(const std::string val, int ny=0) {return SetValue(val,Kappa,ny);} + double GetKappa(int ny=0) {return GetValue(Kappa,ny);} + const std::string GetKappaTerm(int ny=0) {return GetTerm(Kappa,ny);} + + int SetKappaWeightFunction(const std::string fct, int ny) {return SetValue(fct,WeightKappa,ny);} + const std::string GetKappaWeightFunction(int ny) {return GetTerm(WeightKappa,ny);} + virtual double GetKappaWeighted(int ny, const double* coords) {return GetWeight(WeightKappa,ny,coords)*GetKappa(ny);} + + void SetSigma(double val, int ny=0) {SetValue(val,Sigma,ny);} + int SetSigma(const std::string val, int ny=0) {return SetValue(val,Sigma,ny);} + double GetSigma(int ny=0) {return GetValue(Sigma,ny);} + const std::string GetSigmaTerm(int ny=0) {return GetTerm(Sigma,ny);} + + int SetSigmaWeightFunction(const std::string fct, int ny) {return SetValue(fct,WeightSigma,ny);} + const std::string GetSigmaWeightFunction(int ny) {return GetTerm(WeightSigma,ny);} + virtual double GetSigmaWeighted(int ny, const double* coords) {return GetWeight(WeightSigma,ny,coords)*GetSigma(ny);} + + void SetDensity(double val) {Density.SetValue(val);} + int SetDensity(const std::string val) {return Density.SetValue(val);} + double GetDensity() {return Density.GetValue();} + const std::string GetDensityTerm() {return Density.GetString();} + + int SetDensityWeightFunction(const std::string fct) {return WeightDensity.SetValue(fct);} + const std::string GetDensityWeightFunction() {return WeightDensity.GetString();} + virtual double GetDensityWeighted(const double* coords) {return GetWeight(WeightDensity,coords)*GetDensity();} + + void SetIsotropy(bool val) {bIsotropy=val;} + bool GetIsotropy() {return bIsotropy;} + + virtual void Init(); + virtual bool Update(std::string *ErrStr=NULL); + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual void ShowPropertyStatus(std::ostream& stream); + +protected: + double GetValue(ParameterScalar *ps, int ny); + std::string GetTerm(ParameterScalar *ps, int ny); + void SetValue(double val, ParameterScalar *ps, int ny); + int SetValue(std::string val, ParameterScalar *ps, int ny); + + //electro-magnetic properties + ParameterScalar Epsilon[3],Mue[3],Kappa[3],Sigma[3]; + ParameterScalar WeightEpsilon[3],WeightMue[3],WeightKappa[3],WeightSigma[3]; + + //other physical properties + ParameterScalar Density, WeightDensity; + + double GetWeight(ParameterScalar &ps, const double* coords); + double GetWeight(ParameterScalar *ps, int ny, const double* coords); + bool bIsotropy; +}; diff --git a/CSXCAD/src/CSPropMetal.cpp b/CSXCAD/src/CSPropMetal.cpp new file mode 100644 index 0000000..8acb728 --- /dev/null +++ b/CSXCAD/src/CSPropMetal.cpp @@ -0,0 +1,39 @@ +/* +* 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 "tinyxml.h" + +#include "CSPropMetal.h" + +CSPropMetal::CSPropMetal(ParameterSet* paraSet) : CSProperties(paraSet) {Type=METAL;bMaterial=true;} +CSPropMetal::CSPropMetal(CSProperties* prop) : CSProperties(prop) {Type=METAL;bMaterial=true;} +CSPropMetal::CSPropMetal(unsigned int ID, ParameterSet* paraSet) : CSProperties(ID,paraSet) {Type=METAL;bMaterial=true;} +CSPropMetal::~CSPropMetal() {} + +bool CSPropMetal::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + if (CSProperties::Write2XML(root,parameterised,sparse) == false) return false; + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + return true; +} + +bool CSPropMetal::ReadFromXML(TiXmlNode &root) +{ + return CSProperties::ReadFromXML(root); +} diff --git a/CSXCAD/src/CSPropMetal.h b/CSXCAD/src/CSPropMetal.h new file mode 100644 index 0000000..a5b1ace --- /dev/null +++ b/CSXCAD/src/CSPropMetal.h @@ -0,0 +1,39 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSProperties.h" + +//! Continuous Structure Metal Property +/*! + This Property defines a metal property (aka. PEC). + */ +class CSXCAD_EXPORT CSPropMetal : public CSProperties +{ +public: + CSPropMetal(ParameterSet* paraSet); + CSPropMetal(CSProperties* prop); + CSPropMetal(unsigned int ID, ParameterSet* paraSet); + virtual ~CSPropMetal(); + + //! Get PropertyType as a xml element name \sa PropertyType and GetType + virtual const std::string GetTypeXMLString() const {return std::string("Metal");} + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); +}; diff --git a/CSXCAD/src/CSPropProbeBox.cpp b/CSXCAD/src/CSPropProbeBox.cpp new file mode 100644 index 0000000..b7c87da --- /dev/null +++ b/CSXCAD/src/CSPropProbeBox.cpp @@ -0,0 +1,102 @@ +/* +* 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 "tinyxml.h" + +#include "CSPropProbeBox.h" + +CSPropProbeBox::CSPropProbeBox(ParameterSet* paraSet) : CSProperties(paraSet) {Type=PROBEBOX;uiNumber=0;m_NormDir=-1;ProbeType=0;m_weight=1;bVisisble=false;startTime=0;stopTime=0;} +CSPropProbeBox::CSPropProbeBox(CSProperties* prop) : CSProperties(prop) {Type=PROBEBOX;uiNumber=0;m_NormDir=-1;ProbeType=0;m_weight=1;bVisisble=false;startTime=0;stopTime=0;} +CSPropProbeBox::CSPropProbeBox(unsigned int ID, ParameterSet* paraSet) : CSProperties(ID,paraSet) {Type=PROBEBOX;uiNumber=0;m_NormDir=-1;ProbeType=0;m_weight=1;bVisisble=false;startTime=0;stopTime=0;} +CSPropProbeBox::~CSPropProbeBox() {} + +void CSPropProbeBox::SetNumber(unsigned int val) {uiNumber=val;} +unsigned int CSPropProbeBox::GetNumber() {return uiNumber;} + +void CSPropProbeBox::AddFDSample(std::vector<double> *freqs) +{ + for (size_t n=0;n<freqs->size();++n) + AddFDSample(freqs->at(n)); +} + +void CSPropProbeBox::AddFDSample(std::string freqs) +{ + std::vector<double> v_freqs = SplitString2Double(freqs, ','); + AddFDSample(&v_freqs); +} + +bool CSPropProbeBox::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + if (CSProperties::Write2XML(root,parameterised,sparse) == false) return false; + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + prop->SetAttribute("Number",(int)uiNumber); + if ((m_NormDir>0) && (m_NormDir<3)) + prop->SetAttribute("NormDir",(int)uiNumber); + prop->SetAttribute("Type",ProbeType); + prop->SetAttribute("Weight",m_weight); + prop->SetAttribute("StartTime",startTime); + prop->SetAttribute("StopTime" ,stopTime ); + + if (m_FD_Samples.size()) + { + std::string fdSamples = CombineVector2String(m_FD_Samples,','); + + TiXmlElement FDS_Elem("FD_Samples"); + TiXmlText FDS_Text(fdSamples.c_str()); + FDS_Elem.InsertEndChild(FDS_Text); + prop->InsertEndChild(FDS_Elem); + } + + return true; +} + +bool CSPropProbeBox::ReadFromXML(TiXmlNode &root) +{ + if (CSProperties::ReadFromXML(root)==false) return false; + + TiXmlElement *prop = root.ToElement(); + if (prop==NULL) return false; + + int iHelp; + if (prop->QueryIntAttribute("Number",&iHelp)!=TIXML_SUCCESS) uiNumber=0; + else uiNumber=(unsigned int)iHelp; + + if (prop->QueryIntAttribute("NormDir",&m_NormDir)!=TIXML_SUCCESS) m_NormDir=-1; + + if (prop->QueryIntAttribute("Type",&ProbeType)!=TIXML_SUCCESS) ProbeType=0; + + if (prop->QueryDoubleAttribute("Weight",&m_weight)!=TIXML_SUCCESS) m_weight=1; + + if (prop->QueryDoubleAttribute("StartTime",&startTime)!=TIXML_SUCCESS) startTime=0; + if (prop->QueryDoubleAttribute("StopTime" ,&stopTime )!=TIXML_SUCCESS) stopTime =0; + + TiXmlElement* FDSamples = prop->FirstChildElement("FD_Samples"); + if (FDSamples!=NULL) + { + TiXmlNode* node = FDSamples->FirstChild(); + if (node) + { + TiXmlText* text = node->ToText(); + if (text) + this->AddFDSample(text->Value()); + } + } + + return true; +} diff --git a/CSXCAD/src/CSPropProbeBox.h b/CSXCAD/src/CSPropProbeBox.h new file mode 100644 index 0000000..a8997d7 --- /dev/null +++ b/CSXCAD/src/CSPropProbeBox.h @@ -0,0 +1,86 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSProperties.h" + + +//! Continuous Structure Probe Property for calculating integral properties +/*! + CSProbProbeBox is a class for calculating integral properties such as (static) charges, voltages or currents. +*/ +class CSXCAD_EXPORT CSPropProbeBox : public CSProperties +{ +public: + CSPropProbeBox(ParameterSet* paraSet); + CSPropProbeBox(CSProperties* prop); + CSPropProbeBox(unsigned int ID, ParameterSet* paraSet); + virtual ~CSPropProbeBox(); + + //! Get PropertyType as a xml element name \sa PropertyType and GetType + virtual const std::string GetTypeXMLString() const {return std::string("ProbeBox");} + + //! Define a number for this probe property \sa GetNumber + void SetNumber(unsigned int val); + //! Get the number designated to this probe property \sa SetNumber + unsigned int GetNumber(); + + //! Get the normal direction of this probe box (required by some types of probes) + int GetNormalDir() const {return m_NormDir;} + //! Set the normal direction of this probe box (required by some types of probes) + void SetNormalDir(unsigned int ndir) {m_NormDir=ndir;} + + //! Define/Set the probe weighting \sa GetWeighting + void SetWeighting(double weight) {m_weight=weight;} + //! Get the probe weighting \sa GetWeighting + double GetWeighting() {return m_weight;} + + //! Define the probe type (e.g. type=0 for a charge integration, can/must be defined by the user interface) \sa GetProbeType + void SetProbeType(int type) {ProbeType=type;} + //! Get the probe type \sa SetProbeType + int GetProbeType() {return ProbeType;} + + //! Set the probe start time + void SetStartTime(float value) {startTime=value;} + //! Get the probe start time + double GetStartTime() {return startTime;} + + //! Set the probe stop time + void SetStopTime(float value) {stopTime=value;} + //! Get the probe stop time + double GetStopTime() {return stopTime;} + + size_t CountFDSamples() {return m_FD_Samples.size();} + std::vector<double> *GetFDSamples() {return &m_FD_Samples;} + void ClearFDSamples() {m_FD_Samples.clear();} + void AddFDSample(double freq) {m_FD_Samples.push_back(freq);} + void AddFDSample(std::vector<double> *freqs); + void AddFDSample(std::string freqs); + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); + +protected: + unsigned int uiNumber; + int m_NormDir; + double m_weight; + int ProbeType; + std::vector<double> m_FD_Samples; + double startTime, stopTime; +}; + diff --git a/CSXCAD/src/CSPropResBox.cpp b/CSXCAD/src/CSPropResBox.cpp new file mode 100644 index 0000000..201aec8 --- /dev/null +++ b/CSXCAD/src/CSPropResBox.cpp @@ -0,0 +1,53 @@ +/* +* 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 "tinyxml.h" + +#include "CSPropResBox.h" + +CSPropResBox::CSPropResBox(ParameterSet* paraSet) : CSProperties(paraSet) {Type=RESBOX;uiFactor=1;bVisisble=false;} +CSPropResBox::CSPropResBox(CSProperties* prop) : CSProperties(prop) {Type=RESBOX;uiFactor=1;bVisisble=false;} +CSPropResBox::CSPropResBox(unsigned int ID, ParameterSet* paraSet) : CSProperties(ID,paraSet) {Type=RESBOX;uiFactor=1;bVisisble=false;} +CSPropResBox::~CSPropResBox() {}; + +void CSPropResBox::SetResFactor(unsigned int val) {uiFactor=val;} +unsigned int CSPropResBox::GetResFactor() {return uiFactor;} + +bool CSPropResBox::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + if (CSProperties::Write2XML(root,parameterised,sparse) == false) return false; + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + prop->SetAttribute("Factor",(int)uiFactor); + + return true; +} + +bool CSPropResBox::ReadFromXML(TiXmlNode &root) +{ + if (CSProperties::ReadFromXML(root)==false) return false; + + TiXmlElement *prop = root.ToElement(); + if (prop==NULL) return false; + + int iHelp; + if (prop->QueryIntAttribute("Factor",&iHelp)!=TIXML_SUCCESS) uiFactor=1; + else uiFactor=(unsigned int)iHelp; + + return true; +} diff --git a/CSXCAD/src/CSPropResBox.h b/CSXCAD/src/CSPropResBox.h new file mode 100644 index 0000000..e98d8ef --- /dev/null +++ b/CSXCAD/src/CSPropResBox.h @@ -0,0 +1,45 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSProperties.h" + +//! Continuous Structure Resolution Property +/*! + This Property defines a refined mesh area. + */ +class CSXCAD_EXPORT CSPropResBox : public CSProperties +{ +public: + CSPropResBox(ParameterSet* paraSet); + CSPropResBox(CSProperties* prop); + CSPropResBox(unsigned int ID, ParameterSet* paraSet); + virtual ~CSPropResBox(); + + //! Get PropertyType as a xml element name \sa PropertyType and GetType + virtual const std::string GetTypeXMLString() const {return std::string("ResBox");} + + void SetResFactor(unsigned int val); + unsigned int GetResFactor(); + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); + +protected: + unsigned int uiFactor; +}; diff --git a/CSXCAD/src/CSPropUnknown.cpp b/CSXCAD/src/CSPropUnknown.cpp new file mode 100644 index 0000000..e5e4cfc --- /dev/null +++ b/CSXCAD/src/CSPropUnknown.cpp @@ -0,0 +1,52 @@ +/* +* 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 "tinyxml.h" + +#include "CSPropUnknown.h" + +CSPropUnknown::CSPropUnknown(ParameterSet* paraSet) : CSProperties(paraSet) {Type=UNKNOWN;bVisisble=false;} +CSPropUnknown::CSPropUnknown(unsigned int ID, ParameterSet* paraSet) : CSProperties(ID,paraSet) {Type=UNKNOWN;bVisisble=false;} +CSPropUnknown::CSPropUnknown(CSProperties* prop) : CSProperties(prop) {Type=UNKNOWN;bVisisble=false;} +CSPropUnknown::~CSPropUnknown() {} + +void CSPropUnknown::SetProperty(const std::string val) {sUnknownProperty=std::string(val);} +const std::string CSPropUnknown::GetProperty() {return sUnknownProperty;} + + +bool CSPropUnknown::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + if (CSProperties::Write2XML(root,parameterised,sparse) == false) return false; + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + prop->SetAttribute("Property",sUnknownProperty.c_str()); + + return true; +} + +bool CSPropUnknown::ReadFromXML(TiXmlNode &root) +{ + if (CSProperties::ReadFromXML(root)==false) return false; + TiXmlElement* prob=root.ToElement(); + + const char* chProp=prob->Attribute("Property"); + if (chProp==NULL) + sUnknownProperty=std::string("unknown"); + else sUnknownProperty=std::string(chProp); + return true; +} diff --git a/CSXCAD/src/CSPropUnknown.h b/CSXCAD/src/CSPropUnknown.h new file mode 100644 index 0000000..2bc6d08 --- /dev/null +++ b/CSXCAD/src/CSPropUnknown.h @@ -0,0 +1,45 @@ +/* +* 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/>. +*/ + +#pragma once + +#include "CSProperties.h" + +//! Continuous Structure Unknown Property +/*! + This is a property that is getting designated for new properties which are unknown so far (e.g. written by a newer version of CSXCAD) +*/ +class CSXCAD_EXPORT CSPropUnknown : public CSProperties +{ +public: + CSPropUnknown(ParameterSet* paraSet); + CSPropUnknown(unsigned int ID, ParameterSet* paraSet); + CSPropUnknown(CSProperties* prop); + virtual ~CSPropUnknown(); + + //! Get PropertyType as a xml element name \sa PropertyType and GetType + virtual const std::string GetTypeXMLString() const {return std::string("Unknown");} + + void SetProperty(const std::string val); + const std::string GetProperty(); + + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + virtual bool ReadFromXML(TiXmlNode &root); + +protected: + std::string sUnknownProperty; +}; diff --git a/CSXCAD/src/CSProperties.cpp b/CSXCAD/src/CSProperties.cpp new file mode 100644 index 0000000..605b0be --- /dev/null +++ b/CSXCAD/src/CSProperties.cpp @@ -0,0 +1,399 @@ +/* +* 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 <http://www.gnu.org/licenses/>. +*/ + +#include "CSProperties.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 "CSPrimitives.h" +#include <iostream> +#include <sstream> +#include "tinyxml.h" + +/*********************CSProperties********************************************************************/ +CSProperties::CSProperties(CSProperties* prop) +{ + uiID=prop->uiID; + bMaterial=prop->bMaterial; + coordInputType=prop->coordInputType; + clParaSet=prop->clParaSet; + FillColor=prop->FillColor; + EdgeColor=prop->EdgeColor; + bVisisble=prop->bVisisble; + sName=std::string(prop->sName); + for (size_t i=0;i<prop->vPrimitives.size();++i) + { + vPrimitives.push_back(prop->vPrimitives.at(i)); + } + InitCoordParameter(); +} + +CSProperties::CSProperties(ParameterSet* paraSet) +{ + uiID=0; + bMaterial=false; + coordInputType=CARTESIAN; + clParaSet=paraSet; + FillColor.R=(rand()%256); + FillColor.G=(rand()%256); + FillColor.B=(rand()%256); + EdgeColor.R=FillColor.R; + EdgeColor.G=FillColor.G; + EdgeColor.B=FillColor.B; + FillColor.a=EdgeColor.a=255; + bVisisble=true; + Type=ANY; + InitCoordParameter(); +} + +CSProperties::CSProperties(unsigned int ID, ParameterSet* paraSet) +{ + uiID=ID; + bMaterial=false; + coordInputType=CARTESIAN; + clParaSet=paraSet; + FillColor.R=(rand()%256); + FillColor.G=(rand()%256); + FillColor.B=(rand()%256); + EdgeColor.R=FillColor.R; + EdgeColor.G=FillColor.G; + EdgeColor.B=FillColor.B; + FillColor.a=EdgeColor.a=255; + bVisisble=true; + Type=ANY; + InitCoordParameter(); +} + + +CSProperties::~CSProperties() +{ + while (vPrimitives.size()>0) + DeletePrimitive(vPrimitives.back()); + delete coordParaSet; + coordParaSet=NULL; +} + +void CSProperties::SetCoordInputType(CoordinateSystem type, bool CopyToPrimitives) +{ + coordInputType = type; + if (CopyToPrimitives==false) + return; + for (size_t i=0;i<vPrimitives.size();++i) + vPrimitives.at(i)->SetCoordInputType(type); +} + +void CSProperties::InitCoordParameter() +{ + coordParaSet = new ParameterSet(); + + coordPara[0]=new Parameter("x",0); + coordPara[1]=new Parameter("y",0); + coordPara[2]=new Parameter("z",0); + coordPara[3]=new Parameter("rho",0); + coordPara[4]=new Parameter("r",0); + coordPara[5]=new Parameter("a",0); + coordPara[6]=new Parameter("t",0); + + for (int i=0;i<7;++i) + coordParaSet->LinkParameter(coordPara[i]); //the Paraset will take care of deletion... +} + +int CSProperties::GetType() {return Type;} + +unsigned int CSProperties::GetID() {return uiID;} +void CSProperties::SetID(unsigned int ID) {uiID=ID;} + +unsigned int CSProperties::GetUniqueID() {return UniqueID;} +void CSProperties::SetUniqueID(unsigned int uID) {UniqueID=uID;} + +void CSProperties::SetName(const std::string name) {sName=std::string(name);} +const std::string CSProperties::GetName() {return sName;} + +bool CSProperties::ExistAttribute(std::string name) +{ + for (size_t n=0;n<m_Attribute_Name.size();++n) + { + if (m_Attribute_Name.at(n) == name) + return true; + } + return false; +} + +std::string CSProperties::GetAttributeValue(std::string name) +{ + for (size_t n=0;n<m_Attribute_Name.size();++n) + { + if (m_Attribute_Name.at(n) == name) + return m_Attribute_Value.at(n); + } + return std::string(); +} + +void CSProperties::AddAttribute(std::string name, std::string value) +{ + if (name.empty()) return; + m_Attribute_Name.push_back(name); + m_Attribute_Value.push_back(value); +} + +size_t CSProperties::GetQtyPrimitives() {return vPrimitives.size();} +CSPrimitives* CSProperties::GetPrimitive(size_t index) {if (index<vPrimitives.size()) return vPrimitives.at(index); else return NULL;} +void CSProperties::SetFillColor(RGBa color) {FillColor.R=color.R;FillColor.G=color.G;FillColor.B=color.B;FillColor.a=color.a;} +RGBa CSProperties::GetFillColor() {return FillColor;} + +RGBa CSProperties::GetEdgeColor() {return EdgeColor;} +void CSProperties::SetEdgeColor(RGBa color) {EdgeColor.R=color.R;EdgeColor.G=color.G;EdgeColor.B=color.B;EdgeColor.a=color.a;} + +bool CSProperties::GetVisibility() {return bVisisble;} +void CSProperties::SetVisibility(bool val) {bVisisble=val;} + +CSPropUnknown* CSProperties::ToUnknown() { return dynamic_cast<CSPropUnknown*>(this); } +CSPropMaterial* CSProperties::ToMaterial() { return dynamic_cast<CSPropMaterial*>(this); } +CSPropLorentzMaterial* CSProperties::ToLorentzMaterial() { return dynamic_cast<CSPropLorentzMaterial*>(this); } +CSPropDebyeMaterial* CSProperties::ToDebyeMaterial() { return dynamic_cast<CSPropDebyeMaterial*>(this); } +CSPropDiscMaterial* CSProperties::ToDiscMaterial() { return dynamic_cast<CSPropDiscMaterial*>(this); } +CSPropMetal* CSProperties::ToMetal() { return dynamic_cast<CSPropMetal*>(this); } +CSPropConductingSheet* CSProperties::ToConductingSheet() { return dynamic_cast<CSPropConductingSheet*>(this); } +CSPropExcitation* CSProperties::ToExcitation() { return dynamic_cast<CSPropExcitation*>(this); } +CSPropProbeBox* CSProperties::ToProbeBox() { return dynamic_cast<CSPropProbeBox*>(this); } +CSPropResBox* CSProperties::ToResBox() { return dynamic_cast<CSPropResBox*>(this); } +CSPropDumpBox* CSProperties::ToDumpBox() { return dynamic_cast<CSPropDumpBox*>(this); } + +bool CSProperties::Update(std::string */*ErrStr*/) {return true;} + +bool CSProperties::Write2XML(TiXmlNode& root, bool parameterised, bool sparse) +{ + TiXmlElement* prop=root.ToElement(); + if (prop==NULL) return false; + + prop->SetAttribute("ID",uiID); + prop->SetAttribute("Name",sName.c_str()); + + if (!sparse) + { + TiXmlElement FC("FillColor"); + FC.SetAttribute("R",FillColor.R); + FC.SetAttribute("G",FillColor.G); + FC.SetAttribute("B",FillColor.B); + FC.SetAttribute("a",FillColor.a); + prop->InsertEndChild(FC); + TiXmlElement EC("EdgeColor"); + EC.SetAttribute("R",EdgeColor.R); + EC.SetAttribute("G",EdgeColor.G); + EC.SetAttribute("B",EdgeColor.B); + EC.SetAttribute("a",EdgeColor.a); + prop->InsertEndChild(EC); + } + + if (m_Attribute_Name.size()) + { + TiXmlElement Attributes("Attributes"); + for (size_t n=0;n<m_Attribute_Name.size();++n) + { + Attributes.SetAttribute(m_Attribute_Name.at(n).c_str(),m_Attribute_Value.at(n).c_str()); + } + prop->InsertEndChild(Attributes); + } + + TiXmlElement Primitives("Primitives"); + for (size_t i=0;i<vPrimitives.size();++i) + { + TiXmlElement PrimElem(vPrimitives.at(i)->GetTypeName().c_str()); + vPrimitives.at(i)->Write2XML(PrimElem,parameterised); + Primitives.InsertEndChild(PrimElem); + } + prop->InsertEndChild(Primitives); + + return true; +} + +void CSProperties::AddPrimitive(CSPrimitives *prim) +{ + if (HasPrimitive(prim)==true) + { + std::cerr << __func__ << ": Error, primitive is already owned by this property!" << std::endl; + return; + } + vPrimitives.push_back(prim); + prim->SetProperty(this); +} + +bool CSProperties::HasPrimitive(CSPrimitives *prim) +{ + if (prim==NULL) + return false; + for (size_t i=0; i<vPrimitives.size();++i) + if (vPrimitives.at(i)==prim) + return true; + return false; +} + +void CSProperties::RemovePrimitive(CSPrimitives *prim) +{ + for (size_t i=0; i<vPrimitives.size();++i) + { + if (vPrimitives.at(i)==prim) + { + std::vector<CSPrimitives*>::iterator iter=vPrimitives.begin()+i; + vPrimitives.erase(iter); + prim->SetProperty(NULL); + return; + } + } +} + +void CSProperties::DeletePrimitive(CSPrimitives *prim) +{ + if (!HasPrimitive(prim)) + { + std::cerr << __func__ << ": Error, primitive not found, can't delete it! Skipping." << std::endl; + return; + } + RemovePrimitive(prim); + delete prim; +} + +CSPrimitives* CSProperties::TakePrimitive(size_t index) +{ + if (index>=vPrimitives.size()) return NULL; + CSPrimitives* prim=vPrimitives.at(index); + std::vector<CSPrimitives*>::iterator iter=vPrimitives.begin()+index; + vPrimitives.erase(iter); + return prim; +} + +CSPrimitives* CSProperties::CheckCoordInPrimitive(const double *coord, int &priority, bool markFoundAsUsed, double tol) +{ + priority=0; + CSPrimitives* found_CSPrim = NULL; + bool found=false; + for (size_t i=0; i<vPrimitives.size();++i) + { + if (vPrimitives.at(i)->IsInside(coord,tol)==true) + { + if (found==false) + { + priority=vPrimitives.at(i)->GetPriority()-1; + found_CSPrim = vPrimitives.at(i); + } + found=true; + if (vPrimitives.at(i)->GetPriority()>priority) + { + priority=vPrimitives.at(i)->GetPriority(); + found_CSPrim = vPrimitives.at(i); + } + } + } + if ((markFoundAsUsed) && (found_CSPrim)) + found_CSPrim->SetPrimitiveUsed(true); + return found_CSPrim; +} + +void CSProperties::WarnUnusedPrimitves(std::ostream& stream) +{ + if (vPrimitives.size()==0) + { + stream << "Warning: No primitives found in property: " << GetName() << "!" << std::endl; + return; + } + for (size_t i=0; i<vPrimitives.size();++i) + { + if (vPrimitives.at(i)->GetPrimitiveUsed()==false) + { + stream << "Warning: Unused primitive (type: " << vPrimitives.at(i)->GetTypeName() << ") detected in property: " << GetName() << "!" << std::endl; + } + } +} + +void CSProperties::ShowPropertyStatus(std::ostream& stream) +{ + stream << " Property #" << GetID() << " Type: \"" << GetTypeString() << "\" Name: \"" << GetName() << "\"" << std::endl; + stream << " Primitive Count \t: " << vPrimitives.size() << std::endl; + stream << " Coordinate System \t: " << coordInputType << std::endl; + + stream << " -- Primitives: --" << std::endl; + for (size_t i=0; i<vPrimitives.size();++i) + { + vPrimitives.at(i)->ShowPrimitiveStatus(stream); + if (i<vPrimitives.size()-1) + stream << " ---- " << std::endl; + } +} + +bool CSProperties::ReadFromXML(TiXmlNode &root) +{ + TiXmlElement* prop = root.ToElement(); + if (prop==NULL) return false; + + int help; + if (prop->QueryIntAttribute("ID",&help)==TIXML_SUCCESS) + uiID=help; + + const char* cHelp=prop->Attribute("Name"); + if (cHelp!=NULL) sName=std::string(cHelp); + else sName.clear(); + + TiXmlElement* FC = root.FirstChildElement("FillColor"); + if (FC!=NULL) + { + if (FC->QueryIntAttribute("R",&help)==TIXML_SUCCESS) + FillColor.R=(unsigned char) help; + if (FC->QueryIntAttribute("G",&help)==TIXML_SUCCESS) + FillColor.G=(unsigned char) help; + if (FC->QueryIntAttribute("B",&help)==TIXML_SUCCESS) + FillColor.B=(unsigned char) help; + if (FC->QueryIntAttribute("a",&help)==TIXML_SUCCESS) + FillColor.a=(unsigned char) help; + } + + TiXmlElement* EC = root.FirstChildElement("EdgeColor"); + if (EC!=NULL) + { + if (EC->QueryIntAttribute("R",&help)==TIXML_SUCCESS) + EdgeColor.R=(unsigned char) help; + if (EC->QueryIntAttribute("G",&help)==TIXML_SUCCESS) + EdgeColor.G=(unsigned char) help; + if (EC->QueryIntAttribute("B",&help)==TIXML_SUCCESS) + EdgeColor.B=(unsigned char) help; + if (EC->QueryIntAttribute("a",&help)==TIXML_SUCCESS) + EdgeColor.a=(unsigned char) help; + } + + TiXmlElement* att_root = root.FirstChildElement("Attributes"); + if (att_root) + { + TiXmlAttribute* att = att_root->FirstAttribute(); + while (att) + { + AddAttribute(att->Name(),att->Value()); + att = att->Next(); + } + } + + return true; +} diff --git a/CSXCAD/src/CSProperties.h b/CSXCAD/src/CSProperties.h new file mode 100644 index 0000000..d8757ee --- /dev/null +++ b/CSXCAD/src/CSProperties.h @@ -0,0 +1,222 @@ +/* +* 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 <http://www.gnu.org/licenses/>. +*/ + +#pragma once +/* + * Author: Thorsten Liebig + * Date: 03-12-2008 + * Lib: CSXCAD + * Version: 0.1a + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string> +#include <vector> +#include "ParameterObjects.h" +#include "CSTransform.h" +#include "CSXCAD_Global.h" +#include "CSUseful.h" + +#include <stdio.h> +#include <stdlib.h> +#include <iostream> +#include <fstream> +#include <sstream> + +class CSPrimitives; + +class CSPropUnknown; +class CSPropMaterial; + class CSPropDispersiveMaterial; + class CSPropLorentzMaterial; + class CSPropDebyeMaterial; + class CSPropDiscMaterial; +class CSPropLumpedElement; +class CSPropMetal; + class CSPropConductingSheet; +class CSPropExcitation; +class CSPropProbeBox; + class CSPropDumpBox; +class CSPropResBox; + +class TiXmlNode; + +typedef struct +{ + unsigned char R,G,B,a; +} RGBa; + +//! Continuous Structure (CS)Properties (layer) +/*! + CSProperties is a class that contains geometrical primitive structures as boxes, spheres, cylinders etc. (CSPrimitives) + All values in this class can contain parameters and mathematical equations. + This absract base-class contains basic property methodes, e.g. set/get primitives, mesh-relations, color-information etc. +*/ +class CSXCAD_EXPORT CSProperties +{ +public: + virtual ~CSProperties(); + //! Copy constructor + CSProperties(CSProperties* prop); + //! Enumeration of all possible sub-types of this base-class + enum PropertyType + { + ANY = 0xfff, UNKNOWN = 0x001, MATERIAL = 0x002, METAL = 0x004, EXCITATION = 0x008, PROBEBOX = 0x010, RESBOX = 0x020, DUMPBOX = 0x040, /* unused = 0x080, */ + DISPERSIVEMATERIAL = 0x100, LORENTZMATERIAL = 0x200, DEBYEMATERIAL = 0x400, + DISCRETE_MATERIAL = 0x1000, LUMPED_ELEMENT = 0x2000, CONDUCTINGSHEET = 0x4000 + }; + + //! Get PropertyType \sa PropertyType + int GetType(); + //! Get PropertyType as a xml element name \sa PropertyType and GetType + virtual const std::string GetTypeXMLString() const {return std::string("Any");} + + //! Get Property Type as a string. (default is the xml element name) + virtual const std::string GetTypeString() const {return GetTypeXMLString();} + + //! Check if Property is a physical material. Current PropertyType: MATERIAL & METAL + bool GetMaterial() {return bMaterial;} + //!Get ID of this property. Used for primitive-->property mapping. \sa SetID + unsigned int GetID(); + //!Set ID to this property. USE ONLY WHEN YOU KNOW WHAT YOU ARE DOING!!!! \sa GetID + void SetID(unsigned int ID); + + //!Get unique ID of this property. Used internally. \sa SetUniqueID + unsigned int GetUniqueID(); + //!Set unique ID of this property. Used internally. USE ONLY WHEN YOU KNOW WHAT YOU ARE DOING!!!! \sa GetUniqueID + void SetUniqueID(unsigned int uID); + + //! Set Name for this Property. \sa GetName + void SetName(const std::string name); + //! Get Name for this Property. \sa SetName + const std::string GetName(); + + //! Check if given attribute exists + bool ExistAttribute(std::string name); + //! Get the value of a given attribute + std::string GetAttributeValue(std::string name); + //! Add a new attribute + void AddAttribute(std::string name, std::string value); + + //! Add a primitive to this Propertie. Takes ownership of this primitive! \sa CSPrimitives, RemovePrimitive, TakePrimitive + void AddPrimitive(CSPrimitives *prim); + //! Check if primitive is owned by this Propertie. \sa CSPrimitives, AddPrimitive, RemovePrimitive, TakePrimitive + bool HasPrimitive(CSPrimitives *prim); + //! Removes a primitive of this Property. Caller must take ownership! \sa CSPrimitives, AddPrimitive, TakePrimitive + void RemovePrimitive(CSPrimitives *prim); + //! Removes and deletes a primitive of this Property. \sa CSPrimitives, RemovePrimitive, AddPrimitive, TakePrimitive + void DeletePrimitive(CSPrimitives *prim); + //! Take a primitive of this Propertie at index. Releases ownership of this primitive to caller! \sa CSPrimitives, RemovePrimitive, AddPrimitive \return NULL if not found! + CSPrimitives* TakePrimitive(size_t index); + + //! Check whether the given coord is inside of a primitive assigned to this property and return the found primitive and \a priority. + CSPrimitives* CheckCoordInPrimitive(const double *coord, int &priority, bool markFoundAsUsed=false, double tol=0); + + //! Get the quentity of primitives assigned to this property! \return Number of primitives in this property + size_t GetQtyPrimitives(); + + //! Get the Primitive at certain index position. \sa GetQtyPrimitives + CSPrimitives* GetPrimitive(size_t index); + + //! Get all Primitives \sa GetPrimitive + std::vector<CSPrimitives*> GetAllPrimitives() {return vPrimitives;} + + //! Set a fill-color for this property. \sa GetFillColor + void SetFillColor(RGBa color); + //! Get a fill-color for this property. \sa SetFillColor \return RGBa color object. + RGBa GetFillColor(); + + //! Set a edge-color for this property. \sa SetEdgeColor + void SetEdgeColor(RGBa color); + //! Get a fill-color for this property. \sa GetEdgeColor \return RGBa color object. + RGBa GetEdgeColor(); + + //! Get visibility for this property. \sa SetVisibility + bool GetVisibility(); + //! Set visibility for this property. \sa GetVisibility + void SetVisibility(bool val); + + //! Convert to Unknown Property, returns NULL if type is different! \return Returns a CSPropUnknown* or NULL if type is different! + CSPropUnknown* ToUnknown(); + //! Convert to Material Property, returns NULL if type is different! \return Returns a CSPropMaterial* or NULL if type is different! + CSPropMaterial* ToMaterial(); + //! Convert to Lorentzs-Material Property, returns NULL if type is different! \return Returns a CSPropLorentzMaterial* or NULL if type is different! + CSPropLorentzMaterial* ToLorentzMaterial(); + //! Convert to Debye-Material Property, returns NULL if type is different! \return Returns a CSPropDebyeMaterial* or NULL if type is different! + CSPropDebyeMaterial* ToDebyeMaterial(); + //! Convert to Discrete-Material Property, returns NULL if type is different! \return Returns a CSPropDiscMaterial* or NULL if type is different! + CSPropDiscMaterial* ToDiscMaterial(); + //! Convert to Metal Property, returns NULL if type is different! \return Returns a CSPropMetal* or NULL if type is different! + CSPropMetal* ToMetal(); + //! Convert to Conducting Sheet Property, returns NULL if type is different! \return Returns a CSPropConductingSheet* or NULL if type is different! + CSPropConductingSheet* ToConductingSheet(); + //! Convert to Excitation Property, returns NULL if type is different! \return Returns a CSPropExcitation* or NULL if type is different! + CSPropExcitation* ToExcitation(); + //! Convert to ProbeBox Property, returns NULL if type is different! \return Returns a CSPropProbeBox* or NULL if type is different! + CSPropProbeBox* ToProbeBox(); + //! Convert to ResBox Property, returns NULL if type is different! \return Returns a CSPropResBox* or NULL if type is different! + CSPropResBox* ToResBox(); + //! Convert to DumpBox Property, returns NULL if type is different! \return Returns a CSPropDumpBox* or NULL if type is different! + CSPropDumpBox* ToDumpBox(); + + //! Update all parameters. Nothing to do in this base class. \param ErrStr Methode writes error messages to this string! \return Update success + virtual bool Update(std::string *ErrStr=NULL); + + //! Write this property to a xml-node. \param parameterised Use false if parameters should be written as values. Parameters are lost! + virtual bool Write2XML(TiXmlNode& root, bool parameterised=true, bool sparse=false); + //! Read property from xml-node. \return Successful read-operation. + virtual bool ReadFromXML(TiXmlNode &root); + + //! Define the input type for the weighting coordinate system 0=cartesian, 1=cylindrical, 2=spherical + void SetCoordInputType(CoordinateSystem type, bool CopyToPrimitives=true); + //! Get the input type for the weighting coordinate system 0=cartesian, 1=cylindrical, 2=spherical + int GetCoordInputType() const {return coordInputType;} + + //! Check and warn for unused primitives + void WarnUnusedPrimitves(std::ostream& stream); + + //! Show status of this property, incl. all primitives + virtual void ShowPropertyStatus(std::ostream& stream); + +protected: + CSProperties(ParameterSet* paraSet); + CSProperties(unsigned int ID, ParameterSet* paraSet); + ParameterSet* clParaSet; + ParameterSet* coordParaSet; + //! x,y,z,rho,r,a,t one for all coord-systems (rho distance to z-axis (cylinder-coords), r for distance to origin) + void InitCoordParameter(); + Parameter* coordPara[7]; + CoordinateSystem coordInputType; + PropertyType Type; + bool bMaterial; + unsigned int uiID; + unsigned int UniqueID; + std::string sName; + std::string sType; + RGBa FillColor; + RGBa EdgeColor; + + bool bVisisble; + + std::vector<CSPrimitives*> vPrimitives; + + //! List of additional attribute names + std::vector<std::string> m_Attribute_Name; + //! List of additional attribute values + std::vector<std::string> m_Attribute_Value; +}; diff --git a/CSXCAD/src/CSRectGrid.cpp b/CSXCAD/src/CSRectGrid.cpp new file mode 100644 index 0000000..50f2947 --- /dev/null +++ b/CSXCAD/src/CSRectGrid.cpp @@ -0,0 +1,340 @@ +/* +* 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 <http://www.gnu.org/licenses/>. +*/ + +#include "CSRectGrid.h" +#include "CSUseful.h" +#include "tinyxml.h" +#include "CSFunctionParser.h" +#include <stdio.h> +#include <stdlib.h> +#include <iostream> + +CSRectGrid::CSRectGrid(void) +{ + dDeltaUnit=1; + m_meshType = CARTESIAN; +} + +CSRectGrid::~CSRectGrid(void) +{ +} + +CSRectGrid* CSRectGrid::Clone(CSRectGrid* original) +{ + CSRectGrid* clone = new CSRectGrid(); + clone->dDeltaUnit = original->dDeltaUnit; + for (int i=0;i<3;++i) + clone->Lines[i] = original->Lines[i]; + for (int i=0;i<6;++i) + clone->SimBox[i] = original->SimBox[i]; + return clone; +} + +void CSRectGrid::AddDiscLine(int direct, double val) +{ + if ((direct>=0)&&(direct<3)) Lines[direct].push_back(val); +} + +void CSRectGrid::AddDiscLines(int direct, int numLines, double* vals) +{ + for (int n=0;n<numLines;++n) + { + AddDiscLine(direct,vals[n]); + } +} + +std::string CSRectGrid::AddDiscLines(int direct, int numLines, double* vals, std::string DistFunction) +{ + if ((direct<0)||(direct>=3)) return std::string("Unknown grid direction!"); + if (DistFunction.empty()==false) + { + CSFunctionParser fParse; + std::string dirVar; + switch (direct) + { + case 0: + dirVar = "x"; + break; + case 1: + dirVar = "y"; + break; + case 2: + dirVar = "z"; + break; + } + fParse.Parse(DistFunction,dirVar); + if (fParse.GetParseErrorType()!=FunctionParser::FP_NO_ERROR) + return std::string("An error occured parsing f(") + dirVar + std::string(") - Parser message:\n") + std::string(fParse.ErrorMsg()); + + double dValue=0; + bool error=false; + for (int n=0;n<numLines;++n) + { + dValue=fParse.Eval(&vals[n]); + if (fParse.EvalError()!=0) error=true; + AddDiscLine(direct,dValue); + } + if (error) return std::string("An error occured evaluation the grid function f(") + dirVar + std::string(")!"); + } + return ""; +} + +bool CSRectGrid::RemoveDiscLine(int direct, int index) +{ + if ((direct<0) || (direct>=3)) return false; + if ((index>=(int)Lines[direct].size()) || (index<0)) return false; + std::vector<double>::iterator vIter=Lines[direct].begin(); + Lines[direct].erase(vIter+index); + return true; +} + +bool CSRectGrid::RemoveDiscLine(int direct, double val) +{ + if ((direct<0) || (direct>=3)) return false; + for (size_t i=0;i<Lines[direct].size();++i) + { + if (Lines[direct].at(i)==val) return RemoveDiscLine(direct,(int)i); + } + return false; +} + +void CSRectGrid::clear() +{ + Lines[0].clear(); + Lines[1].clear(); + Lines[2].clear(); + dDeltaUnit=1; +} + +void CSRectGrid::ClearLines(int direct) +{ + if ((direct<0) || (direct>=3)) return; + Lines[direct].clear(); +} + +bool CSRectGrid::SetLine(int direct, size_t Index, double value) +{ + if ((direct<0) || (direct>=3)) return false; + if (Lines[direct].size()<=Index) return false; + Lines[direct].at(Index) = value; + return true; +} + +double CSRectGrid::GetLine(int direct, size_t Index) +{ + if ((direct<0) || (direct>=3)) return 0; + if (Lines[direct].size()<=Index) return 0; + return Lines[direct].at(Index); +} + +double* CSRectGrid::GetLines(int direct, double *array, unsigned int &qty, bool sorted) +{ + if ((direct<0) || (direct>=3)) return 0; + if (sorted) Sort(direct); + delete[] array; + array = new double[Lines[direct].size()]; + for (size_t i=0;i<Lines[direct].size();++i) array[i]=Lines[direct].at(i); + qty=Lines[direct].size(); + return array; +} + +std::string CSRectGrid::GetLinesAsString(int direct) +{ + std::stringstream xStr; + if ((direct<0)||(direct>=3)) return xStr.str(); + if (Lines[direct].size()>0) + { + for (size_t i=0;i<Lines[direct].size();++i) + { + if (i>0) xStr << ", "; + xStr<<Lines[direct].at(i); + } + } + return xStr.str(); +} + +unsigned int CSRectGrid::Snap2LineNumber(int ny, double value, bool &inside) const +{ + inside = false; + if ((ny<0) || (ny>2)) + return -1; + if (Lines[ny].size()==0) + return -1; + if (value<Lines[ny].at(0)) + return 0; + if (value>Lines[ny].at(Lines[ny].size()-1)) + return Lines[ny].size()-1; + inside = true; + for (size_t n=0;n<Lines[ny].size()-1;++n) + { + if (value < 0.5*(Lines[ny].at(n)+Lines[ny].at(n+1)) ) + return n; + } + return Lines[ny].size()-1; +} + +int CSRectGrid::GetDimension() +{ + if (Lines[0].size()==0) return -1; + if (Lines[1].size()==0) return -1; + if (Lines[2].size()==0) return -1; + int dim=0; + if (Lines[0].size()>1) ++dim; + if (Lines[1].size()>1) ++dim; + if (Lines[2].size()>1) ++dim; + return dim; +} + +void CSRectGrid::IncreaseResolution(int nu, int factor) +{ + if ((nu<0) || (nu>=GetDimension())) return; + if ((factor<=1) && (factor>9)) return; + size_t size=Lines[nu].size(); + for (size_t i=0;i<size-1;++i) + { + double delta=(Lines[nu].at(i+1)-Lines[nu].at(i))/factor; + for (int n=1;n<factor;++n) + { + AddDiscLine(nu,Lines[nu].at(i)+n*delta); + } + } + Sort(nu); +} + + +void CSRectGrid::Sort(int direct) +{ + if ((direct<0) || (direct>=3)) return; + std::vector<double>::iterator start = Lines[direct].begin(); + std::vector<double>::iterator end = Lines[direct].end(); + sort(start,end); + end=unique(start,end); + Lines[direct].erase(end,Lines[direct].end()); +} + +double* CSRectGrid::GetSimArea() +{ + for (int i=0;i<3;++i) + { + if (Lines[i].size()!=0) + { + SimBox[2*i]=*min_element(Lines[i].begin(),Lines[i].end()); + SimBox[2*i+1]=*max_element(Lines[i].begin(),Lines[i].end()); + } + else SimBox[2*i]=SimBox[2*i+1]=0; + } + return SimBox; +} + +bool CSRectGrid::isValid() +{ + for (int n=0;n<3;++n) + if (GetQtyLines(n)<2) + return false; + return true; +} + + +bool CSRectGrid::Write2XML(TiXmlNode &root, bool sorted) +{ + if (sorted) {Sort(0);Sort(1);Sort(2);} + TiXmlElement grid("RectilinearGrid"); + + grid.SetDoubleAttribute("DeltaUnit",dDeltaUnit); + + TiXmlElement XLines("XLines"); + XLines.SetAttribute("Qty",(int)Lines[0].size()); + if (Lines[0].size()>0) + { + TiXmlText XText(CombineVector2String(Lines[0],',')); + XLines.InsertEndChild(XText); + } + grid.InsertEndChild(XLines); + + TiXmlElement YLines("YLines"); + YLines.SetAttribute("Qty",(int)Lines[1].size()); + if (Lines[1].size()>0) + { + TiXmlText YText(CombineVector2String(Lines[1],',')); + YLines.InsertEndChild(YText); + } + grid.InsertEndChild(YLines); + + TiXmlElement ZLines("ZLines"); + ZLines.SetAttribute("Qty",(int)Lines[2].size()); + if (Lines[2].size()>0) + { + TiXmlText ZText(CombineVector2String(Lines[2],',')); + ZLines.InsertEndChild(ZText); + } + grid.InsertEndChild(ZLines); + + root.InsertEndChild(grid); + + return true; +} + +bool CSRectGrid::ReadFromXML(TiXmlNode &root) +{ + TiXmlElement* Lines=root.ToElement(); + if (Lines->QueryDoubleAttribute("DeltaUnit",&dDeltaUnit)!=TIXML_SUCCESS) dDeltaUnit=1.0; + + int help; + if (Lines->QueryIntAttribute("CoordSystem",&help)==TIXML_SUCCESS) + SetMeshType((CoordinateSystem)help); + + TiXmlNode* FN=NULL; + TiXmlText* Text=NULL; + std::string LineStr[3]; + + Lines = root.FirstChildElement("XLines"); + if (Lines==NULL) return false; + FN = Lines->FirstChild(); + if (FN!=NULL) + { + Text = FN->ToText(); + if (Text!=NULL) LineStr[0]=std::string(Text->Value()); + } + + Lines = root.FirstChildElement("YLines"); + if (Lines==NULL) return false; + FN = Lines->FirstChild(); + if (FN!=NULL) + { + Text = FN->ToText(); + if (Text!=NULL) LineStr[1]=std::string(Text->Value()); + } + + Lines = root.FirstChildElement("ZLines"); + if (Lines==NULL) return false; + FN = Lines->FirstChild(); + if (FN!=NULL) + { + Text = FN->ToText(); + if (Text!=NULL) LineStr[2]=std::string(Text->Value()); + } + + for (int i=0;i<3;++i) + { + std::vector<double> lines = SplitString2Double(LineStr[i],','); + for (size_t n=0;n<lines.size();++n) + AddDiscLine(i,lines.at(n)); + Sort(i); + } + + return true; +} diff --git a/CSXCAD/src/CSRectGrid.h b/CSXCAD/src/CSRectGrid.h new file mode 100644 index 0000000..1b0e03f --- /dev/null +++ b/CSXCAD/src/CSRectGrid.h @@ -0,0 +1,120 @@ +/* +* 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 <http://www.gnu.org/licenses/>. +*/ + +#pragma once +/* + * Author: Thorsten Liebig + * Date: 03-12-2008 + * Lib: CSXCAD + * Version: 0.1a + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string> +#include <sstream> +#include <vector> +#include <algorithm> +#include "ParameterObjects.h" +#include "CSXCAD_Global.h" + +class TiXmlNode; + +//! CSRectGrid is managing a rectilinear graded mesh. +class CSXCAD_EXPORT CSRectGrid +{ +public: + //! Create an empty grid. + CSRectGrid(void); + //! Deconstruct the grid. + ~CSRectGrid(void); + + static CSRectGrid* Clone(CSRectGrid* original); + + //! Add a disc-line in the given direction. + void AddDiscLine(int direct, double val); + void AddDiscLines(int direct, int numLines, double* vals); + std::string AddDiscLines(int direct, int numLines, double* vals, std::string DistFunction); + + //! Remove the disc-line at certain index and direction. + bool RemoveDiscLine(int direct, int index); + //! Remove the disc-line at certain value and direction. + bool RemoveDiscLine(int direct, double val); + + //! Remove all lines and reset to an empty grid. + void clear(); + //! Clear all lines in a given direction. + void ClearLines(int direct); + + //! Set the drawing unit. e.g. 1e-3 for mm as drawing unit. + void SetDeltaUnit(double val) {dDeltaUnit=val;} + //! Get the current drawing unit. + double GetDeltaUnit() {return dDeltaUnit;} + + //! Set a disc-line in a certain direction at a given index. Will return true on success. + bool SetLine(int direct, size_t Index, double value); + + //! Get an array of discretization lines in a certain direction. + /*! + \param direct The direction of interest. + \param array The array in which the lines will be stored. Can be NULL. Caller has to delete the array. + \param qty Methode will return the number of lines in this direction. + \param sorted Define here whether the lines shall be in increasing order (default) or as currently stored (unknown order). + */ + double* GetLines(int direct, double *array, unsigned int &qty, bool sorted=true); + //! Get quantity of lines in certain direction. + size_t GetQtyLines(int direct) {if ((direct>=0) && (direct<3)) return Lines[direct].size(); else return 0;} + //! Get a disc-line in a certain direction an at given index. + double GetLine(int direct, size_t Index); + //! Get disc-lines as a comma-seperated string for given direction + std::string GetLinesAsString(int direct); + + //! Snap a given value to a grid line for the given direction + unsigned int Snap2LineNumber(int ny, double value, bool &inside) const; + + //! Write the grid to a given XML-node. + bool Write2XML(TiXmlNode &root, bool sorted=false); + //! Read the grid from a given XML-node. + bool ReadFromXML(TiXmlNode &root); + + //! Get the dimension of current grid. \return 0,1,2 or 3. Returns -1 if one or more directions have no disc-line at all. + int GetDimension(); + + //! Set the type of mesh (e.g. Cartesian or Cylindrical mesh) + void SetMeshType(CoordinateSystem type) {m_meshType=type;} + + //! Get the type of mesh (e.g. Cartesian or Cylindrical mesh) + CoordinateSystem GetMeshType() {return m_meshType;} + + //! Increase the resolution in the specified direction by the given factor. + void IncreaseResolution(int nu, int factor); + + //! Sort the lines in a given direction. + void Sort(int direct); + + //! Get the bounding box of the area defined by the disc-lines. + double* GetSimArea(); + + //! This will check if the given mesh is a valid 3D mesh (at least 2 lines in all directions); + bool isValid(); + +protected: + std::vector<double> Lines[3]; + double dDeltaUnit; + double SimBox[6]; + CoordinateSystem m_meshType; +}; diff --git a/CSXCAD/src/CSTransform.cpp b/CSXCAD/src/CSTransform.cpp new file mode 100644 index 0000000..2e32481 --- /dev/null +++ b/CSXCAD/src/CSTransform.cpp @@ -0,0 +1,757 @@ +/* +* Copyright (C) 2011 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 "CSTransform.h" + +#include "CSUseful.h" +#include "tinyxml.h" + +#include <math.h> +#include <iostream> + +#include "vtkMatrix4x4.h" + +#define PI 3.141592653589793238462643383279 + +CSTransform::CSTransform() +{ + Reset(); + SetParameterSet(NULL); +} + +CSTransform::CSTransform(CSTransform* transform) +{ + if (transform==NULL) + { + Reset(); + SetParameterSet(NULL); + return; + } + m_PostMultiply = transform->m_PostMultiply; + m_AngleRadian = transform->m_AngleRadian; + m_TransformList = transform->m_TransformList; + m_TransformArguments = transform->m_TransformArguments; + SetParameterSet(transform->m_ParaSet); + for (int n=0;n<16;++n) + { + m_TMatrix[n] = transform->m_TMatrix[n]; + m_Inv_TMatrix[n] = transform->m_Inv_TMatrix[n]; + } +} + +CSTransform::CSTransform(ParameterSet* paraSet) +{ + Reset(); + SetParameterSet(paraSet); +} + +CSTransform::~CSTransform() +{ +} + +void CSTransform::Reset() +{ + m_PostMultiply = true; + m_AngleRadian=true; + m_TransformList.clear(); + m_TransformArguments.clear(); + MakeUnitMatrix(m_TMatrix); + MakeUnitMatrix(m_Inv_TMatrix); +} + +void CSTransform::Invert() +{ + //make sure the inverse matrix is up to date... + UpdateInverse(); + //switch matrices + double help; + for (int n=0;n<16;++n) + { + help = m_TMatrix[n]; + m_TMatrix[n] = m_Inv_TMatrix[n]; + m_Inv_TMatrix[n]=help; + } +} + +void CSTransform::UpdateInverse() +{ + // use vtk to do the matrix inversion + vtkMatrix4x4::Invert(m_TMatrix, m_Inv_TMatrix); +} + +double* CSTransform::Transform(const double inCoords[3], double outCoords[3]) const +{ + double coords[4] = {inCoords[0],inCoords[1],inCoords[2],1}; + for (int m=0;m<3;++m) + { + outCoords[m] = 0; + for (int n=0;n<4;++n) + { + outCoords[m] += m_TMatrix[4*m+n]*coords[n]; + } + } + return outCoords; +} + +double* CSTransform::InvertTransform(const double inCoords[3], double outCoords[3]) const +{ + double coords[4] = {inCoords[0],inCoords[1],inCoords[2],1}; + for (int m=0;m<3;++m) + { + outCoords[m] = 0; + for (int n=0;n<4;++n) + { + outCoords[m] += m_Inv_TMatrix[4*m+n]*coords[n]; + } + } + return outCoords; +} + +void CSTransform::SetMatrix(const double matrix[16], bool concatenate) +{ + ApplyMatrix(matrix,concatenate); + AppendList(MATRIX,matrix,16); +} + +bool CSTransform::SetMatrix(std::string matrix, bool concatenate) +{ + std::vector<std::string> mat_vec = SplitString2Vector(matrix, ','); + ParameterScalar ps_matrix[16]; + + double d_matrix[16]; + if (mat_vec.size()>16) + std::cerr << "CSTransform::SetMatrix: Warning: Number of arguments for operation: \"Matrix\" with arguments: \"" << matrix << "\" is larger than expected, skipping unneeded! " << std::endl; + else if (mat_vec.size()<16) + { + std::cerr << "CSTransform::SetMatrix: Error: Number of arguments for operation: \"Matrix\" with arguments: \"" << matrix << "\" is invalid! Skipping" << std::endl; + return false; + } + + for (int n=0;n<16;++n) + { + ps_matrix[n].SetParameterSet(m_ParaSet); + ps_matrix[n].SetValue(mat_vec.at(n)); + int EC = ps_matrix[n].Evaluate(); + if (EC!=0) + return false; + d_matrix[n]=ps_matrix[n].GetValue(); + } + + ApplyMatrix(d_matrix,concatenate); + AppendList(MATRIX,ps_matrix,16); + return true; +} + +bool CSTransform::TranslateMatrix(double matrix[16], const double translate[3]) +{ + MakeUnitMatrix(matrix); + //put translate vector into the last column + for (int n=0;n<3;++n) + matrix[4*n+3] = translate[n]; + return true; +} + +void CSTransform::Translate(const double translate[3], bool concatenate) +{ + double matrix[16]; + + if (TranslateMatrix(matrix, translate)==false) + return; + + ApplyMatrix(matrix,concatenate); + AppendList(TRANSLATE,translate,3); +} + +bool CSTransform::Translate(std::string translate, bool concatenate) +{ + double matrix[16]; + + std::vector<std::string> tl_vec = SplitString2Vector(translate, ','); + ParameterScalar ps_translate[3]; + double tl_double_vec[3]; + if (tl_vec.size()>3) + std::cerr << "CSTransform::Translate: Warning: Number of arguments for operation: \"Translate\" with arguments: \"" << translate << "\" is larger than expected, skipping unneeded! " << std::endl; + else if (tl_vec.size()<3) + { + std::cerr << "CSTransform::Translate: Error: Number of arguments for operation: \"Translate\" with arguments: \"" << translate << "\" is invalid! Skipping" << std::endl; + return false; + } + + for (int n=0;n<3;++n) + { + ps_translate[n].SetParameterSet(m_ParaSet); + ps_translate[n].SetValue(tl_vec.at(n)); + int EC = ps_translate[n].Evaluate(); + if (EC!=0) + return false; + tl_double_vec[n]=ps_translate[n].GetValue(); + } + + if (TranslateMatrix(matrix, tl_double_vec)==false) + return false; + + ApplyMatrix(matrix,concatenate); + AppendList(TRANSLATE,ps_translate,3); + return true; +} + +bool CSTransform::RotateOriginMatrix(double matrix[16], const double XYZ_A[4]) +{ + double length = sqrt(XYZ_A[0]*XYZ_A[0]+XYZ_A[1]*XYZ_A[1]+XYZ_A[2]*XYZ_A[2]); + if (length==0) + { + std::cerr << "CSTransform::RotateOriginVector: Warning: vector length is zero! skipping" << std::endl; + return false; + } + + for (int n=0;n<16;++n) + matrix[n]=0; + matrix[15] = 1; + + double angle = XYZ_A[3]; + if (m_AngleRadian==false) + angle *= PI/180; + + double unit_vec[3] = {XYZ_A[0]/length,XYZ_A[1]/length,XYZ_A[2]/length}; + + for (int n=0;n<3;++n) + { + int nP = (n+1)%3; + int nM = (n+2)%3; + //diagonal + matrix[4*n+n] += unit_vec[n]*unit_vec[n]+(1-unit_vec[n]*unit_vec[n])*cos(angle); + //diagonal + 1 + matrix[4*n+nP] += unit_vec[n]*unit_vec[nP]*(1-cos(angle))-unit_vec[nM]*sin(angle); + //diagonal + 2 + matrix[4*n+nM] += unit_vec[n]*unit_vec[nM]*(1-cos(angle))+unit_vec[nP]*sin(angle); + } + + return true; +} + +void CSTransform::RotateOrigin(const double vector[3], double angle, bool concatenate) +{ + double XYZ_A[4]={vector[0],vector[1],vector[2],angle}; + + double matrix[16]; + if (RotateOriginMatrix(matrix, XYZ_A)==false) + return; + + ApplyMatrix(matrix,concatenate); + AppendList(ROTATE_ORIGIN,XYZ_A,4); +} + +bool CSTransform::RotateOrigin(std::string XYZ_A, bool concatenate) +{ + double matrix[16]; + + std::vector<std::string> rot_vec = SplitString2Vector(XYZ_A, ','); + ParameterScalar ps_rotate[4]; + double rot_double_vec[4]; + if (rot_vec.size()>4) + std::cerr << "CSTransform::RotateOrigin: Warning: Number of arguments for operation: \"RotateOrigin\" with arguments: \"" << XYZ_A << "\" is larger than expected, skipping unneeded! " << std::endl; + else if (rot_vec.size()<4) + { + std::cerr << "CSTransform::RotateOrigin: Error: Number of arguments for operation: \"RotateOrigin\" with arguments: \"" << XYZ_A << "\" is invalid! Skipping" << std::endl; + return false; + } + + for (int n=0;n<4;++n) + { + ps_rotate[n].SetParameterSet(m_ParaSet); + ps_rotate[n].SetValue(rot_vec.at(n)); + int EC = ps_rotate[n].Evaluate(); + if (EC!=0) + return false; + rot_double_vec[n]=ps_rotate[n].GetValue(); + } + + if (RotateOriginMatrix(matrix, rot_double_vec)==false) + return false; + + ApplyMatrix(matrix,concatenate); + AppendList(ROTATE_ORIGIN,ps_rotate,4); + return true; +} + +void CSTransform::RotateXYZ(int dir, double angle, bool concatenate) +{ + if ((dir<0) || (dir>3)) + return; + + double vec[4]={0,0,0,angle}; + vec[dir] = 1; + + double matrix[16]; + if (RotateOriginMatrix(matrix, vec)==false) + return; + + ApplyMatrix(matrix,concatenate); + TransformType type = (TransformType)((int)ROTATE_X + dir); + AppendList(type,&angle,1); +} + +bool CSTransform::RotateXYZ(int dir, std::string angle, bool concatenate) +{ + if ((dir<0) || (dir>3)) + return false; + + ParameterScalar ps_angle(m_ParaSet, angle); + int EC = ps_angle.Evaluate(); + if (EC!=0) + return false; + double vec[4]={0,0,0,ps_angle.GetValue()}; + vec[dir] = 1; + + double matrix[16]; + if (RotateOriginMatrix(matrix, vec)==false) + return false; + + ApplyMatrix(matrix,concatenate); + TransformType type = (TransformType)((int)ROTATE_X + dir); + AppendList(type,&ps_angle,1); + return true; +} + +void CSTransform::RotateX(double angle, bool concatenate) +{ + return RotateXYZ(0,angle,concatenate); +} + +bool CSTransform::RotateX(std::string angle, bool concatenate) +{ + return RotateXYZ(0,angle,concatenate); +} + +void CSTransform::RotateY(double angle, bool concatenate) +{ + return RotateXYZ(1,angle,concatenate); +} + +bool CSTransform::RotateY(std::string angle, bool concatenate) +{ + return RotateXYZ(1,angle,concatenate); +} + +void CSTransform::RotateZ(double angle, bool concatenate) +{ + return RotateXYZ(2,angle,concatenate); +} + +bool CSTransform::RotateZ(std::string angle, bool concatenate) +{ + return RotateXYZ(2,angle,concatenate); +} + +bool CSTransform::ScaleMatrix(double matrix[16], double scale) +{ + MakeUnitMatrix(matrix); + for (int n=0;n<3;++n) + matrix[4*n+n] = scale; + return true; +} + +bool CSTransform::ScaleMatrix(double matrix[16], const double scale[3]) +{ + MakeUnitMatrix(matrix); + for (int n=0;n<3;++n) + matrix[4*n+n] = scale[n]; + return true; +} + +void CSTransform::Scale(double scale, bool concatenate) +{ + double matrix[16]; + + if (ScaleMatrix(matrix, scale)==false) + return; + + ApplyMatrix(matrix,concatenate); + AppendList(SCALE,&scale,1); +} + +void CSTransform::Scale(const double scale[3], bool concatenate) +{ + double matrix[16]; + + if (ScaleMatrix(matrix, scale)==false) + return; + + ApplyMatrix(matrix,concatenate); + AppendList(SCALE3,scale,3); +} + +bool CSTransform::Scale(std::string scale, bool concatenate) +{ + double matrix[16]; + + std::vector<std::string> scale_vec = SplitString2Vector(scale, ','); + + if ((scale_vec.size()>1) && (scale_vec.size()!=3)) + std::cerr << "CSTransform::Scale: Warning: Number of arguments for operation: \"Scale\" with arguments: \"" << scale << "\" is larger than expected, skipping unneeded! " << std::endl; + else if (scale_vec.size()<1) + { + std::cerr << "CSTransform::Scale: Error: Number of arguments for operation: \"Scale\" with arguments: \"" << scale << "\" is invalid! Skipping" << std::endl; + return false; + } + + if (scale_vec.size()>=3) + { + ParameterScalar ps_scale[3]; + double scale_double_vec[3]; + for (int n=0;n<3;++n) + { + ps_scale[n].SetParameterSet(m_ParaSet); + ps_scale[n].SetValue(scale_vec.at(n)); + int EC = ps_scale[n].Evaluate(); + if (EC!=0) + return false; + scale_double_vec[n]=ps_scale[n].GetValue(); + } + + if (ScaleMatrix(matrix, scale_double_vec)==false) + return false; + + ApplyMatrix(matrix,concatenate); + AppendList(SCALE3,ps_scale,3); + return true; + } + + if(scale_vec.size()>=1) + { + ParameterScalar ps_scale(m_ParaSet, scale); + int EC = ps_scale.Evaluate(); + if (EC!=0) + return false; + + if (ScaleMatrix(matrix, ps_scale.GetValue())==false) + return false; + + ApplyMatrix(matrix,concatenate); + AppendList(SCALE,&ps_scale,1); + return true; + } + + std::cerr << "CSTransform::Scale: Error: Number of arguments for operation: \"Scale\" with arguments: \"" << scale << "\" is invalid! Skipping" << std::endl; + return false; +} + +void CSTransform::ApplyMatrix(const double matrix[16], bool concatenate) +{ + if (concatenate) + { + double new_matrix[16]; + for (int n=0;n<16;++n) + new_matrix[n]=0; + for (int n=0;n<4;++n) + for (int m=0;m<4;++m) + { + for (int k=0;k<4;++k) + if (m_PostMultiply) + new_matrix[4*m+n] += matrix[4*m+k]*m_TMatrix[4*k+n]; + else + new_matrix[4*m+n] += m_TMatrix[4*m+k]*matrix[4*k+n]; + } + for (int n=0;n<16;++n) + m_TMatrix[n]=new_matrix[n]; + } + else + { + m_TransformList.clear(); + m_TransformArguments.clear(); + for (int n=0;n<16;++n) + m_TMatrix[n]=matrix[n]; + } + UpdateInverse(); +} + +bool CSTransform::TransformByString(std::string operation, std::string argument, bool concatenate) +{ + unsigned int numArgs; + int type = GetTypeByName(operation, numArgs); + + if (type<0) + { + std::cerr << "CSTransform::TransformByString: Error, unknown transformation: \"" << operation << "\"" << std::endl; + return false; + } + + return TransformByType((TransformType)type, argument, concatenate); +} + +void CSTransform::TransformByType(TransformType type, std::vector<double> args, bool concatenate) +{ + unsigned int numArgs = args.size(); + double arguments[numArgs]; + for (unsigned int n=0;n<numArgs;++n) + arguments[n] = args.at(n); + return TransformByType(type, arguments, concatenate); +} + +bool CSTransform::TransformByType(TransformType type, std::string args, bool concatenate) +{ + //Keep this in sync with GetTypeByName and TransformType!!! + switch (type) + { + case SCALE: + case SCALE3: + return Scale(args, concatenate); + case TRANSLATE: + return Translate(args,concatenate); + case ROTATE_ORIGIN: + return RotateOrigin(args,concatenate); + case ROTATE_X: + return RotateX(args,concatenate); + case ROTATE_Y: + return RotateY(args,concatenate); + case ROTATE_Z: + return RotateZ(args,concatenate); + case MATRIX: + return SetMatrix(args,concatenate); + default: + return false; + } +} + +void CSTransform::TransformByType(TransformType type, const double* args, bool concatenate) +{ + //Keep this in sync with GetTypeByName and TransformType!!! + switch (type) + { + case SCALE: + return Scale(args[0], concatenate); + case SCALE3: + return Scale(args, concatenate); + case TRANSLATE: + return Translate(args,concatenate); + case ROTATE_ORIGIN: + return RotateOrigin(args,args[3],concatenate); + case ROTATE_X: + return RotateX(args[0],concatenate); + case ROTATE_Y: + return RotateY(args[0],concatenate); + case ROTATE_Z: + return RotateZ(args[0],concatenate); + case MATRIX: + return SetMatrix(args,concatenate); + default: + return; + } +} + +std::string CSTransform::GetNameByType(TransformType type) const +{ + unsigned int numArgs; + return GetNameByType(type, numArgs); +} + +std::string CSTransform::GetNameByType(TransformType type, unsigned int &numArgs) const +{ + //Keep this in sync with GetTypeByName and TransformByType and TransformType!!! + switch (type) + { + case SCALE: + numArgs=1; + return "Scale"; + case SCALE3: + numArgs=3; + return "Scale3"; + case TRANSLATE: + numArgs=3; + return "Translate"; + case ROTATE_ORIGIN: + numArgs=4; + return "Rotate_Origin"; + case ROTATE_X: + numArgs=1; + return "Rotate_X"; + case ROTATE_Y: + numArgs=1; + return "Rotate_Y"; + case ROTATE_Z: + numArgs=1; + return "Rotate_Z"; + case MATRIX: + numArgs=16; + return "Matrix"; + default: + numArgs=0; + return "Unknown"; + } +} + +int CSTransform::GetTypeByName(std::string name, unsigned int &numArgs) const +{ + //Keep this in sync with GetNameByType and TransformByType and TransformType!!! + if (name.compare("Scale")==0) + { + numArgs=1; + return SCALE; + } + if (name.compare("Scale3")==0) + { + numArgs=3; + return SCALE3; + } + if (name.compare("Translate")==0) + { + numArgs=3; + return TRANSLATE; + } + if (name.compare("Rotate_Origin")==0) + { + numArgs=4; + return ROTATE_ORIGIN; + } + if (name.compare("Rotate_X")==0) + { + numArgs=1; + return ROTATE_X; + } + if (name.compare("Rotate_Y")==0) + { + numArgs=1; + return ROTATE_Y; + } + if (name.compare("Rotate_Z")==0) + { + numArgs=1; + return ROTATE_Z; + } + if (name.compare("Matrix")==0) + { + numArgs=16; + return MATRIX; + } + numArgs = 0; + return -1; +} + +void CSTransform::PrintMatrix(ostream& stream) +{ + for (int m=0;m<4;++m) + { + stream << m_TMatrix[4*m+0] << "\t" << m_TMatrix[4*m+1] << "\t" << m_TMatrix[4*m+2] << "\t" << m_TMatrix[4*m+3] << std::endl; + } +} + +void CSTransform::PrintTransformations(ostream& stream, std::string prefix) +{ + for (size_t n=0;n<m_TransformList.size();++n) + { + stream << prefix << GetNameByType(m_TransformList.at(n)) << "("; + for (size_t a=0;a<m_TransformArguments.at(n).size();++a) + { + stream << m_TransformArguments.at(n).at(a).GetValueString(); + if (a<m_TransformArguments.at(n).size()-1) + stream << ","; + } + stream << ")" << std::endl; + } +} + +void CSTransform::AppendList(TransformType type, const double* args, size_t numArgs ) +{ + m_TransformList.push_back(type); + std::vector<ParameterScalar> argument; + for (size_t n=0;n<numArgs;++n) + argument.push_back(ParameterScalar(m_ParaSet,args[n])); + m_TransformArguments.push_back(argument); +} + +void CSTransform::AppendList(TransformType type, const ParameterScalar* args, size_t numArgs ) +{ + m_TransformList.push_back(type); + std::vector<ParameterScalar> argument; + for (size_t n=0;n<numArgs;++n) + argument.push_back(args[n]); + m_TransformArguments.push_back(argument); +} + +double* CSTransform::MakeUnitMatrix(double* matrix) const +{ + for (int n=0;n<4;++n) + for (int m=0;m<4;++m) + { + if (n==m) + matrix[4*m+n]=1; + else + matrix[4*m+n]=0; + } + return matrix; +} + +bool CSTransform::Write2XML(TiXmlNode* root, bool parameterised, bool sparse) +{ + UNUSED(sparse); + UNUSED(parameterised); + + TiXmlElement Transform("Transformation"); + + for (size_t n=0;n<m_TransformList.size();++n) + { + TiXmlElement newTransform(GetNameByType(m_TransformList.at(n)).c_str()); + + std::string args; + for (size_t a=0;a<m_TransformArguments.at(n).size();++a) + { + args.append(m_TransformArguments.at(n).at(a).GetValueString()); + if (a<m_TransformArguments.at(n).size()-1) + args.append(","); + } + newTransform.SetAttribute("Argument",args.c_str()); + Transform.InsertEndChild(newTransform); + } + + root->InsertEndChild(Transform); + return true; +} + +bool CSTransform::ReadFromXML(TiXmlNode* root) +{ + TiXmlElement* prop=root->FirstChildElement("Transformation"); + if (prop==NULL) return false; + + TiXmlElement* PropNode = prop->FirstChildElement(); + while (PropNode!=NULL) + { + std::string argument(PropNode->Attribute("Argument")); + if (TransformByString(PropNode->Value(),argument,true)==false) + std::cerr << "CSTransform::ReadFromXML: Warning: Reading of \"" << PropNode->Value() << "\" with arguments: \"" << argument << "\" failed." << std::endl; + PropNode=PropNode->NextSiblingElement(); + } + return true; +} + +CSTransform* CSTransform::New(TiXmlNode* root, ParameterSet* paraSet) +{ + CSTransform* newCST = new CSTransform(paraSet); + if (newCST->ReadFromXML(root)) + return newCST; + delete newCST; + return NULL; +} + +CSTransform* CSTransform::New(CSTransform* cst, ParameterSet* paraSet) +{ + if (cst==NULL) + return NULL; + CSTransform* newCST = new CSTransform(cst); + if (paraSet) + newCST->SetParameterSet(paraSet); + return newCST; +} diff --git a/CSXCAD/src/CSTransform.h b/CSXCAD/src/CSTransform.h new file mode 100644 index 0000000..8293219 --- /dev/null +++ b/CSXCAD/src/CSTransform.h @@ -0,0 +1,140 @@ +/* +* Copyright (C) 2011 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/>. +*/ + +#ifndef CSTRANSFORM_H +#define CSTRANSFORM_H + +#include <stdio.h> +#include <stdlib.h> +#include <string> +#include <sstream> +#include <vector> +#include <algorithm> + +#include "ParameterObjects.h" + +class CSXCAD_EXPORT CSTransform +{ +public: + CSTransform(); + CSTransform(CSTransform* transform); + CSTransform(ParameterSet* paraSet); + virtual ~CSTransform(); + + void SetParameterSet(ParameterSet* paraset) {m_ParaSet=paraset;} + + enum TransformType + { + SCALE, SCALE3, TRANSLATE, ROTATE_ORIGIN, ROTATE_X, ROTATE_Y, ROTATE_Z, MATRIX + }; //Keep this in sync with GetNameByType and GetTypeByName and TransformByType methods!!! + + double* Transform(const double inCoords[3], double outCoords[3]) const; + double* InvertTransform(const double inCoords[3], double outCoords[3]) const; + + void Invert(); + + double* GetMatrix() {return m_TMatrix;} + + //! Apply a matrix directly + void SetMatrix(const double matrix[16], bool concatenate=true); + bool SetMatrix(std::string matrix, bool concatenate=true); + + //! Create and apply a translation matrix + void Translate(const double translate[3], bool concatenate=true); + bool Translate(std::string translate, bool concatenate=true); + + //! Create and apply a rotation matrix around the given vector and angle + void RotateOrigin(const double vector[3], double angle, bool concatenate=true); + bool RotateOrigin(std::string XYZ_A, bool concatenate=true); + + void RotateX(double angle, bool concatenate=true); + bool RotateX(std::string angle, bool concatenate=true); + + void RotateY(double angle, bool concatenate=true); + bool RotateY(std::string angle, bool concatenate=true); + + void RotateZ(double angle, bool concatenate=true); + bool RotateZ(std::string angle, bool concatenate=true); + + void RotateXYZ(int dir, double angle, bool concatenate=true); + bool RotateXYZ(int dir, std::string angle, bool concatenate=true); + + void Scale(double scale, bool concatenate=true); + void Scale(const double scale[3], bool concatenate=true); + bool Scale(std::string scale, bool concatenate=true); + + bool TransformByString(std::string operation, std::string argument, bool concatenate=true); + + void TransformByType(TransformType type, std::vector<double> args, bool concatenate=true); + void TransformByType(TransformType type, const double* args, bool concatenate=true); + bool TransformByType(TransformType type, std::string args, bool concatenate=true); + + void Reset(); + + //! All subsequent operations will be occur before the previous operations (not the default). + void SetPreMultiply() {m_PostMultiply=false;} + //! All subsequent operations will be after the previous operations (default). + void SetPostMultiply() {m_PostMultiply=true;} + + void SetAngleDegree() {m_AngleRadian=false;} + void SetAngleRadian() {m_AngleRadian=true;} + + double* MakeUnitMatrix(double matrix[16]) const; + + std::string GetNameByType(TransformType type) const; + std::string GetNameByType(TransformType type, unsigned int &numArgs) const; + int GetTypeByName(std::string name, unsigned int &numArgs) const; + + void PrintMatrix(std::ostream& stream); + + void PrintTransformations(std::ostream& stream, std::string prefix=""); + + //! Write this transformations to a xml-node. \param parameterised Use false if parameters should be written as values. Parameters are lost! + virtual bool Write2XML(TiXmlNode* root, bool parameterised=true, bool sparse=false); + //! Read transformations from xml-node. \return Successful read-operation. + virtual bool ReadFromXML(TiXmlNode* root); + + static CSTransform* New(TiXmlNode* root, ParameterSet* paraSet=NULL); + static CSTransform* New(CSTransform* cst, ParameterSet* paraSet=NULL); + +protected: + //transform matrix + double m_TMatrix[16]; + //inverse transform matrix + double m_Inv_TMatrix[16]; + + void UpdateInverse(); + + bool m_PostMultiply; + bool m_AngleRadian; + + ParameterSet* m_ParaSet; + + void ApplyMatrix(const double matrix[16], bool concatenate); + + bool RotateOriginMatrix(double matrix[16], const double XYZ_A[4]); + bool ScaleMatrix(double matrix[16], double scale); + bool ScaleMatrix(double matrix[16], const double scale[3]); + bool TranslateMatrix(double matrix[16], const double translate[3]); + + void AppendList(TransformType type, const double* args, size_t numArgs ); + void AppendList(TransformType type, const ParameterScalar* args, size_t numArgs ); + std::vector<TransformType> m_TransformList; + std::vector<std::vector <ParameterScalar> > m_TransformArguments; +}; + +#endif // CSTRANSFORM_H diff --git a/CSXCAD/src/CSUseful.cpp b/CSXCAD/src/CSUseful.cpp new file mode 100644 index 0000000..8d56c42 --- /dev/null +++ b/CSXCAD/src/CSUseful.cpp @@ -0,0 +1,178 @@ +/* +* Copyright (C) 2011,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 "CSUseful.h" +#include <stdio.h> +#include <stdlib.h> +#include <sstream> +#include <iostream> + +std::string ConvertInt(int number) +{ + std::stringstream ss; + ss << number; + return ss.str(); +} + +int String2Int(std::string number) +{ + int val; + std::stringstream ss(number); + ss >> val; + return val; +} + +double String2Double(std::string number, bool &ok, int accurarcy) +{ + double val; + std::stringstream ss(number); + ss.precision(accurarcy); + ss >> val; + ok = ss.eof() && !ss.fail(); + return val; +} + +std::vector<double> SplitString2Double(std::string str, const char delimiter) +{ + size_t pos=0; + std::string sub; + std::vector<double> values; + bool ok; + double val; + do + { + pos=str.find_first_of(delimiter); + if (pos==std::string::npos) pos=str.size(); + sub=str.substr(0,pos); + if (sub.empty()==false) + { + val = String2Double(sub, ok); + if (ok) + values.push_back(val); + } + str.erase(0,pos+1); + } while (str.size()>0); + return values; +} + +std::vector<std::string> SplitString2Vector(std::string str, const char delimiter) +{ + size_t pos=0; + std::string sub; + std::vector<std::string> values; + do + { + pos=str.find_first_of(delimiter); + if (pos==std::string::npos) + { + pos=str.size(); + sub=str.substr(0,pos); + } + else + { + sub=str.substr(0,pos); + ++pos; + } + if (sub.empty()==false) values.push_back(sub); + str.erase(0,pos); + } while (str.size()>0); + return values; +} + + +std::string CombineVector2String(std::vector<double> values, const char delimiter, int accurarcy) +{ + std::stringstream ss; + ss.precision( accurarcy ); + for (size_t i=0;i<values.size();++i) + { + if (i>0) ss << delimiter; + ss<<values.at(i); + } + return ss.str(); +} + +std::string CombineArray2String(double* values, unsigned int numVal, const char delimiter, int accurarcy) +{ + std::stringstream ss; + ss.precision( accurarcy ); + for (unsigned int i=0;i<numVal;++i) + { + if (i>0) ss << delimiter; + ss<<values[i]; + } + return ss.str(); +} + +std::string CombineArray2String(float* values, unsigned int numVal, const char delimiter, int accurarcy) +{ + std::stringstream ss; + ss.precision( accurarcy ); + for (unsigned int i=0;i<numVal;++i) + { + if (i>0) ss << delimiter; + ss<<values[i]; + } + return ss.str(); +} + +std::string CombineArray2String(int* values, unsigned int numVal, const char delimiter, int accurarcy) +{ + std::stringstream ss; + ss.precision( accurarcy ); + for (unsigned int i=0;i<numVal;++i) + { + if (i>0) ss << delimiter; + ss<<values[i]; + } + return ss.str(); +} + +std::vector<int> SplitString2Int(std::string str, const char delimiter) +{ + size_t pos=0; + std::string sub; + std::vector<int> values; + do + { + pos=str.find_first_of(delimiter); + if (pos==std::string::npos) pos=str.size(); + else ++pos; + sub=str.substr(0,pos); + if (sub.empty()==false) values.push_back(String2Int(sub)); + str.erase(0,pos); + } while (str.size()>0); + return values; +} + +CSDebug::CSDebug() +{ + m_level = 0; +} + +void CSDebug::Debug(int on_level, const char* message) +{ + Debug(on_level,std::string(message)); +} + +void CSDebug::Debug(int on_level, std::string message) +{ + if (on_level<=0) return; //no debug message for debug level smaller or equal zero + if (on_level>=m_level) + std::cerr << message << std::endl; +} + diff --git a/CSXCAD/src/CSUseful.h b/CSXCAD/src/CSUseful.h new file mode 100644 index 0000000..bcb64cb --- /dev/null +++ b/CSXCAD/src/CSUseful.h @@ -0,0 +1,41 @@ +#ifndef CSUSEFUL_H +#define CSUSEFUL_H + +class CSDebug; + +#include "CSXCAD_Global.h" +#include <vector> +#include <stdio.h> +#include <stdlib.h> +#include <string> +#include <iostream> + +std::string CSXCAD_EXPORT ConvertInt(int number); +int CSXCAD_EXPORT String2Int(std::string number); +double CSXCAD_EXPORT String2Double(std::string number, bool &ok, int accurarcy=15); +std::vector<double> CSXCAD_EXPORT SplitString2Double(std::string str, const char delimiter); +std::vector<std::string> CSXCAD_EXPORT SplitString2Vector(std::string str, const char delimiter); +std::string CSXCAD_EXPORT CombineVector2String(std::vector<double> values, const char delimiter, int accurarcy=15); +std::string CSXCAD_EXPORT CombineArray2String(double* values, unsigned int numVal, const char delimiter, int accurarcy=15); +std::string CSXCAD_EXPORT CombineArray2String(float* values, unsigned int numVal, const char delimiter, int accurarcy=15); +std::string CSXCAD_EXPORT CombineArray2String(int* values, unsigned int numVal, const char delimiter, int accurarcy=15); + +std::vector<int> CSXCAD_EXPORT SplitString2Int(std::string str, const char delimiter); + +class CSXCAD_EXPORT CSDebug +{ +public: + CSDebug(); + + void SetLevel(int level) {m_level=level;} + + void Debug(int on_level, const char* message); + void Debug(int on_level, std::string message); + +protected: + int m_level; +}; + +static CSDebug g_CSDebug; + +#endif // CSUSEFUL_H diff --git a/CSXCAD/src/CSXCAD_Global.h b/CSXCAD/src/CSXCAD_Global.h new file mode 100644 index 0000000..15f1b32 --- /dev/null +++ b/CSXCAD/src/CSXCAD_Global.h @@ -0,0 +1,46 @@ +/* +* 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 <http://www.gnu.org/licenses/>. +*/ + +#ifndef CSXCAD_GLOBAL_H_ +#define CSXCAD_GLOBAL_H_ + +#define _CSXCAD_LIB_NAME_ "CSXCAD-Lib: Continuous Structure XML - CAD" +#define _CSXCAD_LIB_NAME_SHORT_ "CSXCAD" +#define _CSXCAD_AUTHOR_ "Thorsten Liebig (2008-2012)" +#define _CSXCAD_AUTHOR_MAIL_ "Thorsten.Liebig@gmx.de" +#define _CSXCAD_VERSION_ GIT_VERSION +#define _CSXCAD_LICENSE_ "LGPL v3" + +#if defined(WIN32) + #ifdef BUILD_CSXCAD_LIB + #define CSXCAD_EXPORT __declspec(dllexport) + #else + #define CSXCAD_EXPORT __declspec(dllimport) + #endif +#else +#define CSXCAD_EXPORT +#endif + +// declare a parameter as unused +#define UNUSED(x) (void)(x); + +enum CoordinateSystem +{ + CARTESIAN, CYLINDRICAL, UNDEFINED_CS +}; + +#endif /*CSXCAD_GLOBAL_H_*/ diff --git a/CSXCAD/src/ContinuousStructure.cpp b/CSXCAD/src/ContinuousStructure.cpp new file mode 100644 index 0000000..a0c17a1 --- /dev/null +++ b/CSXCAD/src/ContinuousStructure.cpp @@ -0,0 +1,660 @@ +/* +* 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 <http://www.gnu.org/licenses/>. +*/ + +#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<CSProperties*>::iterator iter; + for (iter=vProperties.begin();iter<vProperties.end();++iter) + { + if (*iter==oldProp) + { + CSPrimitives* prim=oldProp->GetPrimitive(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<CSProperties*>::iterator iter=vProperties.begin(); + delete vProperties.at(index); + vProperties.erase(iter+index); + this->UpdateIDs(); +} + +void ContinuousStructure::DeleteProperty(CSProperties* prop) +{ + std::vector<CSProperties*>::iterator iter; + for (iter=vProperties.begin();iter<vProperties.end();++iter) + { + if (*iter==prop) + { + delete *iter; + vProperties.erase(iter); + } + } + this->UpdateIDs(); +} + +int ContinuousStructure::GetIndex(CSProperties* prop) +{ + if (prop==NULL) return -1; + for (size_t i=0;i<vProperties.size();++i) + if (vProperties.at(i)==prop) return (int)i; + return -1; +} + +size_t ContinuousStructure::GetQtyPropertyType(CSProperties::PropertyType type) +{ + size_t count=0; + for (size_t i=0;i<vProperties.size();++i) if (vProperties.at(i)->GetType() & type) ++count; + return count; +} + +std::vector<CSProperties*> ContinuousStructure::GetPropertyByType(CSProperties::PropertyType type) +{ + std::vector<CSProperties*> found; + for (size_t i=0;i<vProperties.size();++i) + if (vProperties.at(i)->GetType() & 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;i<vProperties.size();++i) + if (vProperties.at(i)->GetType() & type) + count+=vProperties.at(i)->GetQtyPrimitives(); + return count; +} + +bool sortPrimByPrio(CSPrimitives* a, CSPrimitives* b) +{ + return a->GetPriority()<b->GetPriority(); +} + +std::vector<CSPrimitives*> ContinuousStructure::GetAllPrimitives(bool sorted, CSProperties::PropertyType type) +{ + std::vector<CSProperties*> props = this->GetPropertyByType(type); + std::vector<CSPrimitives*> vPrim; + vPrim.reserve(GetQtyPrimitives(type)); + for (size_t i=0;i<props.size();++i) + { + std::vector<CSPrimitives*> 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;i<vProperties.size();++i) + if (vProperties.at(i)->HasPrimitive(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<CSPrimitives*> ContinuousStructure::GetPrimitivesByType(CSPrimitives::PrimitiveType type) +{ + UNUSED(type); + std::vector<CSPrimitives*> vPrim; + std::cerr << __func__ << ": Error, not yet implemented!" << std::endl; + return vPrim; +} + +std::vector<CSPrimitives*> ContinuousStructure::GetPrimitivesByBoundBox(const double* boundbox, bool sorted, CSProperties::PropertyType type) +{ + std::vector<CSPrimitives*> out_list; + std::vector<CSPrimitives*> prims =this->GetAllPrimitives(sorted, type); + for (size_t j=0;j<prims.size();++j) + { + // add primitive to list of IsInside reports 0 or 1 (unknown or true) + if (prims.at(j)->IsInsideBox(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<CSPrimitives*> vPrimitives=GetAllPrimitives(); + for (size_t i=0;i<vPrimitives.size();++i) + { + accBound = vPrimitives.at(i)->GetBoundBox(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<CSPrimitives*> vPrimitives=GetAllPrimitives(); + for (size_t i=0;i<vPrimitives.size();++i) + if (vPrimitives.at(i)->GetID()==ID) + return vPrimitives.at(i); + return NULL; +} + +std::vector<CSProperties*> ContinuousStructure::GetPropertiesByName(std::string name) +{ + std::vector<CSProperties*> vProp; + for (size_t i=0;i<vProperties.size();++i) + if (name.compare(vProperties.at(i)->GetName())==0) + vProp.push_back(vProperties.at(i)); + return vProp; +} + +CSProperties* ContinuousStructure::GetProperty(size_t index) +{ + if (index<vProperties.size()) return vProperties.at(index); + return NULL; +} + +CSProperties* ContinuousStructure::GetPropertyByCoordPriority(const double* coord, CSProperties::PropertyType type, bool markFoundAsUsed, CSPrimitives** foundPrimitive) +{ + CSProperties* winProp=NULL; + CSPrimitives* winPrim=NULL; + CSPrimitives* locPrim=NULL; + int winPrio=0; + int locPrio=0; + for (size_t i=0;i<vProperties.size();++i) + { + if ((type==CSProperties::ANY) || (vProperties.at(i)->GetType() & 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<CSPrimitives*> primList, bool markFoundAsUsed, CSPrimitives** foundPrimitive) +{ + CSProperties* prop = NULL; + // search in all given primitives if coordinate given is inside + for (size_t i=0;i<primList.size();++i) + if (primList.at(i)->IsInside(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;i<vProperties.size();++i) + { + if ((type==CSProperties::ANY) || (vProperties.at(i)->GetType() & type)) + { + vProperties.at(i)->WarnUnusedPrimitves(stream); + } + } +} + +void ContinuousStructure::ShowPropertyStatus(std::ostream& stream, CSProperties::PropertyType type) +{ + for (size_t i=0;i<vProperties.size();++i) + { + if ((type==CSProperties::ANY) || (vProperties.at(i)->GetType() & type)) + { + stream << "-----------------------------------------" << std::endl; + vProperties.at(i)->ShowPropertyStatus(stream); + } + } +} + +void ContinuousStructure::SetCoordInputType(CoordinateSystem type) +{ + m_MeshType = type; + for (size_t i=0;i<vProperties.size();++i) + { + vProperties.at(i)->SetCoordInputType(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<CSPrimitives*> vPrimitives=GetAllPrimitives(); + for (size_t i=0;i<vPrimitives.size();++i) + { + if (vPrimitives.at(i)->Update()==false) + return false; + } + + int excit=0; + for (size_t i=0;i<vProperties.size();++i) + { + if (vProperties.at(i)->Update()==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<CSPrimitives*> vPrimitives=GetAllPrimitives(); + for (size_t i=0;i<vPrimitives.size();++i) + { + prim=vPrimitives.at(i); + double box[6] = {0,0,0,0,0,0}; + AccBound = prim->GetBoundBox(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]<box[2*i+1]) ObjArea[2*i+1]=box[2*i+1]; + } + } + } + } + return ObjArea; +} + +std::string ContinuousStructure::Update() +{ + ErrString.clear(); + + for (size_t i=0;i<vProperties.size();++i) + vProperties.at(i)->Update(&ErrString); + + std::vector<CSPrimitives*> vPrimitives=GetAllPrimitives(); + for (size_t i=0;i<vPrimitives.size();++i) + vPrimitives.at(i)->Update(&ErrString); + + return std::string(ErrString); +} + +void ContinuousStructure::clear() +{ + UniqueIDCounter=0; + dDrawingTol=0; + maxID=0; + m_BG_Mat.Reset(); + for (unsigned int n=0;n<vProperties.size();++n) + { + delete vProperties.at(n); + vProperties.at(n)=NULL; + } + vProperties.clear(); + SetCoordInputType(CARTESIAN); + if (clParaSet) + clParaSet->clear(); + 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;i<vProperties.size();++i) + { + TiXmlElement PropElem(vProperties.at(i)->GetTypeXMLString().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;i<vProperties.size();++i) + vProperties.at(i)->SetID((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; +} + + + + diff --git a/CSXCAD/src/ContinuousStructure.h b/CSXCAD/src/ContinuousStructure.h new file mode 100644 index 0000000..aa986c5 --- /dev/null +++ b/CSXCAD/src/ContinuousStructure.h @@ -0,0 +1,218 @@ +/* +* 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 <http://www.gnu.org/licenses/>. +*/ + +#pragma once +/* + * Author: Thorsten Liebig + * Date: 03-12-2008 + * Lib: CSXCAD + * Version: 0.1a + */ + +#include <stdio.h> +#include <stdlib.h> +#include <iostream> +#include <string> +#include <vector> +#include "CSXCAD_Global.h" +#include "CSProperties.h" +#include "CSPrimitives.h" +#include "CSRectGrid.h" +#include "CSBackgroundMaterial.h" +#include "ParameterObjects.h" +#include "CSUseful.h" + +class TiXmlNode; + +//! Continuous Structure containing properties (layer) and primitives. +/*! + ContinuousStructure is a class that contains certain property objects containing geometrical primitive structures as boxes, spheres, cylinders etc. + All values in this class can contain parameters and mathematical equations. +*/ +class CSXCAD_EXPORT ContinuousStructure +{ +public: + //! Create an empty structure + ContinuousStructure(void); + //! Deconstructor. Will delete all properties and primitives it contains! + virtual ~ContinuousStructure(void); + + //! Get the ParameterSet created by this Structure. Needed for creation of any property or primitive! + /*! + \return ParameterSet owned by this class. + */ + ParameterSet* GetParameterSet() {return clParaSet;} + + //! Get the Grid of this Structure. + CSRectGrid* GetGrid() {return &clGrid;} + + //! Get the background material + CSBackgroundMaterial* GetBackgroundMaterial() {return &m_BG_Mat;} + + //! Add an existing CSProperty. Class takes ownership! + void AddProperty(CSProperties* prop); + + //! Replace an existing property with a new one. \sa AddProperty, DeleteProperty + bool ReplaceProperty(CSProperties* oldProp, CSProperties* newProp); + + //! Remove and delete Property at known index + void DeleteProperty(size_t index); + + //! Remove and delete a known Property + void DeleteProperty(CSProperties* prop); + + //! Get a primitive by its unique ID. + CSPrimitives* GetPrimitiveByID(unsigned int ID); + + //! Get all primitives with the given name + std::vector<CSProperties*> GetPropertiesByName(std::string name); + + //! Get a property by its internal index number. \sa GetQtyProperties + CSProperties* GetProperty(size_t index); + + //! Define the input type for the CSProperties weighting coordinate system 0=cartesian, 1=cylindrical, 2=spherical + void SetCoordInputType(CoordinateSystem type); + + CoordinateSystem GetCoordInputType() const {return m_MeshType;} + + //! Set a drawing tolerance. /sa GetPropertyByCoordPriority /sa GetPropertiesByCoordsPriority + void SetDrawingTolerance(double val) {dDrawingTol=val;} + + //! Get a property by its priority at a given coordinate and property type. + /*! + \param coord Give a 3-element array with a 3D-coordinate set (x,y,z). + \param type Specify the type searched for. (Default is ANY-type) + \param markFoundAsUsed Mark the found primitives as beeing used. \sa WarnUnusedPrimitves + \param foundPrimitive return the found primitive, set to NULL if none was found + \return Returns NULL if coordinate is outside the mesh, no mesh is defined or no property is found. + */ + CSProperties* GetPropertyByCoordPriority(const double* coord, CSProperties::PropertyType type=CSProperties::ANY, bool markFoundAsUsed=false, CSPrimitives** foundPrimitive=NULL); + + //! Get properties by its priority at given coordinates and property type. + /*! + \sa GetPropertyByCoordPriority + \param coords Give a 3*n-element array with the 3D-coordinate set (e.g. x1,y1,z1,x2,y2,z2,...) + \param type Specify the type searched for. (Default is ANY-type) + \param markFoundAsUsed Mark the found primitives as beeing used. \sa WarnUnusedPrimitves + \return Returns an array of n properties. NULL if coordinate is outside the mesh, no mesh is defined or no property is found. + */ + CSProperties** GetPropertiesByCoordsPriority(const double* coords, CSProperties::PropertyType type=CSProperties::ANY, bool markFoundAsUsed=false); + + CSProperties* GetPropertyByCoordPriority(const double* coord, std::vector<CSPrimitives*> primList, bool markFoundAsUsed=false, CSPrimitives** foundPrimitive=NULL); + + //! Check and warn for unused primitives in properties of given type + void WarnUnusedPrimitves(std::ostream& stream, CSProperties::PropertyType type=CSProperties::ANY); + + //! Show status of all properties with given type + void ShowPropertyStatus(std::ostream& stream, CSProperties::PropertyType type=CSProperties::ANY); + + //! Find the property owning the given primitive or return NULL if primitive is not to be found + CSProperties* HasPrimitive(CSPrimitives* prim); + + //! Delete the given primitive + void DeletePrimitive(CSPrimitives* prim); + + //! Get the quantity of primitives included in this structure. + size_t GetQtyPrimitives(CSProperties::PropertyType type=CSProperties::ANY); + + //! Get a primitives array + std::vector<CSPrimitives*> GetAllPrimitives(bool sorted=false, CSProperties::PropertyType type=CSProperties::ANY); + + //! Get a primitives array of a certian type + std::vector<CSPrimitives*> GetPrimitivesByType(CSPrimitives::PrimitiveType type); + + + //! Get a primitives array inside a bounding box and with a certian property type (default is any) + std::vector<CSPrimitives*> GetPrimitivesByBoundBox(const double* boundbox, bool sorted=false, CSProperties::PropertyType type=CSProperties::ANY); + + //! Get the internal index of the property. + int GetIndex(CSProperties* prop); + + //! Get the quantity of properties included in this structure. + size_t GetQtyProperties() {return vProperties.size();} + + //! Get the quantity of properties of a certain type included in this structure. + size_t GetQtyPropertyType(CSProperties::PropertyType type); + + //! Get a properties array of a certian type + std::vector<CSProperties*> GetPropertyByType(CSProperties::PropertyType type); + + //! Get the edges of all includes primitives and add to the desired grid direction. \param nu Direction of grid (x=0,y=1,z=2). + bool InsertEdges2Grid(int nu); + + //! Check whether the structure is valid. + virtual bool isGeometryValid(); + //! Update all primitives and properties e.g. with respect to changed parameter settings. \return Gives an error message in case of a found error. + std::string Update(); + + //! Get an array containing the absolute size of the current structure. + double* GetObjectArea(); + + //! Delete and clear all objects includes. This will result in an empty structure. + void clear(); + + //! Write this structure to an existing XML-node. + /*! + \param rootNode XML-Node to write this structure into. + \param parameterised Include full parameters (default) or parameter-values only. + */ + virtual bool Write2XML(TiXmlNode* rootNode, bool parameterised=true, bool sparse=false); + //! Write this structure to a file. + /*! + \param file Filename to write this structure into. Will create a new file or overwrite an existing one! + \param parameterised Include full parameters (default) or parameter-values only. + */ + virtual bool Write2XML(const char* file, bool parameterised=true, bool sparse=false); + virtual bool Write2XML(std::string file, bool parameterised=true, bool sparse=false); + + //! Read a structure from file. + /*! + \return Will return a string with possible error-messages! + \param file Filename to read this structure from. + */ + const char* ReadFromXML(const char* file); + //! Read a structure from a given XML-node. + /*! + \return Will return a string with possible error-messages! + \param rootNode XML-node to read this structure from. + */ + const char* ReadFromXML(TiXmlNode* rootNode); + + //! Get a Info-Line containing lib-name, -version etc. + static std::string GetInfoLine(bool shortInfo=false); + +protected: + ParameterSet* clParaSet; + CSRectGrid clGrid; + CSBackgroundMaterial m_BG_Mat; + std::vector<CSProperties*> vProperties; + bool ReadPropertyPrimitives(TiXmlElement* PropNode, CSProperties* prop); + + void UpdateIDs(); + + CoordinateSystem m_MeshType; + + unsigned int maxID; + + double ObjArea[6]; + double dDrawingTol; + + std::string ErrString; + unsigned int UniqueIDCounter; +}; + + diff --git a/CSXCAD/src/ParameterCoord.cpp b/CSXCAD/src/ParameterCoord.cpp new file mode 100644 index 0000000..62da688 --- /dev/null +++ b/CSXCAD/src/ParameterCoord.cpp @@ -0,0 +1,261 @@ +/* +* Copyright (C) 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 <http://www.gnu.org/licenses/>. +*/ + +#include "ParameterCoord.h" +#include "tinyxml.h" +#include <sstream> + +double* TransformCoordSystem(const double* inCoord, double* out, CoordinateSystem CS_In, CoordinateSystem CS_out) +{ + double in[3] = {inCoord[0],inCoord[1],inCoord[2]}; + switch (CS_In) + { + case CARTESIAN: //input coords are cartesian + switch (CS_out) + { + default: //unknown transform --> just copy + case CARTESIAN: // transform cartesian --> cartesian + for (int n=0;n<3;++n) + out[n] = in[n]; //just copy + break; + case CYLINDRICAL: // transform cartesian --> cylindrical + out[0] = sqrt(in[0]*in[0]+in[1]*in[1]); // r = sqrt(x²+y²) + out[1] = atan2(in[1],in[0]); //alpha = atan2(y,x) + out[2] = in[2]; //z==z + break; + } + break; + case CYLINDRICAL: //input coords are cylindrical + switch (CS_out) + { + case CARTESIAN: // transform cylindrical --> cartesian + out[0] = in[0] * cos(in[1]); // x = r * cos(alpha) + out[1] = in[0] * sin(in[1]); // y = r * sin(alpha) + out[2] = in[2]; // z = z + break; + default: //unknown transform --> just copy + case CYLINDRICAL: // transform cylindrical --> cylindrical + for (int n=0;n<3;++n) + out[n] = in[n]; //just copy + break; + } + break; + default: //unknown transform --> just copy + for (int n=0;n<3;++n) + out[n] = in[n]; //just copy + } + return out; +} + +ParameterCoord::ParameterCoord() +{ + m_CoordSystem = UNDEFINED_CS; + for (int n=0;n<3;++n) + m_Coords[n] = new ParameterScalar(); + Update(); +} + +ParameterCoord::ParameterCoord(ParameterSet* ParaSet) +{ + m_CoordSystem = UNDEFINED_CS; + for (int n=0;n<3;++n) + m_Coords[n] = new ParameterScalar(ParaSet,0); + Update(); +} + +ParameterCoord::ParameterCoord(CoordinateSystem cs) +{ + m_CoordSystem = cs; + for (int n=0;n<3;++n) + m_Coords[n] = new ParameterScalar(); + Update(); +} + +ParameterCoord::ParameterCoord(ParameterSet* ParaSet, const double value[3]) +{ + m_CoordSystem = UNDEFINED_CS; + for (int n=0;n<3;++n) + m_Coords[n] = new ParameterScalar(ParaSet, value[n]); + Update(); +} + +ParameterCoord::ParameterCoord(ParameterSet* ParaSet, const std::string value[3]) +{ + m_CoordSystem = UNDEFINED_CS; + for (int n=0;n<3;++n) + m_Coords[n] = new ParameterScalar(ParaSet, value[n]); + Update(); +} + +ParameterCoord::ParameterCoord(ParameterCoord* pc) +{ + m_CoordSystem = UNDEFINED_CS; + for (int n=0;n<3;++n) + m_Coords[n]=NULL; + Copy(pc); +} + +ParameterCoord::~ParameterCoord() +{ + for (int n=0;n<3;++n) + { + delete m_Coords[n]; + m_Coords[n]=NULL; + } +} + +void ParameterCoord::SetParameterSet(ParameterSet *paraSet) +{ + for (int n=0;n<3;++n) + m_Coords[n]->SetParameterSet(paraSet); + Update(); +} + +void ParameterCoord::SetCoordinateSystem(CoordinateSystem cs, CoordinateSystem fallBack_cs) +{ + if (cs!=UNDEFINED_CS) + return SetCoordinateSystem(cs); + return SetCoordinateSystem(fallBack_cs); +} + +int ParameterCoord::SetValue(int ny, std::string value) +{ + if ((ny<0) || (ny>2)) + return -1; + int EC = m_Coords[ny]->SetValue(value); + Update(); + return EC; +} + +void ParameterCoord::SetValue(int ny, double value) +{ + if ((ny<0) || (ny>2)) + return; + m_Coords[ny]->SetValue(value); + Update(); +} + +double ParameterCoord::GetValue(int ny) +{ + if ((ny<0) || (ny>2)) + return nan(""); + return m_Coords[ny]->GetValue(); +} + +const std::string ParameterCoord::GetValueString(int ny) const +{ + if ((ny<0) || (ny>2)) + return "nan"; + return m_Coords[ny]->GetValueString(); +} + +double ParameterCoord::GetCoordValue(int ny, CoordinateSystem cs) +{ + if ((ny<0) || (ny>2)) + return nan(""); + return GetCoords(cs)[ny]; +} + +ParameterScalar* ParameterCoord::GetCoordPS(int ny) +{ + if ((ny>=0) && (ny<3)) + return m_Coords[ny]; + return 0; +} + +const double* ParameterCoord::GetNativeCoords() const +{ + switch (m_CoordSystem) + { + default: + case CARTESIAN: + return GetCartesianCoords(); + case CYLINDRICAL: + return GetCylindricalCoords(); + } + return NULL; //this should not happen... +} + +const double* ParameterCoord::GetCoords(CoordinateSystem cs) const +{ + switch (cs) + { + case CARTESIAN: + return GetCartesianCoords(); + case CYLINDRICAL: + return GetCylindricalCoords(); + default: + return GetNativeCoords(); + } +} + +bool ParameterCoord::Evaluate(std::string *ErrStr) +{ + int EC=0; + bool bOK=true; + for (int i=0;i<3;++i) + { + EC=m_Coords[i]->Evaluate(); + if (EC!=ParameterScalar::NO_ERROR) bOK=false; + if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) + { + std::stringstream stream; + stream << std::endl << "Error in ParameterCoord (component: " << i << "): "; + ErrStr->append(stream.str()); + PSErrorCode2Msg(EC,ErrStr); + } + } + return bOK; +} + +void ParameterCoord::Copy(ParameterCoord* pc) +{ + m_CoordSystem = pc->m_CoordSystem; + for (int n=0;n<3;++n) + { + delete m_Coords[n]; + m_Coords[n] = new ParameterScalar(pc->m_Coords[n]); + } + Update(); +} + +void ParameterCoord::Update() +{ + double coords[3] = {m_Coords[0]->GetValue(),m_Coords[1]->GetValue(),m_Coords[2]->GetValue()}; + TransformCoordSystem(coords, m_CartesianCoords, m_CoordSystem, CARTESIAN); + TransformCoordSystem(coords, m_CylindricalCoords, m_CoordSystem, CYLINDRICAL); +} + +bool ParameterCoord::Write2XML(TiXmlElement *elem, bool parameterised) +{ + if (elem==NULL) + return false; + WriteTerm(*m_Coords[0],*elem,"X",parameterised); + WriteTerm(*m_Coords[1],*elem,"Y",parameterised); + WriteTerm(*m_Coords[2],*elem,"Z",parameterised); + return true; +} + +bool ParameterCoord::ReadFromXML(TiXmlElement *elem) +{ + if (elem==NULL) + return false; + if (ReadTerm(*m_Coords[0],*elem,"X")==false) return false; + if (ReadTerm(*m_Coords[1],*elem,"Y")==false) return false; + if (ReadTerm(*m_Coords[2],*elem,"Z")==false) return false; + return true; +} diff --git a/CSXCAD/src/ParameterCoord.h b/CSXCAD/src/ParameterCoord.h new file mode 100644 index 0000000..3a101dc --- /dev/null +++ b/CSXCAD/src/ParameterCoord.h @@ -0,0 +1,90 @@ +/* +* Copyright (C) 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 <http://www.gnu.org/licenses/>. +*/ + +#ifndef PARAMETERCOORD_H +#define PARAMETERCOORD_H + +#include "ParameterObjects.h" + +//! This class can hold a parameterized coordinate, defined in different coordinate systems. +class CSXCAD_EXPORT ParameterCoord +{ +public: + ParameterCoord(); + ParameterCoord(ParameterSet* ParaSet); + ParameterCoord(CoordinateSystem cs); + ParameterCoord(ParameterSet* ParaSet, const double value[3]); + ParameterCoord(ParameterSet* ParaSet, const std::string value[3]); + ParameterCoord(ParameterCoord* pc); + ~ParameterCoord(); + + void SetParameterSet(ParameterSet *paraSet); + + //! Set the coordinate system used for this coordinates + void SetCoordinateSystem(CoordinateSystem cs) {m_CoordSystem=cs; Update();} + //! Convienient method to set the coordinate system, including a fall back if primary coordinate system is undefined. + void SetCoordinateSystem(CoordinateSystem cs, CoordinateSystem fallBack_cs); + //! Get the coordinate system that has been set for this coordinate + CoordinateSystem GetCoordinateSystem() const {return m_CoordSystem;} + + int SetValue(int ny, std::string value); + void SetValue(int ny, double value); + + //! Get the native coordinate values + double GetValue(int ny); + //! Get the native coordinate values as string + const std::string GetValueString(int ny) const; + //! Get the internal scalar parameter, use carefully... + ParameterScalar* GetCoordPS(int ny); + + //! Get the coordinate in the given coordinate system + double GetCoordValue(int ny, CoordinateSystem cs); + + const double* GetNativeCoords() const; + const double* GetCartesianCoords() const {return m_CartesianCoords;} + const double* GetCylindricalCoords() const {return m_CylindricalCoords;} + const double* GetCoords(CoordinateSystem cs) const; + + //! Evaluate the parametric coordinates and return an error message. This methode should be called before requesting coordinate values to check for valid parametric coordinates. + bool Evaluate(std::string *ErrStr); + + // Copy all values and parameter from pc to this. + void Copy(ParameterCoord* pc); + + //! Write this coords to a XML-node. + bool Write2XML(TiXmlElement *elem, bool parameterised=true); + //! Read coords from a XML-node. + bool ReadFromXML(TiXmlElement *elem); + +protected: + //! Update/evaluate the internal data structure + void Update(); + ParameterScalar* m_Coords[3]; + + //! Coordinate system used for this coordinate + CoordinateSystem m_CoordSystem; + + //! evaluated cartesian coords + double m_CartesianCoords[3]; + //! evaluated cylindrical coords + double m_CylindricalCoords[3]; +}; + +//! Convert a given coordinate into another coordinate system +double* CSXCAD_EXPORT TransformCoordSystem(const double* in, double* out, CoordinateSystem CS_In, CoordinateSystem CS_out); + +#endif // PARAMETERCOORD_H diff --git a/CSXCAD/src/ParameterObjects.cpp b/CSXCAD/src/ParameterObjects.cpp new file mode 100644 index 0000000..161d4dd --- /dev/null +++ b/CSXCAD/src/ParameterObjects.cpp @@ -0,0 +1,713 @@ +/* +* 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 <http://www.gnu.org/licenses/>. +*/ + +#include "ParameterObjects.h" +#include <sstream> +#include <iostream> +#include "tinyxml.h" +#include "CSFunctionParser.h" +#include "CSUseful.h" + +bool ReadTerm(ParameterScalar &PS, TiXmlElement &elem, const char* attr, double val) +{ + double dHelp; + + PS.SetValue(val); // set default value + const char* chHelp=elem.Attribute(attr); + if (chHelp==NULL) + return false; + PS.SetValue(chHelp); // set string value if found + return true; +} + +void WriteTerm(ParameterScalar &PS, TiXmlElement &elem, const char* attr, bool mode, bool scientific) +{ + if (PS.GetMode() && mode) + elem.SetAttribute(attr,PS.GetString().c_str()); + else + { + if (PS.GetValue()==NAN) + return; + if (scientific) + { + char doubleVal[50]; + sprintf(doubleVal,"%e",PS.GetValue()); + elem.SetAttribute(attr,doubleVal); + } + else + elem.SetDoubleAttribute(attr,PS.GetValue()); + } +} + +bool ReadVectorTerm(ParameterScalar PS[3], TiXmlElement &elem, std::string attr, double val, const char delimiter) +{ + return ReadVectorTerm(PS, elem, attr.c_str(), val, delimiter); +} + +bool ReadVectorTerm(ParameterScalar PS[3], TiXmlElement &elem, const char* attr, double val, const char delimiter) +{ + //initialize with default value + for (int n=0;n<3;++n) + PS[n].SetValue(val); + + const char* values = elem.Attribute(attr); + if (values==NULL) + return false; + std::vector<std::string> val_list = SplitString2Vector(values, delimiter); + if (val_list.size()>3) + return false; + + for (int n=0;n<3;++n) + PS[n].SetValue(val); + for (int n=0;n<(int)val_list.size();++n) + { + std::string sHelp=val_list.at(n); + bool ok; + double val = String2Double(sHelp, ok); + if (ok) + PS[n].SetValue(val); + else + PS[n].SetValue(sHelp.c_str()); + } + return true; +} + +void WriteVectorTerm(ParameterScalar PS[3], TiXmlElement &elem, std::string attr, bool mode, bool scientific, const char delimiter) +{ + WriteVectorTerm(PS, elem, attr.c_str(), mode, scientific, delimiter); +} + +void WriteVectorTerm(ParameterScalar PS[3], TiXmlElement &elem, const char* attr, bool mode, bool sci, const char delimiter) +{ + std::stringstream ss; + if (sci) + ss << std::scientific; + for (int i=0;i<3;++i) + { + if (PS[i].GetMode() && mode) + ss << PS[i].GetString(); + else if (PS[i].GetValue()==NAN) + ss << "NAN" << std::endl; + else + ss << PS[i].GetValue(); + if (i<2) + ss << delimiter; + } + elem.SetAttribute(attr,ss.str().c_str()); +} + +Parameter::Parameter() +{ + bModified=true; + dValue=0; + Type=Const; + bSweep=true; +// Set=NULL; +} + +Parameter::Parameter(const std::string Paraname, double val) +{ + sName=Paraname; + SetValue(val); + Type=Const; + bSweep=true; +// Set=NULL; +} + +Parameter::~Parameter() +{ +// if (Set!=NULL) Set->RemoveParameter(this); +} + + +void Parameter::PrintSelf(FILE* /*out*/) +{ + fprintf(stderr," Parameter: %s Value: %f Type %d\n\n",sName.c_str(),dValue,Type); +} + +bool Parameter::Write2XML(TiXmlNode& root) +{ + TiXmlElement *elem=NULL; + if (Type==Const) + { + elem = new TiXmlElement("Parameter"); + elem->SetAttribute("Type","Const"); + } + else elem = root.ToElement(); + if (elem==NULL) return false; + elem->SetAttribute("name",sName.c_str()); + elem->SetAttribute("Sweep",bSweep); + elem->SetDoubleAttribute("value",dValue); + if (Type==Const) root.LinkEndChild(elem); + return true; +} + +bool Parameter::ReadFromXML(TiXmlNode &root) +{ + TiXmlElement *elem = root.ToElement(); + if (elem==NULL) return false; + + int iAtt=0; + if (elem->QueryIntAttribute("Sweep",&iAtt)!=TIXML_SUCCESS) bSweep=true; + else if (iAtt>0) bSweep=true; + else bSweep=false; + + double val=0; + if (elem->QueryDoubleAttribute("value",&val)!=TIXML_SUCCESS) return false; + SetValue(val); + + const char* att=elem->Attribute("name"); + if (att==NULL) sName=std::string(); + else sName=std::string(att); + + return true; +} + +Parameter* Parameter::GetParameterFromXML(TiXmlNode &/*root*/) +{ + return NULL; +} + +LinearParameter::LinearParameter() : Parameter() +{ + Type=Linear; + dMin=dMax=dStep=0; +} + +LinearParameter::LinearParameter(const std::string Paraname, double val, double min, double max, double step) : Parameter(Paraname,val) +{ + //sName=string(Paraname); + if (max<min) max=min; + dMin=min; + dMax=max; + if (step<0) step=0; + dStep=step; + Type=Linear; + + SetValue(dValue); +} + +LinearParameter::LinearParameter(const LinearParameter *parameter) : Parameter(parameter) +{ + if (parameter->Type==Linear) + { + dMin=parameter->dMin; + dMax=parameter->dMax; + dStep=parameter->dStep; + } + else + { + Type=Linear; + dMin=dMax=dStep=0; + } + SetValue(dValue); +} + +void LinearParameter::SetValue(double val) +{ + if (val>dMax) val=dMax; + else if (val<dMin) val=dMin; + if (dStep==0) dValue=val; + else + { + dValue=dMin+dStep*floor((val-dMin)/dStep+0.5); + if (dValue>dMax) dValue=dValue-dStep; + } + bModified=true; +} + +bool LinearParameter::IncreaseStep() +{ + if (dValue+dStep>dMax) return false; + SetValue(dValue+dStep); + return true; +} + +void LinearParameter::PrintSelf(FILE* /*out*/) +{ + fprintf(stderr," Parameter: %s Value: %f\n from %f to %f; Stepsize: %f\n",sName.c_str(),dValue,dMin,dMax,dStep); +} + +bool LinearParameter::Write2XML(TiXmlNode& root) +{ + TiXmlElement para("Parameter"); + para.SetAttribute("Type","Linear"); + Parameter::Write2XML(para); + para.SetDoubleAttribute("min",dMin); + para.SetDoubleAttribute("max",dMax); + para.SetDoubleAttribute("step",dStep); + root.InsertEndChild(para); + return true; +} + +bool LinearParameter::ReadFromXML(TiXmlNode &root) +{ + TiXmlElement *elem = root.ToElement(); + if (elem==NULL) return false; + + if (elem->QueryDoubleAttribute("min",&dMin)!=TIXML_SUCCESS) return false; + if (elem->QueryDoubleAttribute("max",&dMax)!=TIXML_SUCCESS) return false; + if (elem->QueryDoubleAttribute("step",&dStep)!=TIXML_SUCCESS) return false; + + if (Parameter::ReadFromXML(root)==false) return false; +// const char* att=elem->Attribute("name"); +// if (att==NULL) return false; +// sName=string(att); + +// if (elem->QueryDoubleAttribute("value",&dValue)!=TIXML_SUCCESS) return false; + + return true; +} + + +ParameterSet::ParameterSet(void) +{ + bModified=true; +} + +ParameterSet::~ParameterSet(void) +{ + clear(); +} + +size_t ParameterSet::LinkParameter(Parameter* newPara) +{ + vParameter.push_back(newPara); +// newPara->ParameterSet(this); + return vParameter.size(); +} + +size_t ParameterSet::DeleteParameter(size_t index) +{ + if (index>=vParameter.size()) return vParameter.size(); + std::vector<Parameter*>::iterator pIter=vParameter.begin(); + vParameter.erase(pIter+index); + + return vParameter.size(); +} + +size_t ParameterSet::DeleteParameter(Parameter* para) +{ + std::vector<Parameter*>::iterator pIter=vParameter.begin(); + while (pIter!=vParameter.end()) + { + if (*pIter==para) + { + vParameter.erase(pIter); + return vParameter.size(); + } + ++pIter; + } + return vParameter.size(); +} + +void ParameterSet::clear() +{ + for (size_t i=0; i<vParameter.size();++i) + { + delete vParameter.at(i); + } + vParameter.clear(); +// ParameterString.clear(); +// ParameterValueString.clear(); +} + +bool ParameterSet::GetModified() +{ + if (bModified==true) return true; + for (size_t i=0; i<vParameter.size();++i) if (vParameter.at(i)->GetModified()==true) return true; + return false; +} + +void ParameterSet::SetModified(bool mod) +{ + if (mod==true) + { + bModified=true; + return; + } + bModified=false; + for (size_t i=0; i<vParameter.size();++i) vParameter.at(i)->SetModified(false); +} + +double* ParameterSet::GetValueArray(double *array) +{ + if (array==NULL) return array; + for (size_t i=0; i<vParameter.size();++i) + { + array[i]=vParameter.at(i)->GetValue(); + } + return array; +} + +int ParameterSet::CountSweepSteps(int SweepMode) +{ + int count=0; + switch (SweepMode) + { + case 1: + for (size_t i=0; i<vParameter.size();++i) + if (vParameter.at(i)->GetSweep()) + { + if (count==0) count=vParameter.at(i)->CountSteps(); + else count*=vParameter.at(i)->CountSteps(); + } + return count; + break; + case 2: + for (size_t i=0; i<vParameter.size();++i) if (vParameter.at(i)->GetSweep()) count+=vParameter.at(i)->CountSteps(); + return count; + break; + } + return 0; +} + +void ParameterSet::InitSweep() +{ + for (size_t i=0; i<vParameter.size();++i) + if (vParameter.at(i)->GetSweep()) + { + vParameter.at(i)->Save(); + vParameter.at(i)->InitSweep(); + } + SweepPara=0; +} + +void ParameterSet::EndSweep() +{ + for (size_t i=0; i<vParameter.size();++i) + if (vParameter.at(i)->GetSweep()) + { + vParameter.at(i)->Restore(); + } +} + +bool ParameterSet::NextSweepPos(int SweepMode) +{ + switch (SweepMode) + { + case 1: + { + int level=vParameter.size()-1; + while (level>=0) + { + if (vParameter.at(level)->GetSweep()) + { + if (vParameter.at(level)->IncreaseStep()) return true; + else + { + vParameter.at(level)->InitSweep(); + --level; + } + } + else --level; + } + return false; + break; + } + case 2: + if ((unsigned int)SweepPara>=vParameter.size()) return false; + if (vParameter.at(SweepPara)->GetSweep()) + { + if (vParameter.at(SweepPara)->IncreaseStep()) return true; + else ++SweepPara; + return NextSweepPos(SweepMode); + } + else + { + ++SweepPara; + return NextSweepPos(SweepMode); + } + break; + } + return false; +} + + +const std::string ParameterSet::GetParameterString(const std::string spacer) +{ + std::string ParameterString; + for (size_t i=0; i<vParameter.size();++i) + { + if (i>0) ParameterString+=spacer; + ParameterString+=vParameter.at(i)->GetName(); + } + return ParameterString; +} + +const std::string ParameterSet::GetParameterValueString(const std::string spacer, bool ValuesOnly) +{ + std::string ParameterValueString; + for (size_t i=0; i<vParameter.size();++i) + { + if (i>0) ParameterValueString+=spacer; + if (!ValuesOnly) + { + ParameterValueString+=vParameter.at(i)->GetName(); + ParameterValueString+="="; + } + std::ostringstream os; + os << vParameter.at(i)->GetValue(); + ParameterValueString+=os.str(); + } + return ParameterValueString.c_str(); +} + +void ParameterSet::PrintSelf(FILE* out) +{ + fprintf(out," Parameter-Set Printout, Qty of Parameter: %d\n",(int)vParameter.size()); + for (size_t i=0; i<vParameter.size();++i) + { + fprintf(out,"----Nr. %d----\n",(int)i); + vParameter.at(i)->PrintSelf(out); + } +} + +bool ParameterSet::Write2XML(TiXmlNode& root) +{ + TiXmlElement pSet("ParameterSet"); + //pSet.SetAttribute("QtyParameter",(int)vParameter.size()); + for (size_t i=0;i<vParameter.size();++i) vParameter.at(i)->Write2XML(pSet); + + root.InsertEndChild(pSet); + return true; +} + +bool ParameterSet::ReadFromXML(TiXmlNode &root) +{ + TiXmlNode* paraNode = root.FirstChild("Parameter"); + while (paraNode!=NULL) + { + TiXmlElement *elem = paraNode->ToElement(); + if (elem!=NULL) + { + const char* att=elem->Attribute("Type"); + if (att!=NULL) + { + Parameter* newPara=NULL; + if (strcmp(att,"Const")==0) newPara = new Parameter(); + else if (strcmp(att,"Linear")==0) newPara = new LinearParameter(); + if (newPara!=NULL) + { + if (newPara->ReadFromXML(*elem)==true) this->InsertParameter(newPara); + } + } + } + paraNode=paraNode->NextSiblingElement("Parameter"); + }; + return true; +} + + +ParameterScalar::ParameterScalar() +{ + clParaSet=NULL; + bModified=true; + ParameterMode=false; + sValue.clear(); + dValue=0; +} + +ParameterScalar::ParameterScalar(ParameterSet* ParaSet, const std::string value) +{ + SetParameterSet(ParaSet); + SetValue(value); +} + +ParameterScalar::ParameterScalar(ParameterSet* ParaSet, double value) +{ + SetParameterSet(ParaSet); + bModified=true; + SetValue(value); +} + +ParameterScalar::ParameterScalar(ParameterScalar* ps) +{ + Copy(ps); +} + +ParameterScalar::~ParameterScalar() +{ +} + +void ParameterScalar::SetParameterSet(ParameterSet *paraSet) +{ + clParaSet=paraSet; +} + +int ParameterScalar::SetValue(const std::string value, bool Eval) +{ + if (value.empty()) return -1; + + //check if string is only a plain double + char *pEnd; + double val = strtod(value.c_str(),&pEnd); + if (*pEnd == 0) + SetValue(val); + + ParameterMode=true; + bModified=true; + sValue=value; + + if (Eval) return Evaluate(); + + return 0; +} + +void ParameterScalar::SetValue(double value) +{ + ParameterMode=false; + dValue=value; + sValue.clear(); +} + +double ParameterScalar::GetValue() const +{ + return dValue; +} + +const std::string ParameterScalar::GetValueString() const +{ + if (ParameterMode) + return sValue; + std::stringstream numString; + numString << dValue; + return numString.str(); +} + +int ParameterScalar::Evaluate() +{ + if (ParameterMode==false) return 0; + if (clParaSet!=NULL) + bModified = bModified || clParaSet->GetModified(); + if (bModified==false) + return 0; + + CSFunctionParser fParse; + dValue=0; + + if (clParaSet!=NULL) + fParse.Parse(sValue,clParaSet->GetParameterString()); + else + fParse.Parse(sValue,""); + + if (fParse.GetParseErrorType()!=FunctionParser::FP_NO_ERROR) return fParse.GetParseErrorType()+100; + bModified=false; + + if (clParaSet!=NULL) + { + double *vars = new double[clParaSet->GetQtyParameter()]; + vars=clParaSet->GetValueArray(vars); + dValue=fParse.Eval(vars); + delete[] vars;vars=NULL; + } + else + dValue=fParse.Eval(NULL); + return fParse.EvalError(); +} + +double ParameterScalar::GetEvaluated(double* ParaValues, int &EC) +{ + if (ParameterMode==false) return dValue; + CSFunctionParser fParse; + fParse.Parse(sValue,clParaSet->GetParameterString()); + if (fParse.GetParseErrorType()!=FunctionParser::FP_NO_ERROR) + { + EC = fParse.GetParseErrorType()+100; + return 0; + } + double dvalue = fParse.Eval(ParaValues); + EC = fParse.EvalError(); + return dvalue; +} + +void ParameterScalar::Copy(ParameterScalar* ps) +{ + SetParameterSet(ps->clParaSet); + bModified=ps->bModified; + ParameterMode=ps->ParameterMode; + sValue=std::string(ps->sValue); + dValue=ps->dValue; +} + +std::string PSErrorCode2Msg(int code) +{ + std::string msg; + PSErrorCode2Msg(code,&msg); + return msg; +} + +void PSErrorCode2Msg(int code, std::string *msg) +{ + switch (code) + { + case -1: + msg->append("Internal Error"); + break; + case 0: + msg->append("No Error"); + break; + case 1: + msg->append("Division by zero"); + break; + case 2: + msg->append("sqrt error (sqrt of a negative value)"); + break; + case 3: + msg->append("log error (logarithm of a negative value)"); + break; + case 4: + msg->append("trigonometric error (asin or acos of illegal value)"); + break; + case 5: + msg->append("Maximum recursion level reached"); + break; + case 100: + msg->append("Syntax error (check Parameter)"); + break; + case 101: + msg->append("Mismatched parenthesis"); + break; + case 102: + msg->append("Missing \')\'"); + break; + case 103: + msg->append("Empty parentheses"); + break; + case 104: + msg->append("Syntax error: Operator expected"); + break; + case 105: + msg->append("Not enough memory"); + break; + case 106: + msg->append("An unexpected error occurred"); + break; + case 107: + msg->append("Syntax error in parameters"); + break; + case 108: + msg->append("Illegal number of parameters to function"); + break; + case 109: + msg->append("Syntax error: Premature end of string"); + break; + case 110: + msg->append("Syntax error: Expecting ( after function"); + break; + }; +} diff --git a/CSXCAD/src/ParameterObjects.h b/CSXCAD/src/ParameterObjects.h new file mode 100644 index 0000000..9e9da49 --- /dev/null +++ b/CSXCAD/src/ParameterObjects.h @@ -0,0 +1,251 @@ +/* +* 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 <http://www.gnu.org/licenses/>. +*/ + +#ifndef _PARAMETEROBJECTS_H_ +#define _PARAMETEROBJECTS_H_ +/* + * Author: Thorsten Liebig + * Date: 03-12-2008 + * Lib: CSXCAD + * Version: 0.1a + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string> +#include <vector> +#include <math.h> +#include "CSXCAD_Global.h" + +class Parameter; +class LinearParameter; +class ParameterSet; +class ParameterScalar; +class TiXmlNode; +class TiXmlElement; + +bool ReadTerm(ParameterScalar &PS, TiXmlElement &elem, const char* attr, double val=0.0); +void WriteTerm(ParameterScalar &PS, TiXmlElement &elem, const char* attr, bool mode, bool scientific=true); + +bool ReadVectorTerm(ParameterScalar PS[3], TiXmlElement &elem, std::string attr, double val=0.0, const char delimiter=','); +bool ReadVectorTerm(ParameterScalar PS[3], TiXmlElement &elem, const char* attr, double val=0.0, const char delimiter=','); +void WriteVectorTerm(ParameterScalar PS[3], TiXmlElement &elem, std::string attr, bool mode, bool scientific=true, const char delimiter=','); +void WriteVectorTerm(ParameterScalar PS[3], TiXmlElement &elem, const char* attr, bool mode, bool scientific=true, const char delimiter=','); + +class CSXCAD_EXPORT Parameter +{ +public: + Parameter(); + Parameter(const std::string Paraname, double val); + Parameter(const Parameter* parameter) {sName=std::string(parameter->sName);dValue=parameter->dValue;bModified=true;Type=parameter->Type;bSweep=parameter->bSweep;} + virtual ~Parameter(); + enum ParameterType + { + Const, Linear + }; + ParameterType GetType() {return Type;} + + const std::string GetName() {return sName;} + void SetName(const std::string Paraname) {sName=std::string(Paraname);bModified=true;} + + virtual double GetValue() {return dValue;} + virtual void SetValue(double val) {dValue=val;bModified=true;} + + bool GetModified() {return bModified;} + void SetModified(bool mod) {bModified=mod;} + + virtual bool GetSweep() {return false;} ///const parameter can't sweep + void SetSweep(bool mod) {bSweep=mod;} + + virtual void InitSweep() {} + void Save() {dValueSaved=dValue;} + void Restore() {dValue=dValueSaved;} + + virtual bool IncreaseStep() {return false;} ///return false if no more sweep step available + virtual int CountSteps() {return 1;} + + virtual void PrintSelf(FILE* out=stdout); + + virtual bool Write2XML(TiXmlNode& root); + virtual bool ReadFromXML(TiXmlNode &root); + Parameter* GetParameterFromXML(TiXmlNode &root); + + virtual Parameter* Clone() {return new Parameter(this);} + + Parameter* ToConst() { return ( this && Type == Const ) ? this : 0; } /// Cast Parameter to a more defined type. Will return null if not of the requested type. + LinearParameter* ToLinear() { return ( this && Type == Linear ) ? (LinearParameter*) this : 0; } /// Cast Parameter to a more defined type. Will return null if not of the requested type. + +protected: + std::string sName; + double dValue; + double dValueSaved; + bool bModified; + bool bSweep; + ParameterType Type; +}; + +class CSXCAD_EXPORT LinearParameter : public Parameter +{ +public: + LinearParameter(); + LinearParameter(const std::string Paraname, double val, double min, double max, double step); + //copy-constructor + LinearParameter(const LinearParameter *parameter); + virtual ~LinearParameter(void) {} + + virtual void SetValue(double val); + + virtual bool GetSweep() {return bSweep;} + + virtual void InitSweep() {dValue=dMin;} + + virtual bool IncreaseStep(); + virtual int CountSteps() {return (int)((dMax-dMin)/dStep)+1;} + + double GetMin() {return dMin;} + void SetMin(double min) {dMin=min; if (dMax<dMin) dMax=dMin; SetValue(dValue);} + + double GetMax() {return dMax;} + void SetMax(double max) {dMax=max; if (dMax<dMin) dMax=dMin; SetValue(dValue);} + + double GetStep() {return dStep;} + void SetStep(double step) {dStep=step; if (dStep<0) dStep=0; SetValue(dValue);} + + void PrintSelf(FILE* out=stdout); + + virtual bool Write2XML(TiXmlNode& root); + virtual bool ReadFromXML(TiXmlNode &root); + + virtual Parameter* Clone() {return new LinearParameter(this);} + +protected: + double dMin; + double dMax; + double dStep; +}; + + +class CSXCAD_EXPORT ParameterSet +{ +public: + //! Create an empty Parameter-Set + ParameterSet(void); + //! Delete the Parameter-Set, including all parameter + virtual ~ParameterSet(void); + + //! This will create a clone of the parameter and insert it into the ParameterSet, caller keeps ownership of original parameter \sa LinkParameter \return number of current parameter + virtual size_t InsertParameter(Parameter* newPara) {return LinkParameter(newPara->Clone());} + //! This will add/link the given parameter into the ParameterSet and take ownership \return number of current parameter + virtual size_t LinkParameter(Parameter* newPara); + //! Same as LinkParameter \sa LinkParameter \return number of current parameter + virtual size_t AddParameter(Parameter* newPara) {return LinkParameter(newPara);} + //! Delete a Parameter at given index \return number of current parameter + virtual size_t DeleteParameter(size_t index); + //! Delete a given Parameter \return number of current parameter + virtual size_t DeleteParameter(Parameter* para); + //! Get the Parameter at the given index + Parameter* GetParameter(size_t index) {if (index<vParameter.size()) return vParameter.at(index); else return NULL;} + + //! Check whether the ParameterSet or any Parameter has been modified + bool GetModified(); + //! Set this ParameterSet's modfication status, including all Parameter + virtual void SetModified(bool mod=true); + + //! Check whether the ParameterSet has been modified (will not check the Parameter) \sa GetModified + bool GetParaSetModified() {return bModified;} + //! Set the ParameterSet's modfication status \sa SetModified + void SetParaSetModified(bool val) {bModified=val;} + + //! Get the string of all parameter separated by the given spacer + const std::string GetParameterString(const std::string spacer=","); + //! Get a string of all parameter and values or only the values separated by the given spacer + const std::string GetParameterValueString(const std::string spacer=",", bool ValuesOnly=false); + + //! Get the number of parameters in this Parameter-Set + size_t GetQtyParameter() {return vParameter.size();} + //! Fill a given array with the parameter values + double* GetValueArray(double *array); + + //! Get the number of necessary sweep steps for the given mode (1: full sweep, 2: sweep independently) + int CountSweepSteps(int SweepMode); + //! Init a sweep, will set all sweep-enabled Parameter to there initial value + void InitSweep(); + //! This will restore all Parameter values as prior to InitSweep \sa InitSweep + void EndSweep(); + //! Move sweep to the next step \sa InitSweep \sa CountSweepSteps + bool NextSweepPos(int SweepMode); + + //! Clear this ParameterSet, this will delete all Parameter + virtual void clear(); + + void PrintSelf(FILE* out=stdout); + //! Write this ParameterSet into a xml-node + bool Write2XML(TiXmlNode& root); + //! Read the ParameterSet from a xml-node + bool ReadFromXML(TiXmlNode &root); + +protected: + std::vector<Parameter* > vParameter; + bool bModified; + int SweepPara; +}; + +void PSErrorCode2Msg(int code, std::string* msg); +std::string PSErrorCode2Msg(int code); + +class CSXCAD_EXPORT ParameterScalar +{ +public: + enum EvaluateErrorType + { + NO_ERROR + }; + ParameterScalar(); + ParameterScalar(ParameterSet* ParaSet, double value); + ParameterScalar(ParameterSet* ParaSet, const std::string value); + ParameterScalar(ParameterScalar* ps); + ~ParameterScalar(); + + void SetParameterSet(ParameterSet *paraSet); + + int SetValue(const std::string value, bool Eval=true); ///returns eval-error-code + void SetValue(double value); + + bool GetMode() const {return ParameterMode;} + const std::string GetString() const {return sValue;} + + double GetValue() const; + + const std::string GetValueString() const; + + //returns error-code + int Evaluate(); + + double GetEvaluated(double* ParaValues, int &EC); + + // Copy all values and parameter from ps to this. + void Copy(ParameterScalar* ps); + +protected: + ParameterSet* clParaSet; + bool bModified; + bool ParameterMode; + std::string sValue; + double dValue; +}; + +#endif |