HierarchicalLayouter.cpp 348 KB

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