summaryrefslogtreecommitdiff
path: root/CSXCAD
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2016-07-05 18:02:38 +0200
committerRuben Undheim <ruben.undheim@gmail.com>2016-07-05 18:02:38 +0200
commitef962f6008f25ab7cbd4ca21bcc72b97a1e2d76f (patch)
tree8149bee93d1a3f91d4503bfb3853adac4af0a85e /CSXCAD
Imported Upstream version 0.0.34
Diffstat (limited to 'CSXCAD')
-rw-r--r--CSXCAD/CMakeLists.txt146
-rw-r--r--CSXCAD/COPYING165
-rw-r--r--CSXCAD/INSTALL25
-rw-r--r--CSXCAD/NEWS12
-rw-r--r--CSXCAD/README18
-rw-r--r--CSXCAD/cmake/Modules/FindTinyXML.cmake74
-rw-r--r--CSXCAD/doxydoc1541
-rw-r--r--CSXCAD/linux/CSXCAD.dsc9
-rw-r--r--CSXCAD/linux/CSXCAD.spec131
-rw-r--r--CSXCAD/linux/CSXGeomPlot.m.patch25
-rw-r--r--CSXCAD/linux/README.patch15
-rw-r--r--CSXCAD/linux/debian.changelog27
-rw-r--r--CSXCAD/linux/debian.control18
-rw-r--r--CSXCAD/linux/debian.csxcad-dev.install2
-rw-r--r--CSXCAD/linux/debian.csxcad.docs2
-rw-r--r--CSXCAD/linux/debian.csxcad.install2
-rw-r--r--CSXCAD/linux/debian.rules8
-rw-r--r--CSXCAD/linux/debian.series2
-rw-r--r--CSXCAD/matlab/AddBox.m42
-rw-r--r--CSXCAD/matlab/AddConductingSheet.m47
-rw-r--r--CSXCAD/matlab/AddCurve.m44
-rw-r--r--CSXCAD/matlab/AddCylinder.m35
-rw-r--r--CSXCAD/matlab/AddCylindricalShell.m41
-rw-r--r--CSXCAD/matlab/AddDebyeMaterial.m29
-rw-r--r--CSXCAD/matlab/AddDiscMaterial.m47
-rw-r--r--CSXCAD/matlab/AddDump.m87
-rw-r--r--CSXCAD/matlab/AddExcitation.m32
-rw-r--r--CSXCAD/matlab/AddLinPoly.m41
-rw-r--r--CSXCAD/matlab/AddLorentzMaterial.m60
-rw-r--r--CSXCAD/matlab/AddLumpedElement.m29
-rw-r--r--CSXCAD/matlab/AddMaterial.m26
-rw-r--r--CSXCAD/matlab/AddMetal.m26
-rw-r--r--CSXCAD/matlab/AddPlaneWaveExcite.m38
-rw-r--r--CSXCAD/matlab/AddPoint.m14
-rw-r--r--CSXCAD/matlab/AddPolygon.m41
-rw-r--r--CSXCAD/matlab/AddPolyhedron.m51
-rw-r--r--CSXCAD/matlab/AddProbe.m79
-rw-r--r--CSXCAD/matlab/AddPropAttribute.m24
-rw-r--r--CSXCAD/matlab/AddRotPoly.m48
-rw-r--r--CSXCAD/matlab/AddSphere.m30
-rw-r--r--CSXCAD/matlab/AddSphericalShell.m36
-rw-r--r--CSXCAD/matlab/AddWire.m46
-rw-r--r--CSXCAD/matlab/AnalyseMesh.m42
-rw-r--r--CSXCAD/matlab/AutoSmoothMeshLines.m159
-rw-r--r--CSXCAD/matlab/CSXGeomPlot.m43
-rw-r--r--CSXCAD/matlab/CalcDebyeMaterial.m29
-rw-r--r--CSXCAD/matlab/CalcDrudeMaterial.m37
-rw-r--r--CSXCAD/matlab/CalcLorentzMaterial.m61
-rw-r--r--CSXCAD/matlab/CheckMesh.m65
-rw-r--r--CSXCAD/matlab/Convert_VF_DiscMaterial.m255
-rw-r--r--CSXCAD/matlab/CreateDiscMaterial.m83
-rw-r--r--CSXCAD/matlab/DefineRectGrid.m50
-rw-r--r--CSXCAD/matlab/DetectEdges.m278
-rw-r--r--CSXCAD/matlab/DirChar2Int.m31
-rw-r--r--CSXCAD/matlab/ImportPLY.m23
-rw-r--r--CSXCAD/matlab/ImportSTL.m23
-rw-r--r--CSXCAD/matlab/InitCSX.m31
-rw-r--r--CSXCAD/matlab/RecursiveSmoothMesh.m176
-rw-r--r--CSXCAD/matlab/SetBackgroundMaterial.m23
-rw-r--r--CSXCAD/matlab/SetExcitationWeight.m53
-rw-r--r--CSXCAD/matlab/SetMaterialProperty.m29
-rw-r--r--CSXCAD/matlab/SetMaterialWeight.m31
-rw-r--r--CSXCAD/matlab/SmoothMesh.m73
-rw-r--r--CSXCAD/matlab/SmoothMeshLines.m122
-rw-r--r--CSXCAD/matlab/SmoothMeshLines2.m318
-rw-r--r--CSXCAD/matlab/export_empire.m305
-rw-r--r--CSXCAD/matlab/export_excellon.m144
-rw-r--r--CSXCAD/matlab/export_gerber.m198
-rw-r--r--CSXCAD/matlab/export_povray.m237
-rw-r--r--CSXCAD/matlab/isOctave.m46
-rw-r--r--CSXCAD/matlab/private/Add2Property.m26
-rw-r--r--CSXCAD/matlab/private/AddPrimitiveArgs.m28
-rw-r--r--CSXCAD/matlab/private/AddProperty.m29
-rw-r--r--CSXCAD/matlab/private/CheckSymmtricLines.m34
-rw-r--r--CSXCAD/matlab/private/FindProperty.m17
-rw-r--r--CSXCAD/matlab/private/GetPropertyPosition.m41
-rw-r--r--CSXCAD/matlab/private/GetPropertyType.m30
-rw-r--r--CSXCAD/matlab/private/SetPropertyArgs.m16
-rw-r--r--CSXCAD/matlab/private/SmoothRange.m58
-rw-r--r--CSXCAD/matlab/private/octave_struct2xml_2.m57
-rw-r--r--CSXCAD/matlab/private/struct_2_xmlNode.m48
-rw-r--r--CSXCAD/matlab/private/vector2str.m35
-rw-r--r--CSXCAD/matlab/searchBinary.m47
-rw-r--r--CSXCAD/matlab/struct_2_xml.m23
-rw-r--r--CSXCAD/src/CMakeLists.txt104
-rw-r--r--CSXCAD/src/CSBackgroundMaterial.cpp115
-rw-r--r--CSXCAD/src/CSBackgroundMaterial.h63
-rw-r--r--CSXCAD/src/CSFunctionParser.cpp76
-rw-r--r--CSXCAD/src/CSFunctionParser.h34
-rw-r--r--CSXCAD/src/CSPrimBox.cpp149
-rw-r--r--CSXCAD/src/CSPrimBox.h59
-rw-r--r--CSXCAD/src/CSPrimCurve.cpp188
-rw-r--r--CSXCAD/src/CSPrimCurve.h56
-rw-r--r--CSXCAD/src/CSPrimCylinder.cpp210
-rw-r--r--CSXCAD/src/CSPrimCylinder.h65
-rw-r--r--CSXCAD/src/CSPrimCylindricalShell.cpp177
-rw-r--r--CSXCAD/src/CSPrimCylindricalShell.h56
-rw-r--r--CSXCAD/src/CSPrimLinPoly.cpp131
-rw-r--r--CSXCAD/src/CSPrimLinPoly.h53
-rw-r--r--CSXCAD/src/CSPrimMultiBox.cpp279
-rw-r--r--CSXCAD/src/CSPrimMultiBox.h64
-rw-r--r--CSXCAD/src/CSPrimPoint.cpp126
-rw-r--r--CSXCAD/src/CSPrimPoint.h59
-rw-r--r--CSXCAD/src/CSPrimPolygon.cpp294
-rw-r--r--CSXCAD/src/CSPrimPolygon.h77
-rw-r--r--CSXCAD/src/CSPrimPolyhedron.cpp357
-rw-r--r--CSXCAD/src/CSPrimPolyhedron.h83
-rw-r--r--CSXCAD/src/CSPrimPolyhedronReader.cpp177
-rw-r--r--CSXCAD/src/CSPrimPolyhedronReader.h55
-rw-r--r--CSXCAD/src/CSPrimPolyhedron_p.h48
-rw-r--r--CSXCAD/src/CSPrimRotPoly.cpp191
-rw-r--r--CSXCAD/src/CSPrimRotPoly.h61
-rw-r--r--CSXCAD/src/CSPrimSphere.cpp176
-rw-r--r--CSXCAD/src/CSPrimSphere.h72
-rw-r--r--CSXCAD/src/CSPrimSphericalShell.cpp134
-rw-r--r--CSXCAD/src/CSPrimSphericalShell.h57
-rw-r--r--CSXCAD/src/CSPrimUserDefined.cpp252
-rw-r--r--CSXCAD/src/CSPrimUserDefined.h66
-rw-r--r--CSXCAD/src/CSPrimWire.cpp149
-rw-r--r--CSXCAD/src/CSPrimWire.h53
-rw-r--r--CSXCAD/src/CSPrimitives.cpp219
-rw-r--r--CSXCAD/src/CSPrimitives.h212
-rw-r--r--CSXCAD/src/CSPropConductingSheet.cpp97
-rw-r--r--CSXCAD/src/CSPropConductingSheet.h67
-rw-r--r--CSXCAD/src/CSPropDebyeMaterial.cpp238
-rw-r--r--CSXCAD/src/CSPropDebyeMaterial.h91
-rw-r--r--CSXCAD/src/CSPropDiscMaterial.cpp619
-rw-r--r--CSXCAD/src/CSPropDiscMaterial.h88
-rw-r--r--CSXCAD/src/CSPropDispersiveMaterial.cpp40
-rw-r--r--CSXCAD/src/CSPropDispersiveMaterial.h49
-rw-r--r--CSXCAD/src/CSPropDumpBox.cpp158
-rw-r--r--CSXCAD/src/CSPropDumpBox.h98
-rw-r--r--CSXCAD/src/CSPropExcitation.cpp278
-rw-r--r--CSXCAD/src/CSPropExcitation.h114
-rw-r--r--CSXCAD/src/CSPropLorentzMaterial.cpp416
-rw-r--r--CSXCAD/src/CSPropLorentzMaterial.h167
-rw-r--r--CSXCAD/src/CSPropLumpedElement.cpp128
-rw-r--r--CSXCAD/src/CSPropLumpedElement.h71
-rw-r--r--CSXCAD/src/CSPropMaterial.cpp304
-rw-r--r--CSXCAD/src/CSPropMaterial.h111
-rw-r--r--CSXCAD/src/CSPropMetal.cpp39
-rw-r--r--CSXCAD/src/CSPropMetal.h39
-rw-r--r--CSXCAD/src/CSPropProbeBox.cpp102
-rw-r--r--CSXCAD/src/CSPropProbeBox.h86
-rw-r--r--CSXCAD/src/CSPropResBox.cpp53
-rw-r--r--CSXCAD/src/CSPropResBox.h45
-rw-r--r--CSXCAD/src/CSPropUnknown.cpp52
-rw-r--r--CSXCAD/src/CSPropUnknown.h45
-rw-r--r--CSXCAD/src/CSProperties.cpp399
-rw-r--r--CSXCAD/src/CSProperties.h222
-rw-r--r--CSXCAD/src/CSRectGrid.cpp340
-rw-r--r--CSXCAD/src/CSRectGrid.h120
-rw-r--r--CSXCAD/src/CSTransform.cpp757
-rw-r--r--CSXCAD/src/CSTransform.h140
-rw-r--r--CSXCAD/src/CSUseful.cpp178
-rw-r--r--CSXCAD/src/CSUseful.h41
-rw-r--r--CSXCAD/src/CSXCAD_Global.h46
-rw-r--r--CSXCAD/src/ContinuousStructure.cpp660
-rw-r--r--CSXCAD/src/ContinuousStructure.h218
-rw-r--r--CSXCAD/src/ParameterCoord.cpp261
-rw-r--r--CSXCAD/src/ParameterCoord.h90
-rw-r--r--CSXCAD/src/ParameterObjects.cpp713
-rw-r--r--CSXCAD/src/ParameterObjects.h251
163 files changed, 19497 insertions, 0 deletions
diff --git a/CSXCAD/CMakeLists.txt b/CSXCAD/CMakeLists.txt
new file mode 100644
index 0000000..a349287
--- /dev/null
+++ b/CSXCAD/CMakeLists.txt
@@ -0,0 +1,146 @@
+
+# define build type
+IF( DEFINED CMAKE_BUILD_TYPE )
+ SET( CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Set to either \"Release\" or \"Debug\"" )
+ELSE()
+ SET( CMAKE_BUILD_TYPE Release CACHE STRING "Set to either \"Release\" or \"Debug\"" )
+ENDIF()
+
+PROJECT(CSXCAD CXX)
+
+cmake_minimum_required(VERSION 2.8)
+
+# default
+set(LIB_VERSION_MAJOR 0)
+set(LIB_VERSION_MINOR 6)
+set(LIB_VERSION_PATCH 1)
+set(LIB_VERSION_STRING ${LIB_VERSION_MAJOR}.${LIB_VERSION_MINOR}.${LIB_VERSION_PATCH})
+
+set(VERSION "v${LIB_VERSION_STRING}")
+
+IF(EXISTS ${PROJECT_SOURCE_DIR}/localConfig.cmake)
+ include(${PROJECT_SOURCE_DIR}/localConfig.cmake)
+ENDIF()
+
+# add git revision
+IF(EXISTS ${PROJECT_SOURCE_DIR}/.git )
+ FIND_PACKAGE(Git)
+ # Get the latest abbreviated commit hash of the working branch
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} describe --tags
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ OUTPUT_VARIABLE GITREV
+ )
+ set(VERSION ${GITREV})
+ string(STRIP ${VERSION} VERSION)
+ message(STATUS "Found Git repository, ${PROJECT_NAME} version tag: ${VERSION}")
+ENDIF()
+
+ADD_DEFINITIONS(-DGIT_VERSION=\"${VERSION}\")
+
+if (WIN32)
+ ADD_DEFINITIONS( -DBUILD_CSXCAD_LIB )
+endif (WIN32)
+
+#
+# Set up RPATH for the project
+#
+option(ENABLE_RPATH "Enable rpath support on Linux and Mac" ON)
+if(NOT CMAKE_INSTALL_RPATH)
+ # the RPATH to be used when installing, but only if it's not a system directory
+ LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" isSystemDir)
+ IF("${isSystemDir}" STREQUAL "-1")
+ SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}")
+ ENDIF("${isSystemDir}" STREQUAL "-1")
+endif()
+if(APPLE AND NOT CMAKE_INSTALL_NAME_DIR)
+ set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}")
+endif()
+if(UNIX AND ENABLE_RPATH)
+ set(CMAKE_SKIP_BUILD_RPATH FALSE)
+ set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
+ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+endif()
+
+# Set locations of CMake modules
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CSXCAD_SOURCE_DIR}/cmake/Modules/")
+
+# fparser
+# $ cmake -D FPARSER_ROOT_DIR=~/opt/openEMS .
+IF(NOT EXISTS ${FPARSER_ROOT_DIR})
+ SET(FPARSER_ROOT_DIR /usr)
+ENDIF()
+message(STATUS "FPARSER_ROOT_DIR: ${FPARSER_ROOT_DIR}" )
+find_library(fparser_LIBRARIES
+ NAMES fparser
+ HINTS ${FPARSER_ROOT_DIR}/lib${LIB_SUFFIX}
+ NO_CMAKE_FIND_ROOT_PATH
+)
+message(STATUS "fparser_LIBRARIES: ${fparser_LIBRARIES}" )
+find_path(fparser_INCLUDE_DIR
+ NAMES fparser.hh
+ HINTS ${FPARSER_ROOT_DIR}/include ${FPARSER_ROOT_DIR}/include/fparser
+ NO_CMAKE_FIND_ROOT_PATH
+)
+message(STATUS "fparser_INCLUDE_DIR: ${fparser_INCLUDE_DIR}" )
+#TODO test if fparser was found
+INCLUDE_DIRECTORIES( ${fparser_INCLUDE_DIR} )
+
+# TinyXML module from https://github.com/ros/cmake_modules
+find_package(TinyXML REQUIRED)
+ADD_DEFINITIONS( -DTIXML_USE_STL )
+
+find_package(HDF5 1.8 COMPONENTS C HL REQUIRED)
+INCLUDE_DIRECTORIES (${HDF5_INCLUDE_DIR})
+link_directories(${HDF5_LIBRARY_DIRS})
+# hdf5 compat
+ADD_DEFINITIONS( -DH5_USE_16_API )
+
+# message(status "hdf5 all libs: ${HDF5_LIBRARIES}")
+
+
+find_package(CGAL REQUIRED)
+INCLUDE_DIRECTORIES (${CGAL_INCLUDE_DIR})
+
+# cgal needs, fail o Linux otherwise
+if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -frounding-math" )
+endif()
+
+# TODO what are the needed libs?
+find_package(Boost 1.46 COMPONENTS
+ thread
+ system
+ date_time
+ serialization
+ chrono
+)
+
+# vtk
+if (WIN32)
+ find_package(VTK 6.1 REQUIRED)
+else()
+ # prefer >=6.1, fallback to >=5.4
+ find_package(VTK 6.1 COMPONENTS vtkIOGeometry vtkIOPLY NO_MODULE)
+ IF (NOT ${VTK_FOUND})
+ find_package(VTK REQUIRED)
+ endif()
+endif()
+
+message(STATUS "Found package VTK. Using version " ${VTK_VERSION})
+include(${VTK_USE_FILE})
+INCLUDE_DIRECTORIES (${VTK_INCLUDE_DIR})
+if("${VTK_MAJOR_VERSION}" GREATER 5)
+ set( vtk_LIBS ${VTK_LIBRARIES} )
+else()
+ set( vtk_LIBS
+ vtkCommon
+ )
+endif()
+message(STATUS "vtk libraries " ${vtk_LIBS})
+# depend on fparser.hh
+ADD_SUBDIRECTORY( src )
+
+INSTALL(DIRECTORY matlab DESTINATION share/CSXCAD)
+
+#TODO tarball, debug, release, doxygen
diff --git a/CSXCAD/COPYING b/CSXCAD/COPYING
new file mode 100644
index 0000000..cca7fc2
--- /dev/null
+++ b/CSXCAD/COPYING
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/CSXCAD/INSTALL b/CSXCAD/INSTALL
new file mode 100644
index 0000000..2c87401
--- /dev/null
+++ b/CSXCAD/INSTALL
@@ -0,0 +1,25 @@
+Install instructions for the CSXCAD library:
+---------------------------------------------
+
+1) Prerequirements:
+ CSXCAD relies on a number of third-party open-source libraries:
+ - fparser (http://warp.povusers.org/FunctionParser/)
+ - tinyxml (http://www.grinninglizard.com/tinyxml/)
+ - hdf5 (http://www.hdfgroup.org/HDF5/)
+ - vtk (http://www.vtk.org/)
+ - boost (http://www.boost.org/)
+ - cgal (http://www.cgal.org/)
+
+2) Build:
+ - change directory to CSXCAD
+ - build:
+ mkdir build
+ cd build
+ cmake .. -DCMAKE_INSTALL_PREFIX=<path/to/install/> -DFPARSER_ROOT_DIR=<path/to/fparser>
+ make
+ make install (may require root)
+
+ Note:
+ - all path informations may be stored in a localConfig.cmake
+ - the default "prefix" is /usr/local
+
diff --git a/CSXCAD/NEWS b/CSXCAD/NEWS
new file mode 100644
index 0000000..af8ecca
--- /dev/null
+++ b/CSXCAD/NEWS
@@ -0,0 +1,12 @@
+Changes in v0.5.1
+-------------------------------
+- matlab interface: throw an error when re-adding an already existing property (fix)
+
+Changes in v0.5.0
+-------------------------------
+- new file-format for discrete materials
+- new create function for discrete materials
+- fix for curve primitive in cylindrical coordinates
+- full multi-pole Lorentz/Drude/Debye material models
+- extensive code-cleanup
+- bug fixes \ No newline at end of file
diff --git a/CSXCAD/README b/CSXCAD/README
new file mode 100644
index 0000000..9b5056e
--- /dev/null
+++ b/CSXCAD/README
@@ -0,0 +1,18 @@
+*
+* CSXCAD - Continuous Structure XML
+*
+
+A C++ library to describe geometrical objects and their physical or non-physical properties.
+CSXCAD is licensed under the terms of the LGPLv3.
+
+
+Website: http://openems.de/index.php/CSXCAD
+Forum: http://openems.de/forum/
+Tutorials: http://openems.de/index.php/Tutorials
+
+
+To use CSXCAD from Matlab or Octave, you need to include the <CSXCAD-install-folder>/matlab folder in the respective environment:
+> addpath( '<CSXCAD-install-folder>/matlab' );
+
+To verify the correct installation follow the instructions at:
+http://openems.de/index.php/Tutorial:_First_Steps
diff --git a/CSXCAD/cmake/Modules/FindTinyXML.cmake b/CSXCAD/cmake/Modules/FindTinyXML.cmake
new file mode 100644
index 0000000..aabb323
--- /dev/null
+++ b/CSXCAD/cmake/Modules/FindTinyXML.cmake
@@ -0,0 +1,74 @@
+##################################################################################################
+#
+# CMake script for finding TinyXML.
+#
+# Input variables:
+#
+# - TinyXML_ROOT_DIR (optional): When specified, header files and libraries will be searched for in
+# ${TinyXML_ROOT_DIR}/include
+# ${TinyXML_ROOT_DIR}/libs
+# respectively, and the default CMake search order will be ignored. When unspecified, the default
+# CMake search order is used.
+# This variable can be specified either as a CMake or environment variable. If both are set,
+# preference is given to the CMake variable.
+# Use this variable for finding packages installed in a nonstandard location, or for enforcing
+# that one of multiple package installations is picked up.
+#
+#
+# Cache variables (not intended to be used in CMakeLists.txt files)
+#
+# - TinyXML_INCLUDE_DIR: Absolute path to package headers.
+# - TinyXML_LIBRARY: Absolute path to library.
+#
+#
+# Output variables:
+#
+# - TinyXML_FOUND: Boolean that indicates if the package was found
+# - TinyXML_INCLUDE_DIRS: Paths to the necessary header files
+# - TinyXML_LIBRARIES: Package libraries
+#
+#
+# Example usage:
+#
+# find_package(TinyXML)
+# if(NOT TinyXML_FOUND)
+# # Error handling
+# endif()
+# ...
+# include_directories(${TinyXML_INCLUDE_DIRS} ...)
+# ...
+# target_link_libraries(my_target ${TinyXML_LIBRARIES})
+#
+##################################################################################################
+
+# Get package location hint from environment variable (if any)
+if(NOT TinyXML_ROOT_DIR AND DEFINED ENV{TinyXML_ROOT_DIR})
+ set(TinyXML_ROOT_DIR "$ENV{TinyXML_ROOT_DIR}" CACHE PATH
+ "TinyXML base directory location (optional, used for nonstandard installation paths)")
+endif()
+
+# Search path for nonstandard package locations
+if(TinyXML_ROOT_DIR)
+ set(TinyXML_INCLUDE_PATH PATHS "${TinyXML_ROOT_DIR}/include" NO_DEFAULT_PATH)
+ set(TinyXML_LIBRARY_PATH PATHS "${TinyXML_ROOT_DIR}/lib" NO_DEFAULT_PATH)
+endif()
+
+# Find headers and libraries
+find_path(TinyXML_INCLUDE_DIR NAMES tinyxml.h PATH_SUFFIXES "tinyxml" ${TinyXML_INCLUDE_PATH})
+find_library(TinyXML_LIBRARY NAMES tinyxml PATH_SUFFIXES "tinyxml" ${TinyXML_LIBRARY_PATH})
+
+mark_as_advanced(TinyXML_INCLUDE_DIR
+ TinyXML_LIBRARY)
+
+# Output variables generation
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(TinyXML DEFAULT_MSG TinyXML_LIBRARY
+ TinyXML_INCLUDE_DIR)
+
+set(TinyXML_FOUND ${TINYXML_FOUND}) # Enforce case-correctness: Set appropriately cased variable...
+unset(TINYXML_FOUND) # ...and unset uppercase variable generated by find_package_handle_standard_args
+
+if(TinyXML_FOUND)
+ set(TinyXML_INCLUDE_DIRS ${TinyXML_INCLUDE_DIR})
+ set(TinyXML_LIBRARIES ${TinyXML_LIBRARY})
+endif()
diff --git a/CSXCAD/doxydoc b/CSXCAD/doxydoc
new file mode 100644
index 0000000..2b272ce
--- /dev/null
+++ b/CSXCAD/doxydoc
@@ -0,0 +1,1541 @@
+# Doxyfile 1.5.8
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = CSXCAD
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = $(CSXCAD_VERSION)
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = doc
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek,
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish,
+# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene,
+# Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH = /Users/dimitri/doxygen/mail/1.5.7/doxywizard/
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses.
+# With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this tag.
+# The format is ext=language, where ext is a file extension, and language is one of
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
+# use: inc=Fortran f=C
+
+EXTENSION_MAPPING =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will rougly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page. This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
+# doxygen. The layout file controls the global structure of the generated output files
+# in an output format independent way. The create the layout file that represents
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name
+# of the layout file.
+
+LAYOUT_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = src/
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.d \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.mm \
+ *.dox \
+ *.py \
+ *.f90 \
+ *.f \
+ *.vhd \
+ *.vhdl
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code. Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
+# are set, an additional index file will be generated that can be used as input for
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
+# HTML documentation.
+
+GENERATE_QHP = YES
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE = ../CSXCAD.qch
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = de.openems.CSXCAD.$(CSXCAD_VERSION)
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
+# For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION = qhelpgenerator
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to FRAME, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature. Other possible values
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list;
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
+# disables this behavior completely. For backwards compatibility with previous
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
+# respectively.
+
+GENERATE_TREEVIEW = NONE
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Options related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/CSXCAD/linux/CSXCAD.dsc b/CSXCAD/linux/CSXCAD.dsc
new file mode 100644
index 0000000..43849b5
--- /dev/null
+++ b/CSXCAD/linux/CSXCAD.dsc
@@ -0,0 +1,9 @@
+Format: 1.0
+Source: csxcad
+Version: 0.3.0-3
+Binary: csxcad, csxcad-dev
+Maintainer: Thorsten Liebig <thorsten.liebig@uni-due.de>, Sebastian Held <sebastian.held@gmx.de>
+Homepage: http://www.openems.de
+Architecture: any
+Build-Depends: debhelper (>=7.0.50~), qt4-qmake, libfparser4, libhdf5-serial-dev, libtinyxml-dev, libvtk5-qt4-dev
+DEBTRANSFORM-TAR: CSXCAD-0.3.0.tar.bz2
diff --git a/CSXCAD/linux/CSXCAD.spec b/CSXCAD/linux/CSXCAD.spec
new file mode 100644
index 0000000..38fd332
--- /dev/null
+++ b/CSXCAD/linux/CSXCAD.spec
@@ -0,0 +1,131 @@
+#
+# spec file for package [spectemplate]
+#
+# Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany.
+#
+# All modifications and additions to the file contributed by third parties
+# remain the property of their copyright owners, unless otherwise agreed
+# upon. The license for this file, and modifications and additions to the
+# file, is the same license as for the pristine package itself (unless the
+# license for the pristine package is not an Open Source License, in which
+# case the license is the MIT License). An "Open Source License" is a
+# license that conforms to the Open Source Definition (Version 1.9)
+# published by the Open Source Initiative.
+
+# Please submit bugfixes or comments via http://bugs.opensuse.org/
+#
+
+# norootforbuild
+
+Name: CSXCAD
+Version: 0.3.0
+Release: 2
+Summary: Library for Geometric Primitives primarily used by openEMS
+Group: Development/Languages/C and C++
+License: LGPLv3
+URL: http://www.openems.de
+Source0: %{name}-%{version}.tar.bz2
+Patch0: CSXGeomPlot.m.patch
+Patch1: README.patch
+# BuildArch: noarch
+BuildRoot: %_tmppath/%name-%version-build
+
+BuildRequires: libqt4-devel gcc-c++ libfparser4-devel hdf5-devel tinyxml-devel vtk-devel
+#Requires:
+
+
+# determine qt4 qmake executable
+%if 0%{?fedora}
+ %global qmake qmake-qt4
+%else
+ %global qmake qmake
+%endif
+
+
+
+%description
+Library for Geometric Primitives primarily used by openEMS.
+
+%package -n lib%{name}0
+Summary: Shared Library for %{name}
+Group: Development/Languages/C and C++
+
+%description -n lib%{name}0
+The lib%{name}0 package contains the shared library.
+
+%package devel
+Summary: Development files for %{name}
+Group: Development/Languages/C and C++
+Requires: %{name} = %{version}-%{release}
+Requires: lib%{name}0 = %{version}-%{release}
+
+%description devel
+The %{name}-devel package contains libraries and header files for
+developing applications that use %{name}.
+
+
+%prep
+%setup -q
+%patch0 -p1
+%patch1 -p1
+
+%build
+%{qmake} QMAKE_CFLAGS="%optflags" QMAKE_CXXFLAGS="%optflags" LIB_SUFFIX="$(echo %_lib | cut -b4-)"
+make %{?_smp_mflags}
+
+
+%install
+make INSTALL_ROOT=%{buildroot} install
+find %{buildroot} -name '*.la' -exec rm -f {} ';'
+
+
+%clean
+rm -rf %{buildroot}
+
+
+%post -n lib%{name}0 -p /sbin/ldconfig
+
+%postun -n lib%{name}0 -p /sbin/ldconfig
+
+
+%files
+%defattr(-,root,root)
+%doc COPYING README
+/usr/share/%{name}
+#/usr/share/%{name}/matlab
+#/usr/share/%{name}/matlab/*
+
+
+%files -n lib%{name}0
+%defattr(-,root,root)
+%{_libdir}/*.so.*
+
+
+%files devel
+%defattr(-,root,root)
+%{_includedir}/*
+%{_libdir}/*.so
+
+
+%changelog
+* Sat Jun 23 2012 Sebastian Held <sebastian.held@gmx.de> - 0.3.0-2
+- fixed missing files and version information
+* Sun Jun 17 2012 Sebastian Held <sebastian.held@gmx.de> - 0.3.0-1
+- new upstream version
+* Wed Feb 29 2012 Sebastian Held <sebastian.held@gmx.de> - 0.2.4-7
+- new upstream fixes
+* Sat Jan 21 2012 Sebastian Held <sebastian.held@gmx.de> - 0.2.4-6
+- new upstream fixes
+* Thu Dec 29 2011 Sebastian Held <sebastian.held@gmx.de> - 0.2.4-5
+- added README
+* Thu Dec 22 2011 Sebastian Held <sebastian.held@gmx.de> - 0.2.4-4
+- new upstream fix and support for Fedora 16
+* Mon Dec 05 2011 Sebastian Held <sebastian.held@gmx.de> - 0.2.4-3
+- includes now in /usr/include/CSXCAD
+- fix for CSXGeomView.m
+* Sun Dec 04 2011 Sebastian Held <sebastian.held@gmx.de> - 0.2.4-2
+- missing build dep vtk-devel
+* Sun Dec 04 2011 Sebastian Held <sebastian.held@gmx.de> - 0.2.4-1
+- next release
+* Tue Sep 29 2011 Sebastian Held <sebastian.held@gmx.de> - 0.0.24-1
+- initial version
diff --git a/CSXCAD/linux/CSXGeomPlot.m.patch b/CSXCAD/linux/CSXGeomPlot.m.patch
new file mode 100644
index 0000000..09dc664
--- /dev/null
+++ b/CSXCAD/linux/CSXGeomPlot.m.patch
@@ -0,0 +1,25 @@
+diff --git a/matlab/CSXGeomPlot.m b/matlab/CSXGeomPlot.m
+index 21d3ef8..37427a1 100644
+--- a/matlab/CSXGeomPlot.m
++++ b/matlab/CSXGeomPlot.m
+@@ -13,18 +13,10 @@ if nargin < 1
+ error 'specify the xml file to open'
+ end
+
+-filename = mfilename('fullpath');
+-dir = fileparts( filename );
+-AppCSXCAD_Path = [dir filesep '../../AppCSXCAD' filesep];
+-
+-if (~exist(AppCSXCAD_Path,'dir'))
+- AppCSXCAD_Path = [dir filesep '..' filesep]
+-end
+-
+ if isunix
+- AppCSXCAD_Path = [AppCSXCAD_Path 'AppCSXCAD.sh'];
++ AppCSXCAD_Path = 'AppCSXCAD.sh';
+ else
+- AppCSXCAD_Path = [AppCSXCAD_Path 'AppCSXCAD'];
++ AppCSXCAD_Path = 'AppCSXCAD';
+ end
+
+ command = [AppCSXCAD_Path ' --disableEdit ' CSX_filename];
diff --git a/CSXCAD/linux/README.patch b/CSXCAD/linux/README.patch
new file mode 100644
index 0000000..ea947f6
--- /dev/null
+++ b/CSXCAD/linux/README.patch
@@ -0,0 +1,15 @@
+diff --git a/README b/README
+index 9b5056e..fc3176c 100644
+--- a/README
++++ b/README
+@@ -11,8 +11,8 @@ Forum: http://openems.de/forum/
+ Tutorials: http://openems.de/index.php/Tutorials
+
+
+-To use CSXCAD from Matlab or Octave, you need to include the <CSXCAD-install-folder>/matlab folder in the respective environment:
+-> addpath( '<CSXCAD-install-folder>/matlab' );
++To use CSXCAD from Matlab or Octave, you need to include the /usr/share/CSXCAD/matlab folder in the respective environment:
++> addpath( '/usr/share/CSXCAD/matlab' );
+
+ To verify the correct installation follow the instructions at:
+ http://openems.de/index.php/Tutorial:_First_Steps
diff --git a/CSXCAD/linux/debian.changelog b/CSXCAD/linux/debian.changelog
new file mode 100644
index 0000000..dfbccbb
--- /dev/null
+++ b/CSXCAD/linux/debian.changelog
@@ -0,0 +1,27 @@
+csxcad (0.3.0-3) stable; urgency=low
+ * replaced recommended deps by suggested deps
+ -- Sebastian Held <sebastian.held@gmx.de> Sat, 30 Jun 2012 12:16:00 +0200
+csxcad (0.3.0-2) stable; urgency=low
+ * fixed missing files and version information
+ -- Sebastian Held <sebastian.held@gmx.de> Sat, 23 Jun 2012 11:58:00 +0200
+csxcad (0.3.0-1) stable; urgency=low
+ * New upstream version
+ -- Sebastian Held <sebastian.held@gmx.de> Sun, 17 Jun 2012 21:54:30 +0200
+csxcad (0.2.4-6) stable; urgency=low
+ * New upstream fix
+ -- Sebastian Held <sebastian.held@gmx.de> Wed, 29 Feb 2012 23:20:00 +0100
+csxcad (0.2.4-5) stable; urgency=low
+ * New upstream fix
+ -- Sebastian Held <sebastian.held@gmx.de> Sat, 21 Jan 2012 21:22:00 +0100
+csxcad (0.2.4-4) stable; urgency=low
+ * Added README
+ -- Sebastian Held <sebastian.held@gmx.de> Thu, 29 Dec 2011 21:06:00 +0100
+csxcad (0.2.4-3) stable; urgency=low
+ * New upstream fix
+ -- Sebastian Held <sebastian.held@gmx.de> Thu, 22 Dec 2011 22:45:00 +0100
+csxcad (0.2.4-2) stable; urgency=low
+ * New upstream release
+ -- Sebastian Held <sebastian.held@gmx.de> Sun, 4 Dec 2011 15:20:00 +0100
+csxcad (0.0.24-1) stable; urgency=low
+ * Initial Release
+ -- Sebastian Held <sebastian.held@gmx.de> Thu, 6 Oct 2011 17:58:38 +0200
diff --git a/CSXCAD/linux/debian.control b/CSXCAD/linux/debian.control
new file mode 100644
index 0000000..54ac8ab
--- /dev/null
+++ b/CSXCAD/linux/debian.control
@@ -0,0 +1,18 @@
+Source: csxcad
+Section: contrib/libdevel
+Priority: optional
+Maintainer: Sebastian Held <sebastian.held@gmx.de>
+Build-Depends: debhelper (>=7.0.50~), qt4-qmake, libfparser4, libhdf5-serial-dev, libtinyxml-dev, libvtk5-qt4-dev
+
+Package: csxcad
+Architecture: any
+Depends: ${shlibs:Depends}
+Suggests: appcsxcad
+Description: Library for Geometric Primitives primarily used by openEMS
+ Library for Geometric Primitives primarily used by openEMS.
+
+Package: csxcad-dev
+Architecture: any
+Depends: ${shlibs:Depends} csxcad (= ${binary:Version})
+Description: Development files for csxcad
+ The csxcad-dev package contains libraries and header files for developing applications that use csxcad.
diff --git a/CSXCAD/linux/debian.csxcad-dev.install b/CSXCAD/linux/debian.csxcad-dev.install
new file mode 100644
index 0000000..1537de1
--- /dev/null
+++ b/CSXCAD/linux/debian.csxcad-dev.install
@@ -0,0 +1,2 @@
+usr/include/*
+usr/lib/*.so
diff --git a/CSXCAD/linux/debian.csxcad.docs b/CSXCAD/linux/debian.csxcad.docs
new file mode 100644
index 0000000..2e3abae
--- /dev/null
+++ b/CSXCAD/linux/debian.csxcad.docs
@@ -0,0 +1,2 @@
+COPYING
+README
diff --git a/CSXCAD/linux/debian.csxcad.install b/CSXCAD/linux/debian.csxcad.install
new file mode 100644
index 0000000..96f3c01
--- /dev/null
+++ b/CSXCAD/linux/debian.csxcad.install
@@ -0,0 +1,2 @@
+usr/lib/*.so.*
+usr/share/CSXCAD/*
diff --git a/CSXCAD/linux/debian.rules b/CSXCAD/linux/debian.rules
new file mode 100644
index 0000000..a6ec285
--- /dev/null
+++ b/CSXCAD/linux/debian.rules
@@ -0,0 +1,8 @@
+#!/usr/bin/make -f
+
+export DH_VERBOSE=1
+export DH_OPTIONS=-v
+export DH_COMPAT=7
+
+%:
+ dh $@
diff --git a/CSXCAD/linux/debian.series b/CSXCAD/linux/debian.series
new file mode 100644
index 0000000..a16dfed
--- /dev/null
+++ b/CSXCAD/linux/debian.series
@@ -0,0 +1,2 @@
+CSXGeomPlot.m.patch -p1
+README.patch -p1
diff --git a/CSXCAD/matlab/AddBox.m b/CSXCAD/matlab/AddBox.m
new file mode 100644
index 0000000..d07274c
--- /dev/null
+++ b/CSXCAD/matlab/AddBox.m
@@ -0,0 +1,42 @@
+function CSX = AddBox(CSX, propName, prio, start, stop, varargin)
+% function CSX = AddBox(CSX, propName, prio, start, stop, varargin)
+%
+% Add a box to CSX and assign to a property with name <propName>.
+%
+% start: box start coordinates
+% stop : box stop coordinates
+% prio : primitive priority
+%
+% optional:
+% Transformation: perform a transformation on a primitive by adding
+% e.g.: 'Transform', {'Scale','1,1,2','Rotate_X',pi/4,'Translate','0,0,100'}
+% Note: This will only affect the 3D material/metal discretisation
+%
+% example:
+% CSX = AddMetal(CSX,'metal'); %create PEC with propName 'metal'
+% CSX = AddBox(CSX,'metal',10,[0 0 0],[100 100 200]); %assign box
+%
+% with transformation:
+% CSX = AddBox(CSX,'metal',10,[0 0 0],[100 100 200], ...
+% 'Transform', {Rotate_Z, pi/4});
+%
+% See also AddCylinder, AddCylindricalShell, AddSphere, AddSphericalShell,
+% AddCurve, AddWire, AddMetal
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+box.ATTRIBUTE.Priority = prio;
+
+box.P1.ATTRIBUTE.X=start(1);
+box.P1.ATTRIBUTE.Y=start(2);
+box.P1.ATTRIBUTE.Z=start(3);
+
+box.P2.ATTRIBUTE.X=stop(1);
+box.P2.ATTRIBUTE.Y=stop(2);
+box.P2.ATTRIBUTE.Z=stop(3);
+
+box = AddPrimitiveArgs(box,varargin{:});
+
+CSX = Add2Property(CSX,propName, box, 'Box'); \ No newline at end of file
diff --git a/CSXCAD/matlab/AddConductingSheet.m b/CSXCAD/matlab/AddConductingSheet.m
new file mode 100644
index 0000000..f3e79b4
--- /dev/null
+++ b/CSXCAD/matlab/AddConductingSheet.m
@@ -0,0 +1,47 @@
+function CSX = AddConductingSheet(CSX, name, conductivity, thickness)
+%function CSX = AddConductingSheet(CSX, name, conductivity, thickness)
+%
+% Add a conducting sheet property to CSX with the given name.
+% Remember to add at least one or more 2D!! geometrical primitives to this
+% property.
+%
+% Hint:
+% Set the thickness to 0 to fall back to a perfect metal (AddMetal)
+%
+% example:
+% % create the conducting material peroperty, e.g. 40um thick copper
+% CSX = AddConductingSheet(CSX,'copper',56e6,40e-6);
+% % assign box the 2D box --> 40um thick sheet
+% CSX = AddBox(CSX,'copper',10,[0 -50 200],[1000 50 200]);
+%
+% See also AddMaterial, AddMetal, AddExcitation, AddBox
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig 2012
+
+
+% fall back to ideal pec for t==0 or c==0
+if ((thickness==0) || (conductivity==0))
+ CSX = AddMetal(CSX,name);
+ return;
+end
+
+if ((conductivity<0) || (thickness<0))
+ error('CSXCAD:AddConductingSheet','a negative conductivity or thickness is invalid');
+end
+
+if (conductivity<1e6)
+ warning('CSXCAD:AddConductingSheet','a conductivity below 1MA/Vm is not recommended');
+end
+
+if (thickness>500e-6)
+ warning('CSXCAD:AddConductingSheet','a thickness greater than 500um is not recommended');
+end
+
+
+if (thickness<1e-6)
+ warning('CSXCAD:AddConductingSheet','a thickness lower than 1um is not recommended');
+end
+
+CSX = AddProperty(CSX, 'ConductingSheet', name,'Conductivity',conductivity,'Thickness',thickness);
diff --git a/CSXCAD/matlab/AddCurve.m b/CSXCAD/matlab/AddCurve.m
new file mode 100644
index 0000000..2e4e5b2
--- /dev/null
+++ b/CSXCAD/matlab/AddCurve.m
@@ -0,0 +1,44 @@
+function CSX = AddCurve(CSX, propName, prio, points, varargin)
+% function CSX = AddCurve(CSX, propName, prio, points, varargin)
+%
+% Add a curve to CSX and assign to a property with name <propName>.
+%
+% Warning: This is a 1D object, not all properties may be compatible with a
+% 1D object, e.g. a material property.
+%
+% points: curve coordinates array
+% prio : primitive priority
+%
+% example:
+% %first point
+% points(1,1) = 0;
+% points(2,1) = 5;
+% points(3,1) = 10;
+% %second point
+% points(1,2) = 0;
+% points(2,2) = 10;
+% points(3,2) = 10;
+% %third point ...
+% % create a thin metal wire...
+% CSX = AddMetal(CSX,'metal'); %create PEC with propName 'metal'
+% CSX = AddCurve(CSX,'metal',10, points);
+%
+% See also AddBox, AddCylindricalShell, AddCylinder, AddSphere,
+% AddSphericalShell, AddWire, AddMetal
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+curve.ATTRIBUTE.Priority = prio;
+
+curve.Vertex={};
+for s=1:size(points,2)
+ curve.Vertex{end+1}.ATTRIBUTE.X = points(1,s);
+ curve.Vertex{end}.ATTRIBUTE.Y = points(2,s);
+ curve.Vertex{end}.ATTRIBUTE.Z = points(3,s);
+end
+
+curve = AddPrimitiveArgs(curve,varargin{:});
+
+CSX = Add2Property(CSX,propName, curve, 'Curve'); \ No newline at end of file
diff --git a/CSXCAD/matlab/AddCylinder.m b/CSXCAD/matlab/AddCylinder.m
new file mode 100644
index 0000000..1998325
--- /dev/null
+++ b/CSXCAD/matlab/AddCylinder.m
@@ -0,0 +1,35 @@
+function CSX = AddCylinder(CSX, propName, prio, start, stop, rad, varargin)
+% function CSX = AddCylinder(CSX, propName, prio, start, stop, rad, varargin)
+%
+% Add a cylinder to CSX and assign to a property with name <propName>.
+%
+% start: cylinder axis start coordinates
+% stop : cylinder axis box stop coordinates
+% rad : cylinder radius
+% prio : primitive priority
+%
+% example:
+% CSX = AddMetal(CSX,'metal'); %create PEC with propName 'metal'
+% CSX = AddCylinder(CSX,'metal',10,[0 0 0],[0 0 200],50);
+%
+% See also AddBox, AddCylindricalShell, AddSphere, AddSphericalShell,
+% AddCurve, AddWire, AddMetal
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+cylinder.ATTRIBUTE.Priority = prio;
+cylinder.ATTRIBUTE.Radius = rad;
+
+cylinder.P1.ATTRIBUTE.X=start(1);
+cylinder.P1.ATTRIBUTE.Y=start(2);
+cylinder.P1.ATTRIBUTE.Z=start(3);
+
+cylinder.P2.ATTRIBUTE.X=stop(1);
+cylinder.P2.ATTRIBUTE.Y=stop(2);
+cylinder.P2.ATTRIBUTE.Z=stop(3);
+
+cylinder = AddPrimitiveArgs(cylinder,varargin{:});
+
+CSX = Add2Property(CSX,propName, cylinder, 'Cylinder'); \ No newline at end of file
diff --git a/CSXCAD/matlab/AddCylindricalShell.m b/CSXCAD/matlab/AddCylindricalShell.m
new file mode 100644
index 0000000..53ff5f4
--- /dev/null
+++ b/CSXCAD/matlab/AddCylindricalShell.m
@@ -0,0 +1,41 @@
+function CSX = AddCylindricalShell(CSX, propName, prio, start, stop, rad, shell_width, varargin)
+%function CSX = AddCylindricalShell(CSX, propName, prio, start, stop, rad, shell_width, varargin)
+%
+% Add a cylinder shell to CSX and assign to a property with name <propName>.
+%
+% start: cylinder axis start coordinates
+% stop : cylinder axis box stop coordinates
+% rad : cylinder radius
+% shell_width: cylinder shell width
+% prio : primitive priority
+%
+% Note:
+% the inner radius of this shell is rad-shell_width/2
+% the outer radius of this shell is rad+shell_width/2
+%
+% example:
+% CSX = AddMetal(CSX,'metal'); %create PEC with propName 'metal'
+% CSX = AddCylindricalShell(CSX,'metal',10,[0 0 0],[0 0 200],50,10);
+%
+% See also AddBox, AddCylinder, AddSphere, AddSphericalShell,
+% AddCurve, AddWire, AddMetal
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+cylinder.ATTRIBUTE.Priority = prio;
+cylinder.ATTRIBUTE.Radius = rad;
+cylinder.ATTRIBUTE.ShellWidth = shell_width;
+
+cylinder.P1.ATTRIBUTE.X=start(1);
+cylinder.P1.ATTRIBUTE.Y=start(2);
+cylinder.P1.ATTRIBUTE.Z=start(3);
+
+cylinder.P2.ATTRIBUTE.X=stop(1);
+cylinder.P2.ATTRIBUTE.Y=stop(2);
+cylinder.P2.ATTRIBUTE.Z=stop(3);
+
+cylinder = AddPrimitiveArgs(cylinder,varargin{:});
+
+CSX = Add2Property(CSX,propName, cylinder, 'CylindricalShell');
diff --git a/CSXCAD/matlab/AddDebyeMaterial.m b/CSXCAD/matlab/AddDebyeMaterial.m
new file mode 100644
index 0000000..941ffe9
--- /dev/null
+++ b/CSXCAD/matlab/AddDebyeMaterial.m
@@ -0,0 +1,29 @@
+function CSX = AddDebyeMaterial(CSX, name, varargin)
+% function CSX = AddDebyeMaterial(CSX, name, varargin)
+%
+% Add a Debye type dispersive material model.
+%
+% The Debye type frequency dependent material:
+% eps_r(w) = eps_r + sum_p ( eps_r_delta,p / (1+jw*t_relex,p) ) - j*kappa/w
+%
+% with
+% eps_r_delta,p: the delta electric relative permitivity
+% t_relex,p: the electric relaxation time
+%
+% Use SetMaterialProperty to define the material constants:
+% 'EpsilonDelta_p': p-th eps_r_delta,p
+% 'EpsilonRelaxTime_p': p-th t_relex,p
+%
+% example:
+% CSX = AddDebyeMaterial(CSX,'debye');
+% CSX = SetMaterialProperty(CSX,'debye','Epsilon',5,'EpsilonDelta_1',0.1,'EpsilonRelaxTime_1',1e-9);
+% [..]
+% CSX = AddBox(CSX,'debye', 10 ,start,stop);
+%
+% See also AddBox, AddMaterial, SetMaterialProperty, AddLorentzMaterial
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (2013)
+
+CSX = AddProperty(CSX, 'DebyeMaterial', name, varargin{:});
diff --git a/CSXCAD/matlab/AddDiscMaterial.m b/CSXCAD/matlab/AddDiscMaterial.m
new file mode 100644
index 0000000..86f5213
--- /dev/null
+++ b/CSXCAD/matlab/AddDiscMaterial.m
@@ -0,0 +1,47 @@
+function CSX = AddDiscMaterial(CSX, name, varargin)
+% function CSX = AddDiscMaterial(CSX, name, varargin)
+%
+% Add a discretized material model property to CSX with the given name.
+% Discretized model has to be stored in an hdf5 file.
+% Use Transform option to perfom some transformation actions.
+%
+% variable arguments (key/value)
+% 'File' (mandatory): define the filename of the discrete material
+% 'Scale': scale the discrete material
+% e.g. to your drawing units: 'Scale', 1/unit
+% 'Transform': Apply a transformation, see AddBox for more infos
+% 'UseDBBackground': set to 0, to use the properties background material
+% instead of the database material with index 0 (default)
+%
+% examples:
+% %add human body model
+% CSX = AddDiscMaterial(CSX, 'Ella', 'Scale', 1/unit, ...
+% 'Transform', {'Rotate_Z',pi/2,'Translate','300,300,500'}, ...
+% 'File', 'model_file_name.h5' );
+% start = [mesh.x(1) mesh.y(1) mesh.z(1)];
+% stop = [mesh.x(end) mesh.y(end) mesh.z(end)];
+% CSX = AddBox(CSX,'Ella', 0 ,start,stop);
+%
+% See also AddBox, AddMetal, AddExcitation, AddProbe, AddDump
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+transform = [];
+
+for n=1:2:(nargin-2)
+ if (strcmp(varargin{n},'Transform'))
+ transform = varargin([n:n+1]);
+ varargin([n:n+1]) = [];
+ break
+ end
+end
+
+CSX = AddProperty(CSX, 'DiscMaterial', name, varargin{:});
+
+if ~isempty(transform)
+ for n=1:2:numel(transform{2})
+ CSX.Properties.DiscMaterial{end}.Transformation.(transform{2}{n}).ATTRIBUTE.Argument=transform{2}{n+1};
+ end
+end
diff --git a/CSXCAD/matlab/AddDump.m b/CSXCAD/matlab/AddDump.m
new file mode 100644
index 0000000..f454992
--- /dev/null
+++ b/CSXCAD/matlab/AddDump.m
@@ -0,0 +1,87 @@
+function CSX = AddDump(CSX, name, varargin)
+% function CSX = AddDump(CSX, name, varargin)
+%
+% Add a dump property to CSX with the given name.
+%
+% possible arguments for useage with openEMS:
+% DumpType: 0 for E-field time-domain dump (default)
+% 1 for H-field time-domain dump
+% 2 for electric current time-domain dump
+% 3 for total current density (rot(H)) time-domain dump
+%
+% 10 for E-field frequency-domain dump
+% 11 for H-field frequency-domain dump
+% 12 for electric current frequency-domain dump
+% 13 for total current density (rot(H)) frequency-domain dump
+%
+% 20 local SAR frequency-domain dump
+% 21 1g averaging SAR frequency-domain dump
+% 22 10g averaging SAR frequency-domain dump
+%
+% 29 raw data needed for SAR calculations (electric field FD,
+% cell volume, conductivity and density)
+%
+% Frequency: specify a frequency vector (required for dump types >=10)
+%
+% DumpMode: 0 no-interpolation
+% 1 node-interpolation (default, see warning below)
+% 2 cell-interpolation (see warning below)
+%
+% FileType: 0 vtk-file dump (default)
+% 1 hdf5-file dump
+%
+% SubSampling: field domain sub-sampling, e.g. '2,2,4'
+% OptResolution: field domain dump resolution, e.g. '10' or '10,20,5'
+%
+% MultiGridLevel: Request to dump from a multigrid level (default is 0)
+% Note: This only takes effect if the method supports and
+% uses multiple grids!
+%
+% StartTime/StopTime: Define a start and/or stop time (in seconds)
+% for this dump to be active.
+%
+% Warning:
+% FDTD Interpolation abnormalities:
+% - no-interpolation: fields are located in the mesh by the
+% Yee-scheme, the mesh only specifies E- or H-Yee-nodes
+% --> use node- or cell-interpolation or be aware of the offset
+% - E-field dump & node-interpolation: normal electric fields on
+% boundaries will have false amplitude due to forward/backward
+% interpolation in case of (strong) changes in material
+% permittivity or on metal surfaces
+% --> use no- or cell-interpolation
+% - H-field dump & cell-interpolation: normal magnetic fields on
+% boundaries will have false amplitude due to forward/backward
+% interpolation in case of (strong) changes in material permeability
+% --> use no- or node-interpolation
+%
+% e.g. AddDump(CSX,'Et');
+% CSX = AddBox(CSX,'Et',10,[0 0 0],[100 100 200]); %assign box
+%
+% or AddDump(CSX,'Ef',DumpType, 10, 'Frequency',[1e9 2e9]);
+% CSX = AddBox(CSX,'Ef',10,[0 0 0],[100 100 200]); %assign box
+%
+% or AddDump(CSX,'Ht','SubSampling','2,2,4','DumpType',1);
+% CSX = AddBox(CSX,'Ht',10,[0 0 0],[100 100 200]); %assign box
+%
+% See also AddMaterial, AddExcitation, AddProbe, AddMetal, AddBox
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+[CSX pos] = AddProperty(CSX, 'DumpBox', name);
+
+% make Node-Interpolation the default
+CSX.Properties.DumpBox{pos}.ATTRIBUTE.DumpMode = 1;
+
+for n=1:numel(varargin)/2
+ if ~ischar(varargin{2*n-1})
+ error(['CSXCAD::AddDump: not an attribute: ' varargin{2*n-1}]);
+ end
+ if strcmp(varargin{2*n-1},'Frequency')
+ CSX.Properties.DumpBox{pos}.FD_Samples=varargin{2*n};
+ else
+ CSX.Properties.DumpBox{pos}.ATTRIBUTE.(varargin{2*n-1})=varargin{2*n};
+ end
+end
diff --git a/CSXCAD/matlab/AddExcitation.m b/CSXCAD/matlab/AddExcitation.m
new file mode 100644
index 0000000..45a1a2c
--- /dev/null
+++ b/CSXCAD/matlab/AddExcitation.m
@@ -0,0 +1,32 @@
+function CSX = AddExcitation(CSX, name, type, excite, varargin)
+% function CSX = AddExcitation(CSX, name, type, excite, varargin)
+%
+% Creates an E-field or H-field excitation.
+%
+% CSX: CSX-struct created by InitCSX
+% name: property name for the excitation
+% type: 0=E-field soft excitation 1=E-field hard excitation
+% 2=H-field soft excitation 3=H-field hard excitation
+% 10=plane wave excitation
+%
+% excite: e.g. [2 0 0] for excitation of 2 V/m in x-direction
+%
+% additional options for openEMS:
+% 'Delay' : setup an excitation time delay in seconds
+% 'PropDir': direction of plane wave propagation (plane wave excite only)
+%
+% example:
+% CSX = AddExcitation( CSX, 'infDipole', 1, [1 0 0] );
+% start = [-dipole_length/2, 0, 0];
+% stop = [+dipole_length/2, 0, 0];
+% CSX = AddBox( CSX, 'infDipole', 1, start, stop );
+%
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+%
+% See also SetExcitationWeight, AddMetal, AddExcitation, AddProbe,
+% AddDump, AddBox
+
+CSX = AddProperty(CSX, 'Excitation', name, 'Type', type, 'Excite', excite, varargin{:});
diff --git a/CSXCAD/matlab/AddLinPoly.m b/CSXCAD/matlab/AddLinPoly.m
new file mode 100644
index 0000000..b93a4ac
--- /dev/null
+++ b/CSXCAD/matlab/AddLinPoly.m
@@ -0,0 +1,41 @@
+function CSX = AddLinPoly( CSX, materialname, prio, normDir, elevation, points, Length, varargin)
+% CSX = AddLinPoly( CSX, materialname, prio, normDir, elevation, points, Length, varargin)
+%
+% CSX: CSX-object created by InitCSX()
+% materialname: created by AddMetal() or AddMaterial()
+% prio: priority
+% normDir: normal direction of the polygon,
+% e.g. 'x', 'y' or 'z', or numeric 0..2
+% elevation: position of the polygon plane
+% points: two-dimensional coordinates
+% length: linear extrution in normal direction, starting at elevation
+%
+% Warning: Polygon has to be defined using Cartesian Coords
+% for use with cylindrical mesh, set 'CoordSystem',0
+%
+% example:
+% p(1,1) = 0; % x-coord point 1
+% p(2,1) = 0; % y-coord point 1
+% p(1,2) = 10; % x-coord point 2
+% p(2,2) = 20; % y-coord point 2
+% % normal direction: z (2)
+% CSX = AddLinPoly( CSX, 'PEC', 1, 2, 254, p , 10, 'CoordSystem',0)
+%
+% 2011, Thorsten Liebig <thorsten.liebig@gmx.de>
+%
+% See also InitCSX AddMetal AddMaterial AddPolygon AddRotPoly
+
+polygon.ATTRIBUTE.Priority = prio;
+polygon.ATTRIBUTE.Elevation = elevation;
+polygon.ATTRIBUTE.Length = Length;
+polygon.ATTRIBUTE.NormDir = DirChar2Int(normDir);
+
+polygon.Vertex = {};
+for s=1:size(points,2)
+ polygon.Vertex{end+1}.ATTRIBUTE.X1 = points(1,s);
+ polygon.Vertex{end}.ATTRIBUTE.X2 = points(2,s);
+end
+
+polygon = AddPrimitiveArgs(polygon,varargin{:});
+
+CSX = Add2Property( CSX, materialname, polygon, 'LinPoly');
diff --git a/CSXCAD/matlab/AddLorentzMaterial.m b/CSXCAD/matlab/AddLorentzMaterial.m
new file mode 100644
index 0000000..b0e9629
--- /dev/null
+++ b/CSXCAD/matlab/AddLorentzMaterial.m
@@ -0,0 +1,60 @@
+function CSX = AddLorentzMaterial(CSX, name, varargin)
+% function CSX = AddLorentzMaterial(CSX, name, varargin)
+%
+% Add a Drude/Lorentz type dispersive material model.
+% Note: openEMS currently only supports a drude material type.
+%
+% The drude type frequency dependent material:
+% eps_r(f) = eps_r* ( 1 - f_eps_plasma^2/(f*(f-j/t_eps_r)) )
+% mue_r(f) = mue_r* ( 1 - f_mue_plasma^2/(f*(f-j/t_mue_r)) )
+% with
+% f_eps_plasma: the respective electric angular plasma frequency
+% f_mue_plasma: the respective magnetic angular plasma frequency
+% t_eps_r: the respective electric relaxation time
+% t_mue_r: the respective magnetic relaxation time
+%
+% Use SetMaterialProperty to define the material constants:
+% 'EpsilonPlasmaFrequency': electric plasma frequency (f_eps_plasma)
+% 'MuePlasmaFrequency': magnetic plasma frequency (f_mue_plasma)
+% 'EpsilonRelaxTime': electric plasma relaxation time (losses)
+% 'MueRelaxTime': magnetic plasma relaxation time (losses)
+%
+% Note: all properties must be positive values
+%
+% Higher order Drude type:
+% 'EpsilonPlasmaFrequency_<n>': n-th order electric plasma frequency (f_eps_plasma)
+% 'MuePlasmaFrequency_<n>': n-th order magnetic plasma frequency (f_mue_plasma)
+% 'EpsilonRelaxTime_<n>': n-th order electric plasma relaxation time (losses)
+% 'MueRelaxTime_<n>': n-th order magnetic plasma relaxation time (losses)
+%
+% The Lorentz type frequency dependent material:
+% eps_r(f) = eps_r* ( 1 - f_eps_plasma^2/(f^2-f_eps_Lor_Pole^2-jf^2*/t_eps_r)) )
+% mue_r(f) = mue_r* ( 1 - f_mue_plasma^2/(f^2-f_mue_Lor_Pole^2-jf^2*/t_mue_r)) )
+% with the additional parameter (see above)
+% f_eps_Lor_Pole: the respective electric angular lorentz pole frequency
+% f_mue_Lor_Pole: the respective magnetic angular lorentz pole frequency
+%
+% Use SetMaterialProperty to define the material constants:
+% 'EpsilonLorPoleFrequency': electric lorentz pole frequency (f_eps_Lor_Pole)
+% 'MueLorPoleFrequency': magnetic lorentz pole frequency (f_mue_Lor_Pole)
+%
+% Note: all properties must be positive values
+%
+% Higher order Drude type:
+% 'EpsilonLorPoleFrequency_<n>': n-th order electric lorentz pole frequency (f_eps_plasma)
+% 'MueLorPoleFrequency_<n>': n-th order magnetic lorentz pole frequency (f_mue_plasma)
+%
+% example:
+% CSX = AddLorentzMaterial(CSX,'drude');
+% CSX = SetMaterialProperty(CSX,'drude','Epsilon',5,'EpsilonPlasmaFrequency',5e9,'EpsilonRelaxTime',1e-9);
+% CSX = SetMaterialProperty(CSX,'drude','Mue',5,'MuePlasmaFrequency',5e9,'MueRelaxTime',1e-9);
+% [..]
+% CSX = AddBox(CSX,'drude', 10 ,start,stop);
+%
+% See also AddBox, AddMaterial, SetMaterialProperty
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+CSX = AddProperty(CSX, 'LorentzMaterial', name, varargin{:});
diff --git a/CSXCAD/matlab/AddLumpedElement.m b/CSXCAD/matlab/AddLumpedElement.m
new file mode 100644
index 0000000..cefa4c7
--- /dev/null
+++ b/CSXCAD/matlab/AddLumpedElement.m
@@ -0,0 +1,29 @@
+function CSX = AddLumpedElement(CSX, name, direction, varargin)
+% function CSX = AddLumpedElement(CSX, name, direction, varargin)
+%
+% Add a lumped element property to CSX with the given name.
+% Remember to add at least one or more box primitive to any
+% property.
+%
+% arguments:
+% direction: 0,1,2 or 'x','y','z' for the orientation of the lumped element
+%
+% optional arguments:
+% 'R', 'C', 'L': definition of the lumped element properties
+% 'Caps': 0 or 1 to (de)activate lumped element caps (1=default)
+% If Caps are enable, a small PEC plate is added to each
+% end of the lumped element to ensure contact to e.g
+% a microstrip line
+%
+% examples:
+% lumped element capacitor in y-direction with 1pF
+% CSX = AddLumpedElement( CSX, 'Capacitor', 1, 'Caps', 1, 'C', 1e-12 );
+% CSX = AddBox( CSX, 'Capacitor', 0, [0 0 0], [10 10 10] );
+%
+% See also AddMaterial, AddMetal, AddExcitation, AddProbe, AddDump, AddBox
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+CSX = AddProperty(CSX, 'LumpedElement', name, 'Direction', DirChar2Int(direction), varargin{:});
diff --git a/CSXCAD/matlab/AddMaterial.m b/CSXCAD/matlab/AddMaterial.m
new file mode 100644
index 0000000..d21a8c9
--- /dev/null
+++ b/CSXCAD/matlab/AddMaterial.m
@@ -0,0 +1,26 @@
+function CSX = AddMaterial(CSX, name, varargin)
+% function CSX = AddMaterial(CSX, name, varargin)
+%
+% Add a material property to CSX with the given name.
+% Remember to add at least one or more geometrical primitives to any
+% property.
+%
+% Use SetMaterialProperty to define the material constants:
+% 'Epsilon': relative electric permitivity
+% 'Mue': relative magnetic permeability
+% 'Kappa': electric conductivity
+% 'Sigma': magnetc conductivity (non-physical property)
+%
+% examples:
+% CSX = AddMaterial( CSX, 'RO3010' );
+% CSX = SetMaterialProperty( CSX, 'RO3010', 'Epsilon', 10.2, 'Mue', 1 );
+% CSX = AddBox( CSX, 'RO3010', 0, [0 0 0], [100 1000 1000] );
+%
+% See also SetMaterialProperty, SetMaterialWeight, AddMetal, AddExcitation,
+% AddProbe, AddDump, AddBox
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+CSX = AddProperty(CSX, 'Material', name, varargin{:});
diff --git a/CSXCAD/matlab/AddMetal.m b/CSXCAD/matlab/AddMetal.m
new file mode 100644
index 0000000..98ce9d1
--- /dev/null
+++ b/CSXCAD/matlab/AddMetal.m
@@ -0,0 +1,26 @@
+function CSX = AddMetal(CSX, name)
+%function CSX = AddMetal(CSX, name)
+%
+% Add a metal property (PEC) to CSX with the given name.
+% Remember to add at least one or more geometrical primitives to any
+% property.
+%
+% example:
+% CSX = AddMetal(CSX,'metal'); %create PEC with propName 'metal'
+% CSX = AddBox(CSX,'metal',10,[0 0 0],[100 100 200]); %assign box
+%
+% See also AddMaterial, AddExcitation, AddProbe, AddDump, AddBox
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+% check if this property already exists
+[type_found pos] = FindProperty(CSX, name);
+
+% since it has no varargs, accept already existing metal with this name
+if ((pos>0) && strcmp(type_found,'Metal'))
+ return
+end
+
+CSX = AddProperty(CSX, 'Metal', name);
diff --git a/CSXCAD/matlab/AddPlaneWaveExcite.m b/CSXCAD/matlab/AddPlaneWaveExcite.m
new file mode 100644
index 0000000..aa59c02
--- /dev/null
+++ b/CSXCAD/matlab/AddPlaneWaveExcite.m
@@ -0,0 +1,38 @@
+function CSX = AddPlaneWaveExcite(CSX, name, k_dir, E_dir, f0, varargin)
+% function CSX = AddPlaneWaveExcite(CSX, name, k_dir, E_dir, <f0, varargin>)
+%
+% Creates a plane wave excitation in the sense of a total-field/scattered
+% field approach.
+%
+% Note: A plane wave excitation must not intersect with any kind of
+% material. This exctiation type can only be applies in air/vacuum and
+% completely surrounding a structure!!!
+%
+% Note: Only a single Box can be applied to this property!!
+%
+% Arguments
+% CSX: CSX-struct created by InitCSX
+% name: property name for the excitation
+% k_dir: unit vector of wave progation direction
+% E_dir: electric field polarisation vector (must be orthogonal to k_dir)
+% f0: frequency for numerical phase velocity compensation (optional)
+%
+% example:
+% inc_angle = 0 /180*pi; %incident angle on the x-axis
+% k_dir = [cos(inc_angle) sin(inc_angle) 0]; % plane wave direction
+% E_dir = [0 0 1]; % plane wave polarization --> E_z
+% f0 = 500e6; % frequency for numerical phase velocity compensation
+%
+% CSX = AddPlaneWaveExcite(CSX, 'plane_wave', k_dir, E_dir, f0);
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+%
+% See also AddExcitation, AddBox
+
+if (nargin<5)
+ f0 = 0;
+end
+
+CSX = AddExcitation(CSX, name, 10, E_dir, 'PropDir', k_dir, 'Frequency', f0, varargin{:});
diff --git a/CSXCAD/matlab/AddPoint.m b/CSXCAD/matlab/AddPoint.m
new file mode 100644
index 0000000..15af7d4
--- /dev/null
+++ b/CSXCAD/matlab/AddPoint.m
@@ -0,0 +1,14 @@
+function CSX = AddPoint(CSX, propName, prio, pos, varargin)
+% CSX = AddPoint(CSX, propName, prio, pos, varargin)
+%
+% CSXCAD matlab interface
+
+point.ATTRIBUTE.Priority = prio;
+
+point.ATTRIBUTE.X=pos(1);
+point.ATTRIBUTE.Y=pos(2);
+point.ATTRIBUTE.Z=pos(3);
+
+point = AddPrimitiveArgs(point,varargin{:});
+
+CSX = Add2Property(CSX,propName, point, 'Point');
diff --git a/CSXCAD/matlab/AddPolygon.m b/CSXCAD/matlab/AddPolygon.m
new file mode 100644
index 0000000..4590248
--- /dev/null
+++ b/CSXCAD/matlab/AddPolygon.m
@@ -0,0 +1,41 @@
+function CSX = AddPolygon( CSX, materialname, prio, normDir, elevation, points, varargin)
+% CSX = AddPolygon( CSX, materialname, prio, normDir, elevation, points, varargin)
+%
+% CSX: CSX-object created by InitCSX()
+% materialname: created by AddMetal() or AddMaterial()
+% prio: priority
+% normDir: normal direction of the polygon,
+% e.g. 'x', 'y' or 'z', or numeric 0..2
+% elevation: position of the polygon plane
+% points: two-dimensional coordinates
+%
+% Warning: Polygon has to be defined using Cartesian Coords
+% for use with cylindrical mesh, set 'CoordSystem',0
+%
+% example:
+% p(1,1) = 0; % x-coord point 1
+% p(2,1) = 0; % y-coord point 1
+% p(1,2) = 10; % x-coord point 2
+% p(2,2) = 20; % y-coord point 2
+% % normal direction: z (2)
+% CSX = AddPolygon( CSX, 'PEC', 1, 'z', 254, p, 'CoordSystem',0)
+%
+%
+% (c) 2011 Thorsten Liebig <thorsten.liebig@gmx.de>
+% (c) 2010 Sebastian Held <sebastian.held@gmx.de>
+%
+% See also InitCSX AddMetal AddMaterial AddLinPoly AddRotPoly
+
+polygon.ATTRIBUTE.Priority = prio;
+polygon.ATTRIBUTE.Elevation = elevation;
+polygon.ATTRIBUTE.NormDir = DirChar2Int(normDir);
+
+polygon.Vertex = {};
+for s=1:size(points,2)
+ polygon.Vertex{end+1}.ATTRIBUTE.X1 = points(1,s);
+ polygon.Vertex{end}.ATTRIBUTE.X2 = points(2,s);
+end
+
+polygon = AddPrimitiveArgs(polygon,varargin{:});
+
+CSX = Add2Property( CSX, materialname, polygon, 'Polygon');
diff --git a/CSXCAD/matlab/AddPolyhedron.m b/CSXCAD/matlab/AddPolyhedron.m
new file mode 100644
index 0000000..7da8a86
--- /dev/null
+++ b/CSXCAD/matlab/AddPolyhedron.m
@@ -0,0 +1,51 @@
+function CSX = AddPolyhedron(CSX, propName, prio, vertices, faces, varargin)
+% CSX = AddPolyhedron(CSX, propName, prio, vertices, faces, varargin)
+%
+% Add a polyhedron to CSX and assign to a property with name <propName>.
+%
+% prio: primitive priority
+% vertices: cell array of all vertices
+% faces: cell array of all faces
+%
+% Note: - The polyhedron must be a closed surface for 3D discretisation
+% - All faces must contain the vertices in a right-handed order with
+% the normal direction for each face pointing out of the solid
+%
+% optional:
+% Transformation: perform a transformation on a primitive by adding
+% e.g.: 'Transform', {'Scale','1,1,2','Rotate_X',pi/4,'Translate','0,0,100'}
+% Note: This will only affect the 3D material/metal discretisation
+%
+% example:
+% % example tetrahedron
+% vertices{1}=[0 0 0];
+% vertices{2}=[1 0 0];
+% vertices{3}=[0 1 0];
+% vertices{4}=[0 0 1];
+% faces{1}=[0 2 1];
+% faces{2}=[0 1 3];
+% faces{3}=[0 3 2];
+% faces{4}=[1 2 3];
+% CSX = AddMetal( CSX, 'metal' );
+% CSX = AddPolyhedron(CSX, 'metal', 0, vertices, faces);
+%
+%
+% See also AddBox, AddCylinder, AddCylindricalShell, AddSphere, AddSphericalShell,
+% AddCurve, AddWire, AddMetal
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+polyhedron.ATTRIBUTE.Priority = prio;
+
+for n=1:numel(vertices)
+ polyhedron.Vertex{n}=vector2str(vertices{n});
+end
+for n=1:numel(faces)
+ polyhedron.Face{n}=vector2str(faces{n});
+end
+
+polyhedron = AddPrimitiveArgs(polyhedron,varargin{:});
+
+CSX = Add2Property(CSX,propName, polyhedron, 'Polyhedron');
diff --git a/CSXCAD/matlab/AddProbe.m b/CSXCAD/matlab/AddProbe.m
new file mode 100644
index 0000000..2a6692e
--- /dev/null
+++ b/CSXCAD/matlab/AddProbe.m
@@ -0,0 +1,79 @@
+function CSX = AddProbe(CSX, name, type, varargin)
+% function CSX = AddProbe(CSX, name, type, varargin)
+%
+% Add a probe property to CSX with the given name.
+% Remember to add a geometrical primitive to any property.
+%
+% name: name of the property and probe file
+%
+% type: 0 for voltage probing
+% 1 for current probing
+% 2 for E-field probing
+% 3 for H-field probing
+%
+% 10 for waveguide voltage mode matching
+% 11 for waveguide current mode matching
+%
+% all following parameter are optional key/value parameter:
+%
+% weight: weighting factor (default is 1)
+% frequency: dump in the frequency domain at the given samples (in Hz)
+% ModeFunction: A mode function (used only with type 3/4)
+% NormDir: necessary for current probing box with dimension~=2
+% StartTime/StopTime: Define a start and/or stop time (in seconds)
+% for this probe to be active.
+
+% examples:
+% CSX = AddProbe(CSX,'ut1',0); %voltate probe
+% CSX = AddProbe(CSX,'it1',1); %current probe
+%
+% See also ReadUI in the openEMS matlab interface, AddDump,
+% AddExcitation, AddMaterial, AddExcitation, AddProbe, AddBox
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+FD_samples = [];
+ModeFunction = {};
+
+if ~ischar(name)
+ error('CSXCAD::AddProbe: name must be a string');
+end
+
+prop_args = {'Type', type};
+
+for n=1:2:numel(varargin)
+ if (strcmpi(varargin{n},'weight')==1);
+ prop_args{end+1} = 'Weight';
+ prop_args{end+1} = varargin{n+1};
+ elseif (strcmpi(varargin{n},'Frequency')==1);
+ FD_samples = varargin{n+1};
+ elseif (strcmpi(varargin{n},'ModeFunction')==1);
+ ModeFunction = varargin{n+1};
+ elseif (strcmpi(varargin{n},'NormDir')==1);
+ prop_args{end+1} = 'NormDir';
+ prop_args{end+1} = varargin{n+1};
+ elseif (strcmpi(varargin{n},'StartTime')==1);
+ prop_args{end+1} = 'StartTime';
+ prop_args{end+1} = varargin{n+1};
+ elseif (strcmpi(varargin{n},'StopTime')==1);
+ prop_args{end+1} = 'StopTime';
+ prop_args{end+1} = varargin{n+1};
+ else
+ warning('CSXCAD:AddProbe',['variable argument key: "' varargin{n+1} '" unknown']);
+ end
+end
+
+[CSX pos] = AddProperty(CSX, 'ProbeBox', name, prop_args{:});
+
+if (numel(FD_samples)>0)
+ CSX.Properties.ProbeBox{pos}.FD_Samples=FD_samples;
+end
+
+if (numel(ModeFunction)>0)
+ CSX.Properties.ProbeBox{pos}.Attributes.ATTRIBUTE.ModeFunctionX = ModeFunction{1};
+ CSX.Properties.ProbeBox{pos}.Attributes.ATTRIBUTE.ModeFunctionY = ModeFunction{2};
+ CSX.Properties.ProbeBox{pos}.Attributes.ATTRIBUTE.ModeFunctionZ = ModeFunction{3};
+end
+
diff --git a/CSXCAD/matlab/AddPropAttribute.m b/CSXCAD/matlab/AddPropAttribute.m
new file mode 100644
index 0000000..05408f9
--- /dev/null
+++ b/CSXCAD/matlab/AddPropAttribute.m
@@ -0,0 +1,24 @@
+function CSX = AddPropAttribute(CSX, name, att_name, att_value)
+% CSX = AddPropAttribute(CSX, name, att_name, att_value)
+%
+% Add a given attribute (name and value) to the given property
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (c) 2013
+
+type = GetPropertyType(CSX, name);
+
+pos=0;
+for n=1:numel(CSX.Properties.(type))
+ if strcmp(CSX.Properties.(type){n}.ATTRIBUTE.Name, name)
+ pos=n;
+ end
+end
+
+if (pos==0)
+ error('CSXCAD::AddPropAttribute: property not found');
+ return;
+end
+
+CSX.Properties.(type){pos}.Attributes.ATTRIBUTE.(att_name) = att_value;
diff --git a/CSXCAD/matlab/AddRotPoly.m b/CSXCAD/matlab/AddRotPoly.m
new file mode 100644
index 0000000..e694e98
--- /dev/null
+++ b/CSXCAD/matlab/AddRotPoly.m
@@ -0,0 +1,48 @@
+function CSX = AddRotPoly( CSX, materialname, prio, normDir, points, RotAxisDir, angle, varargin)
+% function CSX = AddRotPoly( CSX, materialname, prio, normDir, points, RotAxisDir, angle, varargin)
+%
+% CSX: CSX-object created by InitCSX()
+% materialname: created by AddMetal() or AddMaterial()
+% prio: priority
+% normDir: normal direction of the polygon,
+% e.g. 'x', 'y' or 'z', or numeric 0..2
+% points: two-dimensional coordinates
+% RotAxisDir: direction of the rotational axis
+% e.g. 'x', 'y' or 'z', or numeric 0..2
+% angle (optional): rotational start/stop angle, default is [0 2pi]
+%
+% Warning: Polygon has to be defined using Cartesian Coords
+% for use with cylindrical mesh, set 'CoordSystem',0
+%
+% example:
+% p(1,1) = 0; % x-coord point 1
+% p(2,1) = 0; % y-coord point 1
+% p(1,2) = 10; % x-coord point 2
+% p(2,2) = 20; % y-coord point 2
+% % normal direction: z
+% CSX = AddRotPoly( CSX, 'PEC', 1, 'z', p , 'y');
+%
+% 2011, Thorsten Liebig <thorsten.liebig@gmx.de>
+%
+% See also InitCSX AddMetal AddMaterial AddPolygon
+
+if (nargin<7)
+ angle = [0 2*pi];
+end
+
+polygon.ATTRIBUTE.Priority = prio;
+polygon.ATTRIBUTE.NormDir = DirChar2Int(normDir);
+polygon.ATTRIBUTE.RotAxisDir = DirChar2Int(RotAxisDir);
+
+polygon.Angles.ATTRIBUTE.Start = angle(1);
+polygon.Angles.ATTRIBUTE.Stop = angle(2);
+
+polygon.Vertex = {};
+for s=1:size(points,2)
+ polygon.Vertex{end+1}.ATTRIBUTE.X1 = points(1,s);
+ polygon.Vertex{end}.ATTRIBUTE.X2 = points(2,s);
+end
+
+polygon = AddPrimitiveArgs(polygon,varargin{:});
+
+CSX = Add2Property( CSX, materialname, polygon, 'RotPoly');
diff --git a/CSXCAD/matlab/AddSphere.m b/CSXCAD/matlab/AddSphere.m
new file mode 100644
index 0000000..457142f
--- /dev/null
+++ b/CSXCAD/matlab/AddSphere.m
@@ -0,0 +1,30 @@
+function CSX = AddSphere(CSX, propName, prio, center, rad, varargin)
+% function CSX = AddSphere(CSX, propName, prio, center, rad, varargin)
+%
+% Add a sphere to CSX and assign to a property with name <propName>.
+%
+% center: sphere center coordinates
+% rad : sphere radius
+% prio : primitive priority
+%
+% example:
+% CSX = AddMetal(CSX,'metal'); %create PEC with propName 'metal'
+% CSX = AddSphere(CSX,'metal',10,[0 0 0],50);
+%
+% See also AddBox, AddCylindricalShell, AddCylinder, AddSphericalShell,
+% AddCurve, AddWire, AddMetal
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+sphere.ATTRIBUTE.Priority = prio;
+sphere.ATTRIBUTE.Radius = rad;
+
+sphere.Center.ATTRIBUTE.X=center(1);
+sphere.Center.ATTRIBUTE.Y=center(2);
+sphere.Center.ATTRIBUTE.Z=center(3);
+
+sphere = AddPrimitiveArgs(sphere,varargin{:});
+
+CSX = Add2Property(CSX,propName, sphere, 'Sphere'); \ No newline at end of file
diff --git a/CSXCAD/matlab/AddSphericalShell.m b/CSXCAD/matlab/AddSphericalShell.m
new file mode 100644
index 0000000..3e76cef
--- /dev/null
+++ b/CSXCAD/matlab/AddSphericalShell.m
@@ -0,0 +1,36 @@
+function CSX = AddSphericalShell(CSX, propName, prio, center, rad, shell_width, varargin)
+% function CSX = AddSphericalShell(CSX, propName, prio, center, rad, shell_width, varargin)
+%
+% Add a sphere shell to CSX and assign to a property with name <propName>.
+%
+% center: sphere center coordinates
+% rad : sphere radius
+% shell_width: sphere shell width
+% prio : primitive priority
+%
+% Note:
+% the inner radius of this shell is rad-shell_width/2
+% the outer radius of this shell is rad+shell_width/2
+%
+% example:
+% CSX = AddMetal(CSX,'metal'); %create PEC with propName 'metal'
+% CSX = AddSphericalShell(CSX,'metal',10,[0 0 0],50,10);
+%
+% See also AddBox, AddCylindricalShell, AddCylinder, AddSphere,
+% AddCurve, AddWire, AddMetal
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+sphere.ATTRIBUTE.Priority = prio;
+sphere.ATTRIBUTE.Radius = rad;
+sphere.ATTRIBUTE.ShellWidth = shell_width;
+
+sphere.Center.ATTRIBUTE.X=center(1);
+sphere.Center.ATTRIBUTE.Y=center(2);
+sphere.Center.ATTRIBUTE.Z=center(3);
+
+sphere = AddPrimitiveArgs(sphere,varargin{:});
+
+CSX = Add2Property(CSX,propName, sphere, 'SphericalShell'); \ No newline at end of file
diff --git a/CSXCAD/matlab/AddWire.m b/CSXCAD/matlab/AddWire.m
new file mode 100644
index 0000000..f90843c
--- /dev/null
+++ b/CSXCAD/matlab/AddWire.m
@@ -0,0 +1,46 @@
+function CSX = AddWire(CSX, propName, prio, points, wire_rad, varargin)
+% function CSX = AddWire(CSX, propName, prio, points, wire_rad, varargin)
+%
+% Add a wire to CSX and assign to a property with name <propName>.
+%
+% Warning: This is a 1D object, not all properties may be compatible with a
+% 1D object, e.g. a material property.
+%
+% points: curve coordinates array
+% prio : primitive priority
+% wire_rad: wire radius
+%
+% example:
+% %first point
+% points(1,1) = 0;
+% points(2,1) = 5;
+% points(3,1) = 10;
+% %second point
+% points(1,2) = 0;
+% points(2,2) = 10;
+% points(3,2) = 10;
+% %third point ...
+% % create a metal wire with finite radius...
+% CSX = AddMetal(CSX,'metal'); %create PEC with propName 'metal'
+% CSX = AddCurve(CSX,'metal',10, points, 2);
+%
+% See also AddBox, AddCylindricalShell, AddCylinder, AddSphere,
+% AddSphericalShell, AddCurve, AddMetal
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+wire.ATTRIBUTE.Priority = prio;
+wire.ATTRIBUTE.WireRadius = wire_rad;
+
+wire.Vertex={};
+for s=1:size(points,2)
+ wire.Vertex{end+1}.ATTRIBUTE.X = points(1,s);
+ wire.Vertex{end}.ATTRIBUTE.Y = points(2,s);
+ wire.Vertex{end}.ATTRIBUTE.Z = points(3,s);
+end
+
+wire = AddPrimitiveArgs(wire,varargin{:});
+
+CSX = Add2Property(CSX,propName, wire, 'Wire'); \ No newline at end of file
diff --git a/CSXCAD/matlab/AnalyseMesh.m b/CSXCAD/matlab/AnalyseMesh.m
new file mode 100644
index 0000000..93295c3
--- /dev/null
+++ b/CSXCAD/matlab/AnalyseMesh.m
@@ -0,0 +1,42 @@
+function results = AnalyseMesh(lines)
+% function results = AnalyseMesh(lines)
+%
+% Analyse a given mesh line vector
+%
+% output structure:
+% results.numLines: number of lines
+% results.max_res: max. resolution found
+% results.min_res: min. resolution found
+% results.max_ratio: max. grading ratio found
+% results.homogeneous: true/false for homogeneous mesh
+% results.symmetric: true/false for symmetric mesh
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (C) 2012
+
+results = [];
+
+lines = sort(unique(lines));
+
+if (numel(lines)<=1)
+ warning('CSXCAD:AnalyseMesh', 'more than one line needed to analyse mesh');
+end
+
+diff_lines = diff(lines);
+
+results.numLines = numel(lines);
+
+results.max_res = max(diff_lines);
+results.min_res = min(diff_lines);
+if (results.max_res==results.min_res)
+ results.homogeneous = 1;
+else
+ results.homogeneous = 0;
+end
+
+results.symmetric = CheckSymmtricLines(lines);
+
+ratio_lines = diff_lines(1:end-1)./diff_lines(2:end);
+
+results.max_ratio = max([ratio_lines 1./ratio_lines]);
diff --git a/CSXCAD/matlab/AutoSmoothMeshLines.m b/CSXCAD/matlab/AutoSmoothMeshLines.m
new file mode 100644
index 0000000..e41e261
--- /dev/null
+++ b/CSXCAD/matlab/AutoSmoothMeshLines.m
@@ -0,0 +1,159 @@
+function [lines quality] = AutoSmoothMeshLines( lines, max_res, ratio, varargin)
+% function [lines quality] = AutoSmoothMeshLines( lines, max_res, ratio, varargin)
+%
+% Generate smooth mesh lines by choosing an appropriate algorithm.
+%
+% Currently supported algorithm:
+% SmoothMeshLines, SmoothMeshLines2 and RecursiveSmoothMesh
+%
+% arguments:
+% lines: given fixed lines to create a smooth mesh in between
+% max_res: desired max. resolution
+% ratio: grading ratio: desired neighboring line-delta ratio
+% - default is 1.5
+% - see also 'allowed_max_ratio' argument
+%
+% variable arguments ('keyword',value):
+% algorithm: define subset of tried algorihm, e.g. [1 3]
+% symmetric: 0/1 force symmetric mesh (default is input symmetry)
+% homogeneous: 0/1 force homogeneous mesh
+% allowed_min_res: allow a given min resolution only
+% allowed_max_ratio: allow only a given max. grading ratio
+% (default --> ratio*1.25)
+% debug: 0/1 off/on
+%
+% example:
+% lines = AutoSmoothMeshLines([-100 -10 10 100], 20, 1.5, 'algorihm', ...
+% 1:3);
+%
+% See also InitCSX, DefineRectGrid
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (C) 2012
+
+if (nargin<2)
+ error('CSXCAD:AutoSmoothMeshLines','lines and max_res are a required parameter');
+end
+
+if (nargin<3)
+ ratio = 1.5;
+end
+
+lines = sort(unique(lines));
+
+range = lines(end)-lines(1);
+if (~isempty(find(diff(lines)<range*1e-6)))
+ warning('CSXCAD:AutoSmoothMeshLines','some lines found with very small distance which may cause smoothing failure!');
+end
+
+methods = {};
+methods{end+1} = @SmoothMeshLines;
+methods{end+1} = @SmoothMeshLines2;
+methods{end+1} = @RecursiveSmoothMesh;
+
+requires_homogen = 0;
+requires_symmetric = CheckSymmtricLines(lines);
+allowed_min_res = 0;
+debug = 0;
+max_ratio = ratio*1.25;
+
+algorithm = 1:numel(methods);
+
+for vn=1:2:numel(varargin)
+ if (strcmpi(varargin{vn},'algorithm'))
+ algorithm = intersect(varargin{vn+1},algorithm);
+ end
+ if (strcmpi(varargin{vn},'symmetric'))
+ requires_symmetric = varargin{vn+1};
+ end
+ if (strcmpi(varargin{vn},'homogeneous'))
+ requires_homogen = varargin{vn+1};
+ end
+ if (strcmpi(varargin{vn},'force_min_res'))
+ requires_homogen = varargin{vn+1};
+ end
+ if (strcmpi(varargin{vn},'allowed_min_res'))
+ allowed_min_res = varargin{vn+1};
+ end
+ if (strcmpi(varargin{vn},'allowed_max_ratio'))
+ max_ratio = varargin{vn+1};
+ end
+ if (strcmpi(varargin{vn},'debug'))
+ debug = varargin{vn+1};
+ end
+end
+
+for m=algorithm
+ if (debug>0)
+ disp(['AutoSmoothMeshLines: trying method: ' func2str(methods{m})]);
+ tic
+ end
+ out_lines{m} = methods{m}(lines, max_res, ratio, 'CheckMesh', false);
+ if (debug>0)
+ toc
+ end
+ quality(m) = eval_mesh(out_lines{m}, max_res, max_ratio, requires_homogen, requires_symmetric, allowed_min_res, 1);
+ if (quality(m)==100) % uncomment to release!
+ lines = out_lines{m};
+ if (debug>0)
+ disp(['AutoSmoothMeshLines: The winner with 100% is ' func2str(methods{m})]); % remove to release
+ end
+ return
+ end
+end
+winner = find(quality==max(quality),1);
+lines = out_lines{winner};
+if (debug>0)
+ disp(['New_SmoothMeshLines: The winner with ' num2str(quality(winner)) '% is ' func2str(methods{winner})]); % remove to release
+end
+
+% show mesh problems
+eval_mesh(lines, max_res, ratio, requires_homogen, requires_symmetric, allowed_min_res, 0);
+return
+
+error('CSXCAD:AutoSmoothMeshLines',['unknown algorithm requested: ' algorithm ]);
+
+end
+
+function quality = eval_mesh(lines, max_res, ratio, requires_homogen, requires_symmetric, allowed_min_res, silent)
+
+quality = 100;
+
+results = AnalyseMesh(lines);
+if ((requires_homogen==1) && (results.homogeneous~=1))
+ if (silent==0)
+ warning('CSXCAD:AutoSmoothMeshLines','method failed to create homogenous mesh');
+ end
+ quality = -1;
+ return
+end
+if ((requires_symmetric==1) && (results.symmetric~=1))
+ if (silent==0)
+ warning('CSXCAD:AutoSmoothMeshLines','method failed to create symmetric mesh');
+ end
+ quality = -1;
+ return
+end
+
+if ((allowed_min_res>0) && (results.min_res<allowed_min_res))
+ if (silent==0)
+ warning('CSXCAD:AutoSmoothMeshLines','method failed to obey allowed min res!');
+ end
+ quality = -1;
+ return
+end
+
+if (results.max_res>max_res*1.01)
+ if (silent==0)
+ warning('CSXCAD:AutoSmoothMeshLines',['method failed to fulfill max. res: ' num2str(results.max_res) ' > ' num2str(max_res)]);
+ end
+ quality = quality*(max_res/results.max_res);
+end
+if (results.max_ratio>ratio*1.01)
+ if (silent==0)
+ warning('CSXCAD:AutoSmoothMeshLines',['method failed to fulfill the max. ratio: ' num2str(results.max_ratio) ' > ' num2str(ratio)]');
+ end
+ quality = quality*(ratio/results.max_ratio);
+end
+end \ No newline at end of file
diff --git a/CSXCAD/matlab/CSXGeomPlot.m b/CSXCAD/matlab/CSXGeomPlot.m
new file mode 100644
index 0000000..df33c94
--- /dev/null
+++ b/CSXCAD/matlab/CSXGeomPlot.m
@@ -0,0 +1,43 @@
+function CSXGeomPlot(CSX_filename, args_string)
+% function CSXGeomPlot(CSX_filename<, args_string>)
+%
+% Show the geometry stored in the CSX file using AppCSXCAD
+%
+% Optional AppCSXCAD arguments (args_string):
+% '--RenderDiscMaterial', enable material rendering
+%
+% exports:
+% '--export-polydata-vtk=<path-for-export>'
+% '--export-STL=<path-for-export>'
+%
+% See also InitCSX, DefineRectGrid
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+if nargin < 1
+ error 'specify the xml file to open'
+end
+
+if nargin < 2
+ args_string = '';
+end
+
+filename = mfilename('fullpath');
+dir = fileparts( filename );
+
+if isunix
+ AppCSXCAD_bin = searchBinary('AppCSXCAD.sh', ...
+ {[dir filesep '..' filesep '..' filesep 'AppCSXCAD' filesep], ...
+ [dir filesep '..' filesep '..' filesep '..' filesep 'bin' filesep]});
+else % assume windows
+ AppCSXCAD_bin = searchBinary('AppCSXCAD.exe',[dir filesep '..' filesep]);
+end
+
+command = [AppCSXCAD_bin ' --disableEdit ' args_string ' ' CSX_filename];
+disp( ['invoking AppCSXCAD, exit to continue script...'] );
+if isOctave()
+ fflush(stdout);
+end
+system(command);
diff --git a/CSXCAD/matlab/CalcDebyeMaterial.m b/CSXCAD/matlab/CalcDebyeMaterial.m
new file mode 100644
index 0000000..a4a3a5e
--- /dev/null
+++ b/CSXCAD/matlab/CalcDebyeMaterial.m
@@ -0,0 +1,29 @@
+function eps_debye = CalcDebyeMaterial(f, eps_r, kappa, eps_Delta, t_relax)
+% eps_debye = CalcDebyeMaterial(f, eps_r, kappa, eps_Delta, t_relax)
+%
+% Calculate the Debye type dispersive material constant
+%
+% arguments:
+% f: frequeny range of interest
+% eps_r: eps_r infinity
+% kappa: conductivity (losses)
+% eps_Delta: (vector) delta of relative permitivity
+% t_relax: (vector) relaxation time (losses)
+%
+% return:
+% eps_debye: the complex relative permitivity
+%
+% See also: CalcLorentzMaterial
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (2013)
+
+EPS0 = 8.85418781762e-12;
+eps_debye = ones(size(f))*eps_r - 1j*kappa./(2*pi*f)/EPS0;
+
+for n=1:numel(eps_Delta)
+ eps_debye = eps_debye + eps_Delta(n)./(1+2j*pi*f*t_relax(n));
+end
+
+end
diff --git a/CSXCAD/matlab/CalcDrudeMaterial.m b/CSXCAD/matlab/CalcDrudeMaterial.m
new file mode 100644
index 0000000..9901566
--- /dev/null
+++ b/CSXCAD/matlab/CalcDrudeMaterial.m
@@ -0,0 +1,37 @@
+function eps_drude = CalcDrudeMaterial(f, eps_r, kappa, plasmaFreq, t_relax)
+% eps_drude = CalcDrudeMaterial(f, eps_r, kappa, plasmaFreq, t_relax)
+%
+% Calculate the Drude type dispersive material constant
+%
+% arguments:
+% f: frequeny range of interest
+% eps_r: eps_r infinity
+% kappa: conductivity (losses)
+% plasmaFreq: (vector) plasma frequencies
+% t_relax: (vector) relaxation time (losses)
+%
+% return:
+% eps_drude: the complex relative permitivity
+%
+% Example:
+% % silver (AG) at optical frequencies (Drude model) [1, p. 201]
+% f = linspace(300e12, 1100e12, 201);
+% eps_model = CalcDrudeMaterial(f, 3.942, 7.97e3, 7e15/2/pi, 0, 1/2.3e13);
+%
+% figure
+% plot(f,real(eps_model))
+% hold on;
+% grid on;
+% plot(f,imag(eps_model),'r--')
+%
+% See also: CalcDebyeMaterial, CalcLorentzMaterial
+%
+% [1] Rennings, Andre: "Elektromagnetische Zeitbereichssimulationen
+% innovativer Antennen auf Basis von Metamaterialien."
+% PhD Thesis, University of Duisburg-Essen, September 2008
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (2013)
+
+eps_drude = CalcLorentzMaterial(f, eps_r, kappa, plasmaFreq, plasmaFreq*0, t_relax);
diff --git a/CSXCAD/matlab/CalcLorentzMaterial.m b/CSXCAD/matlab/CalcLorentzMaterial.m
new file mode 100644
index 0000000..2785747
--- /dev/null
+++ b/CSXCAD/matlab/CalcLorentzMaterial.m
@@ -0,0 +1,61 @@
+function eps_lorentz = CalcLorentzMaterial(f, eps_r, kappa, plasmaFreq, LorPoleFreq, t_relax)
+% eps_lorentz = CalcLorentzMaterial(f, eps_r, kappa, plasmaFreq, LorPoleFreq, t_relax)
+%
+% Calculate the Lorentz type dispersive material constant
+%
+% arguments:
+% f: frequeny range of interest
+% eps_r: eps_r infinity
+% kappa: conductivity (losses)
+% plasmaFreq: (vector) plasma frequencies (Drude model)
+% LorPoleFreq: (vector) Lorentz pole frequencies (zero for pure Drude model)
+% t_relax: (vector) relaxation time (losses)
+%
+% return:
+% eps_lorentz: the complex relative permitivity
+%
+% Example:
+% % silver (AG) at optical frequencies (Drude model) [1, p. 201]
+% f = linspace(300e12, 1100e12, 201);
+% eps_model = CalcLorentzMaterial(f, 3.942, 7.97e3, 7e15/2/pi, 0, 1/2.3e13);
+%
+% figure
+% plot(f,real(eps_model))
+% hold on;
+% grid on;
+% plot(f,imag(eps_model),'r--')
+%
+% % silver (AG) at optical frequencies (Drude+Lorentz model) [1, p. 201]
+% f = linspace(300e12, 1100e12, 201);
+% eps_model = CalcLorentzMaterial(f, 1.138, 4.04e3, [13e15 9.61e15]/2/pi, [0 7.5e15]/2/pi,[1/2.59e13 1/3e14]);
+%
+% figure
+% plot(f,real(eps_model))
+% hold on;
+% grid on;
+% plot(f,imag(eps_model),'r--')
+%
+% See also: CalcDebyeMaterial
+%
+% [1] Rennings, Andre: "Elektromagnetische Zeitbereichssimulationen
+% innovativer Antennen auf Basis von Metamaterialien."
+% PhD Thesis, University of Duisburg-Essen, September 2008
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (2013)
+
+EPS0 = 8.85418781762e-12;
+eps_lorentz = ones(size(f))*eps_r - 1j*kappa./(2*pi*f)/EPS0;
+
+w = 2*pi*f;
+for n=1:numel(plasmaFreq)
+ if (t_relax(n)>0)
+ w_r = 1/t_relax(n);
+ else
+ w_r = 0;
+ end
+ eps_lorentz = eps_lorentz - eps_r*(2*pi*plasmaFreq(n))^2./(w.^2 - (2*pi*LorPoleFreq(n))^2 - 2j*pi*f*w_r);
+end
+
+end
diff --git a/CSXCAD/matlab/CheckMesh.m b/CSXCAD/matlab/CheckMesh.m
new file mode 100644
index 0000000..68cac0b
--- /dev/null
+++ b/CSXCAD/matlab/CheckMesh.m
@@ -0,0 +1,65 @@
+function [EC pos E_type] = CheckMesh(lines, min_res, max_res, ratio, be_quiet)
+% function [EC pos E_type] = CheckMesh(lines, min_res, max_res, ratio, be_quiet)
+%
+% Check if mesh lines are valid
+%
+% parameter:
+% min_res: minimal allowed mesh-diff
+% max_res: maximal allowed mesh-diff
+% ratio: maximal allowed mesh-diff ratio
+% be_quiet: disable warnings
+%
+% return:
+% EC: error code (number of found errors)
+% pos: line positions with error
+% E_type: error type
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+if (nargin<5)
+ be_quiet = 0;
+end
+
+diff_lines = diff(lines);
+EC = 0;
+E_type = [];
+
+pos = [];
+max_err = find(diff_lines>max_res);
+if (~isempty(max_err) && ~be_quiet)
+ warning('CSXCAD:CheckMesh','found resolution larger than max_res');
+ pos = [pos max_err];
+ EC = EC + numel(max_err);
+ E_type = [E_type 1];
+end
+
+min_err = find(diff_lines<min_res);
+if (~isempty(min_err) && ~be_quiet)
+ warning('CSXCAD:CheckMesh','found resolution smaller than min_res');
+ pos = [pos min_err];
+ EC = EC + numel(min_err);
+ E_type = [E_type 2];
+end
+
+for n=1:numel(diff_lines)-1
+ if (diff_lines(n+1)/diff_lines(n) > ratio*1.01)
+ str = ['lines: ' num2str(n) '@' num2str(lines(n)) ' ' num2str(n+1) '@' num2str(lines(n+1)) ' ' num2str(n+2) '@' num2str(lines(n+2))];
+ if (~be_quiet)
+ warning('CSXCAD:CheckMesh', [str '\nfound resolution increase larger than ratio: ' num2str(diff_lines(n+1)/diff_lines(n)) ' > ' num2str(ratio) ]);
+ end
+ pos = [pos n+1];
+ EC = EC + 1;
+ E_type = [E_type 3];
+ end
+ if (diff_lines(n+1)/diff_lines(n) < 1/ratio/1.01)
+ str = ['lines: ' num2str(n) '@' num2str(lines(n)) ' ' num2str(n+1) '@' num2str(lines(n+1)) ' ' num2str(n+2) '@' num2str(lines(n+2))];
+ if (~be_quiet)
+ warning('CSXCAD:SmoothRange', [str '\nfound resolution decrease smaller than ratio: ' num2str(diff_lines(n+1)/diff_lines(n)) ' < 1/' num2str(ratio) '=' num2str(1/ratio) ]);
+ end
+ pos = [pos n];
+ EC = EC + 1;
+ E_type = [E_type 4];
+ end
+end
diff --git a/CSXCAD/matlab/Convert_VF_DiscMaterial.m b/CSXCAD/matlab/Convert_VF_DiscMaterial.m
new file mode 100644
index 0000000..5d78451
--- /dev/null
+++ b/CSXCAD/matlab/Convert_VF_DiscMaterial.m
@@ -0,0 +1,255 @@
+function Convert_VF_DiscMaterial(raw_filesuffix, mat_db_file, out_filename, varargin)
+% function Convert_VF_DiscMaterial(raw_filesuffix, mat_db_file, out_filename, varargin)
+%
+% function to convert the virtual family raw voxel data to a disc material
+% property required by CSXCAD/openEMS
+%
+% Note: The conversion is (currently) done, converting the broad-band data
+% into a relative permittivity and conductivity for a given frequency of
+% interest. Thus the converted model is only valid within a small frequency
+% range around the used conversion frequency.
+%
+% required arguments:
+% raw_filesuffix: suffix for the virtual family body model files
+% the files:
+% <raw_filesuffix>.txt and <raw_filesuffix>.raw
+% must be found!
+% example: '/tmp/Ella_26y_V2_1mm'
+% mat_db_file: tissue database file (incl. full path if necessary)
+% example: '/tmp/DB_h5_20120711_SEMCADv14.8.h5'
+% out_filename: outfile name, e.g. 'Ella_298MHz.h5'
+%
+% variable arguments (key/value):
+% 'Frequency': specifiy the frequency of interest (required!)
+% 'Center': 0/1 make the model centered around (0,0,0)
+% (default is off)
+%
+% Requirements:
+% - Matlab, Octave is currently not supported due to missing hdf5 write
+% functions
+% - ~6GB of RAM to convert the largest voxel model
+% - Virtual Family voxel models
+% e.g. Duke_34y_V5_1mm.raw and .txt
+% See http://www.itis.ethz.ch/itis-for-health/virtual-population/overview/
+% - Virtual Family tissue database
+% e.g. DB_h5_20120711_SEMCADv14.8.h5
+% Download from: http://www.itis.ethz.ch/assets/Downloads/TissueDb/DBh5_20120711_SEMCADv14.8.zip
+%
+% example:
+% Convert_VF_DiscMaterial('/tmp/Ella_26y_V2_1mm', ...
+% '/tmp/DB_h5_20120711_SEMCADv14.8.h5', ...
+% 'Ella_centered_298MHz.h5', ...
+% 'Frequency', 2.4e9);
+%
+% (c) 2013 Thorsten Liebig
+
+if exist(out_filename,'file')
+ disp(['requested model file: "' out_filename '" already exists, skipping']);
+ return
+end
+
+%% default settings
+center_Model = 0; % make the model centered around (0,0,0)
+freq = nan; % frequency of interest
+range = {[],[],[]};
+
+% internal
+range_used = 0;
+
+for n=1:2:numel(varargin)
+ if (strcmp(varargin{n},'Frequency'))
+ freq = varargin{n+1};
+ elseif (strcmp(varargin{n},'Center'))
+ center_Model = varargin{n+1};
+ elseif (strcmp(varargin{n},'Range'))
+ range = varargin{n+1};
+ range_used = 1;
+ else
+ warning('CSXCAD:Convert_VF_DiscMaterial',['unknown argument: ' varagin{n}]);
+ end
+end
+
+if (isnan(freq))
+ error('CSXCAD:Convert_VF_DiscMaterial','a frequency of interest must be specified');
+end
+
+%% end of settings (do not edit below)
+physical_constants
+w = 2*pi*freq;
+
+%%
+disp(['reading raw body specs: ' raw_filesuffix '.txt']);
+fid = fopen([raw_filesuffix '.txt']);
+material_list = textscan(fid,'%d %f %f %f %s');
+
+frewind(fid)
+feof(fid);
+while ~feof(fid)
+ line = fgetl(fid);
+ if strcmp(line,'Grid extent (number of cells)')
+ n_cells = textscan(fid,'n%c %f');
+ end
+ if strcmp(line,'Spatial steps [m]')
+ d_cells = textscan(fid,'d%c %f');
+ end
+end
+
+fclose(fid);
+
+nx = n_cells{2}(1);
+ny = n_cells{2}(2);
+nz = n_cells{2}(3);
+
+disp(['body model contains ' num2str(nx*ny*nz) ' voxels']);
+
+dx = d_cells{2}(1);
+dy = d_cells{2}(2);
+dz = d_cells{2}(3);
+
+%
+x = (0:nx)*dx;
+y = (0:ny)*dy;
+z = (0:nz)*dz;
+
+if (center_Model>0)
+ disp('centering model...');
+ x = x - x(1) - (max(x)-min(x))/2;
+ y = y - y(1) - (max(y)-min(y))/2;
+ z = z - z(1) - (max(z)-min(z))/2;
+end
+
+disp('Body model mesh range (original):');
+disp(['x: ' num2str(x(1)) ' --> ' num2str(x(end)) ', width: ' num2str(max(x)-min(x))]);
+disp(['y: ' num2str(y(1)) ' --> ' num2str(y(end)) ', width: ' num2str(max(y)-min(y))]);
+disp(['z: ' num2str(z(1)) ' --> ' num2str(z(end)) ', width: ' num2str(max(z)-min(z))]);
+
+%% map to range
+if (isempty(range{1}))
+ x_idx = 1:nx;
+else
+ x_idx = find(x>=range{1}(1) & x<=range{1}(2));
+end
+
+if (isempty(range{2}))
+ y_idx = 1:ny;
+else
+ y_idx = find(y>=range{2}(1) & y<=range{2}(2));
+end
+
+if (isempty(range{3}))
+ z_idx = 1:nz;
+else
+ z_idx = find(z>=range{3}(1) & z<=range{3}(2));
+end
+
+tic
+disp(['reading raw body data: ' raw_filesuffix '.raw']);
+fid = fopen([raw_filesuffix '.raw']);
+
+skip=(z(z_idx(1))-z(1))/dz*nx*ny;
+fseek(fid,skip,'bof');
+
+% read in line by line to save memory
+for n=1:length(z_idx)
+ data_plane = reshape(fread(fid,nx*ny),nx,ny);
+ mat(1:numel(x_idx),1:numel(y_idx),n) = uint8(data_plane(x_idx,y_idx));
+end
+fclose(fid);
+
+% resize to range
+x = x(x_idx);x=[x x(end)+dx];
+y = y(y_idx);y=[y y(end)+dx];
+z = z(z_idx);z=[z z(end)+dx];
+
+if (range_used)
+ disp('Body model mesh range (new):');
+ disp(['x: ' num2str(x(1)) ' --> ' num2str(x(end)) ', width: ' num2str(max(x)-min(x))]);
+ disp(['y: ' num2str(y(1)) ' --> ' num2str(y(end)) ', width: ' num2str(max(y)-min(y))]);
+ disp(['z: ' num2str(z(1)) ' --> ' num2str(z(end)) ', width: ' num2str(max(z)-min(z))]);
+end
+
+nx = numel(x_idx);
+ny = numel(y_idx);
+nz = numel(z_idx);
+
+mesh.x=x;
+mesh.y=y;
+mesh.z=z;
+
+toc
+
+%%
+disp(['reading/analysing material database: ' mat_db_file]);
+
+mat_db_info = h5info(mat_db_file);
+
+%%
+% there is no material in the list for number 0
+mat_db.epsR(1) = 1;
+mat_db.kappa(1) = 0;
+mat_db.density(1) = 0;
+mat_db.Name{1} = 'Background';
+
+for n=1:numel(material_list{end})
+ mat_para = GetColeData(mat_db_info, material_list{end}{n});
+ eps_colo_cole = mat_para.ef + mat_para.sig/(1j*w*EPS0);
+ if (mat_para.del1>0)
+ eps_colo_cole = eps_colo_cole + mat_para.del1/(1 + (1j*w*mat_para.tau1*1e-12)^(1-mat_para.alf1));
+ end
+ if (mat_para.del2>0)
+ eps_colo_cole = eps_colo_cole + mat_para.del2/(1 + (1j*w*mat_para.tau2*1e-9)^(1-mat_para.alf2));
+ end
+ if (mat_para.del3>0)
+ eps_colo_cole = eps_colo_cole + mat_para.del3/(1 + (1j*w*mat_para.tau3*1e-6)^(1-mat_para.alf3));
+ end
+ if (mat_para.del4>0)
+ eps_colo_cole = eps_colo_cole + mat_para.del4/(1 + (1j*w*mat_para.tau4*1e-3)^(1-mat_para.alf4));
+ end
+ mat_db.epsR(n+1) = real(eps_colo_cole);
+ mat_db.kappa(n+1) = -1*imag(eps_colo_cole)*w*EPS0;
+ mat_db.density(n+1) = mat_para.Dens;
+ mat_db.Name{n+1} = mat_para.Name;
+end
+toc
+%%
+
+disp(['Creating DiscMaterial file: ' out_filename]);
+CreateDiscMaterial(out_filename, mat, mat_db, mesh)
+toc
+
+disp('done..');
+
+end
+
+function [mat_para] = GetColeData(mat_db, mat_name)
+
+% search for mat_name in all "AlternNames"
+
+N_grp = numel(mat_db.Groups(1).Groups);
+
+mat_name = regexp(mat_name, '/','split');
+mat_name = mat_name{end};
+
+for n=1:N_grp
+ found = false;
+ name = regexp(mat_db.Groups(1).Groups(n).Name, '/','split');
+ alt_names = [name(end) regexp(mat_db.Groups(1).Groups(n).Attributes(end).Value, '/','split')];
+
+ alt_names = regexprep(alt_names,' ','_');
+
+ if (sum(strcmpi(alt_names, mat_name))>0)
+ % we found it, break
+ found = true;
+ break;
+ end
+end
+
+if (found==false)
+ error(['property "' mat_name '" not found']);
+end
+
+for a = 1:numel(mat_db.Groups(1).Groups(n).Attributes)
+ mat_para.(mat_db.Groups(1).Groups(n).Attributes(a).Name) = mat_db.Groups(1).Groups(n).Attributes(a).Value;
+end
+
+end
diff --git a/CSXCAD/matlab/CreateDiscMaterial.m b/CSXCAD/matlab/CreateDiscMaterial.m
new file mode 100644
index 0000000..f874230
--- /dev/null
+++ b/CSXCAD/matlab/CreateDiscMaterial.m
@@ -0,0 +1,83 @@
+function CreateDiscMaterial(filename, data, mat_db, mesh)
+% function CreateDiscMaterial(filename, data, mat_db, mesh)
+%
+% Create the discrete material hdf5 file (version 2) usable by AddDiscMaterial
+%
+% Note: This function currently requires Matlab. Octave is missing the
+% necessary hdf5 write functions.
+%
+% arguments:
+% filename: hdf5 file to create (must not exist)
+% data: voxel based index data, index as used in mat_db-1
+% mat_db: material database
+% mesh: used voxel mesh. Note size is size(data)+[1 1 1]
+%
+% example:
+% mat_db.epsR = [1 3 4]; %relative permittivity
+% mat_db.kappa = [0 0.2 0.4]; %electric conductivity (S/m)
+% mat_db.density = [0 1000 1010]; %material density (kg/m³)
+% mat_db.Name = {'Background','mat2','mat3'};
+%
+% data = [0 1 0; 2 1 2; 0 1 0]; % 3x3x3 data
+% mesh.x = [0 0.1 0.2 0.3]; % 4 mesh lines in x-dir (3 cells)
+% mesh.y = [-0.1 0 0.1 0.2]; % 4 mesh lines in y-dir (3 cells)
+% mesh.z = [0 0.4 0.8 1.2]; % 4 mesh lines in z-dir (3 cells)
+%
+% CreateDiscMaterial('test_mat.h5', data, mat_db, mesh);
+%
+% See also AddDiscMaterial
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (2013)
+
+if isOctave
+ error('CreateDiscMaterial currently does not support Octave, due to missing hdf5 functions!');
+end
+
+if (exist('h5create')==0)
+ error('CSXCAD:CreateDiscMaterial','Your matlab seems to be too old, h5create cannot be found!');
+end
+
+data_size = size(data);
+mesh_size = [numel(mesh.x) numel(mesh.y) numel(mesh.z)];
+
+if ((mesh_size-1)~=data_size)
+ error('data size and mesh size mismatch');
+end
+
+if (exist(filename,'file'))
+ error(['file "' filename '" already exist. Delete/rename first!']);
+end
+
+h5create(filename, '/DiscData',data_size, 'Datatype', 'uint8', 'ChunkSize',data_size, 'Deflate',9);
+h5write(filename, '/DiscData', data);
+
+clear data;
+
+h5writeatt(filename, '/DiscData', 'DB_Size', int32(numel(mat_db.epsR)));
+
+h5writeatt(filename, '/DiscData', 'epsR', mat_db.epsR);
+h5writeatt(filename, '/DiscData', 'kappa', mat_db.kappa);
+h5writeatt(filename, '/DiscData', 'density', mat_db.density);
+h5writeatt(filename, '/DiscData', 'Name', strjoin(mat_db.Name,','));
+
+h5create(filename, '/mesh/x', mesh_size(1));
+h5write(filename, '/mesh/x', mesh.x);
+
+h5create(filename, '/mesh/y', mesh_size(2));
+h5write(filename, '/mesh/y', mesh.y);
+
+h5create(filename, '/mesh/z', mesh_size(3));
+h5write(filename, '/mesh/z', mesh.z);
+
+h5writeatt(filename, '/', 'Version', 2);
+
+
+
+function out = strjoin(names, delimitier)
+
+out = names{1};
+for n=2:numel(names)
+ out = [out delimitier names{n}];
+end
diff --git a/CSXCAD/matlab/DefineRectGrid.m b/CSXCAD/matlab/DefineRectGrid.m
new file mode 100644
index 0000000..efc8a41
--- /dev/null
+++ b/CSXCAD/matlab/DefineRectGrid.m
@@ -0,0 +1,50 @@
+function CSX = DefineRectGrid(CSX, deltaUnit, mesh)
+% function CSX = DefineRectGrid(CSX, deltaUnit, mesh);
+%
+% Create a rectiliniear grid.
+%
+% example Cartesian mesh:
+% CSX = InitCSX();
+% mesh.x = AutoSmoothMeshLines([0 a], 10);
+% mesh.y = AutoSmoothMeshLines([0 b], 10);
+% mesh.z = AutoSmoothMeshLines([0 length], 15);
+% CSX = DefineRectGrid(CSX, unit,mesh);
+%
+% example Cylindrical mesh:
+% CSX = InitCSX('CoordSystem',1);
+% mesh.r = AutoSmoothMeshLines([0 a], 10);
+% mesh.a = AutoSmoothMeshLines([0 2*pi], pi/30);
+% mesh.z = AutoSmoothMeshLines([-length 0 length], 15);
+% CSX = DefineRectGrid(CSX, unit,mesh);
+%
+% See also InitCSX, SmoothMesh, AutoSmoothMeshLines, DetectEdges
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+CSX.RectilinearGrid.ATTRIBUTE.DeltaUnit = deltaUnit;
+
+if (isfield(CSX,'ATTRIBUTE'))
+ if (isfield(CSX.ATTRIBUTE,'CoordSystem'))
+ CSX.RectilinearGrid.ATTRIBUTE.CoordSystem = CSX.ATTRIBUTE.CoordSystem;
+ end
+end
+
+if (isfield(mesh,'x'))
+ CSX.RectilinearGrid.XLines = mesh.x;
+elseif ( (isfield(mesh,'r')) && (CSX.ATTRIBUTE.CoordSystem==1))
+ CSX.RectilinearGrid.XLines = mesh.r;
+else
+ error 'x/(r) direction not found'
+end
+
+if (isfield(mesh,'y'))
+ CSX.RectilinearGrid.YLines = mesh.y;
+elseif ((isfield(mesh,'a')) && (CSX.ATTRIBUTE.CoordSystem==1))
+ CSX.RectilinearGrid.YLines = mesh.a;
+else
+ error 'y/(a) direction not found'
+end
+
+CSX.RectilinearGrid.ZLines = mesh.z;
diff --git a/CSXCAD/matlab/DetectEdges.m b/CSXCAD/matlab/DetectEdges.m
new file mode 100644
index 0000000..ea01909
--- /dev/null
+++ b/CSXCAD/matlab/DetectEdges.m
@@ -0,0 +1,278 @@
+function mesh = DetectEdges(CSX, mesh, varargin)
+% mesh = DetectEdges(CSX <, mesh, varargin>)
+%
+% Returns a mesh with the edges added of certain (see below) primitives
+% found in the CSX structure.
+%
+% optional arguments:
+% mesh: add edges to an existing (predefined) mesh
+%
+% optional: 'keyword', value
+% 'Debug' enable debug mode (default is 1)
+% 'AddPropertyType' add a list of additional property types to detect
+% e.g. 'DumpBox' or {'DumpBox','ProbeBox'}
+% 'SetPropertyType' set the list of property types to detect (override default)
+% e.g. 'Metal' or {'Metal','ConductingSheet'}
+% 'ExcludeProperty' give a list of property names to exclude from
+% detection
+% 'SetProperty' give a list of property names to handly exlusively for detection
+%
+% advanced options: 'keyword', value
+% '2D_Metal_Edge_Res' define a one-third/two-third metal edge resolution
+%
+% example:
+% CSX = InitCSX();
+% % define all properties and primitives to detect
+% % ...
+% % ...
+% mesh = DetectEdges(CSX);
+% mesh = SmoothMesh(mesh, lambda/20/unit);
+% CSX = DefineRectGrid(CSX, unit, mesh);
+%
+% Note:
+% - Only primitives contained in Metal, Material, Excitation, LumpedElement
+% or ConductingSheet properties are processed
+% - Currently this function handles only Box, Polygons, LinPoly and Cylinder.
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Koen De Vleeschauwer (c) 2012
+% modified by: Thorsten Liebig (c) 2012, 2013
+%
+% See also InitCSX, SmoothMesh, DefineRectGrid
+
+supported_properties = {};
+supported_properties{end+1}='Metal';
+supported_properties{end+1}='Material';
+supported_properties{end+1}='Excitation';
+supported_properties{end+1}='LumpedElement';
+supported_properties{end+1}='ConductingSheet';
+
+exclude_list = {};
+prop_list_only = {};
+
+debug = 1;
+mesh_2D_metal_edges = 0;
+
+for n=1:2:numel(varargin)
+ if (strcmpi(varargin{n},'debug')==1);
+ debug = varargin{n+1};
+ elseif (strcmpi(varargin{n},'AddPropertyType')==1);
+ if iscell(varargin{n+1})
+ supported_properties(end+1) = varargin{n+1};
+ elseif ischar(varargin{n+1})
+ supported_properties{end+1} = varargin{n+1};
+ else
+ error('CSXCAD:DetectEdges','unknown property definition');
+ end
+ elseif (strcmpi(varargin{n},'SetPropertyType')==1);
+ if iscell(varargin{n+1})
+ supported_properties = varargin{n+1};
+ elseif ischar(varargin{n+1})
+ supported_properties = {varargin{n+1}};
+ else
+ error('CSXCAD:DetectEdges','unknown property definition');
+ end
+ elseif (strcmpi(varargin{n},'ExcludeProperty')==1);
+ exclude_list = varargin{n+1};
+ elseif (strcmpi(varargin{n},'SetProperty')==1);
+ prop_list_only = varargin{n+1};
+ elseif (strcmpi(varargin{n},'2D_Metal_Edge_Res')==1);
+ mesh_2D_metal_edges = varargin{n+1}*[-1 2]/3;
+ else
+ warning('CSXCAD:DetectEdges',['unknown argument: ' varargin{n}]);
+ end
+end
+
+if (nargin<2)
+ mesh = [];
+end
+
+if isempty(mesh)
+ if (CSX.ATTRIBUTE.CoordSystem==0)
+ mesh.x = [];
+ mesh.y = [];
+ mesh.z = [];
+ elseif (CSX.ATTRIBUTE.CoordSystem==1)
+ mesh.r = [];
+ mesh.a = [];
+ mesh.z = [];
+ else
+ error('CSXCAD:DetectEdges','unknown coordinate system used');
+ end
+end
+
+edges = {};
+edges.x = [ ];
+edges.y = [ ];
+edges.z = [ ];
+
+if (~isstruct(CSX))
+ error('expected a CSX structure');
+end
+
+CoordSystem = CSX.ATTRIBUTE.CoordSystem;
+
+if (isfield(CSX, 'Properties'))
+ prop_fn = fieldnames(CSX.Properties);
+ for p = 1:numel(prop_fn)
+ if (sum(strcmpi(prop_fn{p}, supported_properties))==0)
+ continue;
+ end
+ isMetal = sum(strcmpi(prop_fn{p},{'Metal','ConductingSheet'}));
+ property_group = CSX.Properties.(prop_fn{p});
+ for m = 1:numel(property_group)
+ property=property_group{m};
+ if ~isfield(property, 'Primitives')
+ continue;
+ end
+ if (sum(strcmpi(property.ATTRIBUTE.Name,exclude_list)))
+ continue;
+ end
+ if (~isempty(prop_list_only) && (sum(strcmpi(property.ATTRIBUTE.Name,prop_list_only))==0))
+ continue;
+ end
+ primitives = property.Primitives;
+ prim_fn = fieldnames(primitives);
+ for n_prim = 1:numel(prim_fn)
+ if (strcmp(prim_fn{n_prim}, 'Box'))
+ for b = 1:length(primitives.Box)
+ box = primitives.Box{b};
+ x1 = box.P1.ATTRIBUTE.X;
+ y1 = box.P1.ATTRIBUTE.Y;
+ z1 = box.P1.ATTRIBUTE.Z;
+ x2 = box.P2.ATTRIBUTE.X;
+ y2 = box.P2.ATTRIBUTE.Y;
+ z2 = box.P2.ATTRIBUTE.Z;
+ % check dimension
+ dim = (x1~=x2) + (y1~=y2) + (z1~=z2);
+ if ((dim==2) && isMetal)
+ % add to global list of edges, with a given 2D
+ % edge resolution
+ edges = AddEdge (edges, box, x1+sign(x1-x2)*mesh_2D_metal_edges, y1+sign(y1-y2)*mesh_2D_metal_edges, ...
+ z1+sign(z1-z2)*mesh_2D_metal_edges, CoordSystem, debug);
+ edges = AddEdge (edges, box, x2+sign(x2-x1)*mesh_2D_metal_edges, y2+sign(y2-y1)*mesh_2D_metal_edges, ...
+ z2+sign(z2-z1)*mesh_2D_metal_edges, CoordSystem, debug);
+ else
+ % add to global list of edges
+ edges = AddEdge (edges, box, x1, y1, z1, CoordSystem, debug);
+ edges = AddEdge (edges, box, x2, y2, z2, CoordSystem, debug);
+ end
+ end
+ elseif (strcmp(prim_fn{n_prim}, 'LinPoly') || strcmp(prim_fn{n_prim}, 'Polygon'))
+ for l = 1:length(primitives.(prim_fn{n_prim}))
+ poly = primitives.(prim_fn{n_prim}){l};
+ dir = poly.ATTRIBUTE.NormDir + 1;
+ dirP = mod(poly.ATTRIBUTE.NormDir+1,3) + 1;
+ dirPP = mod(poly.ATTRIBUTE.NormDir+2,3) + 1;
+ lin_length = 0;
+ if (strcmp(prim_fn{n_prim}, 'LinPoly'))
+ lin_length = poly.ATTRIBUTE.Length;
+ end
+ if (isfield(poly, 'Vertex'))
+ for v = 1:length(poly.Vertex)
+ vertex = poly.Vertex{v};
+ edge(dir) = poly.ATTRIBUTE.Elevation;
+ edge(dirP) = vertex.ATTRIBUTE.X1;
+ edge(dirPP) = vertex.ATTRIBUTE.X2;
+ edges = AddEdge (edges, poly, edge(1), edge(2), edge(3), CoordSystem, debug);
+ if (lin_length~=0)
+ edge(dir) = edge(dir) + lin_length;
+ edges = AddEdge (edges, poly, edge(1), edge(2), edge(3), CoordSystem, debug);
+ end
+ end
+ end
+ end
+ elseif (strcmp(prim_fn{n_prim}, 'Cylinder'))
+ for c = 1:length(primitives.Cylinder)
+ cylinder = primitives.Cylinder{c};
+ r = cylinder.ATTRIBUTE.Radius;
+ x1 = cylinder.P1.ATTRIBUTE.X;
+ y1 = cylinder.P1.ATTRIBUTE.Y;
+ z1 = cylinder.P1.ATTRIBUTE.Z;
+ x2 = cylinder.P2.ATTRIBUTE.X;
+ y2 = cylinder.P2.ATTRIBUTE.Y;
+ z2 = cylinder.P2.ATTRIBUTE.Z;
+ if ((x1 == x2) && (y1 == y2) && (z1 ~= z2))
+ % cylinder parallel with z axis
+ edges = AddEdge (edges, cylinder, x1 - r, y1 - r, z1, CoordSystem, debug);
+ edges = AddEdge (edges, cylinder, x2 + r, y2 + r, z2, CoordSystem, debug);
+ elseif ((x1 == x2) && (y1 ~= y2) && (z1 == z2))
+ % cylinder parallel with y axis
+ edges = AddEdge (edges, cylinder, x1 - r, y1, z1 - r, CoordSystem, debug);
+ edges = AddEdge (edges, cylinder, x2 + r, y2, z2 + r, CoordSystem, debug);
+ elseif ((x1 ~= x2) && (y1 == y2) && (z1 == z2))
+ % cylinder parallel with x axis
+ edges = AddEdge (edges, cylinder, x1, y1 - r, z1 - r, CoordSystem, debug);
+ edges = AddEdge (edges, cylinder, x2, y2 + r, z2 + r, CoordSystem, debug);
+ elseif (debug > 0)
+ warning('CSXCAD:DetectEdges',['unsupported primitive of type: "' prim_fn{n_prim} '" found, skipping edges']);
+ end
+ end
+ else
+ if (debug>0)
+ warning('CSXCAD:DetectEdges',['unsupported primitive of type: "' prim_fn{n_prim} '" found, skipping edges']);
+ end
+ end
+ end
+ end
+ end
+end
+
+if (CSX.ATTRIBUTE.CoordSystem==0)
+ mesh.x = sort(unique([mesh.x edges.x]));
+ mesh.y = sort(unique([mesh.y edges.y]));
+ mesh.z = sort(unique([mesh.z edges.z]));
+elseif (CSX.ATTRIBUTE.CoordSystem==1)
+ mesh.r = sort(unique([mesh.r edges.x]));
+ mesh.a = sort(unique([mesh.a edges.y]));
+ mesh.z = sort(unique([mesh.z edges.z]));
+else
+ error('CSXCAD:DetectEdges','unknown coordinate system used');
+end
+
+end
+
+
+function edges = AddEdge(edges, csx_prim, x, y, z, CoordSystem, debug)
+% Add edges of CSX primitives including some transformations
+
+xt = unique(x);
+yt = unique(y);
+zt = unique(z);
+
+if isfield(csx_prim.ATTRIBUTE,'CoordSystem')
+ if (csx_prim.ATTRIBUTE.CoordSystem~=CoordSystem)
+ if (debug>2)
+ warning('CSXCAD:DetectEdges','different coordinate systems not supported, skipping edges');
+ end
+ return
+ end
+end
+
+if (isfield(csx_prim, 'Transformation'))
+
+ transformation = csx_prim.Transformation;
+ trans_fn = fieldnames(transformation);
+
+ for t=1:numel(trans_fn)
+ if (strcmp(trans_fn{t}, 'Translate'))
+ xt = xt + transformation.Translate.ATTRIBUTE.Argument(1);
+ yt = yt + transformation.Translate.ATTRIBUTE.Argument(2);
+ zt = zt + transformation.Translate.ATTRIBUTE.Argument(3);
+ else
+ if (debug>0)
+ warning('CSXCAD:DetectEdges','unsupported transformation found in primitive, skipping edges');
+ end
+ return
+ end
+ end
+
+end
+
+% add to global list of edges
+edges.x = [edges.x xt];
+edges.y = [edges.y yt];
+edges.z = [edges.z zt];
+end
+
diff --git a/CSXCAD/matlab/DirChar2Int.m b/CSXCAD/matlab/DirChar2Int.m
new file mode 100644
index 0000000..0454448
--- /dev/null
+++ b/CSXCAD/matlab/DirChar2Int.m
@@ -0,0 +1,31 @@
+function n = DirChar2Int(dir_char)
+% function n = DirChar2Int(dir_char)
+%
+% internal function to convert a character like 'x','y','z' into a numeric
+% direction: 0..2!
+% If input already is a numeric value from 0..2, it will just be copied!
+% Everything else will raise an error!
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (c) 2013
+
+if (numel(dir_char)>1)
+ error('CSXCAD:DirChar2Int','invalid normal direction')
+end
+
+if (ischar(dir_char))
+ if (strcmp(dir_char,'x') || strcmp(dir_char,'r'))
+ n = 0; return;
+ elseif (strcmp(dir_char,'y') || strcmp(dir_char,'a'))
+ n = 1; return;
+ elseif strcmp(dir_char,'z')
+ n = 2; return;
+ else
+ error('CSXCAD:DirChar2Int','invalid normal direction')
+ end
+elseif (isnumeric(dir_char) && ((dir_char==0) || (dir_char==1) || (dir_char==2)))
+ n = dir_char;
+else
+ error('CSXCAD:DirChar2Int','invalid normal direction')
+end
diff --git a/CSXCAD/matlab/ImportPLY.m b/CSXCAD/matlab/ImportPLY.m
new file mode 100644
index 0000000..a221b38
--- /dev/null
+++ b/CSXCAD/matlab/ImportPLY.m
@@ -0,0 +1,23 @@
+function CSX = ImportPLY(CSX, propName, prio, filename, varargin)
+% function CSX = ImportPLY(CSX, propName, prio, filename, varargin)
+%
+% example:
+% CSX = AddMetal( CSX, 'cad_model' ); % create a perfect electric conductor (PEC)
+% CSX = ImportPLY(CSX, 'cad_model',10, 'sphere.ply','Transform',{'Scale',1/unit});
+%
+% Note: make sure the file 'sphere.ply' is in the working directory
+%
+% See also AddBox, AddCylinder, AddCylindricalShell, AddSphere, AddSphericalShell,
+% AddCurve, AddWire, AddMetal, ImportSTL
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+plyfile.ATTRIBUTE.Priority = prio;
+plyfile.ATTRIBUTE.FileName = filename;
+plyfile.ATTRIBUTE.FileType = 'PLY';
+
+plyfile = AddPrimitiveArgs(plyfile,varargin{:});
+
+CSX = Add2Property(CSX,propName, plyfile, 'PolyhedronReader');
diff --git a/CSXCAD/matlab/ImportSTL.m b/CSXCAD/matlab/ImportSTL.m
new file mode 100644
index 0000000..a3641f1
--- /dev/null
+++ b/CSXCAD/matlab/ImportSTL.m
@@ -0,0 +1,23 @@
+function CSX = ImportSTL(CSX, propName, prio, filename, varargin)
+% function CSX = ImportSTL(CSX, propName, prio, filename, varargin)
+%
+% example:
+% CSX = AddMetal( CSX, 'cad_model' ); % create a perfect electric conductor (PEC)
+% CSX = ImportSTL(CSX, 'cad_model',10, 'sphere.stl','Transform',{'Scale',1/unit});
+%
+% Note: make sure the file 'sphere.stl' is in the working directory
+%
+% See also AddBox, AddCylinder, AddCylindricalShell, AddSphere, AddSphericalShell,
+% AddCurve, AddWire, AddMetal, ImportPLY
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+stlfile.ATTRIBUTE.Priority = prio;
+stlfile.ATTRIBUTE.FileName = filename;
+stlfile.ATTRIBUTE.FileType = 'STL';
+
+stlfile = AddPrimitiveArgs(stlfile,varargin{:});
+
+CSX = Add2Property(CSX,propName, stlfile, 'PolyhedronReader');
diff --git a/CSXCAD/matlab/InitCSX.m b/CSXCAD/matlab/InitCSX.m
new file mode 100644
index 0000000..2411d85
--- /dev/null
+++ b/CSXCAD/matlab/InitCSX.m
@@ -0,0 +1,31 @@
+function CSX = InitCSX(varargin)
+% function CSX = InitCSX()
+%
+% Inititalize the CSX data-structure.
+%
+% variable arguments:
+% 'CoordSystem' : define the default coordinate system
+% 0 -> Cartesian
+% 1 -> Cylindircal
+% 2 -> Sphercial (not yet implemented)
+%
+% example:
+% CSX = InitCSX(); %for a default cartesian mesh
+% or
+% CSX = InitCSX('CoordSystem','1'); % for a cylindrical mesh definition
+%
+% See also DefineRectGrid, SmoothMeshLines, SmoothMeshLines2,
+% SetBackgroundMaterial
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+CSX.Properties = [];
+
+%Cartesian mesh as default coordinate system
+CSX.ATTRIBUTE.CoordSystem = 0;
+
+for n=1:2:numel(varargin)
+ CSX.ATTRIBUTE.(varargin{n}) = (varargin{n+1});
+end
diff --git a/CSXCAD/matlab/RecursiveSmoothMesh.m b/CSXCAD/matlab/RecursiveSmoothMesh.m
new file mode 100644
index 0000000..0ce791c
--- /dev/null
+++ b/CSXCAD/matlab/RecursiveSmoothMesh.m
@@ -0,0 +1,176 @@
+function resultMeshPoints = RecursiveSmoothMesh(fixedMeshPoints, max_res, ratio, varargin)
+% function resultMeshPoints = RecursiveSmoothMesh(fixedMeshPoints, max_res, ratio, varargin)
+%
+% RecursiveSmoothMesh: This function tries to generate an optimal mesh
+% between the given fixedMeshPoints. The space between the fixed points is
+% filled with the largest possible mesh step size considdering mesh max
+% resolution and mesh increase/decrease ratio.
+%
+% Algorithm: Mesh creation is done via a simple try and error approach:
+% The next mesh point could be between lastDistance*ratio and
+% lastDistance/ratio away from the last mesh point. If a fixed mesh point
+% exist in this distance, this point is used. If there is a fixed mesh
+% point below this distance, the last (determined) mesh point is wrong, go
+% back and try with a mesh point a few mm below. (If that is not possible
+% because the distance to the mesh point behind the last point is to low,
+% also update this mesh point).
+% The algorithm seems to work very well, except if the ratio is to low.
+% At a value of 1.2, the calculation takes a very long time.
+%
+%
+% Parameter: fixedMeshPoints: List containing points at which a mesh
+% line should appear
+% max_res: Maximum distance between two mesh lines
+% ratio: Maximum grading ratio between two
+% neighbour mesh lines
+%
+% optional variable arguments ('key', value):
+% CheckMesh: Do a final mesh check (default is true)
+% allowed_max_ratio: allow only a given max. grading ratio
+% (default --> ratio*1.25)
+%
+% Returns: resultMeshPoints: List containing the positions of all
+% mesh lines. If a empty list is
+% returned, no resolution could be
+% found.
+%
+% CSXCAD matlab interface
+% -----------------------
+% Author: Florian Pfanner
+% Date: 28.09.2012
+
+
+if (nargin < 3)
+ ratio = 1.4;
+end
+
+if (ratio < 1.2)
+ warning('ratio must be > 1.2, set it to 1.2');
+ ratio = 1.2;
+end
+
+check_mesh = true;
+max_ratio = ratio*1.25;
+
+for vn=1:2:numel(varargin)
+ if (strcmpi(varargin{vn},'CheckMesh'))
+ check_mesh = varargin{vn+1};
+ end
+ if (strcmpi(varargin{vn},'allowed_max_ratio'))
+ max_ratio = varargin{vn+1};
+ end
+end
+
+fixedMeshPoints = sort(unique(fixedMeshPoints(:)'));
+if (length(fixedMeshPoints) < 2)
+ error('Not enoughts points to create mesh!');
+end
+
+
+% special behaviour to generate a symetric mesh (If the fixedMeshPoints are
+% given in a symetric way.)
+symMesh = CheckSymmtricLines(fixedMeshPoints);
+if (symMesh)
+ nPoints = length(fixedMeshPoints);
+
+ symMeshEven = mod(nPoints,2)==0;
+
+ if (symMeshEven)
+ center = mean(fixedMeshPoints);
+ if (center-fixedMeshPoints(nPoints/2) > 0.5*max_res)
+ fixedMeshPoints = [fixedMeshPoints(1:nPoints/2) center];
+ else
+ % this is not working!!!
+ % fixedMeshPoints = fixedMeshPoints(1:nPoints/2+1);
+ fixedMeshPoints = [fixedMeshPoints(1:nPoints/2) center];
+ end
+ else
+ % For symetric mesh, only the first half of the fixed mesh points is
+ % needed. But add center of the symetric mesh to the fixed mesh points
+ % to ensure the center is included.
+ fixedMeshPoints = fixedMeshPoints(1:(nPoints+1)/2);
+ end
+end
+
+
+minDistance = min(fixedMeshPoints(2:end)-fixedMeshPoints(1:end-1));
+
+% two cases:
+% * minDistance is smaller than max_res
+% -> try spaces for the first mesh between max_res and minDistance/2
+% * max_res is smaller than minDistance
+% -> try spaces for the first mesh between max_res and max_res/10
+if (minDistance < max_res)
+ trySpaces = linspace(max_res, minDistance/2, 10);
+else
+ trySpaces = linspace(max_res, max_res/10, 10);
+end
+for k=1:length(trySpaces)
+ [resultMeshPoints, success] = recursiveMeshSearch(fixedMeshPoints(1), ...
+ trySpaces(k), fixedMeshPoints(2:end), max_res, ratio);
+ if (success)
+ resultMeshPoints = [fixedMeshPoints(1) resultMeshPoints];
+ break;
+ end
+end
+
+
+if (symMesh)
+ resultMeshPoints = [resultMeshPoints(1:end-1) max(resultMeshPoints)*2-resultMeshPoints(end:-1:1)];
+end
+
+% check result
+if (check_mesh)
+ CheckMesh(resultMeshPoints,0,max_res,ratio,0);
+end
+
+end % main function
+
+function [meshPoints, success] = recursiveMeshSearch(lastMeshPoint, ...
+ lastSpace, fixedMeshPoints, max_res, ratio)
+
+nextMeshPointMax = lastMeshPoint + min(lastSpace*ratio, max_res);
+nextMeshPointMin = lastMeshPoint + lastSpace/ratio;
+
+% check if below ratio is a fixed mesh point -> abbort
+if (fixedMeshPoints(1) < nextMeshPointMin)
+ meshPoints = [];
+ success = false;
+ return;
+end
+
+% check if in range of ratio is a fixed mesh point:
+if (fixedMeshPoints(1) >= nextMeshPointMin && fixedMeshPoints(1) <= nextMeshPointMax)
+ % yes, use this fixed mesh point
+ nextMeshPoint = fixedMeshPoints(1);
+ if (length(fixedMeshPoints) > 1)
+ [meshPointsCall, success] = recursiveMeshSearch(nextMeshPoint, ...
+ nextMeshPoint-lastMeshPoint, fixedMeshPoints(2:end), ...
+ max_res, ratio);
+ if (success) % backtracking was successful, return result
+ meshPoints = [nextMeshPoint meshPointsCall];
+ else % no possible resulution found, last step has to be repeated!
+ meshPoints = [];
+ end
+ else % this was the last mesh point, finish!
+ meshPoints = nextMeshPoint;
+ success = true;
+ end
+ return;
+end
+
+% try to set next mesh point, begin with highest width
+trySpace = linspace(nextMeshPointMax, nextMeshPointMin, 10);
+for i=1:length(trySpace)
+ [meshPointsCall, success] = recursiveMeshSearch(trySpace(i), ...
+ trySpace(i)-lastMeshPoint, fixedMeshPoints, max_res, ...
+ ratio);
+ if (success) % backtracking was successful, return
+ meshPoints = [trySpace(i) meshPointsCall];
+ return;
+ end
+end
+% no sucessful points found, return false
+meshPoints = [];
+success = false;
+end
diff --git a/CSXCAD/matlab/SetBackgroundMaterial.m b/CSXCAD/matlab/SetBackgroundMaterial.m
new file mode 100644
index 0000000..5aaa6df
--- /dev/null
+++ b/CSXCAD/matlab/SetBackgroundMaterial.m
@@ -0,0 +1,23 @@
+function CSX = SetBackgroundMaterial(CSX, varargin)
+% function CSX = SetBackgroundMaterial(CSX, varargin))
+%
+% Set the background material properties
+%
+% variable arguments:
+% 'Epsilon' : background rel. electric permittivity (default 1)
+% 'Kappa' : background electric conductivity (default 0)
+% 'Mue' : background rel. magnetic permeability (default 1)
+%
+% example:
+% CSX = InitCSX();
+% CSX = SetBackgroundMaterial(CSX, 'Epsilon', 4)
+%
+% See also InitCSX
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (c) 2013
+
+for n=1:2:numel(varargin)
+ CSX.BackgroundMaterial.ATTRIBUTE.(varargin{n}) = (varargin{n+1});
+end
diff --git a/CSXCAD/matlab/SetExcitationWeight.m b/CSXCAD/matlab/SetExcitationWeight.m
new file mode 100644
index 0000000..67a50ee
--- /dev/null
+++ b/CSXCAD/matlab/SetExcitationWeight.m
@@ -0,0 +1,53 @@
+function CSX = SetExcitationWeight(CSX, name, weight)
+% function CSX = SetExcitationWeight(CSX, name, weight)
+%
+% Define weighting functions for x-, y- and z-direction of excitation
+%
+% The functions can use the variables:
+% x,y,z
+% rho for the distance to z-axis
+% r for the distance to origin
+% a for alpha (as in cylindircal and spherical coord systems)
+% t for theta (as in the spherical coord system
+%
+% all these variables are not weighted with the drawing unit defined by
+% the grid
+%
+% example:
+% start=[0 0 0];
+% stop=[width height 0];
+% CSX = AddExcitation(CSX,'excite',0,[1 1 0]);
+% weight{1} = '2*cos(0.0031416*x)*sin(0.0062832*y)';
+% weight{2} = '1*sin(0.0031416*x)*cos(0.0062832*y)';
+% weight{3} = 0;
+% CSX = SetExcitationWeight(CSX,'excite',weight);
+% CSX = AddBox(CSX,'excite',0 ,start,stop);
+%
+% See also AddExcitation, InitCSX, DefineRectGrid
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+if ~isfield(CSX,'Properties')
+ error('CSXCAD::SetExcitationWeight: no properties not found');
+end
+if ~isfield(CSX.Properties,'Excitation')
+ error('CSXCAD::SetExcitationWeight: no excitation properties found');
+end
+
+pos=0;
+for n=1:numel(CSX.Properties.Excitation)
+ if strcmp(CSX.Properties.Excitation{n}.ATTRIBUTE.Name, name)
+ pos=n;
+ end
+end
+
+if (pos==0)
+ error('CSXCAD::SetExcitationWeight: property not found');
+ return;
+end
+
+CSX.Properties.Excitation{pos}.Weight.ATTRIBUTE.X = weight{1};
+CSX.Properties.Excitation{pos}.Weight.ATTRIBUTE.Y = weight{2};
+CSX.Properties.Excitation{pos}.Weight.ATTRIBUTE.Z = weight{3};
diff --git a/CSXCAD/matlab/SetMaterialProperty.m b/CSXCAD/matlab/SetMaterialProperty.m
new file mode 100644
index 0000000..463d22e
--- /dev/null
+++ b/CSXCAD/matlab/SetMaterialProperty.m
@@ -0,0 +1,29 @@
+function CSX = SetMaterialProperty(CSX, name, varargin)
+% function CSX = SetMaterialProperty(CSX, name, varargin)
+%
+% Use this function to define the material constants:
+% 'Epsilon': relative electric permittivity: [Epsilon] = 1
+% 'Mue': relative magnetic permeability: [Mue} = 1
+% 'Kappa': electric conductivity: [Kappa] = S/m
+% 'Sigma': magnetic conductivity (non-physical property): [Sigma] = Ohm/m
+% 'Density': material mass density: [Density] = kg/m^3, e.g. water: 1000
+% necessary for SAR calculations
+%
+% examples:
+% CSX = AddMaterial( CSX, 'RO3010' );
+% CSX = SetMaterialProperty( CSX, 'RO3010', 'Epsilon', 10.2, 'Mue', 1 );
+% CSX = AddBox( CSX, 'RO3010', 0, [0 0 0], [100 1000 1000] );
+%
+% % anisotropic material
+% CSX = AddMaterial( CSX, 'sheet','Isotropy',0);
+% CSX = SetMaterialProperty(CSX, 'sheet', 'Kappa', [0 0 kappa]);
+% CSX = AddBox( CSX, 'sheet', 0, [0 0 0], [10 1000 1000] );
+%
+% See also AddMaterial, SetMaterialWeight
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+CSX = SetPropertyArgs(CSX, GetPropertyType(CSX,name), name, 'Property', varargin{:});
+
diff --git a/CSXCAD/matlab/SetMaterialWeight.m b/CSXCAD/matlab/SetMaterialWeight.m
new file mode 100644
index 0000000..825892e
--- /dev/null
+++ b/CSXCAD/matlab/SetMaterialWeight.m
@@ -0,0 +1,31 @@
+function CSX = SetMaterialWeight(CSX, name, varargin)
+% function CSX = SetMaterialWeight(CSX, name, varargin)
+%
+% Define the material weighting function(s)
+%
+% The functions can use the variables:
+% x,y,z
+% rho for the distance to z-axis
+% r for the distance to origin
+% a for alpha (as in cylindircal and spherical coord systems)
+% t for theta (as in the spherical coord system
+%
+% all these variables are not weighted with the drawing unit defined by
+% the grid
+%
+% example:
+% %material distribution as a rect-function with 4 periods
+% start=[-500 -100 -500];
+% stop =[ 500 100 500];
+% CSX = AddMaterial(CSX, 'material');
+% CSX = SetMaterialProperty(CSX, 'material', 'Epsilon', 1);
+% CSX = SetMaterialWeight(CSX, 'material', 'Epsilon', ['(sin(4*z / 1000 *2*pi)>0)+1']);
+% CSX = AddBox(CSX, 'material' ,10 , start, stop);
+%
+% See also AddMaterial, SetMaterialProperty, InitCSX, DefineRectGrid
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+CSX = SetPropertyArgs(CSX, GetPropertyType(CSX,name), name, 'Weight', varargin{:});
diff --git a/CSXCAD/matlab/SmoothMesh.m b/CSXCAD/matlab/SmoothMesh.m
new file mode 100644
index 0000000..7ba37bc
--- /dev/null
+++ b/CSXCAD/matlab/SmoothMesh.m
@@ -0,0 +1,73 @@
+function [mesh] = SmoothMesh( mesh, max_res, ratio, varargin)
+% function [mesh] = SmoothMesh( mesh, max_res, <ratio, varargin>)
+%
+% Convienent function to create a smooth mesh in all directions.
+% Generate smooth mesh by choosing an appropriate algorithm in each direction.
+%
+% Currently supported smoothing algorithm:
+% SmoothMeshLines, SmoothMeshLines2 and RecursiveSmoothMesh
+%
+% arguments:
+% lines: given fixed lines to create a smooth mesh in between
+% max_res: scalar or vector of desired max. allowed resolution
+% ratio: grading ratio: scalar or vector of desired neighboring
+% line-delta ratio (optional, default is 1.5)
+% - see also 'allowed_max_ratio' argument
+%
+% variable arguments ('keyword',value):
+% algorithm: define subset of tried algorihm, e.g. [1 3]
+% symmetric: 0/1 force symmetric mesh (default is input symmetry)
+% homogeneous: 0/1 force homogeneous mesh
+% allowed_min_res: allow a given min resolution only
+% allowed_max_ratio: allow only a given max. grading ratio
+% (default --> ratio*1.25)
+% debug: 0/1 off/on
+%
+% example:
+% mesh.x = [-BoundBox 0 BoundBox];
+% mesh.y = [-BoundBox 0 BoundBox];
+% mesh.z = [0 BoundBox];
+% mesh = SmoothMesh(mesh, lambda/20/unit);
+% CSX = DefineRectGrid(CSX, unit, mesh);
+%
+% See also AutoSmoothMeshLines, InitCSX, DefineRectGrid, DetectEdges
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (C) 2012
+
+if (nargin<3)
+ ratio = 1.5;
+end
+
+if (numel(max_res)==1)
+ max_res = [max_res max_res max_res];
+end
+if (numel(ratio)==1)
+ ratio = [ratio ratio ratio];
+end
+if (numel(max_res)~=1)
+ max_res = [max_res max_res max_res];
+end
+
+if isfield(mesh,'x')
+ mesh.x = AutoSmoothMeshLines(mesh.x, max_res(1), ratio(1), varargin{:});
+elseif isfield(mesh,'r')
+ mesh.r = AutoSmoothMeshLines(mesh.r, max_res(1), ratio(1), varargin{:});
+else
+ error 'x/(r) direction not found'
+end
+
+if isfield(mesh,'y')
+ mesh.y = AutoSmoothMeshLines(mesh.y, max_res(2), ratio(2), varargin{:});
+elseif isfield(mesh,'a')
+ mesh.a = AutoSmoothMeshLines(mesh.a, max_res(2), ratio(2), varargin{:});
+else
+ error 'y/(a) direction not found'
+end
+
+if isfield(mesh,'z')
+ mesh.z = AutoSmoothMeshLines(mesh.z, max_res(3), ratio(3), varargin{:});
+else
+ error 'z direction not found'
+end
diff --git a/CSXCAD/matlab/SmoothMeshLines.m b/CSXCAD/matlab/SmoothMeshLines.m
new file mode 100644
index 0000000..bc1160f
--- /dev/null
+++ b/CSXCAD/matlab/SmoothMeshLines.m
@@ -0,0 +1,122 @@
+function lines = SmoothMeshLines( lines, max_res, ratio, varargin)
+%function lines = SmoothMeshLines( lines, max_res, ratio, varargin)
+%
+% create smooth mesh lines
+%
+% Warning: This function may not always produce a desired output.
+%
+% lines: given fixed lines to create a smooth mesh in between
+% max_res: desired max. resolution
+% ratio: max. neighboring line-delta ratio, (optional, default is 1.3)
+%
+% optional variable arguments ('key', value)
+% recursive: SmoothMeshLines a couple of times recursivly (default is 0)
+% CheckMesh: Do a final mesh check (default is true)
+% allowed_max_ratio: allow only a given max. grading ratio
+% (default --> ratio*1.25)
+%
+% example:
+% % create a x-mesh with lines at 0, 50 and 200 an a desired mesh
+% resolution of 5
+% mesh.x = SmoothMeshLines([0 50 200],5,1.3);
+%
+% See also InitCSX, DefineRectGrid
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+if (numel(lines)<2)
+ return
+end
+
+if (nargin<3)
+ ratio = 1.3;
+end
+
+recursive = 0;
+check_mesh = true;
+max_ratio = ratio*1.25;
+
+for vn=1:2:numel(varargin)
+ if (strcmpi(varargin{vn},'recursive'))
+ recursive = varargin{vn+1};
+ end
+ if (strcmpi(varargin{vn},'CheckMesh'))
+ check_mesh = varargin{vn+1};
+ end
+ if (strcmpi(varargin{vn},'allowed_max_ratio'))
+ max_ratio = varargin{vn+1};
+ end
+end
+
+lines = unique(sort(lines));
+
+diff_Lines = diff(lines);
+
+index = find(diff_Lines>(1.001*max_res));
+
+% for n=1:numel(diff_Lines)-1
+% if ( (diff_Lines(n+1)/diff_Lines(n) > ratio) )
+% index = [index n+1];
+% end
+% end
+
+index = unique(index);
+
+addLines = [];
+
+for n=1:numel(index)
+ if (index(n)==1)
+ start_res = max_res;
+ else
+ start_res = lines(index(n)) - lines(index(n)-1);
+ end
+
+ if ((index(n)+1)==numel(lines))
+ stop_res = max_res;
+ else
+ stop_res = lines(index(n)+2) - lines(index(n)+1);
+ end
+
+ addLines = [addLines SmoothRange(lines(index(n)),lines(index(n)+1),start_res,stop_res,max_res,ratio)];
+end
+
+
+lines = unique(sort([lines addLines]));
+
+addLines = [];
+% relax ratio for test
+ratio_relax = ratio + (ratio-1) * 1;
+
+[EC pos E_type] = CheckMesh(lines,0,max_res,ratio_relax,1);
+diff_Lines = diff(lines);
+
+for n=1:EC
+ if pos(n)>1
+ start_res = diff_Lines(pos(n)-1);
+ else
+ start_res = diff_Lines(pos(n));
+ end
+ if pos(n) >= numel(diff_Lines)
+ stop_res = diff_Lines(end);
+ else
+ stop_res = diff_Lines(pos(n)+1);
+ end
+ max_res_R = max([start_res stop_res])/2/ratio;
+ addLines = [addLines SmoothRange(lines(pos(n)),lines(pos(n)+1),start_res,stop_res,max_res_R,ratio)];
+end
+
+lines = unique(sort([lines addLines]));
+
+for n=1:recursive
+ old_numL = numel(lines);
+ lines = SmoothMeshLines( lines, max_res, ratio, 0);
+ if numel(lines) == old_numL
+ return
+ end
+end
+
+if (check_mesh)
+ CheckMesh(lines,0,max_res,max_ratio,0);
+end
diff --git a/CSXCAD/matlab/SmoothMeshLines2.m b/CSXCAD/matlab/SmoothMeshLines2.m
new file mode 100644
index 0000000..5d347c0
--- /dev/null
+++ b/CSXCAD/matlab/SmoothMeshLines2.m
@@ -0,0 +1,318 @@
+function lines = SmoothMeshLines2(lines, max_res, ratio, varargin)
+%lines = SmoothMeshLines2( lines, max_res [, ratio, varargin] )
+%
+% Create smooth mesh lines.
+%
+% input:
+% lines: 1xn vector of (fixed) mesh lines
+% max_res: maximum distance between any two lines (e.g. lambda/10)
+% ratio: (optional) default: 1.3
+%
+% optional variable arguments ('key', value)
+% CheckMesh: Do a final mesh check (default is true)
+% allowed_max_ratio: allow only a given max. grading ratio
+% (default --> ratio*1.25)
+% output:
+% lines: 1xn vector of (smoothed) mesh lines
+%
+% example:
+% mesh.x = [0 100 2300 2400];
+% mesh.x = SmoothMeshLines2( mesh.x, 43 );
+%
+% todo:
+% - if gaps cannot be completely filled because of the ratio restriction,
+% the spacing is not optimal. SmoothRange() needs to be optimized.
+% - SmoothRange() has special handling if stop_taper is to long; can this
+% also happen for start_taper?
+%
+% CSXCAD matlab interface
+% -----------------------
+% (C) 2010 Sebastian Held <sebastian.held@uni-due.de>
+% See also SmoothMeshLines
+
+if (numel(lines)<2)
+ return
+end
+
+if (nargin<3)
+ ratio = 1.3;
+end
+
+check_mesh = true;
+max_ratio = ratio*1.25;
+
+for vn=1:2:numel(varargin)
+ if (strcmpi(varargin{vn},'CheckMesh'))
+ check_mesh = varargin{vn+1};
+ end
+ if (strcmpi(varargin{vn},'allowed_max_ratio'))
+ max_ratio = varargin{vn+1};
+ end
+end
+
+%
+% | | | |
+% | gap(1) | gap(2) | ... |
+% | | | |
+%
+% lines(1) lines(2) ... lines(end)
+
+lines = unique(sort(lines));
+
+for n=1:(numel(lines)-1)
+ old_gap(n).start_res = -1;
+ old_gap(n).stop_res = -1;
+ old_gap(n).lines = [];
+end
+
+if numel(lines) == 2
+ % special case
+ addLines = SmoothRange( lines(1), lines(2), [], [], max_res, ratio );
+ lines = sort(unique([lines addLines]));
+ [EC pos] = CheckMesh(lines,0,max_res,ratio);
+ return
+end
+
+while 1
+ gap = calc_gaps(lines,old_gap,max_res);
+
+ % determine gap to process
+ index = find( [old_gap(2:end).start_res] ~= [gap(2:end).start_res], 1, 'first' ) + 1;
+ if isempty(index)
+ index = find( [old_gap(1:end-1).stop_res] ~= [gap(1:end-1).stop_res], 1, 'first' );
+ end
+ if isempty(index)
+ break; % done
+ end
+
+ start_res = min( max_res, calc_start_res(index,lines,old_gap) );
+ stop_res = min( max_res, calc_stop_res(index,lines,old_gap) );
+
+ % create new lines
+ old_gap(index).lines = SmoothRange( lines(index), lines(index+1), start_res, stop_res, max_res, ratio );
+
+ % remember gap setting
+ old_gap(index).start_res = start_res;
+ old_gap(index).stop_res = stop_res;
+
+ % debug
+% plot_lines
+end
+
+% merge lines
+for n=1:numel(old_gap)
+ lines = [lines old_gap(n).lines];
+end
+lines = sort(unique(lines));
+
+if (check_mesh)
+ CheckMesh(lines,0,max_res,max_ratio,0);
+end
+
+end % SmoothMeshLines2()
+
+%% ------------------------------------------------------------------------
+function gap = calc_gaps(lines,old_gap,max_res)
+ temp_lines = lines;
+ for n=1:numel(old_gap)
+ temp_lines = [temp_lines old_gap(n).lines];
+ end
+ temp_lines = sort(unique(temp_lines));
+
+ if numel(temp_lines) == 2
+ gap(1).start_res = inf; % resolution not fixed
+ gap(1).stop_res = max_res;
+ return
+ end
+
+ gap(1).start_res = inf; % resolution not fixed
+ idx = interp1( temp_lines, 1:numel(temp_lines), lines(2), 'nearest' );
+ gap(1).stop_res = min( max_res, temp_lines(idx+1) - temp_lines(idx) );
+ for n=2:numel(lines)-2
+ idx = interp1( temp_lines, 1:numel(temp_lines), lines(n), 'nearest' );
+ gap(n).start_res = min( max_res, temp_lines(idx) - temp_lines(idx-1) );
+ idx = interp1( temp_lines, 1:numel(temp_lines), lines(n+1), 'nearest' );
+ gap(n).stop_res = min( max_res, temp_lines(idx+1) - temp_lines(idx) );
+ gap(n).lines = old_gap(n).lines;
+ end
+ idx = interp1( temp_lines, 1:numel(temp_lines), lines(end-1), 'nearest' );
+ gap(numel(lines)-1).start_res = min( max_res, temp_lines(idx) - temp_lines(idx-1) );
+ gap(numel(lines)-1).stop_res = inf; % resolution not fixed
+end % calc_gaps()
+
+
+%% ------------------------------------------------------------------------
+function plot_lines
+ temp_lines = lines;
+ for n=1:numel(old_gap)
+ temp_lines = [temp_lines old_gap(n).lines];
+ end
+ temp_lines = sort(unique(temp_lines));
+
+ plot( temp_lines, ones(size(temp_lines)), 'r+' );
+ hold on
+ plot( lines, ones(size(lines)), 'bo' );
+ hold off
+end % plot_lines
+
+
+%% ------------------------------------------------------------------------
+function res = calc_start_res(pos,lines,old_gap)
+ if (pos < 2) || (pos > numel(lines))
+ res = [];
+ return
+ end
+ temp_lines = lines;
+ for n=1:numel(old_gap)
+ temp_lines = [temp_lines old_gap(n).lines];
+ end
+ temp_lines = sort(unique(temp_lines));
+
+ idx = interp1( temp_lines, 1:numel(temp_lines), lines(pos), 'nearest' );
+ res = temp_lines(idx) - temp_lines(idx-1);
+end % calc_res()
+
+
+%% ------------------------------------------------------------------------
+function res = calc_stop_res(pos,lines,old_gap)
+ if (pos < 1) || (pos >= numel(lines)-1)
+ res = [];
+ return
+ end
+ temp_lines = lines;
+ for n=1:numel(old_gap)
+ temp_lines = [temp_lines old_gap(n).lines];
+ end
+ temp_lines = sort(unique(temp_lines));
+
+ idx = interp1( temp_lines, 1:numel(temp_lines), lines(pos+1), 'nearest' );
+ res = temp_lines(idx+1) - temp_lines(idx);
+end % calc_res()
+
+
+%% ------------------------------------------------------------------------
+function lines = SmoothRange(start, stop, start_res, stop_res, max_res, ratio)
+
+if (nargin<6)
+ ratio = 1.3;
+end
+
+if isempty(start_res) && isempty(stop_res)
+ % special case: fill entire range with max_res
+ n1 = ceil( (stop-start) / max_res ) + 1;
+ lines = linspace( start, stop, n1 );
+ return
+end
+
+if isempty(start_res)
+ % special case: taper from stop_res at stop to max_res at start (if
+ % possible)
+ taper = stop_res*ratio;
+ stop_taper = stop;
+ while (taper*ratio < max_res) && (stop_taper(1)-taper > start)
+ stop_taper = [stop_taper(1)-taper stop_taper];
+ taper = taper*ratio;
+ end
+ if (stop_taper(1) - start) >= max_res
+ % fill with equidistant lines
+ n1 = ceil( (stop_taper(1)-start) / max_res ) + 1;
+ stop_taper = [linspace(start,stop_taper(1),n1) stop_taper];
+ else
+ % not enough space for entire taper
+ stop_taper(1) = []; % likely too near to start
+ if numel(stop_taper) > 0
+ stop_taper = [(start+stop_taper(1))/2 stop_taper]; % create a centered line
+ end
+ end
+ lines = sort(unique(stop_taper(stop_taper>=start)));
+ return
+end
+
+if isempty(stop_res)
+ % special case: taper from stop_res at stop to max_res at start (if
+ % possible)
+ taper = start_res*ratio;
+ start_taper = start;
+ while (taper*ratio < max_res) && (start_taper(end)+taper < stop)
+ start_taper = [start_taper start_taper(end)+taper];
+ taper = taper*ratio;
+ end
+ if (stop - start_taper(end)) >= max_res
+ % fill with equidistant lines
+ n1 = ceil( (stop-start_taper(end)) / max_res ) + 1;
+ start_taper = [start_taper linspace(start_taper(end),stop,n1)];
+ else
+ % not enough space for entire taper
+ start_taper(end) = []; % likely too near to stop
+ if numel(start_taper) > 0
+ start_taper = [start_taper (stop+start_taper(end))/2]; % create a centered line
+ end
+ end
+ lines = sort(unique(start_taper(start_taper<=stop)));
+ return
+end
+
+taper = start_res*ratio;
+start_taper = start;
+while (taper*ratio<max_res) && (start_taper(end)+taper < stop)
+ start_taper = [start_taper start_taper(end)+taper];
+ taper = taper*ratio;
+end
+if (numel(start_taper) > 1) && (start_taper(end) - start_taper(end-1) > stop - start_taper(end))
+ % not enough space for entire taper
+ start_taper(end) = []; % likely too near to stop
+ start_taper = [start_taper (stop+start_taper(end))/2]; % create a centered line
+end
+
+taper = stop_res*ratio;
+stop_taper = stop;
+while (taper*ratio<max_res) && (stop_taper(1)-taper > start)
+ stop_taper = [stop_taper(1)-taper stop_taper];
+ taper = taper*ratio;
+end
+if (numel(stop_taper) > 1) && (stop_taper(2) - stop_taper(1) > start - stop_taper(1))
+ % not enough space for entire taper
+ stop_taper(1) = []; % likely too near to start
+ stop_taper = [(start+stop_taper(1))/2 stop_taper]; % create a centered line
+end
+
+while ~isempty(start_taper) && ~isempty(stop_taper) && (stop_taper(1) < start_taper(end))
+
+ diff_start = diff(start_taper);
+ if isempty(diff_start)
+ diff_start = start_res;
+ end
+ diff_stop = diff(stop_taper);
+ if isempty(diff_stop)
+ diff_stop = stop_res;
+ end
+
+ if (diff_start(end)>diff_stop(1))
+ start_taper(end) = [];
+ else
+ stop_taper(1) = [];
+ end
+end
+
+% it may happen, that the space between start_taper(end) and stop_taper(1)
+% is very small; correct it:
+if numel(start_taper)>=2 && numel(stop_taper)>=2
+ d = diff( [start_taper(end-1) start_taper(end) stop_taper(1) stop_taper(2) ]);
+ if (d(1)/d(2) > ratio) || (d(3)/d(2) > ratio)
+ addLines = linspace( start_taper(end-1), stop_taper(2), 4 );
+ lines = unique( [start_taper(1:end-1) addLines stop_taper(2:end)] );
+ return
+ end
+end
+
+if isempty(start_taper)
+ start_taper = start;
+end
+if isempty(stop_taper)
+ stop_taper = stop;
+end
+
+% fill remaining space with equidistant lines
+numL = ceil((stop_taper(1) - start_taper(end))/max_res)+1;
+lines = unique([start_taper linspace(start_taper(end),stop_taper(1),numL) stop_taper]);
+end % SmoothRange()
diff --git a/CSXCAD/matlab/export_empire.m b/CSXCAD/matlab/export_empire.m
new file mode 100644
index 0000000..104a0bf
--- /dev/null
+++ b/CSXCAD/matlab/export_empire.m
@@ -0,0 +1,305 @@
+function export_empire( CSX, FDTD, filename, options )
+% export_empire( CSX, FDTD, filename, options )
+%
+% Exports the geometry defined in CSX to filename as an Empire python file.
+%
+% CSX: CSX-object created by InitCSX()
+% FDTD: FDTD-object created by InitFDTD()
+% filename: export filename (e.g. '/tmp/export.py')
+% options (optional): struct
+% options.ignore : cell array with property names to ignore
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Sebastian Held <sebastian.held@gmx.de>
+% 17. Jun 2010: initial version
+% 28. Sep 2010: rewritten using Empire python scripting
+% See also InitCSX InitFDTD
+
+if nargin < 3
+ options = [];
+end
+
+fid = fopen( filename, 'w' );
+
+% write header
+fprintf( fid, ['# Empire python script\n\n' ...
+ '# start Empire and select File/"Run Script" and select this file\n\n'] );
+fprintf( fid, 'from scripting import *\n\n' );
+export_empire_meshlines( fid, CSX );
+export_empire_settings( fid, CSX, FDTD );
+
+if isfield(CSX.Properties,'Material')
+ % process material
+ Material = CSX.Properties.Material;
+ options.Property = 'Material';
+ process_primitives( fid, Material, options );
+end
+if isfield(CSX.Properties,'Metal')
+ % process PEC
+ Metal = CSX.Properties.Metal;
+ options.Property = 'Metal';
+ process_primitives( fid, Metal, options );
+end
+
+fclose( fid );
+
+% -----------------------------------------------------------------------------
+function str = gym_vect( start,stop )
+str = ['[' num2str(start(1)) ',' num2str(stop(1)) ',' num2str(start(2)) ',' num2str(stop(2)) ',' num2str(start(3)) ',' num2str(stop(3)) ']'];
+function str = gym_vector( v )
+str = ['[' num2str(v(1))];
+for a=2:numel(v), str = [str ', ' num2str(v(a))]; end
+str = [str ']'];
+
+% -----------------------------------------------------------------------------
+function primitive_box( fid, CSX_box, layertype )
+%primitive_box( fid, CSX_box, layertype )
+% layertype may be: 'dielectric Dielectric' or 'conductor Conductor'
+global current_layer_prio
+properties = '';
+if current_layer_prio ~= CSX_box.ATTRIBUTE.Priority
+ properties = [properties ' prio ' num2str(CSX_box.ATTRIBUTE.Priority)];
+end
+if ~isempty(properties)
+ fprintf( fid, 'g.objecttext("%s")\n', [layertype properties] );
+end
+start = [CSX_box.P1.ATTRIBUTE.X CSX_box.P1.ATTRIBUTE.Y CSX_box.P1.ATTRIBUTE.Z];
+stop = [CSX_box.P2.ATTRIBUTE.X CSX_box.P2.ATTRIBUTE.Y CSX_box.P2.ATTRIBUTE.Z];
+fprintf( fid, 'g.layerextrude("z",%g,%g)\n', start(3), stop(3) );
+fprintf( fid, 'g.box(%g,%g,%g,%g)\n', start(1), start(2), stop(1), stop(2) );
+
+% -----------------------------------------------------------------------------
+function primitive_cylinder( fid, CSX_cylinder, layertype )
+%primitive_cylinder( fid, CSX_cylinder, layertype )
+% layertype may be: 'dielectric Dielectric' or 'conductor Conductor'
+global current_layer_prio
+properties = '';
+if current_layer_prio ~= CSX_cylinder.ATTRIBUTE.Priority
+ properties = [properties ' prio ' num2str(CSX_cylinder.ATTRIBUTE.Priority)];
+end
+if ~isempty(properties)
+ fprintf( fid, 'g.objecttext("%s")\n', [layertype properties] );
+end
+
+start = [CSX_cylinder.P1.ATTRIBUTE.X CSX_cylinder.P1.ATTRIBUTE.Y CSX_cylinder.P1.ATTRIBUTE.Z];
+stop = [CSX_cylinder.P2.ATTRIBUTE.X CSX_cylinder.P2.ATTRIBUTE.Y CSX_cylinder.P2.ATTRIBUTE.Z];
+
+radius = CSX_cylinder.ATTRIBUTE.Radius;
+if start([1 2]) == stop([1 2])
+ fprintf( fid, 'g.layerextrude("z",%g,%g)\n', start(3), stop(3) );
+ fprintf( fid, 'g.circle(%g,%g,%g)\n', start(1), start(2), radius );
+elseif start([1 3]) == stop([1 3])
+ fprintf( fid, 'g.layerextrude("y",%g,%g)\n', start(2), stop(2) );
+ fprintf( fid, 'g.circle(%g,%g,%g)\n', start(3), start(1), radius );
+elseif start([2 3]) == stop([2 3])
+ fprintf( fid, 'g.layerextrude("x",%g,%g)\n', start(1), stop(1) );
+ fprintf( fid, 'g.circle(%g,%g,%g)\n', start(2), start(3), radius );
+else
+ disp( ['cylinder coordinates: (' num2str(start) ') -> (' num2str(stop) ')'] );
+ error 'cylinder orientation not supported'
+end
+
+% -----------------------------------------------------------------------------
+function str = primitive_wire( CSX_wire, options )
+radius = CSX_wire.ATTRIBUTE.WireRadius;
+str = ['sphere_sweep { linear_spline, ' num2str(numel(CSX_wire.Vertex))];
+for a=1:numel(CSX_wire.Vertex)
+ % iterate over all vertices
+ v = [CSX_wire.Vertex{a}.ATTRIBUTE.X CSX_wire.Vertex{a}.ATTRIBUTE.Y CSX_wire.Vertex{a}.ATTRIBUTE.Z];
+ str = [str ', ' pov_vect(v) ', ' num2str(radius)];
+end
+str = [str ' ' options '}'];
+
+% -----------------------------------------------------------------------------
+function primitive_polygon( fid, CSX_polygon, layertype )
+%primitive_polygon( fid, CSX_polygon, layertype )
+% layertype may be: 'dielectric Dielectric' or 'conductor Conductor'
+global current_layer_prio
+properties = '';
+if current_layer_prio ~= CSX_polygon.ATTRIBUTE.Priority
+ properties = [properties ' prio ' num2str(CSX_polygon.ATTRIBUTE.Priority)];
+end
+if ~isempty(properties)
+ fprintf( fid, 'g.objecttext("%s")\n', [layertype properties] );
+end
+Elevation = CSX_polygon.ATTRIBUTE.Elevation;
+if (CSX_polygon.NormDir.ATTRIBUTE.X ~= 0)
+ NormDir = 'x';
+elseif (CSX_polygon.NormDir.ATTRIBUTE.Y ~= 0)
+ NormDir = 'y';
+elseif (CSX_polygon.NormDir.ATTRIBUTE.Z ~= 0)
+ NormDir = 'z';
+end
+coords = [];
+for a=1:numel(CSX_polygon.Vertex)
+ % iterate over all vertices
+ coords = [coords CSX_polygon.Vertex{a}.ATTRIBUTE.X1 CSX_polygon.Vertex{a}.ATTRIBUTE.X2];
+end
+fprintf( fid, 'g.layerextrude("%s",%g,%g)\n', NormDir, Elevation, Elevation+1 );
+fprintf( fid, 'g.poly(' );
+for n=1:numel(coords)
+ if n > 1
+ fprintf( fid, ', %g', coords(n) );
+ else
+ fprintf( fid, '%g', coords(n) );
+ end
+end
+fprintf( fid, ')\n' );
+
+
+
+
+% -----------------------------------------------------------------------------
+function process_primitives( fid, prop, options )
+global current_layer_prio
+ignore = {};
+if isfield(options,'ignore'), ignore = options.ignore; end
+
+% iterate over all properties and extract the priority
+prio = [];
+for num=1:numel(prop)
+ if isfield(prop{num}.Primitives,'Box')
+ for a=1:numel(prop{num}.Primitives.Box)
+ % iterate over all boxes
+ prio(end+1) = prop{num}.Primitives.Box{a}.ATTRIBUTE.Priority;
+ end
+ end
+ if isfield(prop{num}.Primitives,'Cylinder')
+ for a=1:numel(prop{num}.Primitives.Cylinder)
+ % iterate over all cylinders
+ prio(end+1) = prop{num}.Primitives.Cylinder{a}.ATTRIBUTE.Priority;
+ end
+ end
+ if isfield(prop{num}.Primitives,'Polygon')
+ for a=1:numel(prop{num}.Primitives.Polygon)
+ % iterate over all polygons
+ prio(end+1) = prop{num}.Primitives.Polygon{a}.ATTRIBUTE.Priority;
+ end
+ end
+end
+% Now prio is a vector full of priorities. Extract the priority, which is
+% most often used.
+u_prios = unique(prio);
+count = histc(prio,u_prios);
+[~,idx] = max(count);
+current_layer_prio = u_prios(idx);
+
+% now export all properties/primitives
+for num=1:numel(prop)
+ Name = prop{num}.ATTRIBUTE.Name;
+ if any( strcmp(Name,ignore) )
+ disp( ['omitting ' Name '...'] );
+ continue
+ end
+
+ disp( ['processing ' prop{num}.ATTRIBUTE.Name '...'] );
+
+ if strcmp(options.Property,'Metal')
+ layertype = 'conductor';
+ properties = [layertype ' sigma infinite sides auto rough 0 prio ' num2str(current_layer_prio) ' automodel auto'];
+ else
+ layertype = 'dielectric';
+ epsr = 1;
+ sigma = 0;
+ if isfield(prop{num},'PropertyX')
+ if isfield(prop{num}.PropertyX.ATTRIBUTE,'Epsilon'), epsr = prop{num}.PropertyX.ATTRIBUTE.Epsilon; end
+ if isfield(prop{num}.PropertyX.ATTRIBUTE,'Kappa'), sigma = prop{num}.PropertyX.ATTRIBUTE.Kappa; end
+ end
+ properties = [layertype ' epsr ' num2str(epsr) ' sigma ' num2str(sigma) ' prio ' num2str(current_layer_prio) ' tand 0 density 0'];
+ end
+
+ export_empire_layer( fid, Name, properties )
+
+ if isfield(prop{num}.Primitives,'Box')
+ for a=1:numel(prop{num}.Primitives.Box)
+ % iterate over all boxes
+ Box = prop{num}.Primitives.Box{a};
+ primitive_box( fid, Box, layertype );
+ end
+ end
+ if isfield(prop{num}.Primitives,'Cylinder')
+ for a=1:numel(prop{num}.Primitives.Cylinder)
+ % iterate over all cylinders
+ Cylinder = prop{num}.Primitives.Cylinder{a};
+ primitive_cylinder( fid, Cylinder, layertype );
+ end
+ end
+ if isfield(prop{num}.Primitives,'Wire')
+ for a=1:numel(prop{num}.Primitives.Wire)
+ % iterate over all wires
+ Wire = prop{num}.Primitives.Wire{a};
+% str = primitive_wire( Wire, obj_modifier );
+% fprintf( fid, '%s\n', str );
+ end
+ warning( 'CSXCAD:export_empire', 'primitive wire currently unsupported' );
+ end
+ if isfield(prop{num}.Primitives,'Polygon')
+ for a=1:numel(prop{num}.Primitives.Polygon)
+ % iterate over all polygons
+ Polygon = prop{num}.Primitives.Polygon{a};
+ primitive_polygon( fid, Polygon, layertype );
+ end
+ end
+
+ fprintf( fid, 'g.load()\n\n' );
+end
+
+
+
+
+function export_empire_layer( fid, name, layertext )
+fprintf( fid, '# create a new layer\n' );
+fprintf( fid, 'g = gmf()\n' );
+fprintf( fid, 'g.layer("%s")\n', name );
+fprintf( fid, 'g.layerextrude("z",0,0)\n' );
+fprintf( fid, 'g.layertext("%s")\n', layertext );
+
+function export_empire_meshlines(fid,CSX)
+fprintf( fid, '# create the mesh\n' );
+fprintf( fid, 'empty_disc()\n' );
+fprintf( fid, 'g = gmf()\n' );
+fprintf( fid, 'g.raw_write("DISC X %g")\n', CSX.RectilinearGrid.XLines );
+fprintf( fid, 'g.raw_write("DISC Y %g")\n', CSX.RectilinearGrid.YLines );
+fprintf( fid, 'g.raw_write("DISC Z %g")\n', CSX.RectilinearGrid.ZLines );
+fprintf( fid, 'g.load()\n\n' );
+
+function empire_BC = convert_BC( openEMS_BC )
+if ischar(openEMS_BC)
+ if strcmp(openEMS_BC,'PEC')
+ empire_BC = 'electric';
+ elseif strcmp(openEMS_BC,'PMC')
+ empire_BC = 'magnetic';
+ elseif strncmp(openEMS_BC,'MUR',3) || strncmp(openEMS_BC,'PML',3)
+ empire_BC = 'pml 6';
+ else
+ empire_BC = 'UNKNOWN';
+ end
+else
+ if openEMS_BC == 0
+ empire_BC = 'electric';
+ elseif openEMS_BC == 1
+ empire_BC = 'magnetic';
+ elseif openEMS_BC == 2 || openEMS_BC == 3
+ empire_BC = 'pml 6';
+ else
+ empire_BC = 'UNKNOWN';
+ end
+end
+
+function export_empire_settings(fid,CSX,FDTD)
+fprintf( fid, '# settings\n' );
+fprintf( fid, 'set_fs_parameter( ''dx'', %g )\n', CSX.RectilinearGrid.ATTRIBUTE.DeltaUnit );
+fprintf( fid, 'set_fs_parameter( ''xmin'', ''%s'' )\n', convert_BC(FDTD.BoundaryCond.ATTRIBUTE.xmin) );
+fprintf( fid, 'set_fs_parameter( ''xmax'', ''%s'' )\n', convert_BC(FDTD.BoundaryCond.ATTRIBUTE.xmax) );
+fprintf( fid, 'set_fs_parameter( ''ymin'', ''%s'' )\n', convert_BC(FDTD.BoundaryCond.ATTRIBUTE.ymin) );
+fprintf( fid, 'set_fs_parameter( ''ymax'', ''%s'' )\n', convert_BC(FDTD.BoundaryCond.ATTRIBUTE.ymax) );
+fprintf( fid, 'set_fs_parameter( ''zmin'', ''%s'' )\n', convert_BC(FDTD.BoundaryCond.ATTRIBUTE.zmin) );
+fprintf( fid, 'set_fs_parameter( ''zmax'', ''%s'' )\n', convert_BC(FDTD.BoundaryCond.ATTRIBUTE.zmax) );
+fprintf( fid, 'set_fs_parameter( ''f_0'', %g )\n', FDTD.Excitation.ATTRIBUTE.f0 );
+fprintf( fid, 'set_fs_parameter( ''f_c'', %g )\n', FDTD.Excitation.ATTRIBUTE.fc );
+f_start = max(0,FDTD.Excitation.ATTRIBUTE.f0 - FDTD.Excitation.ATTRIBUTE.fc);
+f_end = max(0,FDTD.Excitation.ATTRIBUTE.f0 + FDTD.Excitation.ATTRIBUTE.fc);
+fprintf( fid, 'set_fs_parameter( ''F_START'', %g )\n', f_start );
+fprintf( fid, 'set_fs_parameter( ''F_END'', %g )\n', f_end );
+fprintf( fid, 'set_fs_parameter( ''F_MID'', %g )\n', (f_start+f_end)/2 );
diff --git a/CSXCAD/matlab/export_excellon.m b/CSXCAD/matlab/export_excellon.m
new file mode 100644
index 0000000..8877fcd
--- /dev/null
+++ b/CSXCAD/matlab/export_excellon.m
@@ -0,0 +1,144 @@
+function export_excellon( CSX, filename, options )
+% export_excellon( CSX, filename, options )
+%
+% Exports the geometry defined in CSX to filename as an excellon drill file.
+% Only cylinders will be considered for export.
+% The xy-plane is exported.
+%
+% CSX: CSX-object created by InitCSX()
+% filename: export filename (e.g. '/tmp/export.gbr')
+% options (optional): struct
+% .header: (string) add this to the header of the file
+% comment line must have ';' as the very first character
+% .exclude: (cell array) ignore these CSX-properties
+% .include: (cell array) include only these CSX-properties
+% if neither .exclude or .include is specified, process all properties
+%
+% See also InitCSX
+% CSXCAD matlab interface
+% -----------------------
+% author: Sebastian Held <sebastian.held@gmx.de>
+% 26. Aug 2010: initial version
+
+
+if nargin < 3
+ options = [];
+end
+
+fid = fopen( filename, 'w' );
+
+% create header
+header = [];
+header = [header 'M48\n'];
+header = [header '; EXCELLON file written by CSXCAD\n' ];
+header = [header '; ' datestr(now) '\n' ];
+header = [header 'METRIC,LZ\n'];
+header = [header 'VER,1\n'];
+header = [header 'FMAT,1\n'];
+
+if isfield(options,'header')
+ header = [header options.header];
+end
+
+% determine the drawing unit
+options.drawingunit = CSX.RectilinearGrid.ATTRIBUTE.DeltaUnit;
+
+if isfield(CSX.Properties,'Material')
+ % process material
+ Material = CSX.Properties.Material;
+ options.Property = 'Material';
+ [tools,drill] = process_primitives( Material, options );
+end
+if isfield(CSX.Properties,'Metal')
+ % process PEC
+ Metal = CSX.Properties.Metal;
+ options.Property = 'Metal';
+ [tools_,drill_] = process_primitives( Metal, options );
+ tools = unique( [tools tools_] );
+ drill = [drill drill_];
+end
+
+% check the generated tools
+[~,m] = unique( cellfun( @(x) x(1:3), tools, 'UniformOutput', 0 ) );
+if length(m) ~= numel(tools)
+ disp( 'the tool list is not unique:' );
+ disp( tools );
+ error( 'the tool list is not unique!' );
+end
+a = unique( cellfun( @(x) x(4), tools, 'UniformOutput', 0 ) );
+if (length(a) > 1) || (a ~= 'C')
+ disp( 'the tool list has errors:' );
+ disp( tools );
+ error( 'the tool list has errors!' );
+end
+
+% convert cell array of strings to string
+tools = char(cellfun( @(x)[x '\n'], tools ));
+drill = char(cellfun( @(x)[x '\n'], drill ));
+
+% save the file
+fprintf( fid, header );
+fprintf( fid, tools );
+fprintf( fid, '%s\n', 'M95' ); % end of program header
+fprintf( fid, drill );
+fprintf( fid, '%s\n', 'M00' ); % end
+fclose( fid );
+
+
+% -----------------------------------------------------------------------------
+function str = coord(v)
+% str = coord(v)
+% 2D-vector v takes coordinates in unit m
+x = sprintf( '%.3f', v(1)*1e3 ); % mm
+y = sprintf( '%.3f', v(2)*1e3 ); % mm
+str = ['X' x 'Y' y];
+
+% -----------------------------------------------------------------------------
+function [tool,drill] = primitive_cylinder( CSX_cylinder, drawingunit )
+start = [CSX_cylinder.P1.ATTRIBUTE.X CSX_cylinder.P1.ATTRIBUTE.Y] * drawingunit;
+stop = [CSX_cylinder.P2.ATTRIBUTE.X CSX_cylinder.P2.ATTRIBUTE.Y] * drawingunit;
+radius = CSX_cylinder.ATTRIBUTE.Radius * drawingunit;
+if start(1:2) == stop(1:2)
+ % via in z-plane
+ dia_mm = radius * 2 * 1e3; % mm
+ tool = sprintf( 'T%02iC1.3f', round(dia_mm*10), dia_mm );
+ drill = sprintf( 'T%02i\n%s', round(dia_mm*10), coord(start(1:2)) );
+else
+ disp( 'omitting primitive cylinder, because the projection onto the z-plane is not a circle' );
+end
+
+
+% -----------------------------------------------------------------------------
+function [tools,drill] = process_primitives( prop, options )
+exclude = {};
+if isfield(options,'exclude'), exclude = options.exclude; end
+for num=1:numel(prop)
+ Name = prop{num}.ATTRIBUTE.Name;
+ if any( strcmp(Name,exclude) )
+ disp( ['omitting ' Name '...'] );
+ continue
+ end
+ if isfield(options,'include')
+ include = options.include;
+ if ~any( strcmp(Name,include) )
+ disp( ['omitting ' Name '...'] );
+ continue
+ end
+ end
+
+ tools = {};
+ drill = {};
+
+ disp( ['processing ' prop{num}.ATTRIBUTE.Name '...'] );
+ fprintf( fid, '%s\n', ['%LN' Name '*%'] );
+ if isfield(prop{num}.Primitives,'Cylinder')
+ for a=1:numel(prop{num}.Primitives.Cylinder)
+ % iterate over all cylinders
+ Cylinder = prop{num}.Primitives.Cylinder{a};
+ [tool,drill_] = primitive_cylinder( fid, Cylinder );
+ tools = [tools tool];
+ drill = [drill drill_];
+ end
+ end
+end
+
diff --git a/CSXCAD/matlab/export_gerber.m b/CSXCAD/matlab/export_gerber.m
new file mode 100644
index 0000000..8a50f6f
--- /dev/null
+++ b/CSXCAD/matlab/export_gerber.m
@@ -0,0 +1,198 @@
+function export_gerber( CSX, filename, options )
+% export_gerber( CSX, filename, options )
+%
+% Exports the geometry defined in CSX to filename as a gerber RS-274X file.
+% The xy-plane is exported.
+%
+% CSX: CSX-object created by InitCSX()
+% filename: export filename (e.g. '/tmp/export.gbr')
+% options (optional): struct
+% .header: (string) add this to the header of the file
+% .ignore: (cell array) ignore these CSX-properties
+%
+% See also InitCSX
+% CSXCAD matlab interface
+% -----------------------
+% author: Sebastian Held <sebastian.held@gmx.de>
+% 13. Jun 2010: initial version
+
+%TODO:
+% .include: (cell array) include only these CSX-properties
+% if neither .ignore or .include is specified, process all properties
+
+if nargin < 3
+ options = [];
+end
+
+fid = fopen( filename, 'w' );
+
+% write header
+fprintf( fid, '%s\n', 'G04 gerber RS274X-file exported by openEMS*' );
+fprintf( fid, '%s\n', '%FSLAX66Y66*%' ); % leading zeros omitted; absolute coordinate values; 123456.123456
+fprintf( fid, '%s\n', '%MOMM*%' ); % set units to mm
+fprintf( fid, '%s\n', '%INopenEMS export*%' ); % image name
+fprintf( fid, '%s\n', '%ADD10C,0.00100*%' ); % aperture description
+if isfield(options,'header')
+ fprintf( fid, '%s\n', header );
+end
+
+global drawingunit
+drawingunit = CSX.RectilinearGrid.ATTRIBUTE.DeltaUnit;
+global CoordSystem
+CoordSystem = CSX.ATTRIBUTE.CoordSystem;
+
+if isfield(CSX.Properties,'Material')
+ % process material
+ Material = CSX.Properties.Material;
+ options.Property = 'Material';
+ process_primitives( fid, Material, options );
+end
+if isfield(CSX.Properties,'Metal')
+ % process PEC
+ Metal = CSX.Properties.Metal;
+ options.Property = 'Metal';
+ process_primitives( fid, Metal, options );
+end
+
+fprintf( fid, '%s\n', 'M02*' ); % end of program
+fclose( fid );
+
+
+% -----------------------------------------------------------------------------
+function str = gerber_coord(v, CoordSystem)
+global drawingunit
+
+if (CoordSystem==1)
+ r = v(1);
+ a = v(2);
+ v(1) = r*cos(a) * drawingunit;
+ v(2) = r*sin(a) * drawingunit;
+else
+ v(1) = v(1) * drawingunit;
+ v(2) = v(2) * drawingunit;
+end
+x = sprintf( '%+013i', round(v(1)*1e9) ); % mm
+y = sprintf( '%+013i', round(v(2)*1e9) ); % mm
+if (numel(x) ~= 13) || (numel(y) ~= 13)
+ error( ['gerber_coord(): coordinate transformation failed: x=' x ' y=' y] );
+end
+str = ['X' x 'Y' y];
+
+% -----------------------------------------------------------------------------
+function primitive_box( fid, CSX_box, CoordSystem )
+start = [CSX_box.P1.ATTRIBUTE.X CSX_box.P1.ATTRIBUTE.Y];
+stop = [CSX_box.P2.ATTRIBUTE.X CSX_box.P2.ATTRIBUTE.Y];
+
+if (CoordSystem==0)
+ fprintf( fid, '%s\n', 'G36*' );
+ fprintf( fid, '%s\n', [gerber_coord(start, CoordSystem) 'D02*'] );
+ fprintf( fid, '%s\n', [gerber_coord([stop(1) start(2)], CoordSystem) 'D01*'] );
+ fprintf( fid, '%s\n', [gerber_coord([stop], CoordSystem) 'D01*'] );
+ fprintf( fid, '%s\n', [gerber_coord([start(1) stop(2)], CoordSystem) 'D01*'] );
+ fprintf( fid, '%s\n', [gerber_coord(start, CoordSystem) 'D01*'] );
+ fprintf( fid, '%s\n', 'G37*' );
+elseif (CoordSystem==1)
+ r = sort([start(1) stop(1)]);
+ a = sort([start(2) stop(2)]);
+ max_arc = 0.5*pi/180;
+ a = linspace(a(1),a(2),ceil((a(2)-a(1))/max_arc));
+
+ fprintf( fid, '%s\n', 'G36*' );
+ fprintf( fid, '%s\n', [gerber_coord([r(1) a(1)], CoordSystem) 'D02*'] );
+
+ for ang = a(2:end)
+ fprintf( fid, '%s\n', [gerber_coord([r(1) ang], CoordSystem) 'D01*'] );
+ end
+
+ for ang = fliplr(a)
+ fprintf( fid, '%s\n', [gerber_coord([r(2) ang], CoordSystem) 'D01*'] );
+ end
+
+ fprintf( fid, '%s\n', [gerber_coord([r(1) a(1)], CoordSystem) 'D01*'] );
+ fprintf( fid, '%s\n', 'G37*' );
+else
+ error 'unknown coordinate system'
+end
+
+% -----------------------------------------------------------------------------
+function primitive_cylinder( fid, CSX_cylinder, CoordSystem )
+global drawingunit
+start = [CSX_cylinder.P1.ATTRIBUTE.X CSX_cylinder.P1.ATTRIBUTE.Y];
+stop = [CSX_cylinder.P2.ATTRIBUTE.X CSX_cylinder.P2.ATTRIBUTE.Y];
+radius = CSX_cylinder.ATTRIBUTE.Radius * drawingunit;
+if start(1:2) == stop(1:2)
+ % via => draw circle
+ fprintf( fid, '%%ADD10C,%f*%%\n', radius*2*1e3 ); % aperture definition (mm)
+ fprintf( fid, '%s\n', 'G54D10*' ); % select aperture D10
+ fprintf( fid, '%s\n', [gerber_coord(start, CoordSystem) 'D03*'] ); % flash
+else
+ disp( ['omitting primitive cylinder, because the projection onto the z-plane is not a circle'] );
+end
+
+
+% -----------------------------------------------------------------------------
+function primitive_polygon( fid, CSX_polygon, CoordSystem )
+if CSX_polygon.ATTRIBUTE.NormDir ~= 2
+ disp( ['omitting primitive polygon, because the normal direction is not 2'] );
+end
+fprintf( fid, '%s\n', 'G36*' );
+v = [CSX_polygon.Vertex{1}.ATTRIBUTE.X1 CSX_polygon.Vertex{1}.ATTRIBUTE.X2];
+fprintf( fid, '%s\n', [gerber_coord(v, CoordSystem) 'D02*'] );
+for a=2:numel(CSX_polygon.Vertex)
+ % iterate over all vertices
+ v = [CSX_polygon.Vertex{a}.ATTRIBUTE.X1 CSX_polygon.Vertex{a}.ATTRIBUTE.X2];
+ fprintf( fid, '%s\n', [gerber_coord(v, CoordSystem) 'D01*'] );
+end
+fprintf( fid, '%s\n', 'G37*' );
+
+% -----------------------------------------------------------------------------
+function primCoordSystem = GetCoordSystem(prim)
+global CoordSystem
+primCoordSystem = CoordSystem;
+if (isfield(prim.ATTRIBUTE,'CoordSystem'))
+ primCoordSystem = prim.ATTRIBUTE.CoordSystem;
+end
+
+% -----------------------------------------------------------------------------
+function process_primitives( fid, prop, options )
+ignore = {};
+if isfield(options,'ignore'), ignore = options.ignore; end
+for num=1:numel(prop)
+ Name = prop{num}.ATTRIBUTE.Name;
+ if any( strcmp(Name,ignore) )
+ disp( ['omitting ' Name '...'] );
+ continue
+ end
+ if strcmp(options.Property,'Material') && ~isfield(prop{num}.Property.ATTRIBUTE,'Kappa')
+ disp( ['omitting ' Name ' (no Kappa-value)...'] );
+ continue
+ end
+
+ disp( ['processing ' prop{num}.ATTRIBUTE.Name '...'] );
+ fprintf( fid, '%s\n', ['%LN' Name '*%'] );
+ if ~isfield(prop{num},'Primitives')
+ continue
+ end
+ if isfield(prop{num}.Primitives,'Box')
+ for a=1:numel(prop{num}.Primitives.Box)
+ % iterate over all boxes
+ Box = prop{num}.Primitives.Box{a};
+ primitive_box( fid, Box, GetCoordSystem(Box) );
+ end
+ end
+ if isfield(prop{num}.Primitives,'Cylinder')
+ for a=1:numel(prop{num}.Primitives.Cylinder)
+ % iterate over all cylinders
+ Cylinder = prop{num}.Primitives.Cylinder{a};
+ primitive_cylinder( fid, Cylinder, GetCoordSystem(Cylinder) );
+ end
+ end
+ if isfield(prop{num}.Primitives,'Polygon')
+ for a=1:numel(prop{num}.Primitives.Polygon)
+ % iterate over all polygons
+ Polygon = prop{num}.Primitives.Polygon{a};
+ primitive_polygon( fid, Polygon, GetCoordSystem(Polygon) );
+ end
+ end
+end
+
diff --git a/CSXCAD/matlab/export_povray.m b/CSXCAD/matlab/export_povray.m
new file mode 100644
index 0000000..a53cb13
--- /dev/null
+++ b/CSXCAD/matlab/export_povray.m
@@ -0,0 +1,237 @@
+function export_povray( CSX, filename, options )
+% export_povray( CSX, filename, options )
+%
+% Exports the geometry defined in CSX to filename as a povray file.
+%
+% CSX: CSX-object created by InitCSX()
+% filename: export filename (e.g. '/tmp/export.pov')
+% options (optional): struct
+% .camera: (string) use this as the camera definition line
+% 1 camera on positive x-axis
+% 2 camera on positive y-axis
+% 3 camera on positive z-axis
+% .light: (string) use this as the light definition line
+% 1 point light at camera position
+% .header: (string) add this to the header of the file
+% .ignore: (cell array) ignore these CSX-properties
+% .obj_modifier: struct
+% .<propname>: (string) povray object modifier for corresponding primitives
+% example: options.obj_modifier.copper = 'pigment { color rgbt <0.8,0.5,0,0> }';
+%
+% See also InitCSX
+% CSXCAD matlab interface
+% -----------------------
+% author: Sebastian Held <sebastian.held@gmx.de>
+% 12. Jun 2010: initial version
+
+if nargin < 3
+ options = [];
+end
+
+fid = fopen( filename, 'w' );
+
+% write header
+fprintf( fid, '%s\n', '// povray-file exported by openEMS' );
+fprintf( fid, '%s\n', '#include "colors.inc"' );
+fprintf( fid, '%s\n', '#include "metals.inc"' );
+fprintf( fid, '%s\n', '#include "textures.inc"' );
+fprintf( fid, '%s\n', '#include "transforms.inc"' );
+fprintf( fid, '%s\n', 'background { color rgb<1.000000,1.000000,1.000000> }' );
+if isfield(options,'header')
+ fprintf( fid, '%s\n', header );
+end
+
+if isfield(CSX.Properties,'Material')
+ % process material
+ Material = CSX.Properties.Material;
+ process_primitives( fid, Material, 'pigment { color rgbt <0.000, 0.533, 0.800,0.0> } finish { diffuse 0.6 }', options );
+end
+if isfield(CSX.Properties,'Metal')
+ % process PEC
+ Metal = CSX.Properties.Metal;
+ process_primitives( fid, Metal, 'texture { Copper_Metal }', options );
+end
+
+% create coordinate system vectors (for debugging)
+debug_coords = 0;
+if debug_coords
+ fprintf( fid, [...
+ '#macro Axis_( AxisLen, RedTexture,WhiteTexture) \n' ...
+ 'union{\n' ...
+ ' cylinder {<0,-AxisLen,0>,<0,AxisLen,0>,0.5\n' ...
+ ' texture{checker texture{RedTexture} \n' ...
+ ' texture{WhiteTexture}\n' ...
+ ' translate<0.1,0,0.1>}}\n' ...
+ ' cone{<0,AxisLen,0>,2,<0,AxisLen+0.7,0>,0\n' ...
+ ' texture{RedTexture}}\n' ...
+ ' } // end of union \n' ...
+ '#end // of macro "Axis( )"\n' ...
+ '\n' ...
+ '#macro AxisXYZ( AxisLenX, AxisLenY, AxisLenZ, TexRed, TexWhite)\n' ...
+ 'union{\n' ...
+ ' object{Axis_(AxisLenX, TexRed, TexWhite) rotate< 0,0,-90>} // x axis\n' ...
+ ' object{Axis_(AxisLenY, TexRed, TexWhite) rotate< 0,0, 0>} // y axis \n' ...
+ ' object{Axis_(AxisLenZ, TexRed, TexWhite) rotate<90,0, 0>} // z axis\n' ...
+ ' text{ ttf"timrom.ttf", "x", 0.15, 0 texture{TexRed} \n' ...
+ ' scale 10 translate <AxisLenX+0.05,0.4,-0.10>}\n' ...
+ ' text{ ttf"timrom.ttf", "y", 0.15, 0 texture{TexRed} \n' ...
+ ' scale 10 translate <-0.75,AxisLenY+0.50,-0.00>}\n' ...
+ ' text{ ttf"timrom.ttf", "z", 0.15, 0 texture{TexRed} \n' ...
+ ' scale 10 translate <-0.75,0.2,AxisLenZ+0.50>}\n' ...
+ ' scale <1000,1000,1000>\n' ...
+ '} // end of union\n' ...
+ '#end// of macro\n' ...
+ '\n' ...
+ 'object{AxisXYZ( 10, 10, 10, texture{ pigment{rgb<1,0,0>} finish{ phong 1}}, texture{ pigment{rgb<1,1,1>} finish{ phong 1}} )}\n' ...
+ ''] );
+end
+
+% create camera and light
+xmin = min(CSX.RectilinearGrid.XLines);
+xmax = max(CSX.RectilinearGrid.XLines);
+ymin = min(CSX.RectilinearGrid.YLines);
+ymax = max(CSX.RectilinearGrid.YLines);
+zmin = min(CSX.RectilinearGrid.ZLines);
+zmax = max(CSX.RectilinearGrid.ZLines);
+center = [(xmin+xmax)/2 (ymin+ymax)/2 (zmin+zmax)/2];
+% default camera
+camera_pos = [center(1), ymin, zmax+sqrt((xmax-xmin)^2+(ymax-ymin)^2)];
+camera = ['camera {location ' pov_vect(camera_pos) ' right <-1.33,0,0> look_at ' pov_vect(center) ' angle 40}']; % right-handed coordinate system
+if isfield(options,'camera')
+ if ischar(options.camera)
+ camera = options.camera;
+ elseif options.camera == 1
+ % looking from positive x-axis
+ camera_pos = [xmax+sqrt((ymax-ymin)^2+(zmax-zmin)^2), 0, 0];
+ camera = ['camera {location ' pov_vect(camera_pos) ' right <-1.33,0,0> look_at ' pov_vect(center) ' angle 40}'];
+ elseif options.camera == 2
+ % looking from positive y-axis
+ camera_pos = [0, ymax+sqrt((xmax-xmin)^2+(zmax-zmin)^2), 0];
+ camera = ['camera {location ' pov_vect(camera_pos) ' right <-1.33,0,0> look_at ' pov_vect(center) ' angle 40}'];
+ elseif options.camera == 3
+ % looking from positive z-axis
+ camera_pos = [0, 0, zmax+sqrt((xmax-xmin)^2+(ymax-ymin)^2)];
+ camera = ['camera {location ' pov_vect(camera_pos) ' right <-1.33,0,0> look_at ' pov_vect(center) ' angle 40}'];
+ end
+end
+fprintf( fid, '%s\n', camera );
+% default light
+light = 'light_source { <3500,-3500,10000> White area_light <10000, 0, 0>, <0, 10000, 0>, 2, 2 adaptive 1 }';
+if isfield(options,'light')
+ if ischar(options.light)
+ light = options.light;
+ elseif options.light == 1
+ % point light at position of camera
+ light = ['light_source { ' pov_vect(camera_pos) ', rgb <1,1,1> }'];
+ end
+end
+fprintf( fid, '%s\n', light );
+
+fclose( fid );
+
+% -----------------------------------------------------------------------------
+function str = pov_vect( vec )
+if numel(vec) == 3
+ str = ['<' num2str(vec(1)) ',' num2str(vec(2)) ',' num2str(vec(3)) '>'];
+else
+ str = ['<' num2str(vec(1)) ',' num2str(vec(2)) '>'];
+end
+
+% -----------------------------------------------------------------------------
+function str = primitive_box( CSX_box, options )
+start = [CSX_box.P1.ATTRIBUTE.X CSX_box.P1.ATTRIBUTE.Y CSX_box.P1.ATTRIBUTE.Z];
+stop = [CSX_box.P2.ATTRIBUTE.X CSX_box.P2.ATTRIBUTE.Y CSX_box.P2.ATTRIBUTE.Z];
+if any( start == stop )
+ % 2D box
+ % povray supports 2D polygons, but has no priority concept, therefore use the box primitive
+ epsilon = 1; % FIXME this should be small compared to any other linear dimension of any object in the scene
+ epsilon = (start == stop) * epsilon; % select identical components
+ start = start - epsilon;
+ stop = stop + epsilon;
+end
+str = ['box { ' pov_vect(start) ', ' pov_vect(stop) ' ' options '}'];
+
+% -----------------------------------------------------------------------------
+function str = primitive_cylinder( CSX_cylinder, options )
+start = [CSX_cylinder.P1.ATTRIBUTE.X CSX_cylinder.P0.ATTRIBUTE.Y CSX_cylinder.P1.ATTRIBUTE.Z];
+stop = [CSX_cylinder.P2.ATTRIBUTE.X CSX_cylinder.P1.ATTRIBUTE.Y CSX_cylinder.P2.ATTRIBUTE.Z];
+radius = CSX_cylinder.ATTRIBUTE.Radius;
+str = ['cylinder { ' pov_vect(start) ', ' pov_vect(stop) ', ' num2str(radius) ' ' options '}'];
+
+% -----------------------------------------------------------------------------
+function str = primitive_wire( CSX_wire, options )
+radius = CSX_wire.ATTRIBUTE.WireRadius;
+str = ['sphere_sweep { linear_spline, ' num2str(numel(CSX_wire.Vertex))];
+for a=1:numel(CSX_wire.Vertex)
+ % iterate over all vertices
+ v = [CSX_wire.Vertex{a}.ATTRIBUTE.X CSX_wire.Vertex{a}.ATTRIBUTE.Y CSX_wire.Vertex{a}.ATTRIBUTE.Z];
+ str = [str ', ' pov_vect(v) ', ' num2str(radius)];
+end
+str = [str ' ' options '}'];
+
+% -----------------------------------------------------------------------------
+function str = primitive_polygon( CSX_polygon, options )
+Elevation = -CSX_polygon.ATTRIBUTE.Elevation;
+% NormDir = CSX_polygon.ATTRIBUTE.NormDir;
+epsilon = 1; % FIXME this should be small compared to any other linear dimension of any object in the scene
+str = ['prism { linear_spline linear_sweep ' num2str(Elevation - epsilon) ', ' num2str(Elevation + epsilon) ', ' num2str(numel(CSX_polygon.Vertex)+1)];
+for a=1:numel(CSX_polygon.Vertex)
+ % iterate over all vertices
+ v = [CSX_polygon.Vertex{a}.ATTRIBUTE.X1 CSX_polygon.Vertex{a}.ATTRIBUTE.X2];
+ str = [str ', ' pov_vect(v)];
+end
+v = [CSX_polygon.Vertex{1}.ATTRIBUTE.X1 CSX_polygon.Vertex{1}.ATTRIBUTE.X2]; % close prism
+str = [str ', ' pov_vect(v)];
+% str = [str ' ' options ' Point_At_Trans(' pov_vect(NormDir) ')}']; % needs transforms.inc
+str = [str ' ' options ' rotate<-90,0,0> }'];
+
+% -----------------------------------------------------------------------------
+function process_primitives( fid, prop, default_obj_modifier, options )
+ignore = {};
+if isfield(options,'ignore'), ignore = options.ignore; end
+for num=1:numel(prop)
+ Name = prop{num}.ATTRIBUTE.Name;
+ if any( strcmp(Name,ignore) )
+ disp( ['omitting ' Name '...'] );
+ continue
+ end
+ obj_modifier = default_obj_modifier;
+ if isfield(options,'obj_modifier') && isfield(options.obj_modifier,Name)
+ obj_modifier = options.obj_modifier.(Name);
+ end
+ disp( ['processing ' prop{num}.ATTRIBUTE.Name '...'] );
+ fprintf( fid, '%s\n', ['// ' Name] );
+ if isfield(prop{num}.Primitives,'Box')
+ for a=1:numel(prop{num}.Primitives.Box)
+ % iterate over all boxes
+ Box = prop{num}.Primitives.Box{a};
+ str = primitive_box( Box, obj_modifier );
+ fprintf( fid, '%s\n', str );
+ end
+ end
+ if isfield(prop{num}.Primitives,'Cylinder')
+ for a=1:numel(prop{num}.Primitives.Cylinder)
+ % iterate over all cylinders
+ Cylinder = prop{num}.Primitives.Cylinder{a};
+ str = primitive_cylinder( Cylinder, obj_modifier );
+ fprintf( fid, '%s\n', str );
+ end
+ end
+ if isfield(prop{num}.Primitives,'Wire')
+ for a=1:numel(prop{num}.Primitives.Wire)
+ % iterate over all wires
+ Wire = prop{num}.Primitives.Wire{a};
+ str = primitive_wire( Wire, obj_modifier );
+ fprintf( fid, '%s\n', str );
+ end
+ end
+ if isfield(prop{num}.Primitives,'Polygon')
+ for a=1:numel(prop{num}.Primitives.Polygon)
+ % iterate over all polygons
+ Polygon = prop{num}.Primitives.Polygon{a};
+ str = primitive_polygon( Polygon, obj_modifier );
+ fprintf( fid, '%s\n', str );
+ end
+ end
+end
+
diff --git a/CSXCAD/matlab/isOctave.m b/CSXCAD/matlab/isOctave.m
new file mode 100644
index 0000000..b536e48
--- /dev/null
+++ b/CSXCAD/matlab/isOctave.m
@@ -0,0 +1,46 @@
+function [isOct,ver] = isOctave()
+% [isOct,version] = isOctave()
+%
+% Function to test if matlab or octave is used.
+%
+% Output:
+% isOct: bool; true, if interpreter is Octave
+% version: struct
+% .major: number; major version
+% .minor: number; minor version
+% .release: number; release version
+%
+% example (Octave 3.6.1):
+% isOct = true
+% version.major = 3
+% version.minor = 6
+% version.release = 1
+%
+% example (Matlab 7.8.0.347 (R2009a)):
+% isOct = false
+% version.major = 7
+% version.minor = 8
+% version.release = 0
+%
+% openEMS matlab/octave interface
+% -----------------------
+% (C) 2011 Thorsten Liebig <thorsten.leibig@gmx.de>
+% (C) 2012 Sebastian Held <sebastian.held@gmx.de>
+
+isOct = exist('OCTAVE_VERSION','builtin') ~= 0;
+
+if (isOct)
+ ver_cell = strsplit( OCTAVE_VERSION, '.' );
+else
+ remain = version();
+ ver_cell = {};
+ while ~isempty(remain)
+ [str, remain] = strtok(remain, '.');
+ ver_cell{end+1} = str;
+ end
+end
+
+ver = [];
+ver.major = str2double(ver_cell{1});
+ver.minor = str2double(ver_cell{2});
+ver.release = str2double(ver_cell{3});
diff --git a/CSXCAD/matlab/private/Add2Property.m b/CSXCAD/matlab/private/Add2Property.m
new file mode 100644
index 0000000..e38ddc9
--- /dev/null
+++ b/CSXCAD/matlab/private/Add2Property.m
@@ -0,0 +1,26 @@
+function CSX = Add2Property(CSX, propName, newPrim, primName)
+% function CSX = Add2Property(CSX, propName, newPrim, primName)
+%
+% meant for internal use!!
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+type = GetPropertyType(CSX, propName);
+if isempty(type)
+ error('CSXCAD:Add2Property',['the type for the property "' propName '" cannot be found']);
+end
+
+pos = GetPropertyPosition(CSX, type, propName);
+if (pos==0)
+ error('CSXCAD:Add2Property',['property "' propName '" of type "' type '" not found!']);
+end
+
+if ~isfield(CSX.Properties.(type){pos}, 'Primitives')
+ CSX.Properties.(type){pos}.Primitives.(primName){1}=newPrim;
+elseif ~isfield(CSX.Properties.(type){pos}.Primitives, primName)
+ CSX.Properties.(type){pos}.Primitives.(primName){1}=newPrim;
+else
+ CSX.Properties.(type){pos}.Primitives.(primName){end+1}=newPrim;
+end
diff --git a/CSXCAD/matlab/private/AddPrimitiveArgs.m b/CSXCAD/matlab/private/AddPrimitiveArgs.m
new file mode 100644
index 0000000..df3cf28
--- /dev/null
+++ b/CSXCAD/matlab/private/AddPrimitiveArgs.m
@@ -0,0 +1,28 @@
+function primitive = AddPrimitiveArgs(primitive, varargin)
+% prim = AddPrimitiveArgs(primitive, varargin)
+%
+% meant for internal use only
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+transform = [];
+
+for n=1:2:(nargin-2)
+ if (strcmp(varargin{n},'Transform'))
+ transform = varargin([n:n+1]);
+ varargin([n:n+1]) = [];
+ break
+ end
+end
+
+for n=1:2:numel(varargin)
+ primitive.ATTRIBUTE.(varargin{n}) = varargin{n+1};
+end
+
+if ~isempty(transform)
+ for n=1:2:numel(transform{2})
+ primitive.Transformation.(transform{2}{n}).ATTRIBUTE.Argument=transform{2}{n+1};
+ end
+end
diff --git a/CSXCAD/matlab/private/AddProperty.m b/CSXCAD/matlab/private/AddProperty.m
new file mode 100644
index 0000000..ec4c2ed
--- /dev/null
+++ b/CSXCAD/matlab/private/AddProperty.m
@@ -0,0 +1,29 @@
+function [CSX pos] = AddProperty(CSX, type, name, varargin)
+% function [CSX pos] = AddProperty(CSX, type, name, varargin)
+%
+% internal function to add a property to CSX.Properties
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+% check if this property already exists
+[type_found pos] = FindProperty(CSX, name);
+if (pos>0)
+ error('CSXCAD:AddProperty',['property with name "' name '" with type "' type_found '" already exists! Choose a different name!']);
+end
+
+if isfield(CSX.Properties,type)
+ pos = numel(CSX.Properties.(type))+1;
+else
+ CSX.Properties.(type) = {}; % create cell array
+ pos = 1;
+end
+
+CSX.Properties.(type){pos}.ATTRIBUTE.Name=name;
+for n=1:numel(varargin)/2
+ if ~ischar(varargin{2*n-1})
+ error(['CSXCAD::AddProperty: not an attribute: ' varargin{2*n-1}]);
+ end
+ CSX.Properties.(type){pos}.ATTRIBUTE.(varargin{2*n-1})=varargin{2*n};
+end
diff --git a/CSXCAD/matlab/private/CheckSymmtricLines.m b/CSXCAD/matlab/private/CheckSymmtricLines.m
new file mode 100644
index 0000000..6106d63
--- /dev/null
+++ b/CSXCAD/matlab/private/CheckSymmtricLines.m
@@ -0,0 +1,34 @@
+function result = CheckSymmtricLines(lines)
+% function result = CheckSymmtricLines(lines)
+%
+% check mesh lines for symmetry
+%
+% Note: make sure lines are sorted and unique
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (C) 2012
+
+result = false;
+
+tolerance = 1e-10;
+NP = numel(lines);
+range = lines(end)-lines(1);
+center = 0.5*(lines(end)+lines(1));
+
+% check all lines for symmetry
+for n=1:NP/2
+ if (abs((center-lines(n))-(lines(end-n+1)-center)) > range*tolerance/NP)
+ return;
+ end
+end
+
+% check central point to be symmetry-center
+if (mod(NP,2))
+ if (abs(lines((NP+1)/2)-center) > range*tolerance/NP)
+ return;
+ end
+end
+
+% if all checks pass, return true
+result = true;
diff --git a/CSXCAD/matlab/private/FindProperty.m b/CSXCAD/matlab/private/FindProperty.m
new file mode 100644
index 0000000..1df5ef6
--- /dev/null
+++ b/CSXCAD/matlab/private/FindProperty.m
@@ -0,0 +1,17 @@
+function [type pos] = FindProperty(CSX, name)
+% function [type pos] = FindProperty(CSX, name)
+%
+% internal function to find a given property
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (c) 2013
+
+pos = 0;
+type = GetPropertyType(CSX, name);
+
+if isempty(type)
+ return;
+end
+
+pos = GetPropertyPosition(CSX, type, name);
diff --git a/CSXCAD/matlab/private/GetPropertyPosition.m b/CSXCAD/matlab/private/GetPropertyPosition.m
new file mode 100644
index 0000000..8305876
--- /dev/null
+++ b/CSXCAD/matlab/private/GetPropertyPosition.m
@@ -0,0 +1,41 @@
+function pos = GetPropertyPosition(CSX, type, name)
+% function pos = GetPropertyPosition(CSX, type, name)
+%
+% - internal function to get the position of property with name: <name>
+% inside a given type
+% - function will perform a series of validitiy tests
+% - will return 0 if not found
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (c) 2013
+
+pos = 0;
+
+if ~ischar(name)
+ error('CSXCAD::GetPropertyPosition: name must be a string');
+end
+
+if ~ischar(type)
+ error('CSXCAD::GetPropertyPosition: type name must be a string');
+end
+
+if ~isfield(CSX,'Properties')
+ error('CSXCAD:GetPropertyPosition','CSX.Properties is not defined');
+end
+
+if isempty(type)
+ error('CSXCAD:GetPropertyPosition','type is empty, maybe the property you requested is undefined');
+end
+
+% type not (yet) defined, thus <name> not found
+if ~isfield(CSX.Properties,type)
+ return
+end
+
+for n=1:numel(CSX.Properties.(type))
+ if strcmp(CSX.Properties.(type){n}.ATTRIBUTE.Name, name)
+ pos=n;
+ return
+ end
+end
diff --git a/CSXCAD/matlab/private/GetPropertyType.m b/CSXCAD/matlab/private/GetPropertyType.m
new file mode 100644
index 0000000..5a63dff
--- /dev/null
+++ b/CSXCAD/matlab/private/GetPropertyType.m
@@ -0,0 +1,30 @@
+function type_name = GetPropertyType(CSX, name)
+% function type_name = GetPropertyType(CSX, name)
+%
+% internal function to get the type of a given property
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig (c) 2010-2013
+
+if ~ischar(name)
+ error('CSXCAD::GetPropertyType: name must be a string');
+end
+if ~isfield(CSX,'Properties')
+ error('CSXCAD:GetPropertyPosition','CSX.Properties is not defined');
+end
+
+type_name = '';
+if isempty(CSX.Properties)
+ return
+end
+
+prop_types = fieldnames(CSX.Properties);
+for n=1:numel(prop_types)
+ for p = 1:numel(CSX.Properties.(prop_types{n}))
+ if (strcmp(CSX.Properties.(prop_types{n}){p}.ATTRIBUTE.Name,name))
+ type_name = prop_types{n};
+ return;
+ end
+ end
+end
diff --git a/CSXCAD/matlab/private/SetPropertyArgs.m b/CSXCAD/matlab/private/SetPropertyArgs.m
new file mode 100644
index 0000000..893a642
--- /dev/null
+++ b/CSXCAD/matlab/private/SetPropertyArgs.m
@@ -0,0 +1,16 @@
+function CSX = SetPropertyArgs(CSX, type, name, property, varargin)
+% CSX = SetPropertyArgs(CSX, type, name, property, varargin)
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+pos = GetPropertyPosition(CSX, type, name);
+
+if (pos==0)
+ error('CSXCAD:SetPropertyArgs',['property "' name '" of type "' type '" not found!']);
+end
+
+for n=1:numel(varargin)/2
+ CSX.Properties.(type){pos}.(property).ATTRIBUTE.(varargin{2*n-1}) = varargin{2*n};
+end
diff --git a/CSXCAD/matlab/private/SmoothRange.m b/CSXCAD/matlab/private/SmoothRange.m
new file mode 100644
index 0000000..d36db70
--- /dev/null
+++ b/CSXCAD/matlab/private/SmoothRange.m
@@ -0,0 +1,58 @@
+function [ lines ] = SmoothRange(start, stop, start_res, stop_res, max_res, ratio)
+%function [ lines ] = SmoothRange(start, stop, start_res, stop_res, max_res, ratio)
+%
+% internal function only, use SmoothMeshLines instead
+%
+% See also SmoothMeshLines
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Thorsten Liebig
+
+if (nargin<6)
+ ratio = 1.3;
+end
+
+taper = start_res*ratio;
+start_taper = start;
+while (taper<max_res)
+ start_taper = [start_taper start_taper(end)+taper];
+ taper = taper*ratio;
+end
+
+taper = stop_res*ratio;
+stop_taper = stop;
+while (taper<max_res)
+ stop_taper = [stop_taper stop_taper(end)-taper];
+ taper = taper*ratio;
+end
+stop_taper = sort(stop_taper);
+
+while ( (abs(stop_taper(1) - start_taper(end)) < max_res) || (stop_taper(1) < start_taper(end)) )
+
+ diff_start = diff(start_taper);
+ if isempty(diff_start)
+ diff_start = 0;
+ end
+ diff_stop = diff([stop_taper]);
+ if isempty(diff_stop)
+ diff_stop = 0;
+ end
+
+ if (diff_start(end)>diff_stop(1))
+ start_taper = start_taper(1:end-1);
+ else
+ stop_taper = stop_taper(2:end);
+ end
+
+ if (numel(stop_taper)==0) || (numel(start_taper)==0)
+ break
+ end
+end
+
+if (numel(stop_taper)==0) || (numel(start_taper)==0)
+ lines = unique([start_taper stop_taper]);
+else
+ numL = ceil((stop_taper(1) - start_taper(end))/max_res)+1;
+ lines = unique([start_taper linspace(start_taper(end),stop_taper(1),numL) stop_taper]);
+end \ No newline at end of file
diff --git a/CSXCAD/matlab/private/octave_struct2xml_2.m b/CSXCAD/matlab/private/octave_struct2xml_2.m
new file mode 100644
index 0000000..3ebc549
--- /dev/null
+++ b/CSXCAD/matlab/private/octave_struct2xml_2.m
@@ -0,0 +1,57 @@
+function out = octave_struct2xml_2( in, rootName, indent )
+
+out = [indent '<' rootName];
+
+float_accuracy = 15;
+
+% process attributes
+if isstruct( in )
+ fnames = fieldnames( in );
+ for n=1:numel(fnames)
+ current_field = fnames{n};
+ if strcmp( current_field, 'ATTRIBUTE' )
+ attributes = fieldnames( in.ATTRIBUTE );
+ for m=1:numel( attributes )
+ temp = in.ATTRIBUTE.(attributes{m});
+ if ~ischar( temp )
+ temp = vector2str( temp, float_accuracy );
+ end
+ out = [out ' ' attributes{m} '="' temp '"'];
+ end
+ break
+ end
+ end
+end
+
+out = [out '>'];
+
+
+% process content
+if ~isstruct( in )
+ if ~ischar( in )
+ temp = vector2str(in, float_accuracy);
+ else
+ temp = in;
+ end
+ out = [out temp '</' rootName '>\n'];
+ return
+end
+
+out = [out '\n'];
+
+fnames = fieldnames( in );
+for n=1:numel(fnames)
+ current_field = fnames{n};
+ if strcmp( current_field, 'ATTRIBUTE' )
+ continue
+ end
+ if iscell( in.(current_field) )
+ for m=1:numel( in.(current_field) )
+ out = [out octave_struct2xml_2( in.(current_field){m}, current_field, [indent ' '] )];
+ end
+ else
+ out = [out octave_struct2xml_2( in.(current_field), current_field, [indent ' '] )];
+ end
+end
+
+out = [out indent '</' rootName '>\n'];
diff --git a/CSXCAD/matlab/private/struct_2_xmlNode.m b/CSXCAD/matlab/private/struct_2_xmlNode.m
new file mode 100644
index 0000000..207632f
--- /dev/null
+++ b/CSXCAD/matlab/private/struct_2_xmlNode.m
@@ -0,0 +1,48 @@
+function docElem = struct_2_xmlNode(docNode, docElem, mat_struct)
+
+if (isfield(mat_struct,'ATTRIBUTE'))
+ names = fieldnames(mat_struct.ATTRIBUTE);
+ for n=1:numel(names)
+ if isnumeric(getfield(mat_struct.ATTRIBUTE,names{n})) || islogical(getfield(mat_struct.ATTRIBUTE,names{n}))
+ docElem.setAttribute(names{n},vector2str(getfield(mat_struct.ATTRIBUTE,names{n}),15));
+ else
+ docElem.setAttribute(names{n},getfield(mat_struct.ATTRIBUTE,names{n}));
+ end
+ end
+ mat_struct = rmfield(mat_struct,'ATTRIBUTE');
+end
+
+names = fieldnames(mat_struct);
+
+for n=1:numel(names)
+ if isstruct(getfield(mat_struct,names{n}))
+ docNewElem = docNode.createElement(names{n});
+ docNewElem = struct_2_xmlNode(docNode, docNewElem, getfield(mat_struct,names{n}));
+ docElem.appendChild(docNewElem);
+ elseif iscell(getfield(mat_struct,names{n}))
+ cellfield = getfield(mat_struct,names{n});
+ for m=1:numel(cellfield)
+ if ischar(cellfield{m})
+ docNewElem = docNode.createElement(names{n});
+ docNewElem.appendChild(docNode.createTextNode(cellfield{m}));
+ docElem.appendChild(docNewElem);
+ else
+ docNewElem = docNode.createElement(names{n});
+ docNewElem = struct_2_xmlNode(docNode, docNewElem, cellfield{m});
+ docElem.appendChild(docNewElem);
+ end
+ end
+ elseif isempty(getfield(mat_struct,names{n}))
+ %do nothing...
+ elseif isnumeric(getfield(mat_struct,names{n}))
+ number = getfield(mat_struct,names{n});
+ str = vector2str(number,15);
+ docNewElem = docNode.createElement(names{n});
+ docNewElem.appendChild(docNode.createTextNode(str));
+ docElem.appendChild(docNewElem);
+ elseif ischar(getfield(mat_struct,names{n}))
+ docNewElem = docNode.createElement(names{n});
+ docNewElem.appendChild(docNode.createTextNode(getfield(mat_struct,names{n})));
+ docElem.appendChild(docNewElem);
+ end
+end
diff --git a/CSXCAD/matlab/private/vector2str.m b/CSXCAD/matlab/private/vector2str.m
new file mode 100644
index 0000000..5e3685b
--- /dev/null
+++ b/CSXCAD/matlab/private/vector2str.m
@@ -0,0 +1,35 @@
+function str = vector2str(vec, acc)
+% str = vector2str( vec [, acc] )
+%
+% internal function for CSXCAD
+%
+% (c) 2012-2015 Thorsten Liebig <thorsten.liebig@gmx.de>
+% (C) 2012 Sebastian Held <sebastian.held@gmx.de>
+
+str = '';
+
+if (numel(vec)==0)
+ return
+end
+
+if (nargin<2)
+ acc = 9;
+end
+
+% Octave < 3.8.0 has a bug in num2str() (only 64bit versions)
+% see bug report https://savannah.gnu.org/bugs/index.php?36121
+[isOct,version] = isOctave();
+if (isOct && version.major <= 3 && version.minor < 8)
+ % affected Octave versions
+ for n = 1:numel(vec)
+ str = [str sprintf('%.*g', acc, vec(n)) ','];
+ end
+else
+ % Matlab and non affected Octave
+ for n = 1:numel(vec)
+ str = [str num2str(vec(n),acc) ','];
+ end
+end
+
+% remove the last ','
+str = str(1:end-1);
diff --git a/CSXCAD/matlab/searchBinary.m b/CSXCAD/matlab/searchBinary.m
new file mode 100644
index 0000000..6310dde
--- /dev/null
+++ b/CSXCAD/matlab/searchBinary.m
@@ -0,0 +1,47 @@
+function [binary_location] = searchBinary(name, searchpath, err_fail)
+% [binary_location] = searchBinary(name, searchpath<, err_fail>)
+%
+% Function to search for executable. If the executable isn't found
+% in searchpath, look in environment search path.
+%
+% parameter:
+% name: name of the binary to search
+% searchpath: (list of) search paths
+% err_fail: 0/1, throw an error if binary is not found (default is 1)
+%
+% Output:
+% binary_location:
+% if found in searchpath: full path of binary
+% if found in environment search path: name of binary
+% if not found: empty string
+%
+%
+% openEMS matlab/octave interface
+% -----------------------
+% (C) 2013 Stefan Mahr <dac922@gmx.de>
+
+if (nargin<3)
+ err_fail = 1;
+end
+
+if ischar(searchpath)
+ searchpath = {searchpath};
+end
+
+% append PATH search paths
+searchpath = [searchpath regexp(getenv('PATH'), pathsep, 'split')];
+
+% try all search paths
+for n=1:numel(searchpath)
+ binary_location = [searchpath{n} name];
+ if exist(binary_location, 'file')
+ return
+ end
+end
+
+% binary not found
+binary_location = '';
+
+if (err_fail)
+ error('CSXCAD:binary_location', [name ' binary not found!']);
+end
diff --git a/CSXCAD/matlab/struct_2_xml.m b/CSXCAD/matlab/struct_2_xml.m
new file mode 100644
index 0000000..73c0a30
--- /dev/null
+++ b/CSXCAD/matlab/struct_2_xml.m
@@ -0,0 +1,23 @@
+function struct_2_xml(filename, xml_struct, rootName);
+
+if ~isOctave()
+ docNode = com.mathworks.xml.XMLUtils.createDocument(rootName);
+ docElem = docNode.getDocumentElement;
+
+ docElem = struct_2_xmlNode(docNode, docElem, xml_struct);
+
+ % Save the sample XML document.
+ xmlFileName = [filename];
+ xmlwrite(xmlFileName,docNode);
+else
+% % for octave you need the octave_xmltoolbox (C) 2007 Thomas Geiger
+% % http://wiki.octave.org/wiki.pl?XMLToolboxPort
+% xml_struct = octave_struct2xml( xml_struct, rootName );
+% xml_save( filename, xml_struct, 'any' );
+
+% xml_toolbox is buggy (sequence of elements is not preserved)
+ fid = fopen( filename, 'w' );
+ fprintf( fid, '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n' );
+ fprintf( fid, octave_struct2xml_2(xml_struct,rootName,'') );
+ fclose( fid );
+end
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 Lic