edgesort.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2007                                                    *
00003  *   Joachim Zettler <Joachim.Zettler@gmx.de>                              *
00004  *                                                                         *
00005  *   This file is part of the FreeCAD CAx development system.              *
00006  *                                                                         *
00007  *   This library is free software; you can redistribute it and/or         *
00008  *   modify it under the terms of the GNU Library General Public           *
00009  *   License as published by the Free Software Foundation; either          *
00010  *   version 2 of the License, or (at your option) any later version.      *
00011  *                                                                         *
00012  *   This library  is distributed in the hope that it will be useful,      *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU Library General Public License for more details.                  *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU Library General Public     *
00018  *   License along with this library; see the file COPYING.LIB. If not,    *
00019  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00020  *   Suite 330, Boston, MA  02111-1307, USA                                *
00021  *                                                                         *
00022  ***************************************************************************/
00023 
00024 #include "PreCompiled.h"
00025 
00026 #include "edgesort.h"
00027 #include <TopExp_Explorer.hxx>
00028 #include <TopAbs_ShapeEnum.hxx>
00029 #include <BRep_Tool.hxx>
00030 #include <TopExp.hxx>
00031 #include <TopoDS.hxx>
00032 #include <TopoDS_Shape.hxx>
00033 #include <TopoDS_Vertex.hxx>
00034 #include <TopoDS_Compound.hxx>
00035 #include <BRepAdaptor_Curve.hxx>
00036 #include <GCPnts_QuasiUniformDeflection.hxx>
00037 #include <BRep_Builder.hxx>
00038 
00039 
00040 Edgesort::Edgesort(const TopoDS_Shape& aShape)
00041         :m_shape(aShape),m_done(false)
00042 {
00043     m_edges.clear();
00044     m_EdgeBBoxMap.clear();
00045     m_vertices.clear();
00046 }
00047 
00048 Edgesort::~Edgesort(void)
00049 {
00050 }
00051 
00052 void Edgesort::Init()
00053 {
00054 
00055     Perform();
00056 
00057     m_edges.clear();
00058     m_edges = m_EdgeBBoxMap.begin()->second;
00059     m_edgeIter = m_edges.begin();
00060 }
00061 
00062 //#include <BRepBuilder.hxx>
00063 TopoDS_Shape Edgesort::GetDesiredCutShape(int desiredIndex)
00064 {
00065     m_edges.clear();
00066     m_EdgeBBoxMap.clear();
00067     m_vertices.clear();
00068 
00069     Perform();
00070 
00071     if (m_EdgeBBoxMap.size()>1)
00072     {
00073         if (desiredIndex == 1) //Return the smallest to return it
00074         {
00075             m_edges = m_EdgeBBoxMap.begin()->second;
00076 
00077         }
00078         else
00079         {
00080             m_edges = m_EdgeBBoxMap.rbegin()->second;
00081         }
00082         BRep_Builder aBuilder;
00083         TopoDS_Compound aCompound;
00084         aBuilder.MakeCompound(aCompound);
00085         for (m_edgeIter = m_edges.begin();m_edgeIter!=m_edges.end();++m_edgeIter)
00086         {
00087             aBuilder.Add(aCompound,*m_edgeIter);
00088         }
00089         return aCompound;
00090     }
00091     else
00092     {
00093         return m_shape;
00094     }
00095     //Go through the edges of the result you do not like and remove this result from the original shape
00096 
00097 }
00098 
00099 void Edgesort::ReInit(const TopoDS_Shape& aShape)
00100 {
00101     m_shape= aShape;
00102     m_done = false;
00103     m_edges.clear();
00104     m_EdgeBBoxMap.clear();
00105     m_vertices.clear();
00106     Perform();
00107     m_edges.clear();
00108     m_edges = m_EdgeBBoxMap.begin()->second;
00109     m_edgeIter = m_edges.begin();
00110 }
00111 
00112 
00113 bool Edgesort::More()
00114 {
00115     return m_edgeIter != m_edges.end();
00116 }
00117 
00118 bool Edgesort::MoreEdge()
00119 {
00120     return (m_edgeIter+1) != m_edges.end();
00121 }
00122 const TopoDS_Edge& Edgesort::NextEdge()
00123 {
00124     return *(m_edgeIter+1);
00125 }
00126 
00127 void Edgesort::Next()
00128 {
00129     ++m_edgeIter;
00130 }
00131 
00132 const TopoDS_Edge& Edgesort::Current()
00133 {
00134     return *m_edgeIter;
00135 }
00136 
00137 void Edgesort::Perform()
00138 {
00139     if ( m_shape.IsNull() )
00140         return;
00141 
00142     //adds all the vertices to a map, and store the associated edges
00143     TopExp_Explorer explorer;
00144     Standard_Integer nbEdges = 0;
00145     Standard_Integer nbNonEdges = 0;
00146     for ( explorer.Init(m_shape,TopAbs_EDGE) ; explorer.More() ; explorer.Next() )
00147     {
00148         const TopoDS_Edge& currentEdge = TopoDS::Edge(explorer.Current());
00149         if (IsValidEdge(currentEdge))
00150         {
00151             Perform(currentEdge);
00152             nbEdges++;
00153         }
00154         else
00155         {
00156             nbNonEdges++;
00157         }
00158     }
00159 
00160     //now, iterate through the edges to sort them
00161 
00162 
00163 
00164     do
00165     {
00166         m_edges.clear();
00167         tMapPntEdge::iterator iter = m_vertices.begin();
00168         const gp_Pnt& firstPoint = iter->first;
00169         gp_Pnt currentPoint = firstPoint;
00170         Standard_Boolean toContinue;
00171         do
00172         {
00173             toContinue = PerformEdges(currentPoint);
00174         }
00175         while (toContinue == Standard_True);
00176 
00177         tEdgeBBoxPair aTempPair;
00178         aTempPair.first = getBoundingBox(m_edges);
00179         aTempPair.second = m_edges;
00180         m_EdgeBBoxMap.insert(aTempPair);
00181     }
00182     while (!m_vertices.empty());
00183 
00184 
00185 
00186     m_done = true;
00187 
00188 }
00189 
00190 Base::BoundBox3f Edgesort::getBoundingBox(std::vector<TopoDS_Edge>& aList)
00191 {
00192     std::vector<TopoDS_Edge>::iterator aListIt;
00193     //Fill Bounding Boxes with Edges
00194     //Therefore we have to evaluate some points on our wire and feed the BBox Algorithm
00195     Base::BoundBox3f currentBox;
00196     currentBox.Flush();
00197     for (aListIt = aList.begin();aListIt!=aList.end();aListIt++)
00198     {
00199         BRepAdaptor_Curve curveAdaptor(*aListIt);
00200         GCPnts_QuasiUniformDeflection aProp(curveAdaptor,0.1);
00201         Base::Vector3f aPoint;
00202         for (int j=1;j<=aProp.NbPoints();++j)
00203         {
00204             aPoint.x = aProp.Value(j).X();
00205             aPoint.y = aProp.Value(j).Y();
00206             aPoint.z = aProp.Value(j).Z();
00207             currentBox.Add(aPoint);
00208         }
00209     }
00210     return currentBox;
00211 }
00212 
00213 
00214 
00215 bool Edgesort::PerformEdges(gp_Pnt& point)
00216 {
00217     tMapPntEdge::iterator iter = m_vertices.find(point);
00218     if ( iter == m_vertices.end() )
00219         return false;
00220 
00221     tEdgeVector& edges = iter->second;
00222 
00223     tEdgeVector::iterator edgeIt = edges.begin();
00224 
00225     //no more edges. pb
00226     if ( edgeIt == edges.end() )
00227     {
00228         //Delete also the current vertex
00229         m_vertices.erase(iter);
00230         return false;
00231     }
00232 
00233     TopoDS_Edge theEdge = *edgeIt;
00234 
00235     //we are storing the edge, so remove it from the vertex association
00236     edges.erase(edgeIt);
00237 
00238     //if no more edges, remove the vertex
00239     if ( edges.empty() )
00240         m_vertices.erase(iter);
00241 
00242 
00243     TopoDS_Vertex V1,V2;
00244     TopExp::Vertices(theEdge,V1,V2);
00245     gp_Pnt P1 = BRep_Tool::Pnt(V1);
00246     gp_Pnt P2 = BRep_Tool::Pnt(V2);
00247     if ( theEdge.Orientation() == TopAbs_REVERSED )
00248     {
00249         //switch the points
00250         gp_Pnt tmpP = P1;
00251         P1 = P2;
00252         P2 = tmpP;
00253     }
00254 
00255     gp_Pnt nextPoint;
00256     if ( P2.IsEqual(point,0.2) )
00257     {
00258         //need to reverse the edge
00259 
00260         theEdge.Reverse();
00261         nextPoint = P1;
00262     }
00263     else
00264     {
00265         nextPoint = P2;
00266     }
00267 
00268 
00269     //need to erase the edge from the second point
00270     iter = m_vertices.find(nextPoint);
00271     if ( iter != m_vertices.end() )
00272     {
00273         tEdgeVector& nextEdges = iter->second;
00274         bool somethingRemoved = false;
00275         for ( edgeIt = nextEdges.begin() ; edgeIt != nextEdges.end(); ++edgeIt )
00276         {
00277             if ( theEdge.IsSame(*edgeIt) )
00278             {
00279                 nextEdges.erase(edgeIt);
00280                 somethingRemoved = true;
00281                 break;
00282             }
00283         }
00284     }
00285 
00286     //put the edge at the end of the list
00287     m_edges.push_back(theEdge);
00288 
00289 
00290     point = nextPoint;
00291     return true;
00292 
00293 }
00294 
00295 void Edgesort::Perform(const TopoDS_Edge& edge)
00296 {
00297     if ( edge.IsNull() )
00298         return;
00299     TopoDS_Vertex V1,V2;
00300     TopExp::Vertices(edge,V1,V2);
00301     gp_Pnt P1 = BRep_Tool::Pnt(V1);
00302     gp_Pnt P2 = BRep_Tool::Pnt(V2);
00303 
00304     tEdgeVector emptyList;
00305 
00306     std::pair<tMapPntEdge::iterator,bool> iter = m_vertices.insert(tMapPntEdgePair(P1,emptyList));
00307     iter.first->second.push_back(edge);
00308     iter = m_vertices.insert(tMapPntEdgePair(P2,emptyList));
00309     iter.first->second.push_back(edge);
00310 }
00311 
00312 #include <BRepAdaptor_Curve.hxx>
00313 
00314 bool Edgesort::IsValidEdge(const TopoDS_Edge& edge)
00315 {
00316     if ( edge.IsNull() )
00317         return false;
00318     if ( BRep_Tool::Degenerated(edge) )
00319         return false;
00320 
00321     BRepAdaptor_Curve bac(edge);
00322 
00323     Standard_Real fparam = bac.FirstParameter();
00324     Standard_Real lparam = bac.LastParameter();
00325 
00326     gp_Pnt fpoint = bac.Value(fparam);
00327     gp_Pnt lpoint = bac.Value(lparam);
00328 
00329     //do not test the distance first last in case of a full circle edge (fpoint == lastpoint)
00330     //if ( fpoint.IsEqual(lpoint,1e-5 ) )
00331     //      return false;
00332 
00333     gp_Pnt mpoint = bac.Value((fparam+lparam)*0.5);
00334 
00335     Standard_Real dist = mpoint.Distance(lpoint);
00336     if ( dist <= 1e-5 )
00337         return false;
00338     dist = mpoint.Distance(fpoint);
00339     if ( dist <= 1e-5 )
00340         return false;
00341 
00342     return true;
00343 }
00344 

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