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.
17 # include <MAT_Graph.ixx>
18 # include <MAT_SequenceOfArc.hxx>
19 # include <MAT_Arc.hxx>
20 # include <MAT_Node.hxx>
21 # include <MAT_BasicElt.hxx>
22 # include <MAT_Zone.hxx>
23 # include <MAT_DataMapOfIntegerBasicElt.hxx>
24 # include <MAT_DataMapIteratorOfDataMapOfIntegerBasicElt.hxx>
25 # include <MAT_DataMapOfIntegerArc.hxx>
26 # include <MAT_SequenceOfArc.hxx>
27 # include <MAT_Bisector.hxx>
28 # include <MAT_Edge.hxx>
29 # include <Precision.hxx>
34 static Handle(MAT_Arc) MakeArc(const Handle(MAT_Bisector)& aBisector,
35 MAT_DataMapOfIntegerBasicElt& TheBasicElts,
36 MAT_DataMapOfIntegerArc& TheArcs,
37 Standard_Integer& IndTabArcs);
39 // =====================================================================
41 // =====================================================================
42 MAT_Graph::MAT_Graph() {}
44 // =====================================================================
46 // purpose : Creation du graphe contenant le resultat.
47 // =====================================================================
48 void MAT_Graph::Perform(const Standard_Boolean SemiInfinite,
49 const Handle(MAT_ListOfBisector)& TheRoots,
50 const Standard_Integer NbBasicElts,
51 const Standard_Integer NbArcs)
53 Standard_Integer NbRoots;
54 Handle(MAT_Arc) FirstArc;
55 Handle(MAT_Arc) CurrentArc;
56 Handle(MAT_Node) Extremite;
57 Standard_Integer IndTabArcs = 1;
58 Standard_Integer IndTabNodes;
60 Standard_Real DistExt;
61 Standard_Integer IndExt;
62 Handle(MAT_Arc) PreviousArc = CurrentArc;
64 //------------------------
65 // Construction du graphe.
66 //------------------------
69 NbRoots = TheRoots->Number();
70 numberOfInfiniteNodes = NbRoots;
74 numberOfInfiniteNodes = 0;
77 numberOfArcs = NbArcs;
78 numberOfBasicElts = NbBasicElts;
79 numberOfNodes = NbRoots + NbArcs;
80 IndTabNodes = numberOfNodes;
82 //---------------------------
83 //... Creation des BasicElts.
84 //---------------------------
85 for (i = 1; i <= NbBasicElts; i++) {
86 theBasicElts.Bind(i,new MAT_BasicElt(i));
87 theBasicElts(i)->SetGeomIndex(i);
90 //--------------------------------------------------------------------
91 // ... Creation des ARCS et des NODES.
92 // Construction des arbres d arcs a partir des <Bisector> racines.
93 //--------------------------------------------------------------------
97 // Plusieurs points d entree a l infini.
98 //--------------------------------------
101 while (TheRoots->More()) {
102 CurrentArc = MakeArc(TheRoots->Current(),
106 Extremite = new MAT_Node (0,CurrentArc,Precision::Infinite());
107 Extremite ->SetIndex (IndTabNodes);
108 CurrentArc->SetSecondNode(Extremite);
109 theNodes.Bind(IndTabNodes,Extremite);
115 // -----------------------------------------------
116 // Un seul point d entree .
117 // Creation d un premier ARC et du NODE racine.
118 // -----------------------------------------------
121 CurrentArc = MakeArc(TheRoots->Current(),
125 DistExt = TheRoots->Current()->FirstEdge()->Distance();
126 IndExt = TheRoots->Current()->EndPoint();
128 Extremite = new MAT_Node(IndExt,CurrentArc,DistExt);
129 Extremite ->SetIndex (IndTabNodes);
130 CurrentArc->SetSecondNode(Extremite);
131 theNodes.Bind(IndTabNodes,Extremite);
134 // -----------------------------------------------------------
135 // ...Creation des ARCs issues de la racine.
136 // Codage des voisinages sur ces arcs et mise a jour de la
137 // sequence des arcs issue du Node racine.
138 // -----------------------------------------------------------
139 FirstArc = CurrentArc;
140 PreviousArc = FirstArc;
143 while (TheRoots->More()) {
144 CurrentArc = MakeArc(TheRoots->Current(),
148 CurrentArc ->SetSecondNode(Extremite);
149 CurrentArc ->SetNeighbour (MAT_Left,Extremite ,PreviousArc);
150 PreviousArc->SetNeighbour (MAT_Right,Extremite,CurrentArc);
152 PreviousArc = CurrentArc;
155 FirstArc ->SetNeighbour (MAT_Left ,Extremite,CurrentArc);
156 CurrentArc->SetNeighbour (MAT_Right,Extremite,FirstArc);
159 // ----------------------------------------------------
160 // Les sequence des Arcs des Nodes racines sont a jour.
161 // Mise a jour des sequences des autres Nodes.
162 // ----------------------------------------------------
163 UpDateNodes(IndTabNodes);
166 //=============================================================================
169 //=============================================================================
170 Handle(MAT_Arc) MAT_Graph::Arc(const Standard_Integer Index) const
172 return theArcs(Index);
175 //=============================================================================
176 //function : BasicElt
178 //=============================================================================
179 Handle(MAT_BasicElt) MAT_Graph::BasicElt(const Standard_Integer Index) const
181 return theBasicElts(Index);
184 //=============================================================================
187 //=============================================================================
188 Handle(MAT_Node) MAT_Graph::Node(const Standard_Integer Index) const
190 return theNodes(Index);
193 //=============================================================================
194 //function : NumberOfArcs
196 //=============================================================================
197 Standard_Integer MAT_Graph::NumberOfArcs() const
202 //=============================================================================
203 //function : NumberOfNodes
205 //=============================================================================
206 Standard_Integer MAT_Graph::NumberOfNodes() const
208 return numberOfNodes;
211 //=============================================================================
212 //function : NumberOfInfiniteNodes
214 //=============================================================================
215 Standard_Integer MAT_Graph::NumberOfInfiniteNodes() const
217 return numberOfInfiniteNodes;
220 //=============================================================================
221 //function : NumberOfBasicElts
223 //=============================================================================
224 Standard_Integer MAT_Graph::NumberOfBasicElts() const
226 return numberOfBasicElts;
229 //=============================================================================
230 //function : FusionOfBasicElts
232 //=============================================================================
233 void MAT_Graph::FusionOfBasicElts(const Standard_Integer IndexElt1,
234 const Standard_Integer IndexElt2,
235 Standard_Boolean& MergeArc1,
236 Standard_Integer& IGeomArc1,
237 Standard_Integer& IGeomArc2,
238 Standard_Boolean& MergeArc2,
239 Standard_Integer& IGeomArc3,
240 Standard_Integer& IGeomArc4)
242 Handle(MAT_BasicElt) Elt1 = theBasicElts(IndexElt1);
243 Handle(MAT_BasicElt) Elt2 = theBasicElts(IndexElt2);
245 if (Elt1 == Elt2) return;
248 Handle(MAT_Zone) Zone2 = new MAT_Zone(Elt2);
250 //--------------------------------------------------------------------
251 // Les arcs de la zone de Elt2 ne separent plus Elt2 et qq chose mais
253 //--------------------------------------------------------------------
254 for (i = 1; i <= Zone2->NumberOfArcs(); i++) {
255 if (Zone2->ArcOnFrontier(i)->FirstElement() == Elt2) {
256 theArcs(Zone2->ArcOnFrontier(i)->Index())->SetFirstElement(Elt1);
259 theArcs(Zone2->ArcOnFrontier(i)->Index())->SetSecondElement(Elt1);
263 //-------------------------------------------------------------------
264 // le EndArc de Elt1 et le StartArc de Elt2 peuvent separes les memes
265 // elements de base => Fusion des deux arcs et mise a jour des noeuds.
266 //-------------------------------------------------------------------
267 Handle(MAT_Arc) EA1 = Elt1->EndArc();
268 Handle(MAT_Arc) SA2 = Elt2->StartArc();
270 Handle(MAT_BasicElt) E1 = EA1->FirstElement();
271 Handle(MAT_BasicElt) E2 = EA1->SecondElement();
272 Handle(MAT_BasicElt) E3 = SA2->FirstElement();
273 Handle(MAT_BasicElt) E4 = SA2->SecondElement();
274 MergeArc1 = Standard_False;
276 if ( (E1 == E3 || E1 == E4) && (E2 == E3 || E2 == E4)) {
277 FusionOfArcs(theArcs(EA1->Index()),theArcs(SA2->Index()));
278 MergeArc1 = Standard_True;
279 IGeomArc1 = EA1->GeomIndex();
280 IGeomArc2 = SA2->GeomIndex();
283 //-------------------------------------------------
284 // La fin de Elt1 devient la fin de Elt2.
285 //-------------------------------------------------
286 Elt1->SetEndArc(Elt2->EndArc());
288 //-------------------------------------------------------------------
289 // le EndArc de Elt1 et le StartArc de Elt1 peuvent separer les memes
291 // si les noeuds des arcs ne sont pas sur le contour
292 // => fusion des arcs.(contour ferme compose d un seul BasicElt)
293 // sinon rien (contour ferme compose de deux BasicElts)
294 //-------------------------------------------------------------------
295 Handle(MAT_Arc) SA1 = Elt1->StartArc();
296 EA1 = Elt1->EndArc();
299 Handle(MAT_BasicElt) E1 = EA1->FirstElement ();
300 Handle(MAT_BasicElt) E2 = EA1->SecondElement();
301 Handle(MAT_BasicElt) E3 = SA1->FirstElement ();
302 Handle(MAT_BasicElt) E4 = SA1->SecondElement();
304 Standard_Boolean OnFig = (EA1->FirstNode() ->OnBasicElt() ||
305 EA1->SecondNode()->OnBasicElt() ||
306 SA1->FirstNode() ->OnBasicElt() ||
307 SA1->SecondNode()->OnBasicElt() );
309 MergeArc2 = Standard_False;
311 if ((E1 == E3 || E1 == E4) && (E2 == E3 || E2 == E4) && !OnFig) {
312 FusionOfArcs(theArcs(EA1->Index()),theArcs(SA1->Index()));
313 MergeArc2 = Standard_True;
314 IGeomArc3 = EA1->GeomIndex();
315 IGeomArc4 = SA1->GeomIndex();
319 //----------------------------------------------------
320 // un element de base a ete elimine.
321 //----------------------------------------------------
322 theBasicElts.UnBind(Elt2->Index());
326 //=============================================================================
327 // function : FusionOfArcs
328 // purpose : Fusion de deux arcs separant les memes elements.
329 // l <Arc1> ira du Second noeud de <Arc2> au second Noeud de <Arc1>.
330 //=============================================================================
331 void MAT_Graph::FusionOfArcs(const Handle(MAT_Arc)& Arc1,
332 const Handle(MAT_Arc)& Arc2)
335 Handle(MAT_Node) OldNode1 = Arc1->FirstNode();
336 Handle(MAT_Node) OldNode2 = Arc2->FirstNode();
338 Arc1->SetFirstNode(Arc2->SecondNode());
340 //--------------------------------------------------------------------
341 // Mise a jour des voisinages autour du nouveau premier noeud de Arc1.
342 //--------------------------------------------------------------------
343 if (!Arc2->SecondNode()->Infinite()) {
344 Handle(MAT_Arc) LNeighbour = Arc2->Neighbour(Arc2->SecondNode(),MAT_Left);
345 Handle(MAT_Arc) RNeighbour = Arc2->Neighbour(Arc2->SecondNode(),MAT_Right);
347 Arc1->SetFirstArc(MAT_Left,LNeighbour);
348 Arc1->SetFirstArc(MAT_Right,RNeighbour);
349 theArcs(LNeighbour->Index())->SetNeighbour(MAT_Right,
352 theArcs(RNeighbour->Index())->SetNeighbour(MAT_Left,
357 Handle(MAT_Arc) EmptyArc;
358 Arc1->SetFirstArc(MAT_Left ,EmptyArc);
359 Arc1->SetFirstArc(MAT_Right,EmptyArc);
362 //-------------------------------------------------------------------
363 // Mise a jour du premier noeud Arc1.
364 //-----------------------------------------------------------------
365 Arc1->FirstNode()->SetLinkedArc(Arc1);
367 //------------------------------------
368 // Elimination de Arc2 et des OldNode
369 //------------------------------------
370 if (theNodes.IsBound(OldNode1->Index())) {
371 theNodes.UnBind(OldNode1->Index());
374 if (theNodes.IsBound(OldNode2->Index())) {
375 theNodes.UnBind(OldNode2->Index());
379 // Note: the Arc2 is actually a reference to a handle contained in theArcs map;
380 // it is necessary to create copy of that handle and use only it to access
381 // that object, since the handle contained in the map is destroyed by UnBind()
382 Handle(MAT_Arc) anArc2 = Arc2;
383 theArcs .UnBind(Arc2->Index());
386 for (Standard_Integer i = 1; i <= 2; i++){
387 Handle(MAT_BasicElt) BE;
389 BE = theBasicElts(anArc2->FirstElement ()->Index());
391 BE = theBasicElts(anArc2->SecondElement ()->Index());
393 if (BE->StartArc() == anArc2) { BE->SetStartArc(Arc1);}
394 if (BE->EndArc () == anArc2) { BE->SetEndArc (Arc1);}
398 //=============================================================================
399 // function : CompactArcs
400 // purpose : Decalage des Arcs pour boucher les trous.
401 //=============================================================================
402 void MAT_Graph::CompactArcs()
404 Standard_Integer IFind = 0;
405 Standard_Integer i = 1;
406 Standard_Boolean YaDecalage = Standard_False;
408 while (IFind < numberOfArcs) {
409 if (!theArcs.IsBound(i)) {
410 YaDecalage = Standard_True;
415 theArcs(i)->SetIndex(IFind);
416 theArcs.Bind(IFind,theArcs(i));
424 //=============================================================================
425 // function : CompactNodes
426 // purpose : Decalage des Nodes pour boucher les trous.
427 //=============================================================================
428 void MAT_Graph::CompactNodes()
430 Standard_Integer IFind = 0;
431 Standard_Integer i = 1;
432 Standard_Boolean YaDecalage = Standard_False;
434 while (IFind < numberOfNodes) {
435 if (!theNodes.IsBound(i)) {
436 YaDecalage = Standard_True;
441 theNodes(i)->SetIndex(IFind);
442 theNodes.Bind(IFind,theNodes(i));
450 //=============================================================================
451 // function : ChangeBasicElts
453 //=============================================================================
454 void MAT_Graph::ChangeBasicElts(const MAT_DataMapOfIntegerBasicElt& NewMap)
456 theBasicElts = NewMap;
457 MAT_DataMapIteratorOfDataMapOfIntegerBasicElt Ite;
458 for (Ite.Initialize(theBasicElts); Ite.More(); Ite.Next()) {
459 Ite.Value()->SetIndex(Ite.Key());
463 //=============================================================================
464 //function : ChangeBasicElt
466 //=============================================================================
467 Handle(MAT_BasicElt) MAT_Graph::ChangeBasicElt(const Standard_Integer Index)
469 return theBasicElts(Index);
472 //=============================================================================
473 // function : UpDateNodes
474 // purpose : Mise a jour des sequence d'ARC de chaque FirstNode de chaque arc.
475 // et stockage de chaque noeud dans la table des noeuds.
476 // Les noeuds racines sont traites dans PERFORM.
477 //=============================================================================
478 void MAT_Graph::UpDateNodes (Standard_Integer& IndTabNodes)
481 Handle(MAT_Node) Bout;
482 Handle(MAT_Arc) CurrentArc;
484 for (i = 1; i <= numberOfArcs; i++) {
485 Bout = theArcs(i)->FirstNode();
486 theNodes.Bind(IndTabNodes,Bout);
487 Bout->SetIndex(IndTabNodes);
489 Bout->SetLinkedArc(theArcs(i));
494 //=============================================================================
495 // function : MakeArc
496 // purpose : Creation des <ARCS> en parcourant l'arbre issue de <aBisector>.
497 //=============================================================================
498 static Handle(MAT_Arc) MakeArc(const Handle(MAT_Bisector)& aBisector,
499 MAT_DataMapOfIntegerBasicElt& TheBasicElts,
500 MAT_DataMapOfIntegerArc& TheArcs,
501 Standard_Integer& IndTabArcs)
503 Handle(MAT_Arc) CurrentArc;
504 Handle(MAT_Arc) PrevArc;
505 Handle(MAT_Arc) NextArc;
506 Handle(MAT_Node) Extremite;
507 Handle(MAT_ListOfBisector) BisectorList;
508 Standard_Real DistExt;
510 #ifdef OCCT_DEBUG_Graph
511 cout<<"Construction Arc : Index"<<aBisector->IndexNumber()<<endl;
512 cout<<"Construction Arc : Bisector"<<aBisector->BisectorNumber()<<endl;
515 CurrentArc = new MAT_Arc(IndTabArcs,
516 aBisector->BisectorNumber(),
517 TheBasicElts(aBisector->FirstEdge()->EdgeNumber()),
518 TheBasicElts(aBisector->SecondEdge()->EdgeNumber())
520 DistExt = aBisector->DistIssuePoint();
521 if (DistExt == Precision::Infinite()) {
523 #ifdef OCCT_DEBUG_Graph
524 cout<<"PB:RECUPERATION DISTANCE SUR ISSUEPOINT."<<endl;
528 Extremite = new MAT_Node(aBisector->IssuePoint(),CurrentArc,DistExt);
530 CurrentArc->SetFirstNode(Extremite);
531 BisectorList = aBisector->List();
532 BisectorList->First();
534 if (!BisectorList->More()) {
535 // -------------------
536 // Arc sur le contour.
537 // -------------------
538 TheBasicElts(aBisector->SecondEdge()->EdgeNumber())
539 ->SetStartArc(CurrentArc);
540 TheBasicElts(aBisector->FirstEdge()->EdgeNumber())
541 ->SetEndArc(CurrentArc);
544 PrevArc = CurrentArc;
546 while (BisectorList->More()) {
547 NextArc = MakeArc(BisectorList->Current(),
551 NextArc->SetSecondNode(Extremite);
552 NextArc->SetNeighbour (MAT_Left ,Extremite,PrevArc);
553 PrevArc->SetNeighbour (MAT_Right,Extremite,NextArc);
555 BisectorList->Next();
557 CurrentArc->SetNeighbour(MAT_Left ,Extremite,NextArc);
558 NextArc ->SetNeighbour(MAT_Right,Extremite,CurrentArc);
561 #ifdef OCCT_DEBUG_Graph
562 cout<<"IndTabArcs = "<<IndTabArcs<<endl;
563 cout<<"ArcIndex = "<<CurrentArc->ArcIndex()<<endl;
565 CurrentArc->SetIndex(IndTabArcs);
566 TheArcs.Bind(IndTabArcs,CurrentArc);
567 IndTabArcs = IndTabArcs + 1;