HierarchicalLayouter.cpp 352 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583
  1. #include "HierarchicalLayouter.h"
  2. // File contains starting of actual logic
  3. // Understand this File ***IMP***
  4. HierarchicalLayouter::HierarchicalLayouter()
  5. {
  6. m_sExecutionLogFileName = FILENAME_EXECUTION_TIME_DETAILS;
  7. m_iFinalCrossings = 0;
  8. }
  9. void HierarchicalLayouter::applyHierarchicalLayout(SubGraph &gGraph, int iNodeSeparation, int iEdgeSeparation, int iLayerSeparation, int iBorderMargin)
  10. {
  11. m_iNodeSeparation = iNodeSeparation;
  12. m_iEdgeSeparation = iEdgeSeparation;
  13. m_iRankSeparation = iLayerSeparation;
  14. m_iBorderMargin = iBorderMargin;
  15. applyHierarchicalLayout(gGraph);
  16. }
  17. void HierarchicalLayouter::applyHierarchicalLayout(SubGraph &gGraph)
  18. {
  19. QString sTimeDetails = "";
  20. QTime tGlobalTimer; // Main function
  21. QTime tProcessTimer;
  22. qDebug() << "applyHierarchicalLayout() start";
  23. //sTimeDetails.append("ApplyHierarchicalLayout Started");
  24. tGlobalTimer.start();
  25. //Validate gGraph
  26. m_gMainGraph = &gGraph;
  27. ////qDebug()<<"Test input00000000000000000";
  28. BGL_FORALL_EDGES(eEdge , *m_gMainGraph , SubGraph)
  29. {
  30. //Get source vertex of long edge to connect to the first dummy node
  31. VertexDescriptor vSource = m_BoostGraphWrapper.getEdgeSource(eEdge , *m_gMainGraph);
  32. VertexDescriptor vTarget = m_BoostGraphWrapper.getEdgeTarget(eEdge , *m_gMainGraph);
  33. // XXX unused
  34. Q_UNUSED(vSource);
  35. Q_UNUSED(vTarget);
  36. //qDebug()<<"Edge: "<<(int)vSource <<" , "<<vTarget;
  37. }
  38. //qDebug()<<"Test input00000000000000000";
  39. //Set default margins if not already set
  40. if(m_iNodeSeparation.isSet() == false)
  41. {
  42. m_iNodeSeparation = 80; // setting node separation = 80
  43. }
  44. if(m_iEdgeSeparation.isSet() == false)
  45. {
  46. m_iEdgeSeparation = 70; // setting edge separation =70
  47. }
  48. if(m_iRankSeparation.isSet() == false)
  49. {
  50. m_iRankSeparation = 40;
  51. }
  52. if(m_iBorderMargin.isSet() == false)
  53. {
  54. m_iBorderMargin = 30;
  55. }
  56. //Reset counters. Initializations
  57. m_iNestingDepth.reset();
  58. int iTotalTime = 0;
  59. try
  60. {
  61. //Remove previous bend point entries if there are any
  62. BGL_FORALL_EDGES(eEdge , *m_gMainGraph , SubGraph)
  63. {
  64. (*m_gMainGraph)[eEdge].vecBendPoints.clear();
  65. }
  66. //sTimeDetails.append("\nRemoving Cycles: ");//1
  67. tProcessTimer.start();
  68. //Initial Cycle Removal
  69. //-Record Back Edges
  70. //-Recheck for cycles
  71. //This vector preserves the edges which are removed from graph because they creates cycles.
  72. VectorEdgeDescriptor vecBackEdges;
  73. removeCycle(gGraph , vecBackEdges);
  74. iTotalTime += tProcessTimer.elapsed();
  75. sTimeDetails.append(QString::number(tProcessTimer.elapsed()));
  76. sTimeDetails.append(",");//Add comma for CSV
  77. ////qDebug()<<"Graph after cycle removal:\n";
  78. //print_graph(gGraph);
  79. //Get graphs nesting depth
  80. m_iNestingDepth.reset();
  81. //qDebug()<<"Test after cycle removal 00000000000000000";
  82. BGL_FORALL_EDGES(eEdge , *m_gMainGraph , SubGraph)
  83. {
  84. //Get source vertex of long edge to connect to the first dummy node
  85. VertexDescriptor vSource = m_BoostGraphWrapper.getEdgeSource(eEdge , *m_gMainGraph);
  86. VertexDescriptor vTarget = m_BoostGraphWrapper.getEdgeTarget(eEdge , *m_gMainGraph);
  87. // XXX unused
  88. Q_UNUSED(vSource);
  89. Q_UNUSED(vTarget);
  90. //qDebug()<<"Edge: "<<(int)vSource <<" , "<<vTarget;
  91. }
  92. //qDebug()<<"Test after cycle removal 00000000000000000";
  93. // *************************************************************
  94. int iNestingDepth = getGraphNestingDepth(gGraph); // Checking for number
  95. //Check if graph has only single cluster // of clusters
  96. if(iNestingDepth == 0)
  97. {
  98. /*For single cluster graph change Depth to 1 because then
  99. *later it becomes simpler to identify the LayerRanks.
  100. */
  101. iNestingDepth = 1;
  102. }
  103. m_iNestingDepth = iNestingDepth;
  104. int iTotalClusters = 0;
  105. QQueue<SubGraph*> qSubgraphs; // a queue of subgraphs
  106. qSubgraphs.enqueue(m_gMainGraph);
  107. SubGraph* gSubgraph1 = NULL;
  108. while(qSubgraphs.isEmpty() == false)
  109. {
  110. gSubgraph1 = qSubgraphs.dequeue();
  111. iTotalClusters++;
  112. ChildrenIterator iterChild , iterChildEnd;
  113. for(boost::tie(iterChild , iterChildEnd) = gSubgraph1->children();
  114. iterChild != iterChildEnd;
  115. iterChild++)
  116. {
  117. SubGraph* gChildGraph = &(*iterChild);
  118. qSubgraphs.enqueue(gChildGraph);
  119. }
  120. }
  121. //***************************************************************************
  122. sTimeDetails.append(QString::number(iTotalClusters));
  123. sTimeDetails.append(",");//Add comma for CSV
  124. m_iRankDifferenceInLayers = m_iNestingDepth * 2 + 1;
  125. //sTimeDetails.append("\nCreate Nesting Graph: ");//2
  126. tProcessTimer.restart();
  127. //Nested Graph Creation
  128. createNestingGraph(gGraph);
  129. iTotalTime += tProcessTimer.elapsed();
  130. sTimeDetails.append(QString::number(tProcessTimer.elapsed()));
  131. sTimeDetails.append(",");//Add comma for CSV
  132. ////qDebug()<<"Nesting graph:\n";
  133. //print_graph(gGraph);
  134. qDebug()<<"applyHierarchicalLayout() Rank Asignment:\n";
  135. //sTimeDetails.append("\nAssign Ranks: ");//3
  136. tProcessTimer.restart();
  137. //Initial rank assignment // returns root vertex
  138. VertexDescriptor vRootVertex = m_BoostGraphWrapper.getGraphUpperBorderVertex(gGraph);
  139. //assign rank to nodes may be :0
  140. assignVertexRanks(gGraph , vRootVertex);
  141. //pullDownUpperBorderVertices();
  142. //Final Rank Assignment
  143. adjustVertexRanks(gGraph);
  144. //Pull up vertex ranks
  145. pullUpVertexRanks(gGraph , vRootVertex);//Commented for 42314-4
  146. //pullAndSpreadUpVertexRanks(gGraph , vRootVertex);
  147. iTotalTime += tProcessTimer.elapsed();
  148. sTimeDetails.append(QString::number(tProcessTimer.elapsed()));
  149. sTimeDetails.append(",");//Add comma for CSV
  150. //Test ranking and upward edges
  151. bool bIsUpwardEdgeFound = testUpwardEdgesAndRanks(gGraph);
  152. // XXX unused
  153. Q_UNUSED(bIsUpwardEdgeFound);
  154. LAYOUT_ASSERT(bIsUpwardEdgeFound == false , LayoutException(__FUNCTION__,LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION));
  155. // if(bIsUpwardEdgeFound == true)
  156. // {
  157. // ////qDebug() << "CAUTION : Upward Edge(s) found in nesting graph\n";
  158. // ////qDebug() << "***************************************************\n";
  159. // }
  160. // else
  161. // {
  162. // ////qDebug() << "Vertex Ranking is proper and No upward edge found. ";
  163. // }
  164. //Record unique ranks needed in splitting edges
  165. recordUniqueRankAndSort();
  166. //Production of Proper Hierarchy
  167. //- remove nested edges
  168. removeNestingEdges();//Approach 42014-1 //Change algorithm
  169. }
  170. catch(boost::exception &eBoostException)
  171. {
  172. throw *boost::get_error_info<errmsg_info>(eBoostException);
  173. }
  174. catch(LayoutException &eLayoutException)
  175. {
  176. throw eLayoutException;
  177. }
  178. catch(...)
  179. {
  180. throw;
  181. }
  182. bool bIsLayeredGraphCorrect = false;
  183. // XXX unused
  184. Q_UNUSED(bIsLayeredGraphCorrect);
  185. try
  186. {
  187. //sTimeDetails.append("\nInitialise ");
  188. //sTimeDetails.append(QString::number(num_vertices(*m_gMainGraph)));
  189. //sTimeDetails.append(" vertices LayerNode Hashset: ");//4
  190. tProcessTimer.restart();
  191. //Initialize hash of vertex mapped to corresponding LayerNode
  192. initHashVertexToLayerNode(gGraph);
  193. iTotalTime += tProcessTimer.elapsed();
  194. sTimeDetails.append(QString::number(tProcessTimer.elapsed()));
  195. sTimeDetails.append(",");//Add comma for CSV
  196. //sTimeDetails.append("\nGenerate Nesting Tree: ");//5
  197. tProcessTimer.restart();
  198. //Create Nesting tree
  199. generateNestingTree();
  200. iTotalTime += tProcessTimer.elapsed();
  201. sTimeDetails.append(QString::number(tProcessTimer.elapsed()));
  202. sTimeDetails.append(",");//Add comma for CSV
  203. //sTimeDetails.append("\nVertices Before Splitting: ");//6
  204. sTimeDetails.append(QString::number(num_vertices(*m_gMainGraph)));
  205. sTimeDetails.append(",");//Add comma for CSV
  206. //sTimeDetails.append(" , Edges Before Splitting: ");//7
  207. sTimeDetails.append(QString::number(num_edges(*m_gMainGraph)));
  208. sTimeDetails.append(",");//Add comma for CSV.
  209. bool bIsNestingTreeCorrect = testNestingTree();
  210. // XXX unusd
  211. Q_UNUSED(bIsNestingTreeCorrect);
  212. //Q_ASSERT_X(bIsNestingTreeCorrect , "Nesting Tree Generation" , "Incorrect Nesting Tree");
  213. LAYOUT_ASSERT(bIsNestingTreeCorrect , LayoutException(__FUNCTION__
  214. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  215. , "Nesting Tree"
  216. , "due to incorrect nesting tree generation"));
  217. //sTimeDetails.append("\nSplit Long Edges: ");//8
  218. tProcessTimer.restart();
  219. //Nesting tree is neccessary to Split Long Edges
  220. //Splitting long edges
  221. int iTotalLongEdges = 0;
  222. iTotalLongEdges = splitLongEdgesAndUpdateNestingTree();
  223. //iTotalLongEdges = splitLongEdgesAtAllLayerAndUpdateNestingTree();
  224. iTotalTime += tProcessTimer.elapsed();
  225. sTimeDetails.append(QString::number(tProcessTimer.elapsed()));
  226. sTimeDetails.append(",");//Add comma for CSV
  227. //Total Long Edges //9
  228. sTimeDetails.append(QString::number(iTotalLongEdges));
  229. sTimeDetails.append(",");//Add comma for CSV
  230. //sTimeDetails.append("\nVertices After Splitting: ");//10
  231. sTimeDetails.append(QString::number(num_vertices(*m_gMainGraph)));
  232. sTimeDetails.append(",");//Add comma for CSV
  233. //sTimeDetails.append(" , Edges After Splitting: ");//11
  234. sTimeDetails.append(QString::number(num_edges(*m_gMainGraph)));
  235. sTimeDetails.append(",");//Add comma for CSV.
  236. //Check if the Nesting tree is consistent with added dummy node
  237. bIsNestingTreeCorrect = testNestingTree();
  238. //Q_ASSERT_X(bIsNestingTreeCorrect , "After splitting long edges" , "Incorrect Nesting Tree");
  239. LAYOUT_ASSERT(bIsNestingTreeCorrect == true , LayoutException(__FUNCTION__
  240. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  241. , "Nesting Tree"
  242. , "after splitting of long edges"));
  243. // XXX bIsNestingTreeCorrect is never read
  244. //sTimeDetails.append("\nGenerate Layered Graph: ");//12
  245. tProcessTimer.restart();
  246. //Generate Layered Graph
  247. generateLayeredGraph();
  248. iTotalTime += tProcessTimer.elapsed();
  249. sTimeDetails.append(QString::number(tProcessTimer.elapsed()));
  250. sTimeDetails.append(",");//Add comma for CSV.
  251. //Testing Layered Graph
  252. bIsLayeredGraphCorrect = testLayeredGraph();
  253. LAYOUT_ASSERT(bIsLayeredGraphCorrect == true , LayoutException(__FUNCTION__
  254. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  255. , "Layered Graph"
  256. , "incorrect generation of layered graph"));
  257. // if(bIsLayeredGraphCorrect == false)
  258. // {
  259. // ////qDebug() << "Layered Graph is Incorrect";
  260. // }
  261. // else
  262. // {
  263. // ////qDebug() << "Layered Graph is Correct";
  264. // }
  265. //Set total number of layers
  266. m_iTotalLayers = m_mapLayeredGraph.size();
  267. }
  268. catch(boost::exception &eBoostException)
  269. {
  270. throw *boost::get_error_info<errmsg_info>(eBoostException);
  271. }
  272. catch(LayoutException &eLayoutException)
  273. {
  274. throw eLayoutException;
  275. }
  276. catch(...)
  277. {
  278. throw;
  279. }
  280. //Edge Crossing Minimisation
  281. //sTimeDetails.append("\nGlobal Crossing Reduction: ");//13
  282. qDebug() << "applyHierarchicalLayout() Global Crossing Reduction";
  283. //1. Global crossing reduction using BarryCenter Method
  284. int iIterCrossingReduction = 5;//m_iTotalLayers;
  285. int iCrossingCount = 0;
  286. int iSumPrevCrossings = 0;
  287. double dMeanPrevCrossings = 0.0;
  288. double dDeviation = INT_MAX;
  289. double dPrevDeviation = INT_MAX - 1;
  290. boost::circular_buffer<int> cbPrevCrossingCounts(4);
  291. iCrossingCount = getTotalCrossings();
  292. sTimeDetails.append(QString::number(iCrossingCount));
  293. try
  294. {
  295. tProcessTimer.restart();
  296. while(iIterCrossingReduction--)
  297. {
  298. qDebug() <<"applyHierarchicalLayout() Crossing Reduction iIterCrossingReduction=" << iIterCrossingReduction;
  299. globalCrossingReducion(gGraph);
  300. //Calculate crossings
  301. iCrossingCount = getTotalCrossings();
  302. //Calculate total of previous crossing counts
  303. iSumPrevCrossings = std::accumulate(cbPrevCrossingCounts.begin() , cbPrevCrossingCounts.end(), 0);
  304. //Calculate Previous crossings mean
  305. if(cbPrevCrossingCounts.size() != 0)
  306. {
  307. dMeanPrevCrossings = ((double)iSumPrevCrossings / cbPrevCrossingCounts.size());
  308. }
  309. else
  310. {
  311. dMeanPrevCrossings = 0;
  312. }
  313. //Calculate deviation of current crossing count with mean of previous crossings
  314. dDeviation = dMeanPrevCrossings - iCrossingCount;
  315. ////qDebug() << "____________________________________________";
  316. //If current deviation is zero means the
  317. //saturation state is achieved then stop
  318. if(dDeviation == 0 && dPrevDeviation == 0 )
  319. {
  320. ////qDebug() << ">>> Stopping Global Crossing at saturation <<<";
  321. ////qDebug() << iCrossingCount <<" Mean: "<< dMeanPrevCrossings << " Deviation: " << dDeviation;
  322. break;
  323. }
  324. //store crossing
  325. cbPrevCrossingCounts.push_back(iCrossingCount);
  326. dPrevDeviation = dDeviation;
  327. ////qDebug() << iCrossingCount <<" Mean: "<< dMeanPrevCrossings<< " Deviation: " << dDeviation ;
  328. }
  329. iTotalTime += tProcessTimer.elapsed();
  330. sTimeDetails.append(",");//Add comma for CSV.
  331. sTimeDetails.append(QString::number(tProcessTimer.elapsed()));
  332. }
  333. catch(boost::exception &eBoostException)
  334. {
  335. throw *boost::get_error_info<errmsg_info>(eBoostException);
  336. }
  337. catch(LayoutException &eLayoutException)
  338. {
  339. throw eLayoutException;
  340. }
  341. catch(...)
  342. {
  343. throw;
  344. }
  345. try
  346. {
  347. //***Add dummy nodes to empty layers in leaf NestingTree nodes
  348. addDummyNodeToEmptyLayersRecur(m_rootNestingTreeSubgraphNode);
  349. //2. Local + Global crossing reduction
  350. bIsLayeredGraphCorrect = testLayeredGraph();
  351. LAYOUT_ASSERT(bIsLayeredGraphCorrect, LayoutException(__FUNCTION__
  352. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  353. , "Layered Graph"
  354. , "in Layouting"));
  355. iCrossingCount = getTotalCrossings();
  356. sTimeDetails.append(",");//Add comma for CSV.
  357. sTimeDetails.append(QString::number(iCrossingCount));
  358. int iIterCrossingReduction = 2;//m_iTotalLayers;
  359. int iCrossingCount = 0;
  360. int iSumPrevCrossings = 0;
  361. double dMeanPrevCrossings = 0.0;
  362. double dDeviation = 99999;
  363. double dPrevDeviation = 10000;
  364. boost::circular_buffer<int> cbPrevCrossingCounts(20);
  365. tProcessTimer.restart();
  366. while(iIterCrossingReduction--)
  367. {
  368. qDebug() <<"applyHierarchicalLayout() LOCAL + GLOBAL Crossing Reduction iIterCrossingReduction=" << iIterCrossingReduction;
  369. reduceEdgeCrossings(1);
  370. //Calculate crossings
  371. iCrossingCount = getTotalCrossings();
  372. //Calculate total of previous crossing counts
  373. iSumPrevCrossings = std::accumulate(cbPrevCrossingCounts.begin() , cbPrevCrossingCounts.end(), 0);
  374. //Calculate Previous crossings mean
  375. if(cbPrevCrossingCounts.size() != 0)
  376. {
  377. if(cbPrevCrossingCounts.size() > (size_t)(m_iTotalLayers/2))
  378. {
  379. dMeanPrevCrossings = ((double)iSumPrevCrossings / cbPrevCrossingCounts.size());
  380. }
  381. }
  382. else
  383. {
  384. dMeanPrevCrossings = 0;
  385. }
  386. //Calculate deviation of current crossing count with mean of previous crossings
  387. dDeviation = dMeanPrevCrossings - iCrossingCount;
  388. ////qDebug() << "__________________LOCAL + GLOBAL__________________________";
  389. //If current deviation is zero means the
  390. //saturation state is achieved then stop
  391. if(dDeviation == 0 && dPrevDeviation == 0 )
  392. {
  393. ////qDebug() << ">>> Stopping Global Crossing at saturation <<<";
  394. ////qDebug() << iCrossingCount <<" Mean: "<< dMeanPrevCrossings<< " Deviation: " << dDeviation;
  395. break;
  396. }
  397. if(dDeviation == dPrevDeviation)
  398. {
  399. ////qDebug() << ">>> Stopping Global Crossing at saturation <<<";
  400. ////qDebug() << iCrossingCount <<" Mean: "<< dMeanPrevCrossings<< " Deviation: " << dDeviation;
  401. break;
  402. }
  403. //store crossing
  404. cbPrevCrossingCounts.push_back(iCrossingCount);
  405. dPrevDeviation = dDeviation;
  406. qDebug() << "applyHierarchicalLayout() iCrossingCount=" << iCrossingCount <<" Mean: "<< dMeanPrevCrossings<< " Deviation: " << dDeviation ;
  407. }
  408. }
  409. catch(boost::exception &eBoostException)
  410. {
  411. throw *boost::get_error_info<errmsg_info>(eBoostException);
  412. }
  413. catch(LayoutException &eLayoutException)
  414. {
  415. throw eLayoutException;
  416. }
  417. // XXX obselete
  418. // catch(LayoutMemoryException &eMemoryException)
  419. // {
  420. // throw eMemoryException;
  421. // }
  422. catch(...)
  423. {
  424. throw;
  425. }
  426. try
  427. {
  428. iTotalTime += tProcessTimer.elapsed();
  429. sTimeDetails.append(",");//Add comma for CSV.
  430. sTimeDetails.append(QString::number(tProcessTimer.elapsed()));
  431. bIsLayeredGraphCorrect = testLayeredGraph();
  432. LAYOUT_ASSERT(bIsLayeredGraphCorrect == true
  433. , LayoutException(__FUNCTION__
  434. ,LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  435. ,"after crossing reduction"
  436. ,"Layered graph"));
  437. //Add vertical border nodes for every subgraph
  438. addVerticalBorderNodesForSubgraphs();
  439. bIsLayeredGraphCorrect = testNestingTree();
  440. LAYOUT_ASSERT(bIsLayeredGraphCorrect, LayoutException(__FUNCTION__
  441. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  442. , "NestingTree"
  443. , "in Layouting"));
  444. bIsLayeredGraphCorrect = testLayeredGraph();
  445. LAYOUT_ASSERT(bIsLayeredGraphCorrect, LayoutException(__FUNCTION__
  446. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  447. , "Layered Graph"
  448. , "in Layouting"));
  449. //Posititioning of nodes and edges- straighten out long edges as far as possible
  450. tProcessTimer.restart();
  451. setHorizontalPosition2();
  452. //applyXCoordinatesFromHorizontalPosition(80);
  453. iTotalTime += tProcessTimer.elapsed();
  454. sTimeDetails.append(",");//Add comma for CSV.
  455. sTimeDetails.append(QString::number(tProcessTimer.elapsed()));
  456. //Set Temporary Coordinates for lay outing of intermidiete stages of Layout Processs
  457. assignYCoordinates(gGraph);
  458. //Set compartment properties
  459. setSubgraphCompartmentProperties();
  460. //Find total crossings
  461. int iTotalCrossings = 0;
  462. iTotalCrossings = getTotalCrossings();
  463. qDebug() << "applyHierarchicalLayout() Total Crossings=" << QString::number(iTotalCrossings);
  464. m_iFinalCrossings = iTotalCrossings;
  465. sTimeDetails.append(",");//Add comma for CSV.
  466. sTimeDetails.append(QString::number(iTotalCrossings));
  467. sTimeDetails.append(",");//Add comma for CSV.
  468. sTimeDetails.append(QString::number(iTotalTime));
  469. ////qDebug() << sTimeDetails;
  470. if(WRITE_TIME_DETAILS_LOG)
  471. {
  472. writeLog(sTimeDetails);
  473. }
  474. qDebug() << "applyHierarchicalLayout() shiftVertexCoordinateToLeftTop()";
  475. //Shift to vertices center coordinate to left top
  476. shiftVertexCoordinateToLeftTop();
  477. //Restor revrsed and Long edges with bends
  478. restoreReversedAndLongEdgesWithBendPoints();
  479. qDebug() << "applyHierarchicalLayout() end";
  480. }
  481. catch(boost::exception &eBoostException)
  482. {
  483. throw *boost::get_error_info<errmsg_info>(eBoostException);
  484. }
  485. catch(LayoutException &eLayoutException)
  486. {
  487. throw eLayoutException;
  488. }
  489. // XXX obselete
  490. // catch(LayoutMemoryException &eMemoryException)
  491. // {
  492. // throw eMemoryException;
  493. // }
  494. catch(...)
  495. {
  496. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  497. }
  498. }
  499. void HierarchicalLayouter::setExecutionLogFileName(QString sFileName)
  500. {
  501. LAYOUT_ASSERT(sFileName.isEmpty() == false , LayoutException(__FUNCTION__
  502. , LayoutExceptionEnum::EMPTY_CONTAINER
  503. , "Setting Execution Log file name"
  504. , "Execution Log file name is empty"));
  505. m_sExecutionLogFileName = sFileName;
  506. }
  507. int HierarchicalLayouter::getGraphNestingDepth(SubGraph &gGraph)
  508. {
  509. int iDepth = 0;
  510. int iMaxChildrenDepth = 0; // returns number of clusters (may be :P)
  511. int iChildDepth = 0;
  512. int iChildCount = 0;
  513. ChildrenIterator iterChild , iterChildEnd;
  514. for(boost::tie(iterChild , iterChildEnd) = gGraph.children();
  515. iterChild != iterChildEnd;
  516. iterChild++)
  517. {
  518. ++iChildCount;
  519. iChildDepth = getGraphNestingDepth(*iterChild);
  520. if(iMaxChildrenDepth < iChildDepth)
  521. {
  522. iMaxChildrenDepth = iChildDepth;
  523. }
  524. }
  525. if(iChildCount > 0)
  526. {
  527. iDepth += iMaxChildrenDepth + 1;
  528. }
  529. return iDepth;
  530. }
  531. void HierarchicalLayouter::createNestingGraph(SubGraph &gGraph)
  532. {
  533. //First create UpperBorder Vertex then LowerBorder Vertex
  534. //so the index difference is 1 between border vertices of same graph
  535. //This will help to find UpperBorderVertex from LowerBorderVertex of same graph
  536. //UpperBorderVertex = LowerBorderVertex - 1 and vice versa
  537. VertexDescriptor vUpperBorder;
  538. VertexDescriptor vLowerBorder;
  539. try
  540. {
  541. addNestingToChildByRecur(gGraph , vUpperBorder , vLowerBorder);
  542. }
  543. catch(boost::exception& eBoostException)
  544. {
  545. throw *boost::get_error_info<errmsg_info>(eBoostException);
  546. }
  547. catch(LayoutException &eLayoutException)
  548. {
  549. throw eLayoutException;
  550. }
  551. // XXX obselete
  552. // catch(LayoutMemoryException &eMemoryException)
  553. // {
  554. // throw eMemoryException;
  555. // }
  556. catch(...)
  557. {
  558. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  559. }
  560. }
  561. void HierarchicalLayouter::addNestingToChildByRecur(SubGraph &gGraph, VertexDescriptor &vUpperBorder, VertexDescriptor &vLowerBorder)
  562. {
  563. BoostGraphWrapper graphWrapper;
  564. GraphCycleHandler cycleHandler;
  565. bool bIsEdgeCreateCycle;
  566. SubGraph& gRootGraph = gGraph.root();
  567. //Create upper lower border nodes
  568. //First create UpperBorder Vertex then LowerBorder Vertex
  569. //so the index difference is 1 between border vertices of same graph
  570. //This will help to find UpperBorderVertex from LowerBorderVertex of same graph
  571. //UpperBorderVertex = LowerBorderVertex - 1 and vice versa
  572. VertexDescriptor vCurrentUpperBorderVertex = graphWrapper.addVertex(gGraph , LayoutEnum::UpperBorderNode);
  573. VertexDescriptor vCurrentLowerBorderVertex = graphWrapper.addVertex(gGraph , LayoutEnum::LowerBorderNode);
  574. vUpperBorder = vCurrentUpperBorderVertex;
  575. vLowerBorder = vCurrentLowerBorderVertex;
  576. VertexDescriptor vGlobalCurrentUpperBorder = gGraph.local_to_global(vCurrentUpperBorderVertex);
  577. VertexDescriptor vGlobalCurrentLowerBorder = gGraph.local_to_global(vCurrentLowerBorderVertex);
  578. //Testing 42314-1 //For empty graph
  579. //Add edge between upper to lower border vertex
  580. int iTotalVertices = num_vertices(gGraph);
  581. if(iTotalVertices == 2)
  582. {
  583. graphWrapper.addEdge(vGlobalCurrentUpperBorder , vGlobalCurrentLowerBorder , gRootGraph , LayoutEnum::NestingEdge);
  584. }
  585. VertexDescriptor vChildGraphUpperBorder , vChildGraphLowerBorder;
  586. //Recursive call
  587. ChildrenIterator iterChildGraph , iterEndChildGraph;
  588. for(boost::tie(iterChildGraph , iterEndChildGraph) = gGraph.children();
  589. iterChildGraph != iterEndChildGraph;
  590. iterChildGraph++)
  591. {
  592. try
  593. {
  594. addNestingToChildByRecur(*iterChildGraph , vChildGraphUpperBorder , vChildGraphLowerBorder);
  595. }
  596. catch(boost::exception& eBoostException)
  597. {
  598. throw *boost::get_error_info<errmsg_info>(eBoostException);
  599. }
  600. catch(...)
  601. {
  602. //throw LayoutException( __FUNCTION__ , ExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  603. throw;
  604. }
  605. VertexDescriptor vGlobalChildUpperBorder = (*iterChildGraph).local_to_global(vChildGraphUpperBorder);
  606. VertexDescriptor vGlobalChildLowerBorder = (*iterChildGraph).local_to_global(vChildGraphLowerBorder);
  607. try
  608. {
  609. bIsEdgeCreateCycle = cycleHandler.doesEdgeCreateCycle(vGlobalCurrentUpperBorder ,
  610. vGlobalChildUpperBorder ,
  611. gRootGraph);
  612. }
  613. catch(boost::exception& eBoostException)
  614. {
  615. throw *boost::get_error_info<errmsg_info>(eBoostException);
  616. }
  617. catch(...)
  618. {
  619. //throw LayoutException( __FUNCTION__ , ExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  620. throw;
  621. }
  622. if(bIsEdgeCreateCycle == false)
  623. {
  624. //Add nesting edge from current graphs upper border to its child graph's upper border
  625. graphWrapper.addEdge(vGlobalCurrentUpperBorder , vGlobalChildUpperBorder , gRootGraph , LayoutEnum::NestingEdge);
  626. }
  627. try
  628. {
  629. bIsEdgeCreateCycle = cycleHandler.doesEdgeCreateCycle(vGlobalChildLowerBorder ,
  630. vGlobalCurrentLowerBorder ,
  631. gRootGraph);
  632. }
  633. catch(boost::exception& eBoostException)
  634. {
  635. throw *boost::get_error_info<errmsg_info>(eBoostException);
  636. }
  637. catch(...)
  638. {
  639. //throw LayoutException( __FUNCTION__ , ExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  640. throw;
  641. }
  642. if(bIsEdgeCreateCycle == false)
  643. {
  644. try
  645. {
  646. //Add nesting edge from child graph's lower border to current graph's lower border
  647. graphWrapper.addEdge(vGlobalChildLowerBorder , vGlobalCurrentLowerBorder ,gRootGraph , LayoutEnum::NestingEdge);
  648. }
  649. catch(boost::exception& eBoostException)
  650. {
  651. throw *boost::get_error_info<errmsg_info>(eBoostException);
  652. }
  653. catch(...)
  654. {
  655. //throw LayoutException( __FUNCTION__ , ExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  656. throw;
  657. }
  658. }
  659. }
  660. //add nesting edges
  661. IteratorQVectorUInt iterOwnVertex , iterOwnVertexEnd;
  662. //cout<<endl<<(graphWrapper.getGraphId(gGraph)).toStdString()<<endl;
  663. for(boost::tie(iterOwnVertex , iterOwnVertexEnd) = graphWrapper.ownVerticesIter(gGraph);
  664. iterOwnVertex != iterOwnVertexEnd;
  665. iterOwnVertex++)
  666. {
  667. VertexDescriptor vCurrentVertex = *iterOwnVertex;
  668. try
  669. {
  670. if(graphWrapper.getVertexType( vCurrentVertex , gGraph) == LayoutEnum::GraphNode)
  671. {
  672. //cout<<*iterOwnVertex<<"--";
  673. //cout<<gGraph.local_to_global(vCurrentVertex)<<endl;
  674. //check if any new nesting edge should not create cycle
  675. //Add nesting edges from upper and lower border nodes to own vertices
  676. //Nesting edge from gGraphs UpperBorder vertex to own vertex
  677. bIsEdgeCreateCycle = cycleHandler.doesEdgeCreateCycle(vCurrentUpperBorderVertex ,
  678. vCurrentVertex ,
  679. gGraph);
  680. if(bIsEdgeCreateCycle == false)
  681. {
  682. try
  683. {
  684. //Add nesting edge from current graphs upper border to its child graph's upper border
  685. graphWrapper.addEdge(vCurrentUpperBorderVertex , vCurrentVertex , gGraph , LayoutEnum::NestingEdge);
  686. }
  687. //TODO: catch enum exception
  688. catch(boost::exception& eBoostException)
  689. {
  690. throw *boost::get_error_info<errmsg_info>(eBoostException);
  691. }
  692. catch(...)
  693. {
  694. //throw LayoutException( __FUNCTION__ , ExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  695. throw;
  696. }
  697. }
  698. try
  699. {
  700. //Nesting edge from gGraphs LowerBorder vertex to own vertex
  701. bIsEdgeCreateCycle = cycleHandler.doesEdgeCreateCycle(vCurrentVertex ,
  702. vCurrentLowerBorderVertex ,
  703. gGraph);
  704. }
  705. catch(boost::exception& eBoostException)
  706. {
  707. throw *boost::get_error_info<errmsg_info>(eBoostException);
  708. }
  709. catch(...)
  710. {
  711. //throw LayoutException( __FUNCTION__ , ExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  712. throw;
  713. }
  714. if(bIsEdgeCreateCycle == false)
  715. {
  716. try
  717. {
  718. //Add nesting edge from own vertex to its lower border node
  719. graphWrapper.addEdge(vCurrentVertex , vCurrentLowerBorderVertex, gGraph , LayoutEnum::NestingEdge);
  720. }
  721. catch(boost::exception& eBoostException)
  722. {
  723. throw *boost::get_error_info<errmsg_info>(eBoostException);
  724. }
  725. catch(...)
  726. {
  727. //throw LayoutException( __FUNCTION__ , ExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  728. throw;
  729. }
  730. }
  731. }
  732. }
  733. catch(boost::exception& eBoostException)
  734. {
  735. throw *boost::get_error_info<errmsg_info>(eBoostException);
  736. }
  737. catch(...)
  738. {
  739. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  740. }
  741. }
  742. }
  743. void HierarchicalLayouter::assignVertexRanks(SubGraph &gGraph, VertexDescriptor vRootVertex)
  744. {
  745. //Validate gGraph
  746. //Assert Nesting Depth is calculated
  747. //Q_ASSERT_X(m_iNestingDepth.isSet() , "Assigning Ranks" , "Graphs Nesting Depth is not set");
  748. LAYOUT_ASSERT(m_iNestingDepth.isSet(),LayoutException(__FUNCTION__ , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET , "NestingGraphDepth" ));
  749. //Traverse graph in topological order
  750. //Rank = max(Rank(predecessors)} + 1
  751. try
  752. {
  753. int iRankLevelDifference = 2 * m_iNestingDepth + 1;
  754. QQueue<VertexDescriptor> qRankedVertices;
  755. //Create Map of Vertex to Rank property - int iRank
  756. PGL_MAP_VERTEX_BUNDLED_PROPERTY(mapVertexRank , int , iRank , gGraph);
  757. //Assign rank to root node
  758. //m_BoostGraphWrapper.setVertexRank(vRootVertex , gGraph , 1);
  759. mapVertexRank[vRootVertex] = 1;
  760. //Add root vertex to RankedVertices Queue
  761. qRankedVertices.enqueue(vRootVertex);
  762. //Create external map for keeping each vertex in edges visit count
  763. std::size_t iTotalVertices = num_vertices(gGraph);
  764. std::vector<int> vecVertexInEdgeVisitedCount(iTotalVertices);
  765. std::fill(vecVertexInEdgeVisitedCount.begin() , vecVertexInEdgeVisitedCount.end() , 0);
  766. VertexDescriptor vCurrentVertex;
  767. VertexDescriptor vCurrentOutVertex;
  768. EdgeDescriptor eCurrentEdge;
  769. std::size_t iInEdgeCount;
  770. while(qRankedVertices.empty() == false)
  771. {
  772. //Deque the ranked vertex
  773. vCurrentVertex = qRankedVertices.dequeue();
  774. //Iterate out(child) vertices
  775. OutEdgeIterator iterOutEdge , iterOutEdgeEnd;
  776. for(boost::tie(iterOutEdge , iterOutEdgeEnd) = out_edges(vCurrentVertex , gGraph);
  777. iterOutEdge != iterOutEdgeEnd;
  778. iterOutEdge++)
  779. {
  780. eCurrentEdge = *iterOutEdge;
  781. //Get OutVertex
  782. vCurrentOutVertex = m_BoostGraphWrapper.getEdgeTarget(eCurrentEdge,
  783. gGraph);
  784. //Increase OutVertex's inEdgeVisited Count
  785. vecVertexInEdgeVisitedCount[vCurrentOutVertex] += 1;
  786. iInEdgeCount = vecVertexInEdgeVisitedCount[vCurrentOutVertex];
  787. //check if all InEdges of CurrentOutVertex are visited
  788. if(iInEdgeCount == in_degree(vCurrentOutVertex , gGraph))
  789. {
  790. //Assign Rank to current OutVertex
  791. InEdgeIterator iterOutVertexInEdge , iterOutVertexInEdgeEnd;
  792. int iMaxPredecessorRank = 0;
  793. int iPredecessorVertexRank = 0;
  794. int iRank = 0;
  795. VertexDescriptor vPredecessor;
  796. //Checking ranks of predecesor vertices
  797. for(boost::tie(iterOutVertexInEdge , iterOutVertexInEdgeEnd) = in_edges(vCurrentOutVertex , gGraph);
  798. iterOutVertexInEdge != iterOutVertexInEdgeEnd;
  799. iterOutVertexInEdge++)
  800. {
  801. vPredecessor = m_BoostGraphWrapper.getEdgeSource(*iterOutVertexInEdge , gGraph);
  802. //iPredecessorVertexRank = m_BoostGraphWrapper.getVertexRank(vPredecessor , gGraph);
  803. iPredecessorVertexRank = mapVertexRank[vPredecessor];
  804. if(iMaxPredecessorRank < iPredecessorVertexRank)
  805. {
  806. iMaxPredecessorRank = iPredecessorVertexRank;
  807. }
  808. }
  809. //Rank of vertex is greater than maximum rank of its predecessors
  810. //iRank += 1;
  811. LayoutEnum::NodeType enCurrentVertexType;
  812. enCurrentVertexType = m_BoostGraphWrapper.getVertexType(vCurrentOutVertex , gGraph);
  813. if(enCurrentVertexType == LayoutEnum::GraphNode)
  814. {
  815. //For GraphNode
  816. //Assign Rank in multiple of 2K+1 (where K- Nesting Depth of Graph)
  817. //iRank = (iMaxPredecessorRank + iRankLevelDifference); //Commented for 42314-3
  818. //iRank = (iMaxPredecessorRank + (iRankLevelDifference * 2));//Added for 42314-3
  819. iRank = (iMaxPredecessorRank + iRankLevelDifference); // 42414-4
  820. //42414-4
  821. int iMaxOutDegreeOfPredecessors = INT_MIN;
  822. BGL_FORALL_INEDGES(vCurrentOutVertex , eInEdge , *m_gMainGraph , SubGraph)
  823. {
  824. VertexDescriptor vVertex = source(eInEdge , *m_gMainGraph);
  825. int iPredOutDegree = out_degree(vVertex , *m_gMainGraph);
  826. LayoutEnum::NodeType enPredecessorVertexType;
  827. enPredecessorVertexType = m_BoostGraphWrapper.getVertexType(vVertex , *m_gMainGraph);
  828. if(enPredecessorVertexType == LayoutEnum::UpperBorderNode)
  829. {
  830. iPredOutDegree = 0;
  831. }
  832. iMaxOutDegreeOfPredecessors = (iMaxOutDegreeOfPredecessors < iPredOutDegree) ? iPredOutDegree : iMaxOutDegreeOfPredecessors;
  833. }
  834. //Add rank two level below actual for vertices having parent with more than 5 out degree
  835. //that will make space for dummy vertices to be added
  836. //*This threshold we add makes a lot of difference in crossing reduction and straightness of edges
  837. //number 5 is found to work well for many graphs (inflamation etc.)
  838. if( iMaxOutDegreeOfPredecessors > 5)
  839. {
  840. iRank += (iRankLevelDifference*2);
  841. }
  842. iRank -= (iRank % iRankLevelDifference);
  843. }
  844. else
  845. {
  846. //For Upper and Lower border vertex
  847. iRank = iMaxPredecessorRank + 1;
  848. }
  849. //cout<<"Rank Vertex: "<<vCurrentOutVertex<<" = "<<iRank<<endl;
  850. //m_BoostGraphWrapper.setVertexRank(vCurrentOutVertex , gGraph , iRank);
  851. mapVertexRank[vCurrentOutVertex] = iRank;
  852. //Adjust UpperBorder Vertices rank value
  853. //Rank(UpperBorderVertex) = MinRank{Successors(UpperBorderVertex)} - 1
  854. if(enCurrentVertexType == LayoutEnum::LowerBorderNode) //51514-1 commented for - little ranking change
  855. {
  856. int iSuccessorRank = 0;
  857. int iMinSuccessorRank = INT_MAX;
  858. //UpperBorderVertex and LowerBorderVertex are added in sequence do if
  859. //their index are contiguous, ther for index of UpperBorderVertex = LowerBorderVertex -1
  860. VertexDescriptor vUpperBorderVertex = vCurrentOutVertex - 1;
  861. // Q_ASSERT_X((m_BoostGraphWrapper.getVertexType(vUpperBorderVertex , gGraph) == Enum::UpperBorderNode),
  862. // "Adjusting Upper Border Vertex Rank",
  863. // "Wrong UpperBorder Vertex found from lower border vertex");
  864. LAYOUT_ASSERT((m_BoostGraphWrapper.getVertexType(vUpperBorderVertex , gGraph) == LayoutEnum::UpperBorderNode),
  865. LayoutException(__FUNCTION__ , LayoutExceptionEnum::INVALID_OPERATION
  866. , "Wrong UpperBorder Vertex found from lower border vertex"
  867. , "Adjusting Upper Border Vertex Rank"));
  868. //Rank(UpperBorderVertex) = MinRank{Successors(UpperBorderVertex)} - 1
  869. AdjacencyIterator iterOutVertices , iterOutVerticesEnd;
  870. for(boost::tie(iterOutVertices , iterOutVerticesEnd)
  871. = adjacent_vertices(vUpperBorderVertex , gGraph);
  872. iterOutVertices != iterOutVerticesEnd;
  873. iterOutVertices++)
  874. {
  875. VertexDescriptor vUpperBorderSucessor = *iterOutVertices;
  876. //iSuccessorRank = m_BoostGraphWrapper.getVertexRank(vUpperBorderSucessor , gGraph);
  877. iSuccessorRank = mapVertexRank[vUpperBorderSucessor];
  878. if(iMinSuccessorRank > iSuccessorRank)
  879. {
  880. //Min{Successors(UpperBorderVertex)}
  881. iMinSuccessorRank = iSuccessorRank;
  882. }
  883. }
  884. //MinRank{Successors(UpperBorderVertex)} - 1
  885. --iMinSuccessorRank;
  886. //m_BoostGraphWrapper.setVertexRank(vUpperBorderVertex , gGraph , iMinSuccessorRank);
  887. mapVertexRank[vUpperBorderVertex] = iMinSuccessorRank;
  888. }
  889. //Add current OutVertex to RankedVertices
  890. qRankedVertices.enqueue(vCurrentOutVertex);
  891. }
  892. }
  893. }
  894. }
  895. catch(boost::exception &eBoostException)
  896. {
  897. throw *boost::get_error_info<errmsg_info>(eBoostException);
  898. }
  899. catch(LayoutException &eLayoutException)
  900. {
  901. throw eLayoutException;
  902. }
  903. // XXX obselete
  904. // catch(LayoutMemoryException &eMemoryException)
  905. // {
  906. // throw eMemoryException;
  907. // }
  908. catch(...)
  909. {
  910. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  911. }
  912. }
  913. void HierarchicalLayouter::adjustVertexRanks(SubGraph &gGraph)
  914. {
  915. //Validate gGraph
  916. //Assert Nesting Depth is calculated
  917. //Q_ASSERT_X(m_iNestingDepth.isSet() , "Adjusting Ranks" , "Graphs Nesting Depth is not set");
  918. LAYOUT_ASSERT(m_iNestingDepth.isSet() == true , LayoutException(__FUNCTION__ , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  919. , "Graph Nesting Depth" , ""));
  920. ////////////////
  921. //Traverse graph in topological order
  922. //Rank = max(Rank(predecessors)} + 1
  923. ConstantType<int> iRankLevelDifference;
  924. iRankLevelDifference = 2 * m_iNestingDepth + 1;
  925. QQueue<VertexDescriptor> qRankedVertices;
  926. //Create Map of Vertex to Rank property - int iRank
  927. PGL_MAP_VERTEX_BUNDLED_PROPERTY(mapVertexRank , int , iRank , gGraph);
  928. VertexDescriptor vConverseRoot = m_BoostGraphWrapper.getGraphLowerBorderVertex(gGraph);
  929. //Add root vertex to RankedVertices Queue
  930. qRankedVertices.enqueue(vConverseRoot);
  931. //Create external map for keeping each vertex in edges visit count
  932. std::size_t iTotalVertices = num_vertices(gGraph);
  933. std::vector<int> vecVertexOutEdgeVisitedCount(iTotalVertices);
  934. std::fill(vecVertexOutEdgeVisitedCount.begin() , vecVertexOutEdgeVisitedCount.end() , 0);
  935. VertexDescriptor vCurrentVertex;
  936. VertexDescriptor vCurrentInVertex;
  937. EdgeDescriptor eCurrentEdge;
  938. std::size_t iOutEdgeCount;
  939. while(qRankedVertices.empty() == false)
  940. {
  941. //Deque the ranked vertex
  942. vCurrentVertex = qRankedVertices.dequeue();
  943. //Iterate in(parent) vertices
  944. InEdgeIterator iterInEdge , iterInEdgeEnd;
  945. for(boost::tie(iterInEdge , iterInEdgeEnd) = in_edges(vCurrentVertex , gGraph);
  946. iterInEdge != iterInEdgeEnd;
  947. iterInEdge++)
  948. {
  949. eCurrentEdge = *iterInEdge;
  950. //Get InVertex
  951. vCurrentInVertex = m_BoostGraphWrapper.getEdgeSource(eCurrentEdge,
  952. gGraph);
  953. //Increase InVertex's OutEdgeVisited Count
  954. vecVertexOutEdgeVisitedCount[vCurrentInVertex] += 1;
  955. iOutEdgeCount = vecVertexOutEdgeVisitedCount[vCurrentInVertex];
  956. //check if all OutEdges of CurrentInVertex are visited
  957. if(iOutEdgeCount == out_degree(vCurrentInVertex , gGraph))
  958. {
  959. //Assign Rank to current InVertex
  960. OutEdgeIterator iterInVertexOutEdge , iterInVertexOutEdgeEnd;
  961. int iMinSuccessorRank = INT_MAX;
  962. int iSuccessorVertexRank = 0;
  963. int iRank = 0;
  964. VertexDescriptor vSuccessor;
  965. //Checking ranks of successor vertices
  966. for(boost::tie(iterInVertexOutEdge , iterInVertexOutEdgeEnd) = out_edges(vCurrentInVertex , gGraph);
  967. iterInVertexOutEdge != iterInVertexOutEdgeEnd;
  968. iterInVertexOutEdge++)
  969. {
  970. vSuccessor = m_BoostGraphWrapper.getEdgeTarget(*iterInVertexOutEdge , gGraph);
  971. //iSuccessorVertexRank = m_BoostGraphWrapper.getVertexRank(vSuccessor , gGraph);
  972. iSuccessorVertexRank =mapVertexRank[vSuccessor];
  973. if(iMinSuccessorRank > iSuccessorVertexRank)
  974. {
  975. iMinSuccessorRank = iSuccessorVertexRank;
  976. }
  977. }
  978. //Rank of vertex is lesser than minimum rank of its successors
  979. //iRank -= 1;
  980. LayoutEnum::NodeType enCurrentVertexType;
  981. enCurrentVertexType = m_BoostGraphWrapper.getVertexType(vCurrentInVertex , gGraph);
  982. if(enCurrentVertexType == LayoutEnum::GraphNode)
  983. {
  984. //For GraphNode
  985. //Assign Rank in multiple of 2K+1 (where K- Nesting Depth of Graph)
  986. iRank = (iMinSuccessorRank - iRankLevelDifference);
  987. iRank -= (iRank % iRankLevelDifference);
  988. }
  989. else if(enCurrentVertexType == LayoutEnum::UpperBorderNode)
  990. {
  991. //For Upper border vertex
  992. iRank = iMinSuccessorRank - 1;
  993. }
  994. //int iVertexRank = m_BoostGraphWrapper.getVertexRank(vCurrentInVertex , gGraph);
  995. int iVertexRank = mapVertexRank[vCurrentInVertex];
  996. if(enCurrentVertexType == LayoutEnum::GraphNode || enCurrentVertexType == LayoutEnum::UpperBorderNode)
  997. {
  998. //Check if vertex's current rank is lesser than new rank
  999. //otherwise this process pushes the lowest node in subgraph
  1000. //upwards from its lower Border vertex and that again pushes
  1001. //subsequent vertices upwards thus creates gap between
  1002. //LowerBorder Vertex and the highest rank vertex in the subgraph
  1003. if(iRank > iVertexRank)
  1004. {
  1005. //cout<<"Rank Vertex: "<<vCurrentInVertex<<" = "<<iRank<<endl;
  1006. //m_BoostGraphWrapper.setVertexRank(vCurrentInVertex , gGraph , iRank);
  1007. mapVertexRank[vCurrentInVertex] = iRank;
  1008. }
  1009. }
  1010. //Add current OutVertex to RankedVertices
  1011. qRankedVertices.enqueue(vCurrentInVertex);
  1012. }
  1013. }
  1014. }
  1015. //Printing ranks:
  1016. //cout<<"Ranks:\n";
  1017. //BGL_FORALL_VERTICES(vertex , gGraph , SubGraph)
  1018. //{
  1019. //print
  1020. //cout<<"V: "<<vertex<<" -- "<<m_BoostGraphWrapper.getVertexRank(vertex , gGraph)<<endl;
  1021. //}
  1022. }
  1023. void HierarchicalLayouter::pullUpVertexRanks(SubGraph &gGraph, VertexDescriptor vRootVertex)
  1024. {
  1025. //Validate gGraph
  1026. //Assert Nesting Depth is calculated
  1027. //Q_ASSERT_X(m_iNestingDepth.isSet() , "Assigning Ranks" , "Graphs Nesting Depth is not set");
  1028. LAYOUT_ASSERT(m_iNestingDepth.isSet() == true , LayoutException(__FUNCTION__ ,
  1029. LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  1030. , "Nesting Depth of Graph" , ""));
  1031. //Traverse graph in topological order
  1032. //Rank = max(Rank(predecessors)} + 1
  1033. int iRankLevelDifference = 2 * m_iNestingDepth + 1;
  1034. QQueue<VertexDescriptor> qRankedVertices;
  1035. //Create Map of Vertex to Rank property - int iRank
  1036. PGL_MAP_VERTEX_BUNDLED_PROPERTY(mapVertexRank , int , iRank , gGraph);
  1037. //Add root vertex to RankedVertices Queue
  1038. qRankedVertices.enqueue(vRootVertex);
  1039. //Create external map for keeping each vertex in edges visit count
  1040. std::size_t iTotalVertices = num_vertices(gGraph);
  1041. std::vector<int> vecVertexInEdgeVisitedCount(iTotalVertices);
  1042. std::fill(vecVertexInEdgeVisitedCount.begin() , vecVertexInEdgeVisitedCount.end() , 0);
  1043. //Vector to correct the pull of vertex
  1044. std::vector<int> vecVertexOldRank(iTotalVertices);
  1045. std::fill(vecVertexOldRank.begin() , vecVertexOldRank.end() , 0);
  1046. VertexDescriptor vCurrentVertex;
  1047. VertexDescriptor vCurrentOutVertex;
  1048. EdgeDescriptor eCurrentEdge;
  1049. std::size_t iInEdgeCount;
  1050. while(qRankedVertices.empty() == false)
  1051. {
  1052. //Deque the ranked vertex
  1053. vCurrentVertex = qRankedVertices.dequeue();
  1054. //Iterate out(child) vertices
  1055. OutEdgeIterator iterOutEdge , iterOutEdgeEnd;
  1056. for(boost::tie(iterOutEdge , iterOutEdgeEnd) = out_edges(vCurrentVertex , gGraph);
  1057. iterOutEdge != iterOutEdgeEnd;
  1058. iterOutEdge++)
  1059. {
  1060. eCurrentEdge = *iterOutEdge;
  1061. //Get OutVertex
  1062. vCurrentOutVertex = m_BoostGraphWrapper.getEdgeTarget(eCurrentEdge,
  1063. gGraph);
  1064. //Increase OutVertex's inEdgeVisited Count
  1065. vecVertexInEdgeVisitedCount[vCurrentOutVertex] += 1;
  1066. iInEdgeCount = vecVertexInEdgeVisitedCount[vCurrentOutVertex];
  1067. //check if all InEdges of CurrentOutVertex are visited
  1068. if(iInEdgeCount == in_degree(vCurrentOutVertex , gGraph))
  1069. {
  1070. //Assign Rank to current OutVertex
  1071. InEdgeIterator iterOutVertexInEdge , iterOutVertexInEdgeEnd;
  1072. int iMaxPredecessorRank = 0;
  1073. int iPredecessorVertexRank = 0;
  1074. int iRank = 0;
  1075. VertexDescriptor vPredecessor;
  1076. //Checking ranks of predecesor vertices
  1077. for(boost::tie(iterOutVertexInEdge , iterOutVertexInEdgeEnd) = in_edges(vCurrentOutVertex , gGraph);
  1078. iterOutVertexInEdge != iterOutVertexInEdgeEnd;
  1079. iterOutVertexInEdge++)
  1080. {
  1081. vPredecessor = m_BoostGraphWrapper.getEdgeSource(*iterOutVertexInEdge , gGraph);
  1082. //iPredecessorVertexRank = m_BoostGraphWrapper.getVertexRank(vPredecessor , gGraph);
  1083. iPredecessorVertexRank = mapVertexRank[vPredecessor];
  1084. if(iMaxPredecessorRank < iPredecessorVertexRank)
  1085. {
  1086. iMaxPredecessorRank = iPredecessorVertexRank;
  1087. }
  1088. }
  1089. //Rank of vertex is greater than maximum rank of its predecessors
  1090. //iRank += 1;
  1091. LayoutEnum::NodeType enCurrentVertexType;
  1092. enCurrentVertexType = m_BoostGraphWrapper.getVertexType(vCurrentOutVertex , gGraph);
  1093. if(enCurrentVertexType == LayoutEnum::GraphNode)
  1094. {
  1095. //For GraphNode
  1096. //Assign Rank in multiple of 2K+1 (where K- Nesting Depth of Graph)
  1097. iRank = (iMaxPredecessorRank + iRankLevelDifference);
  1098. iRank -= (iRank % iRankLevelDifference);
  1099. }
  1100. else
  1101. {
  1102. //For Upper and Lower border vertex
  1103. iRank = iMaxPredecessorRank + 1;
  1104. }
  1105. //Get previous rank value
  1106. int iOldRank = mapVertexRank[vCurrentOutVertex];
  1107. vecVertexOldRank[vCurrentOutVertex] = iOldRank;
  1108. //Update rank to new value only if previous rank value is greater than
  1109. //calculated value, thus it pulls up the position of current node
  1110. if(iRank < iOldRank)
  1111. {
  1112. //Check if the vertex is a leaf vertex, because we need to pull
  1113. //leaf vertex rank as up as possible for non-leaf vertices we chose
  1114. //a rank which is mid point of its old and new rank value
  1115. if(out_degree(vCurrentOutVertex , gGraph) > 1)
  1116. {
  1117. //Current vertex is a non-leaf vertex
  1118. if(enCurrentVertexType == LayoutEnum::GraphNode)
  1119. {
  1120. //Add the half of distance in old and new rank
  1121. iRank += (iOldRank - iRank)/2;
  1122. //Adjust rank
  1123. iRank -= (iRank % iRankLevelDifference);
  1124. }
  1125. }
  1126. mapVertexRank[vCurrentOutVertex] = iRank;
  1127. }
  1128. //Adjust UpperBorder Vertices rank value
  1129. //Rank(UpperBorderVertex) = MinRank{Successors(UpperBorderVertex)} - 1
  1130. if(enCurrentVertexType == LayoutEnum::LowerBorderNode)
  1131. {
  1132. int iSuccessorRank = 0;
  1133. int iMinSuccessorRank = INT_MAX;
  1134. VertexDescriptor vUpperBorderVertex = vCurrentOutVertex - 1;
  1135. // Q_ASSERT_X((m_BoostGraphWrapper.getVertexType(vUpperBorderVertex , gGraph) == Enum::UpperBorderNode),
  1136. // "Adjusting Upper Border Vertex Rank",
  1137. // "Wrong UpperBorder Vertex found from lower border vertex");
  1138. LAYOUT_ASSERT((m_BoostGraphWrapper.getVertexType(vUpperBorderVertex , gGraph) == LayoutEnum::UpperBorderNode),
  1139. LayoutException(__FUNCTION__ , LayoutExceptionEnum::INVALID_OPERATION
  1140. , "Wrong UpperBorder Vertex found from lower border vertex"
  1141. , "Adjusting Upper Border Vertex Rank"));
  1142. //Rank(UpperBorderVertex) = MinRank{Successors(UpperBorderVertex)} - 1
  1143. AdjacencyIterator iterOutVertices , iterOutVerticesEnd;
  1144. for(boost::tie(iterOutVertices , iterOutVerticesEnd)
  1145. = adjacent_vertices(vUpperBorderVertex , gGraph);
  1146. iterOutVertices != iterOutVerticesEnd;
  1147. iterOutVertices++)
  1148. {
  1149. VertexDescriptor vUpperBorderSucessor = *iterOutVertices;
  1150. //iSuccessorRank = m_BoostGraphWrapper.getVertexRank(vUpperBorderSucessor , gGraph);
  1151. iSuccessorRank = mapVertexRank[vUpperBorderSucessor];
  1152. if(iMinSuccessorRank > iSuccessorRank)
  1153. {
  1154. //Min{Successors(UpperBorderVertex)}
  1155. iMinSuccessorRank = iSuccessorRank;
  1156. }
  1157. }
  1158. //MinRank{Successors(UpperBorderVertex)} - 1
  1159. --iMinSuccessorRank;
  1160. //m_BoostGraphWrapper.setVertexRank(vUpperBorderVertex , gGraph , iMinSuccessorRank);
  1161. mapVertexRank[vUpperBorderVertex] = iMinSuccessorRank;
  1162. }
  1163. //Add current OutVertex to RankedVertices
  1164. qRankedVertices.enqueue(vCurrentOutVertex);
  1165. }
  1166. }
  1167. }
  1168. }
  1169. void HierarchicalLayouter::pullAndSpreadUpVertexRanks(SubGraph &gGraph, VertexDescriptor vRootVertex)
  1170. {
  1171. //Testing 42314-4
  1172. //Validate gGraph
  1173. //Assert Nesting Depth is calculated
  1174. Q_ASSERT_X(m_iNestingDepth.isSet() , "Assigning Ranks" , "Graphs Nesting Depth is not set");
  1175. //Traverse graph in topological order
  1176. //Rank = max(Rank(predecessors)} + 1
  1177. int iRankLevelDifference = 2 * m_iNestingDepth + 1;
  1178. QQueue<VertexDescriptor> qRankedVertices;
  1179. //Create Map of Vertex to Rank property - int iRank
  1180. PGL_MAP_VERTEX_BUNDLED_PROPERTY(mapVertexRank , int , iRank , gGraph);
  1181. //Add root vertex to RankedVertices Queue
  1182. qRankedVertices.enqueue(vRootVertex);
  1183. //Create external map for keeping each vertex in edges visit count
  1184. std::size_t iTotalVertices = num_vertices(gGraph);
  1185. std::vector<int> vecVertexInEdgeVisitedCount(iTotalVertices);
  1186. std::fill(vecVertexInEdgeVisitedCount.begin() , vecVertexInEdgeVisitedCount.end() , 0);
  1187. //Vector to correct the pull of vertex
  1188. std::vector<int> vecVertexOldRank(iTotalVertices);
  1189. std::fill(vecVertexOldRank.begin() , vecVertexOldRank.end() , 0);
  1190. VertexDescriptor vCurrentVertex;
  1191. VertexDescriptor vCurrentOutVertex;
  1192. EdgeDescriptor eCurrentEdge;
  1193. std::size_t iInEdgeCount;
  1194. while(qRankedVertices.empty() == false)
  1195. {
  1196. //Deque the ranked vertex
  1197. vCurrentVertex = qRankedVertices.dequeue();
  1198. //Iterate out(child) vertices
  1199. OutEdgeIterator iterOutEdge , iterOutEdgeEnd;
  1200. for(boost::tie(iterOutEdge , iterOutEdgeEnd) = out_edges(vCurrentVertex , gGraph);
  1201. iterOutEdge != iterOutEdgeEnd;
  1202. iterOutEdge++)
  1203. {
  1204. eCurrentEdge = *iterOutEdge;
  1205. //Get OutVertex
  1206. vCurrentOutVertex = m_BoostGraphWrapper.getEdgeTarget(eCurrentEdge,
  1207. gGraph);
  1208. //Increase OutVertex's inEdgeVisited Count
  1209. vecVertexInEdgeVisitedCount[vCurrentOutVertex] += 1;
  1210. iInEdgeCount = vecVertexInEdgeVisitedCount[vCurrentOutVertex];
  1211. //check if all InEdges of CurrentOutVertex are visited
  1212. if(iInEdgeCount == in_degree(vCurrentOutVertex , gGraph))
  1213. {
  1214. //Assign Rank to current OutVertex
  1215. InEdgeIterator iterOutVertexInEdge , iterOutVertexInEdgeEnd;
  1216. int iMaxPredecessorRank = 0;
  1217. int iPredecessorVertexRank = 0;
  1218. int iRank = 0;
  1219. VertexDescriptor vPredecessor;
  1220. //Checking ranks of predecesor vertices
  1221. for(boost::tie(iterOutVertexInEdge , iterOutVertexInEdgeEnd) = in_edges(vCurrentOutVertex , gGraph);
  1222. iterOutVertexInEdge != iterOutVertexInEdgeEnd;
  1223. iterOutVertexInEdge++)
  1224. {
  1225. vPredecessor = m_BoostGraphWrapper.getEdgeSource(*iterOutVertexInEdge , gGraph);
  1226. //iPredecessorVertexRank = m_BoostGraphWrapper.getVertexRank(vPredecessor , gGraph);
  1227. iPredecessorVertexRank = mapVertexRank[vPredecessor];
  1228. if(iMaxPredecessorRank < iPredecessorVertexRank)
  1229. {
  1230. iMaxPredecessorRank = iPredecessorVertexRank;
  1231. }
  1232. }
  1233. //Rank of vertex is greater than maximum rank of its predecessors
  1234. //iRank += 1;
  1235. LayoutEnum::NodeType enCurrentVertexType;
  1236. enCurrentVertexType = m_BoostGraphWrapper.getVertexType(vCurrentOutVertex , gGraph);
  1237. if(enCurrentVertexType == LayoutEnum::GraphNode)
  1238. {
  1239. //For GraphNode
  1240. //Assign Rank in multiple of 2K+1 (where K- Nesting Depth of Graph)
  1241. //iRank = (iMaxPredecessorRank + iRankLevelDifference);
  1242. iRank = (iMaxPredecessorRank + iRankLevelDifference*2);
  1243. iRank -= (iRank % iRankLevelDifference);
  1244. }
  1245. else
  1246. {
  1247. //For Upper and Lower border vertex
  1248. iRank = iMaxPredecessorRank + 1;
  1249. }
  1250. //Get previous rank value
  1251. int iOldRank = mapVertexRank[vCurrentOutVertex];
  1252. vecVertexOldRank[vCurrentOutVertex] = iOldRank;
  1253. //Update rank to new value only if previous rank value is greater than
  1254. //calculated value, thus it pulls up the position of current node
  1255. // if(iRank < iOldRank)
  1256. // {
  1257. // //Check if the vertex is a leaf vertex, because we need to pull
  1258. // //leaf vertex rank as up as possible for non-leaf vertices we chose
  1259. // //a rank which is mid point of its old and new rank value
  1260. // if(out_degree(vCurrentOutVertex , gGraph) > 1)
  1261. // {
  1262. // //Current vertex is a non-leaf vertex
  1263. // if(enCurrentVertexType == Enum::GraphNode)
  1264. // {
  1265. // //Add the half of distance in old and new rank
  1266. // iRank += (iOldRank - iRank)/2;
  1267. // //Adjust rank
  1268. // iRank -= (iRank % iRankLevelDifference);
  1269. // }
  1270. // }
  1271. // mapVertexRank[vCurrentOutVertex] = iRank;
  1272. // }
  1273. mapVertexRank[vCurrentOutVertex] = iRank;
  1274. //Adjust UpperBorder Vertices rank value
  1275. //Rank(UpperBorderVertex) = MinRank{Successors(UpperBorderVertex)} - 1
  1276. if(enCurrentVertexType == LayoutEnum::LowerBorderNode)
  1277. {
  1278. int iSuccessorRank = 0;
  1279. int iMinSuccessorRank = INT_MAX;
  1280. VertexDescriptor vUpperBorderVertex = vCurrentOutVertex - 1;
  1281. Q_ASSERT_X((m_BoostGraphWrapper.getVertexType(vUpperBorderVertex , gGraph) == LayoutEnum::UpperBorderNode),
  1282. "Adjusting Upper Border Vertex Rank",
  1283. "Wrong UpperBorder Vertex found from lower border vertex");
  1284. //Rank(UpperBorderVertex) = MinRank{Successors(UpperBorderVertex)} - 1
  1285. AdjacencyIterator iterOutVertices , iterOutVerticesEnd;
  1286. for(boost::tie(iterOutVertices , iterOutVerticesEnd)
  1287. = adjacent_vertices(vUpperBorderVertex , gGraph);
  1288. iterOutVertices != iterOutVerticesEnd;
  1289. iterOutVertices++)
  1290. {
  1291. VertexDescriptor vUpperBorderSucessor = *iterOutVertices;
  1292. //iSuccessorRank = m_BoostGraphWrapper.getVertexRank(vUpperBorderSucessor , gGraph);
  1293. iSuccessorRank = mapVertexRank[vUpperBorderSucessor];
  1294. if(iMinSuccessorRank > iSuccessorRank)
  1295. {
  1296. //Min{Successors(UpperBorderVertex)}
  1297. iMinSuccessorRank = iSuccessorRank;
  1298. }
  1299. }
  1300. //MinRank{Successors(UpperBorderVertex)} - 1
  1301. --iMinSuccessorRank;
  1302. //m_BoostGraphWrapper.setVertexRank(vUpperBorderVertex , gGraph , iMinSuccessorRank);
  1303. mapVertexRank[vUpperBorderVertex] = iMinSuccessorRank;
  1304. }
  1305. //Add current OutVertex to RankedVertices
  1306. qRankedVertices.enqueue(vCurrentOutVertex);
  1307. }
  1308. }
  1309. }
  1310. //Printing ranks:
  1311. //cout<<"Ranks:\n";
  1312. BGL_FORALL_VERTICES(vertex , gGraph , SubGraph)
  1313. {
  1314. //Adjust vertex rank pull
  1315. int iOldRank = vecVertexOldRank[vertex];
  1316. LayoutEnum::NodeType enVertexType = m_BoostGraphWrapper.getVertexType(vertex , gGraph);
  1317. int iRank = mapVertexRank[vertex];
  1318. //if(iRank < iOldRank)
  1319. {
  1320. if(enVertexType == LayoutEnum::GraphNode)
  1321. {
  1322. //Check if the vertex is a leaf vertex, because we need to pull
  1323. //leaf vertex rank as up as possible for non-leaf vertices we chose
  1324. //a rank which is mid point of its old and new rank value
  1325. //if(out_degree(vertex , gGraph) > 1)
  1326. {
  1327. //Current vertex is a non-leaf vertex
  1328. //if(enVertexType == Enum::GraphNode)
  1329. {
  1330. //Add the half of distance between old and new rank into new rank
  1331. iRank = (iOldRank + iRank)/2;
  1332. //Adjust rank
  1333. iRank -= (iRank % iRankLevelDifference);
  1334. }
  1335. }
  1336. mapVertexRank[vertex] = iRank;
  1337. }
  1338. }
  1339. }
  1340. }
  1341. void HierarchicalLayouter::recordUniqueRankAndSort()
  1342. {
  1343. QSet<int> uniqueRanks;
  1344. BGL_FORALL_VERTICES(vVertex , *m_gMainGraph , SubGraph)
  1345. {
  1346. int iRank = m_BoostGraphWrapper.getVertexRank(vVertex , *m_gMainGraph);
  1347. if(uniqueRanks.contains(iRank) == false)
  1348. {
  1349. uniqueRanks.insert(iRank);
  1350. m_vecSortedRanks.push_back(iRank);
  1351. }
  1352. }
  1353. qSort(m_vecSortedRanks.begin() , m_vecSortedRanks.end());
  1354. }
  1355. void HierarchicalLayouter::removeNestingEdges()
  1356. {
  1357. /* This function assumes that basic ranking is assigned to the vertices.
  1358. * that means in a directed graph with two vertices the
  1359. * rank value of two vertices connected must have rank
  1360. * difference equal to 1.
  1361. */
  1362. //For all graph edges
  1363. //remove Nesting Long edges having span > 1
  1364. QQueue<EdgeDescriptor> qEdgesToRemoved;
  1365. int iEdgeSpan =0;
  1366. LayoutEnum::EdgeType enEdgeType;
  1367. LayoutEnum::NodeType enSourceVertexType;
  1368. LayoutEnum::NodeType enTargetVertexTyep;
  1369. VertexDescriptor vSource;
  1370. VertexDescriptor vTarget;
  1371. // XXX unsed
  1372. Q_UNUSED(iEdgeSpan);
  1373. Q_UNUSED(enSourceVertexType);
  1374. Q_UNUSED(enTargetVertexTyep);
  1375. Q_UNUSED(vSource);
  1376. Q_UNUSED(vTarget);
  1377. BGL_FORALL_EDGES(eEdge , *m_gMainGraph , SubGraph)
  1378. {
  1379. //Check if edge is Long Edge i.e. edge span >1
  1380. //iEdgeSpan = edgeSpan(eEdge , gGraph);
  1381. //if(iEdgeSpan > 1) //Comment it for Removing all nesting edges
  1382. {
  1383. enEdgeType = m_BoostGraphWrapper.getEdgeType(eEdge , *m_gMainGraph);
  1384. //If edge is nesting edge - Remove it
  1385. if(enEdgeType == LayoutEnum::NestingEdge)
  1386. {
  1387. //commented for testing 42314-1
  1388. // vSource = m_BoostGraphWrapper.getEdgeSource(eEdge , *m_gMainGraph);
  1389. // vTarget = m_BoostGraphWrapper.getEdgeTarget(eEdge , *m_gMainGraph);
  1390. // enSourceVertexType = m_BoostGraphWrapper.getVertexType(vSource , *m_gMainGraph);
  1391. // enTargetVertexTyep = m_BoostGraphWrapper.getVertexType(vTarget , *m_gMainGraph);
  1392. // if(enSourceVertexType == Enum::UpperBorderNode)
  1393. // {
  1394. // if(enTargetVertexTyep != Enum::LowerBorderNode)
  1395. // {
  1396. // //Check vertex in_degree
  1397. // if(in_degree(vTarget , *m_gMainGraph) > 0)
  1398. // {
  1399. // //Delete nesting edge
  1400. // qEdgesToRemoved.enqueue(eEdge);
  1401. // }
  1402. // }
  1403. // }
  1404. // else if(enTargetVertexTyep == Enum::LowerBorderNode)
  1405. // {
  1406. // //Check vertex outdegree
  1407. // if(out_degree(vSource , *m_gMainGraph) > 0)
  1408. // {
  1409. // //Delete nesting tree node
  1410. // qEdgesToRemoved.enqueue(eEdge);
  1411. // }
  1412. // }
  1413. //Uncommented for testing 42314-1
  1414. //Delete nesting tree node
  1415. qEdgesToRemoved.enqueue(eEdge);
  1416. }
  1417. }
  1418. }
  1419. //Remove edges
  1420. EdgeDescriptor eEdge;
  1421. while(qEdgesToRemoved.empty() == false)
  1422. {
  1423. eEdge = qEdgesToRemoved.dequeue();
  1424. m_BoostGraphWrapper.removeEdge(eEdge , *m_gMainGraph);
  1425. }
  1426. }
  1427. int HierarchicalLayouter::splitLongEdgesAndUpdateNestingTree()
  1428. {
  1429. /* This procedure produce correct splitting of edges
  1430. * only when basic ranking is assigned to the vertices.
  1431. * that means in a directed graph with two vertices the
  1432. * rank value of two vertices connected must have rank
  1433. * difference equal to 1.
  1434. * Assumption 2: There are no upward edges in graph
  1435. */
  1436. //For all graph edges
  1437. //Split edges having span > 1
  1438. int iTotalLongEdges = 0;
  1439. int iEdgeSpan = 0;
  1440. int iDummyNodesRequired = 0;
  1441. int iRank = 0;
  1442. VertexDescriptor vSource = 0;
  1443. VertexDescriptor vTarget = 0;
  1444. VertexDescriptor vOriginalSourceVertex = 0;
  1445. VertexDescriptor vOriginalTargetVertex = 0;
  1446. //For storing long edge dummy node information to later to convert them into bend points
  1447. //and restore the long edge
  1448. QVector<VertexDescriptor>* vecDummyVertices = NULL;
  1449. EdgeProperties* edgePropertiesRef = NULL;
  1450. //qDebug()<<"Test splitting00000000000000000";
  1451. BGL_FORALL_EDGES(eEdge , *m_gMainGraph , SubGraph)
  1452. {
  1453. vSource = m_BoostGraphWrapper.getEdgeSource(eEdge , *m_gMainGraph);
  1454. vTarget = m_BoostGraphWrapper.getEdgeTarget(eEdge , *m_gMainGraph);
  1455. //qDebug()<<"Edge: "<<(int)vSource <<" , "<<vTarget;
  1456. }
  1457. //qDebug()<<"Test splitting00000000000000000";
  1458. LayoutEnum::EdgeType enEdgeType;
  1459. QQueue<EdgeDescriptor> qEdgesToRemove;
  1460. BGL_FORALL_EDGES(eEdge , *m_gMainGraph , SubGraph)
  1461. {
  1462. //Check if edge is Long Edge i.e. edge span >1
  1463. iEdgeSpan = edgeSpan(eEdge , *m_gMainGraph);
  1464. //Get source vertex of long edge to connect to the first dummy node
  1465. vSource = m_BoostGraphWrapper.getEdgeSource(eEdge , *m_gMainGraph);
  1466. vTarget = m_BoostGraphWrapper.getEdgeTarget(eEdge , *m_gMainGraph);
  1467. //qDebug()<<"Current Edge: "<<(int)vSource <<" , "<<vTarget;
  1468. //qDebug() << "Edge span: " << QString::number(iEdgeSpan);
  1469. if(iEdgeSpan > 1)
  1470. {
  1471. iTotalLongEdges++;
  1472. enEdgeType = m_BoostGraphWrapper.getEdgeType(eEdge , *m_gMainGraph);
  1473. //If edge is graph edge - Split the edge
  1474. if(enEdgeType == LayoutEnum::GraphEdge)
  1475. {
  1476. //Queue the long edge to be removed after splitting it
  1477. qEdgesToRemove.enqueue(eEdge);
  1478. //Split and assign ranks to the vertices
  1479. //Calculate dummy nodes required for splitting
  1480. iDummyNodesRequired = iEdgeSpan - 1;
  1481. //Get source vertex of long edge to connect to the first dummy node
  1482. vSource = m_BoostGraphWrapper.getEdgeSource(eEdge , *m_gMainGraph);
  1483. vTarget = m_BoostGraphWrapper.getEdgeTarget(eEdge , *m_gMainGraph);
  1484. vOriginalSourceVertex = vSource;
  1485. vOriginalTargetVertex = vTarget;
  1486. //qDebug()<<"Long edge: "<<(int)vOriginalSourceVertex <<" , "<<vOriginalTargetVertex;
  1487. vecDummyVertices = new QVector<VertexDescriptor>();
  1488. //Record edge properties to restore them later
  1489. edgePropertiesRef = recordEdgeProperties(eEdge);
  1490. NestingTreeSubgraphNode& subgraphNodeOfSourceVertex
  1491. = (hashVertexToLayerNode.value(vSource))->getParentNestingTreeSubgraphNode();
  1492. NestingTreeSubgraphNode& subgraphNodeOfTargetVertex
  1493. = (hashVertexToLayerNode.value(vTarget))->getParentNestingTreeSubgraphNode();
  1494. //Create subgraph tree nodes queue
  1495. QQueue<NestingTreeSubgraphNode*> qNestingSubgraphNodes;
  1496. getNestingTreeSubgraphNodesPath(subgraphNodeOfSourceVertex
  1497. , subgraphNodeOfTargetVertex
  1498. , qNestingSubgraphNodes);
  1499. iRank = m_BoostGraphWrapper.getVertexRank(vSource , *m_gMainGraph);
  1500. NestingTreeSubgraphNode* properSubgraphNodeRef;
  1501. bool bRootSubgraphEncountered = false;
  1502. /*Deque first subgraph node into properSubgraphNode, to be
  1503. *used as parent graph for new Dummy Vertex
  1504. */
  1505. properSubgraphNodeRef = qNestingSubgraphNodes.dequeue();
  1506. if(properSubgraphNodeRef->isRoot())
  1507. {
  1508. bRootSubgraphEncountered = true;
  1509. }
  1510. while(iDummyNodesRequired > 0)
  1511. {
  1512. //Insert dummy nodes to innermost subgraph which
  1513. //also contains long edge source or
  1514. //target vertices and satifies the following condition
  1515. //Rank(UpperBorderVertex) <= Rank(dummy node) <= Rank(LowerBorderVertex)
  1516. //Create dummy node
  1517. //Calculate rank for the dummy node
  1518. iRank += m_iRankDifferenceInLayers;
  1519. /*Find a nearest subgraph node of which min and max ranks
  1520. *can contain the Dummy Nodes rank value in their range
  1521. */
  1522. if(bRootSubgraphEncountered == false)
  1523. {
  1524. if(qNestingSubgraphNodes.isEmpty() == false)
  1525. {
  1526. while(properSubgraphNodeRef->isBetweenMinMaxRanks(iRank) == false)
  1527. {
  1528. properSubgraphNodeRef = qNestingSubgraphNodes.dequeue();
  1529. if(properSubgraphNodeRef->isRoot())
  1530. {
  1531. bRootSubgraphEncountered = true;
  1532. }
  1533. if(qNestingSubgraphNodes.isEmpty())
  1534. {
  1535. break;
  1536. }
  1537. }
  1538. }
  1539. }
  1540. if(bRootSubgraphEncountered == true)
  1541. {
  1542. if(qNestingSubgraphNodes.isEmpty() == false)
  1543. {
  1544. while(qNestingSubgraphNodes.first()->isBetweenMinMaxRanks(iRank))
  1545. {
  1546. properSubgraphNodeRef = qNestingSubgraphNodes.dequeue();
  1547. if(qNestingSubgraphNodes.isEmpty())
  1548. {
  1549. break;
  1550. }
  1551. }
  1552. }
  1553. }
  1554. SubGraph &properSubgraph = properSubgraphNodeRef->getGraph();
  1555. vTarget = m_BoostGraphWrapper.addVertex(properSubgraph , LayoutEnum::DummyNode);
  1556. //Convert dummy node index from local to global index
  1557. vTarget = properSubgraph.local_to_global(vTarget);
  1558. //Record Dummy Nodes in vector
  1559. vecDummyVertices->push_back(vTarget);
  1560. ////qDebug() << "Add dummy vertex: "<<(int)vTarget;
  1561. //Add Long Edge Segment
  1562. m_BoostGraphWrapper.addEdge(vSource , vTarget ,
  1563. *m_gMainGraph , LayoutEnum::LongEdgeSegment);
  1564. m_BoostGraphWrapper.setVertexRank(vTarget , *m_gMainGraph , iRank);
  1565. //Add Layer Node for new Dummy vertex
  1566. LayerNode * dummyVertexLayerNode = new LayerNode(*properSubgraphNodeRef , vTarget);
  1567. //Add new Layer Node Entry to hashVertexToLayerNode
  1568. hashVertexToLayerNode.insert(vTarget , dummyVertexLayerNode);
  1569. //Add Layer Node for new Dummy vertex's entry to the Nesting Graph
  1570. properSubgraphNodeRef->addLayerIdAndLayerNode(iRank ,dummyVertexLayerNode);
  1571. //Set current Target Dummy Vertex to be Source vertex for next dummy vertex
  1572. vSource = vTarget;
  1573. iDummyNodesRequired--;
  1574. }
  1575. //Connect last dummy node to the original long edge target node
  1576. vTarget = m_BoostGraphWrapper.getEdgeTarget(eEdge , *m_gMainGraph);
  1577. m_BoostGraphWrapper.addEdge(vSource , vTarget ,
  1578. *m_gMainGraph , LayoutEnum::LongEdgeSegment);
  1579. }
  1580. //qDebug() << "Delete edge later: " <<(int)vOriginalSourceVertex<<" , "<<(int)vOriginalTargetVertex;
  1581. bool bLongEdgeAlreadyAdded = m_mapDeletedLongEdgesToDummyVertex.contains(VertexPair(vOriginalSourceVertex , vOriginalTargetVertex));
  1582. if(bLongEdgeAlreadyAdded)
  1583. {
  1584. //qDebug() << "Duplicate Edge $$$";
  1585. }
  1586. //Store long edge dummy node information
  1587. m_mapDeletedLongEdgesToDummyVertex.insertMulti(VertexPair(vOriginalSourceVertex , vOriginalTargetVertex) , vecDummyVertices);
  1588. //6314-1 Do not add property of reversed edge to long edge deleted edge because they are already taken in map of reversed edge to their properties
  1589. bool bIsReverseEdge = m_BoostGraphWrapper.getEdgeReversed(eEdge , *m_gMainGraph);
  1590. if(bIsReverseEdge == false)
  1591. {
  1592. //qDebug() << "Add to long edge property : "<<(int)vOriginalSourceVertex<<" , "<<(int)vOriginalTargetVertex;
  1593. m_mapDeletedEdgeProperties.insertMulti(VertexPair(vOriginalSourceVertex , vOriginalTargetVertex) , edgePropertiesRef);
  1594. }
  1595. else
  1596. {
  1597. //qDebug() << "Reversed Long Edge Found";
  1598. }
  1599. //qDebug()<<"---------------";
  1600. vecDummyVertices = NULL;
  1601. }
  1602. }
  1603. //Remove Long Edges from graph and record them to restore later
  1604. while(qEdgesToRemove.isEmpty() == false)
  1605. {
  1606. EdgeDescriptor eEdge = qEdgesToRemove.dequeue();
  1607. vSource = source(eEdge , *m_gMainGraph);
  1608. vTarget = target(eEdge , *m_gMainGraph);
  1609. m_BoostGraphWrapper.removeEdge(eEdge , *m_gMainGraph);
  1610. }
  1611. ////qDebug() << "Splitting done.";
  1612. return iTotalLongEdges;
  1613. }
  1614. int HierarchicalLayouter::edgeSpan(EdgeDescriptor eEdge , SubGraph& gGraph)
  1615. {
  1616. int iEdgeSpan = 0;
  1617. int iSourceRank;
  1618. int iTargetRank;
  1619. VertexDescriptor vSource = m_BoostGraphWrapper.getEdgeSource(eEdge , gGraph);
  1620. VertexDescriptor vTarget = m_BoostGraphWrapper.getEdgeTarget(eEdge , gGraph);
  1621. iSourceRank = m_BoostGraphWrapper.getVertexRank(vSource , gGraph);
  1622. iTargetRank = m_BoostGraphWrapper.getVertexRank(vTarget , gGraph);
  1623. //Assert: source and target vertices of edge must have a valid rank value
  1624. LAYOUT_ASSERT(iSourceRank > 0 && iTargetRank > 0, LayoutException(__FUNCTION__
  1625. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  1626. , "Edge Vertices Rank Values"
  1627. , "for Edge Span"));
  1628. //Difference between Rank(source) and Rank(target)
  1629. iEdgeSpan = std::abs(iTargetRank - iSourceRank);
  1630. int iDifferenceInLayer;
  1631. iDifferenceInLayer = m_iNestingDepth * 2 + 1;
  1632. iEdgeSpan /= iDifferenceInLayer;
  1633. return iEdgeSpan;
  1634. }
  1635. void HierarchicalLayouter::removeCycle(SubGraph &gGraph, VectorEdgeDescriptor &vectBackEdges)
  1636. {
  1637. try
  1638. {
  1639. GraphCycleHandler graphCycleHandler;
  1640. //Record Back edges
  1641. graphCycleHandler.detectBackEdges( gGraph , vectBackEdges );
  1642. EdgeDescriptor eBackEdge;
  1643. VertexDescriptor vSource = 0;
  1644. VertexDescriptor vTarget = 0;
  1645. EdgeProperties* edgeProperties = NULL;
  1646. //Record reversed edges, in vector of EdgeVerticesPair
  1647. VectorEdgeDescriptor::iterator iterVecBackEdges = vectBackEdges.begin();
  1648. //qDebug() << "Recording Back Edges: 1111111111111";
  1649. while(iterVecBackEdges != vectBackEdges.end())
  1650. {
  1651. eBackEdge = *iterVecBackEdges;
  1652. edgeProperties = recordEdgeProperties(eBackEdge);
  1653. vSource = source(eBackEdge , *m_gMainGraph);
  1654. vTarget = target(eBackEdge , *m_gMainGraph);
  1655. //qDebug() << "Record: "<<(int)vSource<<" , "<<(int)vTarget;
  1656. //m_mapReversedEdges.insertMulti(vSource , vTarget);
  1657. m_mapReversedEdgeProperties.insertMulti(VertexPair(vSource , vTarget) , edgeProperties);
  1658. iterVecBackEdges++;
  1659. }
  1660. //qDebug() << "----------------------------";
  1661. //Reverse Back Edges
  1662. //graphCycleHandler.reverseEdges(gGraph,vectBackEdges);
  1663. {
  1664. //Exchange the source and destinition vertices of edge
  1665. VectorEdgeDescriptor::iterator iterEdges;
  1666. //qDebug() << "Reversing Edges 11111111111111111111111";
  1667. for(iterEdges = vectBackEdges.begin();
  1668. iterEdges != vectBackEdges.end();
  1669. iterEdges++)
  1670. {
  1671. EdgeDescriptor eEdge = *iterEdges;
  1672. VertexDescriptor vSource = m_BoostGraphWrapper.getEdgeSource(eEdge , *m_gMainGraph);
  1673. VertexDescriptor vDest = m_BoostGraphWrapper.getEdgeTarget(eEdge , *m_gMainGraph);
  1674. try{
  1675. //Delete edge
  1676. m_BoostGraphWrapper.removeEdge(vSource , vDest , *m_gMainGraph);
  1677. //qDebug() << "Delete: "<<(int)vSource<<" , "<<(int)vDest;
  1678. }
  1679. catch(boost::exception& eBoostException)
  1680. {
  1681. throw *boost::get_error_info<errmsg_info>(eBoostException);
  1682. }
  1683. catch(...)
  1684. {
  1685. throw LayoutException( __FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  1686. }
  1687. //Check if edge is a self loop
  1688. if(vSource == vDest)
  1689. {
  1690. //qDebug() << "Skip: "<<(int)vSource<<" , "<<(int)vDest;
  1691. //Skip edge : handle these edges while restoring reversed edges , by adding calculated
  1692. //bend points
  1693. continue;
  1694. }
  1695. //Add edge
  1696. EdgeDescriptor reversedEdge = (m_BoostGraphWrapper.addEdge(vDest , vSource , *m_gMainGraph)).first;
  1697. //qDebug() << "Reverse add: "<<(int)vSource<<" , "<<(int)vDest;
  1698. try{
  1699. //Setting reversed edge property
  1700. m_BoostGraphWrapper.setEdgeReversed(reversedEdge , *m_gMainGraph , true);
  1701. /*Record reversed edge descriptor for each back edge. To delete the proper reversed edge
  1702. added for corresponding back edge
  1703. */
  1704. m_mapVertexPairToReversedEdgeDescriptor.insert(VertexPair(vSource, vDest),reversedEdge);
  1705. }
  1706. catch(boost::exception& eBoostException)
  1707. {
  1708. throw *boost::get_error_info<errmsg_info>(eBoostException);
  1709. }
  1710. catch(...)
  1711. {
  1712. throw LayoutException( __FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  1713. }
  1714. //qDebug() << "---------";
  1715. }
  1716. //qDebug() << "=================================";
  1717. }
  1718. //Check for new cycles in graph
  1719. VectorEdgeDescriptor vectNewBackEdges;
  1720. graphCycleHandler.detectBackEdges(gGraph , vectNewBackEdges);
  1721. if(vectNewBackEdges.empty() == false)
  1722. {
  1723. //qDebug()<<"Back edge removal has created new back edges\n";
  1724. }
  1725. }
  1726. catch(boost::exception &eBoostException)
  1727. {
  1728. throw *boost::get_error_info<errmsg_info>(eBoostException);
  1729. }
  1730. catch(LayoutException &eLayoutException)
  1731. {
  1732. throw eLayoutException;
  1733. }
  1734. catch(...)
  1735. {
  1736. throw;
  1737. }
  1738. }
  1739. void HierarchicalLayouter::initHashVertexToLayerNode(SubGraph &gGraph)
  1740. {
  1741. ////qDebug() << "Initialising Hash Vertex to Layer Node ";
  1742. LayerNode* newLayerNode;
  1743. BGL_FORALL_VERTICES(vVertex , gGraph , SubGraph)
  1744. {
  1745. newLayerNode = new LayerNode(vVertex);
  1746. hashVertexToLayerNode.insert(vVertex , newLayerNode);
  1747. ////qDebug() << QString::number(vVertex);
  1748. }
  1749. ////qDebug() << "Initialising Hash Vertex to Layer Node DONE!";
  1750. }
  1751. void HierarchicalLayouter::generateNestingTree()
  1752. {
  1753. try
  1754. {
  1755. //set graph for current Nesting Tree Subgraph Node
  1756. m_rootNestingTreeSubgraphNode.setGraph(*m_gMainGraph);
  1757. generateNestingTreeByRecur(m_rootNestingTreeSubgraphNode , *m_gMainGraph);
  1758. }
  1759. catch(boost::exception& eBoostException)
  1760. {
  1761. throw *boost::get_error_info<errmsg_info>(eBoostException);
  1762. }
  1763. catch(...)
  1764. {
  1765. throw;
  1766. }
  1767. }
  1768. void HierarchicalLayouter::generateNestingTreeByRecur(NestingTreeSubgraphNode &nestingTreeSubgraphNodes, SubGraph &gRootGraph)
  1769. {
  1770. // ////qDebug() << "Graph: " << (m_BoostGraphWrapper.getGraphId(nestingTreeSubgraphNodes.getGraph()));
  1771. // if(nestingTreeSubgraphNodes.isRoot() == false)
  1772. // {
  1773. // ////qDebug() << " Parent: " << (m_BoostGraphWrapper.getGraphId((nestingTreeSubgraphNodes.getParent()).getGraph()));
  1774. // }
  1775. // //cout << endl;
  1776. // ////qDebug() << "Vertices : ";
  1777. IteratorQVectorUInt iterOwnVertices , iterOwnVerticesEnd;
  1778. //Add own vertices to Nesting Tree Subgraph Node's multimap
  1779. int iLayerRank = 0;
  1780. VertexDescriptor vOwnVertex , vGlobalOwnVertex;
  1781. LayerNode *layerNode;
  1782. for(boost::tie(iterOwnVertices , iterOwnVerticesEnd)
  1783. = m_BoostGraphWrapper.ownVerticesIter(gRootGraph);
  1784. iterOwnVertices != iterOwnVerticesEnd;
  1785. iterOwnVertices++)
  1786. {
  1787. //Get graphs own vertex
  1788. vOwnVertex = *iterOwnVertices;
  1789. ////qDebug() << " local: " << vOwnVertex;
  1790. //Convert vOwnVertex's local index to global
  1791. vGlobalOwnVertex = gRootGraph.local_to_global(vOwnVertex);
  1792. ////qDebug() << " global: " << vGlobalOwnVertex;
  1793. //Get layer rank of current own vertex
  1794. iLayerRank = m_BoostGraphWrapper.getVertexRank(vOwnVertex , gRootGraph);
  1795. //Get corresponding LayerNode for current own vertex
  1796. layerNode = hashVertexToLayerNode.value(vGlobalOwnVertex);
  1797. //Add curent vertex layer rank and layer node
  1798. //to current Nesting Tree Subgaph Node
  1799. nestingTreeSubgraphNodes.addLayerIdAndLayerNode(iLayerRank , layerNode);
  1800. //Add parent Nesting Tree Subgaph Node entry into layer node
  1801. layerNode->setParentNestingTreeSubgraphNode(nestingTreeSubgraphNodes);
  1802. //Record Layer Id into Nesting Tree Subgaph Node and its parent branch
  1803. nestingTreeSubgraphNodes.recordLayerIdRecurUp(iLayerRank);
  1804. }
  1805. ////qDebug() << endl << "---------------" << endl;
  1806. //cout << "\nChild Subgraphs : ";
  1807. //Add Child Subgraphs to nesting tree
  1808. ChildrenIterator iterChildGraph , iterChildGraphEnd;
  1809. for(boost::tie(iterChildGraph , iterChildGraphEnd)
  1810. = gRootGraph.children();
  1811. iterChildGraph != iterChildGraphEnd;
  1812. iterChildGraph++)
  1813. {
  1814. NestingTreeSubgraphNode& childNestingTreeSubgraphNode
  1815. = nestingTreeSubgraphNodes.addChildNestingTreeSubgraphNode(*iterChildGraph);
  1816. generateNestingTreeByRecur(childNestingTreeSubgraphNode , *iterChildGraph);
  1817. }
  1818. }
  1819. void HierarchicalLayouter::getNestingTreeSubgraphNodesPath(NestingTreeSubgraphNode& sourceSubgraphNode , NestingTreeSubgraphNode& targetSubgraphNode , QueueNestingTreeSubgraphNodesRef &qNestingTreeSubgraphNodesRef)
  1820. {
  1821. //////qDebug() << "Generating Subgraph Path\n";
  1822. /*Add nesting tree subgraph nodes from source subgraph node
  1823. *till the root subgraph node in the queue
  1824. */
  1825. QueueNestingTreeSubgraphNodesRef qSourceSubgraphNodeToRoot;
  1826. qSourceSubgraphNodeToRoot.enqueue(&sourceSubgraphNode);
  1827. QSet<NestingTreeSubgraphNode*> visitedSubgraphNodes;
  1828. visitedSubgraphNodes.insert(&sourceSubgraphNode);
  1829. //Traverse path from source subgrph Node till the root of Nesting Tree
  1830. while(&(qSourceSubgraphNodeToRoot.last()->getParent()) != NULL)
  1831. {
  1832. NestingTreeSubgraphNode& parentSubgraphNode = qSourceSubgraphNodeToRoot.last()->getParent();
  1833. qSourceSubgraphNodeToRoot.enqueue(&parentSubgraphNode);
  1834. //Record traversed subgraph nodes in visited nodes set
  1835. visitedSubgraphNodes.insert(&parentSubgraphNode);
  1836. }
  1837. QStack<NestingTreeSubgraphNode*> stackTargetVertexSubgraphNodesToRootNode;
  1838. //Fill stack till it finds a visited subgraph node OR the nesting tree root
  1839. stackTargetVertexSubgraphNodesToRootNode.push(&targetSubgraphNode);
  1840. while(&(stackTargetVertexSubgraphNodesToRootNode.top()->getParent()) != NULL)
  1841. {
  1842. //Check if the previously stacked Subgraph node is in visited node set or not
  1843. if(visitedSubgraphNodes.contains(stackTargetVertexSubgraphNodesToRootNode.top())== true)
  1844. {
  1845. break;
  1846. }
  1847. NestingTreeSubgraphNode& parentSubgraphNode = stackTargetVertexSubgraphNodesToRootNode.top()->getParent();
  1848. stackTargetVertexSubgraphNodesToRootNode.push(&parentSubgraphNode);
  1849. }
  1850. /*The top of the stack contains common Subgraph node from
  1851. *Queue -qSourceSubgraphNodeToRoot and Stack-stackTargetVertexSubgraphNodesToRootNode
  1852. */
  1853. //Filling final path queue - qNestingTreeSubgraphNodesRef
  1854. while(qSourceSubgraphNodeToRoot.first() != stackTargetVertexSubgraphNodesToRootNode.top())
  1855. {
  1856. //////qDebug() << m_BoostGraphWrapper.getGraphId(qSourceSubgraphNodeToRoot.first()->getGraph());
  1857. qNestingTreeSubgraphNodesRef.enqueue(qSourceSubgraphNodeToRoot.dequeue());
  1858. }
  1859. while(stackTargetVertexSubgraphNodesToRootNode.isEmpty() == false)
  1860. {
  1861. //////qDebug() << m_BoostGraphWrapper.getGraphId(stackTargetVertexSubgraphNodesToRootNode.top()->getGraph());
  1862. qNestingTreeSubgraphNodesRef.enqueue(stackTargetVertexSubgraphNodesToRootNode.pop());
  1863. }
  1864. //////qDebug() << "Path calculation done.";
  1865. }
  1866. void HierarchicalLayouter::generateLayeredGraph()
  1867. {
  1868. /*Add vertex's LayerNode to the Layer which has same LayerId as the Rank of current vertex
  1869. */
  1870. int iRank = 0;
  1871. MapPositionToLayerNode *mapVertexPositionToLayerNode;
  1872. QMap< int , int* > mapLayerIdToLayerNodeCount;
  1873. int iHorizontalPosition;
  1874. int * iLayerNodeCounter;
  1875. BGL_FORALL_VERTICES(vVertex , *m_gMainGraph , SubGraph)
  1876. {
  1877. iRank = m_BoostGraphWrapper.getVertexRank(vVertex , *m_gMainGraph);
  1878. //Check if Layer with Rank exists or not
  1879. if(m_mapLayeredGraph.contains(iRank) == false)
  1880. {
  1881. //Create Layer if new Rank is encountered
  1882. mapVertexPositionToLayerNode = new MapPositionToLayerNode();
  1883. //Add new Layer to layeredGraph
  1884. m_mapLayeredGraph.insert(iRank , mapVertexPositionToLayerNode);
  1885. //Create LayerNode count map entry for new Layer
  1886. iLayerNodeCounter = new int();
  1887. *iLayerNodeCounter = 1;
  1888. mapLayerIdToLayerNodeCount.insert(iRank , iLayerNodeCounter);
  1889. iHorizontalPosition = *iLayerNodeCounter;
  1890. }
  1891. else
  1892. {
  1893. mapVertexPositionToLayerNode = m_mapLayeredGraph.value(iRank);
  1894. iHorizontalPosition = *(mapLayerIdToLayerNodeCount.value(iRank));
  1895. }
  1896. //Find LayerNode for current vertex
  1897. LayerNode *layerNodeOfCurrentVertex = hashVertexToLayerNode.value(vVertex);
  1898. //Add LayerNode to the corresponding Layer
  1899. mapVertexPositionToLayerNode->insert(iHorizontalPosition , layerNodeOfCurrentVertex);
  1900. //Increment Layer Node counter for current layer
  1901. (*(mapLayerIdToLayerNodeCount.value(iRank)))++;
  1902. //Update LayerNode position into the Vertex Property
  1903. m_BoostGraphWrapper.setVertexHorizontalPosition(vVertex , *m_gMainGraph , iHorizontalPosition);
  1904. }
  1905. }
  1906. void HierarchicalLayouter::reverseLayerNodesPositions(int iLayerId)
  1907. {
  1908. MapPositionToLayerNode *mapReversedLayer = new MapPositionToLayerNode();
  1909. int iPositionCounter = 1;
  1910. IteratorMapPositionToLayerNode iterLayerNode(*m_mapLayeredGraph[iLayerId]);
  1911. iterLayerNode.toBack();
  1912. LayerNode * layerNode = NULL;
  1913. while(iterLayerNode.hasPrevious())
  1914. {
  1915. iterLayerNode.previous();
  1916. //Add nodes to reversed layer
  1917. mapReversedLayer->insert(iPositionCounter , iterLayerNode.value());
  1918. //Update horizontal position
  1919. layerNode = iterLayerNode.value();
  1920. VertexDescriptor vVertex = layerNode->getVertex();
  1921. m_BoostGraphWrapper.setVertexHorizontalPosition( vVertex,
  1922. *m_gMainGraph ,
  1923. iPositionCounter);
  1924. iPositionCounter++;
  1925. }
  1926. //Delete old layer
  1927. DELETE_AND_SET_NULL(m_mapLayeredGraph[iLayerId]);
  1928. //Set new reversed layer
  1929. m_mapLayeredGraph[iLayerId] = mapReversedLayer;
  1930. }
  1931. void HierarchicalLayouter::reverseLayeredGraphHorizontaly()
  1932. {
  1933. try
  1934. {
  1935. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  1936. while(iterLayer.hasNext())
  1937. {
  1938. iterLayer.next();
  1939. int iKey = iterLayer.key();
  1940. reverseLayerNodesPositions(iKey);
  1941. }
  1942. bool bIsProperLayeredGraph = testLayeredGraph();
  1943. // XXX unused
  1944. Q_UNUSED(bIsProperLayeredGraph);
  1945. LAYOUT_ASSERT(bIsProperLayeredGraph == true
  1946. , LayoutException(__FUNCTION__
  1947. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  1948. , "in reverse leyered gaph horizontally"
  1949. , "Layer"
  1950. ));
  1951. }
  1952. catch(boost::exception &eBoostException)
  1953. {
  1954. throw *boost::get_error_info<errmsg_info>(eBoostException);
  1955. }
  1956. catch(LayoutException &eLayoutException)
  1957. {
  1958. throw eLayoutException;
  1959. }
  1960. // XXX obselete
  1961. // catch(LayoutMemoryException &eMemoryException)
  1962. // {
  1963. // throw eMemoryException;
  1964. // }
  1965. catch(...)
  1966. {
  1967. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  1968. }
  1969. }
  1970. void HierarchicalLayouter::reverseLayeredGraphVertically()
  1971. {
  1972. try
  1973. {
  1974. //vector of keys
  1975. QVectorUInt vecLayerIds;
  1976. int iLayerId = 0;
  1977. int iNegativeLayerId = 0;
  1978. MapLayerIdToLayerRef reverseLayeredGraph;
  1979. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  1980. while(iterLayer.hasNext())
  1981. {
  1982. iterLayer.next();
  1983. iLayerId = iterLayer.key();
  1984. iNegativeLayerId = iLayerId * -1;
  1985. //record layer ids to delete later
  1986. vecLayerIds.push_back(iLayerId);
  1987. //reversed layered graph
  1988. reverseLayeredGraph.insert(iNegativeLayerId , iterLayer.value());
  1989. }
  1990. //remove items
  1991. int iVecLayerIdSize = vecLayerIds.size();
  1992. for(int iIndex = 0 ; iIndex < iVecLayerIdSize ; iIndex++)
  1993. {
  1994. //remove layer
  1995. m_mapLayeredGraph.remove(vecLayerIds[iIndex]);
  1996. }
  1997. //Add reversed layers
  1998. IteratorMapLayerIdToLayerRef iterReversedLayer(reverseLayeredGraph);
  1999. while(iterReversedLayer.hasNext())
  2000. {
  2001. iterReversedLayer.next();
  2002. //Add to layered graph
  2003. m_mapLayeredGraph.insert(iterReversedLayer.key() ,
  2004. iterReversedLayer.value());
  2005. }
  2006. }
  2007. catch(LayoutMemoryException &eMemoryException)
  2008. {
  2009. throw eMemoryException;
  2010. }
  2011. catch(...)
  2012. {
  2013. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  2014. }
  2015. }
  2016. /**
  2017. * last step
  2018. */
  2019. void HierarchicalLayouter::restoreReversedAndLongEdgesWithBendPoints()
  2020. {
  2021. VertexDescriptor vLongEdgeSource = 0;
  2022. VertexDescriptor vLongEdgeTarget = 0;
  2023. VertexDescriptor vDummyVertex = 0;
  2024. VertexDescriptor vSource = 0;
  2025. VertexDescriptor vTarget = 0;
  2026. EdgeProperties* edgeProperties = NULL;
  2027. bool bIsOriginalEdgeExist;
  2028. LayoutEnum::NodeType enVertexType;
  2029. LayoutEnum::EdgeType enEdgeType;
  2030. // XXX unused
  2031. Q_UNUSED(bIsOriginalEdgeExist);
  2032. Q_UNUSED(enVertexType);
  2033. Q_UNUSED(enEdgeType);
  2034. BendPoints* newBendPoint = NULL;
  2035. BGL_FORALL_EDGES(eEdge , *m_gMainGraph , SubGraph)
  2036. {
  2037. m_BoostGraphWrapper.setEdgeVisited(eEdge , *m_gMainGraph , false);
  2038. }
  2039. //check
  2040. // LAYOUT_ASSERT((m_mapDeletedLongEdgesToDummyVertex.size() == (m_mapReversedEdgeProperties.size() +
  2041. // m_mapDeletedEdgeProperties.size()))
  2042. // , LayoutException(__FUNCTION__
  2043. // , ExceptionEnum::INCONSISTENT_DATASTRUCTURE
  2044. // , "Contains duplicate entries of same edge and edge property"
  2045. // , "Map of Reversed Edge to Edge Property"));
  2046. //qDebug()<<"--------------------------------------------------**";
  2047. //Iterat deleted long edges
  2048. IteratorMapDeletedLongEdgeToVectorDummyVertex iterDeletedEdgeVertexPair(m_mapDeletedLongEdgesToDummyVertex);
  2049. while(iterDeletedEdgeVertexPair.hasNext())
  2050. {
  2051. iterDeletedEdgeVertexPair.next();
  2052. VertexPair pairLongEdgeVertices = iterDeletedEdgeVertexPair.key();
  2053. vLongEdgeSource = pairLongEdgeVertices.first;
  2054. vLongEdgeTarget = pairLongEdgeVertices.second;
  2055. //qDebug() << "Restore long edge: "<<(int)vLongEdgeSource<<" , "<<(int)vLongEdgeTarget;
  2056. QVector<VertexDescriptor> vecDummyVertices = *(iterDeletedEdgeVertexPair.value());
  2057. //Check if the long edge is a reversed edge or not, by checking its
  2058. //target and source vertex into map of Reversed Vertices
  2059. //if(m_mapReversedEdges.contains(vLongEdgeTarget) == true)
  2060. if(m_mapReversedEdgeProperties.contains(VertexPair(vLongEdgeTarget , vLongEdgeSource)))
  2061. {
  2062. //if(m_mapReversedEdges.values(vLongEdgeTarget).contains(vLongEdgeSource) == true)
  2063. //qDebug() << "Add Reversed Edge : "<<(int)vLongEdgeTarget<<" , "<<(int)vLongEdgeSource;
  2064. //Restore reversed edge
  2065. EdgeDescriptor eReversedLongEdge = m_BoostGraphWrapper.addEdge( vLongEdgeTarget
  2066. , vLongEdgeSource
  2067. , *m_gMainGraph).first;
  2068. //Restore reversed edge properties
  2069. //edgeProperties = m_mapReversedEdgeProperties[VertexPair(vLongEdgeTarget , vLongEdgeSource)];
  2070. QList<EdgeProperties*> listProperty = m_mapReversedEdgeProperties.values(VertexPair(vLongEdgeTarget , vLongEdgeSource));
  2071. LAYOUT_ASSERT(listProperty.isEmpty() == false, LayoutException(__FUNCTION__
  2072. , LayoutExceptionEnum::EMPTY_CONTAINER
  2073. , "property"
  2074. , "Property List of Deleted Reversed Edge"));
  2075. edgeProperties = listProperty.takeFirst();
  2076. setEdgeProperties(eReversedLongEdge , edgeProperties);
  2077. int iRemoved = 0;
  2078. // XXX unuseed
  2079. Q_UNUSED(iRemoved);
  2080. //Remove entry of reverse edge, as it is restored
  2081. //m_mapReversedEdges.remove(vLongEdgeTarget , vLongEdgeSource); // Commented for checking
  2082. //Remove properties as well //6214-1
  2083. iRemoved = m_mapReversedEdgeProperties.remove(VertexPair(vLongEdgeTarget , vLongEdgeSource) , edgeProperties);
  2084. LAYOUT_ASSERT(iRemoved == 1, LayoutException(__FUNCTION__
  2085. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  2086. , "Contains duplicate entries of same edge and edge property"
  2087. , "Map of Reversed Edge to Edge Property"));
  2088. if(ALLOW_BEND_POINTS == true)
  2089. {
  2090. //Add bend points in their reversed sequence
  2091. QVectorIterator<VertexDescriptor> reverseIterVecDummyVertex(vecDummyVertices);
  2092. reverseIterVecDummyVertex.toBack();
  2093. while(reverseIterVecDummyVertex.hasPrevious())
  2094. {
  2095. vDummyVertex = reverseIterVecDummyVertex.previous();
  2096. //The dummy vertex added for breaking the long edge makes a bend point
  2097. //Therefor add dummy vertex x,y coordinates as bend point
  2098. newBendPoint = new BendPoints();
  2099. newBendPoint->iCoordinateX = m_BoostGraphWrapper.getVertexCenterCoordX(vDummyVertex , *m_gMainGraph);
  2100. newBendPoint->iCoordinateY = m_BoostGraphWrapper.getVertexCenterCoordY(vDummyVertex , *m_gMainGraph);
  2101. ////qDebug()<<"add bend: "<<newBendPoint->iCoordinateX<<" , "<<newBendPoint->iCoordinateY;
  2102. m_BoostGraphWrapper.addBendPoint( newBendPoint , eReversedLongEdge , *m_gMainGraph);
  2103. }
  2104. }
  2105. }
  2106. else
  2107. {
  2108. //Restore long edge
  2109. EdgeDescriptor eLongEdge = m_BoostGraphWrapper.addEdge( vLongEdgeSource
  2110. , vLongEdgeTarget
  2111. , *m_gMainGraph).first;
  2112. //Restore long edge properties
  2113. //edgeProperties = m_mapDeletedEdgeProperties[VertexPair(vLongEdgeSource , vLongEdgeTarget)];
  2114. //******((
  2115. QList<EdgeProperties*> listProperty = m_mapDeletedEdgeProperties.values(VertexPair(vLongEdgeSource , vLongEdgeTarget));
  2116. LAYOUT_ASSERT(listProperty.isEmpty() == false, LayoutException(__FUNCTION__
  2117. , LayoutExceptionEnum::EMPTY_CONTAINER
  2118. , "property"
  2119. , "Property List of Deleted Long Edge"));
  2120. edgeProperties = listProperty.takeFirst();
  2121. setEdgeProperties(eLongEdge , edgeProperties);
  2122. int iRemoved = 0;
  2123. // XXX unused
  2124. Q_UNUSED(iRemoved);
  2125. //Remove properties as well //6214-1
  2126. iRemoved = m_mapDeletedEdgeProperties.remove(VertexPair(vLongEdgeSource , vLongEdgeTarget) , edgeProperties);
  2127. LAYOUT_ASSERT(iRemoved == 1, LayoutException(__FUNCTION__
  2128. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  2129. , "Contains duplicate entries of same edge and edge property"
  2130. , "Map of Long Edge to Edge Property"));
  2131. //))********
  2132. if(ALLOW_BEND_POINTS == true)
  2133. {
  2134. //Add bend points in their sequence
  2135. QVectorIterator<VertexDescriptor> iterVecDummyVertex(vecDummyVertices);
  2136. while(iterVecDummyVertex.hasNext())
  2137. {
  2138. vDummyVertex = iterVecDummyVertex.next();
  2139. //The dummy vertex added for breaking the long edge makes a bend point
  2140. //Therefor add dummy vertex x,y coordinates as bend point
  2141. newBendPoint = new BendPoints();
  2142. int iX = m_BoostGraphWrapper.getVertexCenterCoordX(vDummyVertex , *m_gMainGraph);
  2143. int iY = m_BoostGraphWrapper.getVertexCenterCoordY(vDummyVertex , *m_gMainGraph);
  2144. newBendPoint->iCoordinateX = iX;
  2145. newBendPoint->iCoordinateY = iY;
  2146. ////qDebug()<<"v: "<<(int)vDummyVertex<<" add bend: "<<newBendPoint->iCoordinateX<<" , "<<newBendPoint->iCoordinateY;
  2147. m_BoostGraphWrapper.addBendPoint(newBendPoint , eLongEdge , *m_gMainGraph);
  2148. }
  2149. }
  2150. }
  2151. }
  2152. //Till here, the reveresed edges which are long edges are restored
  2153. //Now restore reversed edges which are remaining, if any
  2154. //qDebug() << "Restore reverse edges which are not long edges";
  2155. int iRemainingReverseEdges = m_mapReversedEdgeProperties.size();
  2156. //qDebug()<<"Remainig reverse edges: "<<iRemainingReverseEdges;
  2157. //if(m_mapReversedEdges.size() > 0)
  2158. if(iRemainingReverseEdges > 0)
  2159. {
  2160. //QMapIterator<VertexDescriptor , VertexDescriptor> iterEdge(m_mapReversedEdges);
  2161. QMapIterator<VertexPair , EdgeProperties*> iterEdge(m_mapReversedEdgeProperties);
  2162. while(iterEdge.hasNext())
  2163. {
  2164. iterEdge.next();
  2165. VertexPair pairEdge = iterEdge.key();
  2166. vSource = pairEdge.first;
  2167. vTarget = pairEdge.second;
  2168. //6214-1
  2169. if(vSource != vTarget)
  2170. {
  2171. //Delete reversed edge from graph
  2172. QList<EdgeDescriptor> listEdgesToDelete = m_mapVertexPairToReversedEdgeDescriptor.values(
  2173. VertexPair(vSource , vTarget));
  2174. LAYOUT_ASSERT(listEdgesToDelete.isEmpty() == false, LayoutException(__FUNCTION__
  2175. , LayoutExceptionEnum::EMPTY_CONTAINER
  2176. , "reversed edge"
  2177. , "List of Reversed Edges does not contain the required edge descriptor"));
  2178. EdgeDescriptor eEdgeToDelete = listEdgesToDelete.takeFirst();
  2179. m_BoostGraphWrapper.removeEdge(eEdgeToDelete, *m_gMainGraph);
  2180. //Remove edge from the m_mapVertexPairToReversedEdgeDescriptor
  2181. m_mapVertexPairToReversedEdgeDescriptor.remove(VertexPair(vSource , vTarget) , eEdgeToDelete);
  2182. //qDebug() << "Remove edge: "<<(int)vTarget<<" , "<<(int)vSource;
  2183. }
  2184. //Restore the original edge in graph
  2185. EdgeDescriptor eReversedEdge = m_BoostGraphWrapper.addEdge(vSource , vTarget , *m_gMainGraph).first;
  2186. //qDebug() << "Add edge: "<<(int)vSource<<" , "<<(int)vTarget;
  2187. edgeProperties = iterEdge.value();
  2188. setEdgeProperties(eReversedEdge , edgeProperties);
  2189. if(vSource == vTarget)
  2190. {
  2191. if(ALLOW_BEND_POINTS == true)
  2192. {
  2193. //Restore self loop edge with bend points
  2194. int iWidth = m_BoostGraphWrapper.getVertexWidth(vSource , *m_gMainGraph);
  2195. int iHeight = m_BoostGraphWrapper.getVertexHeight(vSource , *m_gMainGraph);
  2196. int iBendX = 0;
  2197. int iBendY = 0;
  2198. int iCenterCoordX = m_BoostGraphWrapper.getVertexCenterCoordX(vSource , *m_gMainGraph);
  2199. int iCenterCoordY = m_BoostGraphWrapper.getVertexCenterCoordY(vSource , *m_gMainGraph);
  2200. //Add two bends for self loop edge
  2201. //First bend
  2202. iBendX = iCenterCoordX + (iWidth / 2) + m_iBorderMargin - 2;
  2203. iBendY = iCenterCoordY - (iHeight / 2);
  2204. newBendPoint = new BendPoints();
  2205. newBendPoint->iCoordinateX = iBendX;
  2206. newBendPoint->iCoordinateY = iBendY;
  2207. m_BoostGraphWrapper.addBendPoint(newBendPoint , eReversedEdge , *m_gMainGraph);
  2208. //Second bend
  2209. iBendX = iCenterCoordX + (iWidth / 2);
  2210. iBendY = iCenterCoordY - (iHeight / 2) - (m_iBorderMargin - 2);
  2211. newBendPoint = new BendPoints();
  2212. newBendPoint->iCoordinateX = iBendX;
  2213. newBendPoint->iCoordinateY = iBendY;
  2214. m_BoostGraphWrapper.addBendPoint(newBendPoint , eReversedEdge , *m_gMainGraph);
  2215. }
  2216. }
  2217. }
  2218. }
  2219. //qDebug()<<"--------------------------------------------------==";
  2220. }
  2221. EdgeProperties *HierarchicalLayouter::recordEdgeProperties(EdgeDescriptor &eGlobalEdge)
  2222. {
  2223. EdgeProperties* newEdgeProperties = new EdgeProperties();
  2224. newEdgeProperties->sId = m_BoostGraphWrapper.getEdgeId(eGlobalEdge , *m_gMainGraph);
  2225. newEdgeProperties->bBidirectional = m_BoostGraphWrapper.getEdgeBidirectional(eGlobalEdge , *m_gMainGraph);
  2226. return newEdgeProperties;
  2227. }
  2228. void HierarchicalLayouter::setEdgeProperties(EdgeDescriptor &eGlobalEdge, EdgeProperties *edgeProperties)
  2229. {
  2230. m_BoostGraphWrapper.setEdgeId(eGlobalEdge , *m_gMainGraph , edgeProperties->sId);
  2231. m_BoostGraphWrapper.setEdgeBidirectional(eGlobalEdge , *m_gMainGraph , edgeProperties->bBidirectional);
  2232. }
  2233. void HierarchicalLayouter::globalCrossingReducion(SubGraph &gMainGraph)
  2234. {
  2235. // XXX unusedd
  2236. Q_UNUSED(gMainGraph);
  2237. /*BarryCenter Crossing Reduction requires at least two layers for
  2238. *crossing reduction
  2239. *
  2240. *This process is done top-down and bottom-up for better results
  2241. */
  2242. //Top-Down Crossing Reduction using BarryCenter
  2243. /*Assumption :
  2244. *1. Graph has no Nesting Edges present
  2245. *2. Graph have at least two layers
  2246. */
  2247. //For Top-Down pass
  2248. int iFirstLayerId = 0;
  2249. int iFirstGraphLayerId = 0;
  2250. int iSecondGraphLayerId = 0;
  2251. //For Bottom-Up pass
  2252. int iLastLayerId = 0;
  2253. int iLastGraphLayerId = 0;
  2254. int iSecondLastGraphLayerId = 0;
  2255. int iCurrentLayerId = 0;
  2256. /*To have minimum two layers a graph must have at least one edge
  2257. */
  2258. if(num_edges(*m_gMainGraph) > 0)
  2259. {
  2260. //***********************Top-Down***********************
  2261. //Start frm second layer to Down
  2262. iFirstLayerId = m_mapLayeredGraph.constBegin().key();
  2263. //find first GraphVerticesLayer type Layer Id
  2264. iFirstGraphLayerId = getNextLayerId(iFirstLayerId ,
  2265. DownDirection ,
  2266. GraphVerticesLayer);
  2267. iSecondGraphLayerId = getNextLayerId(iFirstGraphLayerId ,
  2268. DownDirection ,
  2269. GraphVerticesLayer);
  2270. Q_ASSERT_X(iSecondGraphLayerId > 0 , "Global Crossing Reduction",
  2271. "Invalid second GraphVerticesLayer type layer id for Top-Down crossing reduction");
  2272. int iCrossingCount = 0;
  2273. int iSumPrevCrossings = 0;
  2274. double dMeanPrevCrossings = 0.0;
  2275. double dDeviation = 99999;
  2276. double dPrevDeviation = 10000;
  2277. boost::circular_buffer<int> cbPrevCrossingCounts(6);
  2278. int iReapeatTopDown = m_iTotalLayers * 2;
  2279. ////qDebug() << "Top-Down Crossing Counts:";
  2280. while(iReapeatTopDown--)
  2281. {
  2282. /*Sort Layers according to BarryCenter Method, staring
  2283. *from second GraphVerticesLayer type Layer
  2284. */
  2285. MapLayerIdToLayerRef::iterator iterLayerTopToDown
  2286. = m_mapLayeredGraph.find(iSecondGraphLayerId);
  2287. for(;iterLayerTopToDown != m_mapLayeredGraph.end();
  2288. iterLayerTopToDown++)
  2289. {
  2290. //Skip last layer
  2291. if(iterLayerTopToDown+1 != m_mapLayeredGraph.end())
  2292. {
  2293. /*Apply crossing reduction on only GraphVerticesLayers*/
  2294. iCurrentLayerId = iterLayerTopToDown.key();
  2295. if(iCurrentLayerId % m_iRankDifferenceInLayers == 0)
  2296. {
  2297. sortLayerByBarryCenters(iCurrentLayerId , DownDirection , Predecessor);
  2298. }
  2299. }
  2300. }
  2301. //Calculate crossings
  2302. iCrossingCount = getTotalCrossings();
  2303. //Calculate total of previous crossing counts
  2304. iSumPrevCrossings = std::accumulate(cbPrevCrossingCounts.begin() , cbPrevCrossingCounts.end(), 0);
  2305. //Calculate Previous crossings mean
  2306. if(cbPrevCrossingCounts.size() != 0)
  2307. {
  2308. dMeanPrevCrossings = ((double)iSumPrevCrossings / cbPrevCrossingCounts.size());
  2309. }
  2310. else
  2311. {
  2312. dMeanPrevCrossings = 0;
  2313. }
  2314. //Calculate deviation of current crossing count with mean of previous crossings
  2315. dDeviation = dMeanPrevCrossings - iCrossingCount;
  2316. //If current deviation is positive and equal to negative of previous deviation means the
  2317. //saturation state is achieved then stop
  2318. if(dDeviation >= 0)
  2319. {
  2320. if(dPrevDeviation <= 0)
  2321. {
  2322. if((dDeviation + dPrevDeviation) < 0.03 &&
  2323. (dDeviation + dPrevDeviation) > -0.03 )
  2324. {
  2325. ////qDebug() << "*** Stopping at saturation ***";
  2326. ////qDebug() << iCrossingCount <<" Mean: "<< dMeanPrevCrossings<< " Deviation: " << dDeviation;
  2327. break;
  2328. }
  2329. }
  2330. }
  2331. //store crossing
  2332. cbPrevCrossingCounts.push_back(iCrossingCount);
  2333. dPrevDeviation = dDeviation;
  2334. ////qDebug() << iCrossingCount <<" Mean: "<< dMeanPrevCrossings<< " Deviation: " << dDeviation ;
  2335. }
  2336. //***********************Bottom-Up***********************
  2337. //Start frm second last layer to Up
  2338. IteratorMapLayerIdToLayerRef iterLayerReverse(m_mapLayeredGraph);
  2339. iterLayerReverse.toBack();
  2340. iterLayerReverse.previous();
  2341. iLastLayerId = iterLayerReverse.key();
  2342. //find last GraphVerticesLayer type Layer Id
  2343. iLastGraphLayerId = getNextLayerId(iLastLayerId , UpDirection , GraphVerticesLayer);
  2344. iSecondLastGraphLayerId = getNextLayerId(iLastGraphLayerId , UpDirection , GraphVerticesLayer);
  2345. Q_ASSERT_X(iSecondLastGraphLayerId > 0 , "Global Crossing Reduction",
  2346. "Invalid second last GraphVerticesLayer type layer id for Bottom-Up crossing reduction");
  2347. int iRepeatBottomUp = m_iTotalLayers * 2;
  2348. ////qDebug() << "Bottom-Up Crossing Counts:";
  2349. while(iRepeatBottomUp--)
  2350. {
  2351. /*Sort Layers according to BarryCenter Method, staring
  2352. *from second last GraphVerticesLayer type Layer towards first layer
  2353. */
  2354. MapLayerIdToLayerRef::iterator iterLayerBottomToUp
  2355. = m_mapLayeredGraph.find(iSecondLastGraphLayerId);
  2356. for(;(iterLayerBottomToUp) != m_mapLayeredGraph.begin();
  2357. iterLayerBottomToUp--)
  2358. {
  2359. /*Apply crossing reduction on only GraphVerticesLayers
  2360. */
  2361. iCurrentLayerId = iterLayerBottomToUp.key();
  2362. if(iCurrentLayerId % m_iRankDifferenceInLayers == 0)
  2363. {
  2364. sortLayerByBarryCenters(iCurrentLayerId , UpDirection , Succesor);
  2365. }
  2366. }
  2367. // for(;true;
  2368. // iterLayerBottomToUp--)
  2369. // {
  2370. // /*Apply crossing reduction on only GraphVerticesLayers
  2371. // */
  2372. // iCurrentLayerId = iterLayerBottomToUp.key();
  2373. // if(iCurrentLayerId % m_iRankDifferenceInLayers == 0)
  2374. // {
  2375. // sortLayerByBarryCenters(iCurrentLayerId , UpDirection , Succesor);
  2376. // }
  2377. // if((iterLayerBottomToUp) != m_mapLayeredGraph.begin())
  2378. // {
  2379. // break;
  2380. // }
  2381. // }
  2382. //Calculate crossings
  2383. iCrossingCount = getTotalCrossings();
  2384. //Calculate mean or averageof previous crossing counts
  2385. iSumPrevCrossings = std::accumulate(cbPrevCrossingCounts.begin() , cbPrevCrossingCounts.end(), 0);
  2386. if(cbPrevCrossingCounts.size() != 0)
  2387. {
  2388. dMeanPrevCrossings = ((double)iSumPrevCrossings / cbPrevCrossingCounts.size());
  2389. }
  2390. else
  2391. {
  2392. dMeanPrevCrossings = 0;
  2393. }
  2394. dDeviation = dMeanPrevCrossings - iCrossingCount;
  2395. //If current deviation is positive and equal to negative of previous deviation means the
  2396. //saturation state is achieved then stop
  2397. if(dDeviation >= 0)
  2398. {
  2399. //Only if previous deviation is negative
  2400. if(dPrevDeviation <= 0)
  2401. {
  2402. //Current deviation is closer to negative previous deviation
  2403. if((dDeviation + dPrevDeviation) < 0.09 &&
  2404. (dDeviation + dPrevDeviation) > -0.09 )
  2405. {
  2406. ////qDebug() << "*** Stopping at saturation ***";
  2407. ////qDebug() << iCrossingCount <<" Mean: "<< dMeanPrevCrossings<< " Deviation: " << dDeviation;
  2408. break;
  2409. }
  2410. }
  2411. }
  2412. //store crossing
  2413. cbPrevCrossingCounts.push_back(iCrossingCount);
  2414. dPrevDeviation = dDeviation;
  2415. ////qDebug() << iCrossingCount <<" Mean: "<< dMeanPrevCrossings<< " Deviation: " << dDeviation;
  2416. }
  2417. }
  2418. }
  2419. void HierarchicalLayouter::sortLayerByBarryCenters(int iLayerId, ProcessDirection enDirection, NeighborNodes enNeighborNodes)
  2420. {
  2421. // XXX unused
  2422. Q_UNUSED(enDirection);
  2423. // Q_ASSERT_X(m_mapLayeredGraph.contains(iLayerId) ,
  2424. // "Sort Layer by Barry Center Method" ,
  2425. // "Invalid Layer Id provided");
  2426. LAYOUT_ASSERT(m_mapLayeredGraph.contains(iLayerId), LayoutException(__FUNCTION__,
  2427. LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER
  2428. ,"Layered Graph"
  2429. ,"LayerId"));
  2430. /*Prerequisite:
  2431. *1. Next Layer in the Direction have consistent
  2432. *iHorizontalPositions in Graph and at LayerNode
  2433. */
  2434. //////qDebug() << "Layer Id" << QString::number(iLayerId);//for testing
  2435. //Check if the provided iLayerId is not the first Layer in the provided direction
  2436. if(enNeighborNodes == Predecessor)
  2437. {
  2438. // Q_ASSERT_X(iLayerId != (m_mapLayeredGraph.constBegin()).key()
  2439. // , "Sort Layer by Barry Center Method" ,
  2440. // "Provided Layer is the first layer in the direction");
  2441. LAYOUT_ASSERT(iLayerId != (m_mapLayeredGraph.constBegin()).key()
  2442. , LayoutException(__FUNCTION__
  2443. , LayoutExceptionEnum::INVALID_OPERATION
  2444. , "Sort first layer in provided direction"
  2445. , "SortByBarryCenter"));
  2446. }
  2447. else if(enNeighborNodes == Succesor)//Up Direction
  2448. {
  2449. // Q_ASSERT_X(iLayerId != (m_mapLayeredGraph.constEnd()).key() , "Sort Layer by Barry Center Method" ,
  2450. // "Provided Layer is the first layer in the direction");
  2451. LAYOUT_ASSERT(iLayerId != (m_mapLayeredGraph.constEnd()).key()
  2452. , LayoutException(__FUNCTION__
  2453. , LayoutExceptionEnum::INVALID_OPERATION
  2454. , "Sort first layer in provided direction"
  2455. , "SortByBarryCenter"));
  2456. }
  2457. //Multimap BarryCenter to LayerNode, to have LayerNodes sorted on BarryCenter Weights
  2458. MultiMapBarryCenterToLayerNode mapBarryCenterToLayerNode;
  2459. /*Layer Id of next layer can be checked when we have successor or
  2460. *predecessors of current layerNode vertex at layers farther than
  2461. *adjacent layers, so we can control to choose the layer nodes for
  2462. *calculating BarryCenter using only adjacent( Upper or down) layers
  2463. *or the layers which are not adjacent and still contain a
  2464. *Layer vertex which is a predecessor or successor of current Layer vertex
  2465. *
  2466. *It is required if 'Sparse Long Edge Splitting' is done
  2467. */
  2468. //Find next graph-layer id in specified direction
  2469. //**commented for Testing42014
  2470. // int iNextGraphLayerId = 0;
  2471. // iNextGraphLayerId = getNextLayerId(iLayerId , enDirection , GraphVerticesLayer);
  2472. // //1:
  2473. int iBadLayerNodeCount = 0;
  2474. // XXX unused
  2475. Q_UNUSED(iBadLayerNodeCount);
  2476. // iBadLayerNodeCount = testGetLayerKeysAndVertexPositionNotConsistentCount(*(m_mapLayeredGraph[iNextGraphLayerId]), *m_gMainGraph);
  2477. //////qDebug() << "Next Layer- Inconsistent HorizontalPosition LayerNodes Count :" << QString::number(iBadLayerNodeCount);
  2478. //Q_ASSERT_X(iBadLayerNodeCount == 0 , "Sort Layer by Barry Center Method" , "Next Layer contains LayerNodes with inconsistent HorizontalPosition");
  2479. try
  2480. {
  2481. LayerNode *currentLayerNode = NULL;
  2482. double dBarryCenterWeight = 0;
  2483. double dNextNodeCount = 0;
  2484. int iHorizontalPosition = 0;
  2485. VertexDescriptor vCurrentVertex = 0;
  2486. VertexDescriptor vPredecessor = 0;
  2487. VertexDescriptor vSuccessor = 0;
  2488. InEdgeIterator iterInEdge , iterInEdgeEnd;
  2489. AdjacencyIterator iterAdjacentVertex , iterAdjacentVertexEnd;
  2490. //Calculate BarryCenter Weights for current Layer nodes
  2491. IteratorMapPositionToLayerNode iterLayerNode(*(m_mapLayeredGraph[iLayerId]));
  2492. while(iterLayerNode.hasNext())
  2493. {
  2494. iterLayerNode.next();
  2495. //Get Layer Node
  2496. currentLayerNode = iterLayerNode.value();
  2497. vCurrentVertex = currentLayerNode->getVertex();
  2498. //Reset variables
  2499. dBarryCenterWeight = 0.0;
  2500. dNextNodeCount = 0.0;
  2501. iHorizontalPosition = 0;
  2502. //Iterate next nodes in the Direction
  2503. if(enNeighborNodes == Predecessor)
  2504. {
  2505. //Iterate predecessors
  2506. for(boost::tie(iterInEdge , iterInEdgeEnd) = in_edges(vCurrentVertex , *m_gMainGraph);
  2507. iterInEdge != iterInEdgeEnd;
  2508. iterInEdge++)
  2509. {
  2510. //Get predecessor
  2511. vPredecessor = m_BoostGraphWrapper.getEdgeSource(*iterInEdge , *m_gMainGraph);
  2512. //Get iHorizontal Position
  2513. iHorizontalPosition = m_BoostGraphWrapper.getVertexHorizontalPosition(vPredecessor, *m_gMainGraph);
  2514. dBarryCenterWeight += iHorizontalPosition;
  2515. dNextNodeCount++;
  2516. }
  2517. }
  2518. else if(enNeighborNodes == Succesor)
  2519. {
  2520. //Iterate successors
  2521. for(boost::tie(iterAdjacentVertex , iterAdjacentVertexEnd) = adjacent_vertices(vCurrentVertex , *m_gMainGraph);
  2522. iterAdjacentVertex != iterAdjacentVertexEnd;
  2523. iterAdjacentVertex++)
  2524. {
  2525. //Get successor
  2526. vSuccessor = *iterAdjacentVertex;
  2527. //Get iHorizontal Position
  2528. iHorizontalPosition = m_BoostGraphWrapper.getVertexHorizontalPosition(vSuccessor, *m_gMainGraph);
  2529. dBarryCenterWeight += iHorizontalPosition;
  2530. dNextNodeCount++;
  2531. }
  2532. }
  2533. //Calculate BarryCenter if there are previous layer neighbor nodes
  2534. if(dNextNodeCount > 0)
  2535. {
  2536. dBarryCenterWeight /= dNextNodeCount;
  2537. m_BoostGraphWrapper.setVertexBarryCenter(vCurrentVertex , *m_gMainGraph , dBarryCenterWeight);
  2538. }
  2539. dBarryCenterWeight = m_BoostGraphWrapper.getVertexBarryCenter(vCurrentVertex , *m_gMainGraph);
  2540. m_BoostGraphWrapper.setVertexBarryCenter(vCurrentVertex , *m_gMainGraph , dBarryCenterWeight);
  2541. //Add BarryCenter to LayerNode entry to QMultiMap
  2542. mapBarryCenterToLayerNode.insertMulti(dBarryCenterWeight , currentLayerNode);
  2543. }
  2544. //Delete and set Null old Layer
  2545. DELETE_AND_SET_NULL(m_mapLayeredGraph[iLayerId]);
  2546. //Create layer sorted according to BarryCenter Weights
  2547. MapPositionToLayerNode *newLayer = new MapPositionToLayerNode();
  2548. //Insert new Layer into layered graph
  2549. //m_mapLayeredGraph.insert(iLayerId , newLayer); //OR
  2550. m_mapLayeredGraph[iLayerId] = newLayer;
  2551. //Reset
  2552. iHorizontalPosition = 1;
  2553. vCurrentVertex = 0;
  2554. //Copy LayerNodes sorted on their BarryCenter Weight to new Layer
  2555. IteratorMultiMapBarryCenterToLayerNode iterBarryCenterLayerNode(mapBarryCenterToLayerNode);
  2556. LayerNode* layerNodeFromBarryCenter = NULL;
  2557. while(iterBarryCenterLayerNode.hasNext())
  2558. {
  2559. iterBarryCenterLayerNode.next();
  2560. //Get LayerNode
  2561. layerNodeFromBarryCenter = iterBarryCenterLayerNode.value();
  2562. vCurrentVertex = layerNodeFromBarryCenter->getVertex();
  2563. //insert LayerNode to Layer
  2564. newLayer->insert(iHorizontalPosition , layerNodeFromBarryCenter);
  2565. //Update iHorizotalPosition
  2566. m_BoostGraphWrapper.setVertexHorizontalPosition(vCurrentVertex , *m_gMainGraph , iHorizontalPosition);
  2567. iHorizontalPosition++;
  2568. }
  2569. iBadLayerNodeCount = testGetLayerKeysAndVertexPositionNotConsistentCount(*newLayer , *m_gMainGraph);
  2570. //Q_ASSERT_X(iBadLayerNodeCount == 0 , "Sort Layer by Barry Center Method" , "NEW Layer contains LayerNodes with inconsistent HorizontalPosition");
  2571. LAYOUT_ASSERT(iBadLayerNodeCount == 0, LayoutException(__FUNCTION__
  2572. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  2573. , "Layer"
  2574. ,""));
  2575. //////qDebug() << "Inconsistent HorizontalPosition LayerNodes Count :" << QString::number(iBadLayerNodeCount);
  2576. }
  2577. catch(boost::exception &eBoostException)
  2578. {
  2579. throw *boost::get_error_info<errmsg_info>(eBoostException);
  2580. }
  2581. catch(LayoutException &eLayoutException)
  2582. {
  2583. throw eLayoutException;
  2584. }
  2585. catch(...)
  2586. {
  2587. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  2588. }
  2589. }
  2590. void HierarchicalLayouter::reduceEdgeCrossings(int iCrossingReductionDegree)
  2591. {
  2592. // XXX unused
  2593. Q_UNUSED(iCrossingReductionDegree);
  2594. /*BarryCenter Crossing Reduction requires at least two layers for
  2595. *crossing reduction
  2596. *
  2597. *This process is done top-down and bottom-up for better results
  2598. */
  2599. /*Prerequesits:
  2600. *1. Graph has proper hierarchy
  2601. *2. Nesting Tree is created
  2602. *3. Layered Graph is created
  2603. */
  2604. try
  2605. {
  2606. int iLayerId = 0;
  2607. // XXX unused
  2608. Q_UNUSED(iLayerId);
  2609. int iTotalCrossings = 0;
  2610. ConstantType<int> iTotalVertices;
  2611. iTotalVertices = num_vertices(*m_gMainGraph);
  2612. qDebug() << "iTotalVertices =" << iTotalVertices;
  2613. qDebug() << "reduceEdgeCrossings() crashes";
  2614. // return;
  2615. //TODO: user input iCrossingReduction Degree
  2616. iCrossingReductionDegree = 200;
  2617. int iCrossingIter = 20;//m_mapLayeredGraph.size() * 2;
  2618. int iCurrentCrossing = 0;
  2619. int iPrevCrossing = 0;
  2620. int iCrossingStabilityMargin = 0;
  2621. // XXX unused
  2622. Q_UNUSED(iCurrentCrossing);
  2623. Q_UNUSED(iPrevCrossing);
  2624. Q_UNUSED(iCrossingStabilityMargin);
  2625. bool bUpwardDirection = false;
  2626. QString sCrossingsCount = "";
  2627. //TODO: Accept 'Crossing Degree' from user to decide number of iterations
  2628. //Iterate still Number of Crossings is unsatisfactory
  2629. //while(iTotalCrossings <= iCrossingReductionDegree)
  2630. //Check if graph has atleast 1 vertex i.e. 1 vertex + 2 Border vertices -upper and lower
  2631. //therefor total 3 vertices
  2632. if(iTotalVertices >= 3)
  2633. {
  2634. while(iCrossingIter--)
  2635. {
  2636. // XXX #warning "crash"
  2637. // causes crash
  2638. crossingReductionByReducedNestingTree(bUpwardDirection);
  2639. crossingReductionBySubgraphOrderingGraph(bUpwardDirection);
  2640. //*****************************************
  2641. iTotalCrossings = getTotalCrossings();
  2642. if(bUpwardDirection)
  2643. {
  2644. qDebug() << "Crossing (BottomUp): "<<iTotalCrossings;
  2645. sCrossingsCount.append("Crossing (BottomUp):");
  2646. sCrossingsCount.append(QString::number(iTotalCrossings));
  2647. sCrossingsCount.append("\n");
  2648. }
  2649. else
  2650. {
  2651. qDebug() << "Crossing (TopDown): "<<iTotalCrossings;
  2652. sCrossingsCount.append("Crossing (TopDown):");
  2653. sCrossingsCount.append(QString::number(iTotalCrossings));
  2654. sCrossingsCount.append("\n");
  2655. sCrossingsCount.append("---------------\n");
  2656. }
  2657. //if(iTotalCrossings == 0)
  2658. //{
  2659. //break;
  2660. //}
  2661. //Reverse process
  2662. bUpwardDirection = !bUpwardDirection;
  2663. }
  2664. }
  2665. }
  2666. catch(boost::exception &eBoostException)
  2667. {
  2668. throw *boost::get_error_info<errmsg_info>(eBoostException);
  2669. }
  2670. catch(LayoutException &eLayoutException)
  2671. {
  2672. throw eLayoutException;
  2673. }
  2674. // XXX obselete
  2675. // catch(LayoutMemoryException &eMemoryException)
  2676. // {
  2677. // throw eMemoryException;
  2678. // }
  2679. catch(...)
  2680. {
  2681. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  2682. }
  2683. }
  2684. void HierarchicalLayouter::crossingReductionByReducedNestingTree(bool bIsUpwardDirection)
  2685. {
  2686. int iLayerId = 0;
  2687. try
  2688. {
  2689. MapLayerIdToLayerRef::iterator iterLayer;
  2690. if(bIsUpwardDirection == false)
  2691. {
  2692. /*Rank difference in layers always the rank of first layer with
  2693. *graph nodes if the graph has atleast 1 graph_vertex
  2694. */
  2695. //iterLayer = m_mapLayeredGraph.find(m_iRankDifferenceInLayers);
  2696. iterLayer = m_mapLayeredGraph.begin(); //Testing 42114-1
  2697. iLayerId = iterLayer.key();
  2698. }
  2699. else
  2700. {
  2701. iterLayer = m_mapLayeredGraph.end();
  2702. //Last layer
  2703. iterLayer--;
  2704. //Layer id of last layer
  2705. iLayerId = iterLayer.key();
  2706. // Commented for Testing 42114-1
  2707. // //Coming to last graph layer LayerId
  2708. // iLayerId -= iLayerId % m_iRankDifferenceInLayers;
  2709. // iterLayer = m_mapLayeredGraph.find(iLayerId);
  2710. }
  2711. ////qDebug() <<"Iterate Layer from: ";
  2712. ////qDebug() << iLayerId;
  2713. //sort first layer according to Reduced Nested Tree
  2714. doSortedTraversalByReducedNestingTree(iLayerId);
  2715. if(bIsUpwardDirection == true)
  2716. {
  2717. iterLayer--;
  2718. }
  2719. else
  2720. {
  2721. iterLayer++;
  2722. }
  2723. //For layer 2 to n
  2724. while(iterLayer != m_mapLayeredGraph.end())
  2725. {
  2726. //Sort current layer by barrycenter weights
  2727. //Sort current layer by sorted traversal of Reduced Nesting Tree
  2728. //This produces a placement with unbroken sequences of subgraph nodes in current layer
  2729. iLayerId = iterLayer.key();
  2730. ////qDebug() << iLayerId;
  2731. //if(iLayerId % m_iRankDifferenceInLayers == 0) // Commented for Testing42014-1
  2732. {
  2733. //Sort current layer by barrycenter weights
  2734. if(bIsUpwardDirection == false)
  2735. {
  2736. sortLayerByBarryCenters(iLayerId , DownDirection , Predecessor);
  2737. }
  2738. else
  2739. {
  2740. sortLayerByBarryCenters(iLayerId , UpDirection , Succesor);
  2741. }
  2742. //Sort current layer by sorted traversal of Reduced Nesting Tree
  2743. doSortedTraversalByReducedNestingTree(iLayerId);
  2744. }
  2745. if(bIsUpwardDirection == true)
  2746. {
  2747. if(iterLayer == m_mapLayeredGraph.begin())
  2748. {
  2749. break;
  2750. }
  2751. iterLayer--;
  2752. }
  2753. else
  2754. {
  2755. iterLayer++;
  2756. }
  2757. }
  2758. }
  2759. catch(boost::exception &eBoostException)
  2760. {
  2761. throw *boost::get_error_info<errmsg_info>(eBoostException);
  2762. }
  2763. catch(LayoutException &eLayoutException)
  2764. {
  2765. throw eLayoutException;
  2766. }
  2767. catch(...)
  2768. {
  2769. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  2770. }
  2771. }
  2772. void HierarchicalLayouter::crossingReductionBySubgraphOrderingGraph(bool bIsUpwardDirection)
  2773. {
  2774. try
  2775. {
  2776. int iLayerId = 0;
  2777. MapLayerIdToLayerRef::iterator iterLayer;
  2778. if(bIsUpwardDirection == false)
  2779. {
  2780. /*Rank difference in layers always the rank of first layer with
  2781. *graph nodes if the graph has atleast 1 graph_vertex
  2782. */
  2783. //iterLayer = m_mapLayeredGraph.find(m_iRankDifferenceInLayers);
  2784. iterLayer = m_mapLayeredGraph.begin();//Testing 42114-1
  2785. iLayerId = iterLayer.key();
  2786. }
  2787. else
  2788. {
  2789. iterLayer = m_mapLayeredGraph.end();
  2790. //Last layer
  2791. iterLayer--;
  2792. //Layer id of last layer
  2793. iLayerId = iterLayer.key();
  2794. // Commented for Testing 42114-1
  2795. // //Coming to last graph layer LayerId
  2796. // iLayerId -= iLayerId % m_iRankDifferenceInLayers;
  2797. // iterLayer = m_mapLayeredGraph.find(iLayerId);
  2798. }
  2799. ////qDebug() << "-----------------------------";
  2800. //**Calculate Subgraph Ordering Graph OG
  2801. //**Sort OG topologically, break cycles if necessary
  2802. //LayersSubgraphSorter sorter();
  2803. //**
  2804. //Create SubgraphOrderingGraph
  2805. generateSubgraphOrderingGraph();
  2806. bool bIsSubgraphOrderingGraphCorrect = testSubgraphOrderingGraph();
  2807. // XXX unused
  2808. Q_UNUSED(bIsSubgraphOrderingGraphCorrect);
  2809. LAYOUT_ASSERT(bIsSubgraphOrderingGraphCorrect == true,
  2810. LayoutException(__FUNCTION__
  2811. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  2812. , "Subgraph ordering graph"
  2813. , ""));
  2814. //Update average BarryCenter positions of NestingTreeNode
  2815. updateAverageBarryCenterForNestingTreeNodes();
  2816. //Remove cycles in SubgraphOrderingGraph
  2817. removeCycleFromSubgraphOrderingGraph();
  2818. ////qDebug() << "--Removing Cycle From SOG--";
  2819. //Assign topological order to original graph vertices according to SubgraphOrderingGraphs
  2820. assignTopologicalOrderAccordingToSubgraphOrderingGraph(1,&m_rootNestingTreeSubgraphNode);
  2821. ////qDebug() <<"Iterate Layer from: ";
  2822. ////qDebug() <<"SOG Sort "<< iLayerId;
  2823. //Sort first layer according iTopologicalOrder
  2824. sortLayerByTopologicalOrder(iLayerId);
  2825. if(bIsUpwardDirection == true)
  2826. {
  2827. iterLayer--;
  2828. }
  2829. else
  2830. {
  2831. iterLayer++;
  2832. }
  2833. //For layer 2 to n
  2834. while(iterLayer != m_mapLayeredGraph.end())
  2835. {
  2836. iLayerId = iterLayer.key();
  2837. ////qDebug() <<"SOG Sort "<< iLayerId;
  2838. //if(iLayerId % m_iRankDifferenceInLayers == 0)//42114-1
  2839. {
  2840. //Calculate AverageBarryCenter weigths
  2841. updateAverageBarryCenterForNestingTreeNodes();
  2842. //Assign new topological ordering
  2843. assignTopologicalOrderAccordingToSubgraphOrderingGraph( 1 , &m_rootNestingTreeSubgraphNode);
  2844. //Sort current layer by SubgraphOrderingGraph topological order
  2845. sortLayerByTopologicalOrder(iLayerId);
  2846. }
  2847. ////qDebug() << "-----------------------------";
  2848. if(bIsUpwardDirection == true)
  2849. {
  2850. if(iterLayer == m_mapLayeredGraph.begin())
  2851. {
  2852. break;
  2853. }
  2854. iterLayer--;
  2855. }
  2856. else
  2857. {
  2858. iterLayer++;
  2859. }
  2860. }
  2861. }
  2862. catch(boost::exception &eBoostException)
  2863. {
  2864. throw *boost::get_error_info<errmsg_info>(eBoostException);
  2865. }
  2866. catch(LayoutException &eLayoutException)
  2867. {
  2868. throw eLayoutException;
  2869. }
  2870. // XXX obselete
  2871. // catch(LayoutMemoryException &eMemoryException)
  2872. // {
  2873. // throw eMemoryException;
  2874. // }
  2875. catch(...)
  2876. {
  2877. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  2878. }
  2879. }
  2880. void HierarchicalLayouter::crosingReductionFinalTopologicalSorting()
  2881. {
  2882. int iLayerId = 0;
  2883. int iIteration = 1; // 1 for downward and 1 for upward
  2884. MapLayerIdToLayerRef::iterator iterLayer;
  2885. bool bIsUpwardDirection = false;
  2886. ////qDebug() << "SOG Sort with Single SubgraphOrderingGraph";
  2887. while(iIteration--)
  2888. {
  2889. if(bIsUpwardDirection == false)
  2890. {
  2891. /*Rank difference in layers always the rank of first layer with
  2892. *graph nodes if the graph has atleast 1 graph_vertex
  2893. */
  2894. //iterLayer = m_mapLayeredGraph.find(m_iRankDifferenceInLayers);
  2895. iterLayer = m_mapLayeredGraph.begin();//Testing 42114-1
  2896. iLayerId = iterLayer.key();
  2897. }
  2898. else
  2899. {
  2900. iterLayer = m_mapLayeredGraph.end();
  2901. //Last layer
  2902. iterLayer--;
  2903. //Layer id of last layer
  2904. iLayerId = iterLayer.key();
  2905. // Commented for Testing 42114-1
  2906. // //Coming to last graph layer LayerId
  2907. // iLayerId -= iLayerId % m_iRankDifferenceInLayers;
  2908. // iterLayer = m_mapLayeredGraph.find(iLayerId);
  2909. }
  2910. //**Calculate Subgraph Ordering Graph OG
  2911. //**Sort OG topologically, break cycles if necessary
  2912. //LayersSubgraphSorter sorter();
  2913. //**
  2914. //Create SubgraphOrderingGraph
  2915. generateSubgraphOrderingGraph();
  2916. bool bIsSubgraphOrderingGraphCorrect = testSubgraphOrderingGraph();
  2917. // XXX unused
  2918. Q_UNUSED(bIsSubgraphOrderingGraphCorrect);
  2919. LAYOUT_ASSERT(bIsSubgraphOrderingGraphCorrect == true, LayoutException(__FUNCTION__
  2920. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  2921. , "SubgraphOrderingGraphCorrect"
  2922. , "in Crossing Reduction"));
  2923. //Update average BarryCenter positions of NestingTreeNode
  2924. updateAverageBarryCenterForNestingTreeNodes();
  2925. //Remove cycles in SubgraphOrderingGraph
  2926. removeCycleFromSubgraphOrderingGraph();
  2927. ////qDebug() << "--Removing Cycle From SOG--";
  2928. //Assign topological order to original graph vertices according to SubgraphOrderingGraphs
  2929. assignTopologicalOrderAccordingToSubgraphOrderingGraph(1,&m_rootNestingTreeSubgraphNode);
  2930. ////qDebug() <<"Iterate Layer from: ";
  2931. ////qDebug() <<"SOG Sort "<< iLayerId;
  2932. //Sort first layer according iTopologicalOrder
  2933. sortLayerByTopologicalOrder(iLayerId);
  2934. if(bIsUpwardDirection == true)
  2935. {
  2936. iterLayer--;
  2937. }
  2938. else
  2939. {
  2940. iterLayer++;
  2941. }
  2942. //For layer 2 to n
  2943. while(iterLayer != m_mapLayeredGraph.end())
  2944. {
  2945. iLayerId = iterLayer.key();
  2946. ////qDebug() <<"SOG Sort "<< iLayerId;
  2947. //if(iLayerId % m_iRankDifferenceInLayers == 0)//Only GraphLayerNodes
  2948. {
  2949. //Sort current layer by SubgraphOrderingGraph topological order
  2950. sortLayerByTopologicalOrder(iLayerId);
  2951. }
  2952. if(bIsUpwardDirection == true)
  2953. {
  2954. if(iterLayer == m_mapLayeredGraph.begin())
  2955. {
  2956. break;
  2957. }
  2958. iterLayer--;
  2959. }
  2960. else
  2961. {
  2962. iterLayer++;
  2963. }
  2964. }
  2965. bIsUpwardDirection = !bIsUpwardDirection;
  2966. }
  2967. }
  2968. void HierarchicalLayouter::sortLayerByTopologicalOrder(int iLayerId)
  2969. {
  2970. try
  2971. {
  2972. LAYOUT_ASSERT(m_mapLayeredGraph.contains(iLayerId)
  2973. , LayoutException(__FUNCTION__
  2974. , LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER
  2975. , "Layered Graph"
  2976. , "Layer Id"));
  2977. int iInconsistentLayerNodeCount = testGetLayerKeysAndVertexPositionNotConsistentCount(*(m_mapLayeredGraph[iLayerId]) , *m_gMainGraph);
  2978. // XXX unused
  2979. Q_UNUSED(iInconsistentLayerNodeCount);
  2980. LAYOUT_ASSERT(iInconsistentLayerNodeCount == 0,
  2981. LayoutException(__FUNCTION__
  2982. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  2983. , "Layer"
  2984. , ""));
  2985. ////qDebug() << "Sorting Topologically , Layer: "<<iLayerId;
  2986. QMap<int , QVector<LayerNode*> > mapTopologicalOrderToVectorLayerNodeRef;
  2987. IteratorMapPositionToLayerNode iterLayerNode(*(m_mapLayeredGraph[iLayerId]));
  2988. int iTopologicalOrder = 0;
  2989. LayerNode* currentLayerNode = NULL;
  2990. VertexDescriptor vCurrentVertex = 0;
  2991. //Add LayerNodes to vectors which will preserve their sequence of insertion. For each topological order
  2992. //value there is separate vector
  2993. while(iterLayerNode.hasNext())
  2994. {
  2995. iterLayerNode.next();
  2996. //Get layerNode
  2997. currentLayerNode = iterLayerNode.value();
  2998. //Get TopologicalOrder
  2999. vCurrentVertex = currentLayerNode->getVertex();
  3000. iTopologicalOrder = m_BoostGraphWrapper.getVertexTopologicalOrder(vCurrentVertex , *m_gMainGraph);
  3001. //Add to map
  3002. mapTopologicalOrderToVectorLayerNodeRef[iTopologicalOrder].push_back(currentLayerNode);
  3003. }
  3004. int iOldLayerNodeCount = m_mapLayeredGraph[iLayerId]->size();
  3005. // XXX unused
  3006. Q_UNUSED(iOldLayerNodeCount);
  3007. //Delete and set Null old Layer
  3008. DELETE_AND_SET_NULL(m_mapLayeredGraph[iLayerId]);
  3009. //Create layer sorted according to BarryCenter Weights
  3010. MapPositionToLayerNode *newLayer = new MapPositionToLayerNode();
  3011. //Insert new Layer into layered graph
  3012. m_mapLayeredGraph[iLayerId] = newLayer;
  3013. int iHorizontalPosition = 1;
  3014. //Add layerNodes to new layer
  3015. QMapIterator<int , QVector<LayerNode*> > iterMapTopologicalOrderToVectorLayerNodeRef(
  3016. mapTopologicalOrderToVectorLayerNodeRef);
  3017. //Iterate according to iTopologicalOrder value
  3018. while(iterMapTopologicalOrderToVectorLayerNodeRef.hasNext())
  3019. {
  3020. iterMapTopologicalOrderToVectorLayerNodeRef.next();
  3021. iTopologicalOrder = iterMapTopologicalOrderToVectorLayerNodeRef.key();
  3022. //////qDebug() <<"Topo Order: "<<iTopologicalOrder << " adding nodes";
  3023. QVectorIterator<LayerNode*> iterVectorLayerNodeRef(
  3024. iterMapTopologicalOrderToVectorLayerNodeRef.value());
  3025. //Add nodes with same topological order value while preserving their insertion sequence
  3026. while(iterVectorLayerNodeRef.hasNext())
  3027. {
  3028. currentLayerNode = iterVectorLayerNodeRef.next();
  3029. //Add layerNode to newLayer
  3030. newLayer->insert(iHorizontalPosition , currentLayerNode);
  3031. vCurrentVertex = currentLayerNode->getVertex();
  3032. //Update new iHorizontalPosition of LayerNode in vertex property iHorizontalPosition
  3033. m_BoostGraphWrapper.setVertexHorizontalPosition(vCurrentVertex
  3034. , *m_gMainGraph
  3035. , iHorizontalPosition);
  3036. iHorizontalPosition++;
  3037. }
  3038. }
  3039. LAYOUT_ASSERT(iOldLayerNodeCount == newLayer->size()
  3040. , LayoutException(__FUNCTION__
  3041. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  3042. , "after sorting it by topological order"
  3043. , "Layer"));
  3044. bool bIsLayerSortedTopologically = testIsLayerTopologicallySorted(iLayerId);
  3045. // XXX unused
  3046. Q_UNUSED(bIsLayerSortedTopologically);
  3047. LAYOUT_ASSERT(bIsLayerSortedTopologically == true
  3048. ,LayoutException(__FUNCTION__
  3049. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  3050. , "not properly sorted according to topological order"
  3051. , "Layer"));
  3052. iInconsistentLayerNodeCount = testGetLayerKeysAndVertexPositionNotConsistentCount(*(m_mapLayeredGraph[iLayerId]) , *m_gMainGraph);
  3053. LAYOUT_ASSERT(iInconsistentLayerNodeCount == 0
  3054. ,LayoutException(__FUNCTION__
  3055. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  3056. , "with inconsistent node positions"
  3057. , "Layer"));
  3058. }
  3059. catch(boost::exception &eBoostException)
  3060. {
  3061. throw *boost::get_error_info<errmsg_info>(eBoostException);
  3062. }
  3063. catch(LayoutException &eLayoutException)
  3064. {
  3065. throw eLayoutException;
  3066. }
  3067. // XXX obselet
  3068. // catch(LayoutMemoryException &eMemoryException)
  3069. // {
  3070. // throw eMemoryException;
  3071. // }
  3072. catch(...)
  3073. {
  3074. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  3075. }
  3076. }
  3077. void HierarchicalLayouter::doSortedTraversalByReducedNestingTree(int iLayerId)
  3078. {
  3079. //Q_ASSERT_X(m_mapLayeredGraph.contains(iLayerId) == true , "doSortedTraversalByReducedNestingTree","Invalid layer id passed");
  3080. try
  3081. {
  3082. LAYOUT_ASSERT(m_mapLayeredGraph.contains(iLayerId) == true , LayoutException(__FUNCTION__
  3083. ,LayoutExceptionEnum::INVALID_PARAMETER
  3084. ,QString::number(iLayerId)
  3085. ,"Layer Id"));
  3086. //Create Reduced Nested Tree for iLayerId layer
  3087. ReducedNestingTreeNode *reducedNestingTree = NULL;
  3088. reducedNestingTree = new ReducedNestingTreeNode();
  3089. createReducedNestedTree(iLayerId
  3090. , m_rootNestingTreeSubgraphNode
  3091. , *reducedNestingTree);
  3092. int iTotalLayerNodes = m_mapLayeredGraph[iLayerId]->size();
  3093. int iTotalReducedTreeLayerNodes = reducedNestingTree->getChildLayerNodeCount();
  3094. // XXX unused
  3095. Q_UNUSED(iTotalLayerNodes);
  3096. Q_UNUSED(iTotalReducedTreeLayerNodes);
  3097. ////qDebug() << "LNodes: " << iTotalLayerNodes << " RNT LNodes: " << iTotalReducedTreeLayerNodes;
  3098. //Q_ASSERT_X(iTotalLayerNodes == iTotalReducedTreeLayerNodes , "Do Sorted Traversal By Reduced Nesting Tree" , "Total layer nodes in layer and in Reduced Nested Tree are not equal");
  3099. LAYOUT_ASSERT(iTotalLayerNodes == iTotalReducedTreeLayerNodes , LayoutException(__FUNCTION__
  3100. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  3101. , "Mismatched layer node count"
  3102. , "Reduced Nesting Tree"));
  3103. // if(iTotalLayerNodes != iTotalReducedTreeLayerNodes)
  3104. // {
  3105. // ////qDebug() << "Mismatched layer node count above";
  3106. // }
  3107. //Sorted traversal according to Reduced Nesting Tree
  3108. MapPositionToLayerNode *newLayer = new MapPositionToLayerNode();
  3109. generateLayerByReducedNestingTree(*newLayer , *reducedNestingTree);
  3110. //Test the size of old layer and new layer are same
  3111. int iSizeOfOldLayer = m_mapLayeredGraph[iLayerId]->size();
  3112. int iSizeOfNewLayer = newLayer->size();
  3113. // XXX unused
  3114. Q_UNUSED(iSizeOfOldLayer);
  3115. Q_UNUSED(iSizeOfNewLayer);
  3116. //Q_ASSERT_X(iSizeOfOldLayer == iSizeOfNewLayer , "Do Sorted Traversal By Reduced Nesting Tree" , "Total layer nodes in old layer and in new Layer which is sorted by RNT are not equal");
  3117. LAYOUT_ASSERT(iSizeOfOldLayer == iSizeOfNewLayer , LayoutException(__FUNCTION__
  3118. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  3119. , "Total layer nodes in old layer and in new Layer which is sorted by RNT are not equal"
  3120. , "Layer"));
  3121. //Delete old layer
  3122. DELETE_AND_SET_NULL(m_mapLayeredGraph[iLayerId]);
  3123. //Set new layer
  3124. m_mapLayeredGraph[iLayerId] = newLayer;
  3125. }
  3126. catch(boost::exception &eBoostException)
  3127. {
  3128. throw *boost::get_error_info<errmsg_info>(eBoostException);
  3129. }
  3130. catch(LayoutException &eLayoutException)
  3131. {
  3132. throw eLayoutException;
  3133. }
  3134. catch(...)
  3135. {
  3136. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  3137. }
  3138. }
  3139. void HierarchicalLayouter::createReducedNestedTree(int iLayerId, NestingTreeSubgraphNode &nestingTreeRootNode, ReducedNestingTreeNode &reducedNestingTreeNode)
  3140. {
  3141. // Q_ASSERT_X(m_mapLayeredGraph.contains(iLayerId) == true , "doSortedTraversalByReducedNestingTree",
  3142. // "Invalid layer id passed");
  3143. try
  3144. {
  3145. LAYOUT_ASSERT(m_mapLayeredGraph.contains(iLayerId) == true , LayoutException(__FUNCTION__
  3146. , LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER
  3147. , "Layered Graph"
  3148. , "Layer Id"));
  3149. //Set Nesting tree node to current Reduced Nesting Tree Node
  3150. reducedNestingTreeNode.setNestingTreeNode(&nestingTreeRootNode);
  3151. //RNT - Reduced Nesting Tree
  3152. int iCountTotalLayerNodes = 0;
  3153. double dTotalAveragePosition = 0.0;
  3154. ReducedNestingTreeNode* newReducedNestingTreeNode = NULL;
  3155. //Iterate child nesting tree nodes
  3156. NestingTreeSubgraphNode::VectorNestingTreeSubgraphNodesRef vecChildNestingTreeNodes = nestingTreeRootNode.getChildNestingTreeSubgraphNodes();
  3157. NestingTreeSubgraphNode::VectorNestingTreeSubgraphNodesRef::iterator iterNestingTreeNode
  3158. = vecChildNestingTreeNodes.begin();
  3159. NestingTreeSubgraphNode::VectorNestingTreeSubgraphNodesRef::iterator iterEndNestingTreeNode
  3160. = vecChildNestingTreeNodes.end();
  3161. while(iterNestingTreeNode != iterEndNestingTreeNode)
  3162. {
  3163. NestingTreeSubgraphNode* childNestingTreeNode = *iterNestingTreeNode;
  3164. if(childNestingTreeNode->doesSubgraphNodeContainLayerId(iLayerId))
  3165. {
  3166. //Create new RNT
  3167. newReducedNestingTreeNode = new ReducedNestingTreeNode();
  3168. //Recursive call
  3169. createReducedNestedTree(iLayerId , *childNestingTreeNode , *newReducedNestingTreeNode);
  3170. //Add new reduced nesting tree node to child list of current RNT Node
  3171. double dChildAveragePosition = newReducedNestingTreeNode->getAveragePosition();
  3172. int iChildLayerNodeCount = newReducedNestingTreeNode->getChildLayerNodeCount();
  3173. reducedNestingTreeNode.addChildNode( dChildAveragePosition,
  3174. newReducedNestingTreeNode);
  3175. //Increament child Layer Node counter
  3176. iCountTotalLayerNodes += iChildLayerNodeCount;
  3177. //Accumulate new reduced nesting tree node average position
  3178. dTotalAveragePosition += dChildAveragePosition * iChildLayerNodeCount;
  3179. }
  3180. iterNestingTreeNode++;
  3181. }
  3182. //Iterate layer nodes (vertices) of current nesting Tree Node
  3183. NestingTreeSubgraphNode::MultiMapLayerIdToLayerNodeRef mapLayerNodes
  3184. = nestingTreeRootNode.getMapLayerIdToLayerNodeRef();
  3185. //Get list of layer nodes with rank equal to iLayerId
  3186. QList<LayerNode*> listLayerNodes = mapLayerNodes.values(iLayerId);
  3187. QListIterator<LayerNode*> iterListLayerNodes(listLayerNodes);
  3188. while(iterListLayerNodes.hasNext())
  3189. {
  3190. LayerNode* currentLayerNode = iterListLayerNodes.next();
  3191. VertexDescriptor vCurrentVertex = currentLayerNode->getVertex();
  3192. //Assert the rank of vertex be equal to iLayerId
  3193. int iVertexRank = m_BoostGraphWrapper.getVertexRank(vCurrentVertex , *m_gMainGraph);
  3194. Q_ASSERT_X(iLayerId == iVertexRank , "CreateReducedNestedTree" , "LayerId and vertex rank mismatches");
  3195. int iHorizontalPosition = m_BoostGraphWrapper.getVertexHorizontalPosition(vCurrentVertex , *m_gMainGraph);
  3196. newReducedNestingTreeNode = new ReducedNestingTreeNode();
  3197. newReducedNestingTreeNode->setLayerNode(currentLayerNode);
  3198. newReducedNestingTreeNode->setAveragePosition((double)iHorizontalPosition);
  3199. reducedNestingTreeNode.addChildNode((double)iHorizontalPosition ,
  3200. newReducedNestingTreeNode);
  3201. //Increament child RNT counter
  3202. iCountTotalLayerNodes++;
  3203. //Accumulate new reduced netsting tree node average position
  3204. dTotalAveragePosition += (double)iHorizontalPosition;
  3205. }
  3206. //Set average position for current RNT node
  3207. double dCurrentRNTAveragePosition = dTotalAveragePosition / iCountTotalLayerNodes;
  3208. reducedNestingTreeNode.setAveragePosition(dCurrentRNTAveragePosition);
  3209. //Set total child LayerNode count for current RNT node
  3210. reducedNestingTreeNode.setChildLayerNodeCount(iCountTotalLayerNodes);
  3211. }
  3212. catch(boost::exception &eBoostException)
  3213. {
  3214. throw *boost::get_error_info<errmsg_info>(eBoostException);
  3215. }
  3216. catch(LayoutException &eLayoutException)
  3217. {
  3218. throw eLayoutException;
  3219. }
  3220. // XXX obselete
  3221. // catch(LayoutMemoryException &eMemoryException)
  3222. // {
  3223. // throw eMemoryException;
  3224. // }
  3225. catch(...)
  3226. {
  3227. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  3228. }
  3229. }
  3230. void HierarchicalLayouter::generateLayerByReducedNestingTree(MapPositionToLayerNode &newLayer, ReducedNestingTreeNode &reducedNestingTreeRootNode)
  3231. {
  3232. LAYOUT_ASSERT(newLayer.isEmpty() == true, LayoutException(__FUNCTION__
  3233. , LayoutExceptionEnum::INVALID_PARAMETER
  3234. , "it must be empty"
  3235. , "Layer"));
  3236. //Pass first parameter 1 because the horizontal positions should start from 1
  3237. int iHorizontalPositionStart = 1;
  3238. generateLayerByReducedNestingTreeRecur(iHorizontalPositionStart , newLayer , reducedNestingTreeRootNode);
  3239. }
  3240. void HierarchicalLayouter::generateLayerByReducedNestingTreeRecur(int &iHorizontalPosition, MapPositionToLayerNode &newLayer, ReducedNestingTreeNode &reducedNestingTreeRootNode)
  3241. {
  3242. LAYOUT_ASSERT(reducedNestingTreeRootNode.isLayerNode() == false,
  3243. LayoutException(__FUNCTION__
  3244. ,LayoutExceptionEnum::INVALID_PARAMETER
  3245. ,"it must not be a layer node"
  3246. ,"reducedNestingTreeRootNode"));
  3247. ReducedNestingTreeNode::IteratorMapAvgPosToChildRNTNode iterChildRNTNodes
  3248. = reducedNestingTreeRootNode.getChildNodesIterator();
  3249. ReducedNestingTreeNode *currentChildRNTNode = NULL;
  3250. LayerNode *currentLayerNode = NULL;
  3251. VertexDescriptor vCurrentVertex = 0;
  3252. //Testing
  3253. double dAvgPosition = reducedNestingTreeRootNode.getAveragePosition();
  3254. // XXX unusd
  3255. Q_UNUSED(dAvgPosition);
  3256. ////qDebug() << "RNT NODE Avg Position: "<< dAvgPosition;
  3257. while(iterChildRNTNodes.hasNext())
  3258. {
  3259. iterChildRNTNodes.next();
  3260. currentChildRNTNode = iterChildRNTNodes.value();
  3261. //Check layer node
  3262. if(currentChildRNTNode->isLayerNode() == true)
  3263. {
  3264. currentLayerNode = currentChildRNTNode->getLayerNode();
  3265. vCurrentVertex = currentLayerNode->getVertex();
  3266. //Update Layer Node Horizontal Position property
  3267. m_BoostGraphWrapper.setVertexHorizontalPosition( vCurrentVertex , *m_gMainGraph ,iHorizontalPosition);
  3268. //Add vertex node with given horizontal position
  3269. newLayer.insert(iHorizontalPosition , currentLayerNode);
  3270. //Increment horizontal position
  3271. ++iHorizontalPosition;
  3272. }
  3273. else
  3274. {
  3275. //Recursive Call
  3276. generateLayerByReducedNestingTreeRecur(iHorizontalPosition , newLayer , *currentChildRNTNode);
  3277. }
  3278. }
  3279. }
  3280. int HierarchicalLayouter::getNextLayerId(int iLayerId, ProcessDirection enDirection, LayerType enLayerType)
  3281. {
  3282. Q_ASSERT_X(m_mapLayeredGraph.contains(iLayerId) , "Get Next LayerId Method" , "Invalid Layer Id provided");
  3283. int iNextLayerId = 0;
  3284. MapLayerIdToLayerRef::iterator iterLayer = m_mapLayeredGraph.find(iLayerId);
  3285. if(enDirection == UpDirection)
  3286. {
  3287. //Check if the current Layer Id is the first Layer
  3288. Q_ASSERT_X(iterLayer != m_mapLayeredGraph.begin() , "Get Next LayerId Method" , "There is no layer in Upward Direction");
  3289. }else if(enDirection == DownDirection)
  3290. {
  3291. //Check if the current Layer Id is the last Layer
  3292. Q_ASSERT_X((iterLayer+1) != m_mapLayeredGraph.end() , "Get Next LayerId Method" , "There is no layer in Downwards Direction");
  3293. }
  3294. bool bKeepTraversing = true;
  3295. while(bKeepTraversing == true){
  3296. //Iterate to next layer in the Direction
  3297. if(enDirection == UpDirection)
  3298. {
  3299. if(iterLayer == m_mapLayeredGraph.begin())
  3300. {
  3301. bKeepTraversing = false;
  3302. break;
  3303. }
  3304. iterLayer--;
  3305. }
  3306. else if(enDirection == DownDirection)
  3307. {
  3308. iterLayer++;
  3309. if(iterLayer == m_mapLayeredGraph.end())
  3310. {
  3311. // never read?
  3312. bKeepTraversing = false;
  3313. break;
  3314. }
  3315. } else {
  3316. // XXX at else
  3317. }
  3318. iNextLayerId = iterLayer.key();
  3319. if(enLayerType == GraphVerticesLayer)
  3320. {
  3321. //Check Graph Vertices Layer
  3322. if((iNextLayerId % m_iRankDifferenceInLayers) == 0)
  3323. {
  3324. bKeepTraversing = false;
  3325. }
  3326. }
  3327. else if(enLayerType == BorderVerticesLayer)
  3328. {
  3329. //Check Border Vertices Layer
  3330. if((iNextLayerId % m_iRankDifferenceInLayers) > 0)
  3331. {
  3332. bKeepTraversing = false;
  3333. }
  3334. }
  3335. else
  3336. {
  3337. //For any layer
  3338. bKeepTraversing = false;
  3339. }
  3340. }
  3341. return iNextLayerId;
  3342. }
  3343. int HierarchicalLayouter::getTotalCrossings()
  3344. {
  3345. int iTotalCrossings = 0;
  3346. try
  3347. {
  3348. //Iterate layer from 1 to second last
  3349. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  3350. int iUpperPosCurrentEdge = 0;
  3351. int iLowerPosCurrentEdge = 0;
  3352. int iUpperPos = 0;
  3353. int iLowerPos = 0;
  3354. int iRemainingLowerPos = 0;
  3355. // XXX unused
  3356. Q_UNUSED(iUpperPos);
  3357. QQueue<int> *qUpperLayerVertexPosition = NULL;
  3358. QQueue<int> *qLowerLayerVertexPosition = NULL;
  3359. VertexDescriptor vCurrentVertex;
  3360. LayerNode* currentNode;
  3361. VertexDescriptor vCurrentEdgeSource;
  3362. VertexDescriptor vCurrentEdgeTarget;
  3363. PGL_MAP_VERTEX_BUNDLED_PROPERTY(mapVertexHorizontalPos , int , iHorizontalPosition , *m_gMainGraph);
  3364. while(iterLayer.hasNext())
  3365. {
  3366. iterLayer.next();
  3367. //Check if current layer is not last
  3368. if(iterLayer.hasNext())
  3369. {
  3370. qUpperLayerVertexPosition = new QQueue<int>();
  3371. qLowerLayerVertexPosition = new QQueue<int>();
  3372. //Iterate edges from current layer nodes
  3373. IteratorMapPositionToLayerNode iterNode(*iterLayer.value());
  3374. while(iterNode.hasNext())
  3375. {
  3376. iterNode.next();
  3377. currentNode = iterNode.value();
  3378. vCurrentVertex = currentNode->getVertex();
  3379. //Iterate edges of current vertex
  3380. OutEdgeIterator iterEdge , iterEdgeEnd;
  3381. for(boost::tie(iterEdge , iterEdgeEnd)
  3382. = out_edges(vCurrentVertex , *m_gMainGraph);
  3383. iterEdge != iterEdgeEnd;
  3384. iterEdge++)
  3385. {
  3386. EdgeDescriptor eCurrentEdge = *iterEdge;
  3387. LayoutEnum::EdgeType currentEdgeType = m_BoostGraphWrapper.getEdgeType(eCurrentEdge , *m_gMainGraph);
  3388. vCurrentEdgeSource = m_BoostGraphWrapper.getEdgeSource(eCurrentEdge , *m_gMainGraph);
  3389. vCurrentEdgeTarget = m_BoostGraphWrapper.getEdgeTarget(eCurrentEdge , *m_gMainGraph);
  3390. iUpperPosCurrentEdge = mapVertexHorizontalPos[vCurrentEdgeSource];
  3391. iLowerPosCurrentEdge = mapVertexHorizontalPos[vCurrentEdgeTarget];
  3392. if(currentEdgeType == LayoutEnum::GraphEdge ||
  3393. currentEdgeType == LayoutEnum::LongEdgeSegment)
  3394. {
  3395. //Enque source vertex horizontal position in upper vertex position queue
  3396. qUpperLayerVertexPosition->enqueue(iUpperPosCurrentEdge);
  3397. //Enque target vertex horizontal position in lower vertex position queue
  3398. qLowerLayerVertexPosition->enqueue(iLowerPosCurrentEdge);
  3399. }
  3400. }
  3401. }
  3402. //Assert if both queue Upper and Lower Vertex Positions has same number of elements
  3403. //Q_ASSERT_X(qUpperLayerVertexPosition->size() == qLowerLayerVertexPosition->size(),
  3404. //"Edge Crossing Counting" , "Queue upper and lower vertex position are not of same size");
  3405. LAYOUT_ASSERT(qUpperLayerVertexPosition->size() == qLowerLayerVertexPosition->size(),
  3406. LayoutException(__FUNCTION__
  3407. ,LayoutExceptionEnum::INVALID_OPERATION
  3408. ,"Queue upper and lower vertex position are not of same size"
  3409. , "Edge Crossing Counting"));
  3410. //The target vertices horizontal positions must be in ascending order for
  3411. //their source vertex,For example: if there are horizontal positions of upper and lower nodes
  3412. //of edges originating from an upper vertex are (1,3) and (1,1) then
  3413. //the lower positions 3 and 1 must be in ascending order i.e. it should be (1,1) - (1,3)
  3414. //So we need to sort the lower vertex positions queue
  3415. QListIterator<int> iterUpperVertexPos(*qUpperLayerVertexPosition);
  3416. QQueue<int>::iterator iterQLowerVertexPosBegin;
  3417. int iSequenceStart = 0;
  3418. int iSequenceEnd = 0;
  3419. int iCurrentVal = 0;
  3420. int iPrevVal = 0;
  3421. int iIndex = 0;
  3422. if(iterUpperVertexPos.hasNext())
  3423. {
  3424. iPrevVal = iterUpperVertexPos.next();
  3425. }
  3426. while(iterUpperVertexPos.hasNext())
  3427. {
  3428. iCurrentVal = iterUpperVertexPos.next();
  3429. if(iCurrentVal == iPrevVal)
  3430. {
  3431. //Increase Sequence End
  3432. iSequenceEnd++;
  3433. }
  3434. if(iCurrentVal != iPrevVal ||
  3435. iterUpperVertexPos.hasNext() == false)
  3436. {
  3437. //Sort sequence
  3438. if(iSequenceStart != iSequenceEnd)
  3439. {
  3440. //Iterator to the beginning of LowerVertexPosition queue
  3441. iterQLowerVertexPosBegin = qLowerLayerVertexPosition->begin();
  3442. qSort(iterQLowerVertexPosBegin + iSequenceStart,
  3443. iterQLowerVertexPosBegin + iSequenceEnd + 1,
  3444. qLess<int>());
  3445. }
  3446. //Set new Sequence Start
  3447. iSequenceStart = iIndex+1;
  3448. //Reset Sequence end for new sequence
  3449. iSequenceEnd = iSequenceStart;
  3450. }
  3451. iPrevVal = iCurrentVal;
  3452. iIndex++;
  3453. }
  3454. //Find crossings
  3455. while(qUpperLayerVertexPosition->isEmpty() == false &&
  3456. qLowerLayerVertexPosition->isEmpty() == false)
  3457. {
  3458. iUpperPos = qUpperLayerVertexPosition->dequeue();
  3459. iLowerPos = qLowerLayerVertexPosition->dequeue();
  3460. //if(iUpperPos <= iLowerPos)
  3461. {
  3462. //Find number of positions lesser than iLowerPos
  3463. QListIterator<int> iterLowerPos(*qLowerLayerVertexPosition);
  3464. while(iterLowerPos.hasNext())
  3465. {
  3466. iRemainingLowerPos = iterLowerPos.next();
  3467. if(iRemainingLowerPos < iLowerPos)
  3468. {
  3469. //Increase crossing count
  3470. ++iTotalCrossings;
  3471. }
  3472. }
  3473. }
  3474. }
  3475. //Clean up queues
  3476. DELETE_AND_SET_NULL(qUpperLayerVertexPosition);
  3477. DELETE_AND_SET_NULL(qLowerLayerVertexPosition);
  3478. }
  3479. }
  3480. }
  3481. catch(boost::exception &eBoostException)
  3482. {
  3483. throw *boost::get_error_info<errmsg_info>(eBoostException);
  3484. }
  3485. catch(LayoutException &eLayoutException)
  3486. {
  3487. throw eLayoutException;
  3488. }
  3489. // XXX obselete
  3490. // catch(LayoutMemoryException &eMemoryException)
  3491. // {
  3492. // throw eMemoryException;
  3493. // }
  3494. catch(...)
  3495. {
  3496. throw;
  3497. }
  3498. return iTotalCrossings;
  3499. }
  3500. void HierarchicalLayouter::createEmptySubgraphOrderingGraphsForEachNestingTreeSubgraphNode()
  3501. {
  3502. try
  3503. {
  3504. //Iterate every Nesting Tree Subgraph node
  3505. QueueNestingTreeSubgraphNodesRef qNestingTreeNodes;
  3506. qNestingTreeNodes.enqueue(&m_rootNestingTreeSubgraphNode);
  3507. NestingTreeSubgraphNode *currentNestingTreeNode = (NestingTreeSubgraphNode *)0;
  3508. SubgraphOrderingGraphType *gNewSubgraphOrderingGraph = (SubgraphOrderingGraphType *)0;
  3509. SubgraphOrderingGraphWrapper subgraphOrderingGraphWrapper;
  3510. while(qNestingTreeNodes.isEmpty() == false)
  3511. {
  3512. currentNestingTreeNode = qNestingTreeNodes.dequeue();
  3513. //create Subgraph Ordering Graph
  3514. gNewSubgraphOrderingGraph = new SubgraphOrderingGraphType();
  3515. //Add entry to the global map m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef
  3516. m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.insert(currentNestingTreeNode , gNewSubgraphOrderingGraph);
  3517. //Add node for newSubgraphOrderingGraph in its parent Subgraph Ordering Graph except for root graph
  3518. if(currentNestingTreeNode->isRoot() == false)
  3519. {
  3520. //Find parent nesting tree node
  3521. NestingTreeSubgraphNode& parentNestingTreeNode = currentNestingTreeNode->getParent();
  3522. //Find parent SubgraphOrdering graph from parent nesting tree node
  3523. SubgraphOrderingGraphType* gParentSubgraphOrderingGraph
  3524. = m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.value(&parentNestingTreeNode);
  3525. //Add vertex for current nesting tree node into its parent subgraph Ordering Graph
  3526. SubgraphOrderingGraphVertexDescriptor vVertex = add_vertex(*gParentSubgraphOrderingGraph);
  3527. //Set nesting tree subgraph node link into its representative subgraph Ordering Graph vertex
  3528. subgraphOrderingGraphWrapper.setVertexNestingTreeSubgraphNodeRef(currentNestingTreeNode , vVertex , *gParentSubgraphOrderingGraph);
  3529. //Add entry of vertex descriptor to currentNestingTreeNode
  3530. currentNestingTreeNode->setSubgraphOrderingGraphVertexIndex((int)vVertex);
  3531. }
  3532. //Enque child Nesting Tree Nodes
  3533. NestingTreeSubgraphNode::IteratorVectorNestingTreeSubgraphNodesRef iterChildNestingTreeNodes
  3534. = currentNestingTreeNode->getIteratorChildNestingTreeSubgraphNodes();
  3535. while(iterChildNestingTreeNodes.hasNext())
  3536. {
  3537. qNestingTreeNodes.enqueue(iterChildNestingTreeNodes.next());
  3538. }
  3539. }
  3540. //Test subgraph ordering graph creation
  3541. bool bCorrectSOGCreation = true;
  3542. // XXX unused
  3543. Q_UNUSED(bCorrectSOGCreation);
  3544. SubgraphOrderingGraphType* rootSubgraphOrderingGraph = m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.value(&m_rootNestingTreeSubgraphNode);
  3545. QQueue<SubgraphOrderingGraphType*> qSubgraphOrderingGraphs;
  3546. qSubgraphOrderingGraphs.enqueue(rootSubgraphOrderingGraph);
  3547. int iSOGCount = 0;
  3548. //Check root subgraph ordering graph can reach to every subgraph
  3549. while(qSubgraphOrderingGraphs.isEmpty() == false)
  3550. {
  3551. SubgraphOrderingGraphType * gCurrentSOG = qSubgraphOrderingGraphs.dequeue();
  3552. iSOGCount++;
  3553. BGL_FORALL_VERTICES(vVertex, *gCurrentSOG , SubgraphOrderingGraphType)
  3554. {
  3555. //check vertex index and the NestingTreeNode it is pointing to has stored same vertex index
  3556. NestingTreeSubgraphNode* nestingTreeNode = subgraphOrderingGraphWrapper.getVertexNestingTreeSubgraphNode(vVertex , *gCurrentSOG);
  3557. if(nestingTreeNode->getSubgraphOrderingGraphVertexIndex() != (int)vVertex)
  3558. {
  3559. bCorrectSOGCreation = false;
  3560. ////qDebug() << "Incorrect subgraphOrderingGraph vertex index stored by its NetingTreeSubgraphNode, v: "<<(int)vVertex;
  3561. }
  3562. //check the NestingTree Node points to the correct parent Sbgraph Ordering Graph
  3563. NestingTreeSubgraphNode& parentNestingTreeNode = nestingTreeNode->getParent();
  3564. SubgraphOrderingGraphType *gParentSOG
  3565. = m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.value(&parentNestingTreeNode);
  3566. if(gParentSOG != gCurrentSOG)
  3567. {
  3568. bCorrectSOGCreation = false;
  3569. ////qDebug() << "Incorrect parent SOG pointed by Nesting Tree Subgraph Node";
  3570. }
  3571. //Fill queue by next level SOGs
  3572. qSubgraphOrderingGraphs.enqueue(m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.value(nestingTreeNode));
  3573. }
  3574. }
  3575. int iTotalNestingTreeNodes = m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.size();
  3576. // XXX unused
  3577. Q_UNUSED(iTotalNestingTreeNodes);
  3578. // if(iSOGCount != iTotalNestingTreeNodes)
  3579. // {
  3580. // bCorrectSOGCreation = false;
  3581. // ////qDebug() << "Total Subgraph Ordering Graph count mismatches with total number of NestingTreeNodes";
  3582. // }
  3583. // Q_ASSERT_X(bCorrectSOGCreation , "Create Subgraph Ordering Graphs" , "Incorrect Subgraph Ordering Graph created");
  3584. LAYOUT_ASSERT(iSOGCount == iTotalNestingTreeNodes , LayoutException(__FUNCTION__
  3585. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  3586. , "Total Subgraph Ordering Graph count mismatches with total number of NestingTreeNodes"
  3587. , "Subgraph Ordering Graph"));
  3588. ////qDebug()<<"Subgraph Ordering Graphs created correctly";
  3589. }
  3590. catch(boost::exception &eBoostException)
  3591. {
  3592. throw *boost::get_error_info<errmsg_info>(eBoostException);
  3593. }
  3594. catch(LayoutException &eLayoutException)
  3595. {
  3596. throw eLayoutException;
  3597. }
  3598. catch(...)
  3599. {
  3600. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  3601. }
  3602. }
  3603. void HierarchicalLayouter::generateSubgraphOrderingGraph()
  3604. {
  3605. try
  3606. {
  3607. //Empty up previous subgraph ordering graph
  3608. if(m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.isEmpty() == false)
  3609. {
  3610. //Delete all subgraph ordering graphs
  3611. IteratorMapNestingTreeRefToSubgraphOrderingGraphRef iterMapNestingTreeNodeSubgraphOrderingGraph(
  3612. m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef);
  3613. while(iterMapNestingTreeNodeSubgraphOrderingGraph.hasNext())
  3614. {
  3615. iterMapNestingTreeNodeSubgraphOrderingGraph.next();
  3616. NestingTreeSubgraphNode* keyNestingTreeNode = iterMapNestingTreeNodeSubgraphOrderingGraph.key();
  3617. SubgraphOrderingGraphType* gSubgraphOrderingGraph = iterMapNestingTreeNodeSubgraphOrderingGraph.value();
  3618. // XXX unused
  3619. Q_UNUSED(gSubgraphOrderingGraph);
  3620. //We can not clear graph because boost does not support this method for subgraph type graph
  3621. //gSubgraphOrderingGraph->clear();
  3622. DELETE_AND_SET_NULL(m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef[keyNestingTreeNode]);
  3623. }
  3624. m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.clear();
  3625. //Clear all vertex index entries in the nesting tree
  3626. QueueNestingTreeSubgraphNodesRef qNestingTreeNodes;
  3627. qNestingTreeNodes.enqueue(&m_rootNestingTreeSubgraphNode);
  3628. while(qNestingTreeNodes.isEmpty() == false)
  3629. {
  3630. NestingTreeSubgraphNode* currentNestingTreeNode = qNestingTreeNodes.dequeue();
  3631. //Clear vertex descriptor entry
  3632. currentNestingTreeNode->setSubgraphOrderingGraphVertexIndex(-1);
  3633. //Enque child nesting tree nodes
  3634. NestingTreeSubgraphNode::IteratorVectorNestingTreeSubgraphNodesRef iterChildNestingTreeNode
  3635. = currentNestingTreeNode->getIteratorChildNestingTreeSubgraphNodes();
  3636. while(iterChildNestingTreeNode.hasNext())
  3637. {
  3638. qNestingTreeNodes.enqueue(iterChildNestingTreeNode.next());
  3639. }
  3640. }
  3641. //Reset back all layer node SubgraphOrderingGraphVertex entries to -1
  3642. IteratorHashVertexToLayerNode iterLayerNodes(hashVertexToLayerNode);
  3643. while(iterLayerNodes.hasNext())
  3644. {
  3645. iterLayerNodes.next();
  3646. LayerNode* currentLayerNode = iterLayerNodes.value();
  3647. currentLayerNode->setSubgraphOrderingGraphVertex(-1);
  3648. }
  3649. }
  3650. //Create subgraph ordering graph for every Nesting Tree node
  3651. createEmptySubgraphOrderingGraphsForEachNestingTreeSubgraphNode();
  3652. populateNodesAndEdgesInSubgraphOrderingGraph();
  3653. //Testinfg print
  3654. // IteratorMapNestingTreeRefToSubgraphOrderingGraphRef
  3655. // iterNestingTreeSubgraphOrderingGraph(m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef);
  3656. // ////qDebug()<<"==------start-graph----==\n";
  3657. // SubgraphOrderingGraphType* gSOG = m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.value(
  3658. // &m_rootNestingTreeSubgraphNode);
  3659. // m_subgraphOrderingGraphWrapper.printGraph(*gSOG);
  3660. // ////qDebug()<<"==------end-graph------==\n";
  3661. }
  3662. catch(boost::exception &eBoostException)
  3663. {
  3664. throw *boost::get_error_info<errmsg_info>(eBoostException);
  3665. }
  3666. catch(LayoutException &eLayoutException)
  3667. {
  3668. throw eLayoutException;
  3669. }
  3670. catch(...)
  3671. {
  3672. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  3673. }
  3674. }
  3675. void HierarchicalLayouter::populateNodesAndEdgesInSubgraphOrderingGraph()
  3676. {
  3677. try
  3678. {
  3679. //Add layer nodes and edges according to 'left of' relationships
  3680. LayerNode* leftLayerNode = NULL;
  3681. LayerNode* rightLayerNode = NULL;
  3682. NestingTreeSubgraphNode* leftNestingTreeNode = NULL;
  3683. NestingTreeSubgraphNode* rightNestingTreeNode = NULL;
  3684. SubgraphOrderingGraphVertexDescriptor vLeftVertex = 0;
  3685. SubgraphOrderingGraphVertexDescriptor vRightVertex = 0;
  3686. SubgraphOrderingGraphType* gCommonParentSubgraphOrderingGraph = NULL;
  3687. //Iterate layered graph to found neighbor vertices pairs
  3688. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  3689. while(iterLayer.hasNext())
  3690. {
  3691. iterLayer.next();
  3692. IteratorMapPositionToLayerNode iterLayerNode(*(iterLayer.value()));
  3693. while(iterLayerNode.hasNext())
  3694. {
  3695. iterLayerNode.next();
  3696. //Get left side layer node
  3697. leftLayerNode = iterLayerNode.value();
  3698. if(leftLayerNode->getSubgraphOrderingGraphVertex() < 0)
  3699. {
  3700. //Add vertex in Subgraph Ordering Graph for left layer node
  3701. addLayerNodeToOwnParentSubgraphOrderingGraph(leftLayerNode);
  3702. //////qDebug() << "add left node to SOG";
  3703. }
  3704. //check if current left layer node has right side neighbor
  3705. if(iterLayerNode.hasNext())
  3706. {
  3707. rightLayerNode = iterLayerNode.peekNext().value();
  3708. //////qDebug()<<"Layer node pair: ";
  3709. leftLayerNode->printName();
  3710. rightLayerNode->printName();
  3711. //find common parent NestingTreeSubgraphNode
  3712. /*If the direct parent NestingTreenonde is not same then
  3713. *one or both (left and right) layer nodes will be their NestingTree parent nodes
  3714. *In this case add edge between the parent Nesting Tree Nodes
  3715. */
  3716. NestingTreeSubgraphNode* leftLayerNodeParentNestingTreeNode
  3717. = &(leftLayerNode->getParentNestingTreeSubgraphNode());
  3718. NestingTreeSubgraphNode* rightLayerNodeParentNestingTreeNode
  3719. = &(rightLayerNode->getParentNestingTreeSubgraphNode());
  3720. if(leftLayerNodeParentNestingTreeNode != rightLayerNodeParentNestingTreeNode)
  3721. {
  3722. //Left and right layer nodes are not direct siblings i.e.
  3723. //not direct child of same subgraph
  3724. //Traverse left side layerNode Nesting Tree Parents till root
  3725. QVector<NestingTreeSubgraphNode*> vecLeftLayerNodeNestingTreeParents;
  3726. //Add first element
  3727. vecLeftLayerNodeNestingTreeParents.push_back(leftLayerNodeParentNestingTreeNode);
  3728. while(vecLeftLayerNodeNestingTreeParents.last()->isRoot() == false)
  3729. {
  3730. NestingTreeSubgraphNode* parentNestingTreeNode
  3731. = &(vecLeftLayerNodeNestingTreeParents.last()->getParent());
  3732. vecLeftLayerNodeNestingTreeParents.push_back(parentNestingTreeNode);
  3733. }
  3734. //Traverse right side layerNode Nesting Tree Parents till
  3735. //finding common parent Nesting tree node
  3736. QVector<NestingTreeSubgraphNode*> vecRightLayerNodeNestingTreeParents;
  3737. //Add first element
  3738. vecRightLayerNodeNestingTreeParents.push_back(rightLayerNodeParentNestingTreeNode);
  3739. //Pointer to last Nesting Tree node in vecRightLayerNodeNestingTreeParents
  3740. NestingTreeSubgraphNode* currentRightNestingTreeParent = vecRightLayerNodeNestingTreeParents.last();
  3741. while(vecLeftLayerNodeNestingTreeParents.contains(currentRightNestingTreeParent) == false)
  3742. {
  3743. //Sentinal condition to make sure loop does not go in infinity
  3744. //This condition will never occur if everything is correct
  3745. //This checks if currentRightNestingTreeParent is root nesting tree node and still its not found in
  3746. //vecLeftLayerNodeNestingTreeParents then there must be something wrong because root nesting tree node
  3747. //should be present in vecLeftLayerNodeNestingTreeParents
  3748. //Q_ASSERT_X(currentRightNestingTreeParent->isRoot() == false , "populateNodesAndEdgesInSubgraphOrderingGraph"
  3749. //, "Error while finding common parent nesting node, Left parent list does not contain root nesting tree node");
  3750. LAYOUT_ASSERT(currentRightNestingTreeParent->isRoot() == false
  3751. ,LayoutException(__FUNCTION__
  3752. ,LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER
  3753. ,"Left node nesting tree parent tree. Something wrong with left node nesting tree parents list generation"
  3754. , "Root nesting tree node"));
  3755. NestingTreeSubgraphNode* parentNestingTreeNode
  3756. = &(vecRightLayerNodeNestingTreeParents.last()->getParent());
  3757. vecRightLayerNodeNestingTreeParents.push_back(parentNestingTreeNode);
  3758. currentRightNestingTreeParent = vecRightLayerNodeNestingTreeParents.last();
  3759. }
  3760. //Now currentRightNestingTreeParent contains common parent
  3761. gCommonParentSubgraphOrderingGraph
  3762. = m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.value(currentRightNestingTreeParent);
  3763. //////qDebug() <<"Common parent: ";
  3764. currentRightNestingTreeParent->printName();
  3765. int iLeftCommonParentFountAtIndex
  3766. = vecLeftLayerNodeNestingTreeParents.indexOf(currentRightNestingTreeParent);
  3767. int iRightCommonParentFoundAtIndex
  3768. = vecRightLayerNodeNestingTreeParents.indexOf(currentRightNestingTreeParent);
  3769. LAYOUT_ASSERT(false == (iRightCommonParentFoundAtIndex == iLeftCommonParentFountAtIndex &&
  3770. iLeftCommonParentFountAtIndex == 0)
  3771. ,LayoutException(__FUNCTION__
  3772. , LayoutExceptionEnum::INVALID_OPERATION
  3773. , "Finding Common parent failed"
  3774. , "Populating Nodes and edges for Subgraph Ordering Graph"));
  3775. if(iLeftCommonParentFountAtIndex == 0)
  3776. {
  3777. //Common parent is found at first location in left vector means
  3778. //It is direct parent of leftLayerNode, hence we have to consider
  3779. //leftLayerNodes's vertex descriptor
  3780. vLeftVertex = leftLayerNode->getSubgraphOrderingGraphVertex();
  3781. }
  3782. else
  3783. {
  3784. //Select nesting tree node child to common parent nesting tree node
  3785. leftNestingTreeNode = vecLeftLayerNodeNestingTreeParents.at(iLeftCommonParentFountAtIndex - 1);
  3786. LAYOUT_ASSERT(leftNestingTreeNode->getSubgraphOrderingGraphVertexIndex() >= 0,
  3787. LayoutException(__FUNCTION__
  3788. , LayoutExceptionEnum::INVALID_PARAMETER
  3789. , QString::number(leftNestingTreeNode->getSubgraphOrderingGraphVertexIndex())
  3790. , "LeftNestingTreeNode's Subgraph Ordering Graph Vertex Index"));
  3791. vLeftVertex = leftNestingTreeNode->getSubgraphOrderingGraphVertexIndex();
  3792. //qDebug() << "LeftNTNode: ";
  3793. leftNestingTreeNode->printName();
  3794. }
  3795. if(iRightCommonParentFoundAtIndex == 0)
  3796. {
  3797. //Common parent is found at first location in right vector means
  3798. //It is direct parent of rightLayerNode, hence we have to consider
  3799. //rightLayerNodes's vertex descriptor
  3800. //Check if right layer node is already added to Subgraph Ordering Graph
  3801. if(rightLayerNode->getSubgraphOrderingGraphVertex() < 0)
  3802. {
  3803. //Add vertex in Subgraph Ordering Graph for right layer node
  3804. addLayerNodeToOwnParentSubgraphOrderingGraph(rightLayerNode);
  3805. }
  3806. vRightVertex = rightLayerNode->getSubgraphOrderingGraphVertex();
  3807. }
  3808. else
  3809. {
  3810. //Select nesting tree node child to common parent nesting tree node
  3811. rightNestingTreeNode = vecRightLayerNodeNestingTreeParents.at(iRightCommonParentFoundAtIndex - 1);
  3812. LAYOUT_ASSERT(rightNestingTreeNode->getSubgraphOrderingGraphVertexIndex() >= 0,
  3813. LayoutException(__FUNCTION__
  3814. , LayoutExceptionEnum::INVALID_PARAMETER
  3815. , QString::number(leftNestingTreeNode->getSubgraphOrderingGraphVertexIndex())
  3816. , "RightNestingTreeNode's Subgraph Ordering Graph Vertex Index"));
  3817. vRightVertex = rightNestingTreeNode->getSubgraphOrderingGraphVertexIndex();
  3818. //////qDebug() << "RightNTNode";
  3819. rightNestingTreeNode->printName();
  3820. }
  3821. }
  3822. else
  3823. {
  3824. //left and right layer nodes are direct siblings under same subgraph nesting tree node
  3825. //so get SubgraphOrderingGraph vertices of both layer nodes and add edge
  3826. //leftLayer node vertex in SubgraphOrdering Graph is added already at the start of this loop
  3827. vLeftVertex = leftLayerNode->getSubgraphOrderingGraphVertex();
  3828. //Check if right layer node is already added to Subgraph Ordering Graph
  3829. if(rightLayerNode->getSubgraphOrderingGraphVertex() < 0)
  3830. {
  3831. //Add vertex in Subgraph Ordering Graph for right layer node
  3832. addLayerNodeToOwnParentSubgraphOrderingGraph(rightLayerNode);
  3833. }
  3834. vRightVertex = rightLayerNode->getSubgraphOrderingGraphVertex();
  3835. //////qDebug() << "Direct parent: ";
  3836. leftLayerNodeParentNestingTreeNode->printName();
  3837. //Parent nesting tree node of left and right layer node are same
  3838. gCommonParentSubgraphOrderingGraph
  3839. = m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.value(leftLayerNodeParentNestingTreeNode);
  3840. }
  3841. //Add edge between - vLeft to vRight in SOG
  3842. LAYOUT_ASSERT(gCommonParentSubgraphOrderingGraph->find_vertex(vLeftVertex).second
  3843. , LayoutException(__FUNCTION__
  3844. , LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER
  3845. , "Common Parent SubgraphOrderingGraph"
  3846. , "Left Vertex representing left neighbor node on layer"));
  3847. LAYOUT_ASSERT(gCommonParentSubgraphOrderingGraph->find_vertex(vRightVertex).second
  3848. , LayoutException(__FUNCTION__
  3849. , LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER
  3850. , "Common Parent SubgraphOrderingGraph"
  3851. , "Right Vertex representing right side node on layer"));
  3852. //////qDebug() <<"Edge: "<<(int)vLeftVertex<<" , "<<(int)vRightVertex;
  3853. bool bEdgeAddedAlready = false;
  3854. AdjacencyIteratorSubgraphOrdeingGraph iterAdjacentVertex , iterAdjacentVertexEnd;
  3855. //check if already there is an edge
  3856. for(boost::tie(iterAdjacentVertex , iterAdjacentVertexEnd)
  3857. = adjacent_vertices(vLeftVertex , *gCommonParentSubgraphOrderingGraph);
  3858. iterAdjacentVertex != iterAdjacentVertexEnd;
  3859. iterAdjacentVertex++)
  3860. {
  3861. SubgraphOrderingGraphVertexDescriptor vAdjacentVertex
  3862. = *iterAdjacentVertex;
  3863. //////qDebug()<<(int)vAdjacentVertex;
  3864. if(vAdjacentVertex == vRightVertex)
  3865. {
  3866. bEdgeAddedAlready = true;
  3867. }
  3868. }
  3869. if(bEdgeAddedAlready == false)
  3870. {
  3871. //////qDebug()<<"Adding edge";
  3872. add_edge(vLeftVertex , vRightVertex , *gCommonParentSubgraphOrderingGraph);
  3873. }
  3874. else
  3875. {
  3876. //////qDebug() << "Edge exist";
  3877. }
  3878. }//End of IF Right neighbor
  3879. else
  3880. {
  3881. //////qDebug() <<"No right side node";
  3882. }
  3883. }//Iterate layer layer node loop end
  3884. }//Iterate layer loop end
  3885. }
  3886. catch(boost::exception &eBoostException)
  3887. {
  3888. throw *boost::get_error_info<errmsg_info>(eBoostException);
  3889. }
  3890. catch(LayoutException &eLayoutException)
  3891. {
  3892. throw eLayoutException;
  3893. }
  3894. catch(...)
  3895. {
  3896. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  3897. }
  3898. }
  3899. void HierarchicalLayouter::addLayerNodeToOwnParentSubgraphOrderingGraph(LayerNode *layerNode)
  3900. {
  3901. LAYOUT_ASSERT(layerNode->getSubgraphOrderingGraphVertex() < 0,
  3902. LayoutException(__FUNCTION__
  3903. , LayoutExceptionEnum::INVALID_PARAMETER
  3904. , "it must be uninitialised"
  3905. , "Layer Nodes SubgraphOrderingGraphVertex"));
  3906. //Add vertex in Subgraph Ordering Graph for layer node
  3907. //Get parent Nesting Tree node
  3908. NestingTreeSubgraphNode& nestingTreeNodeForLayerNode
  3909. = layerNode->getParentNestingTreeSubgraphNode();
  3910. //Get parent Subgraph Ordering Graph
  3911. SubgraphOrderingGraphType *gLayerNodeParentSubgraphOrderingGraph
  3912. = m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.value(&nestingTreeNodeForLayerNode);
  3913. //Add vertex for layer node
  3914. SubgraphOrderingGraphVertexDescriptor vNewVertex = add_vertex(*gLayerNodeParentSubgraphOrderingGraph);
  3915. //Add link for layer node into newly addded vertex
  3916. m_subgraphOrderingGraphWrapper.setVertexLayerNodeRef(layerNode
  3917. , vNewVertex
  3918. , *gLayerNodeParentSubgraphOrderingGraph);
  3919. //Set newly added subgraph ordering graph vertex index into leftLayerNode
  3920. layerNode->setSubgraphOrderingGraphVertex(vNewVertex);
  3921. }
  3922. SubgraphOrderingGraphType *HierarchicalLayouter::getParentSubgraphOrderingGraph(NestingTreeSubgraphNode *nestingTreeNode)
  3923. {
  3924. LAYOUT_ASSERT(nestingTreeNode != NULL,
  3925. LayoutException(__FUNCTION__
  3926. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  3927. , "nestingTreeNode"
  3928. , "in SubgraphOrderingGraphType"));
  3929. NestingTreeSubgraphNode& parentNestingTreeNode = nestingTreeNode->getParent();
  3930. return m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.value(&parentNestingTreeNode);
  3931. }
  3932. void HierarchicalLayouter::removeCycleFromSubgraphOrderingGraph()
  3933. {
  3934. LAYOUT_ASSERT(m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.isEmpty() == false,
  3935. LayoutException(__FUNCTION__
  3936. , LayoutExceptionEnum::EMPTY_CONTAINER
  3937. , "Map must not be empty"
  3938. , "mapNestingTreeNodeRefToSubgraphOrderingGraphRef"));
  3939. try
  3940. {
  3941. //For each subgraph ordering graph remove cycles, except the subgraph of a
  3942. //Nesting Tree Node which does not contain any child nesting tree node
  3943. IteratorMapNestingTreeRefToSubgraphOrderingGraphRef iterNestingTreeNodeToSubgraphOrderingGraph(
  3944. m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef);
  3945. NestingTreeSubgraphNode* currentNestingTreeNode = NULL;
  3946. SubgraphOrderingGraphType* currentSubgraphOrderingGraph = NULL;
  3947. int iChildNestingTreeNodeCount = 0;
  3948. bool bIsEdgeExist = false;
  3949. while(iterNestingTreeNodeToSubgraphOrderingGraph.hasNext())
  3950. {
  3951. iterNestingTreeNodeToSubgraphOrderingGraph.next();
  3952. currentNestingTreeNode = iterNestingTreeNodeToSubgraphOrderingGraph.key();
  3953. currentSubgraphOrderingGraph = iterNestingTreeNodeToSubgraphOrderingGraph.value();
  3954. iChildNestingTreeNodeCount = currentNestingTreeNode->getCountOfChildNestingTreeSubgraphNodes();
  3955. //Skip cycle removal of SubgraphOrderingGraph of nesting tree subgaph node which
  3956. //have zero child nesting tree subgraph nodes
  3957. if(iChildNestingTreeNodeCount > 0)
  3958. {
  3959. //Find list of back edges
  3960. VectorSubgraphOrderingGraphEdgeDescriptor vecBackEdges;
  3961. //create DFS visitor
  3962. SubgraphOrderingGraphBackEdgeRecorder backEdgeRecorder(vecBackEdges);
  3963. //Boost DFS
  3964. depth_first_search(*currentSubgraphOrderingGraph , visitor(backEdgeRecorder));
  3965. while(vecBackEdges.isEmpty() == false)
  3966. {
  3967. //For every backEdge(vSource , vTarget)
  3968. //Find path from vTarget to vSource
  3969. //Break cycle path by deleting edge with the least most Average BarryCenter
  3970. //Find backEdges again if backedges found then repeat the above procedure
  3971. IteratorVectorSubgraphOrderingGraphEdgeDescriptor iterBackEdge(vecBackEdges);
  3972. while(iterBackEdge.hasNext())
  3973. {
  3974. SubgraphOrderingGraphEdgeDescriptor eBackEdge
  3975. = iterBackEdge.next();
  3976. //Sometimes cycle removal of previous backEdge removes another backEdge
  3977. //Therefor check that if gSubgaphOrderingGraph contains the backEdge or not
  3978. bIsEdgeExist = currentSubgraphOrderingGraph->find_edge(eBackEdge).second;
  3979. if(bIsEdgeExist == true)
  3980. {
  3981. //Break cycle created by eBackEdge at node which has least most average barrycenter
  3982. breakCycleAtSmallestAverageBarryCenterNode(eBackEdge , *currentSubgraphOrderingGraph);
  3983. }
  3984. }
  3985. //Clear back edge list
  3986. vecBackEdges.clear();
  3987. //Find if there are more cycles remained in graph
  3988. depth_first_search(*currentSubgraphOrderingGraph , visitor(backEdgeRecorder));
  3989. }
  3990. }
  3991. }
  3992. }
  3993. catch(boost::exception &eBoostException)
  3994. {
  3995. throw *boost::get_error_info<errmsg_info>(eBoostException);
  3996. }
  3997. catch(LayoutException &eLayoutException)
  3998. {
  3999. throw eLayoutException;
  4000. }
  4001. // XXX obselete
  4002. // catch(LayoutMemoryException &eMemoryException)
  4003. // {
  4004. // throw eMemoryException;
  4005. // }
  4006. catch(...)
  4007. {
  4008. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  4009. }
  4010. }
  4011. void HierarchicalLayouter::breakCycleAtSmallestAverageBarryCenterNode(SubgraphOrderingGraphEdgeDescriptor eBackEdge, SubgraphOrderingGraphType &gSubgraphOrderingGraph)
  4012. {
  4013. LAYOUT_ASSERT(gSubgraphOrderingGraph.find_edge(eBackEdge).second == true
  4014. , LayoutException(__FUNCTION__
  4015. ,LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER
  4016. , "Subgraph Ordering Graph"
  4017. , "Back Edge"));
  4018. LAYOUT_ASSERT(source(eBackEdge , gSubgraphOrderingGraph) != target(eBackEdge , gSubgraphOrderingGraph)
  4019. , LayoutException(__FUNCTION__
  4020. , LayoutExceptionEnum::INVALID_PARAMETER
  4021. , "edge with self loop"
  4022. , "Back Edge"));
  4023. try
  4024. {
  4025. SubgraphOrderingGraphVertexDescriptor vSource = source(eBackEdge , gSubgraphOrderingGraph);
  4026. SubgraphOrderingGraphVertexDescriptor vTarget = target(eBackEdge , gSubgraphOrderingGraph);
  4027. //Find path from vTarget to vSource
  4028. //Break cycle path by deleting edge with the least most Average BarryCenter
  4029. //m_subgraphOrderingGraphWrapper.printGraph(gSubgraphOrderingGraph);
  4030. //Iterate SubgraphOrderingGraph nodes in bfs manner
  4031. //Reset all edges spanning tree boolean value to false
  4032. BGL_FORALL_EDGES(eEdge , gSubgraphOrderingGraph , SubgraphOrderingGraphType)
  4033. {
  4034. m_subgraphOrderingGraphWrapper.setIsEdgeInSpanningTree(false , eEdge , gSubgraphOrderingGraph);
  4035. }
  4036. typedef QQueue<SubgraphOrderingGraphVertexDescriptor> QueueSubgraphOrderingGraphVertices;
  4037. //Queue to contain upper layer vertices
  4038. QueueSubgraphOrderingGraphVertices* qUpperLayerVertex = NULL;
  4039. //Queue to contain direct child of upper level vertices which thus forms a lower level
  4040. QueueSubgraphOrderingGraphVertices* qLowerLayerVertex = NULL;
  4041. qUpperLayerVertex = new QueueSubgraphOrderingGraphVertices();
  4042. //Add vTarget as the root vertex to start the breadth first search
  4043. qUpperLayerVertex->enqueue(vTarget);
  4044. SubgraphOrderingGraphVertexDescriptor vCurrentVertex = 0;
  4045. SubgraphOrderingGraphVertexDescriptor vChildVertex = 0;
  4046. int iTotalVertices = 0;
  4047. iTotalVertices = num_vertices(gSubgraphOrderingGraph);
  4048. //Vertex visited list
  4049. QVector<bool> vecVertexVisited(iTotalVertices);
  4050. std::fill(vecVertexVisited.begin() , vecVertexVisited.end() , false);
  4051. //Mark first vertex visited
  4052. vecVertexVisited[vTarget] = true;
  4053. ////qDebug() << "Creating spanning tree";
  4054. bool bIsSourceVertexReached = false;
  4055. do
  4056. {
  4057. qLowerLayerVertex = new QueueSubgraphOrderingGraphVertices();
  4058. while(qUpperLayerVertex->isEmpty() == false)
  4059. {
  4060. vCurrentVertex = qUpperLayerVertex->dequeue();
  4061. BGL_FORALL_OUTEDGES(vCurrentVertex , eOutEdge , gSubgraphOrderingGraph , SubgraphOrderingGraphType)
  4062. {
  4063. vChildVertex = target(eOutEdge , gSubgraphOrderingGraph);
  4064. if(vecVertexVisited[vChildVertex] == true)
  4065. {
  4066. //Skip visited vertex to avoid infinite loop
  4067. continue;
  4068. }
  4069. else
  4070. {
  4071. //Mark vertex visited
  4072. vecVertexVisited[vChildVertex] = true;
  4073. }
  4074. //Mark edge as spanning tree edge
  4075. m_subgraphOrderingGraphWrapper.setIsEdgeInSpanningTree(true , eOutEdge , gSubgraphOrderingGraph);
  4076. //Enque child vertices in queue of LowerLayerVertices
  4077. qLowerLayerVertex->enqueue(vChildVertex);
  4078. ////qDebug()<<vChildVertex;
  4079. if(vChildVertex == vSource)
  4080. {
  4081. bIsSourceVertexReached = true;
  4082. //Clear both queues
  4083. qUpperLayerVertex->clear();
  4084. qLowerLayerVertex->clear();
  4085. break;
  4086. }
  4087. }
  4088. }
  4089. DELETE_AND_SET_NULL(qUpperLayerVertex);
  4090. //Set queue of child vertices to be the queue of next upper layer vertices
  4091. qUpperLayerVertex = qLowerLayerVertex;
  4092. qLowerLayerVertex = NULL;
  4093. }while(qUpperLayerVertex->isEmpty() == false && bIsSourceVertexReached == false);
  4094. DELETE_AND_SET_NULL(qUpperLayerVertex);
  4095. //Sometimes cycle removal of previous backEdges breaks one or more cycles
  4096. //So in such case we just stop this cycle removal process
  4097. //This can be detected if the source vertex is not reached through
  4098. //the bfs traversal in above loop which starts from target vertex
  4099. if(bIsSourceVertexReached == true)
  4100. {
  4101. //Now, the edges from root vTarget vertex to vSource vertex are marked as SpanningTreeEdges
  4102. //So traverse edges in reverse direction from vSource till vTarget to find the path between them
  4103. //Then meanwhile find vertex with minimum AverageBarryCenter Value -lets call it vSmallestBaryCenterVertex
  4104. //Delete edge from path which has target as vSmallestBaryCenterVertex
  4105. SubgraphOrderingGraphVertexDescriptor vParentVertex;
  4106. //Together vSourceOfEdgeToDelete and vTargetOfEdgeToDelete forms edge to delete to break cycle
  4107. //This vertex should contain the vertex with smallest average barrycenter
  4108. SubgraphOrderingGraphVertexDescriptor vTargetOfEdgeToDelete;
  4109. //This vertex should contain vertex which serves as source vertex for the vTargetOfEdgeToDelete
  4110. SubgraphOrderingGraphVertexDescriptor vSourceOfEdgeToDelete;
  4111. double dMinAverageBarryCenter = INT_MAX;
  4112. double dCurrentVertexAverageBarryCenter = 0.0;
  4113. bool bIsSpanningTreeEdge = false;
  4114. int iCountSpanningTreeInEdges = 0;
  4115. //Set current vertex to be the start and end of cycle i.e. vTarget vertex
  4116. vCurrentVertex = vTarget;
  4117. //Mark the backedge as in spanning tree = true
  4118. m_subgraphOrderingGraphWrapper.setIsEdgeInSpanningTree(true , eBackEdge , gSubgraphOrderingGraph);
  4119. ////qDebug()<<"BackEdge: "<<(int)vSource<<" , "<<(int)vTarget;
  4120. ////qDebug()<<"#Path:";
  4121. do
  4122. {
  4123. dCurrentVertexAverageBarryCenter =
  4124. getSubgraphOrderingGraphVertexAverageBarryCenter(vCurrentVertex , gSubgraphOrderingGraph);
  4125. //Find in vParentVertex of current vertex by iterating inEdges and
  4126. //finding inEdge with spanning tree property marked as 'true'
  4127. iCountSpanningTreeInEdges = 0;
  4128. ////qDebug() << vCurrentVertex;
  4129. BGL_FORALL_INEDGES(vCurrentVertex , eInEdge , gSubgraphOrderingGraph , SubgraphOrderingGraphType)
  4130. {
  4131. //eInEdge must have be spanning tree edge property value - true
  4132. bIsSpanningTreeEdge
  4133. = m_subgraphOrderingGraphWrapper.getIsEdgeInSpanningTree(eInEdge
  4134. , gSubgraphOrderingGraph);
  4135. if(bIsSpanningTreeEdge == true)
  4136. {
  4137. iCountSpanningTreeInEdges++;
  4138. vParentVertex = source(eInEdge , gSubgraphOrderingGraph);
  4139. }
  4140. }
  4141. //Every vertex must have only one inEdge with isSpanningTree property value as 'true'
  4142. if(iCountSpanningTreeInEdges == 0)
  4143. {
  4144. ////qDebug() << "Invalid in edge count: "<<iCountSpanningTreeInEdges;
  4145. return;
  4146. }
  4147. if(dCurrentVertexAverageBarryCenter < dMinAverageBarryCenter)
  4148. {
  4149. //Update min average barry center
  4150. dMinAverageBarryCenter = dCurrentVertexAverageBarryCenter;
  4151. vTargetOfEdgeToDelete = vCurrentVertex;
  4152. vSourceOfEdgeToDelete = vParentVertex;
  4153. }
  4154. vCurrentVertex = vParentVertex;
  4155. }while(vCurrentVertex != vTarget);
  4156. //Delete edge to break cycle
  4157. remove_edge(vSourceOfEdgeToDelete , vTargetOfEdgeToDelete , gSubgraphOrderingGraph);
  4158. ////qDebug() << "Remove cycle edge: "<<(int)vSourceOfEdgeToDelete<<" , "<<
  4159. // XXX (int)vTargetOfEdgeToDelete;
  4160. }//END_IF Source vertex is reached or not
  4161. else
  4162. {
  4163. //source vertex is not reached
  4164. ////qDebug() << "Cycle is removed already ";
  4165. }
  4166. }
  4167. catch(boost::exception &eBoostException)
  4168. {
  4169. throw *boost::get_error_info<errmsg_info>(eBoostException);
  4170. }
  4171. catch(LayoutException &eLayoutException)
  4172. {
  4173. throw eLayoutException;
  4174. }
  4175. // XXX obselete
  4176. // catch(LayoutMemoryException &eMemoryException)
  4177. // {
  4178. // throw eMemoryException;
  4179. // }
  4180. catch(...)
  4181. {
  4182. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  4183. }
  4184. }
  4185. int HierarchicalLayouter::assignTopologicalOrderAccordingToSubgraphOrderingGraph(int iStartOrder, NestingTreeSubgraphNode *nestingTreeNode)
  4186. {
  4187. int iTopologicalOrder = 0;
  4188. try
  4189. {
  4190. LAYOUT_ASSERT(iStartOrder > 0 , LayoutException(__FUNCTION__
  4191. , LayoutExceptionEnum::INVALID_PARAMETER
  4192. , QString::number(iStartOrder)
  4193. , "Start Order for topological order of subgraph ordering graph"));
  4194. LAYOUT_ASSERT(m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.contains(nestingTreeNode)
  4195. , LayoutException(__FUNCTION__
  4196. , LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER
  4197. , "Nesting Tree Node"
  4198. , "Map of Nesting Tree Nodes to Subgraph Ordering Graph"));
  4199. //If nesting tree node does not have any child nesting tree node then assign
  4200. //same order to all vertices the corresponding SubgraphOrderingGraph it contain.
  4201. //Otherwise assign order values in bfs order, while assigning 'order' if we have
  4202. //choice for several nodes then assign 'order' in ascending order of AverageBarryCenterValues
  4203. //Map type 'AverageBArryCenter' value to 'SubgraphOrderingGraphVertex (SOG Vertex)'
  4204. typedef QMap<double , SubgraphOrderingGraphVertexDescriptor> MapAverageBarryCenterToSOGVertex;
  4205. typedef QMapIterator<double , SubgraphOrderingGraphVertexDescriptor> IteratorMapAverageBarryCenterToSOGVertex;
  4206. typedef QQueue<SubgraphOrderingGraphVertexDescriptor> QueueSubgraphOrderingGraphVertex;
  4207. int iCountOfNestingTreeChildNode = nestingTreeNode->getCountOfChildNestingTreeSubgraphNodes();
  4208. SubgraphOrderingGraphType* gSubgraphOrderingGraph = NULL;
  4209. LayerNode* currentLayerNode = NULL;
  4210. VertexDescriptor vGlobalGraphVertex = 0;
  4211. SubgraphOrderingGraphVertexDescriptor vSubgraphOrderingGraphVertex = 0;
  4212. bool bIsVertexLayerNode = false;
  4213. iTopologicalOrder = iStartOrder;
  4214. int iNextTopologicalOrderValue = 0;
  4215. //Get SubgraphOrderingGraph nestingTreeNode pointing to.
  4216. gSubgraphOrderingGraph
  4217. = m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.value(nestingTreeNode);
  4218. //Testing
  4219. //////qDebug() << "Assigning topological order";
  4220. //m_subgraphOrderingGraphWrapper.printGraph(*gSubgraphOrderingGraph);
  4221. if(iCountOfNestingTreeChildNode == 0)
  4222. {
  4223. //////qDebug() << "Leaf Nesting Tree Node";
  4224. //If nesting tree node does not have any child nesting tree node then assign
  4225. //same order to all LayerNodes vertices it contain.
  4226. BGL_FORALL_VERTICES(vVertex , *gSubgraphOrderingGraph , SubgraphOrderingGraphType)
  4227. {
  4228. bIsVertexLayerNode = m_subgraphOrderingGraphWrapper.isSubgraphOrderingVertexIsLayerNode(
  4229. vVertex , *gSubgraphOrderingGraph);
  4230. LAYOUT_ASSERT(bIsVertexLayerNode == true, LayoutException(__FUNCTION__
  4231. , LayoutExceptionEnum::INVALID_PARAMETER
  4232. , "it must be LayerNode"
  4233. , "vVertex from SubgraphOrderingGraphType"));
  4234. currentLayerNode = m_subgraphOrderingGraphWrapper.getVertexLayerNodeRef(vVertex , *gSubgraphOrderingGraph);
  4235. vGlobalGraphVertex = currentLayerNode->getVertex();
  4236. //Assign Topological order to vertex
  4237. m_BoostGraphWrapper.setVertexTopologicalOrder(iTopologicalOrder , vGlobalGraphVertex , *m_gMainGraph);
  4238. //Later update this change in layered graph
  4239. //Do not increament iTopological Order
  4240. }
  4241. //Increase the topological order to make it StartOrder value of another node to which it might be passed
  4242. iTopologicalOrder++;
  4243. LAYOUT_ASSERT(iTopologicalOrder == (iStartOrder + 1)
  4244. , LayoutException(__FUNCTION__
  4245. , LayoutExceptionEnum::INVALID_OPERATION
  4246. , "assigning topological order to leaf subgraph ordering graph failed"
  4247. , "Assigning Topological Order to whole tree of subgraph ordering graphs"));
  4248. }
  4249. else
  4250. {
  4251. //////qDebug() << "Nonleaf Nestnig Tree Node";
  4252. //assign order values in BFS Order, while assigning 'order' if we have
  4253. //choice for several nodes then assign 'order' in ascending order of AverageBarryCenterValues
  4254. QueueSubgraphOrderingGraphVertex* qUpperLayerVertex = NULL;
  4255. QueueSubgraphOrderingGraphVertex* qLowerLayerVertex = NULL;
  4256. MapAverageBarryCenterToSOGVertex mapBarrycenterToAdjacentVertices;
  4257. NestingTreeSubgraphNode* currentNestingTreeNode = NULL;
  4258. int iTotalVertices = 0;
  4259. iTotalVertices = num_vertices(*gSubgraphOrderingGraph);
  4260. QVector<bool> vecQueuedSubgraphOrderingGraphVertex(iTotalVertices);
  4261. std::fill(vecQueuedSubgraphOrderingGraphVertex.begin() , vecQueuedSubgraphOrderingGraphVertex.end() , false);
  4262. double dAverageBarryCenter = 0.0;
  4263. //Find the vertices with 0 in_degree to be in first layer
  4264. BGL_FORALL_VERTICES(vVertex , *gSubgraphOrderingGraph , SubgraphOrderingGraphType)
  4265. {
  4266. if(in_degree(vVertex , *gSubgraphOrderingGraph) == 0)
  4267. {
  4268. dAverageBarryCenter = getSubgraphOrderingGraphVertexAverageBarryCenter(
  4269. vVertex , *gSubgraphOrderingGraph);
  4270. //Add to first layer
  4271. mapBarrycenterToAdjacentVertices.insertMulti(dAverageBarryCenter , vVertex);
  4272. //Mark vertex as added to queue - mapUpperLayerVertex in this case
  4273. vecQueuedSubgraphOrderingGraphVertex[vVertex] = true;
  4274. }
  4275. }
  4276. qUpperLayerVertex = new QueueSubgraphOrderingGraphVertex();
  4277. //Fill the qUpperLayerVertex to start breadth first search
  4278. IteratorMapAverageBarryCenterToSOGVertex iterFirstLayerBarryCenterToVertex(mapBarrycenterToAdjacentVertices);
  4279. while(iterFirstLayerBarryCenterToVertex.hasNext())
  4280. {
  4281. iterFirstLayerBarryCenterToVertex.next();
  4282. vSubgraphOrderingGraphVertex = iterFirstLayerBarryCenterToVertex.value();
  4283. qUpperLayerVertex->enqueue(vSubgraphOrderingGraphVertex);
  4284. }
  4285. //Breadth First Search traversal of SubgraphOrderingGraph pointed by provided nestingTreeNode
  4286. do
  4287. {
  4288. qLowerLayerVertex = new QueueSubgraphOrderingGraphVertex();
  4289. while(qUpperLayerVertex->isEmpty() == false)
  4290. {
  4291. vSubgraphOrderingGraphVertex = qUpperLayerVertex->dequeue();
  4292. bIsVertexLayerNode = m_subgraphOrderingGraphWrapper.isSubgraphOrderingVertexIsLayerNode(
  4293. vSubgraphOrderingGraphVertex , *gSubgraphOrderingGraph);
  4294. if(bIsVertexLayerNode == true)
  4295. {
  4296. //Get layerNode for current SubgraphOrderingGraph vertex
  4297. currentLayerNode = m_subgraphOrderingGraphWrapper.getVertexLayerNodeRef(vSubgraphOrderingGraphVertex , *gSubgraphOrderingGraph);
  4298. //Get global graph vertex descriptor from layerNode
  4299. vGlobalGraphVertex = currentLayerNode->getVertex();
  4300. //Assign Topological order to graph vertex
  4301. m_BoostGraphWrapper.setVertexTopologicalOrder(iTopologicalOrder , vGlobalGraphVertex , *m_gMainGraph);
  4302. //Increase iTopologicalOrder
  4303. iTopologicalOrder++;
  4304. }
  4305. else
  4306. {
  4307. //The subgraph ordering graph vertex is a NestingTreeNode
  4308. currentNestingTreeNode = m_subgraphOrderingGraphWrapper.getVertexNestingTreeSubgraphNode(
  4309. vSubgraphOrderingGraphVertex , *gSubgraphOrderingGraph);
  4310. //Recursive call
  4311. iNextTopologicalOrderValue = assignTopologicalOrderAccordingToSubgraphOrderingGraph(
  4312. iTopologicalOrder , currentNestingTreeNode);
  4313. iTopologicalOrder = iNextTopologicalOrderValue;
  4314. }
  4315. //Fill mapLowerLayer with child (next) vertices of current vSubgraphOrderingGraphVertex
  4316. //To get them sorted on theeir average barrycenter position
  4317. mapBarrycenterToAdjacentVertices.clear();
  4318. BGL_FORALL_ADJ(vSubgraphOrderingGraphVertex , vAdjacentVertex , *gSubgraphOrderingGraph , SubgraphOrderingGraphType)
  4319. {
  4320. //Skip vertices which are already added to queue
  4321. if(vecQueuedSubgraphOrderingGraphVertex[vAdjacentVertex] == true)
  4322. {
  4323. //Skip
  4324. continue;
  4325. }
  4326. else
  4327. {
  4328. //Mark the vertex as added in queue
  4329. vecQueuedSubgraphOrderingGraphVertex[vAdjacentVertex] = true;
  4330. }
  4331. //Get average barry center
  4332. dAverageBarryCenter = getSubgraphOrderingGraphVertexAverageBarryCenter(
  4333. vAdjacentVertex , *gSubgraphOrderingGraph);
  4334. //Insert adjacent cartex into Lower layer vertices map
  4335. mapBarrycenterToAdjacentVertices.insertMulti(dAverageBarryCenter , vAdjacentVertex);
  4336. }
  4337. //Put vertices from map to qLowerLayerVertices
  4338. IteratorMapAverageBarryCenterToSOGVertex iterAdjacentVertices(mapBarrycenterToAdjacentVertices);
  4339. while(iterAdjacentVertices.hasNext())
  4340. {
  4341. iterAdjacentVertices.next();
  4342. SubgraphOrderingGraphVertexDescriptor vAdjacentVertex = iterAdjacentVertices.value();
  4343. //Fill qLowerLayer
  4344. qLowerLayerVertex->enqueue(vAdjacentVertex);
  4345. }
  4346. }//Iterate upper layer vertices End
  4347. //Make LowerLayer queue of adjacent(child) vertices to be the queue of next upperLayer vertices
  4348. qUpperLayerVertex = qLowerLayerVertex;
  4349. qLowerLayerVertex = NULL;
  4350. }while(qUpperLayerVertex->isEmpty() == false);
  4351. }
  4352. }
  4353. catch(boost::exception &eBoostException)
  4354. {
  4355. throw *boost::get_error_info<errmsg_info>(eBoostException);
  4356. }
  4357. catch(LayoutException &eLayoutException)
  4358. {
  4359. throw eLayoutException;
  4360. }
  4361. // XXX obselete
  4362. // catch(LayoutMemoryException &eMemoryException)
  4363. // {
  4364. // throw eMemoryException;
  4365. // }
  4366. catch(...)
  4367. {
  4368. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  4369. }
  4370. return iTopologicalOrder;
  4371. }
  4372. void HierarchicalLayouter::updateAverageBarryCenterForNestingTreeNodes()
  4373. {
  4374. try
  4375. {
  4376. LAYOUT_ASSERT(m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef.isEmpty() == false,
  4377. LayoutException(__FUNCTION__
  4378. , LayoutExceptionEnum::EMPTY_CONTAINER
  4379. , "Map must not be empty"
  4380. , "mapNestingTreeNodeRefToSubgraphOrderingGraphRef"));
  4381. double dAverageBarryCenter = 0.0;
  4382. // XXX unused
  4383. Q_UNUSED(dAverageBarryCenter);
  4384. IteratorMapNestingTreeRefToSubgraphOrderingGraphRef iterNestingTreeNodeToSubgraphOrderingGraph(
  4385. m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef);
  4386. NestingTreeSubgraphNode* currentNestingTreeNode = NULL;
  4387. while(iterNestingTreeNodeToSubgraphOrderingGraph.hasNext())
  4388. {
  4389. iterNestingTreeNodeToSubgraphOrderingGraph.next();
  4390. currentNestingTreeNode = iterNestingTreeNodeToSubgraphOrderingGraph.key();
  4391. //Skip root nesting tree Subgraph Node
  4392. if(currentNestingTreeNode->isRoot() == false)
  4393. {
  4394. //Recalculate and update averageBarryCenter of nesting tree node
  4395. dAverageBarryCenter = currentNestingTreeNode->updateAverageBarryCenter();
  4396. }
  4397. }
  4398. }
  4399. catch(boost::exception &eBoostException)
  4400. {
  4401. throw *boost::get_error_info<errmsg_info>(eBoostException);
  4402. }
  4403. catch(LayoutException &eLayoutException)
  4404. {
  4405. throw eLayoutException;
  4406. }
  4407. // XXX obselete
  4408. // catch(LayoutMemoryException &eMemoryException)
  4409. // {
  4410. // throw eMemoryException;
  4411. // }
  4412. catch(...)
  4413. {
  4414. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  4415. }
  4416. }
  4417. double HierarchicalLayouter::getSubgraphOrderingGraphVertexAverageBarryCenter(SubgraphOrderingGraphVertexDescriptor vVertex, SubgraphOrderingGraphType &gSubgraphOrderingGraph)
  4418. {
  4419. LAYOUT_ASSERT(gSubgraphOrderingGraph.find_vertex(vVertex).second == true, LayoutException(__FUNCTION__
  4420. , LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER
  4421. , "gSubgraphOrderingGraph"
  4422. , "vVertex"));
  4423. bool bIsLayerNodeVertex = m_subgraphOrderingGraphWrapper.isSubgraphOrderingVertexIsLayerNode(
  4424. vVertex , gSubgraphOrderingGraph);
  4425. double dAverageBarryCenter = 0.0;
  4426. if(bIsLayerNodeVertex == true)
  4427. {
  4428. //The SubgraphOrderingGraphType vVertex is a LayerNode
  4429. LayerNode* layerNode = m_subgraphOrderingGraphWrapper.getVertexLayerNodeRef(
  4430. vVertex , gSubgraphOrderingGraph);
  4431. VertexDescriptor vGlobalVertex = layerNode->getVertex();
  4432. dAverageBarryCenter = m_BoostGraphWrapper.getVertexHorizontalPosition(vGlobalVertex , *m_gMainGraph);
  4433. }
  4434. else
  4435. {
  4436. //The SubgraphOrderingGraphType vVertex is a NestingTreeSubgraph node
  4437. NestingTreeSubgraphNode* nestingTreeNode
  4438. = m_subgraphOrderingGraphWrapper.getVertexNestingTreeSubgraphNode(
  4439. vVertex , gSubgraphOrderingGraph);
  4440. dAverageBarryCenter = nestingTreeNode->getAverageBarryCenter();
  4441. }
  4442. return dAverageBarryCenter;
  4443. }
  4444. void HierarchicalLayouter::addVerticalBorderNodesForSubgraphs()
  4445. {
  4446. LAYOUT_ASSERT(m_iRankDifferenceInLayers.isSet() == true,
  4447. LayoutException(__FUNCTION__
  4448. ,LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  4449. ,"Rank Difference in layers"
  4450. ,""));
  4451. try
  4452. {
  4453. //First update horizontal LayerNode positions to accomodate verticalBorderNodes
  4454. setHorizontalPositionsForVerticalBorderNodes();
  4455. //Recursively add Vertical Border nodes from innermost leaf NestingTreeNodes
  4456. //to Root Nesting tree node
  4457. addVerticalBorderNodesNestingTreeRecur(m_rootNestingTreeSubgraphNode);
  4458. }
  4459. catch(boost::exception &eBoostException)
  4460. {
  4461. throw *boost::get_error_info<errmsg_info>(eBoostException);
  4462. }
  4463. catch(LayoutException &eLayoutException)
  4464. {
  4465. throw eLayoutException;
  4466. }
  4467. // XXX obselete
  4468. // catch(LayoutMemoryException &eMemoryException)
  4469. // {
  4470. // throw eMemoryException;
  4471. // }
  4472. catch(...)
  4473. {
  4474. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  4475. }
  4476. }
  4477. void HierarchicalLayouter::addVerticalBorderNodesNestingTreeRecur(NestingTreeSubgraphNode &nestingTreeNode)
  4478. {
  4479. try
  4480. {
  4481. //Map to contain all LayerNodes of current NestingTreeNode. This includes all LayerNodes of
  4482. //its child NestingTree nodes hierarchy
  4483. NestingTreeSubgraphNode::MultiMapLayerIdToLayerNodeRef mapLayerIdToLayerNode;
  4484. int iLayerId = 0;
  4485. int iHorizontalPosition = 0;
  4486. int iMinHorizontalPosition = 0;
  4487. int iMaxHorizontalPosition = 0;
  4488. int iUpperBorderVertexLayerId = 0;
  4489. int iLowerBorderVertexLayerId = 0;
  4490. LayerNode* layerNode = NULL;
  4491. VertexDescriptor vVertex = 0;
  4492. VertexDescriptor vLeftVerticalBorder = 0;
  4493. VertexDescriptor vRightVerticalBorder = 0;
  4494. VertexDescriptor vPreviousLeftVerticalBorder = 0;
  4495. VertexDescriptor vPreviousRightVerticalBorder = 0;
  4496. VertexDescriptor vGlobalLeftVerticalBorder = 0;
  4497. VertexDescriptor vGlobalRightVerticalBorder = 0;
  4498. LayerNode* leftLayerNode = NULL;
  4499. LayerNode* rightLayerNode = NULL;
  4500. NestingTreeSubgraphNode::IteratorVectorNestingTreeSubgraphNodesRef iterChildNestingTreenodes
  4501. = nestingTreeNode.getIteratorChildNestingTreeSubgraphNodes();
  4502. NestingTreeSubgraphNode* childNestingTreeNode = NULL;
  4503. while(iterChildNestingTreenodes.hasNext())
  4504. {
  4505. childNestingTreeNode = iterChildNestingTreenodes.next();
  4506. //Recursive call
  4507. addVerticalBorderNodesNestingTreeRecur(*childNestingTreeNode);
  4508. //Accumulate all Layernode of childNestingTreeNode to mapLayerIdToLayerNode
  4509. NestingTreeSubgraphNode::IteratorMultiMapLayerIdToLayerNodeRef iterChildLayerNode
  4510. = childNestingTreeNode->getChildLayerNodesIterator();
  4511. while(iterChildLayerNode.hasNext())
  4512. {
  4513. iterChildLayerNode.next();
  4514. //Add layer node
  4515. mapLayerIdToLayerNode.insertMulti(iterChildLayerNode.key(),iterChildLayerNode.value());
  4516. }
  4517. }//Iterating child Nesting Tree End
  4518. //Add own direct layer nodes to mapLayerIdToLayerNode
  4519. NestingTreeSubgraphNode::MultiMapLayerIdToLayerNodeRef& mapOwnLayerNodes
  4520. = nestingTreeNode.getMapLayerIdToLayerNodeRef();
  4521. mapLayerIdToLayerNode += mapOwnLayerNodes;
  4522. //Get upper and Lower border vertex ranks - LayerIds, because
  4523. //to add VerticalBorderVertices for only own Border Vertices
  4524. iUpperBorderVertexLayerId = nestingTreeNode.getMinRank();
  4525. iLowerBorderVertexLayerId = nestingTreeNode.getMaxRank();
  4526. //get unique layerIds in ascending order
  4527. QList<int> listLayerIds = mapLayerIdToLayerNode.uniqueKeys();
  4528. QListIterator<int> iterLayerId(listLayerIds);
  4529. bool bIsFirstVerticalNode = true;
  4530. while(iterLayerId.hasNext())
  4531. {
  4532. iLayerId = iterLayerId.next();
  4533. //testing 42214-1 - consider only GraphNodeLayers
  4534. if(iLayerId % m_iRankDifferenceInLayers != 0)//commented for 5914-1
  4535. {
  4536. //Inside- means iLayerId is a Upper or Lower Border Vertex Layer
  4537. //Skip other subgraphs BorderLayers. Allow only current subgraph
  4538. //border layer ids
  4539. //testing 42214-2
  4540. if(iLayerId != iUpperBorderVertexLayerId &&
  4541. iLayerId != iLowerBorderVertexLayerId)
  4542. {
  4543. //Skip other subgraphs BorderLayers.
  4544. continue;//5914-1 commented for.
  4545. }
  4546. }
  4547. iMinHorizontalPosition = INT_MAX;
  4548. iMaxHorizontalPosition = INT_MIN;
  4549. //Get LayerNodes with same LayerId in a list
  4550. QList<LayerNode*> listLayer = mapLayerIdToLayerNode.values(iLayerId);
  4551. QListIterator<LayerNode*> iterListLayerNode(listLayer);
  4552. while(iterListLayerNode.hasNext())
  4553. {
  4554. layerNode = iterListLayerNode.next();
  4555. vVertex = layerNode->getVertex();
  4556. //Get horizontal position
  4557. iHorizontalPosition = m_BoostGraphWrapper.getVertexHorizontalPosition(
  4558. vVertex , *m_gMainGraph);
  4559. if(iHorizontalPosition < iMinHorizontalPosition)
  4560. {
  4561. iMinHorizontalPosition = iHorizontalPosition;
  4562. }
  4563. if(iHorizontalPosition > iMaxHorizontalPosition)
  4564. {
  4565. iMaxHorizontalPosition = iHorizontalPosition;
  4566. }
  4567. }
  4568. SubGraph &gProperSubgraph = nestingTreeNode.getGraph();
  4569. //*********Add VerticalBorder Vertex at position one minus the min horizontal position
  4570. //Create vertex with VerticalBorderNode type
  4571. vLeftVerticalBorder = m_BoostGraphWrapper.addVertex(gProperSubgraph , LayoutEnum::VerticalBorderNode);
  4572. //Convert vLeftVerticalBorder index from local to global index to add to Layernode
  4573. vGlobalLeftVerticalBorder = gProperSubgraph.local_to_global(vLeftVerticalBorder);
  4574. //Set vertex rank
  4575. m_BoostGraphWrapper.setVertexRank(vGlobalLeftVerticalBorder , *m_gMainGraph , iLayerId);
  4576. //Add Layer Node for new VerticalBorderVertex
  4577. leftLayerNode = new LayerNode(nestingTreeNode , vGlobalLeftVerticalBorder);
  4578. //Add new Layer Node Entry to hashVertexToLayerNode
  4579. hashVertexToLayerNode.insert(vGlobalLeftVerticalBorder , leftLayerNode);
  4580. //Add Layer Node for new VerticalBorderVertex's entry to the Nesting Graph
  4581. nestingTreeNode.addLayerIdAndLayerNode(iLayerId , leftLayerNode);
  4582. //Set vertx Horizontal position
  4583. m_BoostGraphWrapper.setVertexHorizontalPosition(vGlobalLeftVerticalBorder , *m_gMainGraph , (iMinHorizontalPosition - 1));
  4584. //insert Layernode into layer
  4585. LAYOUT_ASSERT((m_mapLayeredGraph[iLayerId]->contains((iMinHorizontalPosition - 1))) == false
  4586. ,LayoutException(__FUNCTION__
  4587. ,LayoutExceptionEnum::INVALID_OPERATION
  4588. ,"adding node at horizontal position which is already taken by another node at same layer"
  4589. ,"Adding Vertical Border Node"));
  4590. m_mapLayeredGraph[iLayerId]->insert(iMinHorizontalPosition - 1 , leftLayerNode);
  4591. //*********Add VerticalBorder Vertex at position one plus the max horizontal position
  4592. //Create vertex with VerticalBorderNode type
  4593. vRightVerticalBorder = m_BoostGraphWrapper.addVertex(gProperSubgraph , LayoutEnum::VerticalBorderNode);
  4594. //Convert vRightVerticalBorder index from local to global index to add to Layernode
  4595. vGlobalRightVerticalBorder = gProperSubgraph.local_to_global(vRightVerticalBorder);
  4596. //Set vertex rank
  4597. m_BoostGraphWrapper.setVertexRank(vGlobalRightVerticalBorder , *m_gMainGraph , iLayerId);
  4598. //Add Layer Node for new VerticalBorderVertex
  4599. rightLayerNode = new LayerNode(nestingTreeNode , vGlobalRightVerticalBorder);
  4600. //Add new Layer Node Entry to hashVertexToLayerNode
  4601. hashVertexToLayerNode.insert(vGlobalRightVerticalBorder , rightLayerNode);
  4602. //Add Layer Node for new VerticalBorderVertex's entry to the Nesting Graph
  4603. nestingTreeNode.addLayerIdAndLayerNode(iLayerId , rightLayerNode);
  4604. //Set vertx Horizontal position
  4605. m_BoostGraphWrapper.setVertexHorizontalPosition(vGlobalRightVerticalBorder , *m_gMainGraph , (iMaxHorizontalPosition + 1));
  4606. //insert Layernode into layer
  4607. LAYOUT_ASSERT((m_mapLayeredGraph[iLayerId]->contains(iMaxHorizontalPosition + 1)) == false
  4608. ,LayoutException(__FUNCTION__
  4609. ,LayoutExceptionEnum::INVALID_OPERATION
  4610. ,"adding node at horizontal position which is already taken by another node at same layer"
  4611. ,"Adding Vertical Border Node"));
  4612. m_mapLayeredGraph[iLayerId]->insert(iMaxHorizontalPosition + 1 , rightLayerNode);
  4613. //Add edges
  4614. if(bIsFirstVerticalNode == false)
  4615. {
  4616. //Add Long Edge Segment
  4617. m_BoostGraphWrapper.addEdge(vPreviousLeftVerticalBorder , vLeftVerticalBorder ,
  4618. gProperSubgraph , LayoutEnum::VerticalBorderEdgeSegment);
  4619. //Add Long Edge Segment
  4620. m_BoostGraphWrapper.addEdge(vPreviousRightVerticalBorder , vRightVerticalBorder ,
  4621. gProperSubgraph , LayoutEnum::VerticalBorderEdgeSegment);
  4622. }
  4623. if(bIsFirstVerticalNode == true)
  4624. {
  4625. bIsFirstVerticalNode = false;
  4626. }
  4627. //Set current Vertical Border Vertices as
  4628. //Previous Vertices to add edge between them later
  4629. vPreviousLeftVerticalBorder = vLeftVerticalBorder;
  4630. vPreviousRightVerticalBorder = vRightVerticalBorder;
  4631. }
  4632. }
  4633. catch(boost::exception &eBoostException)
  4634. {
  4635. throw *boost::get_error_info<errmsg_info>(eBoostException);
  4636. }
  4637. catch(LayoutException &eLayoutException)
  4638. {
  4639. throw eLayoutException;
  4640. }
  4641. // XXX obselete
  4642. // catch(LayoutMemoryException &eMemoryException)
  4643. // {
  4644. // throw eMemoryException;
  4645. // }
  4646. catch(...)
  4647. {
  4648. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  4649. }
  4650. }
  4651. void HierarchicalLayouter::addDummyNodeToEmptyLayersRecur(NestingTreeSubgraphNode &rootNestingTreeNode)
  4652. {
  4653. //Map to contain all LayerNodes of current NestingTreeNode. This includes all LayerNodes of
  4654. //its child NestingTree nodes hierarchy
  4655. // NestingTreeSubgraphNode::MultiMapLayerIdToLayerNodeRef mapLayerIdToLayerNode;
  4656. int iLayerId = 0;
  4657. int iDummyNodeHorizontalPosition = 0;
  4658. VertexDescriptor vDummyVertex = 0;
  4659. VertexDescriptor vGlobalDummyVertex = 0;
  4660. LayerNode* dummyLayerNode = NULL;
  4661. try
  4662. {
  4663. NestingTreeSubgraphNode::IteratorVectorNestingTreeSubgraphNodesRef iterChildNestingTreenodes
  4664. = rootNestingTreeNode.getIteratorChildNestingTreeSubgraphNodes();
  4665. NestingTreeSubgraphNode* childNestingTreeNode = NULL;
  4666. while(iterChildNestingTreenodes.hasNext())
  4667. {
  4668. childNestingTreeNode = iterChildNestingTreenodes.next();
  4669. //Recursive call
  4670. addDummyNodeToEmptyLayersRecur(*childNestingTreeNode);
  4671. }//Iterating child Nesting Tree End
  4672. /*Find list of empty layer ids
  4673. *
  4674. *A graphs child layer nodes are not above its UpperBorderVertex and not below its
  4675. *LowerBorderVertex. Therefor number of layers a graph covers are layers between
  4676. *Upper and Lower Border Vertices
  4677. */
  4678. VertexDescriptor vUpperBorderVertex = 0;
  4679. VertexDescriptor vLowerBorderVertex = 0;
  4680. // XXX unused
  4681. Q_UNUSED(vUpperBorderVertex);
  4682. Q_UNUSED(vLowerBorderVertex);
  4683. int iUpperLayerId = 0;
  4684. int iLowerLayerId = 0;
  4685. int iLastHorizontalPosition = 0;
  4686. bool bIsContainLayerId = true;
  4687. SubGraph& gSubgraph = rootNestingTreeNode.getGraph();
  4688. iUpperLayerId = rootNestingTreeNode.getMinRank();
  4689. iLowerLayerId = rootNestingTreeNode.getMaxRank();
  4690. /*Add dummy node in empty layers
  4691. *
  4692. *Every nestingTreeNode records which LayerId layerNodes its hierarchy of nesting tree contains
  4693. *So if any LayerId is not present in that hash of LayerIds the layer is empty
  4694. */
  4695. MapPositionToLayerNode::iterator iterLayerNode;
  4696. MapLayerIdToLayerRef::iterator iterLayer , iterLayerEnd;
  4697. iterLayer = m_mapLayeredGraph.find(iUpperLayerId);
  4698. iterLayerEnd = m_mapLayeredGraph.find(iLowerLayerId);
  4699. for(;iterLayer != iterLayerEnd ; iterLayer++)
  4700. {
  4701. iLayerId = iterLayer.key();
  4702. //Testing 42214-1 Consider only GraphNodeLayers
  4703. if(iLayerId % m_iRankDifferenceInLayers != 0)
  4704. {
  4705. continue;
  4706. }
  4707. bIsContainLayerId = rootNestingTreeNode.doesSubgraphNodeContainLayerId(iLayerId);
  4708. ////qDebug() << iLayerId;
  4709. if(bIsContainLayerId == false)
  4710. {
  4711. ////qDebug()<<"Empty Layer: "<<iLayerId;
  4712. //Add dummy node to the empty layer
  4713. //Create vertex with VerticalBorderNode type
  4714. vDummyVertex = m_BoostGraphWrapper.addVertex(gSubgraph , LayoutEnum::DummyNode);
  4715. //Convert vLeftVerticalBorder index from local to global index to add to Layernode
  4716. vGlobalDummyVertex = gSubgraph.local_to_global(vDummyVertex);
  4717. //Set vertex rank
  4718. m_BoostGraphWrapper.setVertexRank(vGlobalDummyVertex , *m_gMainGraph , iLayerId);
  4719. //Add Layer Node for new VerticalBorderVertex
  4720. dummyLayerNode = new LayerNode(rootNestingTreeNode , vGlobalDummyVertex);
  4721. //Add new Layer Node Entry to hashVertexToLayerNode
  4722. hashVertexToLayerNode.insert(vGlobalDummyVertex , dummyLayerNode);
  4723. //Add Layer Node for new VerticalBorderVertex's entry to the Nesting Graph
  4724. rootNestingTreeNode.addLayerIdAndLayerNode(iLayerId , dummyLayerNode);
  4725. //Get last horizontal position in the layer
  4726. iterLayerNode = m_mapLayeredGraph[iLayerId]->end();
  4727. iterLayerNode--;
  4728. iLastHorizontalPosition = iterLayerNode.key();
  4729. //Set vertex next position to the last horizontal position as it will be
  4730. //changed while SubgraphOrderingGraph Crossing Reduction
  4731. iDummyNodeHorizontalPosition = iLastHorizontalPosition + 1;
  4732. m_BoostGraphWrapper.setVertexHorizontalPosition(vGlobalDummyVertex , *m_gMainGraph ,iDummyNodeHorizontalPosition);
  4733. //insert Layernode into layer
  4734. LAYOUT_ASSERT((m_mapLayeredGraph[iLayerId]->contains(iDummyNodeHorizontalPosition)) == false
  4735. ,LayoutException(__FUNCTION__
  4736. ,LayoutExceptionEnum::INVALID_OPERATION
  4737. ,"inserting Layernode into layer at position which is already taken by other node"
  4738. ,"Adding Dummy Node to Empty Layers"));
  4739. m_mapLayeredGraph[iLayerId]->insertMulti(iDummyNodeHorizontalPosition , dummyLayerNode);
  4740. }
  4741. }
  4742. }
  4743. catch(boost::exception &eBoostException)
  4744. {
  4745. throw *boost::get_error_info<errmsg_info>(eBoostException);
  4746. }
  4747. catch(LayoutException &eLayoutException)
  4748. {
  4749. throw eLayoutException;
  4750. }
  4751. catch(...)
  4752. {
  4753. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  4754. }
  4755. }
  4756. void HierarchicalLayouter::assignYCoordinates(SubGraph &gMainGraph)
  4757. {
  4758. //"Applying Center Coordinates from rank and position" , "gMainGraph is not main root graph"
  4759. LAYOUT_ASSERT(gMainGraph.is_root() == true , LayoutException(__FUNCTION__
  4760. , LayoutExceptionEnum::INVALID_PARAMETER
  4761. , "Main Graph"
  4762. , "MainGraph is not main root graph"));
  4763. try
  4764. {
  4765. PGL_MAP_VERTEX_BUNDLED_PROPERTY(mapVertexHorizontalPosition , int , iHorizontalPosition , gMainGraph);
  4766. PGL_MAP_VERTEX_BUNDLED_PROPERTY(mapVertexRank , int , iRank , gMainGraph);
  4767. PGL_MAP_VERTEX_BUNDLED_PROPERTY(mapVertexBarryCenter , double , dBarryCenter , gMainGraph);
  4768. int iMaxHeight = 0;
  4769. int iLayerNodeHeight = 0;
  4770. int dBarryCenter = 0;
  4771. int iYCoordinate = 0;
  4772. int iVerticalStep = 0;
  4773. int iHalfHeight = 0;
  4774. int iPreviousHalfHeight = 0;
  4775. int iMaxOutDegree = 0;
  4776. int iMaxInDegree = 0;
  4777. int iOutDegree = 0;
  4778. int iInDegree = 0;
  4779. int iInDegreeSpace = 0;
  4780. int iOutDegreeSpace = 0;
  4781. int iPreviousOutDegreeSpace = 0;
  4782. bool bIsBorderLayer = false;
  4783. bool bIsPrevBorderLayer = true;
  4784. // XXX unused
  4785. Q_UNUSED(bIsPrevBorderLayer);
  4786. LayerNode* layerNode = NULL;
  4787. VertexDescriptor vLayerVertex = 0;
  4788. QMap<int,int> mapLayerIdToHalfHeight;
  4789. QMap<int,int> mapLayerIdToYCoord;
  4790. Q_UNUSED(dBarryCenter);
  4791. //Set y coordinates according to node heights
  4792. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  4793. while(iterLayer.hasNext())
  4794. {
  4795. iterLayer.next();
  4796. //Skip border layers
  4797. if(iterLayer.key() % m_iRankDifferenceInLayers != 0)
  4798. {
  4799. //continue;
  4800. }
  4801. //42314-2
  4802. //iMaxLayerOutDegree = 0;
  4803. //42414-1
  4804. iMaxOutDegree = INT_MIN;
  4805. iMaxInDegree = INT_MIN;
  4806. iInDegreeSpace = 0;
  4807. iOutDegreeSpace = 0;
  4808. iMaxHeight = INT_MIN;
  4809. IteratorMapPositionToLayerNode iterLayerNode(*(iterLayer.value()));
  4810. while(iterLayerNode.hasNext())
  4811. {
  4812. iterLayerNode.next();
  4813. layerNode = iterLayerNode.value();
  4814. vLayerVertex = layerNode->getVertex();
  4815. iLayerNodeHeight = m_BoostGraphWrapper.getVertexHeight(vLayerVertex , *m_gMainGraph);
  4816. //Testing 42414-1 - Maximum out degree
  4817. iOutDegree = out_degree(vLayerVertex , *m_gMainGraph);//42314-2
  4818. iMaxOutDegree = (iMaxOutDegree < iOutDegree) ? iOutDegree : iMaxOutDegree;
  4819. // iMaxOutDegree += iOutDegree;
  4820. //Maximum In degree
  4821. iInDegree = in_degree(vLayerVertex , *m_gMainGraph);//42414-1
  4822. iMaxInDegree = (iMaxInDegree < iInDegree) ? iInDegree : iMaxInDegree;
  4823. // iMaxInDegree += iInDegree;
  4824. if(iLayerNodeHeight > iMaxHeight)
  4825. {
  4826. iMaxHeight = iLayerNodeHeight;
  4827. }
  4828. }
  4829. if(iterLayer.key() % m_iRankDifferenceInLayers != 0)
  4830. {
  4831. bIsBorderLayer = true;
  4832. // iMaxOutDegree = 2;
  4833. }
  4834. else
  4835. {
  4836. bIsBorderLayer = false;
  4837. }
  4838. iHalfHeight = iMaxHeight / 2;
  4839. //Store half heights of each graph layer for later use
  4840. mapLayerIdToHalfHeight[iterLayer.key()] = iHalfHeight;
  4841. //Increament y coordinate by half height because every layer must have atleast
  4842. //its max half height space to draw every node on it half above and half below
  4843. //the ycoordinate
  4844. iYCoordinate += iHalfHeight + iPreviousHalfHeight;
  4845. //calculate current vertical step
  4846. iVerticalStep = iHalfHeight + iPreviousHalfHeight;
  4847. //Add previous outdegree space
  4848. iYCoordinate += iPreviousOutDegreeSpace;
  4849. //42414-2
  4850. iInDegreeSpace = iMaxInDegree * (m_iEdgeSeparation);
  4851. //Update y coordinate from iInDegreeSpace by comparing iInDegreeSpace and
  4852. //iPreviousOutDegreeSpace value. If iPreviousOutDegreeSpace is larger than
  4853. //iInDegreeSpace then no need to increase y coordinate by iInDegreeSpace.
  4854. //Otherwise increase y by iInDegreeSpace - iPreviousOutDegreeSpace.
  4855. if(iPreviousOutDegreeSpace < iInDegreeSpace )
  4856. {
  4857. iYCoordinate += (iInDegreeSpace - iPreviousOutDegreeSpace);
  4858. //Update vertical step
  4859. iVerticalStep += (iInDegreeSpace - iPreviousOutDegreeSpace);
  4860. }
  4861. if(iVerticalStep < m_iRankSeparation)
  4862. {
  4863. //if(bIsBorderLayer == false && bIsPrevBorderLayer == false)
  4864. {
  4865. //Make minimum rank separation
  4866. iYCoordinate += m_iRankSeparation;
  4867. }
  4868. }
  4869. //Store y coord for later use
  4870. mapLayerIdToYCoord[iterLayer.key()] = iYCoordinate;
  4871. //Set y coordinate
  4872. IteratorMapPositionToLayerNode iterLayerNodeToAssignYcoord(*(iterLayer.value()));
  4873. while(iterLayerNodeToAssignYcoord.hasNext())
  4874. {
  4875. iterLayerNodeToAssignYcoord.next();
  4876. layerNode = iterLayerNodeToAssignYcoord.value();
  4877. vLayerVertex = layerNode->getVertex();
  4878. // //if(out_degree(vLayerVertex , *m_gMainGraph) > in_degree(vLayerVertex , *m_gMainGraph))
  4879. // {
  4880. // iSpecificYCoordinate += (iMaxOutDegree - out_degree(vLayerVertex , *m_gMainGraph))*m_iEdgeSeparation;
  4881. // }
  4882. // iSpecificYCoordinate -= (iMaxInDegree - in_degree(vLayerVertex , *m_gMainGraph))*m_iEdgeSeparation;
  4883. m_BoostGraphWrapper.setVertexCenterCoordY(vLayerVertex , *m_gMainGraph , iYCoordinate);
  4884. }
  4885. //42314-2
  4886. iOutDegreeSpace = (iMaxOutDegree)* (m_iEdgeSeparation);
  4887. //if(!bIsBorderLayer)
  4888. iPreviousOutDegreeSpace = iOutDegreeSpace;
  4889. iPreviousHalfHeight = iHalfHeight;
  4890. bIsPrevBorderLayer = bIsBorderLayer;
  4891. }
  4892. //Assign y coordinates to border layers of each graph separately
  4893. //give y coords from innermost graph
  4894. QQueue<SubGraph*> qSubgraphs;
  4895. qSubgraphs.enqueue(m_gMainGraph);
  4896. QStack<SubGraph*> stackSubgraph;
  4897. SubGraph* gGraph = NULL;
  4898. while(qSubgraphs.isEmpty() == false)
  4899. {
  4900. gGraph = qSubgraphs.dequeue();
  4901. stackSubgraph.push(gGraph);
  4902. ChildrenIterator iterChild , iterChildEnd;
  4903. for(boost::tie(iterChild , iterChildEnd) = gGraph->children();
  4904. iterChild != iterChildEnd;
  4905. iterChild++)
  4906. {
  4907. SubGraph* gChildGraph = &(*iterChild);
  4908. qSubgraphs.enqueue(gChildGraph);
  4909. }
  4910. }
  4911. VertexDescriptor vUpperBorder = 0;
  4912. VertexDescriptor vLowerBorder = 0;
  4913. VertexDescriptor vLeftVerticalBorder = 0;
  4914. VertexDescriptor vRightVerticalBorder = 0;
  4915. int iBorderLayerRank = 0;
  4916. int iNextLayerId = 0;
  4917. int iPrevLayerId = 0;
  4918. int iYCoordNextLayer = 0;
  4919. int iYCoordPrevLayer = 0;
  4920. VertexDescriptor vVertex = 0;
  4921. Q_UNUSED(vVertex);
  4922. int iHorizontalPos = 0;
  4923. MapLayerIdToLayerRef::iterator iterGraphLayer;
  4924. MapPositionToLayerNode::iterator iterLayerNode;
  4925. ////qDebug()<<"Setting border layer y coordinate";
  4926. while(stackSubgraph.isEmpty() == false)
  4927. {
  4928. gGraph = stackSubgraph.pop();
  4929. //Get upperborder and lower border vertex
  4930. vUpperBorder = m_BoostGraphWrapper.getGraphUpperBorderVertex(*gGraph);
  4931. vLowerBorder = m_BoostGraphWrapper.getGraphLowerBorderVertex(*gGraph);
  4932. vUpperBorder = gGraph->local_to_global(vUpperBorder);
  4933. vLowerBorder = gGraph->local_to_global(vLowerBorder);
  4934. //find layer of upper border vertex
  4935. iBorderLayerRank = m_BoostGraphWrapper.getVertexRank(vUpperBorder , *m_gMainGraph);
  4936. ////qDebug()<<"Upper border: "<<iBorderLayerRank;
  4937. //Get next layer id
  4938. iterGraphLayer = m_mapLayeredGraph.find(iBorderLayerRank);
  4939. iterGraphLayer++;
  4940. iNextLayerId = iterGraphLayer.key();
  4941. //Get next layer y coordinate
  4942. ////qDebug()<<"Next layer id: "<<iNextLayerId;
  4943. LAYOUT_ASSERT(mapLayerIdToYCoord.contains(iNextLayerId) , LayoutException(__FUNCTION__
  4944. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  4945. , "Y Coordinate of next layer"
  4946. , ""));
  4947. iYCoordNextLayer = mapLayerIdToYCoord[iNextLayerId];
  4948. //Get next layer max vertex height
  4949. LAYOUT_ASSERT(mapLayerIdToHalfHeight.contains(iNextLayerId), LayoutException(__FUNCTION__
  4950. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  4951. , "Half height of next layer"
  4952. , ""));
  4953. iHalfHeight = mapLayerIdToHalfHeight[iNextLayerId];
  4954. //Get neighbor vertical border vertices
  4955. iHorizontalPos = m_BoostGraphWrapper.getVertexHorizontalPosition(vUpperBorder , *m_gMainGraph);
  4956. iterLayerNode = m_mapLayeredGraph[iBorderLayerRank]->find(iHorizontalPos);
  4957. iterLayerNode--;
  4958. vLeftVerticalBorder = (iterLayerNode.value())->getVertex();
  4959. iterLayerNode++;
  4960. iterLayerNode++;
  4961. vRightVerticalBorder = (iterLayerNode.value())->getVertex();
  4962. //Calculate y coord for upper border for gGraph
  4963. iYCoordinate = iYCoordNextLayer - iHalfHeight - 40;
  4964. //assign y coord to upper border vertex and neighbor vertical border nodes
  4965. m_BoostGraphWrapper.setVertexCenterCoordY(vUpperBorder , *m_gMainGraph , iYCoordinate);
  4966. m_BoostGraphWrapper.setVertexCenterCoordY(vLeftVerticalBorder , *m_gMainGraph , iYCoordinate);
  4967. m_BoostGraphWrapper.setVertexCenterCoordY(vRightVerticalBorder , *m_gMainGraph , iYCoordinate);
  4968. mapLayerIdToHalfHeight[iBorderLayerRank] = 0;
  4969. mapLayerIdToYCoord[iBorderLayerRank] = iYCoordinate;
  4970. //find layer of lower border vertex
  4971. //assign y coord to lower border vertex and neighbor vertical border nodes
  4972. //find layer of Lower border vertex
  4973. iBorderLayerRank = m_BoostGraphWrapper.getVertexRank(vLowerBorder , *m_gMainGraph);
  4974. //Get prev layer id
  4975. iterGraphLayer = m_mapLayeredGraph.find(iBorderLayerRank);
  4976. iterGraphLayer--;
  4977. iPrevLayerId = iterGraphLayer.key();
  4978. //Get prev layer y coordinate
  4979. LAYOUT_ASSERT(mapLayerIdToYCoord.contains(iPrevLayerId) , LayoutException(__FUNCTION__
  4980. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  4981. , "Y Coordinate of next layer"
  4982. , ""));
  4983. iYCoordPrevLayer = mapLayerIdToYCoord[iPrevLayerId];
  4984. //Get prev layer max vertex height
  4985. LAYOUT_ASSERT(mapLayerIdToHalfHeight.contains(iPrevLayerId) , LayoutException(__FUNCTION__
  4986. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  4987. , "Half height of next layer"
  4988. , ""));
  4989. iHalfHeight = mapLayerIdToHalfHeight[iPrevLayerId];
  4990. //Get neighbor vertical border vertices
  4991. iHorizontalPos = m_BoostGraphWrapper.getVertexHorizontalPosition(vLowerBorder , *m_gMainGraph);
  4992. iterLayerNode = m_mapLayeredGraph[iBorderLayerRank]->find(iHorizontalPos);
  4993. iterLayerNode--;
  4994. vLeftVerticalBorder = (iterLayerNode.value())->getVertex();
  4995. iterLayerNode++;
  4996. iterLayerNode++;
  4997. vRightVerticalBorder = (iterLayerNode.value())->getVertex();
  4998. //Calculate y coord for Lower border for gGraph
  4999. iYCoordinate = iYCoordPrevLayer + iHalfHeight + 40;
  5000. //assign y coord to Lower border vertex and neighbor vertical border nodes
  5001. m_BoostGraphWrapper.setVertexCenterCoordY(vLowerBorder , *m_gMainGraph , iYCoordinate);
  5002. m_BoostGraphWrapper.setVertexCenterCoordY(vLeftVerticalBorder , *m_gMainGraph , iYCoordinate);
  5003. m_BoostGraphWrapper.setVertexCenterCoordY(vRightVerticalBorder , *m_gMainGraph , iYCoordinate);
  5004. mapLayerIdToHalfHeight[iBorderLayerRank] = 0;
  5005. mapLayerIdToYCoord[iBorderLayerRank] = iYCoordinate;
  5006. }
  5007. }
  5008. catch(boost::exception &eBoostException)
  5009. {
  5010. throw *boost::get_error_info<errmsg_info>(eBoostException);
  5011. }
  5012. catch(LayoutException &eLayoutException)
  5013. {
  5014. throw eLayoutException;
  5015. }
  5016. // XXX obselete
  5017. // catch(LayoutMemoryException &eMemoryException)
  5018. // {
  5019. // throw eMemoryException;
  5020. // }
  5021. catch(...)
  5022. {
  5023. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  5024. }
  5025. }
  5026. void HierarchicalLayouter::setSubgraphCompartmentProperties()
  5027. {
  5028. //Get coordinates of left and right - uppermost and lower most vertical border vertices of current
  5029. //subgraph using its NestingTreeNode - we get four vertical border nodes
  5030. //Find out min X and min Y as the LeftTop coordinate of compartment
  5031. //Find out height and width using the dx and dy of four border vertices coordinates
  5032. try
  5033. {
  5034. int iMinX = INT_MAX;
  5035. int iMaxX = INT_MIN;
  5036. int iMinY = INT_MAX;
  5037. int iMaxY = INT_MIN;
  5038. int iX = 0;
  5039. int iY = 0;
  5040. int iHeight = 0;
  5041. int iWidth = 0;
  5042. int iCountBorderVertex = 0;
  5043. // XXX unused iCountBorderVertex
  5044. Q_UNUSED(iCountBorderVertex);
  5045. int iUpperBorderLayerId = 0;
  5046. int iLowerBorderLayerId = 0;
  5047. int iBorderLayerId = 0;
  5048. // //Array to store four coordinates, first subscript denotes - the point And
  5049. // //second subscript denotes XCoordinate at index '0' and YCoordinate at index '1'
  5050. // int iBorderVertexCoordinate[4][2];
  5051. NestingTreeSubgraphNode* currentNestingTreeNode = NULL;
  5052. //Traverse ALL nesting tree subgraph nodes
  5053. QueueNestingTreeSubgraphNodesRef qNestingTreeNode;
  5054. //Add root nesting tree node into queue
  5055. qNestingTreeNode.enqueue(&m_rootNestingTreeSubgraphNode);
  5056. LayoutEnum::NodeType enVertexType;
  5057. VertexDescriptor vVertex = 0;
  5058. QQueue<int> qBorderLayerIds;
  5059. while(qNestingTreeNode.isEmpty() == false)
  5060. {
  5061. currentNestingTreeNode = qNestingTreeNode.dequeue();
  5062. SubGraph& gSubgraph = currentNestingTreeNode->getGraph();
  5063. //Add child nesting tree nodes to queue
  5064. NestingTreeSubgraphNode::IteratorVectorNestingTreeSubgraphNodesRef iterChildNestingTreeNode
  5065. = currentNestingTreeNode->getIteratorChildNestingTreeSubgraphNodes() ;
  5066. while(iterChildNestingTreeNode.hasNext())
  5067. {
  5068. qNestingTreeNode.enqueue(iterChildNestingTreeNode.next());
  5069. }
  5070. NestingTreeSubgraphNode::MultiMapLayerIdToLayerNodeRef& mapOwnLayerNodes
  5071. = currentNestingTreeNode->getMapLayerIdToLayerNodeRef();
  5072. //Get upper border layer id
  5073. iUpperBorderLayerId = currentNestingTreeNode->getMinRank();
  5074. iLowerBorderLayerId = currentNestingTreeNode->getMaxRank();
  5075. //Enque
  5076. qBorderLayerIds.enqueue(iUpperBorderLayerId);
  5077. qBorderLayerIds.enqueue(iLowerBorderLayerId);
  5078. //Reset variables
  5079. iCountBorderVertex = 0;
  5080. iMinX = INT_MAX;
  5081. iMaxX = INT_MIN;
  5082. iMinY = INT_MAX;
  5083. iMaxY = INT_MIN;
  5084. while(qBorderLayerIds.isEmpty() == false)
  5085. {
  5086. iBorderLayerId = qBorderLayerIds.dequeue();
  5087. //Get LayerNodes residing at Border Layer Id
  5088. QList<LayerNode*> listLayerNodes = mapOwnLayerNodes.values(iBorderLayerId);
  5089. QListIterator<LayerNode*> iterListLayerNode(listLayerNodes);
  5090. while(iterListLayerNode.hasNext())
  5091. {
  5092. //Get vertex from LayerNode
  5093. vVertex = (iterListLayerNode.next())->getVertex();
  5094. enVertexType = m_BoostGraphWrapper.getVertexType(vVertex , *m_gMainGraph);
  5095. //Check for Vertical Border Vertex
  5096. if(enVertexType == LayoutEnum::VerticalBorderNode)
  5097. {
  5098. iX = m_BoostGraphWrapper.getVertexCenterCoordX(vVertex , *m_gMainGraph);
  5099. iY = m_BoostGraphWrapper.getVertexCenterCoordY(vVertex , *m_gMainGraph);
  5100. // //Add coordinates to array
  5101. // iBorderVertexCoordinate[iCountBorderVertex][0] = iX;
  5102. // iBorderVertexCoordinate[iCountBorderVertex][1] = iY;
  5103. //Update min and max X, Y
  5104. iMinX = (iMinX > iX) ? iX : iMinX;
  5105. iMaxX = (iMaxX < iX) ? iX : iMaxX;
  5106. iMinY = (iMinY > iY) ? iY : iMinY;
  5107. iMaxY = (iMaxY < iY) ? iY : iMaxY;
  5108. }
  5109. }//Iterating border layerNodes end
  5110. //Calculate Height and Width of compartment-subgraph
  5111. iWidth = std::abs(iMinX - iMaxX);
  5112. iHeight= std::abs(iMinY - iMaxY);
  5113. //The iMinX and iMinY are the left top coordinate of compartment
  5114. //set Lefttop coordinate to the Graph
  5115. m_BoostGraphWrapper.setGraphLeftTopCoordX(iMinX , gSubgraph);
  5116. m_BoostGraphWrapper.setGraphLeftTopCoordY(iMinY , gSubgraph);
  5117. //set height - width
  5118. m_BoostGraphWrapper.setGraphHeight(iHeight , gSubgraph);
  5119. m_BoostGraphWrapper.setGraphWidth(iWidth , gSubgraph);
  5120. }
  5121. }
  5122. }
  5123. catch(boost::exception &eBoostException)
  5124. {
  5125. throw *boost::get_error_info<errmsg_info>(eBoostException);
  5126. }
  5127. catch(...)
  5128. {
  5129. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  5130. }
  5131. }
  5132. void HierarchicalLayouter::applyXCoordinatesFromHorizontalPosition(int iHorizontalStep)
  5133. {
  5134. int iPos = 0;
  5135. BGL_FORALL_VERTICES(vVertex , *m_gMainGraph , SubGraph)
  5136. {
  5137. iPos = m_BoostGraphWrapper.getVertexHorizontalPosition(vVertex , *m_gMainGraph);
  5138. m_BoostGraphWrapper.setVertexCenterCoordX(vVertex , *m_gMainGraph , iHorizontalStep * iPos);
  5139. }
  5140. }
  5141. void HierarchicalLayouter::setHorizontalPosition2()
  5142. {
  5143. try
  5144. {
  5145. int iTotalVertices = 0;
  5146. iTotalVertices = num_vertices(*m_gMainGraph);
  5147. int iTotalEdges = 0;
  5148. iTotalEdges = num_edges(*m_gMainGraph);
  5149. // XXX unused
  5150. Q_UNUSED(iTotalEdges);
  5151. //Set m_iReductionParameterHorizontal value as smallest width vertex
  5152. PGL_MAP_VERTEX_BUNDLED_PROPERTY(mapVertexWidth , int , iWidth , *m_gMainGraph);
  5153. int iMinVertexWidth = INT_MIN;
  5154. BGL_FORALL_VERTICES(vVertex , *m_gMainGraph , SubGraph)
  5155. {
  5156. if(m_BoostGraphWrapper.getVertexType(vVertex , *m_gMainGraph)== LayoutEnum::GraphNode)
  5157. {
  5158. if(iMinVertexWidth > mapVertexWidth[vVertex])
  5159. {
  5160. iMinVertexWidth = mapVertexWidth[vVertex];
  5161. }
  5162. }
  5163. }
  5164. if(iMinVertexWidth < 1)
  5165. {
  5166. //TODO::set to some default value later
  5167. iMinVertexWidth = 30;
  5168. }
  5169. else
  5170. {
  5171. iMinVertexWidth /= 2;
  5172. }
  5173. m_iReductionParameterHorizontal = iMinVertexWidth;
  5174. bool bLayeredGraphCorrect = testLayeredGraph();
  5175. // XXX unused
  5176. Q_UNUSED(bLayeredGraphCorrect);
  5177. LAYOUT_ASSERT(bLayeredGraphCorrect == true , LayoutException(__FUNCTION__
  5178. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  5179. , "Layered Graph"
  5180. , "incorrect layered graph"));
  5181. /*Create position vector:
  5182. *This vector contains information about "Is Left Of" relationship
  5183. *It tells which vertex is positioned immediete left to the current vertex on same layer
  5184. */
  5185. QVectorInt vecLeftNeighborVertex(iTotalVertices);
  5186. QVectorInt vecRightNeighborVertex(iTotalVertices);
  5187. //Mark conflicted edges
  5188. markConflictedEdges();
  5189. //Vertical alignments
  5190. //1. Upward Left Alignment
  5191. //Initialise Left Neighbor Vertex vector, to be used for Horizontal Compaction
  5192. initLeftNeighborVertexVector(vecLeftNeighborVertex);
  5193. QVectorInt vecLeftAlignRoot(iTotalVertices);
  5194. QVectorInt vecLeftAlign(iTotalVertices);
  5195. //Create upward left alignment
  5196. createUpwardLeftAlignment(vecLeftAlignRoot , vecLeftAlign);
  5197. QVectorDouble vecUpwardLeftPosition(iTotalVertices);
  5198. ////qDebug() <<"Upward Left Alignment Horizontal Compaction";
  5199. horizontalCompaction2(vecUpwardLeftPosition , vecLeftAlign , vecLeftAlignRoot , vecLeftNeighborVertex );
  5200. //2.Upward Right alignment
  5201. //Reverse layered graph horizontally
  5202. reverseLayeredGraphHorizontaly();
  5203. /*Initialise Right Neighbor Vertex vector, here we get
  5204. *right neighbors because we have flipped the layered
  5205. *graph horizontally
  5206. */
  5207. initLeftNeighborVertexVector(vecRightNeighborVertex);
  5208. QVectorInt vecRightAlignRoot(iTotalVertices);
  5209. QVectorInt vecRightAlign(iTotalVertices);
  5210. createUpwardLeftAlignment(vecRightAlignRoot , vecRightAlign);
  5211. //createUpwardRightAlignment(vecRightAlignRoot , vecRightAlign);
  5212. QVectorDouble vecUpwardRightPosition(iTotalVertices);
  5213. ////qDebug() <<"Upward Right Alignment Horizontal Compaction";
  5214. horizontalCompaction2(vecUpwardRightPosition , vecRightAlign ,vecRightAlignRoot , vecRightNeighborVertex );
  5215. //Flip vertex positions
  5216. for(int i = 0; i < iTotalVertices ; i++)
  5217. {
  5218. vecUpwardRightPosition[i] *= -1;
  5219. }
  5220. //3. Downward Right Alignment
  5221. //Reverse layered graph vertically
  5222. reverseLayeredGraphVertically();
  5223. QVectorInt vecDownRightAlignRoot(iTotalVertices);
  5224. QVectorInt vecDownRightAlign(iTotalVertices);
  5225. createDownwardLeftAlignment(vecDownRightAlignRoot , vecDownRightAlign);
  5226. ////qDebug() <<"Downward Right Alignment Horizontal Compaction";
  5227. QVectorDouble vecDownRightPositions(iTotalVertices);
  5228. horizontalCompaction2(vecDownRightPositions , vecDownRightAlign ,
  5229. vecDownRightAlignRoot , vecRightNeighborVertex);
  5230. //Flip vertex positions
  5231. for(int i = 0; i < iTotalVertices ; i++)
  5232. {
  5233. vecDownRightPositions[i] *= -1;
  5234. }
  5235. //4. Downward Left Alignment
  5236. //Reverse layered graph horizontally
  5237. reverseLayeredGraphHorizontaly();
  5238. QVectorInt vecDownLeftAlignRoot(iTotalVertices);
  5239. QVectorInt vecDownLeftAlign(iTotalVertices);
  5240. createDownwardLeftAlignment(vecDownLeftAlignRoot , vecDownLeftAlign);
  5241. ////qDebug() <<"Downward Left Alignment Horizontal Compaction";
  5242. QVectorDouble vecDownLeftPositions(iTotalVertices);
  5243. horizontalCompaction2(vecDownLeftPositions , vecDownLeftAlign ,
  5244. vecDownLeftAlignRoot , vecLeftNeighborVertex);
  5245. //Restore layered graph
  5246. reverseLayeredGraphVertically();
  5247. //align to assignment of smallest width
  5248. alignToSmallestAlignment(vecUpwardLeftPosition , vecUpwardRightPosition ,
  5249. vecDownLeftPositions , vecDownRightPositions);
  5250. //set horizontal position to average median aligned coordinates.
  5251. QVectorDouble vecMergedPosition = mergeAlignments(vecUpwardLeftPosition , vecUpwardRightPosition ,
  5252. vecDownLeftPositions , vecDownRightPositions);
  5253. ////qDebug()<<"Setting Horizontal Coord X:";
  5254. //Writing arrangement
  5255. BGL_FORALL_VERTICES(vVertex , *m_gMainGraph , SubGraph)
  5256. {
  5257. int iXCoord = (vecMergedPosition[vVertex] * m_iReductionParameterHorizontal );
  5258. m_BoostGraphWrapper.setVertexCenterCoordX(vVertex , *m_gMainGraph , iXCoord);
  5259. ////qDebug() << "v: "<<(int)vVertex<<" x: "<<iXCoord;
  5260. }
  5261. }
  5262. catch(boost::exception &eBoostException)
  5263. {
  5264. throw *boost::get_error_info<errmsg_info>(eBoostException);
  5265. }
  5266. catch(LayoutException &eLayoutException)
  5267. {
  5268. throw eLayoutException;
  5269. }
  5270. // XXX obselete
  5271. // catch(LayoutMemoryException &eMemoryException)
  5272. // {
  5273. // throw eMemoryException;
  5274. // }
  5275. catch(...)
  5276. {
  5277. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  5278. }
  5279. }
  5280. void HierarchicalLayouter::alignToSmallestAlignment(QVectorDouble &vecUpLeftAlign, QVectorDouble &vecUpRightAlign, QVectorDouble &vecDownLeftAlign, QVectorDouble &vecDownRightAlign)
  5281. {
  5282. int iTotalVertices = 0;
  5283. try
  5284. {
  5285. iTotalVertices = num_vertices(*m_gMainGraph);
  5286. }
  5287. catch(boost::exception &eBoostException)
  5288. {
  5289. throw *boost::get_error_info<errmsg_info>(eBoostException);
  5290. }
  5291. LAYOUT_ASSERT(vecUpLeftAlign.size() == iTotalVertices
  5292. ,LayoutException(__FUNCTION__
  5293. , LayoutExceptionEnum::INVALID_PARAMETER
  5294. , "Vector UpLeftAlign must have size = total numebr of vertices"
  5295. ,"Vector UpLeftAlign"));
  5296. LAYOUT_ASSERT(vecUpRightAlign.size() == iTotalVertices
  5297. ,LayoutException(__FUNCTION__
  5298. , LayoutExceptionEnum::INVALID_PARAMETER
  5299. , "Vector UpRightAlign must have size = total numebr of vertices"
  5300. ,"Vector UpRightAlign"));
  5301. LAYOUT_ASSERT(vecDownLeftAlign.size() == iTotalVertices
  5302. ,LayoutException(__FUNCTION__
  5303. , LayoutExceptionEnum::INVALID_PARAMETER
  5304. , "Vector DownLeftAlign must have size = total numebr of vertices"
  5305. ,"Vector DownLeftAlign"));
  5306. LAYOUT_ASSERT(vecDownRightAlign.size() == iTotalVertices
  5307. ,LayoutException(__FUNCTION__
  5308. , LayoutExceptionEnum::INVALID_PARAMETER
  5309. , "Vector DownRightAlign must have size = total numebr of vertices"
  5310. ,"Vector DownRightAlign"));
  5311. try
  5312. {
  5313. //Pointer to smallest width alilgnment vector
  5314. QVectorDouble *vecSmallestAlignment = NULL;
  5315. //Store all 4 alignments in a vector
  5316. QVector<QVectorDouble*> vecAlignments;
  5317. //Store min max positions of all 4 alignments in a vector
  5318. QVector<QPair<double,double> > vecMinMaxPos(4);
  5319. //Push left alignments first
  5320. vecAlignments.push_back(&vecUpLeftAlign);
  5321. vecAlignments.push_back(&vecDownLeftAlign);
  5322. //Push right alignments after left alignments
  5323. vecAlignments.push_back(&vecUpRightAlign);
  5324. vecAlignments.push_back(&vecDownRightAlign);
  5325. double iMinPosition = 0;
  5326. double iMaxPosition = 0;
  5327. double iCurrentAlignmentWidth = INT_MAX;
  5328. double iSmallestAlignmentWidth = INT_MAX;
  5329. double iMinSmallestAlign = 0;
  5330. double iMaxSmallestAlign = 0;
  5331. //Select the smallest width alignment
  5332. for(int iAlignment = 0; iAlignment < vecAlignments.size() ; iAlignment++)
  5333. {
  5334. //Get min max positions of current alignment
  5335. getMinMaxPositions(iMinPosition , iMaxPosition , *(vecAlignments[iAlignment]));
  5336. //store min max positions in vector
  5337. vecMinMaxPos[iAlignment].first = iMinPosition;
  5338. vecMinMaxPos[iAlignment].second = iMaxPosition;
  5339. //Calculate width of current alignment
  5340. iCurrentAlignmentWidth = iMaxPosition - iMinPosition;
  5341. //Update smallest alignment
  5342. if(iSmallestAlignmentWidth > iCurrentAlignmentWidth)
  5343. {
  5344. iMinSmallestAlign = iMinPosition;
  5345. iMaxSmallestAlign = iMaxPosition;
  5346. vecSmallestAlignment = vecAlignments[iAlignment];
  5347. }
  5348. }
  5349. double iMinPosLeftAlignment = 0;
  5350. double iMaxPosRightAlignment = 0;
  5351. /*Align alignments with the smallest width alignment
  5352. *Align the left alignment min position to match min position with
  5353. *min position of smallest alignment and
  5354. *Align right alignment to match max position with max position of
  5355. *smallest alignment
  5356. */
  5357. double iShift = 0;
  5358. for(int iAlignment = 0; iAlignment < vecAlignments.size() ; iAlignment++)
  5359. {
  5360. //Skip smallest alignment as it is aligned to itself!
  5361. if(vecAlignments[iAlignment] == vecSmallestAlignment)
  5362. {
  5363. continue;
  5364. }
  5365. //First two alignments are left and third - fourth are right as per the sequence
  5366. if(iAlignment < 2)
  5367. {
  5368. //Left Alignment
  5369. //Align left alignement min
  5370. iMinPosLeftAlignment = vecMinMaxPos[iAlignment].first;
  5371. //Shift current left alignment to match min position with min position of smallest alignment
  5372. iShift = iMinSmallestAlign - iMinPosLeftAlignment;
  5373. }
  5374. else
  5375. {
  5376. //Right Alignment
  5377. //Align right alignment max
  5378. iMaxPosRightAlignment = vecMinMaxPos[iAlignment].second;
  5379. //Shift current right alignment to match max position with max position of smallest alignment
  5380. iShift = iMaxSmallestAlign - iMaxPosRightAlignment;
  5381. }
  5382. for(int iVertex = 0; iVertex < iTotalVertices ; iVertex++ )
  5383. {
  5384. //Shift each vertex of the current alignment according to iShift
  5385. (*(vecAlignments[iAlignment]))[iVertex] += iShift;
  5386. }
  5387. }
  5388. }
  5389. catch(boost::exception &eBoostException)
  5390. {
  5391. throw *boost::get_error_info<errmsg_info>(eBoostException);
  5392. }
  5393. catch(LayoutException &eLayoutException)
  5394. {
  5395. throw eLayoutException;
  5396. }
  5397. // XXX obselete
  5398. // catch(LayoutMemoryException &eMemoryException)
  5399. // {
  5400. // throw eMemoryException;
  5401. // }
  5402. catch(...)
  5403. {
  5404. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  5405. }
  5406. }
  5407. HierarchicalLayouter::QVectorDouble HierarchicalLayouter::mergeAlignments(HierarchicalLayouter::QVectorDouble &vecUpLeftAlign, HierarchicalLayouter::QVectorDouble &vecUpRightAlign, HierarchicalLayouter::QVectorDouble &vecDownLeftAlign, HierarchicalLayouter::QVectorDouble &vecDownRightAlign)
  5408. {
  5409. int iNumVertices = 0;
  5410. try
  5411. {
  5412. iNumVertices = num_vertices(*m_gMainGraph);
  5413. }
  5414. catch(boost::exception &eBoostException)
  5415. {
  5416. throw *boost::get_error_info<errmsg_info>(eBoostException);
  5417. }
  5418. LAYOUT_ASSERT(vecUpLeftAlign.size() == iNumVertices
  5419. ,LayoutException(__FUNCTION__
  5420. , LayoutExceptionEnum::INVALID_PARAMETER
  5421. , "Vector UpLeftAlign must have size = total numebr of vertices"
  5422. ,"Vector UpLeftAlign"));
  5423. LAYOUT_ASSERT(vecUpRightAlign.size() == iNumVertices
  5424. ,LayoutException(__FUNCTION__
  5425. , LayoutExceptionEnum::INVALID_PARAMETER
  5426. , "Vector UpRightAlign must have size = total numebr of vertices"
  5427. ,"Vector UpRightAlign"));
  5428. LAYOUT_ASSERT(vecDownLeftAlign.size() == iNumVertices
  5429. ,LayoutException(__FUNCTION__
  5430. , LayoutExceptionEnum::INVALID_PARAMETER
  5431. , "Vector DownLeftAlign must have size = total numebr of vertices"
  5432. ,"Vector DownLeftAlign"));
  5433. LAYOUT_ASSERT(vecDownRightAlign.size() == iNumVertices
  5434. ,LayoutException(__FUNCTION__
  5435. , LayoutExceptionEnum::INVALID_PARAMETER
  5436. , "Vector DownRightAlign must have size = total numebr of vertices"
  5437. ,"Vector DownRightAlign"));
  5438. //Pointer to smallest width alilgnment vector
  5439. QVectorDouble vecMergedAlignment(iNumVertices);
  5440. try
  5441. {
  5442. //Size = 4 for 4 alignments
  5443. QVectorDouble vecPositions(4);
  5444. BGL_FORALL_VERTICES(vVertex , *m_gMainGraph , SubGraph)
  5445. {
  5446. //get all four positions
  5447. vecPositions[0] = vecUpLeftAlign[vVertex];
  5448. vecPositions[1] = vecUpRightAlign[vVertex];
  5449. vecPositions[2] = vecDownLeftAlign[vVertex];
  5450. vecPositions[3] = vecDownRightAlign[vVertex];
  5451. qSort(vecPositions.begin() , vecPositions.end() , qLess<double>());
  5452. //Mean of median i.e. 1 and 2
  5453. vecMergedAlignment[vVertex] = (double)(vecPositions[1] + vecPositions[2])/2.0;
  5454. }
  5455. }
  5456. catch(boost::exception &eBoostException)
  5457. {
  5458. throw *boost::get_error_info<errmsg_info>(eBoostException);
  5459. }
  5460. catch(LayoutException &eLayoutException)
  5461. {
  5462. throw eLayoutException;
  5463. }
  5464. // XXX obselete
  5465. // catch(LayoutMemoryException &eMemoryException)
  5466. // {
  5467. // throw eMemoryException;
  5468. // }
  5469. catch(...)
  5470. {
  5471. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  5472. }
  5473. return vecMergedAlignment;
  5474. }
  5475. void HierarchicalLayouter::getMinMaxPositions(double &iMinPosition, double &iMaxPosition, QVectorDouble &vecPositions)
  5476. {
  5477. int iNumVertices = 0;
  5478. iNumVertices = num_vertices(*m_gMainGraph);
  5479. Q_ASSERT_X(vecPositions.size() == iNumVertices , "GetMinMaxPositions" , "Invalid length of vecPositions");
  5480. iMinPosition = INT_MAX;
  5481. iMaxPosition = INT_MIN;
  5482. for(int iVertex = 0 ; iVertex < iNumVertices ; iVertex++)
  5483. {
  5484. if(iMinPosition > vecPositions[iVertex])
  5485. {
  5486. iMinPosition = vecPositions[iVertex];
  5487. }
  5488. if(iMaxPosition < vecPositions[iVertex])
  5489. {
  5490. iMaxPosition = vecPositions[iVertex];
  5491. }
  5492. }
  5493. }
  5494. void HierarchicalLayouter::initLeftNeighborVertexVector(QVectorInt &vecLeftNeighborVertex)
  5495. {
  5496. try
  5497. {
  5498. int iNumVertices = 0;
  5499. iNumVertices = num_vertices(*m_gMainGraph);
  5500. // XXX unused
  5501. Q_UNUSED(iNumVertices);
  5502. LAYOUT_ASSERT(vecLeftNeighborVertex.size() == iNumVertices
  5503. ,LayoutException(__FUNCTION__
  5504. , LayoutExceptionEnum::INVALID_PARAMETER
  5505. , "Vector vecLeftNeighborVertex must have size = total number of vertices"
  5506. ,"LeftNeighborVertexVector"));
  5507. ////qDebug() << "Initialising Left Neighbors Vector";
  5508. VertexDescriptor vCurrentVertex = 0;
  5509. VertexDescriptor vLeftNeighbor = 0;
  5510. bool bFirstNodeOfLayer = false;
  5511. //Iterate layered graph
  5512. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  5513. while(iterLayer.hasNext())
  5514. {
  5515. iterLayer.next();
  5516. bFirstNodeOfLayer = true;
  5517. //Iterate layerNodes
  5518. IteratorMapPositionToLayerNode iterNode(*(iterLayer.value()));
  5519. while(iterNode.hasNext())
  5520. {
  5521. iterNode.next();
  5522. vCurrentVertex = iterNode.value()->getVertex();
  5523. if(bFirstNodeOfLayer == true)
  5524. {
  5525. vLeftNeighbor = vCurrentVertex;
  5526. bFirstNodeOfLayer = false;
  5527. }
  5528. //Add left neighbor
  5529. vecLeftNeighborVertex[vCurrentVertex] = vLeftNeighbor;
  5530. vLeftNeighbor = vCurrentVertex;
  5531. }
  5532. }
  5533. //For testing
  5534. // for(int iter = 0;iter < vecLeftNeighborVertex.size() ; iter++)
  5535. // {
  5536. // ////qDebug() << "V: " <<iter << " <- " << vecLeftNeighborVertex[iter];
  5537. // }
  5538. }
  5539. catch(boost::exception &eBoostException)
  5540. {
  5541. throw *boost::get_error_info<errmsg_info>(eBoostException);
  5542. }
  5543. catch(LayoutException &eLayoutException)
  5544. {
  5545. throw eLayoutException;
  5546. }
  5547. // XXX obselete
  5548. // catch(LayoutMemoryException &eMemoryException)
  5549. // {
  5550. // throw eMemoryException;
  5551. // }
  5552. catch(...)
  5553. {
  5554. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  5555. }
  5556. }
  5557. void HierarchicalLayouter::markConflictedEdges()
  5558. {
  5559. try
  5560. {
  5561. //reset bIsConflicted value for all edges
  5562. BGL_FORALL_EDGES(eEdge , *m_gMainGraph , SubGraph)
  5563. {
  5564. m_BoostGraphWrapper.setEdgeIsConflicted(eEdge ,*m_gMainGraph , false);
  5565. }
  5566. //Iterate layer from 1 to second last
  5567. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  5568. double dUpperPosLongEdge = 0;
  5569. double dUpperPosGraphEdge = 0;
  5570. double dUpperPosBorderEdge = 0;
  5571. double dLowerPosLongEdge = 0;
  5572. double dLowerPosGraphEdge = 0;
  5573. double dLowerPosBorderEdge = 0;
  5574. bool bEdgeConflict = false;
  5575. QVector<EdgeDescriptor> *vecLongEdgeOrVerticalBorderSegment = NULL;
  5576. QVector<EdgeDescriptor> *vecGraphEdge = NULL;
  5577. QVector<EdgeDescriptor> *vecVerticalBorderSegment = NULL;
  5578. QVector<EdgeDescriptor>* vecLongEdgeSegment = NULL;
  5579. VertexDescriptor vCurrentVertex;
  5580. LayerNode* currentNode;
  5581. int iSourceLayerId = 0;
  5582. int iTargetLayerId = 0;
  5583. VertexDescriptor vSource = 0;
  5584. VertexDescriptor vTarget = 0;
  5585. VertexDescriptor vGraphEdgeSource;
  5586. VertexDescriptor vGraphEdgeTarget;
  5587. VertexDescriptor vLongEdgeSource;
  5588. VertexDescriptor vLongEdgeTarget;
  5589. VertexDescriptor vBorderEdgeSource;
  5590. VertexDescriptor vBorderEdgeTarget;
  5591. EdgeDescriptor eGraphEdge;
  5592. EdgeDescriptor eLongEdge;
  5593. EdgeDescriptor eBorderEdge;
  5594. EdgeDescriptor eBorderOrLongEdge;
  5595. int iSizeLongEdgeSegments;
  5596. int iSizeBorderOrLongEdges;
  5597. int iSizeGraphEdges;
  5598. int iSizeVerticalEdgeSegments;
  5599. PGL_MAP_VERTEX_BUNDLED_PROPERTY(mapVertexHorizontalPos , int , iHorizontalPosition , *m_gMainGraph);
  5600. while(iterLayer.hasNext())
  5601. {
  5602. iterLayer.next();
  5603. //Check if current layer is not last
  5604. if(iterLayer.hasNext())
  5605. {
  5606. //Create new vectors to hold graph edges and long edge or Vertical Border segments separately
  5607. vecLongEdgeOrVerticalBorderSegment = new QVector<EdgeDescriptor>();
  5608. vecGraphEdge = new QVector<EdgeDescriptor>();
  5609. vecVerticalBorderSegment = new QVector<EdgeDescriptor>;
  5610. vecLongEdgeSegment = new QVector<EdgeDescriptor>;
  5611. //Iterate edges from current layer nodes and fill the vectors
  5612. IteratorMapPositionToLayerNode iterNode(*iterLayer.value());
  5613. while(iterNode.hasNext())
  5614. {
  5615. iterNode.next();
  5616. currentNode = iterNode.value();
  5617. vCurrentVertex = currentNode->getVertex();
  5618. //Iterate edges of current vertex
  5619. OutEdgeIterator iterEdge , iterEdgeEnd;
  5620. for(boost::tie(iterEdge , iterEdgeEnd) = out_edges(vCurrentVertex , *m_gMainGraph); iterEdge != iterEdgeEnd; iterEdge++)
  5621. {
  5622. EdgeDescriptor eCurrentEdge = *iterEdge;
  5623. //Testing 42214-3 Skip edges with atleast one vertex on non GraphNodeLayerId
  5624. vSource = m_BoostGraphWrapper.getEdgeSource(eCurrentEdge , *m_gMainGraph);
  5625. vTarget = m_BoostGraphWrapper.getEdgeTarget(eCurrentEdge , *m_gMainGraph);
  5626. iSourceLayerId = m_BoostGraphWrapper.getVertexRank(vSource , *m_gMainGraph);
  5627. iTargetLayerId = m_BoostGraphWrapper.getVertexRank(vTarget , *m_gMainGraph);
  5628. if(iSourceLayerId % m_iRankDifferenceInLayers != 0 ||
  5629. iTargetLayerId % m_iRankDifferenceInLayers != 0)
  5630. {
  5631. //Either vSource or vTarget vertex is at Layer which is not a GraphNodeLayer
  5632. //This edge will create falls conflict - crossing, so we skip it
  5633. //Skipping
  5634. continue;
  5635. }
  5636. //end 42214-3
  5637. LayoutEnum::EdgeType currentEdgeType = m_BoostGraphWrapper.getEdgeType(eCurrentEdge , *m_gMainGraph);
  5638. if(currentEdgeType == LayoutEnum::LongEdgeSegment)
  5639. {
  5640. //Record in long edge segments
  5641. vecLongEdgeSegment->push_back(eCurrentEdge);
  5642. //Record in long edge and vertical border segments
  5643. vecLongEdgeOrVerticalBorderSegment->push_back(eCurrentEdge);
  5644. }
  5645. if(currentEdgeType == LayoutEnum::VerticalBorderEdgeSegment)
  5646. {
  5647. //Record in vertical border edge
  5648. vecVerticalBorderSegment->push_back(eCurrentEdge);
  5649. //Record in long edge and vertical border segments
  5650. vecLongEdgeOrVerticalBorderSegment->push_back(eCurrentEdge);
  5651. }
  5652. if(currentEdgeType == LayoutEnum::GraphEdge)
  5653. {
  5654. //Record in graph edges vector
  5655. vecGraphEdge->push_back(eCurrentEdge);
  5656. }
  5657. }
  5658. }
  5659. //Find crossings between LongEdgeSegments + VerticalBorderSegments and GraphEdges
  5660. iSizeBorderOrLongEdges = vecLongEdgeOrVerticalBorderSegment->size();
  5661. iSizeGraphEdges = vecGraphEdge->size();
  5662. for(int iBorderOrLongEdgeIndex = 0; iBorderOrLongEdgeIndex < iSizeBorderOrLongEdges; iBorderOrLongEdgeIndex++)
  5663. {
  5664. eBorderOrLongEdge = (*vecLongEdgeOrVerticalBorderSegment)[iBorderOrLongEdgeIndex];
  5665. vLongEdgeSource = m_BoostGraphWrapper.getEdgeSource(eBorderOrLongEdge , *m_gMainGraph);
  5666. vLongEdgeTarget = m_BoostGraphWrapper.getEdgeTarget(eBorderOrLongEdge , *m_gMainGraph);
  5667. dUpperPosLongEdge = mapVertexHorizontalPos[vLongEdgeSource];
  5668. dLowerPosLongEdge = mapVertexHorizontalPos[vLongEdgeTarget];
  5669. for(int iGraphEdgeIndex = 0 ; iGraphEdgeIndex < iSizeGraphEdges ; iGraphEdgeIndex++)
  5670. {
  5671. eGraphEdge = (*vecGraphEdge)[iGraphEdgeIndex];
  5672. vGraphEdgeSource = m_BoostGraphWrapper.getEdgeSource(eGraphEdge , *m_gMainGraph);
  5673. vGraphEdgeTarget = m_BoostGraphWrapper.getEdgeTarget(eGraphEdge , *m_gMainGraph);
  5674. dUpperPosGraphEdge = mapVertexHorizontalPos[vGraphEdgeSource];
  5675. dLowerPosGraphEdge = mapVertexHorizontalPos[vGraphEdgeTarget];
  5676. //Reset for new edges
  5677. bEdgeConflict = false;
  5678. //Check crossing
  5679. if(dUpperPosLongEdge < dUpperPosGraphEdge)
  5680. {
  5681. if(dLowerPosLongEdge > dLowerPosGraphEdge)
  5682. {
  5683. bEdgeConflict = true;
  5684. }
  5685. }
  5686. else if(dUpperPosLongEdge > dUpperPosGraphEdge)
  5687. {
  5688. if(dLowerPosLongEdge < dLowerPosGraphEdge)
  5689. {
  5690. bEdgeConflict = true;
  5691. }
  5692. }
  5693. if(bEdgeConflict == true)
  5694. {
  5695. //Mark GraphEdge as conflicted
  5696. m_BoostGraphWrapper.setEdgeIsConflicted(eGraphEdge , *m_gMainGraph , bEdgeConflict);
  5697. }
  5698. }
  5699. }
  5700. //Find crossings between LongEdgeSegments and VerticalBorderSegments
  5701. iSizeLongEdgeSegments = vecLongEdgeSegment->size();
  5702. iSizeVerticalEdgeSegments = vecVerticalBorderSegment->size();
  5703. for(int iLongEdgeIndex = 0; iLongEdgeIndex < iSizeLongEdgeSegments; iLongEdgeIndex++)
  5704. {
  5705. eLongEdge = (*vecLongEdgeSegment)[iLongEdgeIndex];
  5706. vLongEdgeSource = m_BoostGraphWrapper.getEdgeSource(eLongEdge , *m_gMainGraph);
  5707. vLongEdgeTarget = m_BoostGraphWrapper.getEdgeTarget(eLongEdge , *m_gMainGraph);
  5708. dUpperPosLongEdge = mapVertexHorizontalPos[vLongEdgeSource];
  5709. dLowerPosLongEdge = mapVertexHorizontalPos[vLongEdgeTarget];
  5710. for(int iBorderEdgeIndex = 0 ; iBorderEdgeIndex < iSizeVerticalEdgeSegments ; iBorderEdgeIndex++)
  5711. {
  5712. eBorderEdge = (*vecVerticalBorderSegment)[iBorderEdgeIndex];
  5713. vBorderEdgeSource = m_BoostGraphWrapper.getEdgeSource(eBorderEdge , *m_gMainGraph);
  5714. vBorderEdgeTarget = m_BoostGraphWrapper.getEdgeTarget(eBorderEdge , *m_gMainGraph);
  5715. dUpperPosBorderEdge = mapVertexHorizontalPos[vBorderEdgeSource];
  5716. dLowerPosBorderEdge = mapVertexHorizontalPos[vBorderEdgeTarget];
  5717. //Reset for new edges
  5718. bEdgeConflict = false;
  5719. //Check crossing
  5720. if(dUpperPosLongEdge < dUpperPosBorderEdge)
  5721. {
  5722. if(dLowerPosLongEdge > dLowerPosBorderEdge)
  5723. {
  5724. bEdgeConflict = true;
  5725. }
  5726. }
  5727. else if(dUpperPosLongEdge > dUpperPosBorderEdge)
  5728. {
  5729. if(dLowerPosLongEdge < dLowerPosBorderEdge)
  5730. {
  5731. bEdgeConflict = true;
  5732. }
  5733. }
  5734. if(bEdgeConflict == true)
  5735. {
  5736. //Mark LongEdge as conflicted
  5737. m_BoostGraphWrapper.setEdgeIsConflicted(eLongEdge , *m_gMainGraph , bEdgeConflict);
  5738. }
  5739. }
  5740. }
  5741. //Clean up vectors holding graph edges, long edge and vertical border segments
  5742. vecLongEdgeOrVerticalBorderSegment->clear();
  5743. DELETE_AND_SET_NULL(vecLongEdgeOrVerticalBorderSegment);
  5744. vecGraphEdge->clear();
  5745. DELETE_AND_SET_NULL(vecGraphEdge);
  5746. vecLongEdgeSegment->clear();
  5747. DELETE_AND_SET_NULL(vecLongEdgeSegment);
  5748. vecVerticalBorderSegment->clear();
  5749. DELETE_AND_SET_NULL(vecVerticalBorderSegment);
  5750. }
  5751. }
  5752. }
  5753. catch(boost::exception &eBoostException)
  5754. {
  5755. throw *boost::get_error_info<errmsg_info>(eBoostException);
  5756. }
  5757. catch(LayoutException &eLayoutException)
  5758. {
  5759. throw eLayoutException;
  5760. }
  5761. // XXX obselete
  5762. // catch(LayoutMemoryException &eMemoryException)
  5763. // {
  5764. // throw eMemoryException;
  5765. // }
  5766. catch(...)
  5767. {
  5768. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  5769. }
  5770. }
  5771. QVectorInt HierarchicalLayouter::createUpwardLeftAlignment(QVectorInt &vecUpLeftAlignRoot , QVectorInt &vecUpLeftAlign)
  5772. {
  5773. try
  5774. {
  5775. int iNumVertices = 0;
  5776. iNumVertices = num_vertices(*m_gMainGraph);
  5777. LAYOUT_ASSERT(vecUpLeftAlignRoot.size() == iNumVertices
  5778. ,LayoutException(__FUNCTION__
  5779. , LayoutExceptionEnum::INVALID_PARAMETER
  5780. , "Vector LeftAlignRoot must have size = total numebr of vertices"
  5781. ,"Vector LeftAlignRoot"));
  5782. LAYOUT_ASSERT(vecUpLeftAlign.size() == iNumVertices
  5783. ,LayoutException(__FUNCTION__
  5784. , LayoutExceptionEnum::INVALID_PARAMETER
  5785. , "Vector LeftAlign must have size = total numebr of vertices"
  5786. ,"Vector LeftAlign"));
  5787. for(int iVertexId = 0; iVertexId < iNumVertices ; iVertexId++)
  5788. {
  5789. //Initialise root[v] to v
  5790. vecUpLeftAlignRoot[iVertexId] = iVertexId;
  5791. //Initialise align[v] to v
  5792. vecUpLeftAlign[iVertexId] = iVertexId;
  5793. }
  5794. int iHorizontalPos = 0;
  5795. VertexDescriptor vUpperMedianVertex = 0;
  5796. //Iterate all layers
  5797. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  5798. while(iterLayer.hasNext())
  5799. {
  5800. iterLayer.next();
  5801. MapPositionToLayerNode *currentLayer = iterLayer.value();
  5802. //Reset iAlignedPosition
  5803. int iAlignedPosition = INT_MIN;
  5804. //Iterate LayerNodes
  5805. IteratorMapPositionToLayerNode iterNode(*currentLayer);
  5806. while(iterNode.hasNext())
  5807. {
  5808. iterNode.next();
  5809. LayerNode *currentLayerNode = iterNode.value();
  5810. VertexDescriptor vCurrentVertex = currentLayerNode->getVertex();
  5811. //if current node has upper neighbors : d and d > 0
  5812. int iTotalUpperNeighbors = 0;
  5813. iTotalUpperNeighbors = in_degree(vCurrentVertex , *m_gMainGraph);
  5814. if(iTotalUpperNeighbors > 0)
  5815. {
  5816. //Iterate Median Upper Vertices
  5817. MapPositionToVertexDescriptor mapPosToUpperMedianVertex = getMedianUpperNeighborsExcludeConflictedEdges(vCurrentVertex);
  5818. IteratorMapPositionToVertexDescriptor iterUpperNeighbor(mapPosToUpperMedianVertex);
  5819. //Iterating left to right sorted on (horizontal) position
  5820. while(iterUpperNeighbor.hasNext())
  5821. {
  5822. iterUpperNeighbor.next();
  5823. iHorizontalPos = iterUpperNeighbor.key();
  5824. vUpperMedianVertex = iterUpperNeighbor.value();
  5825. //if align[v] = v
  5826. if(vecUpLeftAlign[vCurrentVertex] == (int)vCurrentVertex)
  5827. {
  5828. //r < position[upperNeighbor]
  5829. if(iAlignedPosition < iHorizontalPos)
  5830. {
  5831. vecUpLeftAlign[vUpperMedianVertex] = vCurrentVertex;
  5832. vecUpLeftAlignRoot[vCurrentVertex] = vecUpLeftAlignRoot[vUpperMedianVertex];
  5833. vecUpLeftAlign[vCurrentVertex] = vecUpLeftAlignRoot[vCurrentVertex];
  5834. //Update iAlignedPosition
  5835. iAlignedPosition = iHorizontalPos;
  5836. }
  5837. }
  5838. }
  5839. }
  5840. }
  5841. }
  5842. int iTotalVertices = 0;
  5843. iTotalVertices = num_vertices(*m_gMainGraph);
  5844. //Align Vertical Border nodes strictly
  5845. QVector<bool> vecVisitedVerticalBorderVertex(iTotalVertices);
  5846. std::fill(vecVisitedVerticalBorderVertex.begin() , vecVisitedVerticalBorderVertex.end() , false);
  5847. LayoutEnum::NodeType enVertexType;
  5848. VertexDescriptor vRootVerticalBorderVertex = 0;
  5849. VertexDescriptor vCurrentVerticalBorderVertex = 0;
  5850. BGL_FORALL_VERTICES(vVertex , *m_gMainGraph , SubGraph)
  5851. {
  5852. enVertexType = m_BoostGraphWrapper.getVertexType(vVertex , *m_gMainGraph);
  5853. if(enVertexType == LayoutEnum::VerticalBorderNode)
  5854. {
  5855. //check if VerticalBorderVertex is visited / aligned already
  5856. if(vecVisitedVerticalBorderVertex[vVertex] == true)
  5857. {
  5858. //skipping visited-aligned vertex
  5859. continue;
  5860. }
  5861. vCurrentVerticalBorderVertex = vVertex;
  5862. //Find the root VerticalBorderVertex - it is the reachable vertex which has in_degree = 0
  5863. while(in_degree(vCurrentVerticalBorderVertex , *m_gMainGraph) != 0)
  5864. {
  5865. //Mark Vertical border vertex visited
  5866. vecVisitedVerticalBorderVertex[vCurrentVerticalBorderVertex] = true;
  5867. //Every VerticalBorderVertex must have at max 1 in edge
  5868. LAYOUT_ASSERT(in_degree(vCurrentVerticalBorderVertex , *m_gMainGraph) == 1
  5869. ,LayoutException(__FUNCTION__
  5870. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  5871. , "every VerticalBorderVertex must have at max 1 in edge"
  5872. , "Vertical Border Vertex Trail"));
  5873. BGL_FORALL_INEDGES(vCurrentVerticalBorderVertex , eInEdge , *m_gMainGraph , SubGraph)
  5874. {
  5875. VertexDescriptor vInVertex = m_BoostGraphWrapper.getEdgeSource(eInEdge , *m_gMainGraph);
  5876. vCurrentVerticalBorderVertex = vInVertex;
  5877. }
  5878. }
  5879. //vCurrentVerticalBorderVertex contains root vertex
  5880. vRootVerticalBorderVertex = vCurrentVerticalBorderVertex;
  5881. //Traverse from root vertex till bottom vertex and align every vertical border vertex
  5882. //with its predecessor and last vertex with root
  5883. while(out_degree(vCurrentVerticalBorderVertex , *m_gMainGraph) != 0)
  5884. {
  5885. //Every VerticalBorderVertex must have at max 1 out edge
  5886. LAYOUT_ASSERT(out_degree(vCurrentVerticalBorderVertex , *m_gMainGraph) == 1
  5887. ,LayoutException(__FUNCTION__
  5888. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  5889. , "every VerticalBorderVertex must have at max 1 out edge"
  5890. , "Vertical Border Vertex Trail"));
  5891. BGL_FORALL_ADJ(vCurrentVerticalBorderVertex , vNextVertex , *m_gMainGraph , SubGraph)
  5892. {
  5893. //Align current vertex with next vertex
  5894. vecUpLeftAlign[vCurrentVerticalBorderVertex] = vNextVertex;
  5895. //Set root
  5896. vecUpLeftAlignRoot[vCurrentVerticalBorderVertex] = vRootVerticalBorderVertex;
  5897. //update current vertex
  5898. vCurrentVerticalBorderVertex = vNextVertex;
  5899. }
  5900. }
  5901. //vCurrentVerticalBorderVertex contains the last/bottom vertex so align it with the root vertex
  5902. vecUpLeftAlign[vCurrentVerticalBorderVertex] = vRootVerticalBorderVertex;
  5903. //Set root
  5904. vecUpLeftAlignRoot[vCurrentVerticalBorderVertex] = vRootVerticalBorderVertex;
  5905. }
  5906. }
  5907. ////qDebug() << "UpwardLeft Alignment";
  5908. QVectorInt::iterator it = vecUpLeftAlign.begin();
  5909. for(int i = 0;it != vecUpLeftAlign.end() ; it++ , i++)
  5910. {
  5911. ////qDebug() << i <<" " <<*it;
  5912. }
  5913. }
  5914. catch(boost::exception &eBoostException)
  5915. {
  5916. throw *boost::get_error_info<errmsg_info>(eBoostException);
  5917. }
  5918. catch(LayoutException &eLayoutException)
  5919. {
  5920. throw eLayoutException;
  5921. }
  5922. // XXX obselete
  5923. // catch(LayoutMemoryException &eMemoryException)
  5924. // {
  5925. // throw eMemoryException;
  5926. // }
  5927. catch(...)
  5928. {
  5929. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  5930. }
  5931. return vecUpLeftAlign;
  5932. }
  5933. QVectorInt HierarchicalLayouter::createDownwardLeftAlignment(QVectorInt &vecDownLeftAlignRoot, QVectorInt &vecDownLeftAlign)
  5934. {
  5935. try
  5936. {
  5937. int iNumVertices = 0;
  5938. iNumVertices = num_vertices(*m_gMainGraph);
  5939. //Assert layered graph is reversed
  5940. LAYOUT_ASSERT((m_mapLayeredGraph.begin().key() <= 0)
  5941. ,LayoutException(__FUNCTION__
  5942. , LayoutExceptionEnum::INVALID_OPERATION
  5943. , "Layered graph is not reversed"
  5944. , "Create Downward Left Vertical Alignment"));
  5945. LAYOUT_ASSERT(vecDownLeftAlign.size() == iNumVertices
  5946. ,LayoutException(__FUNCTION__
  5947. , LayoutExceptionEnum::INVALID_PARAMETER
  5948. , "Vector DownLeftAlign must have size = total numebr of vertices"
  5949. ,"Vector DownLeftAlign"));
  5950. LAYOUT_ASSERT(vecDownLeftAlignRoot.size() == iNumVertices
  5951. ,LayoutException(__FUNCTION__
  5952. , LayoutExceptionEnum::INVALID_PARAMETER
  5953. , "Vector DownLeftAlignRoot must have size = total numebr of vertices"
  5954. ,"Vector DownLeftAlignRoot"));
  5955. for(int iVertexId = 0; iVertexId < iNumVertices ; iVertexId++)
  5956. {
  5957. //Initialise root[v] to v
  5958. vecDownLeftAlignRoot[iVertexId] = iVertexId;
  5959. //Initialise align[v] to v
  5960. vecDownLeftAlign[iVertexId] = iVertexId;
  5961. }
  5962. int iHorizontalPos = 0;
  5963. VertexDescriptor vLowerMedianVertex = 0;
  5964. //Iterate all layers
  5965. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  5966. //Reverse iter
  5967. //iterLayer.toBack(); // testing
  5968. while(iterLayer.hasNext())
  5969. {
  5970. iterLayer.next();
  5971. MapPositionToLayerNode *currentLayer = iterLayer.value();
  5972. //Reset iAlignedPosition
  5973. int iAlignedPosition = INT_MIN;
  5974. //Iterate LayerNodes
  5975. IteratorMapPositionToLayerNode iterNode(*currentLayer);
  5976. while(iterNode.hasNext())
  5977. {
  5978. iterNode.next();
  5979. LayerNode *currentLayerNode = iterNode.value();
  5980. VertexDescriptor vCurrentVertex = currentLayerNode->getVertex();
  5981. //if current node has upper neighbors : d and d > 0
  5982. int iTotalDownNeighbors = 0;
  5983. iTotalDownNeighbors = out_degree(vCurrentVertex , *m_gMainGraph);
  5984. if(iTotalDownNeighbors > 0)
  5985. {
  5986. //Iterate Median Downper Vertices
  5987. MapPositionToVertexDescriptor mapPosToLowerMedianVertex = getMedianLowerNeighborsExcludeConflictedEdges(vCurrentVertex);
  5988. IteratorMapPositionToVertexDescriptor iterLowerNeighbor(mapPosToLowerMedianVertex);
  5989. //Iterating left to right sorted on (horizontal) position
  5990. while(iterLowerNeighbor.hasNext())
  5991. {
  5992. iterLowerNeighbor.next();
  5993. iHorizontalPos = iterLowerNeighbor.key();
  5994. vLowerMedianVertex = iterLowerNeighbor.value();
  5995. //if align[v] = v
  5996. if(vecDownLeftAlign[vCurrentVertex] == (int)vCurrentVertex)
  5997. {
  5998. //r < position[DownperNeighbor]
  5999. if(iAlignedPosition < iHorizontalPos)
  6000. {
  6001. vecDownLeftAlign[vLowerMedianVertex] = vCurrentVertex;
  6002. vecDownLeftAlignRoot[vCurrentVertex] = vecDownLeftAlignRoot[vLowerMedianVertex];
  6003. vecDownLeftAlign[vCurrentVertex] = vecDownLeftAlignRoot[vCurrentVertex];
  6004. //Update iAlignedPosition
  6005. iAlignedPosition = iHorizontalPos;
  6006. }
  6007. }
  6008. }
  6009. }
  6010. }
  6011. }
  6012. ////qDebug() << "DownwardLeft Alignment";
  6013. QVectorInt::iterator it = vecDownLeftAlign.begin();
  6014. for(int i = 0;it != vecDownLeftAlign.end() ; it++ , i++)
  6015. {
  6016. ////qDebug() << i <<" " <<*it;
  6017. }
  6018. int iTotalVertices = 0;
  6019. iTotalVertices = num_vertices(*m_gMainGraph);
  6020. //Align Vertical Border nodes strictly
  6021. QVector<bool> vecVisitedVerticalBorderVertex(iTotalVertices);
  6022. std::fill(vecVisitedVerticalBorderVertex.begin() , vecVisitedVerticalBorderVertex.end() , false);
  6023. LayoutEnum::NodeType enVertexType;
  6024. VertexDescriptor vRootVerticalBorderVertex = 0;
  6025. VertexDescriptor vCurrentVerticalBorderVertex = 0;
  6026. BGL_FORALL_VERTICES(vVertex , *m_gMainGraph , SubGraph)
  6027. {
  6028. enVertexType = m_BoostGraphWrapper.getVertexType(vVertex , *m_gMainGraph);
  6029. if(enVertexType == LayoutEnum::VerticalBorderNode)
  6030. {
  6031. //check if VerticalBorderVertex is visited / aligned already
  6032. if(vecVisitedVerticalBorderVertex[vVertex] == true)
  6033. {
  6034. //skipping visited-aligned vertex
  6035. continue;
  6036. }
  6037. vCurrentVerticalBorderVertex = vVertex;
  6038. //Find the root VerticalBorderVertex - it is the reachable vertex which has in_degree = 0
  6039. while(in_degree(vCurrentVerticalBorderVertex , *m_gMainGraph) != 0)
  6040. {
  6041. //Mark Vertical border vertex visited
  6042. vecVisitedVerticalBorderVertex[vCurrentVerticalBorderVertex] = true;
  6043. //Every VerticalBorderVertex must have at max 1 in edge
  6044. LAYOUT_ASSERT(in_degree(vCurrentVerticalBorderVertex , *m_gMainGraph) == 1
  6045. ,LayoutException(__FUNCTION__
  6046. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  6047. , "every VerticalBorderVertex must have at max 1 in edge"
  6048. , "Vertical Border Vertex Trail"));
  6049. BGL_FORALL_INEDGES(vCurrentVerticalBorderVertex , eInEdge , *m_gMainGraph , SubGraph)
  6050. {
  6051. VertexDescriptor vInVertex = m_BoostGraphWrapper.getEdgeSource(eInEdge , *m_gMainGraph);
  6052. vCurrentVerticalBorderVertex = vInVertex;
  6053. }
  6054. }
  6055. //vCurrentVerticalBorderVertex contains root vertex
  6056. vRootVerticalBorderVertex = vCurrentVerticalBorderVertex;
  6057. //Traverse from root vertex till bottom vertex and align every vertical border vertex
  6058. //with its predecessor and last vertex with root
  6059. while(out_degree(vCurrentVerticalBorderVertex , *m_gMainGraph) != 0)
  6060. {
  6061. //Every VerticalBorderVertex must have at max 1 out edge
  6062. LAYOUT_ASSERT(out_degree(vCurrentVerticalBorderVertex , *m_gMainGraph) == 1
  6063. ,LayoutException(__FUNCTION__
  6064. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  6065. , "every VerticalBorderVertex must have at max 1 out edge"
  6066. , "Vertical Border Vertex Trail"));
  6067. BGL_FORALL_ADJ(vCurrentVerticalBorderVertex , vNextVertex , *m_gMainGraph , SubGraph)
  6068. {
  6069. //Align current vertex with next vertex
  6070. vecDownLeftAlign[vCurrentVerticalBorderVertex] = vNextVertex;
  6071. //Set Root
  6072. vecDownLeftAlignRoot[vCurrentVerticalBorderVertex] = vRootVerticalBorderVertex;
  6073. //update current vertex
  6074. vCurrentVerticalBorderVertex = vNextVertex;
  6075. }
  6076. }
  6077. //vCurrentVerticalBorderVertex contains the last/bottom vertex so align it with the root vertex
  6078. vecDownLeftAlign[vCurrentVerticalBorderVertex] = vRootVerticalBorderVertex;
  6079. //Set Root
  6080. vecDownLeftAlignRoot[vCurrentVerticalBorderVertex] = vRootVerticalBorderVertex;
  6081. }
  6082. }
  6083. }
  6084. catch(boost::exception &eBoostException)
  6085. {
  6086. throw *boost::get_error_info<errmsg_info>(eBoostException);
  6087. }
  6088. catch(LayoutException &eLayoutException)
  6089. {
  6090. throw eLayoutException;
  6091. }
  6092. // XXX obselete
  6093. // catch(LayoutMemoryException &eMemoryException)
  6094. // {
  6095. // throw eMemoryException;
  6096. // }
  6097. catch(...)
  6098. {
  6099. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  6100. }
  6101. return vecDownLeftAlign;
  6102. }
  6103. QVectorInt HierarchicalLayouter::createUpwardRightAlignment(QVectorInt &vecUpRightAlignRoot, QVectorInt &vecUpRightAlign)
  6104. {
  6105. int iNumVertices = 0;
  6106. iNumVertices = num_vertices(*m_gMainGraph);
  6107. Q_ASSERT_X(vecUpRightAlignRoot.size() == iNumVertices , "Create Upward Right Vertical Alignment" , "Vector LeftAlignRoot must have size = total numebr of vertices");
  6108. Q_ASSERT_X(vecUpRightAlign.size() == iNumVertices , "Create Upward Right Vertical Alignment" , "Vector LeftAlign must have size = total numebr of vertices");
  6109. for(int iVertexId = 0; iVertexId < iNumVertices ; iVertexId++)
  6110. {
  6111. //Initialise root[v] to v
  6112. vecUpRightAlignRoot[iVertexId] = iVertexId;
  6113. //Initialise align[v] to v
  6114. vecUpRightAlign[iVertexId] = iVertexId;
  6115. }
  6116. int iHorizontalPos = 0;
  6117. VertexDescriptor vUpperMedianVertex = 0;
  6118. //Iterate all layers
  6119. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  6120. while(iterLayer.hasNext())
  6121. {
  6122. iterLayer.next();
  6123. MapPositionToLayerNode *currentLayer = iterLayer.value();
  6124. //Iterate LayerNodes
  6125. IteratorMapPositionToLayerNode iterNode(*currentLayer);
  6126. iterNode.toBack();
  6127. //Reset iAlignedPosition
  6128. int iAlignedPosition = INT_MAX;
  6129. while(iterNode.hasPrevious())
  6130. {
  6131. iterNode.previous();
  6132. LayerNode *currentLayerNode = iterNode.value();
  6133. // XXX must be a int, but is a size_t
  6134. VertexDescriptor vCurrentVertex = (int) currentLayerNode->getVertex();
  6135. //if current node has upper neighbors : d and d > 0
  6136. int iTotalUpperNeighbors = 0;
  6137. iTotalUpperNeighbors = in_degree(vCurrentVertex , *m_gMainGraph);
  6138. if(iTotalUpperNeighbors > 0)
  6139. {
  6140. //Iterate Median Upper Vertices
  6141. MapPositionToVertexDescriptor mapPosToUpperMedianVertex = getMedianUpperNeighborsExcludeConflictedEdges(vCurrentVertex);
  6142. IteratorMapPositionToVertexDescriptor iterUpperNeighbor(mapPosToUpperMedianVertex);
  6143. iterUpperNeighbor.toBack();
  6144. //Iterating left to right sorted on (horizontal) position
  6145. while(iterUpperNeighbor.hasPrevious())
  6146. {
  6147. iterUpperNeighbor.previous();
  6148. iHorizontalPos = iterUpperNeighbor.key();
  6149. vUpperMedianVertex = iterUpperNeighbor.value();
  6150. //if align[v] = v
  6151. if(vecUpRightAlign[vCurrentVertex] == (int)vCurrentVertex)
  6152. {
  6153. //r < position[upperNeighbor]
  6154. if(iAlignedPosition > iHorizontalPos)
  6155. {
  6156. vecUpRightAlign[vUpperMedianVertex] = vCurrentVertex;
  6157. vecUpRightAlignRoot[vCurrentVertex] = vecUpRightAlignRoot[vUpperMedianVertex];
  6158. vecUpRightAlign[vCurrentVertex] = vecUpRightAlignRoot[vCurrentVertex];
  6159. //Update iAlignedPosition
  6160. iAlignedPosition = iHorizontalPos;
  6161. }
  6162. }
  6163. }
  6164. }
  6165. }
  6166. }
  6167. //Print for testig
  6168. // ////qDebug() << "Up Right Alignement:";
  6169. // int iSize = vecUpRightAlign.size();
  6170. // while(iSize--)
  6171. // {
  6172. // ////qDebug() <<iSize <<" -- "<<vecUpRightAlign[iSize];
  6173. // }
  6174. return vecUpRightAlign;
  6175. }
  6176. QVectorInt HierarchicalLayouter::createDownwardRightAlignment(QVectorInt &vecDownRightAlignRoot, QVectorInt &vecDownRightAlign)
  6177. {
  6178. int iNumVertices = 0;
  6179. iNumVertices = num_vertices(*m_gMainGraph);
  6180. Q_ASSERT_X(vecDownRightAlignRoot.size() == iNumVertices , "Create Downward Left Vertical Alignment" , "Vector DownRightAlignRoot must have size = total numebr of vertices");
  6181. Q_ASSERT_X(vecDownRightAlign.size() == iNumVertices , "Create Downward Left Vertical Alignment" , "Vector DownRightAlign must have size = total numebr of vertices");
  6182. for(int iVertexId = 0; iVertexId < iNumVertices ; iVertexId++)
  6183. {
  6184. //Initialise root[v] to v
  6185. vecDownRightAlignRoot[iVertexId] = iVertexId;
  6186. //Initialise align[v] to v
  6187. vecDownRightAlign[iVertexId] = iVertexId;
  6188. }
  6189. int iHorizontalPos = 0;
  6190. VertexDescriptor vLowerMedianVertex = 0;
  6191. //Iterate all layers
  6192. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  6193. //Reverse iter
  6194. iterLayer.toBack();
  6195. while(iterLayer.hasPrevious())
  6196. {
  6197. iterLayer.previous();
  6198. MapPositionToLayerNode *currentLayer = iterLayer.value();
  6199. //Iterate LayerNodes
  6200. IteratorMapPositionToLayerNode iterNode(*currentLayer);
  6201. iterNode.toBack();
  6202. //Reset iAlignedPosition
  6203. int iAlignedPosition = INT_MAX;
  6204. while(iterNode.hasPrevious())
  6205. {
  6206. iterNode.previous();
  6207. LayerNode *currentLayerNode = iterNode.value();
  6208. VertexDescriptor vCurrentVertex = currentLayerNode->getVertex();
  6209. //if current node has Lower neighbors : d and d > 0
  6210. int iTotalLowerNeighbors = 0;
  6211. iTotalLowerNeighbors = out_degree(vCurrentVertex , *m_gMainGraph);
  6212. if(iTotalLowerNeighbors > 0)
  6213. {
  6214. //Iterate Median Lower Vertices
  6215. MapPositionToVertexDescriptor mapPosToLowerMedianVertex = getMedianLowerNeighborsExcludeConflictedEdges(vCurrentVertex);
  6216. IteratorMapPositionToVertexDescriptor iterLowerNeighbor(mapPosToLowerMedianVertex);
  6217. iterLowerNeighbor.toBack();
  6218. //Iterating left to right sorted on (horizontal) position
  6219. while(iterLowerNeighbor.hasPrevious())
  6220. {
  6221. iterLowerNeighbor.previous();
  6222. iHorizontalPos = iterLowerNeighbor.key();
  6223. vLowerMedianVertex = iterLowerNeighbor.value();
  6224. //if align[v] = v
  6225. if(vecDownRightAlign[vCurrentVertex] == (int)vCurrentVertex)
  6226. {
  6227. //r > position[LowerNeighbor]
  6228. if(iAlignedPosition > iHorizontalPos)
  6229. {
  6230. vecDownRightAlign[vLowerMedianVertex] = vCurrentVertex;
  6231. vecDownRightAlignRoot[vCurrentVertex] = vecDownRightAlignRoot[vLowerMedianVertex];
  6232. vecDownRightAlign[vCurrentVertex] = vecDownRightAlignRoot[vCurrentVertex];
  6233. //Update iAlignedPosition
  6234. iAlignedPosition = iHorizontalPos;
  6235. }
  6236. }
  6237. }
  6238. }
  6239. }
  6240. }
  6241. //Print for testig
  6242. // ////qDebug() << "Down Right Alignement:";
  6243. // int iSize = vecDownRightAlign.size();
  6244. // while(iSize--)
  6245. // {
  6246. // ////qDebug() <<iSize <<" -- "<<vecDownRightAlign[iSize];
  6247. // }
  6248. return vecDownRightAlign;
  6249. }
  6250. MapPositionToVertexDescriptor HierarchicalLayouter::getMedianUpperNeighborsExcludeConflictedEdges(VertexDescriptor &vGlobalVertex)
  6251. {
  6252. MapPositionToVertexDescriptor mapPosToUpperVertex;
  6253. MapPositionToVertexDescriptor mapPosToUpperMedianVertex;;
  6254. VertexDescriptor vInVertex = 0;
  6255. int iHorizontalPos = 0;
  6256. int iInVerticesCounter = 0;
  6257. bool bIsEdgeConflicted = false;
  6258. //Iterate in edges to get upper level vertices
  6259. BGL_FORALL_INEDGES(vGlobalVertex , eInEdge , *m_gMainGraph , SubGraph)
  6260. {
  6261. //Exclude conflicted edges
  6262. bIsEdgeConflicted = m_BoostGraphWrapper.getEdgeIsConflicted(eInEdge , *m_gMainGraph);
  6263. if( bIsEdgeConflicted == true)
  6264. {
  6265. //Skipping conflicted edge
  6266. continue;
  6267. }
  6268. //Upper vertex
  6269. vInVertex = m_BoostGraphWrapper.getEdgeSource(eInEdge , *m_gMainGraph);
  6270. //Horizontal position of upper vertex
  6271. iHorizontalPos = m_BoostGraphWrapper.getVertexHorizontalPosition(vInVertex , *m_gMainGraph);
  6272. mapPosToUpperVertex.insert(iHorizontalPos , vInVertex);
  6273. iInVerticesCounter++;
  6274. }
  6275. double dMean = (iInVerticesCounter + 1 ) / 2.0;
  6276. int iMedianFloor = std::floor(dMean);
  6277. int iMedianCeil = std::ceil(dMean);
  6278. int iCounter = 0;
  6279. IteratorMapPositionToVertexDescriptor iterPosVertex(mapPosToUpperVertex);
  6280. while(iterPosVertex.hasNext())
  6281. {
  6282. iterPosVertex.next();
  6283. iHorizontalPos = iterPosVertex.key();
  6284. vInVertex = iterPosVertex.value();
  6285. iCounter++;
  6286. if(iCounter == iMedianFloor || iCounter == iMedianCeil)
  6287. {
  6288. //Add item to median upper map
  6289. mapPosToUpperMedianVertex.insert(iHorizontalPos , vInVertex);
  6290. }
  6291. if(iCounter == iMedianCeil)
  6292. {
  6293. //break after median ceil encountered to save unnecessary
  6294. //iterating till the end of mapPosToUpperVertex
  6295. break;
  6296. }
  6297. }
  6298. return mapPosToUpperMedianVertex;
  6299. }
  6300. MapPositionToVertexDescriptor HierarchicalLayouter::getMedianLowerNeighborsExcludeConflictedEdges(VertexDescriptor &vGlobalVertex)
  6301. {
  6302. MapPositionToVertexDescriptor mapPosToLowerVertex;
  6303. MapPositionToVertexDescriptor mapPosToLowerMedianVertex;;
  6304. VertexDescriptor vOutVertex = 0;
  6305. int iHorizontalPos = 0;
  6306. int iOutVerticesCounter = 0;
  6307. bool bIsEdgeConflicted = false;
  6308. //Iterate in edges to get Lower level vertices
  6309. BGL_FORALL_OUTEDGES(vGlobalVertex , eOutEdge , *m_gMainGraph , SubGraph)
  6310. {
  6311. //Exclude conflicted edges
  6312. bIsEdgeConflicted = m_BoostGraphWrapper.getEdgeIsConflicted(eOutEdge , *m_gMainGraph);
  6313. if( bIsEdgeConflicted == true)
  6314. {
  6315. //Skipping conflicted edge
  6316. continue;
  6317. }
  6318. //Lower vertex
  6319. vOutVertex = m_BoostGraphWrapper.getEdgeTarget(eOutEdge , *m_gMainGraph);
  6320. //Horizontal position of Lower vertex
  6321. iHorizontalPos = m_BoostGraphWrapper.getVertexHorizontalPosition(vOutVertex , *m_gMainGraph);
  6322. mapPosToLowerVertex.insert(iHorizontalPos , vOutVertex);
  6323. iOutVerticesCounter++;
  6324. }
  6325. double dMean = (iOutVerticesCounter + 1 ) / 2.0;
  6326. int iMedianFloor = std::floor(dMean);
  6327. int iMedianCeil = std::ceil(dMean);
  6328. int iCounter = 0;
  6329. IteratorMapPositionToVertexDescriptor iterPosVertex(mapPosToLowerVertex);
  6330. while(iterPosVertex.hasNext())
  6331. {
  6332. iterPosVertex.next();
  6333. iHorizontalPos = iterPosVertex.key();
  6334. vOutVertex = iterPosVertex.value();
  6335. iCounter++;
  6336. if(iCounter == iMedianFloor || iCounter == iMedianCeil)
  6337. {
  6338. //Add item to median Lower map
  6339. mapPosToLowerMedianVertex.insert(iHorizontalPos , vOutVertex);
  6340. }
  6341. if(iCounter == iMedianCeil)
  6342. {
  6343. //break after median ceil encountered to save unnecessary
  6344. //iterating till the end of mapPosToLowerVertex
  6345. break;
  6346. }
  6347. }
  6348. return mapPosToLowerMedianVertex;
  6349. }
  6350. void HierarchicalLayouter::horizontalCompaction2(QVectorDouble &vecPositions, const QVectorInt &vecAlignVertex, const QVectorInt &vecRootVertex, const QVectorInt vecLeftNeighborVertex )
  6351. {
  6352. try
  6353. {
  6354. int iNumVertices = 0;
  6355. iNumVertices = num_vertices(*m_gMainGraph);
  6356. LAYOUT_ASSERT(vecPositions.size() == iNumVertices
  6357. ,LayoutException(__FUNCTION__
  6358. , LayoutExceptionEnum::INVALID_PARAMETER
  6359. , "Vector Positions must have size = total numebr of vertices"
  6360. ,"Vector Positions"));
  6361. LAYOUT_ASSERT(vecAlignVertex.size() == iNumVertices
  6362. ,LayoutException(__FUNCTION__
  6363. , LayoutExceptionEnum::INVALID_PARAMETER
  6364. , "Vector AlignVertex must have size = total numebr of vertices"
  6365. ,"Vector AlignVertex"));
  6366. LAYOUT_ASSERT(vecAlignVertex.size() == iNumVertices
  6367. ,LayoutException(__FUNCTION__
  6368. , LayoutExceptionEnum::INVALID_PARAMETER
  6369. , "Vector RootVertex must have size = total numebr of vertices"
  6370. ,"Vector RootVertex"));
  6371. LAYOUT_ASSERT(vecAlignVertex.size() == iNumVertices
  6372. ,LayoutException(__FUNCTION__
  6373. , LayoutExceptionEnum::INVALID_PARAMETER
  6374. , "Vector LeftNeighborVertex must have size = total numebr of vertices"
  6375. ,"Vector LeftNeighborVertex"));
  6376. QVectorInt vecSink(iNumVertices);
  6377. QVectorDouble vecShift(iNumVertices);
  6378. VecMapShiftClass mapShiftClass(iNumVertices);
  6379. //initialise sink[v] = v
  6380. //initialise shift[v] = INFINITY
  6381. for(int iVertex = 0; iVertex < iNumVertices ; iVertex++)
  6382. {
  6383. vecSink[iVertex] = iVertex;
  6384. vecShift[iVertex] = INFINITY_INT;
  6385. vecPositions[iVertex] = UNDEFINED_POS;
  6386. }
  6387. //Root coordinate relative to sink
  6388. for(VertexDescriptor vVertex = 0; (int)vVertex < iNumVertices ; vVertex++)
  6389. {
  6390. //Root vertex
  6391. if(vecRootVertex[vVertex] == (int)vVertex)
  6392. {
  6393. //place_block
  6394. placeBlock2(0
  6395. , vVertex
  6396. , vecPositions
  6397. , vecShift
  6398. , vecSink
  6399. , vecAlignVertex
  6400. , vecRootVertex
  6401. , vecLeftNeighborVertex
  6402. , mapShiftClass);
  6403. }
  6404. }
  6405. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  6406. while(iterLayer.hasNext())
  6407. {
  6408. iterLayer.next();
  6409. IteratorMapPositionToLayerNode iterNode(*(iterLayer.value()));
  6410. while(iterNode.hasNext())
  6411. {
  6412. iterNode.next();
  6413. VertexDescriptor vVertex = 0;
  6414. vVertex = (iterNode.value())->getVertex();
  6415. //x[v] = x[root[v]]
  6416. vecPositions[vVertex] = vecPositions[vecRootVertex[vVertex]];
  6417. //if (v === root[v] && v === sink[v])
  6418. if(((int)vVertex == vecRootVertex[vVertex]) && ((int)vVertex == vecSink[vVertex]))
  6419. {
  6420. double dMinShift = INT_MAX;
  6421. if(mapShiftClass[vVertex].size() > 0)
  6422. {
  6423. //Calculate minShift value
  6424. //Sum up class shift value and vertex shift value
  6425. QMap<int , double>::iterator iterShiftClass = mapShiftClass[vVertex].begin();
  6426. while(iterShiftClass != mapShiftClass[vVertex].end())
  6427. {
  6428. double dSum = iterShiftClass.value();
  6429. double dVertexShift = 0;
  6430. VertexDescriptor vNeighborVertex = iterShiftClass.key();
  6431. if(vecShift[vNeighborVertex] != INFINITY_INT)
  6432. {
  6433. dVertexShift = vecShift[vNeighborVertex];
  6434. }
  6435. dSum += dVertexShift;
  6436. //Update min shift with minimum value
  6437. if(dMinShift > dSum)
  6438. {
  6439. dMinShift = dSum;
  6440. }
  6441. iterShiftClass++;
  6442. }
  6443. }
  6444. //shift[v] = minShift;
  6445. vecShift[vVertex] = dMinShift;
  6446. }
  6447. }
  6448. }
  6449. iterLayer.toFront();
  6450. while(iterLayer.hasNext())
  6451. {
  6452. iterLayer.next();
  6453. IteratorMapPositionToLayerNode iterNode(*(iterLayer.value()));
  6454. while(iterNode.hasNext())
  6455. {
  6456. iterNode.next();
  6457. VertexDescriptor vVertex = 0;
  6458. vVertex = (iterNode.value())->getVertex();
  6459. if(vecShift[vecSink[ vecRootVertex[vVertex]]] < INFINITY_INT)
  6460. {
  6461. vecPositions[vVertex] += vecShift[vecSink[vecRootVertex[vVertex]]];
  6462. }
  6463. }
  6464. }
  6465. //******************************************************
  6466. bool bHorizontalCompactionSuccess = testHorizontalCompaction(vecPositions);
  6467. // XXX unused
  6468. Q_UNUSED(bHorizontalCompactionSuccess);
  6469. LAYOUT_ASSERT(bHorizontalCompactionSuccess == true
  6470. ,LayoutException(__FUNCTION__
  6471. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  6472. , "horizontal compaction has shuffled the node positions"
  6473. ,"Node Positions"));
  6474. bool bIsConsistentPositionAlignment = testPositionWithAlignment(vecPositions , vecAlignVertex);
  6475. // XXX unused
  6476. Q_UNUSED(bIsConsistentPositionAlignment);
  6477. LAYOUT_ASSERT(bIsConsistentPositionAlignment == true
  6478. ,LayoutException(__FUNCTION__
  6479. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  6480. , "Inconsistent positions with alignment of nodes"
  6481. ,"Alignment"));
  6482. }
  6483. catch(boost::exception &eBoostException)
  6484. {
  6485. throw *boost::get_error_info<errmsg_info>(eBoostException);
  6486. }
  6487. catch(LayoutException &eLayoutException)
  6488. {
  6489. throw eLayoutException;
  6490. }
  6491. // XXX obselete
  6492. // catch(LayoutMemoryException &eMemoryException)
  6493. // {
  6494. // throw eMemoryException;
  6495. // }
  6496. catch(...)
  6497. {
  6498. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  6499. }
  6500. }
  6501. void HierarchicalLayouter::placeBlock2(int iLevel, VertexDescriptor vVertex, QVectorDouble &vecPositions, QVectorDouble &vecShift, QVectorInt &vecSink, const QVectorInt &vecAlignVertex, const QVectorInt &vecRootVertex, const QVectorInt &vecLeftNeighborVertex, VecMapShiftClass &mapShiftClass)
  6502. {
  6503. int iNumVertices = 0;
  6504. // XXX unused
  6505. Q_UNUSED(iNumVertices);
  6506. try
  6507. {
  6508. iNumVertices = num_vertices(*m_gMainGraph);
  6509. }
  6510. catch(boost::exception &eBoostException)
  6511. {
  6512. throw *boost::get_error_info<errmsg_info>(eBoostException);
  6513. }
  6514. LAYOUT_ASSERT(vecPositions.size() == iNumVertices
  6515. ,LayoutException(__FUNCTION__
  6516. , LayoutExceptionEnum::INVALID_PARAMETER
  6517. , "Vector Positions must have size = total numebr of vertices"
  6518. ,"Vector Positions"));
  6519. LAYOUT_ASSERT(vecShift.size() == iNumVertices
  6520. ,LayoutException(__FUNCTION__
  6521. , LayoutExceptionEnum::INVALID_PARAMETER
  6522. , "Vector Shift must have size = total numebr of vertices"
  6523. ,"Vector Shift"));
  6524. LAYOUT_ASSERT(vecSink.size() == iNumVertices
  6525. ,LayoutException(__FUNCTION__
  6526. , LayoutExceptionEnum::INVALID_PARAMETER
  6527. , "Vector Sink must have size = total numebr of vertices"
  6528. ,"Vector Sink"));
  6529. LAYOUT_ASSERT(vecAlignVertex.size() == iNumVertices
  6530. ,LayoutException(__FUNCTION__
  6531. , LayoutExceptionEnum::INVALID_PARAMETER
  6532. , "Vector AlignVertex must have size = total numebr of vertices"
  6533. ,"Vector AlignVertex"));
  6534. LAYOUT_ASSERT(vecRootVertex.size() == iNumVertices
  6535. ,LayoutException(__FUNCTION__
  6536. , LayoutExceptionEnum::INVALID_PARAMETER
  6537. , "Vector RootVertex must have size = total numebr of vertices"
  6538. ,"Vector RootVertex"));
  6539. LAYOUT_ASSERT(vecLeftNeighborVertex.size() == iNumVertices
  6540. ,LayoutException(__FUNCTION__
  6541. , LayoutExceptionEnum::INVALID_PARAMETER
  6542. , "Vector LeftNeighborVertex must have size = total numebr of vertices"
  6543. ,"Vector LeftNeighborVertex"));
  6544. try
  6545. {
  6546. PGL_MAP_VERTEX_BUNDLED_PROPERTY(mapVertexHorizontalPosition , int , iHorizontalPosition , *m_gMainGraph);
  6547. //----------------------------------------------
  6548. if(vecPositions[vVertex] == UNDEFINED_POS)
  6549. {
  6550. //////qDebug() << printIndent(iLevel)<< "place_block: " << vVertex ;
  6551. //////qDebug()<< printIndent(iLevel)<<"----------------------------------------------------\n";
  6552. vecPositions[vVertex] = 0; //x[v] = 0
  6553. size_t vNextVertex = vVertex; //w = v
  6554. do
  6555. {
  6556. //////qDebug()<< printIndent(iLevel)<<"w: "<<vNextVertex<<endl;
  6557. //Check if v is first vertex in layer
  6558. if(mapVertexHorizontalPosition[vNextVertex] > 1)
  6559. {
  6560. //u = root[pred[w]]
  6561. int vRootVertex = vecRootVertex[vecLeftNeighborVertex[vNextVertex]];
  6562. //////qDebug()<< printIndent(iLevel)<<"u: "<<vRootVertex<<endl << "calling place_block";
  6563. //place_block(u)
  6564. placeBlock2(iLevel+1 ,
  6565. vRootVertex ,
  6566. vecPositions ,
  6567. vecShift,
  6568. vecSink,
  6569. vecAlignVertex,
  6570. vecRootVertex,
  6571. vecLeftNeighborVertex,
  6572. mapShiftClass);
  6573. if(vecSink[vVertex] == (int) vVertex)
  6574. {
  6575. //////qDebug()<< printIndent(iLevel)<<"vecSink[v] == v"<<endl;
  6576. //////qDebug()<< printIndent(iLevel)<<"vecSink[v: "<<vVertex<<"] = "<<"vecSink[u: "<<vRootVertex<<"] = "<<vecSink[vRootVertex]<<endl;
  6577. //because u is left neighbor of v therefore sinks are same
  6578. vecSink[vVertex] = vecSink[vRootVertex];
  6579. }
  6580. double dDelta = (double)(separation(vecLeftNeighborVertex[vNextVertex]) +
  6581. separation(vNextVertex)) / (double)m_iReductionParameterHorizontal;
  6582. //Check if sinks are not same then:
  6583. if(vecSink[vVertex] != vecSink[vRootVertex])
  6584. {
  6585. //This means a left neighbor has different sink node hence
  6586. //it pulls the left neighbor class closer, to find out this shift value:
  6587. //the minimum value between original value i.e. vecShift[vecSink[u]]
  6588. //and (vecPositions[v] - vecPositions[u] - HORIZONTAL_UNIT_SPACE) is chosen
  6589. //updateShift(sink[u], sink[v], xs[v] - xs[u] - delta);
  6590. updateShift(vecSink[vRootVertex] , vecSink[vVertex] , vecPositions[vVertex] - vecPositions[vRootVertex] - dDelta , mapShiftClass);
  6591. }
  6592. else
  6593. {
  6594. //////qDebug()<< printIndent(iLevel)<<"vecPositions[v: "<<vVertex<<"] = ";
  6595. vecPositions[vVertex] = std::max(vecPositions[vVertex] , (vecPositions[vRootVertex] + dDelta));
  6596. }
  6597. }
  6598. vNextVertex = vecAlignVertex[vNextVertex];
  6599. }while(vNextVertex != vVertex);
  6600. //printIndent(iLevel);
  6601. //////qDebug()<<printIndent(iLevel)<<"---------------------------------close block\n";
  6602. }
  6603. }
  6604. catch(boost::exception &eBoostException)
  6605. {
  6606. throw *boost::get_error_info<errmsg_info>(eBoostException);
  6607. }
  6608. catch(LayoutException &eLayoutException)
  6609. {
  6610. throw eLayoutException;
  6611. }
  6612. // XXX obselete
  6613. // catch(LayoutMemoryException &eMemoryException)
  6614. // {
  6615. // throw eMemoryException;
  6616. // }
  6617. catch(...)
  6618. {
  6619. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  6620. }
  6621. }
  6622. void HierarchicalLayouter::updateShift(int iToShift, int iNeighbor, double dDelta , VecMapShiftClass &mapShiftClass)
  6623. {
  6624. if(mapShiftClass[iToShift].contains(iNeighbor))
  6625. {
  6626. mapShiftClass[iToShift][iNeighbor] = std::min(mapShiftClass[iToShift][iNeighbor] , dDelta);
  6627. }
  6628. else
  6629. {
  6630. mapShiftClass[iToShift][iNeighbor] = dDelta;
  6631. }
  6632. }
  6633. int HierarchicalLayouter::separation(VertexDescriptor vVertex)
  6634. {
  6635. // XXX is always true because unsigned expression
  6636. // Q_ASSERT_X(vVertex >= 0 , "Separation" , "invalid vertex");
  6637. int iSeparation = 0;
  6638. int iWidth = m_BoostGraphWrapper.getVertexWidth(vVertex , *m_gMainGraph);
  6639. //Half of the width of node
  6640. iSeparation += iWidth;
  6641. LayoutEnum::NodeType enVertexType = m_BoostGraphWrapper.getVertexType(vVertex , *m_gMainGraph);
  6642. //Add edge or node separation contant
  6643. if(enVertexType == LayoutEnum::DummyNode)
  6644. {
  6645. iSeparation += m_iEdgeSeparation;
  6646. }
  6647. else if(enVertexType == LayoutEnum::VerticalBorderNode)
  6648. {
  6649. iSeparation += m_iBorderMargin;
  6650. }
  6651. else
  6652. {
  6653. iSeparation += m_iNodeSeparation;
  6654. }
  6655. iSeparation /= 2;
  6656. return iSeparation;
  6657. }
  6658. // XXX #warning "crashes"
  6659. // XXX int?
  6660. int HierarchicalLayouter::shiftVertexCoordinateToLeftTop()
  6661. {
  6662. int iXCoordinate = 0;
  6663. int iYCoordinate = 0;
  6664. int iHeight = 0;
  6665. int iWidth = 0;
  6666. int minxx = 0;
  6667. int minyy = 0;
  6668. int maxxx = 0;
  6669. int maxyy = 0;
  6670. try
  6671. {
  6672. minxx = 10 * 1000 * 1000;
  6673. minyy = 10 * 1000 * 1000;
  6674. maxxx = 0;
  6675. maxyy = 0;
  6676. BGL_FORALL_VERTICES(vVertex , *m_gMainGraph , SubGraph)
  6677. {
  6678. LayoutEnum::NodeType enVertexType = m_BoostGraphWrapper.getVertexType(vVertex , *m_gMainGraph);
  6679. if(enVertexType != LayoutEnum::GraphNode)
  6680. {
  6681. //continue;
  6682. }
  6683. iXCoordinate = m_BoostGraphWrapper.getVertexCenterCoordX(vVertex , *m_gMainGraph);
  6684. iYCoordinate = m_BoostGraphWrapper.getVertexCenterCoordY(vVertex , *m_gMainGraph);
  6685. iHeight = m_BoostGraphWrapper.getVertexHeight(vVertex , *m_gMainGraph);
  6686. iWidth = m_BoostGraphWrapper.getVertexWidth(vVertex , *m_gMainGraph);
  6687. if(iHeight > 0 && iWidth > 0)
  6688. {
  6689. iXCoordinate -= (iWidth / 2);
  6690. iYCoordinate -= (iHeight / 2);
  6691. }
  6692. m_BoostGraphWrapper.setVertexLeftCoordX(vVertex , *m_gMainGraph , iXCoordinate);
  6693. m_BoostGraphWrapper.setVertexLeftCoordY(vVertex , *m_gMainGraph , iYCoordinate);
  6694. if (iXCoordinate < minxx) {
  6695. minxx = iXCoordinate;
  6696. }
  6697. if (iXCoordinate > maxxx) {
  6698. maxxx = iXCoordinate;
  6699. }
  6700. if (iYCoordinate < minyy) {
  6701. minyy = iYCoordinate;
  6702. }
  6703. if (iYCoordinate > maxyy) {
  6704. maxyy = iYCoordinate;
  6705. }
  6706. }
  6707. qDebug() << "shiftVertexCoordinateToLeftTop(): min(x,y) = (" << minxx << "," << minyy << ") max(x,y) = (" << maxxx << "," << maxyy << ")";
  6708. }
  6709. catch(boost::exception &eBoostException)
  6710. {
  6711. throw *boost::get_error_info<errmsg_info>(eBoostException);
  6712. }
  6713. catch(...)
  6714. {
  6715. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  6716. }
  6717. // XXX must return something
  6718. return 0;
  6719. }
  6720. QString HierarchicalLayouter::printIndent(int iLevel)
  6721. {
  6722. QString sIndent = "";
  6723. int iSpaces = 2;
  6724. for(int i = 0; i <= (iLevel * iSpaces) ;i++)
  6725. {
  6726. if(i % iSpaces == 0)
  6727. {
  6728. sIndent.append("|");
  6729. }
  6730. else
  6731. {
  6732. sIndent.append(" ");
  6733. }
  6734. }
  6735. return sIndent;
  6736. }
  6737. int HierarchicalLayouter::getFinalCrossings()
  6738. {
  6739. return m_iFinalCrossings;
  6740. }
  6741. //************************************************************************************************************
  6742. /*Testing Functions:
  6743. */
  6744. bool HierarchicalLayouter::testUpwardEdgesAndRanks(SubGraph &gGraph)
  6745. {
  6746. VertexDescriptor vSource , vTarget;
  6747. int iSourceRank , iTargetRank;
  6748. bool bUpwardEdgeFound = false;
  6749. int iUpwardEdges = 0;
  6750. BGL_FORALL_EDGES(eEdge , gGraph , SubGraph)
  6751. {
  6752. vSource = m_BoostGraphWrapper.getEdgeSource(eEdge , gGraph);
  6753. vTarget = m_BoostGraphWrapper.getEdgeTarget(eEdge , gGraph);
  6754. iSourceRank = m_BoostGraphWrapper.getVertexRank(vSource , gGraph);
  6755. iTargetRank = m_BoostGraphWrapper.getVertexRank(vTarget , gGraph);
  6756. if(iSourceRank > iTargetRank)
  6757. {
  6758. ++iUpwardEdges;
  6759. }
  6760. }
  6761. if(iUpwardEdges > 0)
  6762. {
  6763. bUpwardEdgeFound = true;
  6764. }
  6765. return bUpwardEdgeFound;
  6766. }
  6767. bool HierarchicalLayouter::testLayeredGraph()
  6768. {
  6769. ////qDebug() << "Testing Layered Graph:";
  6770. int bIsLayeredGraphCorrect = true;
  6771. //Check if all nodes are present in Layered Graph
  6772. std::size_t iTotalVertices = num_vertices(*m_gMainGraph);
  6773. std::vector<bool> vertexVisited(iTotalVertices);
  6774. std::fill(vertexVisited.begin() , vertexVisited.end() , false);
  6775. //Iterate Layers
  6776. IteratorMapLayerIdToLayerRef iterLayers(m_mapLayeredGraph);
  6777. int iTotalBadPositionNodeCount = 0;
  6778. while(iterLayers.hasNext())
  6779. {
  6780. iterLayers.next();
  6781. MapPositionToLayerNode * currentLayer = iterLayers.value();
  6782. ////qDebug() << "Layer Rank : " << QString::number(iterLayers.key());
  6783. //Test Layer: layer node keys and corresponding Vertex iHorizontalPosition are same
  6784. int iBadPositionNodeCount = testGetLayerKeysAndVertexPositionNotConsistentCount(*currentLayer , *m_gMainGraph);
  6785. iTotalBadPositionNodeCount += iBadPositionNodeCount;
  6786. }
  6787. ////qDebug() << "Total Inconsistent Nodes: " << QString::number(iTotalBadPositionNodeCount);
  6788. if(iTotalBadPositionNodeCount > 0)
  6789. {
  6790. bIsLayeredGraphCorrect = false;
  6791. }
  6792. return bIsLayeredGraphCorrect;
  6793. }
  6794. int HierarchicalLayouter::testGetLayerKeysAndVertexPositionNotConsistentCount(MapPositionToLayerNode &mapPositionToLayerNode, SubGraph &gMainGraph)
  6795. {
  6796. //////qDebug() << "Testing inconsistent LayerNode positions";
  6797. QString sInconsistentNodeList = "";
  6798. int iLayerKeysAndVertexPositionNotConsistentCount = 0;
  6799. IteratorMapPositionToLayerNode iterLayerNodes(mapPositionToLayerNode);
  6800. while(iterLayerNodes.hasNext())
  6801. {
  6802. iterLayerNodes.next();
  6803. //Copy Layer Node key and pointer
  6804. int icurrentLayerNodeKey = iterLayerNodes.key();
  6805. LayerNode *currentLayerNode = iterLayerNodes.value();
  6806. //Compare layer node key with Vertex horizontal position
  6807. VertexDescriptor vCurrentVertex = currentLayerNode->getVertex();
  6808. if(m_BoostGraphWrapper.getVertexHorizontalPosition( vCurrentVertex,
  6809. gMainGraph)
  6810. != icurrentLayerNodeKey)
  6811. {
  6812. iLayerKeysAndVertexPositionNotConsistentCount++;
  6813. sInconsistentNodeList.append(" -");
  6814. sInconsistentNodeList.append(QString::number(icurrentLayerNodeKey));
  6815. }
  6816. }
  6817. //////qDebug() << "Incosistent Node: " << sInconsistentNodeList;
  6818. //////qDebug() << "Testing inconsistent LayerNode positions END";
  6819. return iLayerKeysAndVertexPositionNotConsistentCount;
  6820. }
  6821. bool HierarchicalLayouter::testHorizontalCompaction(QVectorInt &vecAlignedPosition)
  6822. {
  6823. int iNumVertices = 0;
  6824. iNumVertices = num_vertices(*m_gMainGraph);
  6825. // XXX unused
  6826. Q_UNUSED(iNumVertices);
  6827. LAYOUT_ASSERT(vecAlignedPosition.size() == iNumVertices
  6828. ,LayoutException(__FUNCTION__
  6829. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  6830. , "vecAlignedPosition"
  6831. , "size mis matched with number of vertices"));
  6832. bool bHorizontalCompactionCorrect = true;
  6833. VertexDescriptor vCurrent = 0;
  6834. VertexDescriptor vNext = 0;
  6835. LayerNode* currentNode = NULL;
  6836. LayerNode* nextNode = NULL;
  6837. int iPosCurrentVertex = 0;
  6838. int iPosNextVertex = 0;
  6839. //Iterate nodes layer by layer
  6840. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  6841. while(iterLayer.hasNext())
  6842. {
  6843. iterLayer.next();
  6844. int iLayer = iterLayer.key();
  6845. // XXX unused
  6846. Q_UNUSED(iLayer);
  6847. ////qDebug() << "Layer: "<<iLayer;
  6848. IteratorMapPositionToLayerNode iterNode(*(iterLayer.value()));
  6849. while(iterNode.hasNext())
  6850. {
  6851. iterNode.next();
  6852. if(iterNode.hasNext())
  6853. {
  6854. LayoutEnum::NodeType nodeType = m_BoostGraphWrapper.getVertexType(vCurrent
  6855. , *m_gMainGraph);
  6856. if(nodeType == LayoutEnum::UpperBorderNode ||
  6857. nodeType == LayoutEnum::LowerBorderNode)
  6858. {
  6859. //skip border nodes
  6860. continue;
  6861. }
  6862. //get current node
  6863. currentNode = iterNode.value();
  6864. //get current vertex
  6865. vCurrent = currentNode->getVertex();
  6866. //get next node
  6867. nextNode = (iterNode.peekNext()).value();
  6868. //get next vertex
  6869. vNext = nextNode->getVertex();
  6870. //get horizontal positions from aligned position vector
  6871. iPosCurrentVertex = vecAlignedPosition[vCurrent];
  6872. iPosNextVertex = vecAlignedPosition[vNext];
  6873. // iPosCurrentVertex < iPosNextVertex must be true
  6874. if(iPosCurrentVertex == iPosNextVertex)
  6875. {
  6876. bHorizontalCompactionCorrect = false;
  6877. ////qDebug() << "Vertex position overlap, Pos: " << iPosCurrentVertex <<"Vertex: "<<vCurrent <<" , "<<vNext;
  6878. }
  6879. else if(iPosCurrentVertex > iPosNextVertex)
  6880. {
  6881. bHorizontalCompactionCorrect = false;
  6882. ////qDebug() << "Vertex position reversed, v- "<<vCurrent<<" , "<<vNext<<" , Pos: "<< iPosCurrentVertex << " , " << iPosNextVertex;
  6883. }
  6884. }
  6885. }
  6886. }
  6887. return bHorizontalCompactionCorrect;
  6888. }
  6889. bool HierarchicalLayouter::testHorizontalCompaction(QVectorDouble &vecAlignedPosition)
  6890. {
  6891. int iNumVertices = 0;
  6892. // XXX unused
  6893. Q_UNUSED(iNumVertices);
  6894. iNumVertices = num_vertices(*m_gMainGraph);
  6895. LAYOUT_ASSERT(vecAlignedPosition.size() == iNumVertices
  6896. ,LayoutException(__FUNCTION__
  6897. , LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE
  6898. , "vecAlignedPosition"
  6899. , "size mis matched with number of vertices"));
  6900. bool bHorizontalCompactionCorrect = true;
  6901. VertexDescriptor vCurrent = 0;
  6902. VertexDescriptor vNext = 0;
  6903. LayerNode* currentNode = NULL;
  6904. LayerNode* nextNode = NULL;
  6905. int iPosCurrentVertex = 0;
  6906. int iPosNextVertex = 0;
  6907. //Iterate nodes layer by layer
  6908. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  6909. while(iterLayer.hasNext())
  6910. {
  6911. iterLayer.next();
  6912. //int iLayer = iterLayer.key();
  6913. ////qDebug() << "Layer: "<<iLayer;
  6914. IteratorMapPositionToLayerNode iterNode(*(iterLayer.value()));
  6915. while(iterNode.hasNext())
  6916. {
  6917. iterNode.next();
  6918. if(iterNode.hasNext())
  6919. {
  6920. LayoutEnum::NodeType nodeType = m_BoostGraphWrapper.getVertexType(vCurrent
  6921. , *m_gMainGraph);
  6922. if(nodeType == LayoutEnum::UpperBorderNode ||
  6923. nodeType == LayoutEnum::LowerBorderNode)
  6924. {
  6925. //skip border nodes
  6926. continue;
  6927. }
  6928. //get current node
  6929. currentNode = iterNode.value();
  6930. //get current vertex
  6931. vCurrent = currentNode->getVertex();
  6932. //get next node
  6933. nextNode = (iterNode.peekNext()).value();
  6934. //get next vertex
  6935. vNext = nextNode->getVertex();
  6936. //get horizontal positions from aligned position vector
  6937. iPosCurrentVertex = vecAlignedPosition[vCurrent];
  6938. iPosNextVertex = vecAlignedPosition[vNext];
  6939. // iPosCurrentVertex < iPosNextVertex must be true
  6940. if(iPosCurrentVertex == iPosNextVertex)
  6941. {
  6942. //bHorizontalCompactionCorrect = false;
  6943. ////qDebug() << "Vertex position overlap, Pos: " << iPosCurrentVertex <<"Vertex: "<<vCurrent <<" , "<<vNext;
  6944. }
  6945. else if(iPosCurrentVertex > iPosNextVertex)
  6946. {
  6947. bHorizontalCompactionCorrect = false;
  6948. ////qDebug() << "Vertex position reversed, v- "<<vCurrent<<" , "<<vNext<<" , Pos: "<< iPosCurrentVertex << " , " << iPosNextVertex;
  6949. }
  6950. }
  6951. }
  6952. }
  6953. return bHorizontalCompactionCorrect;
  6954. }
  6955. bool HierarchicalLayouter::testPositionWithAlignment(const QVectorInt &vecAlignedPosition, const QVectorInt &vecAlign)
  6956. {
  6957. bool bIsConsistentPositionAlignment = true;
  6958. int iTotalVertices = 0;
  6959. iTotalVertices = num_vertices(*m_gMainGraph);
  6960. for(int iVertex = 0 ; iVertex < iTotalVertices ; iVertex++)
  6961. {
  6962. //check position of current vertex with position of aligned vertex
  6963. if(vecAlignedPosition[iVertex] != vecAlignedPosition[vecAlign[iVertex]])
  6964. {
  6965. bIsConsistentPositionAlignment = false;
  6966. break;
  6967. }
  6968. }
  6969. return bIsConsistentPositionAlignment;
  6970. }
  6971. bool HierarchicalLayouter::testPositionWithAlignment(const HierarchicalLayouter::QVectorDouble &vecAlignedPosition, const QVectorInt &vecAlign)
  6972. {
  6973. bool bIsConsistentPositionAlignment = true;
  6974. int iTotalVertices = 0;
  6975. iTotalVertices = num_vertices(*m_gMainGraph);
  6976. for(int iVertex = 0 ; iVertex < iTotalVertices ; iVertex++)
  6977. {
  6978. //check position of current vertex with position of aligned vertex
  6979. if(std::abs(vecAlignedPosition[iVertex] - vecAlignedPosition[vecAlign[iVertex]]) > 0.5)
  6980. {
  6981. bIsConsistentPositionAlignment = false;
  6982. break;
  6983. }
  6984. }
  6985. return bIsConsistentPositionAlignment;
  6986. }
  6987. void HierarchicalLayouter::writeLog(QString sExecutionDetails)
  6988. {
  6989. QString sFileName;
  6990. sFileName = FILENAME_EXECUTION_TIME_DETAILS;
  6991. sFileName = m_sExecutionLogFileName;
  6992. if (!sFileName.isEmpty())
  6993. {
  6994. QString sLogFilePath = sFileName;
  6995. QFile logFile(sLogFilePath);
  6996. if (!logFile.open(QFile::Append)) {
  6997. cout<<"File could not be open. Exiting.";
  6998. exit(1);
  6999. }
  7000. QTextStream txtStreamOut;
  7001. txtStreamOut.setDevice(&logFile);
  7002. txtStreamOut.setCodec("UTF-8");
  7003. txtStreamOut << sExecutionDetails.toUtf8();
  7004. txtStreamOut << "\n";
  7005. }
  7006. else
  7007. {
  7008. return;
  7009. }
  7010. }
  7011. bool HierarchicalLayouter::testNestingTree()
  7012. {
  7013. bool bIsNestingTreeCorrect = true;
  7014. QQueue<NestingTreeSubgraphNode*> qNestingTreeNodes;
  7015. qNestingTreeNodes.enqueue(&m_rootNestingTreeSubgraphNode);
  7016. NestingTreeSubgraphNode * currentNestingTreeNode = NULL;
  7017. while(qNestingTreeNodes.isEmpty() == false)
  7018. {
  7019. currentNestingTreeNode = qNestingTreeNodes.dequeue();
  7020. SubGraph & currentSubgraph = (currentNestingTreeNode->getGraph());
  7021. QString sGraphName = m_BoostGraphWrapper.getGraphId(currentSubgraph);
  7022. ////qDebug() << "Graph: "<<sGraphName;
  7023. //check if root or not
  7024. if(currentNestingTreeNode->isRoot())
  7025. {
  7026. }
  7027. else
  7028. {
  7029. //check parent node is not null
  7030. if(&(currentNestingTreeNode->getParent()) == NULL)
  7031. {
  7032. bIsNestingTreeCorrect = false;
  7033. ////qDebug()<<"Missing Parent: Non root graph must have Parent.";
  7034. }
  7035. }
  7036. //check no of subgraphs
  7037. int iTotalSubgraphs = currentSubgraph.num_children();
  7038. int iTotalChildNestingTreeNodes = currentNestingTreeNode->getChildNestingTreeSubgraphNodes().size();
  7039. if(iTotalSubgraphs != iTotalChildNestingTreeNodes)
  7040. {
  7041. bIsNestingTreeCorrect = false;
  7042. ////qDebug() << "Incorrect number of child subgraphs : "<<iTotalChildNestingTreeNodes << " actual: "<< iTotalSubgraphs;
  7043. }
  7044. //check no of nodes with own nodes count
  7045. int iTotalNodes = currentNestingTreeNode->getMapLayerIdToLayerNodeRef().size();
  7046. int iTotalOwnVertices = m_BoostGraphWrapper.getCountOfOwnVertices(currentSubgraph);
  7047. if(iTotalNodes != iTotalOwnVertices)
  7048. {
  7049. bIsNestingTreeCorrect = false;
  7050. ////qDebug() << "Incorrect number of own vertices: "<< iTotalNodes <<" actual: "<<iTotalOwnVertices;
  7051. }
  7052. //Check the layer id with vertex actual rank property, it should be same
  7053. NestingTreeSubgraphNode::IteratorMultiMapLayerIdToLayerNodeRef iterLayerNodes
  7054. = currentNestingTreeNode->getChildLayerNodesIterator();
  7055. while(iterLayerNodes.hasNext())
  7056. {
  7057. iterLayerNodes.next();
  7058. int iLayerId = iterLayerNodes.key();
  7059. LayerNode *layerNode = iterLayerNodes.value();
  7060. VertexDescriptor vCurrentVertex = layerNode->getVertex();
  7061. int iRank = m_BoostGraphWrapper.getVertexRank(vCurrentVertex , *m_gMainGraph);
  7062. if(iRank != iLayerId)
  7063. {
  7064. bIsNestingTreeCorrect = false;
  7065. ////qDebug() << "Incorrect layer id assigned to vertex, layer id: " << iLayerId<<" Rank: " << iRank;
  7066. }
  7067. }
  7068. //enque next level Nesting Tree Nodes in queue
  7069. NestingTreeSubgraphNode::IteratorVectorNestingTreeSubgraphNodesRef iterChildNestingTreeNodes
  7070. = currentNestingTreeNode->getIteratorChildNestingTreeSubgraphNodes();
  7071. while (iterChildNestingTreeNodes.hasNext())
  7072. {
  7073. qNestingTreeNodes.enqueue(iterChildNestingTreeNodes.next());
  7074. }
  7075. }
  7076. return bIsNestingTreeCorrect;
  7077. }
  7078. bool HierarchicalLayouter::testReducedNestingTree(ReducedNestingTreeNode &reducedNestingTreeRoot)
  7079. {
  7080. //*THIS TEST IS NOT CREATED COMPLETELY*
  7081. Q_ASSERT_X(reducedNestingTreeRoot.isLayerNode() == false , "testReducedNestingTree" ,
  7082. "Invalid reduced nesting tree root node provided, It must be NestingTreeNode type RNT Node");
  7083. bool bIsReducedNestingTreeCorrect = true;
  7084. QQueue<ReducedNestingTreeNode*> qRNTNodes;
  7085. //Add root
  7086. qRNTNodes.enqueue(&reducedNestingTreeRoot);
  7087. NestingTreeSubgraphNode *currentNestingTreeNode = (NestingTreeSubgraphNode *)0;
  7088. LayerNode *currentLayerNode = (LayerNode *)0;
  7089. // XXX unused
  7090. Q_UNUSED(currentLayerNode);
  7091. Q_UNUSED(currentNestingTreeNode);
  7092. ReducedNestingTreeNode * currentReducedNestingTreeNode = NULL;
  7093. while(qRNTNodes.isEmpty() == false)
  7094. {
  7095. currentReducedNestingTreeNode = qRNTNodes.dequeue();
  7096. if(currentReducedNestingTreeNode->isLayerNode())
  7097. {
  7098. currentLayerNode = currentReducedNestingTreeNode->getLayerNode();
  7099. currentNestingTreeNode = NULL;
  7100. }
  7101. else
  7102. {
  7103. currentLayerNode = NULL;
  7104. currentNestingTreeNode = currentReducedNestingTreeNode->getNestingTreeNode();
  7105. }
  7106. // XXX currentLayerNode is set but not read in this loop
  7107. //TODO:
  7108. //Check number of child nodes equal to num_child graphs + no. of vertices
  7109. }
  7110. return bIsReducedNestingTreeCorrect;
  7111. }
  7112. bool HierarchicalLayouter::testSubgraphOrderingGraph()
  7113. {
  7114. bool bIsSOGCorrect = true;
  7115. int iTotalVertices = 0;
  7116. iTotalVertices = num_vertices(*m_gMainGraph);
  7117. // XXX unused
  7118. Q_UNUSED(iTotalVertices);
  7119. QSet<std::size_t> setVerticesAddedToSOG;
  7120. //check all layer nodes are placed in SubgraphOrderingGraph
  7121. IteratorHashVertexToLayerNode iterLayerNode(hashVertexToLayerNode);
  7122. while(iterLayerNode.hasNext())
  7123. {
  7124. iterLayerNode.next();
  7125. LayerNode* layerNode = iterLayerNode.value();
  7126. VertexDescriptor vVertex = layerNode->getVertex();
  7127. if(layerNode->getSubgraphOrderingGraphVertex() < 0)
  7128. {
  7129. ////qDebug() << "LayerNode not added to SOG, V: "<<(int)vVertex;
  7130. layerNode->printName();
  7131. bIsSOGCorrect = false;
  7132. }
  7133. //Check if layernode is added more than once
  7134. if(setVerticesAddedToSOG.contains(vVertex))
  7135. {
  7136. ////qDebug() << "LayerNode already added to SOG, V: "<<(int)vVertex;
  7137. layerNode->printName();
  7138. }
  7139. else
  7140. {
  7141. setVerticesAddedToSOG.insert(vVertex);
  7142. }
  7143. }
  7144. IteratorMapNestingTreeRefToSubgraphOrderingGraphRef iterNestingTreeSOGRef(
  7145. m_mapNestingTreeNodeRefToSubgraphOrderingGraphRef) ;
  7146. while(iterNestingTreeSOGRef.hasNext())
  7147. {
  7148. iterNestingTreeSOGRef.next();
  7149. NestingTreeSubgraphNode* nestingTreeNode = iterNestingTreeSOGRef.key();
  7150. SubgraphOrderingGraphType* gSOG = iterNestingTreeSOGRef.value();
  7151. //check if total vertices in SOG are equal to =
  7152. //layernodes + nestingtree nodes
  7153. int iNumVerticesInSOG = num_vertices(*gSOG);
  7154. int iTotalLayerNodes = nestingTreeNode->getCountOfLayerNodes();
  7155. int iTotalChildNTNodes = nestingTreeNode->getCountOfChildNestingTreeSubgraphNodes();
  7156. if(iNumVerticesInSOG != (iTotalLayerNodes + iTotalChildNTNodes))
  7157. {
  7158. ////qDebug() << "Incorrect number of nodes in SOG: "<<iNumVerticesInSOG<<" It should be: "<<(iTotalLayerNodes + iTotalChildNTNodes);
  7159. bIsSOGCorrect = false;
  7160. }
  7161. }
  7162. return bIsSOGCorrect;
  7163. }
  7164. bool HierarchicalLayouter::testIsLayerTopologicallySorted(int iLayerId)
  7165. {
  7166. /*This function is to be used only when just sorted a layer topologically
  7167. *according to the current topological order of SugraphOrderingGraph.
  7168. *Do not use it after calculating new topological ordering of SubgraphOrderngGraph
  7169. *Because a graph can have many Topological orders so every layer is sorted
  7170. *topologically but with different topological orders of SubgraphOrderingGraph
  7171. *
  7172. */
  7173. LAYOUT_ASSERT(m_mapLayeredGraph.contains(iLayerId)==true, LayoutException(__FUNCTION__
  7174. , LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER
  7175. , "Layered Graph"
  7176. , "iLayerId"));
  7177. bool bIsTopologicallysorted = true;
  7178. int iTopologicalOrder = 0;
  7179. int iNextTopologicalOrder = 0;
  7180. LayerNode *layerNode = NULL;
  7181. VertexDescriptor vVertex = 0;
  7182. VertexDescriptor vNextVertex = 0;
  7183. IteratorMapPositionToLayerNode iterLayerNodes(*(m_mapLayeredGraph[iLayerId]));
  7184. while(iterLayerNodes.hasNext())
  7185. {
  7186. iterLayerNodes.next();
  7187. layerNode = iterLayerNodes.value();
  7188. vVertex = layerNode->getVertex();
  7189. if(iterLayerNodes.hasNext())
  7190. {
  7191. iTopologicalOrder = m_BoostGraphWrapper.getVertexTopologicalOrder(vVertex , *m_gMainGraph);
  7192. layerNode = (iterLayerNodes.peekNext()).value();
  7193. vNextVertex = layerNode->getVertex();
  7194. iNextTopologicalOrder = m_BoostGraphWrapper.getVertexTopologicalOrder(vNextVertex , *m_gMainGraph);
  7195. if(iTopologicalOrder > iNextTopologicalOrder)
  7196. {
  7197. ////qDebug() << "Reversed Topo Order: v: "<<vVertex<<" , "<<vNextVertex<<"order: "<<iTopologicalOrder<<" , "<<iNextTopologicalOrder;
  7198. bIsTopologicallysorted = false;
  7199. }
  7200. }
  7201. }
  7202. return bIsTopologicallysorted;
  7203. }
  7204. //************************************************************************************************************
  7205. void HierarchicalLayouter::setHorizontalPositionsForVerticalBorderNodes()
  7206. {
  7207. LAYOUT_ASSERT(m_iRankDifferenceInLayers.isSet() == true,
  7208. LayoutException(__FUNCTION__
  7209. ,LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  7210. ,"Rank Difference in layers"
  7211. ,""));
  7212. try
  7213. {
  7214. //Space horizontal positions of Layer nodes by m_iRankDifferenceInLayers
  7215. //It will create space for VerticalBorderNodes
  7216. IteratorMapLayerIdToLayerRef iterLayer(m_mapLayeredGraph);
  7217. MapPositionToLayerNode* newLayer = NULL;
  7218. int iHorizontalPosition = 0;
  7219. LayerNode* currentLayerNode = NULL;
  7220. VertexDescriptor vCurrentVertex = 0;
  7221. int iLayerId = 0;
  7222. while(iterLayer.hasNext())
  7223. {
  7224. iterLayer.next();
  7225. //create new layer
  7226. newLayer = new MapPositionToLayerNode();
  7227. //Create old layer copy in newLayer with new iHorizontalPosition
  7228. IteratorMapPositionToLayerNode iterLayerNode(*(iterLayer.value()));
  7229. while(iterLayerNode.hasNext())
  7230. {
  7231. iterLayerNode.next();
  7232. currentLayerNode = iterLayerNode.value();
  7233. vCurrentVertex = currentLayerNode->getVertex();
  7234. iHorizontalPosition = m_BoostGraphWrapper.getVertexHorizontalPosition(
  7235. vCurrentVertex , *m_gMainGraph);
  7236. iHorizontalPosition *= m_iRankDifferenceInLayers;
  7237. //Update iHorizontalPosition in graph
  7238. m_BoostGraphWrapper.setVertexHorizontalPosition(vCurrentVertex ,*m_gMainGraph ,iHorizontalPosition);
  7239. //Add to newLayer
  7240. newLayer->insert(iHorizontalPosition , currentLayerNode);
  7241. }
  7242. //Delete old layer and replace with new layer
  7243. iLayerId = iterLayer.key();
  7244. m_mapLayeredGraph[iLayerId]->clear();
  7245. DELETE_AND_SET_NULL(m_mapLayeredGraph[iLayerId]);
  7246. m_mapLayeredGraph[iLayerId] = newLayer;
  7247. newLayer = NULL;
  7248. }
  7249. }
  7250. catch(boost::exception &eBoostException)
  7251. {
  7252. throw *boost::get_error_info<errmsg_info>(eBoostException);
  7253. }
  7254. catch(LayoutException &eLayoutException)
  7255. {
  7256. throw eLayoutException;
  7257. }
  7258. // XXX obselete
  7259. // catch(LayoutMemoryException &eMemoryException)
  7260. // {
  7261. // throw eMemoryException;
  7262. // }
  7263. catch(...)
  7264. {
  7265. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  7266. }
  7267. }