Mesher.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2010 Werner Mayer <wmayer[at]users.sourceforge.net>     *
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 #include "PreCompiled.h"
00024 #include "Mesher.h"
00025 
00026 #include <Base/Exception.h>
00027 #include <Mod/Mesh/App/Mesh.h>
00028 
00029 #include <TopoDS_Shape.hxx>
00030 
00031 #ifdef HAVE_SMESH
00032 #include <SMESH_Gen.hxx>
00033 #include <StdMeshers_MaxLength.hxx>
00034 #include <StdMeshers_LocalLength.hxx>
00035 #include <StdMeshers_NumberOfSegments.hxx>
00036 #include <StdMeshers_AutomaticLength.hxx>
00037 #include <StdMeshers_TrianglePreference.hxx>
00038 #include <StdMeshers_MEFISTO_2D.hxx>
00039 #include <StdMeshers_Deflection1D.hxx>
00040 #include <StdMeshers_MaxElementArea.hxx>
00041 #include <StdMeshers_Regular_1D.hxx>
00042 #include <StdMeshers_QuadranglePreference.hxx>
00043 #include <StdMeshers_Quadrangle_2D.hxx>
00044 
00045 #include <StdMeshers_LengthFromEdges.hxx>
00046 #include <StdMeshers_NotConformAllowed.hxx>
00047 #include <StdMeshers_Arithmetic1D.hxx>
00048 #endif // HAVE_SMESH
00049 
00050 using namespace MeshPart;
00051 
00052 Mesher::Mesher(const TopoDS_Shape& s)
00053   : shape(s), maxLength(0), maxArea(0), localLength(0),
00054     regular(false)
00055 {
00056 }
00057 
00058 Mesher::~Mesher()
00059 {
00060 }
00061 
00062 Mesh::MeshObject* Mesher::createMesh() const
00063 {
00064 #ifndef HAVE_SMESH
00065     throw Base::Exception("SMESH is not available on this platform");
00066 #else
00067     std::list<SMESH_Hypothesis*> hypoth;
00068 
00069     SMESH_Gen* meshgen = new SMESH_Gen();
00070     SMESH_Mesh* mesh = meshgen->CreateMesh(0, true);
00071     int hyp=0;
00072 
00073     if (maxLength > 0) {
00074         StdMeshers_MaxLength* hyp1d = new StdMeshers_MaxLength(hyp++, 0, meshgen);
00075         hyp1d->SetLength(maxLength);
00076         hypoth.push_back(hyp1d);
00077     }
00078 
00079     if (localLength > 0) {
00080         StdMeshers_LocalLength* hyp1d = new StdMeshers_LocalLength(hyp++,0,meshgen);
00081         hyp1d->SetLength(localLength);
00082         hypoth.push_back(hyp1d);
00083     }
00084 
00085     if (maxArea > 0) {
00086         StdMeshers_MaxElementArea* hyp2d = new StdMeshers_MaxElementArea(hyp++,0,meshgen);
00087         hyp2d->SetMaxArea(1.0f);
00088         hypoth.push_back(hyp2d);
00089     }
00090 
00091     {
00092         StdMeshers_NumberOfSegments* hyp1d = new StdMeshers_NumberOfSegments(hyp++,0,meshgen);
00093         hyp1d->SetNumberOfSegments(1);
00094         hypoth.push_back(hyp1d);
00095     }
00096 
00097     // if none of the above hypothesis were applied
00098     if (hypoth.empty()) {
00099         StdMeshers_AutomaticLength* hyp1d = new StdMeshers_AutomaticLength(hyp++,0,meshgen);
00100         hypoth.push_back(hyp1d);
00101     }
00102 
00103     if (deflection > 0) {
00104         StdMeshers_Deflection1D* hyp1d = new StdMeshers_Deflection1D(hyp++,0,meshgen);
00105         hyp1d->SetDeflection(deflection);
00106         hypoth.push_back(hyp1d);
00107     }
00108 
00109     if (regular) {
00110         StdMeshers_Regular_1D* hyp1d = new StdMeshers_Regular_1D(hyp++,0,meshgen);
00111         hypoth.push_back(hyp1d);
00112     }
00113 
00114 #if 1
00115     StdMeshers_TrianglePreference* hyp2d_1 = new StdMeshers_TrianglePreference(hyp++,0,meshgen);
00116     hypoth.push_back(hyp2d_1);
00117     StdMeshers_MEFISTO_2D* alg2d = new StdMeshers_MEFISTO_2D(hyp++,0,meshgen);
00118     hypoth.push_back(alg2d);
00119 #else
00120     StdMeshers_QuadranglePreference hyp2d_1(hyp++,0,meshgen);
00121     StdMeshers_Quadrangle_2D alg2d(hyp++,0,meshgen);
00122 #endif
00123 
00124     // Apply the hypothesis and create the mesh
00125     mesh->ShapeToMesh(shape);
00126     for (int i=0; i<hyp;i++)
00127         mesh->AddHypothesis(shape, i);
00128     meshgen->Compute(*mesh, mesh->GetShapeToMesh());
00129 
00130     // build up the mesh structure
00131     SMDS_FaceIteratorPtr aFaceIter = mesh->GetMeshDS()->facesIterator();
00132     SMDS_NodeIteratorPtr aNodeIter = mesh->GetMeshDS()->nodesIterator();
00133 
00134     MeshCore::MeshPointArray verts;
00135     MeshCore::MeshFacetArray faces;
00136     verts.reserve(mesh->NbNodes());
00137     faces.reserve(mesh->NbFaces());
00138 
00139     int index=0;
00140     std::map<const SMDS_MeshNode*, int> mapNodeIndex;
00141     for (;aNodeIter->more();) {
00142         const SMDS_MeshNode* aNode = aNodeIter->next();
00143         MeshCore::MeshPoint p;
00144         p.Set((float)aNode->X(), (float)aNode->Y(), (float)aNode->Z());
00145         verts.push_back(p);
00146         mapNodeIndex[aNode] = index++;
00147     }
00148     for (;aFaceIter->more();) {
00149         const SMDS_MeshFace* aFace = aFaceIter->next();
00150         MeshCore::MeshFacet f;
00151         for (int i=0; i<3;i++) {
00152             const SMDS_MeshNode* node = aFace->GetNode(i);
00153             //int index = node->GetID() - 1;
00154             f._aulPoints[i] = /*index*/mapNodeIndex[node];
00155         }
00156 
00157         faces.push_back(f);
00158     }
00159 
00160     // clean up
00161     //FIXME: Why can't we delete this object?
00162 #if defined(__GNUC__)
00163     delete meshgen; // crashes with MSVC
00164 #endif
00165     TopoDS_Shape aNull;
00166     mesh->ShapeToMesh(aNull);
00167     mesh->Clear();
00168     delete mesh;
00169     for (std::list<SMESH_Hypothesis*>::iterator it = hypoth.begin(); it != hypoth.end(); ++it)
00170         delete *it;
00171 
00172     MeshCore::MeshKernel kernel;
00173     kernel.Adopt(verts, faces, true);
00174 
00175     Mesh::MeshObject* meshdata = new Mesh::MeshObject();
00176     meshdata->swap(kernel);
00177     return meshdata;
00178 #endif // HAVE_SMESH
00179 }
00180 

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