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_Bisector.hxx>
20 #include <MAT_DataMapIteratorOfDataMapOfIntegerBasicElt.hxx>
21 #include <MAT_DataMapOfIntegerBasicElt.hxx>
22 #include <MAT_Edge.hxx>
23 #include <MAT_Graph.hxx>
24 #include <MAT_ListOfBisector.hxx>
25 #include <MAT_Node.hxx>
26 #include <MAT_Zone.hxx>
27 #include <Precision.hxx>
28 #include <Standard_Type.hxx>
30 IMPLEMENT_STANDARD_RTTIEXT(MAT_Graph,Standard_Transient)
35 static Handle(MAT_Arc) MakeArc(const Handle(MAT_Bisector)& aBisector,
36 MAT_DataMapOfIntegerBasicElt& TheBasicElts,
37 MAT_DataMapOfIntegerArc& TheArcs,
38 Standard_Integer& IndTabArcs);
40 // =====================================================================
42 // =====================================================================
43 MAT_Graph::MAT_Graph()
47 numberOfInfiniteNodes(0)
51 // =====================================================================
53 // purpose : Creation du graphe contenant le resultat.
54 // =====================================================================
55 void MAT_Graph::Perform(const Standard_Boolean SemiInfinite,
56 const Handle(MAT_ListOfBisector)& TheRoots,
57 const Standard_Integer NbBasicElts,
58 const Standard_Integer NbArcs)
60 Standard_Integer NbRoots;
61 Handle(MAT_Arc) FirstArc;
62 Handle(MAT_Arc) CurrentArc;
63 Handle(MAT_Node) Extremite;
64 Standard_Integer IndTabArcs = 1;
65 Standard_Integer IndTabNodes;
67 Standard_Real DistExt;
68 Standard_Integer IndExt;
69 Handle(MAT_Arc) PreviousArc = CurrentArc;
71 //------------------------
72 // Construction du graphe.
73 //------------------------
76 NbRoots = TheRoots->Number();
77 numberOfInfiniteNodes = NbRoots;
81 numberOfInfiniteNodes = 0;
84 numberOfArcs = NbArcs;
85 numberOfBasicElts = NbBasicElts;
86 numberOfNodes = NbRoots + NbArcs;
87 IndTabNodes = numberOfNodes;
89 //---------------------------
90 //... Creation des BasicElts.
91 //---------------------------
92 for (i = 1; i <= NbBasicElts; i++) {
93 theBasicElts.Bind(i,new MAT_BasicElt(i));
94 theBasicElts(i)->SetGeomIndex(i);
97 //--------------------------------------------------------------------
98 // ... Creation des ARCS et des NODES.
99 // Construction des arbres d arcs a partir des <Bisector> racines.
100 //--------------------------------------------------------------------
104 // Plusieurs points d entree a l infini.
105 //--------------------------------------
108 while (TheRoots->More()) {
109 CurrentArc = MakeArc(TheRoots->Current(),
113 Extremite = new MAT_Node (0,CurrentArc,Precision::Infinite());
114 Extremite ->SetIndex (IndTabNodes);
115 CurrentArc->SetSecondNode(Extremite);
116 theNodes.Bind(IndTabNodes,Extremite);
122 // -----------------------------------------------
123 // Un seul point d entree .
124 // Creation d un premier ARC et du NODE racine.
125 // -----------------------------------------------
128 CurrentArc = MakeArc(TheRoots->Current(),
132 DistExt = TheRoots->Current()->FirstEdge()->Distance();
133 IndExt = TheRoots->Current()->EndPoint();
135 Extremite = new MAT_Node(IndExt,CurrentArc,DistExt);
136 Extremite ->SetIndex (IndTabNodes);
137 CurrentArc->SetSecondNode(Extremite);
138 theNodes.Bind(IndTabNodes,Extremite);
141 // -----------------------------------------------------------
142 // ...Creation des ARCs issues de la racine.
143 // Codage des voisinages sur ces arcs et mise a jour de la
144 // sequence des arcs issue du Node racine.
145 // -----------------------------------------------------------
146 FirstArc = CurrentArc;
147 PreviousArc = FirstArc;
150 while (TheRoots->More()) {
151 CurrentArc = MakeArc(TheRoots->Current(),
155 CurrentArc ->SetSecondNode(Extremite);
156 CurrentArc ->SetNeighbour (MAT_Left,Extremite ,PreviousArc);
157 PreviousArc->SetNeighbour (MAT_Right,Extremite,CurrentArc);
159 PreviousArc = CurrentArc;
162 FirstArc ->SetNeighbour (MAT_Left ,Extremite,CurrentArc);
163 CurrentArc->SetNeighbour (MAT_Right,Extremite,FirstArc);
166 // ----------------------------------------------------
167 // Les sequence des Arcs des Nodes racines sont a jour.
168 // Mise a jour des sequences des autres Nodes.
169 // ----------------------------------------------------
170 UpDateNodes(IndTabNodes);
173 //=============================================================================
176 //=============================================================================
177 Handle(MAT_Arc) MAT_Graph::Arc(const Standard_Integer Index) const
179 return theArcs(Index);
182 //=============================================================================
183 //function : BasicElt
185 //=============================================================================
186 Handle(MAT_BasicElt) MAT_Graph::BasicElt(const Standard_Integer Index) const
188 return theBasicElts(Index);
191 //=============================================================================
194 //=============================================================================
195 Handle(MAT_Node) MAT_Graph::Node(const Standard_Integer Index) const
197 return theNodes(Index);
200 //=============================================================================
201 //function : NumberOfArcs
203 //=============================================================================
204 Standard_Integer MAT_Graph::NumberOfArcs() const
209 //=============================================================================
210 //function : NumberOfNodes
212 //=============================================================================
213 Standard_Integer MAT_Graph::NumberOfNodes() const
215 return numberOfNodes;
218 //=============================================================================
219 //function : NumberOfInfiniteNodes
221 //=============================================================================
222 Standard_Integer MAT_Graph::NumberOfInfiniteNodes() const
224 return numberOfInfiniteNodes;
227 //=============================================================================
228 //function : NumberOfBasicElts
230 //=============================================================================
231 Standard_Integer MAT_Graph::NumberOfBasicElts() const
233 return numberOfBasicElts;
236 //=============================================================================
237 //function : FusionOfBasicElts
239 //=============================================================================
240 void MAT_Graph::FusionOfBasicElts(const Standard_Integer IndexElt1,
241 const Standard_Integer IndexElt2,
242 Standard_Boolean& MergeArc1,
243 Standard_Integer& IGeomArc1,
244 Standard_Integer& IGeomArc2,
245 Standard_Boolean& MergeArc2,
246 Standard_Integer& IGeomArc3,
247 Standard_Integer& IGeomArc4)
249 Handle(MAT_BasicElt) Elt1 = theBasicElts(IndexElt1);
250 Handle(MAT_BasicElt) Elt2 = theBasicElts(IndexElt2);
252 if (Elt1 == Elt2) return;
255 Handle(MAT_Zone) Zone2 = new MAT_Zone(Elt2);
257 //--------------------------------------------------------------------
258 // Les arcs de la zone de Elt2 ne separent plus Elt2 et qq chose mais
260 //--------------------------------------------------------------------
261 for (i = 1; i <= Zone2->NumberOfArcs(); i++) {
262 if (Zone2->ArcOnFrontier(i)->FirstElement() == Elt2) {
263 theArcs(Zone2->ArcOnFrontier(i)->Index())->SetFirstElement(Elt1);
266 theArcs(Zone2->ArcOnFrontier(i)->Index())->SetSecondElement(Elt1);
270 //-------------------------------------------------------------------
271 // le EndArc de Elt1 et le StartArc de Elt2 peuvent separes les memes
272 // elements de base => Fusion des deux arcs et mise a jour des noeuds.
273 //-------------------------------------------------------------------
274 Handle(MAT_Arc) EA1 = Elt1->EndArc();
275 Handle(MAT_Arc) SA2 = Elt2->StartArc();
277 Handle(MAT_BasicElt) E1 = EA1->FirstElement();
278 Handle(MAT_BasicElt) E2 = EA1->SecondElement();
279 Handle(MAT_BasicElt) E3 = SA2->FirstElement();
280 Handle(MAT_BasicElt) E4 = SA2->SecondElement();
281 MergeArc1 = Standard_False;
283 if ( (E1 == E3 || E1 == E4) && (E2 == E3 || E2 == E4)) {
284 FusionOfArcs(theArcs(EA1->Index()),theArcs(SA2->Index()));
285 MergeArc1 = Standard_True;
286 IGeomArc1 = EA1->GeomIndex();
287 IGeomArc2 = SA2->GeomIndex();
290 //-------------------------------------------------
291 // La fin de Elt1 devient la fin de Elt2.
292 //-------------------------------------------------
293 Elt1->SetEndArc(Elt2->EndArc());
295 //-------------------------------------------------------------------
296 // le EndArc de Elt1 et le StartArc de Elt1 peuvent separer les memes
298 // si les noeuds des arcs ne sont pas sur le contour
299 // => fusion des arcs.(contour ferme compose d un seul BasicElt)
300 // sinon rien (contour ferme compose de deux BasicElts)
301 //-------------------------------------------------------------------
302 Handle(MAT_Arc) SA1 = Elt1->StartArc();
303 EA1 = Elt1->EndArc();
306 E1 = EA1->FirstElement ();
307 E2 = EA1->SecondElement();
308 E3 = SA1->FirstElement ();
309 E4 = SA1->SecondElement();
311 Standard_Boolean OnFig = (EA1->FirstNode() ->OnBasicElt() ||
312 EA1->SecondNode()->OnBasicElt() ||
313 SA1->FirstNode() ->OnBasicElt() ||
314 SA1->SecondNode()->OnBasicElt() );
316 MergeArc2 = Standard_False;
318 if ((E1 == E3 || E1 == E4) && (E2 == E3 || E2 == E4) && !OnFig) {
319 FusionOfArcs(theArcs(EA1->Index()),theArcs(SA1->Index()));
320 MergeArc2 = Standard_True;
321 IGeomArc3 = EA1->GeomIndex();
322 IGeomArc4 = SA1->GeomIndex();
326 //----------------------------------------------------
327 // un element de base a ete elimine.
328 //----------------------------------------------------
329 theBasicElts.UnBind(Elt2->Index());
333 //=============================================================================
334 // function : FusionOfArcs
335 // purpose : Fusion de deux arcs separant les memes elements.
336 // l <Arc1> ira du Second noeud de <Arc2> au second Noeud de <Arc1>.
337 //=============================================================================
338 void MAT_Graph::FusionOfArcs(const Handle(MAT_Arc)& Arc1,
339 const Handle(MAT_Arc)& Arc2)
342 Handle(MAT_Node) OldNode1 = Arc1->FirstNode();
343 Handle(MAT_Node) OldNode2 = Arc2->FirstNode();
345 Arc1->SetFirstNode(Arc2->SecondNode());
347 //--------------------------------------------------------------------
348 // Mise a jour des voisinages autour du nouveau premier noeud de Arc1.
349 //--------------------------------------------------------------------
350 if (!Arc2->SecondNode()->Infinite()) {
351 Handle(MAT_Arc) LNeighbour = Arc2->Neighbour(Arc2->SecondNode(),MAT_Left);
352 Handle(MAT_Arc) RNeighbour = Arc2->Neighbour(Arc2->SecondNode(),MAT_Right);
354 Arc1->SetFirstArc(MAT_Left,LNeighbour);
355 Arc1->SetFirstArc(MAT_Right,RNeighbour);
356 theArcs(LNeighbour->Index())->SetNeighbour(MAT_Right,
359 theArcs(RNeighbour->Index())->SetNeighbour(MAT_Left,
364 Handle(MAT_Arc) EmptyArc;
365 Arc1->SetFirstArc(MAT_Left ,EmptyArc);
366 Arc1->SetFirstArc(MAT_Right,EmptyArc);
369 //-------------------------------------------------------------------
370 // Mise a jour du premier noeud Arc1.
371 //-----------------------------------------------------------------
372 Arc1->FirstNode()->SetLinkedArc(Arc1);
374 //------------------------------------
375 // Elimination de Arc2 et des OldNode
376 //------------------------------------
377 if (theNodes.IsBound(OldNode1->Index())) {
378 theNodes.UnBind(OldNode1->Index());
381 if (theNodes.IsBound(OldNode2->Index())) {
382 theNodes.UnBind(OldNode2->Index());
386 // Note: the Arc2 is actually a reference to a handle contained in theArcs map;
387 // it is necessary to create copy of that handle and use only it to access
388 // that object, since the handle contained in the map is destroyed by UnBind()
389 Handle(MAT_Arc) anArc2 = Arc2;
390 theArcs .UnBind(Arc2->Index());
393 for (Standard_Integer i = 1; i <= 2; i++){
394 Handle(MAT_BasicElt) BE;
396 BE = theBasicElts(anArc2->FirstElement ()->Index());
398 BE = theBasicElts(anArc2->SecondElement ()->Index());
400 if (BE->StartArc() == anArc2) { BE->SetStartArc(Arc1);}
401 if (BE->EndArc () == anArc2) { BE->SetEndArc (Arc1);}
405 //=============================================================================
406 // function : CompactArcs
407 // purpose : Decalage des Arcs pour boucher les trous.
408 //=============================================================================
409 void MAT_Graph::CompactArcs()
411 Standard_Integer IFind = 0;
412 Standard_Integer i = 1;
413 Standard_Boolean YaDecalage = Standard_False;
415 while (IFind < numberOfArcs) {
416 if (!theArcs.IsBound(i)) {
417 YaDecalage = Standard_True;
422 theArcs(i)->SetIndex(IFind);
423 theArcs.Bind(IFind,theArcs(i));
431 //=============================================================================
432 // function : CompactNodes
433 // purpose : Decalage des Nodes pour boucher les trous.
434 //=============================================================================
435 void MAT_Graph::CompactNodes()
437 Standard_Integer IFind = 0;
438 Standard_Integer i = 1;
439 Standard_Boolean YaDecalage = Standard_False;
441 while (IFind < numberOfNodes) {
442 if (!theNodes.IsBound(i)) {
443 YaDecalage = Standard_True;
448 theNodes(i)->SetIndex(IFind);
449 theNodes.Bind(IFind,theNodes(i));
457 //=============================================================================
458 // function : ChangeBasicElts
460 //=============================================================================
461 void MAT_Graph::ChangeBasicElts(const MAT_DataMapOfIntegerBasicElt& NewMap)
463 theBasicElts = NewMap;
464 MAT_DataMapIteratorOfDataMapOfIntegerBasicElt Ite;
465 for (Ite.Initialize(theBasicElts); Ite.More(); Ite.Next()) {
466 Ite.Value()->SetIndex(Ite.Key());
470 //=============================================================================
471 //function : ChangeBasicElt
473 //=============================================================================
474 Handle(MAT_BasicElt) MAT_Graph::ChangeBasicElt(const Standard_Integer Index)
476 return theBasicElts(Index);
479 //=============================================================================
480 // function : UpDateNodes
481 // purpose : Mise a jour des sequence d'ARC de chaque FirstNode de chaque arc.
482 // et stockage de chaque noeud dans la table des noeuds.
483 // Les noeuds racines sont traites dans PERFORM.
484 //=============================================================================
485 void MAT_Graph::UpDateNodes (Standard_Integer& IndTabNodes)
488 Handle(MAT_Node) Bout;
489 Handle(MAT_Arc) CurrentArc;
491 for (i = 1; i <= numberOfArcs; i++) {
492 Bout = theArcs(i)->FirstNode();
493 theNodes.Bind(IndTabNodes,Bout);
494 Bout->SetIndex(IndTabNodes);
496 Bout->SetLinkedArc(theArcs(i));
501 //=============================================================================
502 // function : MakeArc
503 // purpose : Creation des <ARCS> en parcourant l'arbre issue de <aBisector>.
504 //=============================================================================
505 static Handle(MAT_Arc) MakeArc(const Handle(MAT_Bisector)& aBisector,
506 MAT_DataMapOfIntegerBasicElt& TheBasicElts,
507 MAT_DataMapOfIntegerArc& TheArcs,
508 Standard_Integer& IndTabArcs)
510 Handle(MAT_Arc) CurrentArc;
511 Handle(MAT_Arc) PrevArc;
512 Handle(MAT_Arc) NextArc;
513 Handle(MAT_Node) Extremite;
514 Handle(MAT_ListOfBisector) BisectorList;
515 Standard_Real DistExt;
517 #ifdef OCCT_DEBUG_Graph
518 std::cout<<"Construction Arc : Index"<<aBisector->IndexNumber()<<std::endl;
519 std::cout<<"Construction Arc : Bisector"<<aBisector->BisectorNumber()<<std::endl;
522 CurrentArc = new MAT_Arc(IndTabArcs,
523 aBisector->BisectorNumber(),
524 TheBasicElts(aBisector->FirstEdge()->EdgeNumber()),
525 TheBasicElts(aBisector->SecondEdge()->EdgeNumber())
527 DistExt = aBisector->DistIssuePoint();
528 if (DistExt == Precision::Infinite()) {
530 #ifdef OCCT_DEBUG_Graph
531 std::cout<<"PB:RECUPERATION DISTANCE SUR ISSUEPOINT."<<std::endl;
535 Extremite = new MAT_Node(aBisector->IssuePoint(),CurrentArc,DistExt);
537 CurrentArc->SetFirstNode(Extremite);
538 BisectorList = aBisector->List();
539 BisectorList->First();
541 if (!BisectorList->More()) {
542 // -------------------
543 // Arc sur le contour.
544 // -------------------
545 TheBasicElts(aBisector->SecondEdge()->EdgeNumber())
546 ->SetStartArc(CurrentArc);
547 TheBasicElts(aBisector->FirstEdge()->EdgeNumber())
548 ->SetEndArc(CurrentArc);
551 PrevArc = CurrentArc;
553 while (BisectorList->More()) {
554 NextArc = MakeArc(BisectorList->Current(),
558 NextArc->SetSecondNode(Extremite);
559 NextArc->SetNeighbour (MAT_Left ,Extremite,PrevArc);
560 PrevArc->SetNeighbour (MAT_Right,Extremite,NextArc);
562 BisectorList->Next();
564 CurrentArc->SetNeighbour(MAT_Left ,Extremite,NextArc);
565 NextArc ->SetNeighbour(MAT_Right,Extremite,CurrentArc);
568 #ifdef OCCT_DEBUG_Graph
569 std::cout<<"IndTabArcs = "<<IndTabArcs<<std::endl;
570 std::cout<<"ArcIndex = "<<CurrentArc->ArcIndex()<<std::endl;
572 CurrentArc->SetIndex(IndTabArcs);
573 TheArcs.Bind(IndTabArcs,CurrentArc);
574 IndTabArcs = IndTabArcs + 1;