edgesort.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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)
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
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
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
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
00194
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
00226 if ( edgeIt == edges.end() )
00227 {
00228
00229 m_vertices.erase(iter);
00230 return false;
00231 }
00232
00233 TopoDS_Edge theEdge = *edgeIt;
00234
00235
00236 edges.erase(edgeIt);
00237
00238
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
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
00259
00260 theEdge.Reverse();
00261 nextPoint = P1;
00262 }
00263 else
00264 {
00265 nextPoint = P2;
00266 }
00267
00268
00269
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
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
00330
00331
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