FemMesh.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) Jürgen Riegel          (juergen.riegel@web.de) 2009     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 
00026 #ifndef _PreComp_
00027 # include <cstdlib>
00028 # include <memory>
00029 # include <strstream>
00030 # include <Bnd_Box.hxx>
00031 # include <BRepBndLib.hxx>
00032 #endif
00033 
00034 #include <Base/Writer.h>
00035 #include <Base/Reader.h>
00036 #include <Base/Stream.h>
00037 #include <Base/Exception.h>
00038 #include <Base/FileInfo.h>
00039 
00040 #include <Mod/Mesh/App/Core/MeshKernel.h>
00041 #include <Mod/Mesh/App/Core/Evaluation.h>
00042 #include <Mod/Mesh/App/Core/Iterator.h>
00043 
00044 #include "FemMesh.h"
00045 
00046 #include <SMESH_Gen.hxx>
00047 #include <SMESH_Mesh.hxx>
00048 #include <SMDS_PolyhedralVolumeOfNodes.hxx>
00049 #include <SMDS_VolumeTool.hxx>
00050 #include <StdMeshers_MaxLength.hxx>
00051 #include <StdMeshers_LocalLength.hxx>
00052 #include <StdMeshers_MaxElementArea.hxx>
00053 #include <StdMeshers_NumberOfSegments.hxx>
00054 #include <StdMeshers_Deflection1D.hxx>
00055 #include <StdMeshers_Regular_1D.hxx>
00056 #include <StdMeshers_StartEndLength.hxx>
00057 #include <StdMeshers_QuadranglePreference.hxx>
00058 #include <StdMeshers_Quadrangle_2D.hxx>
00059 #include <StdMeshers_QuadraticMesh.hxx>
00060 
00061 
00062 using namespace Fem;
00063 using namespace Base;
00064 
00065 TYPESYSTEM_SOURCE(Fem::FemMesh , Base::Persistence);
00066 
00067 FemMesh::FemMesh()
00068 {
00069     myGen = new SMESH_Gen();
00070     myMesh = myGen->CreateMesh(1,false);
00071 }
00072 
00073 FemMesh::FemMesh(const FemMesh& mesh)
00074 {
00075     myGen = new SMESH_Gen();
00076     myMesh = myGen->CreateMesh(1,false);
00077     copyMeshData(mesh);
00078 }
00079 
00080 FemMesh::~FemMesh()
00081 {
00082     TopoDS_Shape aNull;
00083     myMesh->ShapeToMesh(aNull);
00084     myMesh->Clear();
00085     //myMesh->ClearLog();
00086     delete myMesh;
00087 #if defined(__GNUC__)
00088     delete myGen; // crashes with MSVC
00089 #endif
00090 }
00091 
00092 FemMesh &FemMesh::operator=(const FemMesh& mesh)
00093 {
00094     if (this != &mesh) {
00095         copyMeshData(mesh);
00096     }
00097     return *this;
00098 }
00099 
00100 void FemMesh::copyMeshData(const FemMesh& mesh)
00101 {
00102     const SMDS_MeshInfo& info = mesh.myMesh->GetMeshDS()->GetMeshInfo();
00103     //int numPoly = info.NbPolygons();
00104     //int numVolu = info.NbVolumes();
00105     //int numTetr = info.NbTetras();
00106     //int numHexa = info.NbHexas();
00107     //int numPyrd = info.NbPyramids();
00108     //int numPris = info.NbPrisms();
00109     //int numHedr = info.NbPolyhedrons();
00110 
00111     SMESHDS_Mesh* meshds = this->myMesh->GetMeshDS();
00112     meshds->ClearMesh();
00113 
00114     SMDS_NodeIteratorPtr aNodeIter = mesh.myMesh->GetMeshDS()->nodesIterator();
00115     for (;aNodeIter->more();) {
00116         const SMDS_MeshNode* aNode = aNodeIter->next();
00117         meshds->AddNodeWithID(aNode->X(),aNode->Y(),aNode->Z(), aNode->GetID());
00118     }
00119 
00120     SMDS_EdgeIteratorPtr aEdgeIter = mesh.myMesh->GetMeshDS()->edgesIterator();
00121     for (;aEdgeIter->more();) {
00122         const SMDS_MeshEdge* aEdge = aEdgeIter->next();
00123         meshds->AddEdgeWithID(aEdge->GetNode(0), aEdge->GetNode(1), aEdge->GetID());
00124     }
00125 
00126     SMDS_FaceIteratorPtr aFaceIter = mesh.myMesh->GetMeshDS()->facesIterator();
00127     for (;aFaceIter->more();) {
00128         const SMDS_MeshFace* aFace = aFaceIter->next();
00129         switch (aFace->NbNodes()) {
00130             case 3:
00131                 meshds->AddFaceWithID(aFace->GetNode(0),
00132                                       aFace->GetNode(1),
00133                                       aFace->GetNode(2),
00134                                       aFace->GetID());
00135                 break;
00136             case 4:
00137                 meshds->AddFaceWithID(aFace->GetNode(0),
00138                                       aFace->GetNode(1),
00139                                       aFace->GetNode(2),
00140                                       aFace->GetNode(3),
00141                                       aFace->GetID());
00142                 break;
00143             case 6:
00144                 meshds->AddFaceWithID(aFace->GetNode(0),
00145                                       aFace->GetNode(1),
00146                                       aFace->GetNode(2),
00147                                       aFace->GetNode(3),
00148                                       aFace->GetNode(4),
00149                                       aFace->GetNode(5),
00150                                       aFace->GetID());
00151                 break;
00152             case 8:
00153                 meshds->AddFaceWithID(aFace->GetNode(0),
00154                                       aFace->GetNode(1),
00155                                       aFace->GetNode(2),
00156                                       aFace->GetNode(3),
00157                                       aFace->GetNode(4),
00158                                       aFace->GetNode(5),
00159                                       aFace->GetNode(6),
00160                                       aFace->GetNode(7),
00161                                       aFace->GetID());
00162                 break;
00163             default:
00164                 {
00165                     std::vector<const SMDS_MeshNode*> aNodes;
00166                     for (int i=0; aFace->NbNodes(); i++)
00167                         aNodes.push_back(aFace->GetNode(0));
00168                     meshds->AddPolygonalFaceWithID(aNodes, aFace->GetID());
00169                 }
00170                 break;
00171         }
00172     }
00173 
00174     SMDS_VolumeIteratorPtr aVolIter = mesh.myMesh->GetMeshDS()->volumesIterator();
00175     for (;aVolIter->more();) {
00176         const SMDS_MeshVolume* aVol = aVolIter->next();
00177         switch (aVol->NbNodes()) {
00178             case 4:
00179                 meshds->AddVolumeWithID(aVol->GetNode(0),
00180                                         aVol->GetNode(1),
00181                                         aVol->GetNode(2),
00182                                         aVol->GetNode(3),
00183                                         aVol->GetID());
00184                 break;
00185             case 5:
00186                 meshds->AddVolumeWithID(aVol->GetNode(0),
00187                                         aVol->GetNode(1),
00188                                         aVol->GetNode(2),
00189                                         aVol->GetNode(3),
00190                                         aVol->GetNode(4),
00191                                         aVol->GetID());
00192                 break;
00193             case 6:
00194                 meshds->AddVolumeWithID(aVol->GetNode(0),
00195                                         aVol->GetNode(1),
00196                                         aVol->GetNode(2),
00197                                         aVol->GetNode(3),
00198                                         aVol->GetNode(4),
00199                                         aVol->GetNode(5),
00200                                         aVol->GetID());
00201                 break;
00202             case 8:
00203                 meshds->AddVolumeWithID(aVol->GetNode(0),
00204                                         aVol->GetNode(1),
00205                                         aVol->GetNode(2),
00206                                         aVol->GetNode(3),
00207                                         aVol->GetNode(4),
00208                                         aVol->GetNode(5),
00209                                         aVol->GetNode(6),
00210                                         aVol->GetNode(7),
00211                                         aVol->GetID());
00212                 break;
00213             case 10:
00214                 meshds->AddVolumeWithID(aVol->GetNode(0),
00215                                         aVol->GetNode(1),
00216                                         aVol->GetNode(2),
00217                                         aVol->GetNode(3),
00218                                         aVol->GetNode(4),
00219                                         aVol->GetNode(5),
00220                                         aVol->GetNode(6),
00221                                         aVol->GetNode(7),
00222                                         aVol->GetNode(8),
00223                                         aVol->GetNode(9),
00224                                         aVol->GetID());
00225                 break;
00226             case 13:
00227                 meshds->AddVolumeWithID(aVol->GetNode(0),
00228                                         aVol->GetNode(1),
00229                                         aVol->GetNode(2),
00230                                         aVol->GetNode(3),
00231                                         aVol->GetNode(4),
00232                                         aVol->GetNode(5),
00233                                         aVol->GetNode(6),
00234                                         aVol->GetNode(7),
00235                                         aVol->GetNode(8),
00236                                         aVol->GetNode(9),
00237                                         aVol->GetNode(10),
00238                                         aVol->GetNode(11),
00239                                         aVol->GetNode(12),
00240                                         aVol->GetID());
00241                 break;
00242             case 15:
00243                 meshds->AddVolumeWithID(aVol->GetNode(0),
00244                                         aVol->GetNode(1),
00245                                         aVol->GetNode(2),
00246                                         aVol->GetNode(3),
00247                                         aVol->GetNode(4),
00248                                         aVol->GetNode(5),
00249                                         aVol->GetNode(6),
00250                                         aVol->GetNode(7),
00251                                         aVol->GetNode(8),
00252                                         aVol->GetNode(9),
00253                                         aVol->GetNode(10),
00254                                         aVol->GetNode(11),
00255                                         aVol->GetNode(12),
00256                                         aVol->GetNode(13),
00257                                         aVol->GetNode(14),
00258                                         aVol->GetID());
00259                 break;
00260             case 20:
00261                 meshds->AddVolumeWithID(aVol->GetNode(0),
00262                                         aVol->GetNode(1),
00263                                         aVol->GetNode(2),
00264                                         aVol->GetNode(3),
00265                                         aVol->GetNode(4),
00266                                         aVol->GetNode(5),
00267                                         aVol->GetNode(6),
00268                                         aVol->GetNode(7),
00269                                         aVol->GetNode(8),
00270                                         aVol->GetNode(9),
00271                                         aVol->GetNode(10),
00272                                         aVol->GetNode(11),
00273                                         aVol->GetNode(12),
00274                                         aVol->GetNode(13),
00275                                         aVol->GetNode(14),
00276                                         aVol->GetNode(15),
00277                                         aVol->GetNode(16),
00278                                         aVol->GetNode(17),
00279                                         aVol->GetNode(18),
00280                                         aVol->GetNode(19),
00281                                         aVol->GetID());
00282                 break;
00283             default:
00284                 {
00285                     if (aVol->IsPoly()) {
00286                         const SMDS_PolyhedralVolumeOfNodes* aPolyVol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(aVol);
00287                         if (!aPolyVol) break;
00288                         std::vector<const SMDS_MeshNode*> aNodes;
00289                         for (int i=0; i<aPolyVol->NbNodes(); i++)
00290                             aNodes.push_back(aPolyVol->GetNode(i));
00291                         meshds->AddPolyhedralVolumeWithID(aNodes,
00292                             aPolyVol->GetQuanities(), aPolyVol->GetID());
00293                     }
00294                 }
00295                 break;
00296         }
00297     }
00298 }
00299 
00300 const SMESH_Mesh* FemMesh::getSMesh() const
00301 {
00302     return myMesh;
00303 }
00304 
00305 SMESH_Mesh* FemMesh::getSMesh()
00306 {
00307     return myMesh;
00308 }
00309 
00310 SMESH_Gen * FemMesh::getGenerator()
00311 {
00312     return myGen;
00313 }
00314 
00315 void FemMesh::addHypothesis(const TopoDS_Shape & aSubShape, SMESH_HypothesisPtr hyp)
00316 {
00317     myMesh->AddHypothesis(aSubShape, hyp->GetID());
00318     SMESH_HypothesisPtr ptr(hyp);
00319     hypoth.push_back(ptr);
00320 }
00321 
00322 void FemMesh::setStanardHypotheses()
00323 {
00324     if (!hypoth.empty())
00325         return;
00326     int hyp=0;
00327     SMESH_HypothesisPtr len(new StdMeshers_MaxLength(hyp++, 1, myGen));
00328     static_cast<StdMeshers_MaxLength*>(len.get())->SetLength(1.0);
00329     hypoth.push_back(len);
00330 
00331     SMESH_HypothesisPtr loc(new StdMeshers_LocalLength(hyp++, 1, myGen));
00332     static_cast<StdMeshers_LocalLength*>(loc.get())->SetLength(1.0);
00333     hypoth.push_back(loc);
00334 
00335     SMESH_HypothesisPtr area(new StdMeshers_MaxElementArea(hyp++, 1, myGen));
00336     static_cast<StdMeshers_MaxElementArea*>(area.get())->SetMaxArea(1.0);
00337     hypoth.push_back(area);
00338 
00339     SMESH_HypothesisPtr segm(new StdMeshers_NumberOfSegments(hyp++, 1, myGen));
00340     static_cast<StdMeshers_NumberOfSegments*>(segm.get())->SetNumberOfSegments(1);
00341     hypoth.push_back(segm);
00342 
00343     SMESH_HypothesisPtr defl(new StdMeshers_Deflection1D(hyp++, 1, myGen));
00344     static_cast<StdMeshers_Deflection1D*>(defl.get())->SetDeflection(0.01);
00345     hypoth.push_back(defl);
00346 
00347     SMESH_HypothesisPtr reg(new StdMeshers_Regular_1D(hyp++, 1, myGen));
00348     hypoth.push_back(reg);
00349 
00350     //SMESH_HypothesisPtr sel(new StdMeshers_StartEndLength(hyp++, 1, myGen));
00351     //static_cast<StdMeshers_StartEndLength*>(sel.get())->SetLength(1.0, true);
00352     //hypoth.push_back(sel);
00353 
00354     SMESH_HypothesisPtr qdp(new StdMeshers_QuadranglePreference(hyp++,1,myGen));
00355     hypoth.push_back(qdp);
00356 
00357     SMESH_HypothesisPtr q2d(new StdMeshers_Quadrangle_2D(hyp++,1,myGen));
00358     hypoth.push_back(q2d);
00359 
00360     // Apply hypothesis
00361     for (int i=0; i<hyp;i++)
00362         myMesh->AddHypothesis(myMesh->GetShapeToMesh(), i);
00363 }
00364 
00365 void FemMesh::compute()
00366 {
00367     myGen->Compute(*myMesh, myMesh->GetShapeToMesh());
00368 }
00369 
00370 
00371 void FemMesh::readNastran(const std::string &Filename)
00372 {
00373         std::ifstream inputfile;
00374         inputfile.open(Filename.c_str());
00375         inputfile.seekg(std::ifstream::beg);
00376         std::string line1,line2,temp;
00377         Base::Vector3d current_node;
00378         std::vector<Base::Vector3d> vertices;
00379         vertices.clear();
00380         std::vector<unsigned int> tetra_element;
00381         std::vector<std::vector<unsigned int> > all_elements;
00382         std::vector<unsigned int> element_id;
00383         element_id.clear();
00384         do
00385         {
00386                 std::getline(inputfile,line1);
00387                 if (line1.size() == 0) continue;
00388                 if (line1.find("GRID*")!= std::string::npos) //We found a Grid line
00389                 {
00390                         //Now lets extract the GRID Points = Nodes
00391                         //As each GRID Line consists of two subsequent lines we have to
00392                         //take care of that as well
00393                         std::getline(inputfile,line2);
00394                         //Extract X Value
00395                         current_node.x = atof(line1.substr(40,56).c_str());
00396                         //Extract Y Value
00397                         current_node.y = atof(line1.substr(56,72).c_str());
00398                         //Extract Z Value
00399                         current_node.z = atof(line2.substr(8,24).c_str());
00400 
00401                         vertices.push_back(current_node);
00402                 }
00403                 else if (line1.find("CTETRA")!= std::string::npos)
00404                 {
00405                         tetra_element.clear();
00406                         //Lets extract the elements
00407                         //As each Element Line consists of two subsequent lines as well 
00408                         //we have to take care of that
00409                         //At a first step we only extract Quadratic Tetrahedral Elements
00410                         std::getline(inputfile,line2);
00411                         element_id.push_back(atoi(line1.substr(8,16).c_str()));
00412                         tetra_element.push_back(atoi(line1.substr(24,32).c_str()));
00413                         tetra_element.push_back(atoi(line1.substr(32,40).c_str()));
00414                         tetra_element.push_back(atoi(line1.substr(40,48).c_str()));
00415                         tetra_element.push_back(atoi(line1.substr(48,56).c_str()));
00416                         tetra_element.push_back(atoi(line1.substr(56,64).c_str()));
00417                         tetra_element.push_back(atoi(line1.substr(64,72).c_str()));
00418                         tetra_element.push_back(atoi(line2.substr(8,16).c_str()));
00419                         tetra_element.push_back(atoi(line2.substr(16,24).c_str()));
00420                         tetra_element.push_back(atoi(line2.substr(24,32).c_str()));
00421                         tetra_element.push_back(atoi(line2.substr(32,40).c_str()));
00422 
00423                         all_elements.push_back(tetra_element);
00424                 }
00425 
00426         }
00427         while (inputfile.good());
00428         inputfile.close();
00429 
00430         //Now fill the SMESH datastructure
00431         std::vector<Base::Vector3d>::const_iterator anodeiterator;
00432         SMESHDS_Mesh* meshds = this->myMesh->GetMeshDS();
00433         meshds->ClearMesh();
00434         int j=1;
00435         for(anodeiterator=vertices.begin(); anodeiterator!=vertices.end(); anodeiterator++)
00436         {
00437                 meshds->AddNodeWithID((*anodeiterator).x,(*anodeiterator).y,(*anodeiterator).z,j);
00438                 j++;
00439         }
00440 
00441         for(unsigned int i=0;i<all_elements.size();i++)
00442         {
00443                 //Die Reihenfolge wie hier die Elemente hinzugefügt werden ist sehr wichtig. 
00444                 //Ansonsten ist eine konsistente Datenstruktur nicht möglich
00445                 meshds->AddVolumeWithID(
00446                         meshds->FindNode(all_elements[i][0]),
00447                         meshds->FindNode(all_elements[i][2]),
00448                         meshds->FindNode(all_elements[i][1]),
00449                         meshds->FindNode(all_elements[i][3]),
00450                         meshds->FindNode(all_elements[i][6]),
00451                         meshds->FindNode(all_elements[i][5]),
00452                         meshds->FindNode(all_elements[i][4]),
00453                         meshds->FindNode(all_elements[i][9]),
00454                         meshds->FindNode(all_elements[i][7]),
00455                         meshds->FindNode(all_elements[i][8]),
00456                         element_id[i]
00457                 );
00458         }
00459 }
00460 
00461 void FemMesh::read(const char *FileName)
00462 {
00463     Base::FileInfo File(FileName);
00464   
00465     // checking on the file
00466     if (!File.isReadable())
00467         throw Base::Exception("File to load not existing or not readable");
00468     
00469     if (File.hasExtension("unv") ) {
00470         // read UNV file
00471         myMesh->UNVToMesh(File.filePath().c_str());
00472     }
00473     else if (File.hasExtension("med") ) {
00474         myMesh->MEDToMesh(File.filePath().c_str(),File.fileNamePure().c_str());
00475     }
00476     else if (File.hasExtension("stl") ) {
00477         // read brep-file
00478         myMesh->STLToMesh(File.filePath().c_str());
00479     }
00480     else if (File.hasExtension("dat") ) {
00481         // read brep-file
00482         myMesh->DATToMesh(File.filePath().c_str());
00483     }
00484         else if (File.hasExtension("bdf") ) {
00485                 // read Nastran-file
00486                 readNastran(File.filePath());
00487         }
00488     else{
00489         throw Base::Exception("Unknown extension");
00490     }
00491 }
00492 
00493 void FemMesh::writeABAQUS(const std::string &Filename, Base::Placement* placement) const
00494 {
00495     std::ofstream anABAQUS_Output;
00496     anABAQUS_Output.open(Filename.c_str());
00497     anABAQUS_Output << "*Node , NSET=Nall" << std::endl;
00498 
00499     //Extract Nodes and Elements of the current SMESH datastructure
00500     SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator();
00501     if (placement)
00502     {
00503         Base::Vector3d current_node;
00504         Base::Matrix4D matrix = placement->toMatrix();
00505         for (;aNodeIter->more();) {
00506             const SMDS_MeshNode* aNode = aNodeIter->next();
00507             current_node.Set(aNode->X(),aNode->Y(),aNode->Z());
00508             current_node = matrix * current_node;
00509             anABAQUS_Output << aNode->GetID() << ","
00510                 << current_node.x << "," 
00511                 << current_node.y << ","
00512                 << current_node.z << std::endl;
00513         }
00514     }
00515     else
00516     {
00517         for (;aNodeIter->more();) {
00518             const SMDS_MeshNode* aNode = aNodeIter->next();
00519             anABAQUS_Output << aNode->GetID() << ","
00520                 << aNode->X() << "," 
00521                 << aNode->Y() << ","
00522                 << aNode->Z() << std::endl;
00523         }
00524     }
00525 
00526         anABAQUS_Output << "*Element, TYPE=C3D10, ELSET=Eall" << std::endl;
00527         SMDS_VolumeIteratorPtr aVolIter = myMesh->GetMeshDS()->volumesIterator();
00528 
00529         std::map<int,std::vector<int> > temp_map;
00530         std::pair<int,std::vector<int> > apair;
00531         temp_map.clear();
00532         for (;aVolIter->more();) 
00533         {
00534                 const SMDS_MeshVolume* aVol = aVolIter->next();
00535                 //Dont ask about the order in which we have to output the SMESH structure
00536                 //I absolute dont understand the scheme behind it but somehow its working like this
00537                 apair.first = aVol->GetID();
00538                 apair.second.clear();
00539                 apair.second.push_back(aVol->GetNode(0)->GetID());
00540                 apair.second.push_back(aVol->GetNode(2)->GetID());
00541                 apair.second.push_back(aVol->GetNode(1)->GetID());
00542                 apair.second.push_back(aVol->GetNode(3)->GetID());
00543                 apair.second.push_back(aVol->GetNode(6)->GetID());
00544                 apair.second.push_back(aVol->GetNode(5)->GetID());
00545                 apair.second.push_back(aVol->GetNode(4)->GetID());
00546                 apair.second.push_back(aVol->GetNode(8)->GetID());
00547                 apair.second.push_back(aVol->GetNode(9)->GetID());
00548                 apair.second.push_back(aVol->GetNode(7)->GetID());
00549                 temp_map.insert(apair);
00550         }
00551 
00552         std::map<int,std::vector<int> >::iterator it_map;
00553         std::vector<int>::iterator it_vector;
00554         for(it_map = temp_map.begin();it_map!=temp_map.end();it_map++)
00555         {
00556                 anABAQUS_Output << it_map->first << ",";
00557                 for(it_vector = it_map->second.begin();it_vector!=it_map->second.end();it_vector++)
00558                 {
00559                         anABAQUS_Output << *it_vector << ",";
00560                 }
00561                 anABAQUS_Output << std::endl;
00562         }
00563         anABAQUS_Output.close();
00564 }
00565 
00566 void FemMesh::write(const char *FileName) const
00567 {
00568     Base::FileInfo File(FileName);
00569 
00570     if (File.hasExtension("unv") ) {
00571         // read UNV file
00572          myMesh->ExportUNV(File.filePath().c_str());
00573     }
00574     else if (File.hasExtension("med") ) {
00575          myMesh->ExportMED(File.filePath().c_str());
00576     }
00577     else if (File.hasExtension("stl") ) {
00578         // read brep-file
00579         myMesh->ExportSTL(File.filePath().c_str(),false);
00580     }
00581     else if (File.hasExtension("dat") ) {
00582         // read brep-file
00583         myMesh->ExportDAT(File.filePath().c_str());
00584     }
00585         else if (File.hasExtension("inp") ) {
00586                 // write ABAQUS Output
00587                 writeABAQUS(File.filePath());
00588         }
00589     else{
00590         throw Base::Exception("Unknown extension");
00591     }
00592 }
00593 
00594 // ==== Base class implementer ==============================================================
00595 
00596 unsigned int FemMesh::getMemSize (void) const
00597 {
00598     return 0;
00599 }
00600 
00601 void FemMesh::Save (Base::Writer &writer) const
00602 {
00603 }
00604 
00605 void FemMesh::Restore(Base::XMLReader &reader)
00606 {
00607 }
00608 
00609 void FemMesh::SaveDocFile (Base::Writer &writer) const
00610 {
00611     // create a temporary file and copy the content to the zip stream
00612     Base::FileInfo fi(Base::FileInfo::getTempFileName().c_str());
00613 
00614     myMesh->ExportUNV(fi.filePath().c_str());
00615  
00616     Base::ifstream file(fi, std::ios::in | std::ios::binary);
00617     if (file){
00618         unsigned long ulSize = 0; 
00619         std::streambuf* buf = file.rdbuf();
00620         if (buf) {
00621             unsigned long ulCurr;
00622             ulCurr = buf->pubseekoff(0, std::ios::cur, std::ios::in);
00623             ulSize = buf->pubseekoff(0, std::ios::end, std::ios::in);
00624             buf->pubseekoff(ulCurr, std::ios::beg, std::ios::in);
00625         }
00626 
00627         // read in the ASCII file and write back to the stream
00628         std::strstreambuf sbuf(ulSize);
00629         file >> &sbuf;
00630         writer.Stream() << &sbuf;
00631     }
00632 
00633     file.close();
00634     // remove temp file
00635     fi.deleteFile();
00636 }
00637 
00638 void FemMesh::RestoreDocFile(Base::Reader &reader)
00639 {
00640     // create a temporary file and copy the content from the zip stream
00641     Base::FileInfo fi(Base::FileInfo::getTempFileName().c_str());
00642 
00643     // read in the ASCII file and write back to the file stream
00644     Base::ofstream file(fi, std::ios::out | std::ios::binary);
00645     if (reader)
00646         reader >> file.rdbuf();
00647     file.close();
00648 
00649     // read the shape from the temp file
00650     myMesh->UNVToMesh(fi.filePath().c_str());
00651 
00652     // delete the temp file
00653     fi.deleteFile();
00654 }
00655 
00656 void FemMesh::transformGeometry(const Base::Matrix4D& rclTrf)
00657 {
00658         //We perform a translation and rotation of the current active Mesh object
00659         Base::Matrix4D clMatrix(rclTrf);
00660         SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator();
00661         Base::Vector3d current_node;
00662         for (;aNodeIter->more();) {
00663                 const SMDS_MeshNode* aNode = aNodeIter->next();
00664                 current_node.Set(aNode->X(),aNode->Y(),aNode->Z());
00665                 current_node = clMatrix * current_node;
00666                 myMesh->GetMeshDS()->MoveNode(aNode,current_node.x,current_node.y,current_node.z);
00667         }
00668 }
00669 
00670 void FemMesh::setTransform(const Base::Matrix4D& rclTrf)
00671 {
00672     // Placement handling, no geometric transformation
00673 }
00674 
00675 Base::Matrix4D FemMesh::getTransform(void) const
00676 {
00677     Base::Matrix4D mtrx;
00678     return mtrx;
00679 }
00680 
00681 Base::BoundBox3d FemMesh::getBoundBox(void) const
00682 {
00683     Base::BoundBox3d box;
00684     try {
00685         // If the shape is empty an exception may be thrown
00686         Bnd_Box bounds;
00687         BRepBndLib::Add(myMesh->GetShapeToMesh(), bounds);
00688         bounds.SetGap(0.0);
00689         Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
00690         bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);
00691 
00692         box.MinX = xMin;
00693         box.MaxX = xMax;
00694         box.MinY = yMin;
00695         box.MaxY = yMax;
00696         box.MinZ = zMin;
00697         box.MaxZ = zMax;
00698     }
00699     catch (Standard_Failure) {
00700     }
00701 
00702     return box;
00703 }
00704 
00705 std::vector<const char*> FemMesh::getElementTypes(void) const
00706 {
00707     std::vector<const char*> temp;
00708     temp.push_back("Vertex");
00709     temp.push_back("Edge");
00710     temp.push_back("Face");
00711     temp.push_back("Volume");
00712 
00713     return temp;
00714 }
00715 
00716 unsigned long FemMesh::countSubElements(const char* Type) const
00717 {
00718     return 0;
00719 }
00720 
00721 Data::Segment* FemMesh::getSubElement(const char* Type, unsigned long n) const
00722 {
00723     // FIXME implement subelement interface 
00724     //std::stringstream str;
00725     //str << Type << n;
00726     //std::string temp = str.str();
00727     //return new ShapeSegment(getSubShape(temp.c_str()));
00728     return 0;
00729 }

Generated on Wed Nov 23 19:00:13 2011 for FreeCAD by  doxygen 1.6.1