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>
36 static Handle(MAT_Arc) MakeArc(const Handle(MAT_Bisector)& aBisector,
37 MAT_DataMapOfIntegerBasicElt& TheBasicElts,
38 MAT_DataMapOfIntegerArc& TheArcs,
39 Standard_Integer& IndTabArcs);
41 // =====================================================================
43 // =====================================================================
44 MAT_Graph::MAT_Graph() {}
46 // =====================================================================
48 // purpose : Creation du graphe contenant le resultat.
49 // =====================================================================
50 void MAT_Graph::Perform(const Standard_Boolean SemiInfinite,
51 const Handle(MAT_ListOfBisector)& TheRoots,
52 const Standard_Integer NbBasicElts,
53 const Standard_Integer NbArcs)
55 Standard_Integer NbRoots;
56 Handle(MAT_Arc) FirstArc;
57 Handle(MAT_Arc) CurrentArc;
58 Handle(MAT_Node) Extremite;
59 Standard_Integer IndTabArcs = 1;
60 Standard_Integer IndTabNodes;
62 Standard_Real DistExt;
63 Standard_Integer IndExt;
64 Handle(MAT_Arc) PreviousArc = CurrentArc;
66 //------------------------
67 // Construction du graphe.
68 //------------------------
71 NbRoots = TheRoots->Number();
72 numberOfInfiniteNodes = NbRoots;
76 numberOfInfiniteNodes = 0;
79 numberOfArcs = NbArcs;
80 numberOfBasicElts = NbBasicElts;
81 numberOfNodes = NbRoots + NbArcs;
82 IndTabNodes = numberOfNodes;
84 //---------------------------
85 //... Creation des BasicElts.
86 //---------------------------
87 for (i = 1; i <= NbBasicElts; i++) {
88 theBasicElts.Bind(i,new MAT_BasicElt(i));
89 theBasicElts(i)->SetGeomIndex(i);
92 //--------------------------------------------------------------------
93 // ... Creation des ARCS et des NODES.
94 // Construction des arbres d arcs a partir des <Bisector> racines.
95 //--------------------------------------------------------------------
99 // Plusieurs points d entree a l infini.
100 //--------------------------------------
103 while (TheRoots->More()) {
104 CurrentArc = MakeArc(TheRoots->Current(),
108 Extremite = new MAT_Node (0,CurrentArc,Precision::Infinite());
109 Extremite ->SetIndex (IndTabNodes);
110 CurrentArc->SetSecondNode(Extremite);
111 theNodes.Bind(IndTabNodes,Extremite);
117 // -----------------------------------------------
118 // Un seul point d entree .
119 // Creation d un premier ARC et du NODE racine.
120 // -----------------------------------------------
123 CurrentArc = MakeArc(TheRoots->Current(),
127 DistExt = TheRoots->Current()->FirstEdge()->Distance();
128 IndExt = TheRoots->Current()->EndPoint();
130 Extremite = new MAT_Node(IndExt,CurrentArc,DistExt);
131 Extremite ->SetIndex (IndTabNodes);
132 CurrentArc->SetSecondNode(Extremite);
133 theNodes.Bind(IndTabNodes,Extremite);
136 // -----------------------------------------------------------
137 // ...Creation des ARCs issues de la racine.
138 // Codage des voisinages sur ces arcs et mise a jour de la
139 // sequence des arcs issue du Node racine.
140 // -----------------------------------------------------------
141 FirstArc = CurrentArc;
142 PreviousArc = FirstArc;
145 while (TheRoots->More()) {
146 CurrentArc = MakeArc(TheRoots->Current(),
150 CurrentArc ->SetSecondNode(Extremite);
151 CurrentArc ->SetNeighbour (MAT_Left,Extremite ,PreviousArc);
152 PreviousArc->SetNeighbour (MAT_Right,Extremite,CurrentArc);
154 PreviousArc = CurrentArc;
157 FirstArc ->SetNeighbour (MAT_Left ,Extremite,CurrentArc);
158 CurrentArc->SetNeighbour (MAT_Right,Extremite,FirstArc);
161 // ----------------------------------------------------
162 // Les sequence des Arcs des Nodes racines sont a jour.
163 // Mise a jour des sequences des autres Nodes.
164 // ----------------------------------------------------
165 UpDateNodes(IndTabNodes);
168 //=============================================================================
171 //=============================================================================
172 Handle(MAT_Arc) MAT_Graph::Arc(const Standard_Integer Index) const
174 return theArcs(Index);
177 //=============================================================================
178 //function : BasicElt
180 //=============================================================================
181 Handle(MAT_BasicElt) MAT_Graph::BasicElt(const Standard_Integer Index) const
183 return theBasicElts(Index);
186 //=============================================================================
189 //=============================================================================
190 Handle(MAT_Node) MAT_Graph::Node(const Standard_Integer Index) const
192 return theNodes(Index);
195 //=============================================================================
196 //function : NumberOfArcs
198 //=============================================================================
199 Standard_Integer MAT_Graph::NumberOfArcs() const
204 //=============================================================================
205 //function : NumberOfNodes
207 //=============================================================================
208 Standard_Integer MAT_Graph::NumberOfNodes() const
210 return numberOfNodes;
213 //=============================================================================
214 //function : NumberOfInfiniteNodes
216 //=============================================================================
217 Standard_Integer MAT_Graph::NumberOfInfiniteNodes() const
219 return numberOfInfiniteNodes;
222 //=============================================================================
223 //function : NumberOfBasicElts
225 //=============================================================================
226 Standard_Integer MAT_Graph::NumberOfBasicElts() const
228 return numberOfBasicElts;
231 //=============================================================================
232 //function : FusionOfBasicElts
234 //=============================================================================
235 void MAT_Graph::FusionOfBasicElts(const Standard_Integer IndexElt1,
236 const Standard_Integer IndexElt2,
237 Standard_Boolean& MergeArc1,
238 Standard_Integer& IGeomArc1,
239 Standard_Integer& IGeomArc2,
240 Standard_Boolean& MergeArc2,
241 Standard_Integer& IGeomArc3,
242 Standard_Integer& IGeomArc4)
244 Handle(MAT_BasicElt) Elt1 = theBasicElts(IndexElt1);
245 Handle(MAT_BasicElt) Elt2 = theBasicElts(IndexElt2);
247 if (Elt1 == Elt2) return;
250 Handle(MAT_Zone) Zone2 = new MAT_Zone(Elt2);
252 //--------------------------------------------------------------------
253 // Les arcs de la zone de Elt2 ne separent plus Elt2 et qq chose mais
255 //--------------------------------------------------------------------
256 for (i = 1; i <= Zone2->NumberOfArcs(); i++) {
257 if (Zone2->ArcOnFrontier(i)->FirstElement() == Elt2) {
258 theArcs(Zone2->ArcOnFrontier(i)->Index())->SetFirstElement(Elt1);
261 theArcs(Zone2->ArcOnFrontier(i)->Index())->SetSecondElement(Elt1);
265 //-------------------------------------------------------------------
266 // le EndArc de Elt1 et le StartArc de Elt2 peuvent separes les memes
267 // elements de base => Fusion des deux arcs et mise a jour des noeuds.
268 //-------------------------------------------------------------------
269 Handle(MAT_Arc) EA1 = Elt1->EndArc();
270 Handle(MAT_Arc) SA2 = Elt2->StartArc();
272 Handle(MAT_BasicElt) E1 = EA1->FirstElement();
273 Handle(MAT_BasicElt) E2 = EA1->SecondElement();
274 Handle(MAT_BasicElt) E3 = SA2->FirstElement();
275 Handle(MAT_BasicElt) E4 = SA2->SecondElement();
276 MergeArc1 = Standard_False;
278 if ( (E1 == E3 || E1 == E4) && (E2 == E3 || E2 == E4)) {
279 FusionOfArcs(theArcs(EA1->Index()),theArcs(SA2->Index()));
280 MergeArc1 = Standard_True;
281 IGeomArc1 = EA1->GeomIndex();
282 IGeomArc2 = SA2->GeomIndex();
285 //-------------------------------------------------
286 // La fin de Elt1 devient la fin de Elt2.
287 //-------------------------------------------------
288 Elt1->SetEndArc(Elt2->EndArc());
290 //-------------------------------------------------------------------
291 // le EndArc de Elt1 et le StartArc de Elt1 peuvent separer les memes
293 // si les noeuds des arcs ne sont pas sur le contour
294 // => fusion des arcs.(contour ferme compose d un seul BasicElt)
295 // sinon rien (contour ferme compose de deux BasicElts)
296 //-------------------------------------------------------------------
297 Handle(MAT_Arc) SA1 = Elt1->StartArc();
298 EA1 = Elt1->EndArc();
301 E1 = EA1->FirstElement ();
302 E2 = EA1->SecondElement();
303 E3 = SA1->FirstElement ();
304 E4 = SA1->SecondElement();
306 Standard_Boolean OnFig = (EA1->FirstNode() ->OnBasicElt() ||
307 EA1->SecondNode()->OnBasicElt() ||
308 SA1->FirstNode() ->OnBasicElt() ||
309 SA1->SecondNode()->OnBasicElt() );
311 MergeArc2 = Standard_False;
313 if ((E1 == E3 || E1 == E4) && (E2 == E3 || E2 == E4) && !OnFig) {
314 FusionOfArcs(theArcs(EA1->Index()),theArcs(SA1->Index()));
315 MergeArc2 = Standard_True;
316 IGeomArc3 = EA1->GeomIndex();
317 IGeomArc4 = SA1->GeomIndex();
321 //----------------------------------------------------
322 // un element de base a ete elimine.
323 //----------------------------------------------------
324 theBasicElts.UnBind(Elt2->Index());
328 //=============================================================================
329 // function : FusionOfArcs
330 // purpose : Fusion de deux arcs separant les memes elements.
331 // l <Arc1> ira du Second noeud de <Arc2> au second Noeud de <Arc1>.
332 //=============================================================================
333 void MAT_Graph::FusionOfArcs(const Handle(MAT_Arc)& Arc1,
334 const Handle(MAT_Arc)& Arc2)
337 Handle(MAT_Node) OldNode1 = Arc1->FirstNode();
338 Handle(MAT_Node) OldNode2 = Arc2->FirstNode();
340 Arc1->SetFirstNode(Arc2->SecondNode());
342 //--------------------------------------------------------------------
343 // Mise a jour des voisinages autour du nouveau premier noeud de Arc1.
344 //--------------------------------------------------------------------
345 if (!Arc2->SecondNode()->Infinite()) {
346 Handle(MAT_Arc) LNeighbour = Arc2->Neighbour(Arc2->SecondNode(),MAT_Left);
347 Handle(MAT_Arc) RNeighbour = Arc2->Neighbour(Arc2->SecondNode(),MAT_Right);
349 Arc1->SetFirstArc(MAT_Left,LNeighbour);
350 Arc1->SetFirstArc(MAT_Right,RNeighbour);
351 theArcs(LNeighbour->Index())->SetNeighbour(MAT_Right,
354 theArcs(RNeighbour->Index())->SetNeighbour(MAT_Left,
359 Handle(MAT_Arc) EmptyArc;
360 Arc1->SetFirstArc(MAT_Left ,EmptyArc);
361 Arc1->SetFirstArc(MAT_Right,EmptyArc);
364 //-------------------------------------------------------------------
365 // Mise a jour du premier noeud Arc1.
366 //-----------------------------------------------------------------
367 Arc1->FirstNode()->SetLinkedArc(Arc1);
369 //------------------------------------
370 // Elimination de Arc2 et des OldNode
371 //------------------------------------
372 if (theNodes.IsBound(OldNode1->Index())) {
373 theNodes.UnBind(OldNode1->Index());
376 if (theNodes.IsBound(OldNode2->Index())) {
377 theNodes.UnBind(OldNode2->Index());
381 // Note: the Arc2 is actually a reference to a handle contained in theArcs map;
382 // it is necessary to create copy of that handle and use only it to access
383 // that object, since the handle contained in the map is destroyed by UnBind()
384 Handle(MAT_Arc) anArc2 = Arc2;
385 theArcs .UnBind(Arc2->Index());
388 for (Standard_Integer i = 1; i <= 2; i++){
389 Handle(MAT_BasicElt) BE;
391 BE = theBasicElts(anArc2->FirstElement ()->Index());
393 BE = theBasicElts(anArc2->SecondElement ()->Index());
395 if (BE->StartArc() == anArc2) { BE->SetStartArc(Arc1);}
396 if (BE->EndArc () == anArc2) { BE->SetEndArc (Arc1);}
400 //=============================================================================
401 // function : CompactArcs
402 // purpose : Decalage des Arcs pour boucher les trous.
403 //=============================================================================
404 void MAT_Graph::CompactArcs()
406 Standard_Integer IFind = 0;
407 Standard_Integer i = 1;
408 Standard_Boolean YaDecalage = Standard_False;
410 while (IFind < numberOfArcs) {
411 if (!theArcs.IsBound(i)) {
412 YaDecalage = Standard_True;
417 theArcs(i)->SetIndex(IFind);
418 theArcs.Bind(IFind,theArcs(i));
426 //=============================================================================
427 // function : CompactNodes
428 // purpose : Decalage des Nodes pour boucher les trous.
429 //=============================================================================
430 void MAT_Graph::CompactNodes()
432 Standard_Integer IFind = 0;
433 Standard_Integer i = 1;
434 Standard_Boolean YaDecalage = Standard_False;
436 while (IFind < numberOfNodes) {
437 if (!theNodes.IsBound(i)) {
438 YaDecalage = Standard_True;
443 theNodes(i)->SetIndex(IFind);
444 theNodes.Bind(IFind,theNodes(i));
452 //=============================================================================
453 // function : ChangeBasicElts
455 //=============================================================================
456 void MAT_Graph::ChangeBasicElts(const MAT_DataMapOfIntegerBasicElt& NewMap)
458 theBasicElts = NewMap;
459 MAT_DataMapIteratorOfDataMapOfIntegerBasicElt Ite;
460 for (Ite.Initialize(theBasicElts); Ite.More(); Ite.Next()) {
461 Ite.Value()->SetIndex(Ite.Key());
465 //=============================================================================
466 //function : ChangeBasicElt
468 //=============================================================================
469 Handle(MAT_BasicElt) MAT_Graph::ChangeBasicElt(const Standard_Integer Index)
471 return theBasicElts(Index);
474 //=============================================================================
475 // function : UpDateNodes
476 // purpose : Mise a jour des sequence d'ARC de chaque FirstNode de chaque arc.
477 // et stockage de chaque noeud dans la table des noeuds.
478 // Les noeuds racines sont traites dans PERFORM.
479 //=============================================================================
480 void MAT_Graph::UpDateNodes (Standard_Integer& IndTabNodes)
483 Handle(MAT_Node) Bout;
484 Handle(MAT_Arc) CurrentArc;
486 for (i = 1; i <= numberOfArcs; i++) {
487 Bout = theArcs(i)->FirstNode();
488 theNodes.Bind(IndTabNodes,Bout);
489 Bout->SetIndex(IndTabNodes);
491 Bout->SetLinkedArc(theArcs(i));
496 //=============================================================================
497 // function : MakeArc
498 // purpose : Creation des <ARCS> en parcourant l'arbre issue de <aBisector>.
499 //=============================================================================
500 static Handle(MAT_Arc) MakeArc(const Handle(MAT_Bisector)& aBisector,
501 MAT_DataMapOfIntegerBasicElt& TheBasicElts,
502 MAT_DataMapOfIntegerArc& TheArcs,
503 Standard_Integer& IndTabArcs)
505 Handle(MAT_Arc) CurrentArc;
506 Handle(MAT_Arc) PrevArc;
507 Handle(MAT_Arc) NextArc;
508 Handle(MAT_Node) Extremite;
509 Handle(MAT_ListOfBisector) BisectorList;
510 Standard_Real DistExt;
512 #ifdef OCCT_DEBUG_Graph
513 cout<<"Construction Arc : Index"<<aBisector->IndexNumber()<<endl;
514 cout<<"Construction Arc : Bisector"<<aBisector->BisectorNumber()<<endl;
517 CurrentArc = new MAT_Arc(IndTabArcs,
518 aBisector->BisectorNumber(),
519 TheBasicElts(aBisector->FirstEdge()->EdgeNumber()),
520 TheBasicElts(aBisector->SecondEdge()->EdgeNumber())
522 DistExt = aBisector->DistIssuePoint();
523 if (DistExt == Precision::Infinite()) {
525 #ifdef OCCT_DEBUG_Graph
526 cout<<"PB:RECUPERATION DISTANCE SUR ISSUEPOINT."<<endl;
530 Extremite = new MAT_Node(aBisector->IssuePoint(),CurrentArc,DistExt);
532 CurrentArc->SetFirstNode(Extremite);
533 BisectorList = aBisector->List();
534 BisectorList->First();
536 if (!BisectorList->More()) {
537 // -------------------
538 // Arc sur le contour.
539 // -------------------
540 TheBasicElts(aBisector->SecondEdge()->EdgeNumber())
541 ->SetStartArc(CurrentArc);
542 TheBasicElts(aBisector->FirstEdge()->EdgeNumber())
543 ->SetEndArc(CurrentArc);
546 PrevArc = CurrentArc;
548 while (BisectorList->More()) {
549 NextArc = MakeArc(BisectorList->Current(),
553 NextArc->SetSecondNode(Extremite);
554 NextArc->SetNeighbour (MAT_Left ,Extremite,PrevArc);
555 PrevArc->SetNeighbour (MAT_Right,Extremite,NextArc);
557 BisectorList->Next();
559 CurrentArc->SetNeighbour(MAT_Left ,Extremite,NextArc);
560 NextArc ->SetNeighbour(MAT_Right,Extremite,CurrentArc);
563 #ifdef OCCT_DEBUG_Graph
564 cout<<"IndTabArcs = "<<IndTabArcs<<endl;
565 cout<<"ArcIndex = "<<CurrentArc->ArcIndex()<<endl;
567 CurrentArc->SetIndex(IndTabArcs);
568 TheArcs.Bind(IndTabArcs,CurrentArc);
569 IndTabArcs = IndTabArcs + 1;