1 // Created on: 1993-05-06
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <MAT_Arc.hxx>
19 #include <MAT_BasicElt.hxx>
20 #include <MAT_Bisector.hxx>
21 #include <MAT_DataMapIteratorOfDataMapOfIntegerBasicElt.hxx>
22 #include <MAT_DataMapOfIntegerArc.hxx>
23 #include <MAT_DataMapOfIntegerBasicElt.hxx>
24 #include <MAT_Edge.hxx>
25 #include <MAT_Graph.hxx>
26 #include <MAT_ListOfBisector.hxx>
27 #include <MAT_Node.hxx>
28 #include <MAT_SequenceOfArc.hxx>
29 #include <MAT_Zone.hxx>
30 #include <Precision.hxx>
31 #include <Standard_Type.hxx>
33 IMPLEMENT_STANDARD_RTTIEXT(MAT_Graph,MMgt_TShared)
38 static Handle(MAT_Arc) MakeArc(const Handle(MAT_Bisector)& aBisector,
39 MAT_DataMapOfIntegerBasicElt& TheBasicElts,
40 MAT_DataMapOfIntegerArc& TheArcs,
41 Standard_Integer& IndTabArcs);
43 // =====================================================================
45 // =====================================================================
46 MAT_Graph::MAT_Graph() {}
48 // =====================================================================
50 // purpose : Creation du graphe contenant le resultat.
51 // =====================================================================
52 void MAT_Graph::Perform(const Standard_Boolean SemiInfinite,
53 const Handle(MAT_ListOfBisector)& TheRoots,
54 const Standard_Integer NbBasicElts,
55 const Standard_Integer NbArcs)
57 Standard_Integer NbRoots;
58 Handle(MAT_Arc) FirstArc;
59 Handle(MAT_Arc) CurrentArc;
60 Handle(MAT_Node) Extremite;
61 Standard_Integer IndTabArcs = 1;
62 Standard_Integer IndTabNodes;
64 Standard_Real DistExt;
65 Standard_Integer IndExt;
66 Handle(MAT_Arc) PreviousArc = CurrentArc;
68 //------------------------
69 // Construction du graphe.
70 //------------------------
73 NbRoots = TheRoots->Number();
74 numberOfInfiniteNodes = NbRoots;
78 numberOfInfiniteNodes = 0;
81 numberOfArcs = NbArcs;
82 numberOfBasicElts = NbBasicElts;
83 numberOfNodes = NbRoots + NbArcs;
84 IndTabNodes = numberOfNodes;
86 //---------------------------
87 //... Creation des BasicElts.
88 //---------------------------
89 for (i = 1; i <= NbBasicElts; i++) {
90 theBasicElts.Bind(i,new MAT_BasicElt(i));
91 theBasicElts(i)->SetGeomIndex(i);
94 //--------------------------------------------------------------------
95 // ... Creation des ARCS et des NODES.
96 // Construction des arbres d arcs a partir des <Bisector> racines.
97 //--------------------------------------------------------------------
101 // Plusieurs points d entree a l infini.
102 //--------------------------------------
105 while (TheRoots->More()) {
106 CurrentArc = MakeArc(TheRoots->Current(),
110 Extremite = new MAT_Node (0,CurrentArc,Precision::Infinite());
111 Extremite ->SetIndex (IndTabNodes);
112 CurrentArc->SetSecondNode(Extremite);
113 theNodes.Bind(IndTabNodes,Extremite);
119 // -----------------------------------------------
120 // Un seul point d entree .
121 // Creation d un premier ARC et du NODE racine.
122 // -----------------------------------------------
125 CurrentArc = MakeArc(TheRoots->Current(),
129 DistExt = TheRoots->Current()->FirstEdge()->Distance();
130 IndExt = TheRoots->Current()->EndPoint();
132 Extremite = new MAT_Node(IndExt,CurrentArc,DistExt);
133 Extremite ->SetIndex (IndTabNodes);
134 CurrentArc->SetSecondNode(Extremite);
135 theNodes.Bind(IndTabNodes,Extremite);
138 // -----------------------------------------------------------
139 // ...Creation des ARCs issues de la racine.
140 // Codage des voisinages sur ces arcs et mise a jour de la
141 // sequence des arcs issue du Node racine.
142 // -----------------------------------------------------------
143 FirstArc = CurrentArc;
144 PreviousArc = FirstArc;
147 while (TheRoots->More()) {
148 CurrentArc = MakeArc(TheRoots->Current(),
152 CurrentArc ->SetSecondNode(Extremite);
153 CurrentArc ->SetNeighbour (MAT_Left,Extremite ,PreviousArc);
154 PreviousArc->SetNeighbour (MAT_Right,Extremite,CurrentArc);
156 PreviousArc = CurrentArc;
159 FirstArc ->SetNeighbour (MAT_Left ,Extremite,CurrentArc);
160 CurrentArc->SetNeighbour (MAT_Right,Extremite,FirstArc);
163 // ----------------------------------------------------
164 // Les sequence des Arcs des Nodes racines sont a jour.
165 // Mise a jour des sequences des autres Nodes.
166 // ----------------------------------------------------
167 UpDateNodes(IndTabNodes);
170 //=============================================================================
173 //=============================================================================
174 Handle(MAT_Arc) MAT_Graph::Arc(const Standard_Integer Index) const
176 return theArcs(Index);
179 //=============================================================================
180 //function : BasicElt
182 //=============================================================================
183 Handle(MAT_BasicElt) MAT_Graph::BasicElt(const Standard_Integer Index) const
185 return theBasicElts(Index);
188 //=============================================================================
191 //=============================================================================
192 Handle(MAT_Node) MAT_Graph::Node(const Standard_Integer Index) const
194 return theNodes(Index);
197 //=============================================================================
198 //function : NumberOfArcs
200 //=============================================================================
201 Standard_Integer MAT_Graph::NumberOfArcs() const
206 //=============================================================================
207 //function : NumberOfNodes
209 //=============================================================================
210 Standard_Integer MAT_Graph::NumberOfNodes() const
212 return numberOfNodes;
215 //=============================================================================
216 //function : NumberOfInfiniteNodes
218 //=============================================================================
219 Standard_Integer MAT_Graph::NumberOfInfiniteNodes() const
221 return numberOfInfiniteNodes;
224 //=============================================================================
225 //function : NumberOfBasicElts
227 //=============================================================================
228 Standard_Integer MAT_Graph::NumberOfBasicElts() const
230 return numberOfBasicElts;
233 //=============================================================================
234 //function : FusionOfBasicElts
236 //=============================================================================
237 void MAT_Graph::FusionOfBasicElts(const Standard_Integer IndexElt1,
238 const Standard_Integer IndexElt2,
239 Standard_Boolean& MergeArc1,
240 Standard_Integer& IGeomArc1,
241 Standard_Integer& IGeomArc2,
242 Standard_Boolean& MergeArc2,
243 Standard_Integer& IGeomArc3,
244 Standard_Integer& IGeomArc4)
246 Handle(MAT_BasicElt) Elt1 = theBasicElts(IndexElt1);
247 Handle(MAT_BasicElt) Elt2 = theBasicElts(IndexElt2);
249 if (Elt1 == Elt2) return;
252 Handle(MAT_Zone) Zone2 = new MAT_Zone(Elt2);
254 //--------------------------------------------------------------------
255 // Les arcs de la zone de Elt2 ne separent plus Elt2 et qq chose mais
257 //--------------------------------------------------------------------
258 for (i = 1; i <= Zone2->NumberOfArcs(); i++) {
259 if (Zone2->ArcOnFrontier(i)->FirstElement() == Elt2) {
260 theArcs(Zone2->ArcOnFrontier(i)->Index())->SetFirstElement(Elt1);
263 theArcs(Zone2->ArcOnFrontier(i)->Index())->SetSecondElement(Elt1);
267 //-------------------------------------------------------------------
268 // le EndArc de Elt1 et le StartArc de Elt2 peuvent separes les memes
269 // elements de base => Fusion des deux arcs et mise a jour des noeuds.
270 //-------------------------------------------------------------------
271 Handle(MAT_Arc) EA1 = Elt1->EndArc();
272 Handle(MAT_Arc) SA2 = Elt2->StartArc();
274 Handle(MAT_BasicElt) E1 = EA1->FirstElement();
275 Handle(MAT_BasicElt) E2 = EA1->SecondElement();
276 Handle(MAT_BasicElt) E3 = SA2->FirstElement();
277 Handle(MAT_BasicElt) E4 = SA2->SecondElement();
278 MergeArc1 = Standard_False;
280 if ( (E1 == E3 || E1 == E4) && (E2 == E3 || E2 == E4)) {
281 FusionOfArcs(theArcs(EA1->Index()),theArcs(SA2->Index()));
282 MergeArc1 = Standard_True;
283 IGeomArc1 = EA1->GeomIndex();
284 IGeomArc2 = SA2->GeomIndex();
287 //-------------------------------------------------
288 // La fin de Elt1 devient la fin de Elt2.
289 //-------------------------------------------------
290 Elt1->SetEndArc(Elt2->EndArc());
292 //-------------------------------------------------------------------
293 // le EndArc de Elt1 et le StartArc de Elt1 peuvent separer les memes
295 // si les noeuds des arcs ne sont pas sur le contour
296 // => fusion des arcs.(contour ferme compose d un seul BasicElt)
297 // sinon rien (contour ferme compose de deux BasicElts)
298 //-------------------------------------------------------------------
299 Handle(MAT_Arc) SA1 = Elt1->StartArc();
300 EA1 = Elt1->EndArc();
303 E1 = EA1->FirstElement ();
304 E2 = EA1->SecondElement();
305 E3 = SA1->FirstElement ();
306 E4 = SA1->SecondElement();
308 Standard_Boolean OnFig = (EA1->FirstNode() ->OnBasicElt() ||
309 EA1->SecondNode()->OnBasicElt() ||
310 SA1->FirstNode() ->OnBasicElt() ||
311 SA1->SecondNode()->OnBasicElt() );
313 MergeArc2 = Standard_False;
315 if ((E1 == E3 || E1 == E4) && (E2 == E3 || E2 == E4) && !OnFig) {
316 FusionOfArcs(theArcs(EA1->Index()),theArcs(SA1->Index()));
317 MergeArc2 = Standard_True;
318 IGeomArc3 = EA1->GeomIndex();
319 IGeomArc4 = SA1->GeomIndex();
323 //----------------------------------------------------
324 // un element de base a ete elimine.
325 //----------------------------------------------------
326 theBasicElts.UnBind(Elt2->Index());
330 //=============================================================================
331 // function : FusionOfArcs
332 // purpose : Fusion de deux arcs separant les memes elements.
333 // l <Arc1> ira du Second noeud de <Arc2> au second Noeud de <Arc1>.
334 //=============================================================================
335 void MAT_Graph::FusionOfArcs(const Handle(MAT_Arc)& Arc1,
336 const Handle(MAT_Arc)& Arc2)
339 Handle(MAT_Node) OldNode1 = Arc1->FirstNode();
340 Handle(MAT_Node) OldNode2 = Arc2->FirstNode();
342 Arc1->SetFirstNode(Arc2->SecondNode());
344 //--------------------------------------------------------------------
345 // Mise a jour des voisinages autour du nouveau premier noeud de Arc1.
346 //--------------------------------------------------------------------
347 if (!Arc2->SecondNode()->Infinite()) {
348 Handle(MAT_Arc) LNeighbour = Arc2->Neighbour(Arc2->SecondNode(),MAT_Left);
349 Handle(MAT_Arc) RNeighbour = Arc2->Neighbour(Arc2->SecondNode(),MAT_Right);
351 Arc1->SetFirstArc(MAT_Left,LNeighbour);
352 Arc1->SetFirstArc(MAT_Right,RNeighbour);
353 theArcs(LNeighbour->Index())->SetNeighbour(MAT_Right,
356 theArcs(RNeighbour->Index())->SetNeighbour(MAT_Left,
361 Handle(MAT_Arc) EmptyArc;
362 Arc1->SetFirstArc(MAT_Left ,EmptyArc);
363 Arc1->SetFirstArc(MAT_Right,EmptyArc);
366 //-------------------------------------------------------------------
367 // Mise a jour du premier noeud Arc1.
368 //-----------------------------------------------------------------
369 Arc1->FirstNode()->SetLinkedArc(Arc1);
371 //------------------------------------
372 // Elimination de Arc2 et des OldNode
373 //------------------------------------
374 if (theNodes.IsBound(OldNode1->Index())) {
375 theNodes.UnBind(OldNode1->Index());
378 if (theNodes.IsBound(OldNode2->Index())) {
379 theNodes.UnBind(OldNode2->Index());
383 // Note: the Arc2 is actually a reference to a handle contained in theArcs map;
384 // it is necessary to create copy of that handle and use only it to access
385 // that object, since the handle contained in the map is destroyed by UnBind()
386 Handle(MAT_Arc) anArc2 = Arc2;
387 theArcs .UnBind(Arc2->Index());
390 for (Standard_Integer i = 1; i <= 2; i++){
391 Handle(MAT_BasicElt) BE;
393 BE = theBasicElts(anArc2->FirstElement ()->Index());
395 BE = theBasicElts(anArc2->SecondElement ()->Index());
397 if (BE->StartArc() == anArc2) { BE->SetStartArc(Arc1);}
398 if (BE->EndArc () == anArc2) { BE->SetEndArc (Arc1);}
402 //=============================================================================
403 // function : CompactArcs
404 // purpose : Decalage des Arcs pour boucher les trous.
405 //=============================================================================
406 void MAT_Graph::CompactArcs()
408 Standard_Integer IFind = 0;
409 Standard_Integer i = 1;
410 Standard_Boolean YaDecalage = Standard_False;
412 while (IFind < numberOfArcs) {
413 if (!theArcs.IsBound(i)) {
414 YaDecalage = Standard_True;
419 theArcs(i)->SetIndex(IFind);
420 theArcs.Bind(IFind,theArcs(i));
428 //=============================================================================
429 // function : CompactNodes
430 // purpose : Decalage des Nodes pour boucher les trous.
431 //=============================================================================
432 void MAT_Graph::CompactNodes()
434 Standard_Integer IFind = 0;
435 Standard_Integer i = 1;
436 Standard_Boolean YaDecalage = Standard_False;
438 while (IFind < numberOfNodes) {
439 if (!theNodes.IsBound(i)) {
440 YaDecalage = Standard_True;
445 theNodes(i)->SetIndex(IFind);
446 theNodes.Bind(IFind,theNodes(i));
454 //=============================================================================
455 // function : ChangeBasicElts
457 //=============================================================================
458 void MAT_Graph::ChangeBasicElts(const MAT_DataMapOfIntegerBasicElt& NewMap)
460 theBasicElts = NewMap;
461 MAT_DataMapIteratorOfDataMapOfIntegerBasicElt Ite;
462 for (Ite.Initialize(theBasicElts); Ite.More(); Ite.Next()) {
463 Ite.Value()->SetIndex(Ite.Key());
467 //=============================================================================
468 //function : ChangeBasicElt
470 //=============================================================================
471 Handle(MAT_BasicElt) MAT_Graph::ChangeBasicElt(const Standard_Integer Index)
473 return theBasicElts(Index);
476 //=============================================================================
477 // function : UpDateNodes
478 // purpose : Mise a jour des sequence d'ARC de chaque FirstNode de chaque arc.
479 // et stockage de chaque noeud dans la table des noeuds.
480 // Les noeuds racines sont traites dans PERFORM.
481 //=============================================================================
482 void MAT_Graph::UpDateNodes (Standard_Integer& IndTabNodes)
485 Handle(MAT_Node) Bout;
486 Handle(MAT_Arc) CurrentArc;
488 for (i = 1; i <= numberOfArcs; i++) {
489 Bout = theArcs(i)->FirstNode();
490 theNodes.Bind(IndTabNodes,Bout);
491 Bout->SetIndex(IndTabNodes);
493 Bout->SetLinkedArc(theArcs(i));
498 //=============================================================================
499 // function : MakeArc
500 // purpose : Creation des <ARCS> en parcourant l'arbre issue de <aBisector>.
501 //=============================================================================
502 static Handle(MAT_Arc) MakeArc(const Handle(MAT_Bisector)& aBisector,
503 MAT_DataMapOfIntegerBasicElt& TheBasicElts,
504 MAT_DataMapOfIntegerArc& TheArcs,
505 Standard_Integer& IndTabArcs)
507 Handle(MAT_Arc) CurrentArc;
508 Handle(MAT_Arc) PrevArc;
509 Handle(MAT_Arc) NextArc;
510 Handle(MAT_Node) Extremite;
511 Handle(MAT_ListOfBisector) BisectorList;
512 Standard_Real DistExt;
514 #ifdef OCCT_DEBUG_Graph
515 cout<<"Construction Arc : Index"<<aBisector->IndexNumber()<<endl;
516 cout<<"Construction Arc : Bisector"<<aBisector->BisectorNumber()<<endl;
519 CurrentArc = new MAT_Arc(IndTabArcs,
520 aBisector->BisectorNumber(),
521 TheBasicElts(aBisector->FirstEdge()->EdgeNumber()),
522 TheBasicElts(aBisector->SecondEdge()->EdgeNumber())
524 DistExt = aBisector->DistIssuePoint();
525 if (DistExt == Precision::Infinite()) {
527 #ifdef OCCT_DEBUG_Graph
528 cout<<"PB:RECUPERATION DISTANCE SUR ISSUEPOINT."<<endl;
532 Extremite = new MAT_Node(aBisector->IssuePoint(),CurrentArc,DistExt);
534 CurrentArc->SetFirstNode(Extremite);
535 BisectorList = aBisector->List();
536 BisectorList->First();
538 if (!BisectorList->More()) {
539 // -------------------
540 // Arc sur le contour.
541 // -------------------
542 TheBasicElts(aBisector->SecondEdge()->EdgeNumber())
543 ->SetStartArc(CurrentArc);
544 TheBasicElts(aBisector->FirstEdge()->EdgeNumber())
545 ->SetEndArc(CurrentArc);
548 PrevArc = CurrentArc;
550 while (BisectorList->More()) {
551 NextArc = MakeArc(BisectorList->Current(),
555 NextArc->SetSecondNode(Extremite);
556 NextArc->SetNeighbour (MAT_Left ,Extremite,PrevArc);
557 PrevArc->SetNeighbour (MAT_Right,Extremite,NextArc);
559 BisectorList->Next();
561 CurrentArc->SetNeighbour(MAT_Left ,Extremite,NextArc);
562 NextArc ->SetNeighbour(MAT_Right,Extremite,CurrentArc);
565 #ifdef OCCT_DEBUG_Graph
566 cout<<"IndTabArcs = "<<IndTabArcs<<endl;
567 cout<<"ArcIndex = "<<CurrentArc->ArcIndex()<<endl;
569 CurrentArc->SetIndex(IndTabArcs);
570 TheArcs.Bind(IndTabArcs,CurrentArc);
571 IndTabArcs = IndTabArcs + 1;