Mesh.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) Juergen Riegel         <juergen.riegel@web.de>          *
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 #ifndef _PreComp_
00026 # include <algorithm>
00027 # include <sstream>
00028 #endif
00029 
00030 #include <CXX/Objects.hxx>
00031 #include <Base/Builder3D.h>
00032 #include <Base/Console.h>
00033 #include <Base/Exception.h>
00034 #include <Base/Writer.h>
00035 #include <Base/Reader.h>
00036 #include <Base/Interpreter.h>
00037 
00038 #include "Core/Builder.h"
00039 #include "Core/MeshKernel.h"
00040 #include "Core/Grid.h"
00041 #include "Core/Iterator.h"
00042 #include "Core/Info.h"
00043 #include "Core/TopoAlgorithm.h"
00044 #include "Core/Evaluation.h"
00045 #include "Core/Degeneration.h"
00046 #include "Core/SetOperations.h"
00047 #include "Core/Visitor.h"
00048 
00049 #include "Mesh.h"
00050 #include "MeshPy.h"
00051 
00052 using namespace Mesh;
00053 
00054 float MeshObject::Epsilon = 1.0e-5f;
00055 
00056 TYPESYSTEM_SOURCE(Mesh::MeshObject, Data::ComplexGeoData);
00057 
00058 MeshObject::MeshObject()
00059 {
00060 }
00061 
00062 MeshObject::MeshObject(const MeshCore::MeshKernel& Kernel)
00063   : _kernel(Kernel)
00064 {
00065     // copy the mesh structure
00066 }
00067 
00068 MeshObject::MeshObject(const MeshCore::MeshKernel& Kernel, const Base::Matrix4D &Mtrx)
00069   : _Mtrx(Mtrx),_kernel(Kernel)
00070 {
00071     // copy the mesh structure
00072 }
00073 
00074 MeshObject::MeshObject(const MeshObject& mesh)
00075   : _Mtrx(mesh._Mtrx),_kernel(mesh._kernel)
00076 {
00077     // copy the mesh structure
00078     this->_segments = mesh._segments;
00079 }
00080 
00081 MeshObject::~MeshObject()
00082 {
00083 }
00084 
00085 std::vector<const char*> MeshObject::getElementTypes(void) const
00086 {
00087     std::vector<const char*> temp;
00088     temp.push_back("Face"); // that's the mesh itself
00089     temp.push_back("Segment");
00090 
00091     return temp;
00092 }
00093 
00094 unsigned long MeshObject::countSubElements(const char* Type) const
00095 {
00096     std::string element(Type);
00097     if (element == "Face")
00098         return 1;
00099     else if (element == "Segment")
00100         return countSegments();
00101     return 0;
00102 }
00103 
00104 Data::Segment* MeshObject::getSubElement(const char* Type, unsigned long n) const
00105 {
00106     //TODO
00107     std::string element(Type);
00108     if (element == "Face")
00109         return 0;
00110     else if (element == "Segment")
00111         return 0;
00112     return 0;
00113 }
00114 
00115 void MeshObject::getFacesFromSubelement(const Data::Segment* segm,
00116                                         std::vector<Base::Vector3d> &Points,
00117                                         std::vector<Base::Vector3d> &PointNormals,
00118                                         std::vector<Facet> &faces) const
00119 {
00120     //TODO
00121     this->getFaces(Points, faces, 0.0f);
00122 }
00123 
00124 void MeshObject::transformGeometry(const Base::Matrix4D &rclMat)
00125 {
00126     MeshCore::MeshKernel kernel;
00127     swap(kernel);
00128     kernel.Transform(rclMat);
00129     swap(kernel);
00130 }
00131 
00132 void MeshObject::setTransform(const Base::Matrix4D& rclTrf)
00133 {
00134     _Mtrx = rclTrf;
00135 }
00136 
00137 Base::Matrix4D MeshObject::getTransform(void) const
00138 {
00139     return _Mtrx;
00140 }
00141 
00142 Base::BoundBox3d MeshObject::getBoundBox(void)const
00143 {
00144     const_cast<MeshCore::MeshKernel&>(_kernel).RecalcBoundBox();
00145     Base::BoundBox3f Bnd = _kernel.GetBoundBox();
00146     
00147     Base::BoundBox3d Bnd2;
00148     for(int i =0 ;i<=7;i++)
00149         Bnd2.Add(transformToOutside(Bnd.CalcPoint(i)));
00150     
00151     return Bnd2;
00152 }
00153 
00154 void MeshObject::operator = (const MeshObject& mesh)
00155 {
00156     if (this != &mesh) {
00157         // copy the mesh structure
00158         setTransform(mesh._Mtrx);
00159         this->_kernel = mesh._kernel;
00160         this->_segments = mesh._segments;
00161     }
00162 }
00163 
00164 void MeshObject::setKernel(const MeshCore::MeshKernel& m)
00165 {
00166     this->_kernel = m;
00167     this->_segments.clear();
00168 }
00169 
00170 void MeshObject::swap(MeshCore::MeshKernel& Kernel)
00171 {
00172     this->_kernel.Swap(Kernel);
00173     // clear the segments because we don't know how the new
00174     // topology looks like
00175     this->_segments.clear();
00176 }
00177 
00178 void MeshObject::swap(MeshObject& mesh)
00179 {
00180     this->_kernel.Swap(mesh._kernel);
00181     this->_segments.swap(mesh._segments);
00182     Base::Matrix4D tmp=this->_Mtrx;
00183     this->_Mtrx = mesh._Mtrx;
00184     mesh._Mtrx = tmp;
00185 }
00186 
00187 std::string MeshObject::representation() const
00188 {
00189     std::stringstream str;
00190     MeshCore::MeshInfo info(_kernel);
00191     info.GeneralInformation(str);
00192     return str.str();
00193 }
00194 
00195 std::string MeshObject::topologyInfo() const
00196 {
00197     std::stringstream str;
00198     MeshCore::MeshInfo info(_kernel);
00199     info.TopologyInformation(str);
00200     return str.str();
00201 }
00202 
00203 unsigned long MeshObject::countPoints() const
00204 {
00205     return _kernel.CountPoints();
00206 }
00207 
00208 unsigned long MeshObject::countFacets() const
00209 {
00210     return _kernel.CountFacets();
00211 }
00212 
00213 unsigned long MeshObject::countEdges () const
00214 {
00215     return _kernel.CountEdges();
00216 }
00217 
00218 unsigned long MeshObject::countSegments () const
00219 {
00220     return this->_segments.size();
00221 }
00222 
00223 bool MeshObject::isSolid() const
00224 {
00225     MeshCore::MeshEvalSolid cMeshEval(_kernel);
00226     return cMeshEval.Evaluate();
00227 }
00228 
00229 double MeshObject::getSurface() const
00230 {
00231     return _kernel.GetSurface();
00232 }
00233 
00234 double MeshObject::getVolume() const
00235 {
00236     return _kernel.GetVolume();
00237 }
00238 
00239 MeshPoint MeshObject::getPoint(unsigned long index) const
00240 {
00241     Base::Vector3f vertf = _kernel.GetPoint(index);
00242     Base::Vector3d vertd(vertf.x, vertf.y, vertf.z);
00243     vertd = _Mtrx * vertd;
00244     MeshPoint point(vertd, const_cast<MeshObject*>(this), index);
00245     return point;
00246 }
00247 
00248 Mesh::Facet MeshObject::getFacet(unsigned long index) const
00249 {
00250     Mesh::Facet face(_kernel.GetFacets()[index], const_cast<MeshObject*>(this), index);
00251     return face;
00252 }
00253 
00254 void MeshObject::getFaces(std::vector<Base::Vector3d> &Points,std::vector<Facet> &Topo,
00255                           float Accuracy, uint16_t flags) const
00256 {
00257     unsigned long ctpoints = _kernel.CountPoints();
00258     Points.reserve(ctpoints);
00259     for (unsigned long i=0; i<ctpoints; i++) {
00260         Points.push_back(this->getPoint(i));
00261     }
00262 
00263     unsigned long ctfacets = _kernel.CountFacets();
00264     const MeshCore::MeshFacetArray& ary = _kernel.GetFacets();
00265     Topo.reserve(ctfacets);
00266     for (unsigned long i=0; i<ctfacets; i++) {
00267         Facet face;
00268         face.I1 = (unsigned int)ary[i]._aulPoints[0];
00269         face.I2 = (unsigned int)ary[i]._aulPoints[1];
00270         face.I3 = (unsigned int)ary[i]._aulPoints[2];
00271         Topo.push_back(face);
00272     }
00273 }
00274 
00275 unsigned int MeshObject::getMemSize (void) const
00276 {
00277     return _kernel.GetMemSize();
00278 }
00279 
00280 void MeshObject::Save (Base::Writer &writer) const
00281 {
00282     // this is handled by the property class
00283 }
00284 
00285 void MeshObject::SaveDocFile (Base::Writer &writer) const
00286 {
00287     _kernel.Write(writer.Stream());
00288 }
00289 
00290 void MeshObject::Restore(Base::XMLReader &reader)
00291 {
00292     // this is handled by the property class
00293 }
00294 
00295 void MeshObject::RestoreDocFile(Base::Reader &reader)
00296 {
00297     load(reader);
00298 }
00299 
00300 void MeshObject::save(const char* file, MeshCore::MeshIO::Format f,
00301                       const MeshCore::Material* mat) const
00302 {
00303     MeshCore::MeshOutput aWriter(this->_kernel, mat);
00304     aWriter.Transform(this->_Mtrx);
00305     aWriter.SaveAny(file, f);
00306 }
00307 
00308 void MeshObject::save(std::ostream& out) const
00309 {
00310     _kernel.Write(out);
00311 }
00312 
00313 bool MeshObject::load(const char* file)
00314 {
00315     MeshCore::MeshKernel kernel;
00316     MeshCore::MeshInput aReader(kernel);
00317     if (!aReader.LoadAny(file))
00318         return false;
00319 
00320     _kernel.Swap(kernel);
00321     // Some file formats define several objects per file (e.g. OBJ).
00322     // Now we mark each object as an own segment so that we can break
00323     // the object into its orriginal objects again.
00324     this->_segments.clear();
00325     const MeshCore::MeshFacetArray& faces = _kernel.GetFacets();
00326     MeshCore::MeshFacetArray::_TConstIterator it;
00327     std::vector<unsigned long> segment;
00328     segment.reserve(faces.size());
00329     unsigned long prop = 0;
00330     unsigned long index = 0;
00331     for (it = faces.begin(); it != faces.end(); ++it) {
00332         if (prop < it->_ulProp) {
00333             prop = it->_ulProp;
00334             if (!segment.empty()) {
00335                 this->_segments.push_back(Segment(this,segment,true));
00336                 segment.clear();
00337             }
00338         }
00339 
00340         segment.push_back(index++);
00341     }
00342 
00343     // if the whole mesh is a single object then don't mark as segment
00344     if (!segment.empty() && (segment.size() < faces.size())) {
00345         this->_segments.push_back(Segment(this,segment,true));
00346     }
00347 
00348 #ifndef FC_DEBUG
00349     try {
00350         MeshCore::MeshEvalNeighbourhood nb(_kernel);
00351         if (!nb.Evaluate()) {
00352             Base::Console().Warning("Errors in neighbourhood of mesh found...");
00353             _kernel.RebuildNeighbours();
00354             Base::Console().Warning("fixed\n");
00355         }
00356 
00357         MeshCore::MeshEvalTopology eval(_kernel);
00358         if (!eval.Evaluate()) {
00359             Base::Console().Warning("The mesh data structure has some defects\n");
00360         }
00361     }
00362     catch (const Base::MemoryException&) {
00363         // ignore memory exceptions and continue
00364         Base::Console().Log("Check for defects in mesh data structure failed\n");
00365     }
00366 #endif
00367 
00368     return true;
00369 }
00370 
00371 void MeshObject::load(std::istream& in)
00372 {
00373     _kernel.Read(in);
00374     this->_segments.clear();
00375 
00376 #ifndef FC_DEBUG
00377     try {
00378         MeshCore::MeshEvalNeighbourhood nb(_kernel);
00379         if (!nb.Evaluate()) {
00380             Base::Console().Warning("Errors in neighbourhood of mesh found...");
00381             _kernel.RebuildNeighbours();
00382             Base::Console().Warning("fixed\n");
00383         }
00384 
00385         MeshCore::MeshEvalTopology eval(_kernel);
00386         if (!eval.Evaluate()) {
00387             Base::Console().Warning("The mesh data structure has some defects\n");
00388         }
00389     }
00390     catch (const Base::MemoryException&) {
00391         // ignore memory exceptions and continue
00392         Base::Console().Log("Check for defects in mesh data structure failed\n");
00393     }
00394 #endif
00395 }
00396 
00397 void MeshObject::addFacet(const MeshCore::MeshGeomFacet& facet)
00398 {
00399     _kernel.AddFacet(facet);
00400 }
00401 
00402 void MeshObject::addFacets(const std::vector<MeshCore::MeshGeomFacet>& facets)
00403 {
00404     _kernel.AddFacets(facets);
00405 }
00406 
00407 void MeshObject::addFacets(const std::vector<MeshCore::MeshFacet> &facets)
00408 {
00409     _kernel.AddFacets(facets);
00410 }
00411 
00412 void MeshObject::addFacets(const std::vector<MeshCore::MeshFacet> &facets,
00413                            const std::vector<Base::Vector3f>& points)
00414 {
00415     _kernel.AddFacets(facets, points);
00416 }
00417 
00418 void MeshObject::addFacets(const std::vector<Data::ComplexGeoData::Facet> &facets,
00419                            const std::vector<Base::Vector3d>& points)
00420 {
00421     std::vector<MeshCore::MeshFacet> facet_v;
00422     facet_v.reserve(facets.size());
00423     for (std::vector<Data::ComplexGeoData::Facet>::const_iterator it = facets.begin(); it != facets.end(); ++it) {
00424         MeshCore::MeshFacet f;
00425         f._aulPoints[0] = it->I1;
00426         f._aulPoints[1] = it->I2;
00427         f._aulPoints[2] = it->I3;
00428         facet_v.push_back(f);
00429     }
00430 
00431     std::vector<Base::Vector3f> point_v;
00432     point_v.reserve(points.size());
00433     for (std::vector<Base::Vector3d>::const_iterator it = points.begin(); it != points.end(); ++it) {
00434         Base::Vector3f p((float)it->x,(float)it->y,(float)it->z);
00435         point_v.push_back(p);
00436     }
00437 
00438     _kernel.AddFacets(facet_v, point_v);
00439 }
00440 
00441 void MeshObject::setFacets(const std::vector<MeshCore::MeshGeomFacet>& facets)
00442 {
00443     _kernel = facets;
00444 }
00445 
00446 void MeshObject::setFacets(const std::vector<Data::ComplexGeoData::Facet> &facets,
00447                            const std::vector<Base::Vector3d>& points)
00448 {
00449     MeshCore::MeshFacetArray facet_v;
00450     facet_v.reserve(facets.size());
00451     for (std::vector<Data::ComplexGeoData::Facet>::const_iterator it = facets.begin(); it != facets.end(); ++it) {
00452         MeshCore::MeshFacet f;
00453         f._aulPoints[0] = it->I1;
00454         f._aulPoints[1] = it->I2;
00455         f._aulPoints[2] = it->I3;
00456         facet_v.push_back(f);
00457     }
00458 
00459     MeshCore::MeshPointArray point_v;
00460     point_v.reserve(points.size());
00461     for (std::vector<Base::Vector3d>::const_iterator it = points.begin(); it != points.end(); ++it) {
00462         Base::Vector3f p((float)it->x,(float)it->y,(float)it->z);
00463         point_v.push_back(p);
00464     }
00465 
00466     _kernel.Adopt(point_v, facet_v, true);
00467 }
00468 
00469 void MeshObject::addMesh(const MeshObject& mesh)
00470 {
00471     _kernel.Merge(mesh._kernel);
00472 }
00473 
00474 void MeshObject::addMesh(const MeshCore::MeshKernel& kernel)
00475 {
00476     _kernel.Merge(kernel);
00477 }
00478 
00479 void MeshObject::deleteFacets(const std::vector<unsigned long>& removeIndices)
00480 {
00481     _kernel.DeleteFacets(removeIndices);
00482     deletedFacets(removeIndices);
00483 }
00484 
00485 void MeshObject::deletePoints(const std::vector<unsigned long>& removeIndices)
00486 {
00487     _kernel.DeletePoints(removeIndices);
00488     this->_segments.clear();
00489 }
00490 
00491 void MeshObject::deletedFacets(const std::vector<unsigned long>& remFacets)
00492 {
00493     if (remFacets.empty())
00494         return; // nothing has changed
00495     if (this->_segments.empty())
00496         return; // nothing to do
00497     // set an array with the original indices and mark the removed as ULONG_MAX
00498     std::vector<unsigned long> f_indices(_kernel.CountFacets()+remFacets.size());
00499     for (std::vector<unsigned long>::const_iterator it = remFacets.begin();
00500         it != remFacets.end(); ++it) {
00501         f_indices[*it] = ULONG_MAX;
00502     }
00503 
00504     unsigned long index = 0;
00505     for (std::vector<unsigned long>::iterator it = f_indices.begin();
00506         it != f_indices.end(); ++it) {
00507             if (*it == 0)
00508                 *it = index++;
00509     }
00510 
00511     // the array serves now as LUT to set the new indices in the segments
00512     for (std::vector<Segment>::iterator it = this->_segments.begin();
00513         it != this->_segments.end(); ++it) {
00514             std::vector<unsigned long> segm = it->_indices;
00515             for (std::vector<unsigned long>::iterator jt = segm.begin();
00516                 jt != segm.end(); ++jt) {
00517                     *jt = f_indices[*jt];
00518             }
00519 
00520             // remove the invalid indices
00521             std::sort(segm.begin(), segm.end());
00522             std::vector<unsigned long>::iterator ft = std::find_if
00523                 (segm.begin(), segm.end(), 
00524                 std::bind2nd(std::equal_to<unsigned long>(), ULONG_MAX));
00525             if (ft != segm.end())
00526                 segm.erase(ft, segm.end());
00527             it->_indices = segm;
00528     }
00529 }
00530 
00531 void MeshObject::deleteSelectedFacets()
00532 {
00533     std::vector<unsigned long> facets;
00534     MeshCore::MeshAlgorithm(this->_kernel).GetFacetsFlag(facets, MeshCore::MeshFacet::SELECTED);
00535     deleteFacets(facets);
00536 }
00537 
00538 void MeshObject::deleteSelectedPoints()
00539 {
00540     std::vector<unsigned long> points;
00541     MeshCore::MeshAlgorithm(this->_kernel).GetPointsFlag(points, MeshCore::MeshPoint::SELECTED);
00542     deletePoints(points);
00543 }
00544 
00545 void MeshObject::clearFacetSelection() const
00546 {
00547     MeshCore::MeshAlgorithm(this->_kernel).ResetFacetFlag(MeshCore::MeshFacet::SELECTED);
00548 }
00549 
00550 void MeshObject::clearPointSelection() const
00551 {
00552     MeshCore::MeshAlgorithm(this->_kernel).ResetPointFlag(MeshCore::MeshPoint::SELECTED);
00553 }
00554 
00555 void MeshObject::addFacetsToSelection(const std::vector<unsigned long>& inds) const
00556 {
00557     MeshCore::MeshAlgorithm(this->_kernel).SetFacetsFlag(inds, MeshCore::MeshFacet::SELECTED);
00558 }
00559 
00560 void MeshObject::addPointsToSelection(const std::vector<unsigned long>& inds) const
00561 {
00562     MeshCore::MeshAlgorithm(this->_kernel).SetPointsFlag(inds, MeshCore::MeshPoint::SELECTED);
00563 }
00564 
00565 void MeshObject::removeFacetsFromSelection(const std::vector<unsigned long>& inds) const
00566 {
00567     MeshCore::MeshAlgorithm(this->_kernel).ResetFacetsFlag(inds, MeshCore::MeshFacet::SELECTED);
00568 }
00569 
00570 void MeshObject::removePointsFromSelection(const std::vector<unsigned long>& inds) const
00571 {
00572     MeshCore::MeshAlgorithm(this->_kernel).ResetPointsFlag(inds, MeshCore::MeshPoint::SELECTED);
00573 }
00574 
00575 void MeshObject::getFacetsFromSelection(std::vector<unsigned long>& inds) const
00576 {
00577     MeshCore::MeshAlgorithm(this->_kernel).GetFacetsFlag(inds, MeshCore::MeshFacet::SELECTED);
00578 }
00579 
00580 void MeshObject::getPointsFromSelection(std::vector<unsigned long>& inds) const
00581 {
00582     MeshCore::MeshAlgorithm(this->_kernel).GetPointsFlag(inds, MeshCore::MeshPoint::SELECTED);
00583 }
00584 
00585 void MeshObject::updateMesh(const std::vector<unsigned long>& facets)
00586 {
00587     std::vector<unsigned long> points;
00588     points = _kernel.GetFacetPoints(facets);
00589 
00590     MeshCore::MeshAlgorithm alg(_kernel);
00591     alg.SetFacetsFlag(facets, MeshCore::MeshFacet::SEGMENT);
00592     alg.SetPointsFlag(points, MeshCore::MeshPoint::SEGMENT);
00593 }
00594 
00595 void MeshObject::updateMesh()
00596 {
00597     MeshCore::MeshAlgorithm alg(_kernel);
00598     alg.ResetFacetFlag(MeshCore::MeshFacet::SEGMENT);
00599     alg.ResetPointFlag(MeshCore::MeshPoint::SEGMENT);
00600     for (std::vector<Segment>::iterator it = this->_segments.begin();
00601         it != this->_segments.end(); ++it) {
00602             std::vector<unsigned long> points;
00603             points = _kernel.GetFacetPoints(it->getIndices());
00604             alg.SetFacetsFlag(it->getIndices(), MeshCore::MeshFacet::SEGMENT);
00605             alg.SetPointsFlag(points, MeshCore::MeshPoint::SEGMENT);
00606     }
00607 }
00608 
00609 std::vector<std::vector<unsigned long> > MeshObject::getComponents() const
00610 {
00611     std::vector<std::vector<unsigned long> > segments;
00612     MeshCore::MeshComponents comp(_kernel);
00613     comp.SearchForComponents(MeshCore::MeshComponents::OverEdge,segments);
00614     return segments;
00615 }
00616 
00617 unsigned long MeshObject::countComponents() const
00618 {
00619     std::vector<std::vector<unsigned long> > segments;
00620     MeshCore::MeshComponents comp(_kernel);
00621     comp.SearchForComponents(MeshCore::MeshComponents::OverEdge,segments);
00622     return segments.size();
00623 }
00624 
00625 void MeshObject::removeComponents(unsigned long count)
00626 {
00627     std::vector<unsigned long> removeIndices;
00628     MeshCore::MeshTopoAlgorithm(_kernel).FindComponents(count, removeIndices);
00629     _kernel.DeleteFacets(removeIndices);
00630     deletedFacets(removeIndices);
00631 }
00632 
00633 void MeshObject::fillupHoles(unsigned long length, int level,
00634                              MeshCore::AbstractPolygonTriangulator& cTria)
00635 {
00636     std::list<std::vector<unsigned long> > aFailed;
00637     MeshCore::MeshTopoAlgorithm topalg(_kernel);
00638     topalg.FillupHoles(length, level, cTria, aFailed);
00639 }
00640 
00641 void MeshObject::offset(float fSize)
00642 {
00643     std::vector<Base::Vector3f> normals = _kernel.CalcVertexNormals();
00644 
00645     unsigned int i = 0;
00646     // go through all the vertex normals
00647     for (std::vector<Base::Vector3f>::iterator It= normals.begin();It != normals.end();It++,i++)
00648         // and move each mesh point in the normal direction
00649         _kernel.MovePoint(i,It->Normalize() * fSize);
00650     _kernel.RecalcBoundBox();
00651 }
00652 
00653 void MeshObject::offsetSpecial2(float fSize)
00654 {
00655     Base::Builder3D builder;  
00656     std::vector<Base::Vector3f> PointNormals= _kernel.CalcVertexNormals();
00657     std::vector<Base::Vector3f> FaceNormals;
00658     std::set<unsigned long> fliped;
00659 
00660     MeshCore::MeshFacetIterator it(_kernel);
00661     for (it.Init(); it.More(); it.Next())
00662         FaceNormals.push_back(it->GetNormal().Normalize());
00663 
00664     unsigned int i = 0;
00665 
00666     // go through all the vertex normals
00667     for (std::vector<Base::Vector3f>::iterator It= PointNormals.begin();It != PointNormals.end();It++,i++){
00668         builder.addSingleLine(_kernel.GetPoint(i),_kernel.GetPoint(i)+It->Normalize() * fSize);
00669         // and move each mesh point in the normal direction
00670         _kernel.MovePoint(i,It->Normalize() * fSize);
00671     }
00672     _kernel.RecalcBoundBox();
00673 
00674     MeshCore::MeshTopoAlgorithm alg(_kernel);
00675 
00676     for (int l= 0; l<1 ;l++) {
00677         for ( it.Init(),i=0; it.More(); it.Next(),i++) {
00678             if (it->IsFlag(MeshCore::MeshFacet::INVALID))
00679                 continue;
00680             // calculate the angle between them
00681             float angle = acos((FaceNormals[i] * it->GetNormal()) / (it->GetNormal().Length() * FaceNormals[i].Length()));
00682             if (angle > 1.6) {
00683                 builder.addSinglePoint(it->GetGravityPoint(),4,1,0,0);
00684                 fliped.insert(it.Position());
00685             }
00686         }
00687         
00688         // if there no flipped triangels -> stop
00689         //int f =fliped.size();
00690         if (fliped.size() == 0)
00691             break;
00692       
00693         for( std::set<unsigned long>::iterator It= fliped.begin();It!=fliped.end();++It)
00694             alg.CollapseFacet(*It);
00695         fliped.clear();
00696     }
00697 
00698     alg.Cleanup();
00699 
00700     // search for intersected facets
00701     MeshCore::MeshEvalSelfIntersection eval(_kernel);
00702     std::vector<std::pair<unsigned long, unsigned long> > faces;
00703     eval.GetIntersections(faces);
00704     builder.saveToLog();
00705 }
00706 
00707 void MeshObject::offsetSpecial(float fSize, float zmax, float zmin)
00708 {
00709     std::vector<Base::Vector3f> normals = _kernel.CalcVertexNormals();
00710 
00711     unsigned int i = 0;
00712     // go through all the vertex normals
00713     for (std::vector<Base::Vector3f>::iterator It= normals.begin();It != normals.end();It++,i++) {
00714         Base::Vector3f Pnt = _kernel.GetPoint(i);
00715         if (Pnt.z < zmax && Pnt.z > zmin) {
00716             Pnt.z = 0;
00717             _kernel.MovePoint(i,Pnt.Normalize() * fSize);
00718         }
00719         else {
00720             // and move each mesh point in the normal direction
00721             _kernel.MovePoint(i,It->Normalize() * fSize);
00722         }
00723     }
00724 }
00725 
00726 void MeshObject::clear(void)
00727 {
00728     _kernel.Clear();
00729     this->_segments.clear();
00730     setTransform(Base::Matrix4D());
00731 }
00732 
00733 void MeshObject::transformToEigenSystem()
00734 {
00735     MeshCore::MeshEigensystem cMeshEval(_kernel);
00736     cMeshEval.Evaluate();
00737     this->setTransform(cMeshEval.Transform());
00738 }
00739 
00740 void MeshObject::movePoint(unsigned long index, const Base::Vector3d& v)
00741 {
00742     // v is a vector, hence we must not apply the translation part
00743     // of the transformation to the vector
00744     Base::Vector3d vec(v);
00745     vec.x += _Mtrx[0][3];
00746     vec.y += _Mtrx[1][3];
00747     vec.z += _Mtrx[2][3];
00748     _kernel.MovePoint(index,transformToInside(vec));
00749 }
00750 
00751 void MeshObject::setPoint(unsigned long index, const Base::Vector3d& p)
00752 {
00753     _kernel.SetPoint(index,transformToInside(p));
00754 }
00755 
00756 void MeshObject::smooth(int iterations, float d_max)
00757 {
00758     _kernel.Smooth(iterations, d_max);
00759 }
00760 
00761 Base::Vector3d MeshObject::getPointNormal(unsigned long index) const
00762 {
00763     std::vector<Base::Vector3f> temp = _kernel.CalcVertexNormals();
00764     Base::Vector3d normal = transformToOutside(temp[index]);
00765 
00766     // the normal is a vector, hence we must not apply the translation part
00767     // of the transformation to the vector
00768     normal.x -= _Mtrx[0][3];
00769     normal.y -= _Mtrx[1][3];
00770     normal.z -= _Mtrx[2][3];
00771     normal.Normalize();
00772     return normal;
00773 }
00774 
00775 void MeshObject::crossSections(const std::vector<MeshObject::TPlane>& planes, std::vector<MeshObject::TPolylines> &sections,
00776                                float fMinEps, bool bConnectPolygons) const
00777 {
00778     MeshCore::MeshFacetGrid grid(_kernel);
00779     MeshCore::MeshAlgorithm algo(_kernel);
00780     for (std::vector<MeshObject::TPlane>::const_iterator it = planes.begin(); it != planes.end(); ++it) {
00781         MeshObject::TPolylines polylines;
00782         algo.CutWithPlane(it->first, it->second, grid, polylines, fMinEps, bConnectPolygons);
00783         sections.push_back(polylines);
00784     }
00785 }
00786 
00787 MeshObject* MeshObject::unite(const MeshObject& mesh) const
00788 {
00789     MeshCore::MeshKernel result;
00790     MeshCore::MeshKernel kernel1(this->_kernel);
00791     kernel1.Transform(this->_Mtrx);
00792     MeshCore::MeshKernel kernel2(mesh._kernel);
00793     kernel2.Transform(mesh._Mtrx);
00794     MeshCore::SetOperations setOp(kernel1, kernel2, result,
00795                                   MeshCore::SetOperations::Union, Epsilon);
00796     setOp.Do();
00797     return new MeshObject(result);
00798 }
00799 
00800 MeshObject* MeshObject::intersect(const MeshObject& mesh) const
00801 {
00802     MeshCore::MeshKernel result;
00803     MeshCore::MeshKernel kernel1(this->_kernel);
00804     kernel1.Transform(this->_Mtrx);
00805     MeshCore::MeshKernel kernel2(mesh._kernel);
00806     kernel2.Transform(mesh._Mtrx);
00807     MeshCore::SetOperations setOp(kernel1, kernel2, result,
00808                                   MeshCore::SetOperations::Intersect, Epsilon);
00809     setOp.Do();
00810     return new MeshObject(result);
00811 }
00812 
00813 MeshObject* MeshObject::subtract(const MeshObject& mesh) const
00814 {
00815     MeshCore::MeshKernel result;
00816     MeshCore::MeshKernel kernel1(this->_kernel);
00817     kernel1.Transform(this->_Mtrx);
00818     MeshCore::MeshKernel kernel2(mesh._kernel);
00819     kernel2.Transform(mesh._Mtrx);
00820     MeshCore::SetOperations setOp(kernel1, kernel2, result,
00821                                   MeshCore::SetOperations::Difference, Epsilon);
00822     setOp.Do();
00823     return new MeshObject(result);
00824 }
00825 
00826 MeshObject* MeshObject::inner(const MeshObject& mesh) const
00827 {
00828     MeshCore::MeshKernel result;
00829     MeshCore::MeshKernel kernel1(this->_kernel);
00830     kernel1.Transform(this->_Mtrx);
00831     MeshCore::MeshKernel kernel2(mesh._kernel);
00832     kernel2.Transform(mesh._Mtrx);
00833     MeshCore::SetOperations setOp(kernel1, kernel2, result,
00834                                   MeshCore::SetOperations::Inner, Epsilon);
00835     setOp.Do();
00836     return new MeshObject(result);
00837 }
00838 
00839 MeshObject* MeshObject::outer(const MeshObject& mesh) const
00840 {
00841     MeshCore::MeshKernel result;
00842     MeshCore::MeshKernel kernel1(this->_kernel);
00843     kernel1.Transform(this->_Mtrx);
00844     MeshCore::MeshKernel kernel2(mesh._kernel);
00845     kernel2.Transform(mesh._Mtrx);
00846     MeshCore::SetOperations setOp(kernel1, kernel2, result,
00847                                   MeshCore::SetOperations::Outer, Epsilon);
00848     setOp.Do();
00849     return new MeshObject(result);
00850 }
00851 
00852 void MeshObject::refine()
00853 {
00854     unsigned long cnt = _kernel.CountFacets();
00855     MeshCore::MeshFacetIterator cF(_kernel);
00856     MeshCore::MeshTopoAlgorithm topalg(_kernel);
00857     for (unsigned long i=0; i<cnt; i++) {
00858         cF.Set(i);
00859         if (!cF->IsDeformed())
00860             topalg.InsertVertexAndSwapEdge(i, cF->GetGravityPoint(), 0.1f);
00861     }
00862 
00863     // clear the segments because we don't know how the new
00864     // topology looks like
00865     this->_segments.clear();
00866 }
00867 
00868 void MeshObject::optimizeTopology(float fMaxAngle)
00869 {
00870     MeshCore::MeshTopoAlgorithm topalg(_kernel);
00871     if (fMaxAngle > 0.0f)
00872         topalg.OptimizeTopology(fMaxAngle);
00873     else
00874         topalg.OptimizeTopology();
00875 
00876     // clear the segments because we don't know how the new
00877     // topology looks like
00878     this->_segments.clear();
00879 }
00880 
00881 void MeshObject::optimizeEdges()
00882 {
00883     MeshCore::MeshTopoAlgorithm topalg(_kernel);
00884     topalg.AdjustEdgesToCurvatureDirection();
00885 }
00886 
00887 void MeshObject::splitEdges()
00888 {
00889     std::vector<std::pair<unsigned long, unsigned long> > adjacentFacet;
00890     MeshCore::MeshAlgorithm alg(_kernel);
00891     alg.ResetFacetFlag(MeshCore::MeshFacet::VISIT);
00892     const MeshCore::MeshFacetArray& rFacets = _kernel.GetFacets();
00893     for (MeshCore::MeshFacetArray::_TConstIterator pF = rFacets.begin(); pF != rFacets.end(); ++pF) {
00894         int id=2;
00895         if (pF->_aulNeighbours[id] != ULONG_MAX) {
00896             const MeshCore::MeshFacet& rFace = rFacets[pF->_aulNeighbours[id]];
00897             if (!pF->IsFlag(MeshCore::MeshFacet::VISIT) && !rFace.IsFlag(MeshCore::MeshFacet::VISIT)) {
00898                 pF->SetFlag(MeshCore::MeshFacet::VISIT);
00899                 rFace.SetFlag(MeshCore::MeshFacet::VISIT);
00900                 adjacentFacet.push_back(std::make_pair(pF-rFacets.begin(), pF->_aulNeighbours[id]));
00901             }
00902         }
00903     }
00904 
00905     MeshCore::MeshFacetIterator cIter(_kernel);
00906     MeshCore::MeshTopoAlgorithm topalg(_kernel);
00907     for (std::vector<std::pair<unsigned long, unsigned long> >::iterator it = adjacentFacet.begin(); it != adjacentFacet.end(); ++it) {
00908         cIter.Set(it->first);
00909         Base::Vector3f mid = 0.5f*(cIter->_aclPoints[0]+cIter->_aclPoints[2]);
00910         topalg.SplitEdge(it->first, it->second, mid);
00911     }
00912 
00913     // clear the segments because we don't know how the new
00914     // topology looks like
00915     this->_segments.clear();
00916 }
00917 
00918 void MeshObject::splitEdge(unsigned long facet, unsigned long neighbour, const Base::Vector3f& v)
00919 {
00920     MeshCore::MeshTopoAlgorithm topalg(_kernel);
00921     topalg.SplitEdge(facet, neighbour, v);
00922 }
00923 
00924 void MeshObject::splitFacet(unsigned long facet, const Base::Vector3f& v1, const Base::Vector3f& v2)
00925 {
00926     MeshCore::MeshTopoAlgorithm topalg(_kernel);
00927     topalg.SplitFacet(facet, v1, v2);
00928 }
00929 
00930 void MeshObject::swapEdge(unsigned long facet, unsigned long neighbour)
00931 {
00932     MeshCore::MeshTopoAlgorithm topalg(_kernel);
00933     topalg.SwapEdge(facet, neighbour);
00934 }
00935 
00936 void MeshObject::collapseEdge(unsigned long facet, unsigned long neighbour)
00937 {
00938     MeshCore::MeshTopoAlgorithm topalg(_kernel);
00939     topalg.CollapseEdge(facet, neighbour);
00940 
00941     std::vector<unsigned long> remFacets;
00942     remFacets.push_back(facet);
00943     remFacets.push_back(neighbour);
00944     deletedFacets(remFacets);
00945 }
00946 
00947 void MeshObject::collapseFacet(unsigned long facet)
00948 {
00949     MeshCore::MeshTopoAlgorithm topalg(_kernel);
00950     topalg.CollapseFacet(facet);
00951 
00952     std::vector<unsigned long> remFacets;
00953     remFacets.push_back(facet);
00954     deletedFacets(remFacets);
00955 }
00956 
00957 void MeshObject::collapseFacets(const std::vector<unsigned long>& facets)
00958 {
00959     MeshCore::MeshTopoAlgorithm alg(_kernel);
00960     for (std::vector<unsigned long>::const_iterator it = facets.begin(); it != facets.end(); ++it) {
00961         alg.CollapseFacet(*it);
00962     }
00963 
00964     deletedFacets(facets);
00965 }
00966 
00967 void MeshObject::insertVertex(unsigned long facet, const Base::Vector3f& v)
00968 {
00969     MeshCore::MeshTopoAlgorithm topalg(_kernel);
00970     topalg.InsertVertex(facet, v);
00971 }
00972 
00973 void MeshObject::snapVertex(unsigned long facet, const Base::Vector3f& v)
00974 {
00975     MeshCore::MeshTopoAlgorithm topalg(_kernel);
00976     topalg.SnapVertex(facet, v);
00977 }
00978 
00979 unsigned long MeshObject::countNonUniformOrientedFacets() const
00980 {
00981     MeshCore::MeshEvalOrientation cMeshEval(_kernel);
00982     std::vector<unsigned long> inds = cMeshEval.GetIndices();
00983     return inds.size();
00984 }
00985 
00986 void MeshObject::flipNormals()
00987 {
00988     MeshCore::MeshTopoAlgorithm alg(_kernel);
00989     alg.FlipNormals();
00990 }
00991 
00992 void MeshObject::harmonizeNormals()
00993 {
00994     MeshCore::MeshTopoAlgorithm alg(_kernel);
00995     alg.HarmonizeNormals();
00996 }
00997 
00998 bool MeshObject::hasNonManifolds() const
00999 {
01000     MeshCore::MeshEvalTopology cMeshEval(_kernel);
01001     return !cMeshEval.Evaluate();
01002 }
01003 
01004 void MeshObject::removeNonManifolds()
01005 {
01006     unsigned long count = _kernel.CountFacets();
01007     MeshCore::MeshEvalTopology cMeshEval(_kernel);
01008     if (!cMeshEval.Evaluate()) {
01009         MeshCore::MeshFixTopology cMeshFix(_kernel, cMeshEval.GetFacets());
01010         cMeshFix.Fixup();
01011     }
01012 
01013     if (_kernel.CountFacets() < count)
01014         this->_segments.clear();
01015 }
01016 
01017 bool MeshObject::hasSelfIntersections() const
01018 {
01019     MeshCore::MeshEvalSelfIntersection cMeshEval(_kernel);
01020     return !cMeshEval.Evaluate();
01021 }
01022 
01023 void MeshObject::removeSelfIntersections()
01024 {
01025     std::vector<std::pair<unsigned long, unsigned long> > selfIntersections;
01026     MeshCore::MeshEvalSelfIntersection cMeshEval(_kernel);
01027     cMeshEval.GetIntersections(selfIntersections);
01028 
01029     if (!selfIntersections.empty()) {
01030         MeshCore::MeshFixSelfIntersection cMeshFix(_kernel, selfIntersections);
01031         cMeshFix.Fixup();
01032         this->_segments.clear();
01033     }
01034 }
01035 
01036 void MeshObject::removeSelfIntersections(const std::vector<unsigned long>& indices)
01037 {
01038     // make sure that the number of indices is even and are in range
01039     if (indices.size() % 2 != 0)
01040         return;
01041     if (std::find_if(indices.begin(), indices.end(), 
01042         std::bind2nd(std::greater_equal<unsigned long>(), _kernel.CountFacets())) < indices.end())
01043         return;
01044     std::vector<std::pair<unsigned long, unsigned long> > selfIntersections;
01045     std::vector<unsigned long>::const_iterator it;
01046     for (it = indices.begin(); it != indices.end(); ) {
01047         unsigned long id1 = *it; ++it;
01048         unsigned long id2 = *it; ++it;
01049         selfIntersections.push_back(std::make_pair
01050             <unsigned long, unsigned long>(id1,id2));
01051     }
01052 
01053     if (!selfIntersections.empty()) {
01054         MeshCore::MeshFixSelfIntersection cMeshFix(_kernel, selfIntersections);
01055         cMeshFix.Fixup();
01056         this->_segments.clear();
01057     }
01058 }
01059 
01060 void MeshObject::removeFoldsOnSurface()
01061 {
01062     std::vector<unsigned long> indices;
01063     MeshCore::MeshEvalFoldsOnSurface s_eval(_kernel);
01064     MeshCore::MeshEvalFoldOversOnSurface f_eval(_kernel);
01065 
01066     f_eval.Evaluate();
01067     std::vector<unsigned long> inds  = f_eval.GetIndices();
01068 
01069     s_eval.Evaluate();
01070     std::vector<unsigned long> inds1 = s_eval.GetIndices();
01071 
01072     // remove duplicates
01073     inds.insert(inds.end(), inds1.begin(), inds1.end());
01074     std::sort(inds.begin(), inds.end());
01075     inds.erase(std::unique(inds.begin(), inds.end()), inds.end());
01076 
01077     if (!inds.empty())
01078         deleteFacets(inds);
01079 
01080     // do this as additional check after removing folds on closed area
01081     for (int i=0; i<5; i++) {
01082         MeshCore::MeshEvalFoldsOnBoundary b_eval(_kernel);
01083         if (b_eval.Evaluate())
01084             break;
01085         inds = b_eval.GetIndices();
01086         if (!inds.empty())
01087             deleteFacets(inds);
01088     }
01089 }
01090 
01091 void MeshObject::removeFullBoundaryFacets()
01092 {
01093     std::vector<unsigned long> facets;
01094     if (!MeshCore::MeshEvalBorderFacet(_kernel, facets).Evaluate()) {
01095         deleteFacets(facets);
01096     }
01097 }
01098 
01099 void MeshObject::validateIndices()
01100 {
01101     unsigned long count = _kernel.CountFacets();
01102 
01103     // for invalid neighbour indices we don't need to check first
01104     // but start directly with the validation
01105     MeshCore::MeshFixNeighbourhood fix(_kernel);
01106     fix.Fixup();
01107 
01108     MeshCore::MeshEvalRangeFacet rf(_kernel);
01109     if (!rf.Evaluate()) {
01110         MeshCore::MeshFixRangeFacet fix(_kernel);
01111         fix.Fixup();
01112     }
01113 
01114     MeshCore::MeshEvalRangePoint rp(_kernel);
01115     if (!rp.Evaluate()) {
01116         MeshCore::MeshFixRangePoint fix(_kernel);
01117         fix.Fixup();
01118     }
01119 
01120     MeshCore::MeshEvalCorruptedFacets cf(_kernel);
01121     if (!cf.Evaluate()) {
01122         MeshCore::MeshFixCorruptedFacets fix(_kernel);
01123         fix.Fixup();
01124     }
01125 
01126     if (_kernel.CountFacets() < count)
01127         this->_segments.clear();
01128 }
01129 
01130 void MeshObject::validateDeformations(float fMaxAngle)
01131 {
01132     unsigned long count = _kernel.CountFacets();
01133     MeshCore::MeshFixDeformedFacets eval(_kernel, fMaxAngle);
01134     eval.Fixup();
01135     if (_kernel.CountFacets() < count)
01136         this->_segments.clear();
01137 }
01138 
01139 void MeshObject::validateDegenerations()
01140 {
01141     unsigned long count = _kernel.CountFacets();
01142     MeshCore::MeshFixDegeneratedFacets eval(_kernel);
01143     eval.Fixup();
01144     if (_kernel.CountFacets() < count)
01145         this->_segments.clear();
01146 }
01147 
01148 void MeshObject::removeDuplicatedPoints()
01149 {
01150     unsigned long count = _kernel.CountFacets();
01151     MeshCore::MeshFixDuplicatePoints eval(_kernel);
01152     eval.Fixup();
01153     if (_kernel.CountFacets() < count)
01154         this->_segments.clear();
01155 }
01156 
01157 void MeshObject::removeDuplicatedFacets()
01158 {
01159     unsigned long count = _kernel.CountFacets();
01160     MeshCore::MeshFixDuplicateFacets eval(_kernel);
01161     eval.Fixup();
01162     if (_kernel.CountFacets() < count)
01163         this->_segments.clear();
01164 }
01165 
01166 MeshObject* MeshObject::createMeshFromList(Py::List& list)
01167 {
01168     std::vector<MeshCore::MeshGeomFacet> facets;
01169     MeshCore::MeshGeomFacet facet;
01170     int i = 0;
01171     for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
01172         Py::List item(*it);
01173         for (int j = 0; j < 3; j++) {
01174             Py::Float value(item[j]);
01175             facet._aclPoints[i][j] = (float)value;
01176         }
01177         if (++i == 3) {
01178             i = 0;
01179             facet.CalcNormal();
01180             facets.push_back(facet);
01181         }
01182     }
01183 
01184     std::auto_ptr<MeshObject> mesh(new MeshObject);
01185     //mesh->addFacets(facets);
01186     mesh->getKernel() = facets;
01187     return mesh.release();
01188 }
01189 
01190 MeshObject* MeshObject::createSphere(float radius, int sampling)
01191 {
01192     // load the 'BuildRegularGeoms' module
01193     Base::PyGILStateLocker lock;
01194     try {
01195         Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
01196         Py::Dict dict = module.getDict();
01197         Py::Callable call(dict.getItem("Sphere"));
01198         Py::Tuple args(2);
01199         args.setItem(0, Py::Float(radius));
01200         args.setItem(1, Py::Int(sampling));
01201         Py::List list(call.apply(args));
01202         return createMeshFromList(list);
01203     }
01204     catch (Py::Exception& e) {
01205         e.clear();
01206     }
01207 
01208     return 0;
01209 }
01210 
01211 MeshObject* MeshObject::createEllipsoid(float radius1, float radius2, int sampling)
01212 {
01213     // load the 'BuildRegularGeoms' module
01214     Base::PyGILStateLocker lock;
01215     try {
01216         Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
01217         Py::Dict dict = module.getDict();
01218         Py::Callable call(dict.getItem("Ellipsoid"));
01219         Py::Tuple args(3);
01220         args.setItem(0, Py::Float(radius1));
01221         args.setItem(1, Py::Float(radius2));
01222         args.setItem(2, Py::Int(sampling));
01223         Py::List list(call.apply(args));
01224         return createMeshFromList(list);
01225     }
01226     catch (Py::Exception& e) {
01227         e.clear();
01228     }
01229 
01230     return 0;
01231 }
01232 
01233 MeshObject* MeshObject::createCylinder(float radius, float length, int closed, float edgelen, int sampling)
01234 {
01235     // load the 'BuildRegularGeoms' module
01236     Base::PyGILStateLocker lock;
01237     try {
01238         Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
01239         Py::Dict dict = module.getDict();
01240         Py::Callable call(dict.getItem("Cylinder"));
01241         Py::Tuple args(5);
01242         args.setItem(0, Py::Float(radius));
01243         args.setItem(1, Py::Float(length));
01244         args.setItem(2, Py::Int(closed));
01245         args.setItem(3, Py::Float(edgelen));
01246         args.setItem(4, Py::Int(sampling));
01247         Py::List list(call.apply(args));
01248         return createMeshFromList(list);
01249     }
01250     catch (Py::Exception& e) {
01251         e.clear();
01252     }
01253 
01254     return 0;
01255 }
01256 
01257 MeshObject* MeshObject::createCone(float radius1, float radius2, float len, int closed, float edgelen, int sampling)
01258 {
01259     // load the 'BuildRegularGeoms' module
01260     Base::PyGILStateLocker lock;
01261     try {
01262         Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
01263         Py::Dict dict = module.getDict();
01264         Py::Callable call(dict.getItem("Cone"));
01265         Py::Tuple args(6);
01266         args.setItem(0, Py::Float(radius1));
01267         args.setItem(1, Py::Float(radius2));
01268         args.setItem(2, Py::Float(len));
01269         args.setItem(3, Py::Int(closed));
01270         args.setItem(4, Py::Float(edgelen));
01271         args.setItem(5, Py::Int(sampling));
01272         Py::List list(call.apply(args));
01273         return createMeshFromList(list);
01274     }
01275     catch (Py::Exception& e) {
01276         e.clear();
01277     }
01278 
01279     return 0;
01280 }
01281 
01282 MeshObject* MeshObject::createTorus(float radius1, float radius2, int sampling)
01283 {
01284     // load the 'BuildRegularGeoms' module
01285     Base::PyGILStateLocker lock;
01286     try {
01287         Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
01288         Py::Dict dict = module.getDict();
01289         Py::Callable call(dict.getItem("Toroid"));
01290         Py::Tuple args(3);
01291         args.setItem(0, Py::Float(radius1));
01292         args.setItem(1, Py::Float(radius2));
01293         args.setItem(2, Py::Int(sampling));
01294         Py::List list(call.apply(args));
01295         return createMeshFromList(list);
01296     }
01297     catch (Py::Exception& e) {
01298         e.clear();
01299     }
01300 
01301     return 0;
01302 }
01303 
01304 MeshObject* MeshObject::createCube(float length, float width, float height)
01305 {
01306     // load the 'BuildRegularGeoms' module
01307     Base::PyGILStateLocker lock;
01308     try {
01309         Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
01310         Py::Dict dict = module.getDict();
01311         Py::Callable call(dict.getItem("Cube"));
01312         Py::Tuple args(3);
01313         args.setItem(0, Py::Float(length));
01314         args.setItem(1, Py::Float(width));
01315         args.setItem(2, Py::Float(height));
01316         Py::List list(call.apply(args));
01317         return createMeshFromList(list);
01318     }
01319     catch (Py::Exception& e) {
01320         e.clear();
01321     }
01322 
01323     return 0;
01324 }
01325 
01326 MeshObject* MeshObject::createCube(float length, float width, float height, float edgelen)
01327 {
01328     // load the 'BuildRegularGeoms' module
01329     Base::PyGILStateLocker lock;
01330     try {
01331         Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
01332         Py::Dict dict = module.getDict();
01333         Py::Callable call(dict.getItem("FineCube"));
01334         Py::Tuple args(4);
01335         args.setItem(0, Py::Float(length));
01336         args.setItem(1, Py::Float(width));
01337         args.setItem(2, Py::Float(height));
01338         args.setItem(3, Py::Float(edgelen));
01339         Py::List list(call.apply(args));
01340         return createMeshFromList(list);
01341     }
01342     catch (Py::Exception& e) {
01343         e.clear();
01344     }
01345 
01346     return 0;
01347 }
01348 
01349 void MeshObject::addSegment(const Segment& s)
01350 {
01351     addSegment(s.getIndices());
01352 }
01353 
01354 void MeshObject::addSegment(const std::vector<unsigned long>& inds)
01355 {
01356     unsigned long maxIndex = _kernel.CountFacets();
01357     for (std::vector<unsigned long>::const_iterator it = inds.begin(); it != inds.end(); ++it) {
01358         if (*it >= maxIndex)
01359             throw Base::Exception("Index out of range");
01360     }
01361 
01362     this->_segments.push_back(Segment(this,inds,true));
01363 }
01364 
01365 const Segment& MeshObject::getSegment(unsigned long index) const
01366 {
01367     return this->_segments[index];
01368 }
01369 
01370 Segment& MeshObject::getSegment(unsigned long index)
01371 {
01372     return this->_segments[index];
01373 }
01374 
01375 MeshObject* MeshObject::meshFromSegment(const std::vector<unsigned long>& indices) const
01376 {
01377     MeshCore::MeshFacetArray facets;
01378     facets.reserve(indices.size());
01379     const MeshCore::MeshPointArray& kernel_p = _kernel.GetPoints();
01380     const MeshCore::MeshFacetArray& kernel_f = _kernel.GetFacets();
01381     for (std::vector<unsigned long>::const_iterator it = indices.begin(); it != indices.end(); ++it) {
01382         facets.push_back(kernel_f[*it]);
01383     }
01384 
01385     MeshCore::MeshKernel kernel;
01386     kernel.Merge(kernel_p, facets);
01387 
01388     return new MeshObject(kernel, _Mtrx);
01389 }
01390 
01391 std::vector<Segment> MeshObject::getSegmentsFromType(MeshObject::Type type, const Segment& aSegment, float dev) const
01392 {
01393     std::vector<Segment> segm;
01394     unsigned long startFacet, visited;
01395     if (this->_kernel.CountFacets() == 0)
01396         return segm;
01397 
01398     // reset VISIT flags
01399     MeshCore::MeshAlgorithm cAlgo(this->_kernel);
01400     if (aSegment.isEmpty()) {
01401         cAlgo.ResetFacetFlag(MeshCore::MeshFacet::VISIT);
01402     }
01403     else {
01404         cAlgo.SetFacetFlag(MeshCore::MeshFacet::VISIT);
01405         cAlgo.ResetFacetsFlag(aSegment.getIndices(), MeshCore::MeshFacet::VISIT);
01406     }
01407 
01408     const MeshCore::MeshFacetArray& rFAry = this->_kernel.GetFacets();
01409     MeshCore::MeshFacetArray::_TConstIterator iTri = rFAry.begin();
01410     MeshCore::MeshFacetArray::_TConstIterator iBeg = rFAry.begin();
01411     MeshCore::MeshFacetArray::_TConstIterator iEnd = rFAry.end();
01412 
01413     // start from the first not visited facet
01414     visited = cAlgo.CountFacetFlag(MeshCore::MeshFacet::VISIT);
01415     iTri = std::find_if(iTri, iEnd, std::bind2nd(MeshCore::MeshIsNotFlag<MeshCore::MeshFacet>(),
01416         MeshCore::MeshFacet::VISIT));
01417     startFacet = iTri - iBeg;
01418 
01419     while (startFacet != ULONG_MAX) {
01420         // collect all facets of the same geometry
01421         std::vector<unsigned long> indices;
01422         indices.push_back(startFacet);
01423         MeshCore::MeshPlaneVisitor pv(this->_kernel, startFacet, dev, indices);
01424         visited += this->_kernel.VisitNeighbourFacets(pv, startFacet);
01425 
01426         iTri = std::find_if(iTri, iEnd, std::bind2nd(MeshCore::MeshIsNotFlag<MeshCore::MeshFacet>(),
01427             MeshCore::MeshFacet::VISIT));
01428         if (iTri < iEnd)
01429             startFacet = iTri - iBeg;
01430         else
01431             startFacet = ULONG_MAX;
01432         segm.push_back(Segment(const_cast<MeshObject*>(this), indices, false));
01433     }
01434 
01435     return segm;
01436 }
01437 
01438 // ----------------------------------------------------------------------------
01439 
01440 MeshObject::const_point_iterator::const_point_iterator(const MeshObject* mesh, unsigned long index)
01441   : _mesh(mesh), _p_it(mesh->getKernel())
01442 {
01443     this->_p_it.Set(index);
01444     this->_p_it.Transform(_mesh->_Mtrx);
01445     this->_point.Mesh = const_cast<MeshObject*>(_mesh);
01446 }
01447 
01448 MeshObject::const_point_iterator::const_point_iterator(const MeshObject::const_point_iterator& fi)
01449   : _mesh(fi._mesh), _point(fi._point), _p_it(fi._p_it)
01450 {
01451 }
01452 
01453 MeshObject::const_point_iterator::~const_point_iterator()
01454 {
01455 }
01456 
01457 MeshObject::const_point_iterator& MeshObject::const_point_iterator::operator=(const MeshObject::const_point_iterator& pi)
01458 {
01459     this->_mesh  = pi._mesh;
01460     this->_point = pi._point;
01461     this->_p_it  = pi._p_it;
01462     return *this;
01463 }
01464 
01465 void MeshObject::const_point_iterator::dereference()
01466 {
01467     this->_point.x = _p_it->x;
01468     this->_point.y = _p_it->y;
01469     this->_point.z = _p_it->z;
01470     this->_point.Index = _p_it.Position();
01471 }
01472 
01473 const MeshPoint& MeshObject::const_point_iterator::operator*()
01474 {
01475     dereference();
01476     return this->_point;
01477 }
01478 
01479 const MeshPoint* MeshObject::const_point_iterator::operator->()
01480 {
01481     dereference();
01482     return &(this->_point);
01483 }
01484 
01485 bool MeshObject::const_point_iterator::operator==(const MeshObject::const_point_iterator& pi) const
01486 {
01487     return (this->_mesh == pi._mesh) && (this->_p_it == pi._p_it);
01488 }
01489 
01490 bool MeshObject::const_point_iterator::operator!=(const MeshObject::const_point_iterator& pi) const 
01491 {
01492     return !operator==(pi);
01493 }
01494 
01495 MeshObject::const_point_iterator& MeshObject::const_point_iterator::operator++()
01496 {
01497     ++(this->_p_it);
01498     return *this;
01499 }
01500 
01501 MeshObject::const_point_iterator& MeshObject::const_point_iterator::operator--()
01502 {
01503     --(this->_p_it);
01504     return *this;
01505 }
01506 
01507 // ----------------------------------------------------------------------------
01508 
01509 MeshObject::const_facet_iterator::const_facet_iterator(const MeshObject* mesh, unsigned long index)
01510   : _mesh(mesh), _f_it(mesh->getKernel())
01511 {
01512     this->_f_it.Set(index);
01513     this->_f_it.Transform(_mesh->_Mtrx);
01514     this->_facet.Mesh = const_cast<MeshObject*>(_mesh);
01515 }
01516 
01517 MeshObject::const_facet_iterator::const_facet_iterator(const MeshObject::const_facet_iterator& fi)
01518   : _mesh(fi._mesh), _facet(fi._facet), _f_it(fi._f_it)
01519 {
01520 }
01521 
01522 MeshObject::const_facet_iterator::~const_facet_iterator()
01523 {
01524 }
01525 
01526 MeshObject::const_facet_iterator& MeshObject::const_facet_iterator::operator=(const MeshObject::const_facet_iterator& fi)
01527 {
01528     this->_mesh  = fi._mesh;
01529     this->_facet = fi._facet;
01530     this->_f_it  = fi._f_it;
01531     return *this;
01532 }
01533 
01534 void MeshObject::const_facet_iterator::dereference()
01535 {
01536     this->_facet.MeshCore::MeshGeomFacet::operator = (*_f_it);
01537     this->_facet.Index = _f_it.Position();
01538     const MeshCore::MeshFacet& face = _f_it.GetReference();
01539     for (int i=0; i<3;i++) {
01540         this->_facet.PIndex[i] = face._aulPoints[i];
01541         this->_facet.NIndex[i] = face._aulNeighbours[i];
01542     }
01543 }
01544 
01545 Facet& MeshObject::const_facet_iterator::operator*()
01546 {
01547     dereference();
01548     return this->_facet;
01549 }
01550 
01551 Facet* MeshObject::const_facet_iterator::operator->()
01552 {
01553     dereference();
01554     return &(this->_facet);
01555 }
01556 
01557 bool MeshObject::const_facet_iterator::operator==(const MeshObject::const_facet_iterator& fi) const
01558 {
01559     return (this->_mesh == fi._mesh) && (this->_f_it == fi._f_it);
01560 }
01561 
01562 bool MeshObject::const_facet_iterator::operator!=(const MeshObject::const_facet_iterator& fi) const 
01563 {
01564     return !operator==(fi);
01565 }
01566 
01567 MeshObject::const_facet_iterator& MeshObject::const_facet_iterator::operator++()
01568 {
01569     ++(this->_f_it);
01570     return *this;
01571 }
01572 
01573 MeshObject::const_facet_iterator& MeshObject::const_facet_iterator::operator--()
01574 {
01575     --(this->_f_it);
01576     return *this;
01577 }

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