/* * Copyright (C) 2008,2009,2010 Thorsten Liebig (Thorsten.Liebig@gmx.de) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include #include "tinyxml.h" #include "stdint.h" #include "CSPrimitives.h" #include "CSProperties.h" #include "CSFunctionParser.h" #include "CSUseful.h" #include #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::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::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; } CSTransform* CSPrimitives::GetTransform() { if (m_Transform==NULL) m_Transform = new CSTransform(clParaSet); return m_Transform; } 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 (m_Transform!=NULL) if (m_Transform->HasTransform()) 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; } 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); }