/src/contrib/geom-5.1.2.7/src/Partition/Partition_Loop.cpp

http://pythonocc.googlecode.com/ · C++ · 464 lines · 305 code · 54 blank · 105 comment · 88 complexity · d524d137b24917b78d57e2d93c950139 MD5 · raw file

  1. // GEOM PARTITION : partition algorithm
  2. //
  3. // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
  4. // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
  5. //
  6. // This library is free software; you can redistribute it and/or
  7. // modify it under the terms of the GNU Lesser General Public
  8. // License as published by the Free Software Foundation; either
  9. // version 2.1 of the License.
  10. //
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. // Lesser General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU Lesser General Public
  17. // License along with this library; if not, write to the Free Software
  18. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. //
  20. // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
  21. //
  22. //
  23. //
  24. // File : Partition_Loop.cxx
  25. // Author : Benedicte MARTIN
  26. // Module : GEOM
  27. // $Header: /home/server/cvs/GEOM/GEOM_SRC/src/PARTITION/Partition_Loop.cxx,v 1.6 2006/06/01 11:32:39 jfa Exp $
  28. #include "utilities.h"
  29. #include "Partition_Loop.ixx"
  30. #include <BRep_Builder.hxx>
  31. #include <BRepAlgo_FaceRestrictor.hxx>
  32. #include <BRep_Tool.hxx>
  33. #include <Geom2d_Curve.hxx>
  34. #include <Geom_Surface.hxx>
  35. #include <TopTools_SequenceOfShape.hxx>
  36. #include <TopTools_ListIteratorOfListOfShape.hxx>
  37. #include <TopTools_MapOfShape.hxx>
  38. #include <TopTools_MapIteratorOfMapOfShape.hxx>
  39. #include <TopTools_MapOfOrientedShape.hxx>
  40. #include <TopTools_DataMapOfShapeShape.hxx>
  41. #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
  42. #include <gp_Pnt.hxx>
  43. #include <gp_Pnt2d.hxx>
  44. #include <TopoDS.hxx>
  45. #include <TopoDS_Vertex.hxx>
  46. #include <TopoDS_Wire.hxx>
  47. #include <TopoDS_Iterator.hxx>
  48. #include <Precision.hxx>
  49. #include <BRep_TVertex.hxx>
  50. #include <BRep_TEdge.hxx>
  51. #include <TopExp.hxx>
  52. #include <TopExp_Explorer.hxx>
  53. static char* name = new char[100];
  54. static int nbe = 0;
  55. //=======================================================================
  56. //function : Partition_Loop
  57. //purpose :
  58. //=======================================================================
  59. Partition_Loop::Partition_Loop()
  60. {
  61. }
  62. //=======================================================================
  63. //function : Init
  64. //purpose :
  65. //=======================================================================
  66. void Partition_Loop::Init(const TopoDS_Face& F)
  67. {
  68. myConstEdges.Clear();
  69. myNewWires .Clear();
  70. myNewFaces .Clear();
  71. myFace = F;
  72. }
  73. //=======================================================================
  74. //function : AddConstEdge
  75. //purpose :
  76. //=======================================================================
  77. void Partition_Loop::AddConstEdge (const TopoDS_Edge& E)
  78. {
  79. myConstEdges.Append(E);
  80. }
  81. //=======================================================================
  82. //function : FindDelta
  83. //purpose :
  84. //=======================================================================
  85. static Standard_Real FindDelta(TopTools_ListOfShape& LE,
  86. const TopoDS_Face& F)
  87. {
  88. Standard_Real dist, f, l;
  89. Standard_Real d = Precision::Infinite();
  90. TopTools_ListIteratorOfListOfShape itl;
  91. for ( itl.Initialize(LE); itl.More(); itl.Next()) {
  92. const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
  93. Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l);
  94. gp_Pnt2d p = C->Value(f);
  95. gp_Pnt2d pp = C->Value(l);
  96. Standard_Real d1 = p.Distance(pp);
  97. if (d1<d) { d=d1;}
  98. }
  99. dist = d ;
  100. return dist;
  101. }
  102. //=======================================================================
  103. //function : SelectEdge
  104. //purpose : Find the edge <NE> connected <CE> by the vertex <CV> in the list <LE>.
  105. // <NE> Is erased of the list. If <CE> is too in the list <LE>
  106. // with the same orientation, it's erased of the list
  107. //=======================================================================
  108. static Standard_Boolean SelectEdge(const TopoDS_Face& F,
  109. const TopoDS_Edge& CE,
  110. const TopoDS_Vertex& CV,
  111. TopoDS_Edge& NE,
  112. TopTools_ListOfShape& LE)
  113. {
  114. TopTools_ListIteratorOfListOfShape itl;
  115. NE.Nullify();
  116. for ( itl.Initialize(LE); itl.More(); itl.Next()) {
  117. if (itl.Value().IsEqual(CE)) {
  118. LE.Remove(itl);
  119. break;
  120. }
  121. }
  122. if (LE.Extent() > 1) {
  123. //--------------------------------------------------------------
  124. // Several possible edges.
  125. // - Test the edges differents of CE
  126. //--------------------------------------------------------------
  127. Standard_Real cf, cl, f, l;
  128. TopoDS_Face FForward = F;
  129. Handle(Geom2d_Curve) Cc, C;
  130. FForward.Orientation(TopAbs_FORWARD);
  131. Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl);
  132. Standard_Real dist,distmin = 100*BRep_Tool::Tolerance(CV);
  133. Standard_Real uc,u;
  134. if (CE.Orientation () == TopAbs_FORWARD) uc = cl;
  135. else uc = cf;
  136. gp_Pnt2d P2,PV = Cc->Value(uc);
  137. Standard_Real delta = FindDelta(LE,FForward);
  138. for ( itl.Initialize(LE); itl.More(); itl.Next()) {
  139. const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
  140. if (!E.IsSame(CE)) {
  141. C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
  142. if (E.Orientation () == TopAbs_FORWARD) u = f;
  143. else u = l;
  144. P2 = C->Value(u);
  145. dist = PV.Distance(P2);
  146. if (dist <= distmin){
  147. distmin = dist;
  148. }
  149. }
  150. }
  151. Standard_Real anglemax = - PI;
  152. TopoDS_Edge SelectedEdge;
  153. for ( itl.Initialize(LE); itl.More(); itl.Next()) {
  154. const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
  155. if (!E.IsSame(CE)) {
  156. C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
  157. if (E.Orientation () == TopAbs_FORWARD) u = f;
  158. else u = l;
  159. P2 = C->Value(u);
  160. dist = PV.Distance(P2);
  161. if (dist <= distmin + (1./3)*delta){
  162. gp_Pnt2d PC, P;
  163. gp_Vec2d CTg1, CTg2, Tg1, Tg2;
  164. Cc->D2(uc, PC, CTg1, CTg2);
  165. C->D2(u, P, Tg1, Tg2);
  166. Standard_Real angle;
  167. if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) {
  168. angle = CTg1.Angle(Tg1.Reversed());
  169. }
  170. else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) {
  171. angle = (CTg1.Reversed()).Angle(Tg1);
  172. }
  173. else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) {
  174. angle = CTg1.Angle(Tg1);
  175. }
  176. else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) {
  177. angle = (CTg1.Reversed()).Angle(Tg1.Reversed());
  178. }
  179. if (angle >= anglemax) {
  180. anglemax = angle ;
  181. SelectedEdge = E;
  182. }
  183. }
  184. }
  185. }
  186. for ( itl.Initialize(LE); itl.More(); itl.Next()) {
  187. const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
  188. if (E.IsEqual(SelectedEdge)) {
  189. NE = TopoDS::Edge(E);
  190. LE.Remove(itl);
  191. break;
  192. }
  193. }
  194. }
  195. else if (LE.Extent() == 1) {
  196. NE = TopoDS::Edge(LE.First());
  197. LE.RemoveFirst();
  198. }
  199. else {
  200. return Standard_False;
  201. }
  202. return Standard_True;
  203. }
  204. //=======================================================================
  205. //function : SamePnt2d
  206. //purpose :
  207. //=======================================================================
  208. static Standard_Boolean SamePnt2d(TopoDS_Vertex V,
  209. TopoDS_Edge& E1,
  210. TopoDS_Edge& E2,
  211. TopoDS_Face& F)
  212. {
  213. Standard_Real f1,f2,l1,l2;
  214. gp_Pnt2d P1,P2;
  215. TopoDS_Shape aLocalF = F.Oriented(TopAbs_FORWARD);
  216. TopoDS_Face FF = TopoDS::Face(aLocalF);
  217. Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,FF,f1,l1);
  218. Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,FF,f2,l2);
  219. if (E1.Orientation () == TopAbs_FORWARD) P1 = C1->Value(f1);
  220. else P1 = C1->Value(l1);
  221. if (E2.Orientation () == TopAbs_FORWARD) P2 = C2->Value(l2);
  222. else P2 = C2->Value(f2);
  223. Standard_Real Tol = 100*BRep_Tool::Tolerance(V);
  224. Standard_Real Dist = P1.Distance(P2);
  225. return Dist < Tol;
  226. }
  227. //=======================================================================
  228. //function : PurgeNewEdges
  229. //purpose :
  230. //=======================================================================
  231. static void PurgeNewEdges(TopTools_ListOfShape& ConstEdges,
  232. const TopTools_MapOfOrientedShape& UsedEdges)
  233. {
  234. TopTools_ListIteratorOfListOfShape it(ConstEdges);
  235. while ( it.More()) {
  236. const TopoDS_Shape& NE = it.Value();
  237. if (!UsedEdges.Contains(NE)) {
  238. ConstEdges.Remove(it);
  239. }
  240. else {
  241. it.Next();
  242. }
  243. }
  244. }
  245. //=======================================================================
  246. //function : StoreInMVE
  247. //purpose :
  248. //=======================================================================
  249. static void StoreInMVE (const TopoDS_Face& F,
  250. TopoDS_Edge& E,
  251. TopTools_DataMapOfShapeListOfShape& MVE )
  252. {
  253. TopoDS_Vertex V1, V2;
  254. TopTools_ListOfShape Empty;
  255. TopExp::Vertices(E,V1,V2);
  256. if (!MVE.IsBound(V1)) {
  257. MVE.Bind(V1,Empty);
  258. }
  259. MVE(V1).Append(E);
  260. if (!MVE.IsBound(V2)) {
  261. MVE.Bind(V2,Empty);
  262. }
  263. MVE(V2).Append(E);
  264. }
  265. //=======================================================================
  266. //function : Perform
  267. //purpose :
  268. //=======================================================================
  269. void Partition_Loop::Perform()
  270. {
  271. TopTools_DataMapOfShapeListOfShape MVE;
  272. TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit, Mapit1;
  273. TopTools_ListIteratorOfListOfShape itl;
  274. TopoDS_Vertex V1,V2;
  275. //-----------------------------------
  276. // Construction map vertex => edges
  277. //-----------------------------------
  278. for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
  279. TopoDS_Edge& E = TopoDS::Edge(itl.Value());
  280. StoreInMVE(myFace,E,MVE);
  281. }
  282. //----------------------------------------------
  283. // Construction of all the wires and of all the new faces.
  284. //----------------------------------------------
  285. TopTools_MapOfOrientedShape UsedEdges;
  286. while (!MVE.IsEmpty()) {
  287. TopoDS_Vertex VF,CV;
  288. TopoDS_Edge CE,NE,EF;
  289. TopoDS_Wire NW;
  290. BRep_Builder B;
  291. Standard_Boolean End= Standard_False;
  292. B.MakeWire(NW);
  293. //--------------------------------
  294. // EF first edge.
  295. //--------------------------------
  296. Mapit.Initialize(MVE);
  297. EF = CE = TopoDS::Edge(Mapit.Value().First());
  298. TopExp::Vertices(CE,V1,V2);
  299. //--------------------------------
  300. // VF first vertex
  301. //--------------------------------
  302. if (CE.Orientation() == TopAbs_FORWARD) {
  303. CV = VF = V1;
  304. }
  305. else {
  306. CV = VF = V2;
  307. }
  308. if (!MVE.IsBound(CV)) continue;
  309. for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
  310. if (itl.Value().IsEqual(CE)) {
  311. MVE(CV).Remove(itl);
  312. break;
  313. }
  314. }
  315. int i = 0;
  316. while (!End) {
  317. //-------------------------------
  318. // Construction of a wire.
  319. //-------------------------------
  320. TopExp::Vertices(CE,V1,V2);
  321. if (!CV.IsSame(V1)) CV = V1; else CV = V2;
  322. B.Add (NW,CE);
  323. UsedEdges.Add(CE);
  324. //--------------
  325. // stop test
  326. //--------------
  327. if (!MVE.IsBound(CV) || MVE(CV).IsEmpty() || CV.IsSame(VF) ) {
  328. if (CV.IsSame(VF)) {
  329. if (MVE(CV).Extent() == 1 ) MVE.UnBind(CV);
  330. else {
  331. for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
  332. if (itl.Value().IsEqual(CE)) {
  333. MVE(CV).Remove(itl);
  334. break;
  335. }
  336. }
  337. }
  338. }
  339. End=Standard_True;
  340. }
  341. //--------------
  342. // select edge
  343. //--------------
  344. else {
  345. Standard_Boolean find = SelectEdge(myFace,CE,CV,NE,MVE(CV));
  346. if (find) {
  347. CE=NE;
  348. if (MVE(CV).IsEmpty()) MVE.UnBind(CV);
  349. if (CE.IsNull() ) {
  350. MESSAGE ( " CE is NULL !!! " )
  351. End=Standard_True;
  352. }
  353. }
  354. else {
  355. MESSAGE ( " edge doesn't exist " )
  356. End=Standard_True;
  357. }
  358. }
  359. }
  360. //-----------------------------
  361. // Test if the wire is closed
  362. //-----------------------------
  363. if (VF.IsSame(CV) && SamePnt2d(VF,EF,CE,myFace)) {
  364. }
  365. else{
  366. MESSAGE ( "wire not closed" )
  367. }
  368. myNewWires.Append (NW);
  369. }
  370. PurgeNewEdges(myConstEdges,UsedEdges);
  371. }
  372. //=======================================================================
  373. //function : NewWires
  374. //purpose :
  375. //=======================================================================
  376. const TopTools_ListOfShape& Partition_Loop::NewWires() const
  377. {
  378. return myNewWires;
  379. }
  380. //=======================================================================
  381. //function : NewFaces
  382. //purpose :
  383. //=======================================================================
  384. const TopTools_ListOfShape& Partition_Loop::NewFaces() const
  385. {
  386. return myNewFaces;
  387. }
  388. //=======================================================================
  389. //function : WiresToFaces
  390. //purpose :
  391. //=======================================================================
  392. void Partition_Loop::WiresToFaces()
  393. {
  394. if (!myNewWires.IsEmpty()) {
  395. BRepAlgo_FaceRestrictor FR;
  396. TopAbs_Orientation OriF = myFace.Orientation();
  397. TopoDS_Shape aLocalS = myFace.Oriented(TopAbs_FORWARD);
  398. FR.Init (TopoDS::Face(aLocalS),Standard_False);
  399. TopTools_ListIteratorOfListOfShape it(myNewWires);
  400. for (; it.More(); it.Next()) {
  401. FR.Add(TopoDS::Wire(it.Value()));
  402. }
  403. FR.Perform();
  404. if (FR.IsDone()) {
  405. for (; FR.More(); FR.Next()) {
  406. myNewFaces.Append(FR.Current().Oriented(OriF));
  407. }
  408. }
  409. }
  410. }