WireExplorer.cxx

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2007                                                    *
00003  *   Stephane Routelous <stephane.routelous@exotk.org                      *
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 "WireExplorer.h"
00027 #include <BRep_Tool.hxx>
00028 #include <TopExp_Explorer.hxx>
00029 #include <TopoDS.hxx>
00030 #include <TopExp.hxx>
00031 #include <TopoDS_Vertex.hxx>
00032 #include <Precision.hxx>
00033 
00034 
00035 WireExplorer::WireExplorer(const TopoDS_Wire& wire)
00036 :m_wire(wire),m_done(false)
00037 {
00038 }
00039 
00040 WireExplorer::~WireExplorer(void)
00041 {
00042 }
00043 
00044 void WireExplorer::Init()
00045 {
00046     if ( !m_done )
00047                 Perform();
00048 
00049     m_edgeIter = m_edges.begin();
00050 }
00051 
00052 bool WireExplorer::More()
00053 {
00054        return m_edgeIter != m_edges.end();
00055 }
00056 
00057 bool WireExplorer::MoreEdge()
00058 {
00059        return (m_edgeIter+1) != m_edges.end();
00060 }
00061 
00062 void WireExplorer::Next()
00063 {
00064        ++m_edgeIter;
00065 }
00066 
00067 const TopoDS_Edge& WireExplorer::Current()
00068 {
00069        return *m_edgeIter;
00070 }
00071 
00072 const TopoDS_Edge& WireExplorer::NextEdge()
00073 {
00074         return *(m_edgeIter+1);
00075 }
00076 
00077 void WireExplorer::Perform()
00078 {
00079        if ( m_wire.IsNull() )
00080                return;
00081 
00082        //adds all the vertices to a map, and store the associated edges
00083        TopExp_Explorer explorer;
00084        Standard_Integer nbEdges = 0;
00085        Standard_Integer nbNonEdges = 0;
00086        for ( explorer.Init(m_wire,TopAbs_EDGE) ; explorer.More() ; explorer.Next() )
00087        {
00088                const TopoDS_Edge& currentEdge = TopoDS::Edge(explorer.Current());
00089                if (IsValidEdge(currentEdge))
00090                {
00091                        Perform(currentEdge);
00092                        nbEdges++;
00093                }
00094                else
00095                {
00096                        nbNonEdges++;
00097                }
00098        }
00099 
00100        //now, iterate through the edge to sort them
00101 
00102        //take the first entry in the map
00103        tMapPntShapes::iterator iter = m_vertices.begin();
00104        const gp_Pnt& firstPoint = iter->first;
00105 
00106        gp_Pnt currentPoint = firstPoint;
00107        Standard_Boolean toContinue;
00108        do
00109        {
00110                toContinue = PerformEdges(currentPoint);
00111        }
00112        while (toContinue == Standard_True);
00113 
00114        m_done = true;
00115 
00116 }
00117 
00118 bool WireExplorer::PerformEdges(gp_Pnt& point)
00119 {
00120        tMapPntShapes::iterator iter = m_vertices.find(point);
00121        if ( iter == m_vertices.end() )
00122                return false;
00123 
00124        tEdgeVector& edges = iter->second;
00125 
00126        tEdgeVector::iterator edgeIt = edges.begin();
00127 
00128        //no more edges. pb
00129        if ( edgeIt == edges.end() )
00130                return false;
00131 
00132        TopoDS_Edge theEdge = *edgeIt;
00133 
00134        //we are storing the edge, so remove it from the vertex association
00135        edges.erase(edgeIt);
00136 
00137        //if no more edges, remove the vertex
00138        if ( edges.empty() )
00139                m_vertices.erase(iter);
00140 
00141 
00142        TopoDS_Vertex V1,V2;
00143        TopExp::Vertices(theEdge,V1,V2);
00144        gp_Pnt P1 = BRep_Tool::Pnt(V1);
00145        gp_Pnt P2 = BRep_Tool::Pnt(V2);
00146        if ( theEdge.Orientation() == TopAbs_REVERSED )
00147        {
00148                //switch the points
00149                gp_Pnt tmpP = P1;
00150                P1 = P2;
00151                P2 = tmpP;
00152        }
00153 
00154        gp_Pnt nextPoint;
00155        if ( P2.IsEqual(point,Precision::Confusion()) )
00156        {
00157                //need to reverse the edge
00158                theEdge.Reverse();
00159                nextPoint = P1;
00160        }
00161        else
00162        {
00163                nextPoint = P2;
00164        }
00165 
00166        //need to erase the edge from the second point
00167        iter = m_vertices.find(nextPoint);
00168        if ( iter != m_vertices.end() )
00169        {
00170                tEdgeVector& nextEdges = iter->second;
00171                bool somethingRemoved = false;
00172                for ( edgeIt = nextEdges.begin() ; edgeIt != nextEdges.end(); ++edgeIt )
00173                {
00174                        if ( theEdge.IsSame(*edgeIt) )
00175                        {
00176                                nextEdges.erase(edgeIt);
00177                                somethingRemoved = true;
00178                                break;
00179                        }
00180                }
00181        }
00182 
00183        //put the edge at the end of the list
00184        m_edges.push_back(theEdge);
00185 
00186        point = nextPoint;
00187        return true;
00188 
00189 }
00190 
00191 void WireExplorer::Perform(const TopoDS_Edge& edge)
00192 {
00193        if ( edge.IsNull() )
00194                return;
00195        TopoDS_Vertex V1,V2;
00196        TopExp::Vertices(edge,V1,V2);
00197        gp_Pnt P1 = BRep_Tool::Pnt(V1);
00198        gp_Pnt P2 = BRep_Tool::Pnt(V2);
00199 
00200        tEdgeVector emptyList;
00201        std::pair<tMapPntShapes::iterator,bool> iter = m_vertices.insert(tMapPntShapesPair(P1,emptyList));
00202        iter.first->second.push_back(edge);
00203        iter = m_vertices.insert(tMapPntShapesPair(P2,emptyList));
00204        iter.first->second.push_back(edge);
00205 }
00206 
00207 #include <BRepAdaptor_Curve.hxx>
00208 
00209 bool WireExplorer::IsValidEdge(const TopoDS_Edge& edge)
00210 {
00211        if ( edge.IsNull() )
00212                return false;
00213        if ( BRep_Tool::Degenerated(edge) )
00214                return false;
00215 
00216        BRepAdaptor_Curve bac(edge);
00217 
00218        Standard_Real fparam = bac.FirstParameter();
00219        Standard_Real lparam = bac.LastParameter();
00220 
00221        gp_Pnt fpoint = bac.Value(fparam);
00222        gp_Pnt lpoint = bac.Value(lparam);
00223 
00224        //do not test the distance first last in case of a full circle edge (fpoint == lastpoint)
00225        //if ( fpoint.IsEqual(lpoint,1e-5 ) )
00226        //      return false;
00227 
00228        gp_Pnt mpoint = bac.Value((fparam+lparam)*0.5);
00229 
00230        Standard_Real dist = mpoint.Distance(lpoint);
00231        if ( dist <= 1e-5 )
00232                return false;
00233        dist = mpoint.Distance(fpoint);
00234        if ( dist <= 1e-5 )
00235                return false;
00236 
00237        return true;
00238 }
00239 

Generated on Wed Nov 23 19:01:02 2011 for FreeCAD by  doxygen 1.6.1