FeatureMeshSegmentByMesh.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2005 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 
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 #endif
00027 
00028 #include <Base/Console.h>
00029 #include <Base/Exception.h>
00030 #include <Base/Sequencer.h>
00031 
00032 #include "Core/Algorithm.h"
00033 #include "Core/Evaluation.h"
00034 #include "Core/Iterator.h"
00035 #include "Core/Visitor.h"
00036 
00037 #include "FeatureMeshSegmentByMesh.h"
00038 
00039 
00040 using namespace Mesh;
00041 using namespace MeshCore;
00042 
00043 PROPERTY_SOURCE(Mesh::SegmentByMesh, Mesh::Feature)
00044 
00045 
00046 SegmentByMesh::SegmentByMesh(void)
00047 {
00048     ADD_PROPERTY(Source  ,(0));
00049     ADD_PROPERTY(Tool    ,(0));
00050     ADD_PROPERTY(Base    ,(0.0,0.0,0.0));
00051     ADD_PROPERTY(Normal  ,(0.0,0.0,1.0));
00052 }
00053 
00054 short SegmentByMesh::mustExecute() const
00055 {
00056     if (Source.isTouched() || Tool.isTouched())
00057         return 1;
00058     if (Source.getValue() && Source.getValue()->isTouched())
00059         return 1;
00060     if (Tool.getValue() && Tool.getValue()->isTouched())
00061         return 1;
00062     return 0;
00063 }
00064 
00065 App::DocumentObjectExecReturn *SegmentByMesh::execute(void)
00066 {
00067     Mesh::PropertyMeshKernel *kernel=0;
00068     App::DocumentObject* mesh = Source.getValue();
00069     if (mesh) {
00070         App::Property* prop = mesh->getPropertyByName("Mesh");
00071         if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId())
00072             kernel = static_cast<Mesh::PropertyMeshKernel*>(prop);
00073     }
00074     if (!kernel)
00075         return new App::DocumentObjectExecReturn("No mesh specified.\n");
00076     else if (mesh->isError())
00077         return new App::DocumentObjectExecReturn("No valid mesh.\n");
00078 
00079     Mesh::PropertyMeshKernel *toolmesh=0;
00080     App::DocumentObject* tool = Tool.getValue();
00081     if (tool) {
00082         App::Property* prop = tool->getPropertyByName("Mesh");
00083         if (prop && prop->getTypeId() == Mesh::PropertyMeshKernel::getClassTypeId()) {
00084             toolmesh = static_cast<Mesh::PropertyMeshKernel*>(prop);
00085         }
00086     }
00087     if (!toolmesh) {
00088         return new App::DocumentObjectExecReturn("No toolmesh specified.\n");
00089     }
00090     else if (tool->isError()) {
00091         return new App::DocumentObjectExecReturn("No valid toolmesh.\n");
00092     }
00093 
00094     // the clipping plane
00095     Base::Vector3f cBase, cNormal;
00096     cBase =   Base.getValue();
00097     cNormal = Normal.getValue();
00098 
00099 
00100     const MeshKernel& rMeshKernel = kernel->getValue().getKernel();
00101     const MeshKernel& rToolMesh   = toolmesh->getValue().getKernel();
00102 
00103     // check if the toolmesh is a solid
00104     if (!MeshEvalSolid(rToolMesh).Evaluate()) {
00105         return new App::DocumentObjectExecReturn("Toolmesh is not solid.\n");
00106     }
00107 
00108     std::vector<unsigned long> faces;
00109     std::vector<MeshGeomFacet> aFaces;
00110 
00111     MeshAlgorithm cAlg(rMeshKernel);
00112     if (cNormal.Length() > 0.1f) // not a null vector
00113         cAlg.GetFacetsFromToolMesh(rToolMesh, cNormal, faces);
00114     else
00115         cAlg.GetFacetsFromToolMesh(rToolMesh, Base::Vector3f(0.0, 1.0f, 0.0f), faces);
00116 
00117     // if the clipping plane was set then we want only the visible facets
00118     if ( cNormal.Length() > 0.1f ) { // not a null vector 
00119         // now we have too many facets since we have (invisible) facets near to the back clipping plane, 
00120         // so we need the nearest facet to the front clipping plane
00121         //
00122         float fDist = FLOAT_MAX;
00123         unsigned long uIdx=ULONG_MAX;
00124         MeshFacetIterator cFIt(rMeshKernel);
00125 
00126         // get the nearest facet to the user (front clipping plane)
00127         for ( std::vector<unsigned long>::iterator it = faces.begin(); it != faces.end(); ++it ) {
00128             cFIt.Set(*it);
00129             float dist = (float)fabs(cFIt->GetGravityPoint().DistanceToPlane( cBase, cNormal ));
00130             if ( dist < fDist ) {
00131                 fDist = dist;
00132                 uIdx = *it;
00133             }
00134         }
00135 
00136         // succeeded
00137         if ( uIdx != ULONG_MAX ) {
00138             // set VISIT-Flag to all outer facets
00139             cAlg.SetFacetFlag( MeshFacet::VISIT );
00140             cAlg.ResetFacetsFlag(faces, MeshFacet::VISIT);
00141 
00142             faces.clear();
00143             MeshTopFacetVisitor clVisitor(faces);
00144             rMeshKernel.VisitNeighbourFacets(clVisitor, uIdx);
00145 
00146             // append also the start facet
00147             faces.push_back(uIdx);
00148         }
00149     }
00150 
00151     for ( std::vector<unsigned long>::iterator it = faces.begin(); it != faces.end(); ++it )
00152         aFaces.push_back( rMeshKernel.GetFacet(*it) );
00153 
00154     std::auto_ptr<MeshObject> pcKernel(new MeshObject);
00155     pcKernel->addFacets(aFaces);
00156     Mesh.setValuePtr(pcKernel.release());
00157 
00158     return App::DocumentObject::StdReturn;
00159 }
00160 

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