diff --git a/BGL/include/CGAL/boost/graph/copy_face_graph.h b/BGL/include/CGAL/boost/graph/copy_face_graph.h index 2a4850647ce..80337715cd9 100644 --- a/BGL/include/CGAL/boost/graph/copy_face_graph.h +++ b/BGL/include/CGAL/boost/graph/copy_face_graph.h @@ -24,7 +24,6 @@ #include #include #include -#include #include @@ -213,36 +212,6 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm, } } // end of namespace internal -namespace impl -{ -template -struct Output_iterator_functor -{ - typedef typename boost::property_traits::key_type input_t; - typedef typename boost::property_traits::value_type output_t; - PMAP map; - Output_iterator_functor(PMAP map) - :map(map) - { - } - void operator()(const typename std::pair& pair) - { - put(map, pair.first, pair.second); - } - -}; - -template -boost::function_output_iterator > make_functor(PMAP map) -{ - return boost::make_function_output_iterator(Output_iterator_functor(map)); -} - -inline Emptyset_iterator make_functor(const internal_np::Param_not_found&) -{ - return Emptyset_iterator(); -} -}//end of impl /*! \ingroup PkgBGLHelperFct diff --git a/BGL/include/CGAL/boost/graph/internal/helpers.h b/BGL/include/CGAL/boost/graph/internal/helpers.h index 98d3c7ec28b..ec6b47baf83 100644 --- a/BGL/include/CGAL/boost/graph/internal/helpers.h +++ b/BGL/include/CGAL/boost/graph/internal/helpers.h @@ -13,7 +13,11 @@ #include #include +#include +#include #include +#include +#include namespace CGAL { @@ -200,6 +204,38 @@ adjust_incoming_halfedge(typename boost::graph_traits::vertex_descriptor } // internal + +namespace impl +{ + template + struct Output_iterator_functor + { + typedef typename boost::property_traits::key_type input_t; + typedef typename boost::property_traits::value_type output_t; + PMAP map; + Output_iterator_functor(PMAP map) + :map(map) + { + } + void operator()(const typename std::pair& pair) + { + put(map, pair.first, pair.second); + } + + }; + + template + boost::function_output_iterator > make_functor(PMAP map) + { + return boost::make_function_output_iterator(Output_iterator_functor(map)); + } + + inline Emptyset_iterator make_functor(const internal_np::Param_not_found&) + { + return Emptyset_iterator(); + } +}//end of impl + } // CGAL diff --git a/Data/data/meshes/elephant.mesh b/Data/data/meshes/elephant.mesh new file mode 100644 index 00000000000..4b22a5f896f --- /dev/null +++ b/Data/data/meshes/elephant.mesh @@ -0,0 +1,9457 @@ +MeshVersionFormatted 1 +Dimension 3 +# CGAL::Mesh_complex_3_in_triangulation_3 +Vertices +1028 +0.18190783933880089 -0.19258096982619466 0.041455573981162591 2 +0.053442188512311847 -0.23357063368608913 0.099766904630954473 2 +-0.010044451232351209 -0.32582058705438627 -0.035382010539923951 2 +-0.0044982891469454184 0.06994132246648499 -0.015159671471624741 2 +0.024379529182338013 -0.14346450467189908 0.13875084932009552 2 +-0.22008254837115346 -0.11351404832142181 0.11830529183157903 2 +0.096650215633270295 0.055534885001725952 -0.0098869398920628827 2 +0.079799999124609333 0.065971394948728168 0.0094042558078740943 2 +-4.6921199269546943 2.365714762677563 4.4104548855785968 -1 +5.7464287085725045 -2.9407441846618365 2.3227760939598392 -1 +-1.2696783798683964 -2.5598790078657672 -6.2369579381123721 -1 +-3.5071684960488065 -5.7700160262211471 -1.2130095805367227 -1 +-0.17332430654859557 2.216316884965531 6.4901930784204049 -1 +5.1954615497108323 -4.0265644234933644 1.9643488167669876 -1 +5.7177280330714533 -0.71921420613994524 -3.722233887132206 -1 +6.5670141282484247 -1.9565158046262192 -0.33328574922039328 -1 +-5.2865037267815458 -1.5394156914373953 4.0924058597212909 -1 +4.6031829226102179 -2.8475724209442888 -4.215061842187743 -1 +-0.6084887367979338 -6.161548017996938 -2.954619353505298 -1 +3.7980160442121003 -3.8987102385949606 4.1761035246246347 -1 +1.3903773970571092 -6.1569205477149822 -2.6877291730897537 -1 +-5.5979010677790102 -2.666501989450885 -2.9356394227856195 -1 +6.683656526725958 -1.4478330131650679 -0.54518166123124323 -1 +-1.909680394124005 3.2919945643119046 -5.7079418905450723 -1 +4.9015462139886639 0.93323951817551409 4.7083560569320717 -1 +0.37464244625101656 -6.0681641843468581 3.1783225944320206 -1 +-5.752492671883159 -1.9172738182102083 -3.208986944650321 -1 +4.5550592317121321 4.8369082282933062 -1.708935994021596 -1 +-3.7670348383019916 -0.79033359579622697 5.6788669098135145 -1 +-5.5277060196085737 -1.6048018839545277 3.7327985639516017 -1 +2.9502313028040037 -3.6283821722363725 5.0195304677980248 -1 +-4.7369835075257694 -0.74555495018379858 4.9061026396402765 -1 +5.0460569750764463 1.1041416828450574 -4.5147412100237183 -1 +-1.0891004739851731 -6.3914782214732755 -2.2422253113811035 -1 +-1.5220409922721541 -3.3787116981448801 -5.7734224272663557 -1 +5.3647367669111654 2.7092730849279909 -3.3081938906352368 -1 +-5.1698896572812947 -4.3901933669384823 -1.0310922254702726 -1 +5.3379380057824068 -0.44210333045093159 -4.2866852621376275 -1 +2.0757959954771188 6.5166596852909153 -0.53751797762053888 -1 +-0.55758000567798449 -3.7633622998716643 -5.7088454859255728 -1 +1.2205676774735339 -3.124753535366724 -5.9842157324849197 -1 +-3.876092905296999 4.8818208698668606 -2.8650369681801018 -1 +5.4309186615091187 -1.9126513610809024 3.729825104214322 -1 +4.1420613235946462 3.0064408169009971 -4.5682983320983999 -1 +0.20137475713035852 -6.5808059088644706 1.9279911415888698 -1 +1.1811693707061424 -5.8308655893094405 3.4162191736059229 -1 +1.9234020777156406 -4.8592119227035955 -4.444467570215175 -1 +-0.65494601278128484 -3.6603832652041275 5.7651841355810545 -1 +-1.7819852841763149 6.2051240316233782 -2.3207051178788509 -1 +-5.99576778247443 -3.2932190034600368 0.51979355410715211 -1 +5.577738608855495 -3.339278534873841 2.1915197746800246 -1 +3.9753672892406215 -2.03468356860632 5.2078043104824054 -1 +-0.96951181136480902 -6.6610116042553935 1.3250204906336795 -1 +-1.3826435689884766 -4.2946178683361778 -5.1681004412745724 -1 +1.0686998745084466 -6.776619325832737 -0.0043744686412921178 -1 +5.250041042379932 1.5050262363654747 4.1517072543927993 -1 +-5.2118247727915561 -3.8940292653416408 2.1767238371872244 -1 +-4.345996676960219 -4.2259702842622531 3.2121949015249891 -1 +-3.5317181908723376 -1.5672769783268043 -5.6688021255348318 -1 +-6.4348310145202641 -1.751138368036109 1.6097118610359831 -1 +2.8344674560799659 5.7716140919651311 -2.3914374461509724 -1 +5.4594531295667128 2.8949468436490342 2.9796580917129947 -1 +-2.7593258829989677 1.0181832438838323 -6.1979134874799726 -1 +-0.6928292669811521 -1.5011115417643843 6.658179915787505 -1 +-5.9942888631277205 -2.0973663661940254 -2.5950459333778748 -1 +-1.6531478439130611 -3.1628661218308736 5.859017677609458 -1 +3.0236328453901256 -6.0223719042491544 -1.2858417897192573 -1 +-3.7221058484390301 1.857762124643106 -5.4552136517516434 -1 +0.20874141752301131 -0.017434672329664183 0.14732513563436078 2 +0.034505723128842029 -0.015981666530988547 -0.0056500106163824004 2 +-0.11767652033190942 -0.26137105774910951 0.17091347991092309 2 +0.24732167360422758 0.17826482641672844 0.07515054785769204 2 +0.078247705407699888 0.01031347822545811 0.018331516464894258 2 +-0.17020471763003514 -0.067550211125752269 -0.10488049744242293 2 +0.088544933455775937 -0.16839829708715262 -0.1609468367979289 2 +-0.21530051838297859 -0.27690342075398888 -0.016461125749175187 2 +0.11647627215038311 -0.15804599813252906 0.1066532226919214 2 +0.16119714821717546 0.13754348498655489 0.021953834157381058 2 +0.14279811354677224 -0.077380441952625126 -0.069552508715180816 2 +-0.0098473254583091741 -0.005129508498896344 0.12964937354044426 2 +-0.10961514257975874 -0.23448022297926185 -0.16566815967977327 2 +-0.12028615375606849 -0.3670338812149756 0.06126940717090007 2 +0.12405972280894695 -0.27442261381823485 -0.065817685378146085 2 +-0.25878119948612288 -0.13984022854038425 -0.017664124330750264 2 +-0.22961401963358385 -0.24256430972995957 0.10791242353482811 2 +-0.022664639281246797 -0.22839626728017853 0.16552837087159999 2 +0.12551918489129835 0.096520202750708994 0.012983860693446196 2 +-0.13117845982798704 -0.018666192224404417 0.036021037791955049 2 +0.12662722652760006 -0.10329583740176548 0.26239291676388499 2 +0.15589626263028433 0.038913547185136219 -0.11302486100670528 2 +0.147399447967379 0.16508462963090298 0.13511089870244802 2 +0.090047334833229298 -0.053165767974491032 0.13093765478354724 2 +0.15758093783541979 -0.24897332626493207 -0.16324587803559501 2 +0.20935475562430256 -0.14149998407844244 -0.037373354360513221 2 +0.025640208094566998 -0.080862814742700767 -0.073604490851677709 2 +-0.34525793413932293 -0.42412561309190466 -0.17324260112767187 2 +0.22673146504196337 -0.16413523875923669 0.18943191754675137 2 +-0.14891402027369527 -0.04170570364266242 0.13413657166693382 2 +-0.2055369480775362 -0.057804916419649466 -0.014140074288212512 2 +-0.1738877483737773 -0.18378596385122847 0.16463523518309309 2 +-0.047960336483967358 -0.036844094021161039 0.036034605987006793 2 +-0.049975380336123747 -0.30601491520437352 0.15020711026560069 2 +-0.048772355124402311 -0.36939278771651507 0.021848899423613996 2 +-0.25393551883573684 -0.17337459688211776 0.081864220226055329 2 +-0.11526495027065817 -0.44612115005291764 -0.0095373247751328397 2 +-0.2892632307029126 -0.27061387076752441 -0.16684447013036047 2 +-0.072963252532780826 -0.29438344590374826 -0.10487041699574876 2 +-0.1994664879349452 -0.31331733557260133 -0.094567330130457622 2 +0.17976947864722254 -0.096452673360407276 0.16485344238169897 2 +-0.25951874475612058 -0.21699482894465361 -0.049476539618521026 2 +-0.24034106031803543 -0.10770106585182375 0.046905233204753642 2 +-0.083736153842980138 -0.041725698621238996 0.10009250270823228 2 +0.16011303932443333 0.096155447800392702 0.151545627934741 2 +-0.04055871687920002 -0.14909691150809332 0.15875687603000513 2 +0.10058304407211303 0.00014884682537530261 0.16560245942671459 2 +0.029352768016589221 -0.077239370619325565 0.144259907756707 2 +-0.27443450491399579 -0.31911641104566102 -0.10938902646770984 2 +-0.28822230402670512 -0.27702958749564499 -0.019497303991814485 2 +0.1616339711283587 -0.14541340760966953 0.21502421109514727 2 +0.15731696267986284 -0.05088430006169789 0.11572768288373272 2 +0.1173363069922029 0.1210297250427753 0.13127912759477811 2 +-0.13020186843962811 -0.16546351698137945 0.1924528232437952 2 +-0.27898234732090621 -0.1876845027530758 -0.010635356913400257 2 +-0.030428589709696519 -0.0084562983533389598 0.07921770517354712 2 +0.17627544762166408 0.036144298872786355 0.14206847826421193 2 +0.050437092652807727 0.019041826338353968 0.12125192618561015 2 +-0.091566501362602609 -0.077380483558814578 0.14279011809706976 2 +0.29458485269793083 -0.22193170139511337 -0.21328884674437246 2 +0.22142329370437064 0.23249898613648234 0.15773347064752968 2 +0.1883570036883685 0.027222966846100583 -0.0046015060423791028 2 +0.15923569874352345 0.20126111363407953 0.11200445006052068 2 +0.23214257895184207 0.22176108324286642 0.043591391765302259 2 +0.20291772469540942 0.053322581949480849 -0.046693049738437908 2 +0.14601676578492229 0.13188104418838986 0.15460417980873592 2 +0.12403551368334262 0.0015179636172670658 0.0004389628759189604 2 +0.20601936823517297 -0.1731377694830738 0.0017070293518573749 2 +0.21467589253509506 -0.028321218078640419 0.0010414063831546243 2 +0.19334917069388852 0.17438917633790207 0.029648508668814556 2 +0.045623455773999316 0.052142029651587735 -0.032793866229304199 2 +0.1019862122884824 0.056959489027285856 0.13517746882792475 2 +0.17487642175524565 -0.0077985231617865745 -0.0040224308919088875 2 +0.017529905413755799 0.011051625216560451 0.061971464810079105 2 +0.097528009781698149 -0.032543551462955636 -0.036142978617964491 2 +0.23226703375427568 -0.18631704220618212 -0.12129628968639428 2 +-0.039802402835782069 -0.11592189470094005 -0.13186337619325461 2 +-0.12926381039675772 -0.3561321683549884 -0.064306083695742214 2 +0.11313497740452602 0.12992422565513934 0.078719197781884687 2 +0.16009856211495771 0.06765620975727385 -0.045318192919411006 2 +0.069747862798698976 -0.28633964703848891 0.016849748869664512 2 +0.26641785407491253 0.053647041434125353 0.059176061352693841 2 +0.0055059021465169566 -0.25187581026401606 -0.13063503134305726 2 +-0.12978994546768927 -0.14398469623519283 -0.14449395198564408 2 +0.16261913206784839 -0.13572961663474967 -0.13033119192220871 2 +0.18699363222867199 -0.22392510143192737 -0.03782750230355527 2 +0.086499156092645801 -0.10856891001988977 -0.11219394489762931 2 +0.12742895188021225 0.051612790451273954 -0.0079127317746529868 2 +0.14204443687648838 -0.39232634257331883 -0.014388914595793657 2 +0.30839678639179985 0.13749699189406003 0.15593516691354073 2 +0.075375028047359405 -0.37487903108368986 -0.054045585250345723 2 +0.11390836152386831 -0.43279679528624926 -0.016519894298167935 2 +0.15739395784585741 -0.35661233098959005 -0.015780641956158949 2 +0.12353669154739744 0.048209743128745833 0.014234302459604933 2 +0.1389107904158714 -0.37587573913510075 -0.072839395848301555 2 +0.1808945999597909 0.080722954660183532 0.076186768535811397 1 +0.10375873422677595 -0.058841498772813597 0.047915540642621726 1 +-0.089767277170938492 -0.17993795717711775 0.0096012669869141379 1 +0.0070854362789093961 -0.1997623426889055 0.060457061769447026 1 +-0.08611405780290339 -0.21162842864637765 0.13416532055430647 1 +-0.10099424097813189 -0.12221197698394864 0.17530041360679796 2 +-0.22903512256537661 -0.20677349523354427 -0.12431357312751501 2 +-0.0082188539260599283 -0.33389458346777851 0.083241531728625751 2 +-0.063459165448098001 -0.048292205817184214 -0.046937795374984062 2 +0.19392046044004504 -0.093409996094693609 0.075559283609123659 2 +-0.28240589241990488 -0.22236303922810124 0.028508518304756765 2 +-0.1663158827964144 -0.30675071447163882 0.11003687401542228 2 +0.12327718151680561 -0.22516711307622803 0.074453842733494285 2 +0.10787631766543719 0.039658298001398737 0.028335615273040113 2 +0.097193005619005235 0.065783645873085217 -0.081151579899571794 2 +0.090556264127680003 0.080839566508026095 0.062689328729982743 2 +0.23174017841634226 0.10186112407334735 0.1470772902423681 2 +0.28166359122873796 -0.043600016359332486 0.082336288645491654 2 +0.22740227387736878 0.050323243759863009 -0.0088468527924192748 2 +0.085734850038665711 -0.26683178749198971 0.067431770396967766 2 +0.15407921115902509 0.041404947029170462 0.0010967881813665281 2 +0.1231118538248881 0.41623754085176357 0.19447309476915864 2 +0.30685874215664694 0.15006928977048203 0.13632828939023384 2 +0.21820125117114292 0.19893582843761054 -0.0054285707846783923 2 +0.028198680298162727 0.024708758602894745 -0.11271518606302934 2 +0.23758421462971319 -0.0068830564006121114 0.033390059085092953 2 +0.12874633562317045 0.038567887549627609 -0.034814457465702109 2 +0.20332824023727469 0.10512800273620959 -0.0057405256663363722 2 +0.21163707637606299 -0.1290082237511283 0.025379275003402556 2 +0.10940904528893748 0.10802446041434771 0.051959146732066565 2 +0.34316276217412411 -0.32045275047663002 -0.25263773059008598 2 +0.18493297687897947 0.27318785869750351 0.030737963836950245 2 +0.17039291872076973 0.22622400216924121 0.16210730028022141 2 +0.16440605840399966 0.034259625406023626 -0.03262656332964084 2 +0.26824882161282504 0.15228592467413982 0.10899064274818998 2 +0.09277264663690632 0.088872203491885682 -0.01649669984339916 2 +0.26597962210953735 0.037050904031453093 0.094908254593188926 2 +0.13644701963798461 -0.24757621564440946 -0.11234771265268664 2 +0.043589783327176918 0.088903280354090147 -0.029018986603192146 2 +0.076238470102847594 0.078431353078726201 0.036449003148390752 2 +0.28241679872685932 0.081821803859419368 0.075137969370721244 2 +0.19929629880519772 -0.16154192304869522 -0.14300340273032863 2 +0.2260021452049818 0.021298601192385379 0.013265519565021311 2 +0.2021106077821192 0.22228895730670883 0.019145811301462985 2 +0.19857450088041065 -0.26441183647025973 -0.15840963249856083 2 +0.22204304922951007 -0.0064569591304457549 -0.091330965564602656 2 +0.3336305550401033 -0.25550277598668136 -0.25402841271197757 2 +0.29259405824083151 -0.26276770645648728 -0.17878329149529754 2 +0.1989091542188029 0.20719108953344845 0.16312711109007338 2 +0.23992309526839661 0.16092902197652392 0.0072310962974084106 2 +0.23988697009247389 0.20230496630782069 -0.0054983262287532008 2 +0.18210813649954111 -0.22184940477408935 -0.07317723451903832 2 +0.23724111014372079 0.15811381175605904 0.14751480439016582 2 +0.16814582643017573 0.10788694872260579 0.00237227810921181 2 +0.17415753496182107 -0.29721046844281468 -0.010283118481219371 2 +-0.29135977683646974 -0.43245719544180217 -0.17634673793317734 2 +0.095703844827107087 -0.0026638945488835488 0.21562516813599081 2 +0.1849140448699817 0.49718778261363972 0.083551514857651388 2 +0.17871899266332616 0.44747878530378465 0.071537929284390636 2 +-0.067815086621490023 -0.13611758252836909 -0.070500692145090263 1 +-0.22466449710314687 -0.34343053963119818 -0.17289691681889613 2 +-0.33866674400565755 -0.28579903409284035 -0.084136553664389879 2 +0.13935386101907313 -0.032392510462660062 0.20551463577042098 2 +-0.036320727501038624 -0.084962711963092213 0.13600199066911056 2 +-0.20290391530537111 -0.047367517210117893 0.069276856413800103 2 +-0.17759781793120269 -0.3487154241107393 0.0033751657692848219 2 +-0.13936030976662439 -0.023977450431487586 -0.043170088728274505 2 +-0.085343611652668877 -0.19558978837001717 0.20235892947619707 2 +-0.16508756640554823 -0.10394897130526431 0.15843150583681748 2 +-0.016852005103481435 -0.042234323129993652 -0.01275608671193333 2 +0.065563889974454281 -0.18139453512649384 0.12266486730079035 2 +-0.092746245002214289 -0.29307095947705425 0.151614003127716 2 +-0.053967261589717319 -0.25299731959764016 -0.14674228000328987 2 +0.12389414609342322 -0.088471009025810426 0.11880344675301276 2 +-0.046175316224354827 0.064536154475461488 -0.0564323667764738 2 +-0.14473828601214672 -0.3969435236530825 0.010305255329719723 2 +0.11874589579347242 0.014032415845895018 0.19067033045079013 2 +0.19690033822100589 -0.13575128851359258 0.22000623365172373 2 +0.14208658541311389 0.0074125066915241124 -0.092770405888999818 2 +-0.24305636062757846 -0.25048590931990278 -0.15066755070595886 2 +-0.34139347739955067 -0.27253540133400728 -0.11868140315651381 2 +0.12678398195552376 0.028294511166459611 -0.13801707973623931 2 +0.17988990053075676 -0.064890194628264924 0.14324727986503555 2 +0.016951618161493189 0.058638950884703153 -0.1086436038958577 2 +-0.31746488543304052 -0.26812614793120793 -0.050482212753561594 2 +0.21171222490465066 0.013248823699469895 0.12852971278979392 2 +-0.30404959780467899 -0.30751074228888542 -0.10421871185495059 2 +-0.019376179012102479 -0.0713518548050118 -0.05355633216502402 2 +-0.14791754790274353 -0.22949603452649159 -0.17060710612408131 2 +0.1171988361025222 0.36933978596903783 0.16858917085561412 2 +0.31027324986249399 -0.09423725098712056 0.089200467494687297 2 +0.18940491919152014 0.28535885666178989 0.20038253104190112 2 +0.24657237084035716 4.1996232995855989e-05 -0.098128273838828634 2 +0.065121070362492831 0.097833501979385895 0.033765614740113692 2 +-0.041637943098302849 0.091131148078262822 -0.057714476468227069 2 +0.01458516450324753 0.084716977738874932 0.0042210143414446039 2 +0.054749143201978448 -0.17185525471043384 -0.13896341762319697 2 +-0.016204397238910595 0.092390759521050927 -0.021971897531665143 2 +0.24999415774747213 -0.16338623463207996 0.16309496464475423 2 +-0.0063488503761687815 0.064540682734689186 -0.098382421406233572 2 +0.27323273602094339 -0.24200783022741626 -0.2468706062569811 2 +-0.035493262273648019 0.051933729843830878 -0.082936764654756065 2 +0.28217082972267415 -0.12621735802816292 0.13367823268092505 2 +0.095116455364976635 0.10020192607662924 0.063392454561391226 2 +0.088269814298290575 0.054425098346158975 0.064223222977910027 2 +0.094943482073474056 -0.19569283812336219 -0.16697511433854922 2 +0.1929568755800864 0.034927333390797871 -0.021011857578349245 2 +0.12535556223536523 0.31738828321206336 0.17748107976619384 2 +0.19429418879360327 0.39813147910484514 0.1950945263214785 2 +0.093394274759018334 -0.10622348957212316 0.29216704621584244 2 +0.19091744394921809 0.46436168709192249 0.15963861366085003 2 +0.30688503852339732 -0.11740944274947263 0.089629443879173182 2 +-0.13335081668592685 -0.49681010178391727 -0.040200545495430597 2 +0.18721979317393317 0.32985030509972035 0.20361991808336052 2 +0.22670667902514458 0.30288741678228803 0.22076808972217005 2 +0.14737987492249094 0.43627304048200277 0.20064369220976652 2 +0.15712376812236145 0.30628191181076725 0.12790488073541742 2 +0.14567567821419547 0.34241412269305271 0.22539135839517049 2 +0.25335221104367323 0.033365239967301952 0.051386433097310516 2 +-0.095650936290213762 -0.46310789703497635 -0.090643957374031192 2 +0.050982342250377191 -0.026421257926238586 0.13508498329688634 2 +0.17050193952909659 0.31111980629061042 0.055749450674562467 2 +0.17630949500049359 0.29099214445905819 0.096622018362677919 2 +-0.3035191376207057 -0.3826431675596651 -0.24876750599873421 2 +0.30281254658202533 -0.23591811834188045 -0.18789240824860418 2 +-0.24982630709318454 -0.39035169854889118 -0.23100356031298047 2 +0.30945064760312124 -0.26317176077502913 -0.28049531312799653 2 +-0.27691000366381691 -0.42077431242108654 -0.17446699979306424 2 +0.35021186760266687 -0.3066271876412322 -0.27421918460062022 2 +0.18514338439306668 0.28934558361801854 0.032853781694561518 2 +0.20981284964585542 -0.12511912647815865 0.15989114432625373 2 +0.27452737660680515 0.1630192503648317 0.17786052885376935 2 +0.26872125560762916 0.25349527968875396 0.19876003500180661 2 +0.15761374437570139 -0.26120454932796255 0.030380298606825895 2 +0.27042587990782824 -0.13075347314918986 0.11394825441283341 2 +0.22807930881348748 -0.071299421467643731 0.0030523251970955168 2 +0.25631703279887252 0.12238757162850171 0.016329026093729729 2 +0.22395729934780789 0.18132998220498545 0.15157580611709676 2 +0.17354682215693701 0.19429556419832839 0.070418206375690851 2 +0.23441174703304357 0.039421334081862214 0.11836595657464774 2 +0.085231175992602548 0.10546643175434572 0.027090094768137896 2 +0.19215755415307356 0.013106822281674254 -0.064235432864381381 2 +0.084482913645977945 0.03851001460867641 -0.048799343473804865 2 +0.070256645141689222 0.035185590335017405 0.060956438460174629 2 +0.10464219882275019 0.060866002992784857 0.014037381451763462 2 +0.036374465969928188 0.097429238484006309 0.0062658873008752669 2 +0.21124646545206283 0.25892354653588856 0.11459671422295564 2 +0.18881098944938318 -0.18311464963998206 -0.18296276213688847 2 +0.18999177515100302 -0.23700206686543268 -0.10457827313243162 2 +0.11759866352044082 0.079312809280458904 -0.037999912162938701 2 +0.27749720817573842 0.071796012769224579 0.10948687207661387 2 +0.10309307270422707 0.015727238859669604 -0.090863344083063777 2 +0.019674568894042961 -0.19171774470712505 -0.14251763226897457 2 +-0.096675635797879023 -0.092312806478313025 -0.13717269339075702 2 +0.13367747853375583 0.17303052866177926 0.088927313151002302 2 +-0.0094563373688687224 -0.10577054397460067 -0.095625757119765259 2 +0.027098754509154922 0.038482358700061031 -0.07063475840595268 2 +0.18135275201921258 -0.2411686047386159 0.014628299283835466 2 +-0.27927261159538497 -0.26849758717529204 -0.11652278503199547 2 +0.18413881396244858 -0.060380591947434364 0.19229606181661041 2 +0.076851429378421515 0.046116475411859967 0.10374794714700744 2 +0.2362695105260158 -0.13592787237462198 0.14597709772039064 2 +0.1919646860988018 -0.13681671452222427 0.18344945661048179 2 +0.14338190045317023 0.01666119618517304 0.16749280648004466 2 +-0.31781019276251049 -0.3423076080406311 -0.15810805076498663 2 +-0.25987172146149595 -0.37455399927136412 -0.17986381567003223 2 +0.27279343628155511 -0.10515389531636804 0.13770157207042594 2 +-0.25296316636633442 -0.25804938564104246 0.010097997423827937 2 +0.20507390944953874 0.20165332929143143 0.045639000019094371 2 +0.23128173030726901 -0.18356218166658733 -0.16668690176850248 2 +0.24410144298009767 0.011200813689645369 -0.074474463410954525 2 +0.28880534169607563 0.12068294549863812 0.11841922703395719 2 +0.013758794312372497 0.09728195046090754 -0.017733377243851496 2 +0.28610237910781744 0.053274982121777274 0.080967569202273409 2 +0.20245572680563539 0.24507163438452115 0.049889771530667974 2 +0.24886425643650953 -0.27631916051861549 -0.23218700234537784 2 +0.028593298100507585 0.066936937950485248 -0.0071014904751983965 2 +0.078277931551840929 -0.20417299630764424 -0.14523529217097919 2 +0.081950207526230695 0.097414916452855563 0.048727080603489611 2 +0.23914602907657009 0.23229127664195146 0.01883301639979602 2 +0.099858779529665459 0.063400170698008115 0.042077144909649533 2 +0.20849031121158368 0.01853195914159218 -0.00032923491243670071 2 +0.20860490810592835 0.29289583317136103 0.23166070527607252 2 +-0.32797778682872569 -0.40590330879931846 -0.23363254306457137 2 +0.19074778732904224 0.3003962508469995 0.047944702408273809 2 +0.25582841361105657 -0.11661724815866559 0.16215408341556972 2 +0.23069468493606587 0.020941342806216255 -0.099243550672771033 2 +-0.0376511405051786 0.077560339378598797 -0.024712783572696878 2 +0.29754236795134087 -0.11329227932524095 0.11821641185857473 2 +-0.026628626920475545 0.081468543989348455 -0.077984645559151217 2 +0.30180569795819401 -0.31362737388727757 -0.27314810846661541 2 +0.21322707762923612 0.0056055414617383172 -0.14101234541395313 2 +0.21328379999336211 0.26729260302085867 0.15010512171618076 2 +0.2513631138750283 -0.28652524861697837 -0.19724145667572873 2 +0.22665764182187742 0.24782688725230462 0.037517053575084454 2 +-0.15681207164029573 -0.30026058129986377 -0.096195935616324724 2 +0.18205195937778557 -0.25389533611138915 -0.1855851747278679 2 +0.26550815453441878 0.1041530174324832 0.13849762719050765 2 +0.1876081104068382 0.26713044904781136 0.057628015690754403 2 +-0.25454318085372285 -0.3910271167523266 -0.20987544606855635 2 +0.30214743332264032 0.12763762894617464 0.1357213981245301 2 +-0.027354370294133928 -0.27796204342108488 -0.12537770308429252 2 +0.12326920157477569 -0.041911937191909894 0.12302326015352558 2 +-0.23621028310553308 -0.32336823794511016 -0.19431237952175315 2 +-0.17188314900087953 -0.067946622875534254 0.14599238100604092 2 +0.092885283774467031 -0.070821612142732887 0.21650656279967329 2 +0.14142148036588698 0.0076895079127977505 -0.15697080528106838 2 +0.053882596881767539 0.025424685548994207 -0.088969427987758087 2 +0.29435592160255336 -0.13449418495772203 0.10120875136447328 2 +0.10276758181932541 0.0040676405901681166 -0.12232602261711203 2 +0.26058287746401798 -0.060734846083502846 0.07390835052190331 2 +0.024428038941173992 0.043668852226405014 -0.12218624429428579 2 +-0.32397478143756331 -0.3060006918478092 -0.088583922589664049 2 +-0.30012002849644215 -0.30355296072874371 -0.15769675978407882 2 +-0.25794925726083873 -0.28381538878983248 -0.097679564228918409 2 +-0.138254801999942 -0.054938363621579292 -0.11041997923508248 2 +-0.28713802313669934 -0.27702317220222383 -0.051089530024228093 2 +0.29752155480895082 -0.081100528061842397 0.079094072933104637 2 +-0.18865783303619679 -0.28966856107295869 -0.18696265436752613 2 +0.1830438361933176 0.43851116334246709 0.19894560453738058 2 +-0.10666348714688458 -0.38025070628642577 -0.07597982357661888 2 +0.098927530603550695 -0.1409901018341736 0.26459596051570011 2 +0.15215292320900065 0.40152700443649636 0.15838893749603894 2 +0.17161305709984306 0.018492429202631132 -0.14021466606721633 2 +0.20299107881404194 0.31020571196469671 0.19627689488788908 2 +0.24131411278374854 0.28549560302449717 0.22627287130488133 2 +-0.085499245790452233 -0.49137153288500079 -0.027418859469566868 2 +0.21602274515800723 -0.0087551773415552748 -0.15393637604699253 2 +-0.10107501063510126 -0.47427161520894712 -0.076310733902505506 2 +0.096144745784651903 0.021818006935084483 0.15838578094677552 2 +0.25042440130608962 0.010345096386828144 0.061596316867038703 2 +0.092044502719853816 0.0063622891963587861 -0.14114895691976082 2 +0.13759462090802282 0.36433644375725283 0.22920607686576827 2 +-0.16056113666152189 -0.46642943706758866 -0.079146759659860261 2 +-0.12766348539381539 -0.45990739540080883 -0.099140187418749415 2 +0.23205831954153136 -0.047705734817382314 0.03675474539974613 2 +0.20152998198792149 -0.15548667874937883 0.22060911734680522 2 +0.23602486441000736 -0.053656261344173631 0.074796129341373141 2 +0.26427617997724973 0.23901207457824392 0.22133078815039109 2 +0.032609871184357569 0.028393680501597574 -0.13155874772997442 2 +0.15802324843619878 -0.15881683259173032 0.2388467981645534 2 +-0.085227459025461277 -0.065908901258434432 -0.11678638745091303 2 +-0.075361973078962807 -0.46558232256048293 -0.042308073773941635 2 +0.10925095820471273 -0.016776715766462332 0.21876673297424387 2 +-0.29775077232600672 -0.29754580860616303 -0.058779813176178614 2 +-0.21571557239355524 -0.29611048347700375 -0.068281812836019695 2 +-0.045274350537900264 0.070432851525974879 -0.077273955544761186 2 +0.26694056865536187 -0.14607950635550665 0.12947161970478499 2 +-0.35246549369932073 -0.39523478781127958 -0.17179193220636399 2 +-0.020104906702266185 0.052504333367748679 -0.10304648105972952 2 +-0.27063254622083177 -0.23181929906764712 -0.034067316835042924 2 +-0.25321305037020392 -0.33601023098468341 -0.10830505124798548 2 +-0.29423781353379952 -0.30539487268907362 -0.089227466365527974 2 +0.12797852987676284 -0.0048547597534200947 -0.14906603270784008 2 +0.282190750139797 -0.063174976490484175 0.072818683272471013 2 +-0.30231465605073565 -0.24468718795766753 -0.027692047316684579 2 +0.15266688652088969 -0.012034284113720289 -0.14381047588269025 2 +-0.27991557365090386 -0.34867616177972616 -0.12285585794568873 2 +-0.3434204343004581 -0.37037174240497039 -0.17108393101230832 2 +0.27257350955057502 -0.049824333440569128 0.069731012371351764 2 +-0.30802747722630763 -0.34915765017092626 -0.2079514931337898 2 +-0.19088438710813907 -0.26325768731322408 -0.17868591961572455 2 +-0.22182529341660329 -0.13102104199318271 -0.091368226271897918 2 +-0.041199058099249744 -0.19216020744699797 -0.15849092050651503 2 +0.050705513563134727 -0.28672877220153414 -0.055750930344384858 2 +-0.074993424376485165 -0.39523878810133301 -0.039329938020138136 2 +0.0073726862659389356 -0.27647632462124272 0.12695004191938355 2 +-0.16348498181085228 -0.30724321199816451 -0.042596603990261162 2 +0.22485728031777513 -0.094703925808595657 0.12623815115512158 2 +-0.22376997431974835 -0.18781086668239177 0.13162264875158713 2 +0.016873262164922565 -0.32378451824501198 0.02394290654303028 2 +0.1185731898856657 -0.46552523599896589 -0.053141280104810285 2 +-0.12654964708666938 -0.43685420942664643 -0.094529308924774777 2 +0.081914740999799923 -0.23545147192664465 -0.11992672352382895 2 +-0.1399808058422542 -0.29926261916966995 -0.13752683181549857 2 +-0.20685664169974438 -0.30252269825302502 0.050478773682231838 2 +-0.16800280363339529 -0.20002517295799732 -0.15497507488423121 2 +-0.063153736122239568 -0.26270471056479161 0.1828981011958638 2 +0.25306059362628036 -0.046700271933208359 0.13016350943127786 2 +0.014372757748930525 -0.20498968114452859 0.12942649443377052 2 +-0.24961050066303425 -0.17684205099756967 -0.084281501815726717 2 +-0.20241159627721539 -0.1473486926125934 0.14885467715887576 2 +-0.19383358835122766 -0.2300436668390039 0.14597544520770711 2 +-0.063625055559667132 -0.35692977221372912 0.078806816629182042 2 +0.071151164331143796 0.013236483379327521 -0.11580268947259212 2 +0.18581651112041497 0.32751615277169654 0.17131425248628254 2 +0.21380457745333695 0.4350655138945424 0.1297522260414615 2 +0.14827135572734568 0.44567134746352222 0.16999550377950623 2 +0.097726981111801711 -0.11230629485627502 0.24256647778349011 2 +-0.079594149510421819 -0.46294417113345498 -0.080562128512714534 2 +0.20081882612930582 0.3200406242179048 0.22380406888311877 2 +0.16589582294345973 0.35472627042819116 0.22541350141143027 2 +-0.12155574352333964 -0.49414220585602425 -0.0182798541275156 2 +0.10719134096807338 0.023138410337545011 0.13927636351100209 2 +0.12504434067551429 -0.1306519875968023 0.27214154180658701 2 +0.23198971718082181 0.2671874919319176 0.22835687052469533 2 +0.25228402278293816 0.02944225777856898 0.07641062122605885 2 +0.2951054818080413 -0.10024854846022367 0.078888856433833934 2 +0.16563980248755072 0.41746473632911973 0.21911683775708657 2 +-0.085250444156980659 -0.39064545429302033 -0.063661230058017076 2 +0.23937704420860767 0.23536007570069623 0.18237724533613309 2 +0.3031045377602547 0.19043516687289536 0.19372116951473117 2 +-0.05694039449108089 -0.036732119710978298 0.10205442325016253 2 +0.090326819055578877 -0.039495417809867553 0.25175168317455443 2 +0.26247327923872421 -0.15868019221466917 0.14623211073661135 2 +-0.32747141211446262 -0.278911293247323 -0.065204982781635612 2 +0.071542702909284994 -0.019931834098982696 0.21064624733240639 2 +-0.31779470867078441 -0.2751531627713143 -0.036663935223438478 2 +-0.31825319783134909 -0.43385954391828552 -0.18370226029355308 2 +-0.3126910927607075 -0.36615239466951588 -0.14262993280715891 2 +0.091796481559522358 -0.34047688932272591 0.017758235016364206 2 +0.15353743083164423 -0.45181842707475428 -0.069226297989590291 2 +0.12719703821577322 -0.46516040945251264 -0.019136361459128601 2 +0.1143432255615042 -0.39979316433642487 -0.0085191000385925406 2 +0.094919020414650085 -0.35684517110505865 -0.080714522354239815 2 +0.097259907816277108 -0.41760269037501319 -0.10082540708200184 2 +0.075151902477700025 -0.3272929881192348 -0.048623948236919234 2 +0.16282152009806108 -0.42727931827886523 -0.085478969978165384 2 +0.14157613740671121 -0.46690728123871994 -0.040862190251950717 2 +0.08282718944411005 -0.3802033216223068 -0.078777823241235584 2 +0.18476126325054598 0.31172527334577382 0.22628022231348921 2 +0.059958136600170756 -0.083897261890530192 0.25222518940015948 2 +0.063598648044956324 -0.20840665504739694 0.020316240997727594 1 +-0.18659860785162372 -0.15008997166312232 0.00062478782919481862 1 +0.062021182734006176 -0.11069579963780166 -0.022661576359467986 1 +0.12132215631681859 -0.15910155359135983 0.037497102159098475 1 +0.12873717181370029 -0.18302633090878412 -0.09110865712554235 1 +0.13905225459520276 0.29538762472939406 0.14634803988768491 2 +0.16040749094533865 -0.29256254648527158 0.015481438363693706 2 +0.092397565120575648 0.028082851569372236 -0.13952254660791502 2 +0.28268101213489794 0.11758758743496286 0.080168366151908782 2 +0.023595209921819477 -0.13524452921061253 -0.11501591088412251 2 +0.0066843653180541909 0.076811781865846251 -0.079340636989581326 2 +-0.10714043690170764 -0.045854572369402928 -0.097773925076158105 2 +0.07600666451138044 0.08211619640511722 -0.045537352102952122 2 +-0.20026056553238714 -0.061376534968862473 0.1234472461061728 2 +-0.18540484822793663 -0.043012647433933737 -0.060662051135731365 2 +-0.15715383446200476 -0.021320653239200293 0.084068152159894147 2 +0.2593663050378397 0.14437061245965288 0.15483205514423104 2 +0.24770444240293837 0.17143580065790237 0.025057532364513607 2 +0.22033401756083815 -0.14113686303114129 0.20485463251330369 2 +0.21768241879327585 -0.088834454299171306 0.040478061195637779 2 +0.076115709589772818 -0.42340169861693067 -0.046809908690575386 2 +-0.072175208292825282 -0.46988400781755157 -0.061688807016371368 2 +0.019934902835138497 0.02965869832363131 -0.12398012088124738 2 +0.25402754493800989 -0.0066614352109213813 0.086626409337103832 2 +0.1366337919817302 -0.1484307076211438 0.23861722433320443 2 +0.17496871229500294 -0.13967726057578816 0.24028886750280498 2 +0.047229528862441375 0.017930630685237037 -0.11988403789716146 2 +0.26480676268526904 0.25819593905777344 0.21800149549260572 2 +-0.15060679349274453 -0.46676355531084479 -0.091470570655331512 2 +-0.089299168933965611 -0.44595317817708213 -0.03588621633021178 2 +0.12955968614775812 0.35833053394392522 0.13572260249592166 2 +-0.34642760629725594 -0.42896791742229207 -0.19601589773112801 2 +0.15652860790824158 0.32758224558318627 0.082314809065140104 2 +0.17541480019552408 0.38019099198831496 0.16761614618661863 2 +0.14081983720264091 0.3304606361389566 0.10605779263371151 2 +0.16079332285838405 0.47393303296864742 0.08718566357102539 2 +0.20246970823945137 0.45522156699148397 0.070780496978223306 2 +0.22011162460404768 0.44875354289573888 0.060374989457903247 2 +0.16201844492147088 0.47589259685966134 0.069758460723964522 2 +0.20448772111656205 0.43759461598263227 0.078516807256703056 2 +0.092622749155588963 -0.38015199531673194 -0.008415936405147555 2 +-0.1651021001676907 -0.41142126104444754 -0.042887176065981754 2 +0.22075120133053394 -0.063042772106973871 0.16535484064870817 2 +0.28834063505600338 -0.082140442082632437 0.11639830028718962 2 +0.20057149556184767 -0.061502540491447988 0.10711244479377767 2 +-0.14318148124054647 -0.26799561551279905 -0.17402200238731741 2 +-0.094468987302887497 -0.23741574350964878 0.19808835984562112 2 +-0.026263465940297336 -0.27150883344320592 0.16174210687281443 2 +-0.16972372730100499 -0.34273122729459327 0.057686473647402939 2 +0.112631291898945 -0.21763519248368329 -0.16168852814316831 2 +-0.070539603133840084 -0.34028285577390605 -0.065025457172549317 2 +-0.25029420813627801 -0.14081556111484367 -0.060170076457348246 2 +-0.25058257473057222 -0.21822878097473525 -0.090330110314753187 2 +-0.18769008941596965 -0.3083941346997508 -0.0072069279119800662 2 +-0.19696777246807814 -0.094446899679563906 0.14097003826823454 2 +0.15691203141331156 0.30969762302154774 0.081647458449763288 2 +0.22303192414196227 -0.2325629726955494 -0.22478002820676973 2 +0.25813294151020727 0.269891400321566 0.20392802183715689 2 +0.22347790556259786 0.24796518821214553 0.0020476406503038263 2 +0.16064572319634424 0.27106992036699162 0.18749495362987376 2 +0.22157078041984807 0.035176393153120093 -0.074702881152452105 2 +0.29667810658055704 0.16158221574094411 0.18482129313008944 2 +0.18744897588704207 0.22899359106984485 0.093442156909164825 2 +0.24161673889482471 0.18060689214013581 -0.0027004988127937515 2 +0.17368746433369148 0.19107965986069922 0.1463713461804006 2 +0.25497485569264522 0.17396820959608206 0.1346270476987308 2 +0.23513233202032124 -0.23681198648001039 -0.12849664291219942 2 +0.21238618119772312 0.18629212272877615 0.016534647018122094 2 +0.21111038583221992 0.031131275438574458 -0.018591995524754074 2 +0.17596981429059205 0.12258887463060697 0.15852947272204893 2 +0.20385219449390252 0.022450425509643195 -0.12037417765747657 2 +0.28617117655722207 -0.30475974789218824 -0.21130391513523808 2 +0.16872275826346742 0.35588070251256076 0.16031395324809186 2 +0.29400486030598971 0.19150016903506273 0.1504752945825788 2 +0.14453205893603613 -0.19701529231540629 -0.18903628990169297 2 +-0.1129229778907709 -0.28689353948803697 -0.10944353482495217 2 +-0.14952679262115193 -0.034650784257502842 -0.084498983579987683 2 +0.18458778191795905 -0.12106095178910725 -0.075094738969978259 2 +-0.17572759128522189 -0.028736318114331805 -0.021966225497966507 2 +0.19828918522806449 0.28505497692183701 0.075836513182666737 2 +0.14941257857537993 0.26026751403462012 0.15358048442403688 2 +0.17306304515173104 0.043156153083674029 -0.012660791420318996 2 +-0.017641590361555742 0.0089950892962917389 0.10237329168228637 2 +-0.15007249788617535 -0.023471789211365696 0.11188899862916166 2 +0.21907204770248639 0.0083867750214685274 -0.063872038058420483 2 +0.16332972570910481 0.38466636423998685 0.22758214711019753 2 +0.17830087206290135 0.4698749786894626 0.072536778871106183 2 +0.27169544818852814 -0.21385254321038275 -0.15658329422087691 2 +0.16831773942498929 -0.017798899020126352 0.17654346285157119 2 +-0.34910608283723205 -0.37790035638110014 -0.19581202767199149 2 +0.11118109259635689 -0.035350366715210711 0.17841713046056834 2 +0.21110313120842683 0.27325252252217613 0.019610864264458842 2 +0.2224016435432728 0.20959802748399106 0.07405023307358842 2 +0.16108799675542157 -0.04355236759382318 0.14294764427065676 2 +-0.23320496535317212 -0.25277442872898737 -0.012303962454855278 2 +-0.27082514771051147 -0.34864785649132213 -0.20446686549066115 2 +-0.30412186400600383 -0.25668284140357589 -0.013198052914795724 2 +-0.25506099006453786 -0.22058999715212391 0.073770896280669823 2 +0.21147722372662039 0.22512564814607783 -0.0060682336099917413 2 +-0.27069530647666262 -0.24648527362011638 0.026659446676775316 2 +-0.27335903849452209 -0.39955276562880937 -0.16375516252839717 2 +0.16838339109736294 0.33190358162052014 0.12937666139514153 2 +-0.22377722078749906 -0.27606094518971397 0.027939429658230965 2 +0.16710173595648503 -0.32582265816348777 -0.012740266864585717 2 +0.12930322220836604 -0.24248024290643119 -0.14530970417857331 2 +0.091526407414745284 -0.44384085010112362 -0.093133109349409632 2 +0.121367013482133 -0.14885328000780484 0.25704320050076268 2 +0.21581595089348915 -0.16007838988840142 0.20784369074099346 2 +0.20907264455471097 0.42971912387221078 0.16943483364484727 2 +0.22623315324808679 -0.061022442130338687 0.089052765692814284 2 +0.061355258739505383 0.014773063682689765 -0.13146455170659205 2 +-0.093824737716906387 -0.44305211316668214 -0.014358387833796959 2 +-0.073951115283133223 -0.48118926468977707 -0.03514989068548563 2 +-0.06792070458557789 -0.038792466622519936 0.066943628681013945 2 +0.2805231919550063 0.17895171151563927 0.19371546581924157 2 +0.2909103142590036 0.22036370613608841 0.20319083518130712 2 +0.25580091070767341 0.25493995997539454 0.18331235421479788 2 +-0.10517474851952542 -0.21294400321504806 -0.090542076195170337 1 +-0.054552041517003366 -0.2623633333966322 0.09327101670791213 1 +-0.18266151244704737 -0.15343572852360443 -0.12591690657108573 2 +-0.12851029320461754 -0.25094043861117649 0.097209843089147069 1 +-0.26042109305526223 -0.42036880334318805 -0.19241204205093843 2 +0.095210987023095814 0.014065541885693825 0.12305616799939598 2 +-0.2654669231253215 -0.31222077427233852 -0.19808149540624376 2 +-0.31817233848986937 -0.29837754072066802 -0.13170707761328337 2 +0.010892013318944575 0.02274405680499559 0.10339251846739726 2 +-0.29869985272055249 -0.23075885583985142 -0.015437564985316498 2 +-0.24070522620981111 -0.27157569237844315 -0.073241465254555299 2 +0.039489180946650909 -0.28196988883868823 0.08621801068966628 2 +-0.26659609245999527 -0.15273598023978149 0.033902899481640304 2 +0.076786543662870521 -0.12780582521820438 0.13052110016159607 2 +0.14853140573760115 -0.057947592645168716 0.16401927798402699 2 +-0.0076241424262361336 -0.04933547998041625 0.14334758147129911 2 +0.14155587790074056 0.058633429772082073 0.14897334508797475 2 +0.22857203992972072 -0.1113856220852206 0.18544487796532674 2 +-0.28744563436788195 -0.38014989834499341 -0.14158691261893736 2 +0.10307532229810264 -0.39225178381748904 -0.090627466692376785 2 +-0.10874778000396521 -0.49462913341321962 -0.036114949745444824 2 +0.27686676304194147 -0.0838127614937898 0.077266015532314006 2 +0.16802255684684098 -0.29391013596987148 -0.039022449153490145 2 +0.21350805651467863 -0.06571635730286457 0.076036276904023481 2 +0.23950616212703546 0.019040872608096109 0.094191533533779112 2 +-0.21260569293772305 -0.30252494274351249 -0.19263800373276491 2 +-0.16351754123415574 -0.44417737673942315 -0.07204640859801531 2 +0.13795882952142319 -0.34646215189908658 0.0081094907501393226 2 +-0.19138153917719469 -0.31732264766722285 0.082621361293523821 2 +-0.17713129372568151 -0.31989160745056777 -0.13075432741223519 2 +-0.094418258450879783 -0.41308406848701784 -0.075096994860168659 2 +-0.11308659916058178 -0.21160565680954022 0.20179314851461802 2 +0.16816190086648283 -0.25229650290468847 -0.12890536954613463 2 +-0.053144001371590505 -0.052667663047122587 0.12392777552307439 2 +0.29260134107299285 0.21704002191317984 0.18210806682741271 2 +0.25300159798865873 0.2099953377434593 0.18424661537405618 2 +0.11912866527071528 -0.19845656933357791 -0.17970232986473561 2 +0.064699969289494952 -0.10271754035530661 0.29859031506497247 2 +0.12905276717720601 -0.14498057003524553 0.26947062441136926 2 +0.17592021968095062 0.3386309928664526 0.22552403624093764 2 +0.13953640854336091 -0.039449449172700421 0.15853607546380427 2 +0.20802598767984709 0.47793007395008991 0.08600640349287382 2 +0.16608376725723911 0.45149089113167346 0.089621515468144619 2 +0.084056328314241008 -0.46834858790027323 -0.039425524571272602 2 +0.12482976929394822 0.015365527449936703 -0.15115413094215877 2 +-0.30585925333291686 -0.40353265518602638 -0.23368998334199259 2 +-0.33391429049891524 -0.41880219350580039 -0.21285377370640429 2 +0.12682684903783625 0.34292350651998538 0.14681031686501028 2 +0.14915884116286476 0.31974260192464166 0.096621402650831051 2 +0.15073121117187968 0.3752158986463987 0.16019560035239028 2 +0.2055168583757622 0.43300749662861349 0.059740985381236074 2 +0.16005000309508877 0.4584246182356766 0.069966242708737331 2 +0.19436810931275117 0.48686904336723402 0.099155803117366353 2 +0.14074405510013624 0.01703236596766991 0.097652676145485479 1 +-0.13721024794265038 -0.21529510114965575 0.18103407638377855 2 +0.15884092230132296 -0.34761411651679214 -0.046900205247555102 2 +-0.16101868424886914 -0.48271338577059814 -0.051202548446643049 2 +-0.080775955055526899 -0.45199056807058996 -0.058506864840120798 2 +0.24221476505106107 -0.069789521602618421 0.093648014175317165 2 +-0.17139571048552754 -0.30336418578832014 -0.17006753310009348 2 +0.25168538657294109 -0.079936288252328153 0.14968849576278079 2 +0.11447964842088892 -0.30361396770284155 0.040953157985155975 2 +-0.23091034736721072 -0.34346098968074601 -0.12186978202218962 2 +-0.21143127427633615 -0.28828979095979579 0.098330103857971224 2 +0.23828788110970914 -0.0062528904698129998 0.11379919390195822 2 +0.17065233376150585 -0.081732523164927712 0.10126576227066739 2 +-0.092263533428878886 -0.26350921868768418 0.1851511865622319 2 +-0.16361762290365695 -0.36638824458062369 -0.036210012315025616 2 +-0.11312264676650119 -0.27027134142593423 -0.14682607646414758 2 +0.15992680093934547 -0.13258792917845677 0.088623171163975334 2 +0.13197997921119192 -0.0046367907194073237 -0.12945741492653196 2 +-0.0098391609057262158 0.038857511837147501 -0.095031808918342536 2 +-0.31113571292537012 -0.26087436039258177 -0.13671452458857519 2 +-0.29339238045739013 -0.29059461825007815 -0.078945289187511286 2 +0.19260153624568122 -0.10063615041789756 0.20950189549115539 2 +0.053860495366996219 0.071219072655742122 -0.081568224813076268 2 +0.11071799896542409 0.037491268215733363 0.16751269786264222 2 +0.1166006962090079 0.047625996558276554 -0.11142137976454594 2 +0.045267456179568691 0.034801425260787514 0.088205814123940324 2 +-0.080524901393568354 -0.13757298237663335 -0.15168015291726525 2 +0.094634459912993199 0.083890787883666662 0.10413012121739498 2 +-0.055954153709140461 -0.072501435601392411 -0.098254239196051724 2 +0.11662165165282259 0.14878792980926575 0.1088331901862668 2 +0.13597608556683502 0.10721986726523966 0.14552903320216679 2 +0.07986917108257241 -0.00048072834388324451 0.20391780609565568 2 +0.14498852469944623 -0.1485767410877063 0.26087953011918397 2 +0.2812802375762446 0.23929240273713503 0.20590296313421069 2 +0.14989125941951847 -0.10671626657862569 0.19629024100442377 2 +-0.085143726539245956 -0.46676360105676473 -0.022830658562516044 2 +-0.091302340252339936 -0.44473255885099583 -0.092354846083195302 2 +0.22308430598641199 0.25911869190057391 0.21156215542145618 2 +-0.14016687407774903 -0.48272541464390523 -0.020657744277600948 2 +-0.13872814667135025 -0.4739124625704616 -0.083798036845673995 2 +-0.14614439284202524 -0.41089706960018157 -0.075466849148792217 2 +0.11609773065467957 0.37831002340919484 0.20869117460047493 2 +-0.026220063093269168 -0.028221358083769108 0.1361449405307632 2 +0.270767769610751 0.20745404105977944 0.16038897287208256 2 +-0.26152602112421341 -0.37699086667265969 -0.15193245317146206 2 +0.20132453085716523 0.28741394400179043 0.033033499907365482 2 +0.14514725323002647 -0.029350359562717178 0.12845236252048267 2 +0.2338037315360062 0.22829557609604745 -0.002934723772483501 2 +0.17672376001916229 -0.048948219102888248 0.12737623746452992 2 +0.26053630506803427 -0.24635502275113183 -0.15045309175652619 2 +-0.31945013292933688 -0.33966489952618439 -0.18514555745743436 2 +0.23609471655636327 0.19415522844621899 0.053047081296913642 2 +0.19337034218029367 0.26978469548761658 0.014223358188876489 2 +-0.2832481798459886 -0.32818261060975762 -0.20144681778771545 2 +0.23162517093366911 0.21907020793671789 0.091282385490085272 2 +0.25285187347456572 0.061083495649395157 0.02131201676587028 2 +0.14677417671301024 0.31696468441083481 0.21007412098215505 2 +0.16791540522940657 0.45058823482986665 0.11745945475421429 2 +0.073576523731695695 -0.11777043380887145 0.26648949151744616 2 +0.1399658874009086 0.32381135704587688 0.14274016675118145 2 +-0.1367139551421418 -0.49888543711634536 -0.023842288283966173 2 +0.1638611465358692 0.45050466781215759 0.18870917790219072 2 +0.11379040698708984 0.34425309076699984 0.18509727292413303 2 +0.10392940665459371 -0.12746642008512687 0.28480748115663046 2 +0.18758482777947222 0.33076136894680619 0.22087379570957902 2 +0.30601068886158711 -0.12259321657355776 0.10620690381273334 2 +0.11661508235775558 -0.32708229372871223 -0.072848648208631378 2 +0.15751489462184776 -0.45025454549570698 -0.02859580928503103 2 +0.15511670898961036 -0.38229476412395952 -0.043890618422594022 2 +0.078802920414637254 -0.41447806844578811 -0.080087474423966562 2 +0.13604702340327635 0.023539324792672324 0.012262978606071404 2 +0.12208875808388797 -0.37407625012304724 0.0031519028224216809 2 +0.15413549735365045 0.082615147775305542 -0.015437943873442952 2 +0.17697469250952103 -0.27254620823906439 0.0037415016621191802 2 +0.10499209966181434 -0.16467123845789833 -0.029655512517943784 1 +-0.13569950816929272 -0.11041659017066571 -0.037913148410714387 1 +0.020946401199414391 -0.070250411831398671 0.063607215283314728 1 +-0.13060405646650239 -0.15170819377219241 0.11578713962907758 1 +-0.071775125036155504 -0.10829755829603843 0.079431416859240322 1 +-0.17277376622886392 -0.22972953143416119 -0.090267475797980362 1 +0.19349909694008477 -0.085493911510823223 -0.041783569750484618 2 +0.20629042232302136 -0.19583190662618677 -0.077188094192034581 2 +0.27885248870461421 0.20329492770558161 0.20784435167460497 2 +0.18869522497574787 0.1506667622172112 0.15155569283614517 2 +0.24149724528237104 -0.27143934489121879 -0.16551323846845073 2 +0.20298819857724609 0.29714119376098969 0.17081860437633661 2 +0.16050135432757315 0.2521565420515266 0.11887720031480789 2 +0.23529592870052368 0.01788719479004653 -0.043486295237758626 2 +0.20633692202471124 -0.15811438899480779 -0.099753968078173355 2 +0.21813044820871313 0.16378401875871199 0.0048534689405535965 2 +0.23280334410401426 0.21255227252051562 0.11196743233186653 2 +0.24685045297933289 0.20585404337113 0.01500875350066096 2 +0.24362789173945495 0.09026438354597556 -0.0094789445549943313 2 +0.19271001737810567 0.026831952858393911 -0.037870671233914535 2 +0.18654051244431225 0.072833024835378332 -0.017964269027904586 2 +-0.12245886710405257 -0.0283376976330749 0.10536346859723184 2 +0.21669004643381923 -0.022404231331745968 -0.13999598138031988 2 +0.12657213518788576 0.33869000100629404 0.21191436739044001 2 +-0.22051437980213551 -0.096599709885944934 -0.049239804483389799 2 +0.2751631145554192 -0.27544336114409018 -0.2762821230229584 2 +0.18631310162046139 0.046736512776564994 -0.079577951722127352 2 +0.26671789767742671 0.23412133227080464 0.17324290419979765 2 +0.17653627900076746 -0.22718833642161851 -0.2050380585888823 2 +0.18305702740239282 0.29568240772718829 0.12717564278633542 2 +-0.10981038819828388 -0.31203264311432011 -0.076527003684572589 2 +0.19951046812153295 0.25750995571634783 0.18250317693637441 2 +0.22603718647405927 0.04151632301760827 -0.049741923616752157 2 +-0.051592268272055541 -0.35635699094857143 -0.024117767607751604 2 +-0.012176171546605311 -0.29638138337595893 -0.090473852809194427 2 +-0.22041019474336176 -0.080557779494975029 0.090508893889423667 2 +0.2599945060661597 -0.32587719875865906 -0.25643182449041269 2 +-0.26738115255354222 -0.38238293398000966 -0.24087414750202468 2 +0.27313383000476987 -0.14044733689637356 0.14991499856926324 2 +0.23540387788928546 0.0043240084988720676 -0.1235733166501729 2 +-0.016468022421614669 0.093352233085412628 -0.048171567090055809 2 +0.28931903815189669 0.12413502473757146 0.15440048258752401 2 +0.21262131064951512 0.27607088311268468 0.047867641835512093 2 +0.2201428034550702 -0.26825026933074664 -0.20202863061119114 2 +-0.28789220454974407 -0.25484758612157843 0.0077708917459521128 2 +0.13395572922529919 -0.020740367211262288 0.15005179194429977 2 +-0.23606060386581154 -0.26303046025646826 0.062201323409697154 2 +0.21747794672285209 0.23455108303610428 0.096934048098721803 2 +-0.29883217013665964 -0.4199650757159748 -0.1646450543357153 2 +-0.25823662088423815 -0.25195451533764124 -0.029415462900796316 2 +0.23767478126851532 0.028331969906645812 -0.062160790031803886 2 +0.19488426615179444 0.25109989404590616 0.012201210304890103 2 +-0.29819836441177605 -0.32276383143669163 -0.18329723051189861 2 +0.25273787405633175 -0.20338145164889071 -0.20331469806721358 2 +0.17184242479236561 0.32444663791958606 0.22418446044383272 2 +0.13142416692767378 0.34348745339696174 0.12372306192390084 2 +0.1103500869250402 0.0038975478540282261 -0.15269812703641794 2 +0.05232529002373916 0.051696406518048771 -0.11202172986217201 2 +-0.31929391092526027 -0.29776572664189827 -0.061911244983114969 2 +0.28412882806993978 -0.11186304566403202 0.089712106183824886 2 +-0.33079227670298628 -0.27769130260344599 -0.14239928091173754 2 +0.0047104593304771389 0.036546396163942563 -0.11729835063655522 2 +-0.12510091189125427 -0.19451236809676176 -0.1587446702148162 2 +-0.29689099785784928 -0.32181295659052522 -0.13153800675644967 2 +-0.28324482404784557 -0.2565847189212635 -0.14243224538122382 2 +-0.33680912554157494 -0.29966404863171431 -0.10953306086980368 2 +-0.2287557373436451 -0.2696839724845555 -0.18078157797105454 2 +-0.31208962266128781 -0.27185674704759744 -0.1008075244534285 2 +0.018841800746658595 -0.048326384358117501 -0.041484900510307662 2 +-0.25230881845076092 -0.25211537585101551 -0.10045122191361811 2 +0.29972089788346656 -0.065794775870217148 0.093172967310065274 2 +0.11207094404581555 0.088374652643674237 0.13252755392562171 2 +0.14607946318428505 -0.074969406187235799 0.23053958848989375 2 +0.18325486015560449 -0.16046820047019561 0.22785391280810732 2 +-0.079564802011580088 -0.48518525947741636 -0.050939928508336632 2 +0.24795843093386016 0.25417300164342083 0.22690857446019425 2 +0.22620516235236138 0.29374443820094276 0.19926670951626169 2 +0.094180343767390623 0.021165685396087479 0.1815600563649164 2 +0.13561776219874888 0.40179583603060998 0.22154455050704591 2 +-0.083595946514637198 -0.42338216095376358 -0.01345885392302733 2 +-0.14835168870957835 -0.45109594538246756 -0.092189877212729088 2 +-0.12016726313566953 -0.41107179984411013 -0.085801377003063145 2 +-0.11221360447474224 -0.47447605287979638 -0.015392203045314684 2 +0.21816589472291534 0.25329526179387196 0.16855780583704968 2 +-0.16622400831702561 -0.45678853544918807 -0.048843089401048201 2 +-0.14314525055237559 -0.098613971270357037 -0.1287987181474573 2 +0.25524614341864049 -0.024779170164568848 0.062152484683099168 2 +0.040054321053891791 -0.098228095410583485 0.2827994906364435 2 +0.05128999037916971 0.028996856920011756 -0.13778822570215077 2 +0.18299733474945012 -0.012849733410083154 -0.15425281696345322 2 +0.28743154340358101 -0.14973561218771375 0.12207145738449718 2 +0.1191316512145668 -0.049294760836535279 0.23182829997862442 2 +-0.23884303317040212 -0.31693703619529534 -0.095396056958468867 2 +-0.30553713750960843 -0.28461956491887841 -0.035907830442315838 2 +0.27819134315279204 -0.053208567487236812 0.11163434347466766 2 +-0.3311874887723813 -0.38563101204306571 -0.15325151317526389 2 +-0.30694739705722479 -0.30631648653187865 -0.076456304685725854 2 +-0.28366263642031553 -0.29791009797507684 -0.18077625537750297 2 +-0.28775042092530345 -0.24795835732140475 -0.039286014804769856 2 +-0.026237924945676575 0.067392755713716987 -0.093219110533731775 2 +-0.28220758345745922 -0.28716703918168524 -0.10066550594368286 2 +0.062184696392953279 -0.052882382836561222 -0.060954460051830646 2 +0.29634743071540909 -0.29114397418854693 -0.30023965542949094 2 +-0.35839076030451911 -0.41408374809439552 -0.20938689365481022 2 +0.18791494460605807 0.30850522569643501 0.072355302429205251 2 +0.27978804215494879 0.099796254981485061 0.12112046791312236 2 +0.32399570006021106 -0.32159781401030352 -0.22516097994759834 2 +0.32006977505956136 -0.25235054060382422 -0.20634389755998001 2 +0.35142085179843868 -0.28615148140156327 -0.25731122660834815 2 +0.097496043812938249 -0.019864586794476662 0.12787190991338004 2 +0.26986939373030888 -0.32493612584057863 -0.22845560738219681 2 +-0.29061266319935358 -0.42546460735415675 -0.19364889528253681 2 +-0.26700067915427217 -0.4030559559383507 -0.22743353400530161 2 +-0.2745636285793468 -0.37327517649378306 -0.21599681521022307 2 +-0.32816793714640058 -0.37298888533867613 -0.22293035616893131 2 +-0.15159182224364162 -0.298278410435246 -0.067617936933549352 2 +0.17454322709208311 0.28617024940308039 0.044818185104404079 2 +0.14550963262661376 0.15268010420012909 0.056029793900859201 2 +0.05484628558714244 0.066108055014554801 -0.00088426911392277575 2 +0.11766878215068405 -0.13806049831193518 -0.14143550385451042 2 +0.05127664439746879 0.085568478961957267 0.019640226963889146 2 +0.044251618305719664 -0.26263603446992845 -0.10004354230951709 2 +0.22766348862868568 -0.1509436792707945 0.16487429059114261 2 +0.23591518580276211 -0.010732029156158188 -0.096123025621806246 2 +0.24022630126562156 -0.012951062836471045 -0.1274444610621383 2 +0.077968506217267072 -0.18668785924050951 -0.15756367166394614 2 +-0.048016965413053316 0.079247180987072272 -0.042298799183003513 2 +0.18747835514662653 -0.071535699512999637 0.094354842658464333 2 +0.20614716784991138 0.24622966667856372 -0.00039974782235116177 2 +0.23777480201361836 0.20590467493185927 0.081539763051023936 2 +0.13835588467181176 -0.016363898007613266 0.13517196899172201 2 +-0.34235861280725532 -0.38949317008435402 -0.22839049825390834 2 +0.15152623704661683 0.33922298033061948 0.096999369645983172 2 +-0.24430119817124546 -0.4074321099847017 -0.1996209300125216 2 +0.17296370135371783 0.32279278029872249 0.077080229776626652 2 +0.20360262282462988 0.27838806481484835 0.12924656390648165 2 +0.32112618072297971 -0.24048102940845292 -0.23270281025573264 2 +0.18801588075464221 0.30443417918383253 0.090693541146569287 2 +0.1614559332335227 0.2801422642123752 0.1233890113751023 2 +0.10771626183082574 0.021318342965022649 -0.14724881005793813 2 +0.17670217997280191 0.47679555277470287 0.10423411524382481 2 +0.10305009152486791 -0.47359058736195353 -0.031020054547323456 2 +0.090249508693367481 -0.42377725652529563 -0.024382170126919386 2 +0.21747791546184525 0.45927293518613721 0.12955380593207536 2 +0.20330366366907929 0.45063989548004346 0.1711338509809669 2 +0.14674200058704417 0.35506830070134238 0.143590779376393 2 +0.18628065669804866 0.42445092828094688 0.11749633058361264 2 +-0.34422788275911365 -0.40546838258613416 -0.23154119887912816 2 +0.16123856164736461 0.30539194778029999 0.10239822217421587 2 +0.14505908723994027 0.32402079816212215 0.12068714485211952 2 +-0.32429462249798335 -0.39865755335181996 -0.24514526019585325 2 +0.075873139474289281 -0.31775468293576437 -0.010323413048527737 2 +0.088874918334233555 -0.33071206029313849 -0.072762880333503463 2 +0.16727461625833223 -0.44321507767790647 -0.07769259681439189 2 +0.080288439192786679 -0.080884303587738071 0.29217988435705966 2 +0.12736821885227806 -0.45205825641168645 -0.074431306179505108 2 +0.17040715670941781 -0.44352705241859691 -0.046139543571084726 2 +0.063923567147952998 -0.29185612996350285 -0.010522002240140868 2 +0.20662954020841018 0.43678261452165223 0.10461448597305215 2 +0.21879085916810997 0.46283984382139143 0.071548130253280579 2 +0.1899832487058879 0.43501986056850106 0.070363353177037999 2 +0.23401011822815651 0.45501699771658899 0.068665534383014287 2 +0.22959440580109164 0.46144407629858541 0.080142739898506968 2 +0.22042236993263731 0.46033567457330515 0.10408371170171724 2 +0.17749277615852624 -0.0023166818898972506 0.06930030430887546 1 +-0.093366583606958195 -0.25083224702815082 -0.03304799690577695 1 +0.061769231273037711 -0.028099029985494416 0.23232816129945244 2 +0.16977849048512611 -0.1151101044826674 0.23528207557779765 2 +-0.005286296633443998 0.048874271308378014 -0.061606960806945249 2 +0.17400992108455482 -0.0096953839824609096 -0.11766017989900962 2 +0.19712961190269113 -0.16258987076692061 0.20213036998146572 2 +-0.09070693617761813 -0.40634131103447424 0.021101369962956647 2 +-0.15388672351320237 -0.44891552657348155 -0.026694332218256213 2 +-0.015448907173864827 -0.3148029022193547 0.12308983086477923 2 +0.15633577732708345 0.11454001976975489 0.16205512305139835 2 +-0.16357701589971624 -0.39239471440416185 -0.016185174168993375 2 +-0.18484932812405949 -0.033443577420721619 0.10507503132061229 2 +0.26299860333442671 0.18312981284152979 0.17590481673391928 2 +0.24658058467563379 0.23000592608687892 0.20979867907575112 2 +-0.041457461687826269 -0.017546298819411301 0.11384343297606225 2 +0.15731796654015939 -0.41245141711383204 -0.058976974467509852 2 +0.18246669567637022 0.3580934247159816 0.20047827441198285 2 +0.31083859526681118 0.16852915195275253 0.15946301871890106 2 +-0.17428937797151617 -0.025560084632103675 0.043451742243966626 2 +0.28428650281965118 0.16885231968298209 0.12870708866872232 2 +0.14206996244275485 0.28128597896998481 0.16985566296004367 2 +0.1505467441398452 -0.22827356284095546 -0.18651889085232409 2 +-0.087713751565045975 -0.27452982575667495 -0.12646798659540945 2 +0.15422915181816776 0.043548925258866916 -0.018511373114010667 2 +0.22528029555550033 0.13035157152172816 0.0019506436301192436 2 +0.16077865079522552 -0.25411591518228893 -0.054050648331689585 2 +0.19713984788133115 0.18113867904280595 0.15573459527708966 2 +0.17915789686463079 -0.25737498778075341 -0.020300539989141581 2 +0.19132994603171183 0.13555260687214532 0.0052601089222675057 2 +-0.15233708995395431 -0.49132863876096561 -0.034752070454848696 2 +0.079373737585506254 -0.1266141821655003 0.28907484013264795 2 +0.29721814517302303 -0.1326426521540621 0.12038193709577319 2 +0.11421889695445991 -0.14433747740866776 0.2723082789948541 2 +0.17755916117006043 0.3438241287792605 0.2117412930482841 2 +0.06465915191105423 -0.060091073075840148 0.28300648872187401 2 +0.059794853137681708 -0.11813015406748552 0.28365428253402425 2 +0.18108425195892142 0.32884805969821418 0.23141943402664703 2 +-0.055825576985707115 -0.11600560897067243 0.0080147793226470407 1 +-0.0076668925649968876 -0.14240196715135192 -0.037048707575109849 1 +0.34134119165345966 -0.28836009096698156 -0.29137201292612591 2 +0.29609861106397523 -0.3350496879375981 -0.23798512825555485 2 +0.17168596390897656 0.28931545603151521 0.066188391523012591 2 +0.3289839344831722 -0.28867367634627794 -0.22131677094364505 2 +0.12771436156246346 -0.12815948776228164 0.22995959475601535 2 +0.27028995185193327 -0.30787987431206576 -0.28262814491836941 2 +-0.18044573413955653 -0.29620546275228826 -0.070940085337672612 2 +0.24834956880297446 0.071144500104440289 0.13319521468299911 2 +0.23141242860246775 -0.0064249794145492976 -0.14215484854064975 2 +0.20702050458260382 0.26154726003518303 0.061236662989526264 2 +-0.17937064939966921 -0.042534519639293319 0.13273329883800272 2 +-0.28950378272484034 -0.40990150292079369 -0.22002289946638776 2 +0.15588939064086324 0.23658227870933246 0.14111471395118602 2 +0.26119633738610476 -0.29775263704151045 -0.22027613437570426 2 +0.1183235233164882 0.004091017155171928 0.14076360731885335 2 +-0.12989825508467523 -0.29513032662980215 -0.087923891448296071 2 +0.28753467381453701 0.11413034785729728 0.13722592392713406 2 +0.083331989117098021 -0.037391361646440024 0.20363731465024382 2 +0.067769858129125504 0.096509238137286235 0.0022383512213153198 2 +0.12331281052985855 -0.17300887782787921 -0.17136923772489532 2 +0.23378043493962547 -0.018390979506791139 -0.11114943943443005 2 +-0.032370117629393694 0.094969625045398978 -0.034833399641079621 2 +0.032526504586819049 0.078591640514195857 0.0077498324328937381 2 +0.11627570939259102 0.15485609047720922 0.083905038027668646 2 +0.24343953278781336 -0.13845567974632589 0.18074275827397168 2 +-0.02113867136231912 -0.22797278881261643 -0.15180870349359007 2 +0.23788157091471779 -0.0039655367242016036 -0.082557475644628731 2 +0.044270811731903961 -0.22285291166188154 -0.13119085227671112 2 +0.23912748639490489 0.19411529839658875 0.094394674936596645 2 +0.12382958164291305 -0.018798976317582733 0.12861598731992441 2 +0.20708384805575442 0.26216625738808652 0.0069829293170528117 2 +0.17609630071126664 -0.060965272092391068 0.10826763961319426 2 +0.16280642176774068 -0.040293538924567072 0.12697312249844522 2 +0.17886376968565332 0.31949841974502563 0.097188317999109292 2 +-0.25041899807016799 -0.4050626034700624 -0.22050477724045686 2 +0.18463346360860339 0.2699226074846065 0.1143999842154646 2 +0.35778495519541603 -0.30581178211828763 -0.25485280877238092 2 +-0.32524083936870501 -0.38491686412107162 -0.2421607233248001 2 +0.19261656064467497 0.28229815079902465 0.023165590886271931 2 +0.17931114905652801 0.29823232337503902 0.041144397531892342 2 +0.30397018844025991 -0.24350918996915752 -0.25579600708637756 2 +0.2241150808576069 0.44876624908599283 0.081477579631921093 2 +0.21455195885032718 0.45126775299995081 0.15250784401531456 2 +0.088208240081410108 -0.44963791010522985 -0.029856528244131361 2 +0.17963864579236782 0.47067989822285372 0.13411582314867759 2 +0.089758106682891428 0.017969796202201873 -0.14978023074957211 2 +0.18749787280425526 0.43378420826846997 0.086970097855174774 2 +0.18188923811851138 0.30462371778296704 0.10878659303481478 2 +-0.33809315389018457 -0.39623576186024334 -0.24361399123617189 2 +0.33350714115391589 -0.26308129271947744 -0.22651052061405544 2 +-0.25851530207840001 -0.39476751034716095 -0.18852779593344371 2 +0.15338152026331908 0.34497938431146336 0.11873904314686629 2 +0.17031894137659037 -0.43407298892631696 -0.062150383396905665 2 +0.090987240658302215 -0.29666747850989073 -0.068851310613028738 2 +0.16197088700371692 -0.45981113218548419 -0.049204211577153351 2 +0.14180807706880988 -0.40776359087035674 -0.082791252593540005 2 +0.078502780399479777 -0.36233656939529102 -0.069865196178235861 2 +0.077311525443190102 -0.35396499120983949 -0.025981480132187706 2 +0.16822482217549797 0.30525736523675584 0.20947971294068657 2 +0.037591594352661781 -0.069560869538039069 0.26950879618086099 2 +0.052962246835118187 -0.079619756099208738 0.29571037644973508 2 +0.039379422944850147 -0.30380019068410657 -0.0022460635413450647 2 +0.14899901385395187 -0.4421305052350738 -0.086494711509666464 2 +0.073039682170677078 -0.30035546931741208 -0.048989070650285127 2 +0.069761218369263495 -0.27268861252375381 -0.080059538830640625 2 +0.16712085405737268 -0.44864493148085771 -0.063710588479465396 2 +0.16037910904193342 0.31910763648104867 0.071549119569212338 2 +0.13989883075563619 0.34553214489888306 0.11058825853334087 2 +0.14268669305734083 0.35349257579921256 0.12842183157976905 2 +0.022598981183789814 -0.14192578337391035 0.025080867872095285 1 +-0.12954694169158271 -0.13155947998618406 0.045919338756688612 1 +-0.048144236195062577 -0.19928223802331269 -0.046391789370345653 1 +-0.098654008563826071 -0.26239879946071681 0.03649830833274624 1 +-0.14659369145613071 -0.20566298727598128 -0.030377061745172934 1 +-0.059612413145850779 -0.18655339706512131 0.075090359456422853 1 +-0.16622649314289922 -0.2104008434140906 0.056680696763818733 1 +0.033247391456197775 -0.19517449005180568 -0.054864885610015263 1 +-0.025811849996295173 -0.25769195331976635 0.0036049694581046926 1 +-0.10439826056866382 -0.31502457177567128 -0.0077860001893650388 1 +0.13554323267633231 -0.10033192646291991 -0.001657243998269789 1 +0.073611971261573469 -0.11792468618381965 0.063239829617899632 1 +0.083874576140061191 -0.012953620419417205 0.22773943150843479 2 +0.090724404047686072 -0.017939710877847279 0.18530576301401813 2 +-0.32506207175243917 -0.41289002878193504 -0.15708272243670598 2 +-0.32064222176987367 -0.2863505331075924 -0.047005264032324197 2 +0.28117374602229561 -0.15150194804212477 0.13858924666892664 2 +0.22371568327014668 -0.074422685673094569 0.1106940722858282 2 +0.20340055358053122 0.4764650631694366 0.11926834793927318 2 +0.13835210988036545 -0.42663412733117995 -0.10427639567985784 2 +0.078168969404720567 -0.46241224597936981 -0.059148414198549423 2 +0.188735697930143 0.40112690935203321 0.15905246304148601 2 +-0.10342091089199335 -0.42641460587004143 0.0046186106592802818 2 +0.075420403108526213 0.017979581579671319 -0.14679847386583034 2 +0.20403893883033622 -0.076501655119799561 0.13047163542967258 2 +0.14681213139259655 -0.026256770826613776 0.14349699665531357 2 +Triangles +1871 +778 219 472 2 +472 1017 778 2 +195 846 362 2 +985 862 1001 2 +1001 862 520 2 +547 465 600 2 +695 392 398 2 +392 283 398 2 +191 919 923 2 +919 745 923 2 +988 999 475 2 +475 999 883 2 +324 307 681 2 +246 109 617 2 +430 2 443 2 +872 477 160 2 +298 661 432 2 +255 545 992 2 +702 366 963 2 +674 188 791 2 +127 169 227 2 +169 114 227 2 +842 968 289 2 +881 480 997 2 +151 959 316 2 +612 774 174 2 +774 585 174 2 +711 204 150 2 +204 711 300 2 +550 921 212 2 +479 725 622 2 +622 989 479 2 +723 988 886 2 +208 360 773 2 +196 550 212 2 +270 749 197 2 +143 73 70 2 +938 119 690 2 +145 682 427 2 +693 255 761 2 +124 142 568 2 +253 652 386 2 +111 99 228 2 +307 73 142 2 +901 103 447 2 +447 82 901 2 +770 955 258 2 +367 609 581 2 +306 315 190 2 +441 235 669 2 +102 235 441 2 +736 299 137 2 +191 748 919 2 +763 536 3 2 +308 7 8 2 +333 311 205 2 +205 144 333 2 +793 473 421 2 +473 793 328 2 +233 70 142 2 +279 462 808 2 +129 301 746 2 +212 301 129 2 +243 799 170 2 +212 761 129 2 +773 542 339 2 +339 357 773 2 +302 548 131 2 +548 742 131 2 +667 69 249 2 +454 484 346 2 +585 583 776 2 +142 233 101 2 +178 148 313 2 +699 551 907 2 +559 551 699 2 +71 235 175 2 +235 71 669 2 +737 136 94 2 +720 277 454 2 +331 779 580 2 +961 851 437 2 +851 961 151 2 +529 800 824 2 +582 774 118 2 +118 823 582 2 +3 763 103 2 +797 244 225 2 +244 795 225 2 +425 440 170 2 +170 243 425 2 +974 755 290 2 +264 755 974 2 +271 753 718 2 +181 800 824 2 +138 302 332 2 +797 830 676 2 +830 797 322 2 +229 539 431 2 +117 822 378 2 +551 216 502 2 +302 332 578 2 +578 548 302 2 +172 497 230 2 +130 270 567 2 +567 270 197 2 +898 4 351 2 +757 689 296 2 +689 757 637 2 +1017 825 412 2 +899 752 209 2 +470 1015 896 2 +687 1015 470 2 +86 443 430 2 +119 326 900 2 +572 221 524 2 +581 224 329 2 +133 762 182 2 +867 834 864 2 +310 356 129 2 +75 269 953 2 +953 269 639 2 +407 821 467 2 +330 352 529 2 +224 662 632 2 +662 224 628 2 +237 668 672 2 +193 87 78 2 +87 193 304 2 +369 617 690 2 +124 909 568 2 +909 80 568 2 +740 208 552 2 +81 531 671 2 +296 602 543 2 +621 421 700 2 +95 319 251 2 +334 570 960 2 +979 493 869 2 +440 605 152 2 +152 792 440 2 +412 422 825 2 +269 855 75 2 +341 855 269 2 +449 587 759 2 +996 481 1022 2 +883 481 996 2 +190 7 306 2 +305 749 197 2 +869 647 786 2 +230 172 88 2 +367 224 581 2 +583 433 85 2 +692 633 660 2 +407 226 821 2 +208 312 635 2 +69 442 667 2 +682 427 792 2 +850 956 309 2 +956 259 309 2 +202 678 496 2 +795 610 250 2 +91 121 134 2 +121 686 134 2 +661 624 374 2 +188 371 512 2 +636 909 698 2 +100 433 445 2 +300 748 919 2 +357 211 557 2 +211 357 740 2 +398 692 283 2 +692 398 436 2 +424 782 706 2 +336 202 496 2 +719 89 273 2 +282 150 460 2 +7 190 156 2 +774 582 612 2 +663 824 442 2 +498 178 313 2 +739 180 216 2 +240 679 327 2 +679 619 327 2 +7 156 308 2 +302 318 131 2 +318 91 131 2 +698 618 636 2 +618 227 636 2 +722 987 882 2 +898 320 139 2 +197 305 242 2 +819 355 387 2 +391 355 819 2 +1018 788 408 2 +788 1018 469 2 +420 899 819 2 +857 668 965 2 +698 80 618 2 +538 799 170 2 +125 619 327 2 +532 634 231 2 +448 395 596 2 +79 736 141 2 +154 136 737 2 +483 725 622 2 +960 853 256 2 +209 853 960 2 +69 323 528 2 +181 423 418 2 +765 228 111 2 +899 242 305 2 +429 515 809 2 +110 613 779 2 +613 580 779 2 +587 985 875 2 +665 415 421 2 +458 688 641 2 +115 393 948 2 +986 883 999 2 +473 328 422 2 +422 328 706 2 +636 227 127 2 +498 199 313 2 +332 132 338 2 +338 207 332 2 +500 562 230 2 +230 564 500 2 +775 860 1028 2 +938 510 119 2 +194 354 935 2 +237 120 668 2 +242 673 373 2 +257 342 304 2 +203 342 257 2 +243 796 425 2 +356 129 813 2 +103 434 171 2 +85 446 433 2 +691 515 406 2 +266 768 1019 2 +199 87 304 2 +966 579 1028 2 +518 967 862 2 +864 967 518 2 +523 889 522 2 +400 803 900 2 +803 400 241 2 +249 69 125 2 +946 131 742 2 +913 501 88 2 +672 1 77 2 +1 176 77 2 +614 903 171 2 +903 614 430 2 +320 898 674 2 +8 203 850 2 +79 831 155 2 +254 461 275 2 +259 4 261 2 +4 351 261 2 +962 710 746 2 +81 252 792 2 +92 284 839 2 +121 686 801 2 +91 121 685 2 +1020 530 595 2 +562 379 497 2 +887 995 428 2 +148 133 750 2 +826 408 788 2 +408 826 676 2 +722 478 163 2 +478 622 163 2 +989 481 1022 2 +141 345 137 2 +579 643 617 2 +182 711 748 2 +400 593 900 2 +155 849 153 2 +83 987 722 2 +263 247 791 2 +696 527 629 2 +187 553 745 2 +745 553 138 2 +904 113 686 2 +113 619 686 2 +674 791 413 2 +246 1027 704 2 +632 359 438 2 +949 845 760 2 +845 146 760 2 +309 202 336 2 +219 472 841 2 +291 219 778 2 +313 199 87 2 +291 219 841 2 +534 631 439 2 +739 921 301 2 +301 216 739 2 +835 204 314 2 +355 942 769 2 +901 1025 809 2 +412 422 575 2 +234 2 443 2 +954 256 853 2 +962 710 859 2 +754 426 74 2 +74 500 754 2 +373 448 315 2 +363 968 289 2 +284 80 618 2 +736 137 141 2 +266 1019 820 2 +1019 411 820 2 +842 289 767 2 +467 1015 896 2 +588 776 439 2 +112 127 751 2 +636 127 112 2 +360 758 773 2 +758 542 773 2 +146 670 696 2 +1016 687 470 2 +745 549 213 2 +327 226 574 2 +311 333 783 2 +783 542 311 2 +426 74 605 2 +74 815 605 2 +884 273 640 2 +485 452 714 2 +494 198 335 2 +335 835 494 2 +775 948 115 2 +676 469 248 2 +764 428 3 2 +300 503 494 2 +503 72 494 2 +834 565 348 2 +949 845 359 2 +116 92 616 2 +156 190 918 2 +474 526 991 2 +73 177 307 2 +747 132 707 2 +525 890 653 2 +890 522 653 2 +555 739 134 2 +134 739 91 2 +686 619 801 2 +276 924 659 2 +124 909 466 2 +256 334 960 2 +350 334 256 2 +218 589 625 2 +589 218 492 2 +620 958 504 2 +524 521 221 2 +213 300 919 2 +300 213 503 2 +921 739 550 2 +81 671 917 2 +917 236 81 2 +922 625 218 2 +268 177 344 2 +177 268 307 2 +320 139 306 2 +602 813 464 2 +763 429 103 2 +139 7 306 2 +750 748 191 2 +625 589 658 2 +658 722 625 2 +979 493 1026 2 +493 818 1026 2 +77 237 672 2 +408 380 676 2 +715 879 785 2 +737 144 552 2 +144 573 552 2 +196 946 550 2 +753 281 712 2 +821 226 802 2 +675 322 797 2 +448 371 315 2 +373 448 395 2 +326 690 119 2 +388 741 449 2 +427 145 316 2 +316 145 495 2 +637 689 601 2 +682 145 317 2 +346 255 484 2 +255 992 484 2 +433 104 6 2 +559 914 551 2 +680 787 493 2 +115 576 1016 2 +385 452 714 2 +123 110 444 2 +439 229 534 2 +229 439 539 2 +951 470 896 2 +914 198 551 2 +797 675 244 2 +973 293 846 2 +293 973 348 2 +210 838 983 2 +1017 412 96 2 +122 100 232 2 +100 445 232 2 +624 461 789 2 +673 899 242 2 +626 595 401 2 +595 661 401 2 +678 178 498 2 +552 740 705 2 +113 125 180 2 +802 897 89 2 +916 639 535 2 +608 324 140 2 +185 279 808 2 +861 844 971 2 +538 613 110 2 +81 427 792 2 +330 266 352 2 +234 616 77 2 +192 672 173 2 +620 349 663 2 +409 76 613 2 +532 669 441 2 +554 345 130 2 +6 445 540 2 +124 101 142 2 +789 624 661 2 +242 315 373 2 +349 768 958 2 +274 976 874 2 +873 893 450 2 +835 361 941 2 +361 180 941 2 +338 195 362 2 +898 351 238 2 +196 566 946 2 +405 379 497 2 +573 783 333 2 +930 714 925 2 +915 545 712 2 +397 629 810 2 +688 897 89 2 +750 748 182 2 +750 133 182 2 +237 616 77 2 +922 154 920 2 +920 154 215 2 +515 660 406 2 +391 355 942 2 +942 752 391 2 +136 321 154 2 +1 321 136 2 +114 227 5 2 +227 116 5 2 +530 1027 1020 2 +798 233 70 2 +433 6 445 2 +827 377 106 2 +402 738 908 2 +908 805 402 2 +236 427 959 2 +754 537 426 2 +351 856 955 2 +537 444 426 2 +415 117 421 2 +117 793 421 2 +752 899 819 2 +755 339 264 2 +245 370 647 2 +780 743 334 2 +743 570 334 2 +777 578 710 2 +397 629 814 2 +742 548 969 2 +325 298 432 2 +588 439 539 2 +610 793 250 2 +552 312 208 2 +528 323 677 2 +906 499 228 2 +927 719 385 2 +458 719 927 2 +184 141 130 2 +263 496 247 2 +340 4 259 2 +128 264 783 2 +667 509 442 2 +442 509 824 2 +228 906 501 2 +253 516 650 2 +107 365 764 2 +175 82 235 2 +235 82 447 2 +810 398 436 2 +447 235 102 2 +99 228 913 2 +73 70 142 2 +501 913 228 2 +441 102 533 2 +107 536 764 2 +271 712 753 2 +572 221 644 2 +221 655 644 2 +955 261 351 2 +437 341 535 2 +315 242 190 2 +798 233 251 2 +251 233 172 2 +328 793 377 2 +260 855 75 2 +704 120 965 2 +120 704 966 2 +79 155 153 2 +249 303 627 2 +627 667 249 2 +376 795 250 2 +106 243 796 2 +796 827 106 2 +84 615 123 2 +325 294 432 2 +95 495 319 2 +161 727 157 2 +157 724 161 2 +272 383 462 2 +383 279 462 2 +81 427 236 2 +200 627 303 2 +225 795 376 2 +831 70 143 2 +241 677 897 2 +747 503 549 2 +505 192 173 2 +736 563 94 2 +563 744 94 2 +563 79 736 2 +718 650 253 2 +694 716 924 2 +963 839 948 2 +294 326 852 2 +372 298 820 2 +440 425 252 2 +126 681 611 2 +611 681 142 2 +553 207 187 2 +587 875 558 2 +495 316 260 2 +198 914 186 2 +186 335 198 2 +605 815 152 2 +336 261 259 2 +671 917 561 2 +861 575 833 2 +90 387 556 2 +872 977 160 2 +106 377 790 2 +790 675 106 2 +364 950 335 2 +528 442 69 2 +738 465 600 2 +276 716 924 2 +94 192 299 2 +898 139 4 2 +126 608 324 2 +324 681 126 2 +280 587 759 2 +73 135 177 2 +260 341 855 2 +617 246 579 2 +441 533 86 2 +297 176 1 2 +218 922 729 2 +620 663 528 2 +484 992 784 2 +992 712 784 2 +850 952 309 2 +848 7 139 2 +146 431 845 2 +868 566 742 2 +491 566 868 2 +698 80 909 2 +115 1016 807 2 +994 993 929 2 +189 206 137 2 +206 182 554 2 +182 743 554 2 +577 964 708 2 +964 781 708 2 +756 133 148 2 +925 719 385 2 +284 618 116 2 +345 130 141 2 +323 226 574 2 +367 796 609 2 +796 367 628 2 +677 323 802 2 +802 821 89 2 +92 839 366 2 +910 986 886 2 +986 886 999 2 +140 324 683 2 +318 91 685 2 +807 687 1016 2 +455 281 642 2 +642 928 455 2 +335 835 950 2 +704 246 579 2 +947 339 357 2 +568 142 611 2 +467 821 89 2 +169 122 232 2 +502 907 295 2 +782 377 328 2 +207 781 338 2 +986 481 910 2 +400 593 504 2 +631 666 439 2 +628 382 796 2 +796 382 425 2 +501 751 88 2 +749 305 570 2 +453 507 660 2 +749 570 743 2 +737 552 312 2 +312 215 737 2 +679 393 140 2 +393 679 807 2 +79 143 831 2 +787 493 818 2 +591 479 725 2 +1016 470 951 2 +123 537 444 2 +192 1 672 2 +506 1023 725 2 +998 428 851 2 +680 245 90 2 +431 146 670 2 +320 188 674 2 +753 697 396 2 +176 183 2 2 +176 2 234 2 +2 614 430 2 +614 2 183 2 +872 159 506 2 +403 512 818 2 +512 596 818 2 +457 608 948 2 +384 696 146 2 +664 492 630 2 +948 608 839 2 +467 407 1015 2 +608 140 457 2 +457 140 393 2 +556 387 355 2 +143 79 141 2 +1018 823 408 2 +506 1023 977 2 +590 535 916 2 +566 946 742 2 +441 231 532 2 +231 441 86 2 +781 195 338 2 +947 557 840 2 +557 947 357 2 +596 448 512 2 +244 795 790 2 +642 281 784 2 +793 117 250 2 +100 446 433 2 +328 782 706 2 +432 661 1020 2 +92 366 237 2 +388 278 454 2 +759 449 741 2 +352 254 721 2 +1025 597 809 2 +220 407 240 2 +649 517 472 2 +275 789 461 2 +927 592 385 2 +275 254 721 2 +451 279 717 2 +421 621 473 2 +633 811 384 2 +811 696 384 2 +924 659 814 2 +135 73 143 2 +751 98 127 2 +738 908 638 2 +789 372 275 2 +769 355 556 2 +896 467 929 2 +369 690 938 2 +371 188 320 2 +198 72 494 2 +239 902 105 2 +902 239 905 2 +757 602 296 2 +756 546 133 2 +529 254 352 2 +254 529 800 2 +90 245 387 2 +966 704 579 2 +692 811 633 2 +436 811 692 2 +680 178 148 2 +709 782 424 2 +782 709 827 2 +88 599 101 2 +262 852 325 2 +571 808 462 2 +204 494 300 2 +419 828 612 2 +828 414 612 2 +170 605 440 2 +549 747 214 2 +71 446 175 2 +492 729 218 2 +291 586 778 2 +139 848 340 2 +443 5 234 2 +81 531 252 2 +946 131 550 2 +292 934 354 2 +461 381 624 2 +624 381 418 2 +139 340 4 2 +208 635 93 2 +98 944 569 2 +594 976 450 2 +277 388 454 2 +115 393 807 2 +749 554 270 2 +920 625 83 2 +850 952 257 2 +215 154 737 2 +217 923 78 2 +87 217 78 2 +923 217 191 2 +922 729 321 2 +687 220 1015 2 +388 806 278 2 +459 346 693 2 +304 193 342 2 +744 144 205 2 +737 144 744 2 +209 899 305 2 +856 238 351 2 +179 344 203 2 +268 344 179 2 +954 853 209 2 +812 390 691 2 +114 443 86 2 +5 443 114 2 +686 904 134 2 +389 806 543 2 +806 389 278 2 +438 662 531 2 +90 556 756 2 +700 224 665 2 +665 421 700 2 +769 350 556 2 +714 817 930 2 +71 532 669 2 +790 610 377 2 +724 658 161 2 +149 887 881 2 +130 567 184 2 +635 201 312 2 +768 330 349 2 +501 569 906 2 +366 120 237 2 +510 688 592 2 +206 554 345 2 +683 179 267 2 +267 179 342 2 +921 212 301 2 +147 683 267 2 +737 744 94 2 +528 677 620 2 +625 922 920 2 +799 613 538 2 +437 83 201 2 +83 437 998 2 +531 252 425 2 +425 382 531 2 +902 905 527 2 +341 269 535 2 +747 707 503 2 +772 358 943 2 +213 919 745 2 +549 187 214 2 +285 834 864 2 +348 834 285 2 +927 641 592 2 +641 688 592 2 +677 620 504 2 +504 677 241 2 +505 399 626 2 +399 626 401 2 +986 883 481 2 +394 509 627 2 +627 460 394 2 +688 897 511 2 +404 511 688 2 +404 511 803 2 +878 541 651 2 +515 660 633 2 +96 517 833 2 +472 96 517 2 +517 833 649 2 +651 518 541 2 +525 890 980 2 +522 222 890 2 +879 651 520 2 +862 651 520 2 +724 157 910 2 +70 831 798 2 +210 866 974 2 +71 657 446 2 +312 201 215 2 +201 920 215 2 +169 231 122 2 +113 904 555 2 +980 222 645 2 +890 222 980 2 +364 771 950 2 +758 542 311 2 +311 560 758 2 +183 149 614 2 +149 183 664 2 +116 92 284 2 +369 938 452 2 +232 445 540 2 +92 237 616 2 +689 513 296 2 +296 513 543 2 +253 386 185 2 +386 451 185 2 +772 565 348 2 +615 111 104 2 +123 84 537 2 +260 961 316 2 +586 778 621 2 +444 110 538 2 +169 127 232 2 +777 578 548 2 +3 434 103 2 +221 870 655 2 +200 314 337 2 +882 990 480 2 +990 991 480 2 +374 418 423 2 +6 499 540 2 +563 153 744 2 +153 205 744 2 +116 618 227 2 +469 1018 248 2 +162 156 308 2 +534 239 82 2 +239 534 229 2 +762 546 133 2 +379 317 405 2 +788 826 376 2 +90 756 148 2 +916 360 93 2 +170 605 426 2 +69 125 574 2 +561 107 917 2 +836 937 557 2 +573 783 128 2 +108 359 632 2 +683 268 179 2 +268 683 324 2 +536 763 429 2 +392 804 507 2 +464 908 638 2 +108 940 359 2 +940 845 359 2 +155 75 849 2 +738 601 402 2 +190 242 197 2 +141 135 143 2 +431 76 539 2 +353 770 496 2 +761 196 212 2 +565 772 943 2 +378 799 322 2 +799 243 322 2 +675 244 790 2 +773 740 208 2 +89 688 458 2 +739 180 555 2 +478 483 622 2 +340 848 956 2 +199 202 952 2 +199 498 202 2 +588 580 76 2 +180 113 555 2 +444 538 170 2 +343 747 132 2 +626 505 173 2 +322 830 378 2 +830 117 378 2 +357 773 740 2 +80 126 284 2 +567 918 184 2 +772 701 348 2 +322 675 794 2 +270 554 130 2 +690 109 617 2 +620 349 958 2 +958 504 97 2 +991 474 881 2 +834 565 867 2 +822 378 613 2 +479 591 1022 2 +574 125 327 2 +872 526 159 2 +477 526 872 2 +902 694 105 2 +694 812 105 2 +551 216 301 2 +259 956 340 2 +918 197 567 2 +173 668 672 2 +255 545 761 2 +210 290 934 2 +440 252 792 2 +992 545 712 2 +298 411 325 2 +174 615 104 2 +553 332 207 2 +612 123 174 2 +123 615 174 2 +240 807 220 2 +807 687 220 2 +342 193 267 2 +193 147 267 2 +84 111 615 2 +515 633 429 2 +368 540 232 2 +665 822 108 2 +383 594 272 2 +290 934 832 2 +934 354 832 2 +746 301 551 2 +551 962 746 2 +330 529 663 2 +229 905 670 2 +111 6 104 2 +6 111 765 2 +657 634 532 2 +532 71 657 2 +508 403 375 2 +375 791 508 2 +316 961 151 2 +177 344 308 2 +308 162 177 2 +813 741 356 2 +741 813 806 2 +248 380 676 2 +693 255 346 2 +695 397 659 2 +397 695 514 2 +696 527 670 2 +794 106 675 2 +903 533 102 2 +320 371 306 2 +179 203 342 2 +635 590 93 2 +93 590 916 2 +662 438 632 2 +503 549 213 2 +386 713 451 2 +599 124 101 2 +409 822 613 2 +394 189 282 2 +189 816 394 2 +634 657 122 2 +122 657 100 2 +657 446 100 2 +987 882 480 2 +916 560 639 2 +559 637 699 2 +1023 646 977 2 +729 297 492 2 +931 720 642 2 +369 452 485 2 +931 720 454 2 +273 925 640 2 +841 945 649 2 +953 849 153 2 +798 95 251 2 +366 839 963 2 +79 563 153 2 +187 549 745 2 +997 887 428 2 +428 998 997 2 +534 175 82 2 +631 175 534 2 +115 775 576 2 +670 527 905 2 +277 388 449 2 +362 565 943 2 +298 789 661 2 +708 972 195 2 +195 972 293 2 +362 565 936 2 +513 689 402 2 +689 601 402 2 +224 632 665 2 +952 199 304 2 +758 360 916 2 +762 743 182 2 +780 743 762 2 +808 571 396 2 +262 97 958 2 +466 636 909 2 +477 526 727 2 +526 474 727 2 +390 598 691 2 +598 390 804 2 +666 85 446 2 +446 175 666 2 +935 836 557 2 +332 138 553 2 +436 696 810 2 +129 310 746 2 +678 496 247 2 +412 96 833 2 +150 204 337 2 +204 314 337 2 +325 294 852 2 +630 161 589 2 +589 161 658 2 +536 760 107 2 +801 619 140 2 +619 679 140 2 +670 431 229 2 +671 531 438 2 +462 272 571 2 +753 396 281 2 +172 233 101 2 +88 172 101 2 +551 502 907 2 +309 952 202 2 +365 917 107 2 +304 952 257 2 +969 742 868 2 +685 121 147 2 +121 683 147 2 +951 1016 576 2 +98 368 127 2 +374 423 816 2 +371 315 306 2 +546 780 762 2 +202 498 678 2 +106 243 794 2 +97 326 852 2 +389 805 459 2 +459 346 389 2 +422 473 825 2 +1027 109 294 2 +682 152 792 2 +345 206 137 2 +809 901 103 2 +802 323 226 2 +621 700 586 2 +163 989 622 2 +238 258 410 2 +410 258 353 2 +562 497 230 2 +185 808 697 2 +874 594 976 2 +775 860 948 2 +860 963 948 2 +247 375 787 2 +593 97 900 2 +485 896 369 2 +972 577 701 2 +824 181 509 2 +354 766 939 2 +766 755 939 2 +838 934 210 2 +843 767 289 2 +74 379 562 2 +508 188 403 2 +188 512 403 2 +384 536 146 2 +146 536 760 2 +395 979 786 2 +979 869 786 2 +871 646 977 2 +813 761 129 2 +983 937 838 2 +457 393 948 2 +579 643 1028 2 +154 321 922 2 +574 323 69 2 +510 688 404 2 +90 148 680 2 +954 752 209 2 +264 128 974 2 +974 128 866 2 +928 911 455 2 +816 401 374 2 +399 401 816 2 +546 780 334 2 +938 510 592 2 +673 373 786 2 +299 94 736 2 +924 694 902 2 +1027 432 1020 2 +940 431 845 2 +700 224 329 2 +453 507 392 2 +89 458 719 2 +546 350 334 2 +903 102 447 2 +360 93 208 2 +299 505 192 2 +178 678 787 2 +787 680 178 2 +760 107 561 2 +266 820 926 2 +676 797 469 2 +546 756 556 2 +442 663 528 2 +491 271 715 2 +988 475 482 2 +953 639 560 2 +749 743 554 2 +234 5 616 2 +91 550 131 2 +550 91 739 2 +417 786 673 2 +613 76 580 2 +411 468 1019 2 +122 231 634 2 +84 537 754 2 +754 99 111 2 +111 84 754 2 +754 500 99 2 +590 437 201 2 +569 501 751 2 +981 867 286 2 +361 950 835 2 +155 260 75 2 +260 155 495 2 +383 594 874 2 +874 717 383 2 +535 269 639 2 +889 644 892 2 +644 893 892 2 +263 496 353 2 +220 407 1015 2 +960 570 209 2 +576 951 369 2 +676 416 826 2 +885 482 435 2 +955 856 258 2 +150 337 200 2 +515 597 691 2 +597 812 691 2 +944 906 569 2 +569 751 98 2 +138 847 78 2 +916 560 758 2 +766 339 947 2 +857 530 965 2 +802 677 897 2 +88 599 751 2 +151 851 764 2 +1 136 192 2 +417 647 786 2 +370 647 417 2 +499 6 765 2 +228 499 765 2 +576 369 617 2 +343 544 358 2 +583 104 433 2 +910 886 723 2 +723 157 910 2 +572 654 222 2 +831 95 798 2 +117 822 415 2 +354 935 766 2 +766 935 840 2 +807 679 240 2 +248 828 419 2 +772 577 701 2 +663 330 349 2 +583 85 776 2 +903 533 430 2 +846 362 936 2 +577 544 358 2 +788 225 469 2 +226 327 240 2 +776 666 439 2 +590 535 437 2 +703 187 214 2 +187 703 584 2 +210 974 290 2 +174 104 583 2 +776 85 666 2 +125 619 113 2 +711 206 282 2 +282 206 189 2 +411 298 820 2 +516 875 253 2 +875 652 253 2 +160 157 477 2 +559 914 912 2 +914 186 912 2 +1028 702 966 2 +702 1028 860 2 +444 426 170 2 +746 777 310 2 +98 944 368 2 +777 548 310 2 +303 200 941 2 +200 314 941 2 +665 415 822 2 +310 548 969 2 +847 318 302 2 +957 685 147 2 +257 203 850 2 +770 496 336 2 +794 322 243 2 +774 331 118 2 +941 125 180 2 +493 680 245 2 +906 499 944 2 +174 585 583 2 +99 564 913 2 +8 7 848 2 +849 75 953 2 +482 475 885 2 +476 435 871 2 +482 435 476 2 +552 705 573 2 +771 361 502 2 +132 343 358 2 +344 308 8 2 +203 344 8 2 +261 770 336 2 +767 842 648 2 +842 945 648 2 +522 222 572 2 +645 521 654 2 +495 145 319 2 +981 759 280 2 +935 194 836 2 +695 398 514 2 +779 380 118 2 +869 493 245 2 +514 810 397 2 +290 832 755 2 +329 363 984 2 +363 863 984 2 +259 336 309 2 +142 307 681 2 +136 94 192 2 +581 609 709 2 +419 582 612 2 +377 793 610 2 +787 247 678 2 +132 358 338 2 +171 903 447 2 +303 941 125 2 +727 474 630 2 +474 664 630 2 +937 837 211 2 +114 169 231 2 +195 293 846 2 +347 648 880 2 +250 117 416 2 +416 117 830 2 +491 915 566 2 +438 561 671 2 +827 377 782 2 +171 434 614 2 +3 995 434 2 +959 427 316 2 +907 738 638 2 +907 638 699 2 +276 623 392 2 +623 804 392 2 +368 127 232 2 +392 695 276 2 +116 616 5 2 +339 755 766 2 +870 1021 655 2 +577 708 972 2 +210 983 866 2 +338 358 943 2 +338 362 943 2 +607 945 842 2 +701 972 293 2 +480 987 997 2 +673 420 899 2 +711 282 150 2 +937 557 211 2 +1027 530 704 2 +704 530 965 2 +547 600 295 2 +609 827 796 2 +540 499 368 2 +499 944 368 2 +801 683 140 2 +346 389 278 2 +454 278 346 2 +908 805 693 2 +379 815 317 2 +905 239 229 2 +459 805 693 2 +772 358 577 2 +97 262 852 2 +97 326 900 2 +464 693 908 2 +134 904 555 2 +1021 655 644 2 +693 761 813 2 +329 700 586 2 +272 911 571 2 +176 234 77 2 +464 757 638 2 +211 837 288 2 +288 837 128 2 +875 1002 516 2 +380 408 823 2 +823 118 380 2 +280 981 587 2 +878 981 280 2 +531 662 382 2 +591 1023 725 2 +217 750 191 2 +728 750 217 2 +638 757 699 2 +757 637 699 2 +659 276 695 2 +643 576 617 2 +697 718 253 2 +632 665 108 2 +902 527 814 2 +814 527 629 2 +449 277 911 2 +791 247 375 2 +757 602 464 2 +297 321 1 2 +141 184 726 2 +148 750 728 2 +163 724 910 2 +157 727 477 2 +478 483 990 2 +483 159 990 2 +859 72 962 2 +707 72 859 2 +888 980 525 2 +889 892 891 2 +892 975 891 2 +881 887 997 2 +915 545 566 2 +536 3 764 2 +432 294 1027 2 +185 451 279 2 +411 468 325 2 +468 1019 768 2 +902 924 814 2 +201 83 920 2 +138 745 923 2 +923 138 78 2 +841 291 607 2 +925 714 385 2 +719 273 925 2 +475 996 885 2 +591 1022 885 2 +996 1022 885 2 +556 350 546 2 +241 511 803 2 +180 216 502 2 +409 108 940 2 +180 361 502 2 +314 941 835 2 +684 172 497 2 +196 545 566 2 +545 196 761 2 +365 236 917 2 +918 197 190 2 +260 961 341 2 +955 261 770 2 +568 80 611 2 +771 364 158 2 +364 186 158 2 +437 341 961 2 +209 570 305 2 +715 650 271 2 +494 204 835 2 +103 809 429 2 +645 713 980 2 +713 876 980 2 +827 609 709 2 +298 789 372 2 +238 410 265 2 +857 626 173 2 +530 626 857 2 +645 654 222 2 +871 977 476 2 +977 476 160 2 +722 163 658 2 +437 998 851 2 +226 407 240 2 +950 771 361 2 +578 710 859 2 +207 187 584 2 +710 746 777 2 +764 365 151 2 +76 588 539 2 +599 466 112 2 +124 466 599 2 +863 363 968 2 +141 726 135 2 +135 726 177 2 +726 162 177 2 +804 598 406 2 +598 406 691 2 +450 1024 594 2 +594 1024 272 2 +907 738 600 2 +806 813 602 2 +602 806 543 2 +664 297 183 2 +664 297 492 2 +251 684 319 2 +398 810 514 2 +410 829 265 2 +829 410 353 2 +112 636 466 2 +251 172 684 2 +625 83 722 2 +364 335 186 2 +155 495 95 2 +851 764 428 2 +294 326 109 2 +414 779 110 2 +707 132 578 2 +578 132 332 2 +703 747 214 2 +662 628 382 2 +876 450 888 2 +682 152 317 2 +256 350 769 2 +326 109 690 2 +770 353 258 2 +266 768 330 2 +262 768 958 2 +595 626 530 2 +661 595 1020 2 +752 954 854 2 +264 542 783 2 +898 238 265 2 +265 898 674 2 +324 268 307 2 +435 1023 646 2 +491 915 271 2 +276 456 716 2 +716 456 694 2 +721 372 926 2 +372 820 926 2 +512 448 371 2 +587 558 449 2 +1017 621 778 2 +825 621 473 2 +621 1017 825 2 +1028 643 775 2 +456 276 623 2 +642 931 784 2 +642 928 720 2 +282 394 460 2 +712 915 271 2 +930 640 817 2 +608 839 284 2 +608 284 126 2 +1027 109 246 2 +317 815 152 2 +424 843 287 2 +287 767 843 2 +607 984 291 2 +984 586 291 2 +379 74 815 2 +771 295 502 2 +771 547 295 2 +176 297 183 2 +321 297 729 2 +331 118 779 2 +333 144 573 2 +707 72 503 2 +709 581 424 2 +663 529 824 2 +148 728 313 2 +776 585 331 2 +366 702 120 2 +995 149 887 2 +774 585 331 2 +374 624 418 2 +850 848 956 2 +331 588 580 2 +776 331 588 2 +153 311 205 2 +896 951 369 2 +818 403 787 2 +589 630 492 2 +76 409 940 2 +97 593 504 2 +264 542 339 2 +799 378 613 2 +380 248 828 2 +795 610 790 2 +576 775 643 2 +245 387 370 2 +628 224 367 2 +288 573 211 2 +573 705 211 2 +292 354 194 2 +806 741 388 2 +683 801 121 2 +482 988 723 2 +900 803 119 2 +779 828 414 2 +401 374 661 2 +509 181 816 2 +317 405 145 2 +405 684 145 2 +684 497 405 2 +791 508 188 2 +283 453 392 2 +385 452 592 2 +862 518 651 2 +126 80 611 2 +396 697 808 2 +676 416 830 2 +1024 450 876 2 +810 629 696 2 +785 516 650 2 +696 436 811 2 +272 1024 519 2 +985 862 587 2 +862 967 587 2 +387 370 819 2 +897 241 511 2 +428 995 3 2 +876 386 713 2 +429 633 463 2 +592 452 938 2 +582 471 419 2 +471 823 582 2 +86 231 114 2 +455 281 396 2 +866 983 837 2 +659 397 814 2 +970 292 194 2 +434 149 995 2 +434 149 614 2 +575 706 422 2 +573 288 128 2 +76 431 940 2 +822 108 409 2 +562 500 74 2 +779 380 828 2 +612 123 414 2 +189 399 816 2 +812 456 694 2 +352 721 926 2 +185 697 253 2 +416 826 250 2 +250 826 376 2 +844 575 861 2 +161 727 630 2 +577 544 964 2 +861 982 971 2 +747 703 343 2 +343 703 544 2 +703 584 544 2 +120 965 668 2 +138 302 847 2 +708 195 781 2 +525 653 523 2 +653 522 523 2 +711 182 206 2 +300 748 711 2 +666 175 631 2 +352 926 266 2 +928 277 911 2 +928 277 720 2 +864 1000 518 2 +518 1000 541 2 +989 481 910 2 +159 990 991 2 +723 157 160 2 +541 936 285 2 +936 846 285 2 +137 399 189 2 +299 399 137 2 +937 837 983 2 +286 565 936 2 +836 194 937 2 +329 363 843 2 +149 474 664 2 +474 149 881 2 +846 973 285 2 +310 356 865 2 +701 293 348 2 +705 211 740 2 +303 249 125 2 +857 668 173 2 +856 238 258 2 +929 993 896 2 +881 480 991 2 +424 706 575 2 +575 844 424 2 +280 878 879 2 +879 878 651 2 +840 947 766 2 +86 430 533 2 +936 541 286 2 +949 561 438 2 +760 561 949 2 +438 949 359 2 +560 953 311 2 +153 953 311 2 +8 850 848 2 +847 193 78 2 +978 451 713 2 +318 685 957 2 +151 959 365 2 +959 236 365 2 +72 198 962 2 +962 198 551 2 +578 859 707 2 +702 963 860 2 +970 937 838 2 +966 120 702 2 +713 645 870 2 +645 521 870 2 +865 969 759 2 +969 868 759 2 +759 868 280 2 +868 491 280 2 +607 968 842 2 +984 863 607 2 +970 194 937 2 +838 970 292 2 +715 280 879 2 +356 741 865 2 +171 103 447 2 +564 99 500 2 +524 572 654 2 +654 521 524 2 +523 891 889 2 +889 522 644 2 +975 525 523 2 +981 286 878 2 +286 541 878 2 +89 884 273 2 +89 467 884 2 +526 159 991 2 +420 819 370 2 +370 417 420 2 +721 372 275 2 +901 82 239 2 +829 353 263 2 +423 181 816 2 +254 800 381 2 +728 313 87 2 +519 386 652 2 +1024 386 519 2 +722 882 478 2 +491 715 280 2 +390 623 804 2 +885 1023 591 2 +504 400 241 2 +509 394 816 2 +813 693 464 2 +692 453 660 2 +150 200 460 2 +460 200 627 2 +463 633 384 2 +571 396 455 2 +455 911 571 2 +145 319 684 2 +465 738 601 2 +752 391 819 2 +871 646 435 2 +981 587 967 2 +418 800 381 2 +354 939 832 2 +939 755 832 2 +105 812 597 2 +515 597 809 2 +404 803 119 2 +384 463 536 2 +83 998 987 2 +975 525 888 2 +987 997 998 2 +888 980 876 2 +989 479 1022 2 +348 973 285 2 +329 581 843 2 +424 581 843 2 +1001 985 1002 2 +901 239 1025 2 +597 105 1025 2 +1025 105 239 2 +299 505 399 2 +510 404 119 2 +292 934 838 2 +403 375 787 2 +513 805 389 2 +402 805 513 2 +389 513 543 2 +155 831 95 2 +414 123 110 2 +660 406 507 2 +406 804 507 2 +627 509 667 2 +637 601 465 2 +395 1026 979 2 +225 788 376 2 +833 575 412 2 +674 413 265 2 +829 413 265 2 +263 413 829 2 +263 413 791 2 +880 648 287 2 +287 648 767 2 +373 786 395 2 +262 468 325 2 +800 181 418 2 +417 420 673 2 +990 478 882 2 +469 797 225 2 +930 640 925 2 +468 262 768 2 +978 870 713 2 +870 978 1021 2 +245 647 869 2 +1021 893 873 2 +863 607 968 2 +1026 818 596 2 +596 395 1026 2 +717 383 279 2 +975 893 892 2 +812 390 456 2 +390 456 623 2 +718 697 753 2 +692 453 283 2 +381 461 254 2 +911 558 449 2 +519 558 911 2 +429 536 463 2 +559 465 912 2 +465 547 912 2 +465 637 559 2 +912 158 547 2 +967 867 981 2 +201 635 590 2 +837 128 866 2 +641 458 927 2 +248 471 419 2 +248 471 1018 2 +471 1018 823 2 +96 1017 472 2 +271 650 718 2 +715 785 650 2 +160 476 723 2 +723 476 482 2 +506 872 977 2 +159 483 725 2 +454 484 931 2 +724 658 163 2 +931 784 484 2 +817 993 994 2 +994 640 817 2 +817 993 485 2 +485 817 714 2 +435 1023 885 2 +217 728 87 2 +1024 386 876 2 +984 329 586 2 +840 935 557 2 +844 287 424 2 +287 844 971 2 +833 877 861 2 +877 982 861 2 +841 607 945 2 +281 712 784 2 +295 600 907 2 +289 843 363 2 +847 318 957 2 +147 957 847 2 +147 193 847 2 +163 910 989 2 +942 854 752 2 +769 854 942 2 +769 854 256 2 +854 256 954 2 +867 967 864 2 +564 230 88 2 +913 564 88 2 +982 347 877 2 +964 858 781 2 +544 858 964 2 +207 858 781 2 +584 858 207 2 +544 584 858 2 +759 865 741 2 +883 996 475 2 +969 310 865 2 +286 565 867 2 +873 976 450 2 +978 274 1021 2 +274 873 1021 2 +976 274 873 2 +888 893 450 2 +1021 893 644 2 +717 874 274 2 +879 520 785 2 +558 875 652 2 +472 841 649 2 +975 893 888 2 +971 880 287 2 +982 880 971 2 +347 982 880 2 +884 994 929 2 +994 640 884 2 +929 884 467 2 +886 988 999 2 +912 186 158 2 +547 158 771 2 +156 184 162 2 +918 184 156 2 +726 184 162 2 +274 451 978 2 +717 451 274 2 +599 112 751 2 +725 159 506 2 +877 649 833 2 +877 347 649 2 +649 347 648 2 +945 649 648 2 +558 519 652 2 +870 521 221 2 +522 572 644 2 +1000 285 864 2 +272 519 911 2 +485 896 993 2 +785 1002 1001 2 +541 1000 285 2 +1001 785 520 2 +1002 516 785 2 +985 875 1002 2 +891 975 523 2 +Tetrahedra +6548 +1017 778 219 472 0 +957 541 846 309 0 +846 362 302 195 0 +862 520 985 1001 1 +465 600 559 547 1 +392 398 283 695 0 +690 77 237 109 0 +919 923 745 191 0 +999 883 988 475 0 +307 681 608 324 1 +166 1008 1009 1006 1 +555 295 502 739 0 +323 246 109 617 1 +924 631 666 716 0 +1006 439 631 606 1 +430 443 2 167 1 +477 171 872 160 0 +156 162 728 87 1 +908 921 212 638 0 +791 379 317 413 0 +661 173 298 432 0 +255 992 545 346 0 +366 775 702 963 0 +188 684 674 791 0 +114 127 169 227 1 +842 289 968 939 0 +480 995 881 997 0 +606 1009 85 446 1 +465 23 912 62 0 +610 797 244 795 1 +228 9 42 111 0 +619 948 656 125 1 +1005 151 959 316 1 +195 336 846 708 0 +826 376 473 825 0 +774 174 585 612 1 +204 300 711 150 1 +99 228 42 84 0 +550 212 921 746 1 +676 797 799 322 0 +989 479 725 622 1 +367 767 609 628 0 +988 886 475 723 1 +144 552 312 311 1 +85 17 30 58 0 +83 492 887 881 1 +542 208 360 773 1 +807 121 687 134 0 +196 212 550 548 1 +749 197 130 270 0 +318 491 946 742 0 +689 638 908 757 1 +190 156 148 313 1 +143 70 73 306 0 +616 938 119 690 0 +818 403 815 317 0 +682 75 145 427 0 +806 693 255 761 1 +142 259 124 568 0 +516 253 652 386 0 +111 228 99 84 0 +73 142 165 307 1 +385 510 234 938 0 +82 901 103 447 1 +1010 1005 495 316 1 +915 992 545 449 1 +955 285 770 258 0 +367 581 609 767 0 +178 306 315 190 1 +102 441 235 669 0 +76 940 735 1007 1 +894 656 165 366 1 +946 310 196 548 1 +290 937 755 354 1 +489 176 234 486 1 +299 960 736 137 0 +688 927 404 533 0 +314 150 200 303 1 +710 943 132 777 0 +703 934 214 942 0 +748 919 133 191 0 +190 143 135 306 0 +536 3 1012 763 1 +7 177 308 8 0 +936 742 302 362 0 +711 189 743 282 0 +144 333 311 205 1 +249 894 164 627 1 +208 163 93 622 0 +573 461 144 275 0 +214 256 210 300 0 +473 328 793 421 1 +4 233 70 142 0 +13 279 462 808 0 +216 921 907 301 0 +290 370 819 391 0 +1004 88 112 734 1 +158 547 352 926 0 +250 416 797 676 1 +212 129 301 746 1 +799 170 735 243 1 +306 143 315 190 0 +1012 539 534 1006 1 +1028 574 579 69 1 +902 534 631 924 0 +761 129 464 212 0 +1012 229 670 239 1 +411 325 768 330 1 +357 773 542 339 1 +563 1013 79 730 1 +742 302 548 131 0 +667 249 69 303 0 +101 233 70 732 1 +388 454 484 346 1 +585 776 583 774 0 +39 717 9 49 0 +1016 407 576 240 1 +233 101 70 142 1 +187 178 148 313 0 +73 142 307 848 0 +559 699 551 907 1 +235 669 71 175 0 +136 94 144 737 0 +824 314 200 442 0 +337 509 181 200 0 +619 113 240 327 0 +911 720 277 454 0 +989 725 506 622 1 +960 299 736 853 0 +574 600 226 547 0 +47 880 40 54 0 +101 932 233 732 1 +414 331 779 580 1 +851 151 961 437 0 +800 824 624 529 1 +740 773 333 783 1 +823 582 774 118 0 +211 729 372 705 0 +968 607 695 514 0 +506 3 763 103 0 +783 773 333 542 1 +920 625 635 312 0 +74 42 24 68 0 +795 797 244 225 1 +243 425 440 170 0 +264 974 755 290 0 +271 718 753 558 1 +800 337 181 824 0 +72 138 302 332 1 +830 322 797 676 0 +229 431 539 1012 1 +810 700 224 863 0 +802 738 600 467 0 +822 378 665 117 1 +216 502 198 551 1 +548 302 332 578 0 +497 731 172 230 1 +270 197 130 567 0 +675 444 797 538 0 +981 286 969 759 0 +898 351 4 770 1 +689 637 757 296 0 +575 1017 825 412 1 +752 355 899 209 1 +687 470 1015 896 0 +7 135 73 306 0 +552 705 321 922 0 +333 752 311 205 0 +378 322 243 117 1 +955 501 351 569 0 +234 86 443 430 0 +541 309 336 846 0 +188 787 247 320 1 +854 333 205 752 0 +326 241 119 900 1 +221 524 523 572 0 +244 790 422 575 0 +919 187 756 191 0 +224 329 609 581 1 +351 88 568 501 0 +748 133 762 182 0 +731 1004 932 88 1 +834 541 867 864 1 +356 129 196 310 1 +327 180 555 240 0 +269 639 75 953 0 +740 625 208 658 0 +407 467 821 600 0 +756 242 90 305 1 +789 330 352 529 1 +662 628 224 632 1 +179 683 681 324 0 +996 910 475 986 1 +767 796 609 628 0 +109 237 668 672 0 +580 331 174 123 1 +87 304 193 78 0 +369 690 617 802 1 +80 124 909 568 1 +803 903 430 664 0 +740 552 208 625 0 +236 81 531 671 0 +296 543 602 908 1 +123 419 612 244 0 +456 476 102 46 0 +415 621 421 700 0 +319 933 95 251 1 +264 211 339 947 1 +722 93 622 478 0 +570 350 334 960 1 +250 830 797 416 1 +145 495 260 75 0 +1017 219 659 472 0 +805 543 296 908 1 +186 747 914 559 0 +493 395 979 869 1 +29 9 540 445 0 +792 440 605 152 1 +814 924 631 823 0 +636 751 127 698 0 +795 412 422 825 0 +341 269 855 75 1 +449 759 587 981 0 +883 996 481 1022 0 +7 306 313 190 1 +305 197 749 756 1 +647 786 373 869 1 +238 230 172 88 0 +224 581 609 367 1 +929 281 346 484 0 +433 85 30 583 0 +378 243 665 117 1 +357 1022 208 840 0 +633 660 436 692 1 +600 407 226 821 0 +208 635 312 311 1 +442 667 530 69 1 +815 605 731 426 1 +682 792 427 603 1 +956 309 259 850 0 +139 202 678 496 1 +610 250 797 795 1 +299 189 399 423 0 +299 137 736 1013 1 +686 91 121 134 1 +560 758 755 542 0 +56 23 465 62 0 +505 661 624 374 0 +371 831 188 512 0 +909 751 636 698 0 +52 641 31 719 0 +100 445 433 29 0 +823 118 439 229 0 +300 919 748 191 1 +211 740 357 557 0 +692 436 398 283 1 +782 706 827 424 0 +104 30 9 60 0 +202 4 336 496 1 +452 719 89 273 1 +166 1003 167 933 1 +282 460 150 164 1 +256 299 144 573 0 +522 644 980 888 1 +7 156 190 313 1 +42 9 228 185 0 +675 426 106 74 0 +582 174 774 612 0 +656 73 165 307 1 +661 663 824 442 1 +584 498 178 313 0 +212 129 464 638 0 +180 216 198 739 1 +146 763 1012 429 1 +446 669 634 66 0 +937 275 211 372 0 +223 1005 932 166 1 +58 446 29 66 0 +773 208 333 542 1 +619 240 679 327 0 +7 308 156 199 1 +318 131 91 302 1 +144 312 205 311 1 +186 300 214 210 0 +618 636 227 698 0 +361 494 198 835 1 +987 882 590 722 0 +320 496 898 139 1 +758 333 360 542 1 +197 242 305 141 0 +391 819 355 387 0 +788 469 1018 408 1 +153 420 899 819 0 +58 666 446 66 0 +1027 857 668 965 0 +80 618 896 698 0 +799 170 794 538 0 +900 77 234 119 0 +619 327 948 125 1 +930 532 634 231 0 +905 1025 809 429 1 +448 596 395 155 0 +696 811 632 146 0 +175 669 666 66 0 +24 979 287 832 0 +77 489 234 1014 1 +445 9 6 32 0 +7 498 848 199 1 +870 1021 888 893 1 +736 305 79 141 0 +749 570 137 141 0 +705 321 372 136 0 +136 737 552 154 0 +483 622 725 479 0 +209 960 853 256 1 +323 528 246 69 1 +423 334 181 418 0 +128 211 339 264 1 +165 732 1014 92 1 +228 1004 765 111 1 +574 180 240 226 0 +242 305 79 899 0 +979 75 1026 560 0 +660 429 515 809 0 +580 110 613 779 1 +985 715 587 875 1 +146 905 527 384 1 +689 738 638 601 1 +544 387 391 355 0 +303 249 69 941 0 +415 421 793 665 1 +204 256 337 334 0 +458 641 688 719 0 +165 732 92 284 1 +817 930 634 231 0 +679 115 393 948 1 +603 735 1007 605 1 +1 852 176 262 0 +649 347 19 517 0 +252 425 767 382 0 +836 986 883 999 0 +885 482 723 160 1 +328 706 473 422 1 +745 187 919 191 0 +698 636 227 127 0 +306 70 73 139 0 +798 674 898 320 0 +7 498 199 313 1 +146 670 905 239 1 +207 332 132 338 1 +254 364 337 800 0 +564 500 562 230 0 +860 327 775 1028 1 +354 292 21 47 0 +771 502 186 914 1 +601 513 25 56 0 +72 739 302 164 1 +510 119 234 938 0 +796 243 440 170 0 +187 178 584 680 0 +354 935 21 194 0 +237 668 120 246 0 +319 596 403 512 0 +393 126 807 140 0 +408 613 378 676 0 +673 373 79 242 0 +790 706 377 328 0 +203 257 342 304 1 +244 797 248 469 0 +796 425 440 243 0 +85 774 582 583 0 +602 356 129 813 0 +1011 103 434 171 1 +383 274 39 62 0 +925 48 640 66 0 +446 433 1009 85 1 +724 986 161 886 0 +549 256 214 300 0 +454 571 278 272 0 +567 750 270 133 1 +515 406 809 691 0 +411 266 768 1019 1 +788 469 676 826 1 +57 12 96 58 0 +53 96 12 58 0 +593 727 630 723 0 +199 304 87 78 0 +966 1028 579 69 1 +864 518 967 862 0 +572 523 889 522 0 +96 50 57 60 0 +96 57 30 60 0 +233 172 238 898 0 +666 439 1009 606 1 +622 93 479 590 0 +529 661 789 330 1 +7 313 199 156 1 +803 241 400 900 1 +249 125 69 941 0 +282 189 423 816 0 +318 946 131 742 0 +30 104 9 32 0 +166 1005 1011 895 1 +524 24 818 375 0 +904 459 805 908 0 +913 88 501 1004 1 +1 77 176 672 0 +510 592 234 430 0 +903 430 614 171 1 +330 432 325 349 1 +799 797 538 322 0 +104 6 9 32 0 +317 682 287 1026 0 +393 240 115 679 1 +320 674 898 263 1 +8 850 203 952 1 +831 155 373 79 0 +254 275 461 573 0 +725 479 365 764 0 +23 838 912 36 0 +4 261 351 259 0 +351 261 568 259 0 +710 578 962 746 1 +252 603 81 792 1 +22 833 27 65 0 +141 135 165 894 1 +433 17 30 85 0 +827 609 224 793 1 +284 1016 92 839 0 +686 801 679 121 0 +915 91 121 685 0 +318 651 742 541 0 +58 175 666 66 0 +954 899 79 736 0 +1020 595 530 442 1 +960 570 736 137 0 +616 5 452 369 0 +410 562 379 497 0 +887 428 995 1011 1 +148 750 133 191 0 +235 441 168 669 1 +662 425 382 632 1 +402 513 296 908 1 +846 336 1000 955 0 +408 676 826 788 1 +478 163 622 722 0 +1017 826 473 825 0 +996 989 481 1022 1 +370 819 560 542 0 +256 748 334 300 0 +600 555 407 904 0 +793 322 610 830 1 +768 352 158 547 0 +7 306 498 313 1 +345 137 189 141 1 +617 237 246 109 0 +666 1009 85 606 1 +643 617 366 579 0 +283 436 398 392 1 +549 350 214 769 0 +305 242 79 141 0 +743 182 711 748 0 +185 9 499 697 0 +848 73 70 139 0 +832 370 786 755 0 +803 400 593 900 0 +849 420 155 153 0 +208 625 312 635 0 +83 722 987 201 0 +674 263 247 791 1 +527 665 696 629 0 +664 430 183 614 0 +70 732 165 73 1 +553 138 187 745 0 +619 904 113 686 0 +406 515 623 691 1 +572 653 524 523 0 +674 413 791 405 0 +832 370 290 391 0 +258 253 185 913 0 +787 188 512 371 1 +1027 965 246 704 0 +1019 970 926 51 0 +70 165 143 73 1 +29 446 17 32 0 +146 632 359 438 0 +146 949 845 760 0 +202 340 309 336 1 +219 841 472 778 1 +397 291 219 778 0 +156 313 199 87 1 +163 477 526 159 1 +730 1 489 321 1 +291 841 219 778 1 +156 308 87 199 1 +452 938 385 234 0 +933 166 932 1005 1 +731 605 1007 426 1 +1004 733 1008 734 1 +534 439 631 1006 1 +216 739 921 301 0 +819 370 953 417 0 +335 835 204 314 0 +942 769 214 355 0 +429 901 1025 809 1 +312 635 205 311 1 +7 190 156 135 0 +125 327 860 1028 1 +915 271 992 449 1 +7 177 162 308 0 +156 308 162 87 1 +589 729 820 218 0 +278 594 389 543 0 +918 135 197 726 0 +771 364 158 950 0 +158 364 314 950 0 +771 158 314 950 0 +771 314 158 824 0 +824 314 158 800 0 +158 314 337 800 0 +364 158 337 800 0 +412 575 422 825 1 +234 443 2 430 0 +338 578 132 943 0 +99 1004 731 913 1 +256 769 954 853 1 +7 308 199 8 1 +710 746 962 859 0 +500 754 426 74 0 +191 745 187 923 0 +303 164 125 180 1 +315 143 79 242 0 +831 373 448 315 0 +842 363 968 289 1 +80 618 732 284 1 +137 305 736 141 0 +411 266 1019 820 1 +139 898 202 496 1 +842 767 289 939 0 +683 342 685 267 0 +1015 951 467 896 1 +588 439 776 774 0 +926 970 10 51 0 +636 112 127 751 0 +106 796 815 605 0 +941 771 323 528 0 +916 151 365 479 0 +228 111 42 84 0 +542 360 758 773 1 +174 30 104 60 0 +670 108 146 696 0 +687 470 284 1016 0 +7 73 177 8 0 +549 213 553 745 1 +655 644 870 572 1 +392 435 21 591 0 +692 436 392 660 1 +1010 933 495 1005 1 +925 441 927 102 0 +376 795 793 473 0 +812 691 1025 901 0 +226 775 327 574 1 +542 311 333 783 1 +524 410 24 829 0 +681 683 611 324 0 +815 426 74 605 1 +273 13 884 640 0 +433 104 30 32 0 +884 485 452 714 1 +835 494 198 335 1 +612 444 110 419 0 +148 242 756 197 1 +948 115 839 775 0 +469 248 408 676 1 +450 449 741 1024 0 +428 3 1011 764 1 +481 996 475 986 1 +312 737 205 744 1 +341 490 269 75 1 +503 494 72 300 1 +936 834 565 348 1 +677 897 504 547 0 +72 919 503 300 1 +949 359 845 735 1 +504 897 241 547 0 +13 383 717 39 0 +116 616 92 369 0 +190 918 148 156 1 +526 434 474 991 0 +73 307 177 8 0 +669 48 532 66 0 +798 674 188 251 0 +909 112 636 751 0 +132 707 553 747 1 +548 746 131 962 1 +890 653 522 525 1 +98 733 368 1004 1 +731 223 166 1007 1 +164 150 204 941 1 +591 289 968 283 0 +739 91 555 134 1 +326 119 77 900 0 +80 124 618 698 1 +100 122 445 29 0 +1020 528 442 1027 1 +619 801 679 686 0 +603 895 1005 1007 1 +505 173 789 661 0 +468 161 589 723 0 +924 659 694 276 1 +809 429 633 527 1 +916 365 766 479 0 +329 782 609 581 1 +905 239 1025 429 1 +124 466 909 112 0 +1017 826 621 473 0 +350 256 334 960 1 +589 492 218 625 1 +799 110 538 828 0 +620 504 958 547 0 +795 473 376 825 0 +521 221 572 524 1 +723 727 630 157 0 +300 503 213 919 1 +771 180 323 574 0 +739 550 134 921 0 +236 81 671 917 0 +552 922 625 218 0 +87 308 304 199 1 +94 730 136 1013 1 +177 307 268 344 0 +70 320 139 306 0 +309 957 685 257 0 +813 464 129 602 0 +731 487 754 426 1 +506 763 429 103 0 +7 306 73 139 0 +942 769 355 752 1 +748 191 133 750 0 +611 685 121 683 0 +48 719 925 64 0 +722 625 589 658 1 +818 979 493 1026 0 +234 510 2 404 0 +194 999 883 988 0 +310 356 129 757 0 +109 77 237 672 0 +828 419 110 797 0 +665 629 527 415 0 +446 433 17 32 0 +380 613 408 676 0 +100 168 733 657 1 +622 151 479 478 0 +192 672 1013 489 1 +307 850 956 681 0 +879 491 715 785 0 +568 124 909 751 0 +573 737 144 552 0 +672 173 325 298 0 +819 752 153 205 0 +196 550 946 548 1 +327 679 115 240 1 +533 235 604 102 1 +824 337 181 200 0 +146 239 905 429 1 +929 753 281 712 0 +486 614 2 167 1 +69 941 323 528 0 +332 707 553 132 1 +600 821 226 802 0 +322 797 538 675 0 +831 448 371 315 0 +493 373 448 395 1 +690 119 77 326 0 +741 449 255 388 1 +145 495 427 316 1 +689 601 757 637 1 +145 316 427 75 0 +1026 682 145 317 0 +255 484 992 346 0 +229 1012 534 82 1 +654 1001 516 785 0 +313 190 178 148 1 +320 674 263 247 1 +433 6 104 32 0 +914 295 559 551 1 +979 370 786 832 0 +858 680 787 493 0 +115 1016 576 240 1 +452 5 385 714 0 +24 979 818 1026 0 +123 444 110 612 0 +229 539 439 534 1 +470 116 951 896 0 +388 992 255 484 1 +446 71 669 66 0 +544 391 703 355 0 +502 914 198 551 1 +189 206 894 394 1 +128 211 783 357 1 +248 471 823 828 1 +610 797 675 244 1 +1001 879 985 785 1 +237 246 120 617 0 +293 348 973 846 1 +210 983 838 254 0 +649 1017 412 96 1 +386 185 652 808 1 +100 232 445 122 0 +641 102 476 46 0 +529 624 461 789 1 +703 942 214 355 0 +564 913 856 258 0 +157 886 161 723 0 +899 90 673 242 1 +661 626 595 401 0 +1005 895 107 764 1 +902 695 814 629 1 +584 678 178 498 0 +430 604 167 614 1 +1008 606 1006 604 1 +1 192 298 372 0 +740 208 552 705 1 +547 600 226 802 0 +350 556 769 209 1 +484 712 545 346 0 +433 100 1009 733 1 +765 9 228 111 0 +487 1009 111 104 1 +164 113 125 180 1 +802 89 897 547 0 +959 916 639 535 0 +279 462 185 386 1 +324 126 608 140 0 +279 9 185 808 0 +365 107 692 633 0 +844 347 861 971 1 +921 301 739 962 1 +735 538 613 110 1 +427 252 81 792 0 +298 330 266 352 1 +37 833 22 65 0 +740 481 208 357 0 +119 938 897 690 1 +8 952 203 304 1 +616 119 234 77 0 +234 486 2 167 1 +934 210 214 942 0 +192 173 672 298 0 +506 159 429 763 0 +634 532 930 640 0 +391 783 128 942 0 +836 970 820 886 0 +349 432 620 663 1 +409 613 76 735 1 +662 438 692 365 0 +175 71 666 669 0 +208 625 635 658 0 +128 357 783 339 1 +7 135 156 162 0 +959 916 758 639 0 +1003 932 734 732 1 +547 738 600 802 0 +891 892 689 601 0 +669 441 168 532 1 +182 554 345 130 1 +445 733 6 540 1 +4 124 101 142 0 +325 294 620 349 1 +323 246 617 579 1 +502 739 295 216 0 +345 749 137 141 0 +552 218 625 705 0 +552 922 218 705 0 +624 505 789 661 0 +446 634 29 66 0 +165 839 656 307 1 +250 676 797 376 1 +315 680 242 373 1 +349 958 768 547 0 +874 1021 274 62 0 +976 1021 274 874 0 +873 450 893 892 0 +574 180 600 547 0 +70 488 165 732 1 +636 466 227 734 1 +180 835 361 941 1 +738 600 407 904 0 +283 289 968 692 0 +552 321 136 154 0 +195 302 338 362 0 +766 591 21 996 0 +688 102 476 641 0 +898 238 351 770 1 +566 356 196 946 1 +379 815 405 497 1 +586 984 841 945 1 +246 237 668 109 0 +783 333 705 573 1 +714 925 273 930 1 +915 712 545 992 1 +528 771 323 547 0 +305 546 749 762 1 +863 662 224 436 0 +42 9 451 49 0 +629 810 695 397 1 +897 89 938 688 1 +7 139 848 498 1 +193 267 683 147 1 +748 191 750 182 1 +748 750 133 182 0 +555 686 113 134 1 +54 22 877 59 0 +134 753 687 712 0 +213 503 553 745 1 +919 756 133 191 0 +737 94 144 744 0 +237 77 1014 672 1 +616 77 1014 237 1 +291 607 514 219 0 +567 197 750 133 1 +154 215 922 920 0 +318 541 846 957 0 +491 449 915 741 1 +660 406 809 515 0 +752 391 355 942 1 +1 136 321 154 1 +288 256 573 254 0 +227 5 116 114 0 +1027 1020 857 530 0 +233 732 798 70 1 +433 445 6 32 0 +926 1019 10 43 0 +377 322 827 106 1 +731 605 603 1007 1 +805 402 738 908 0 +846 348 362 293 1 +427 603 236 959 1 +900 803 183 664 0 +500 754 537 426 0 +724 727 526 157 1 +856 501 351 955 0 +598 1023 804 507 0 +974 937 755 290 1 +444 426 675 537 0 +384 760 438 146 0 +108 799 243 378 1 +117 421 793 415 1 +899 819 355 752 1 +935 1022 996 883 0 +224 581 367 363 0 +339 947 755 264 1 +370 673 245 647 1 +361 502 198 216 1 +840 208 773 1022 0 +360 311 208 333 1 +322 799 794 538 0 +634 168 231 532 1 +478 851 365 764 0 +118 774 779 582 1 +493 448 818 596 1 +743 334 570 780 1 +132 777 578 710 0 +80 618 470 896 0 +629 778 397 814 0 +362 742 548 969 0 +298 173 325 432 0 +783 357 542 339 1 +159 3 429 763 0 +118 588 439 539 0 +793 830 610 250 1 +552 208 312 311 1 +139 496 678 320 1 +323 677 109 528 1 +9 906 499 228 0 +458 927 719 385 1 +197 184 141 130 0 +547 89 897 738 0 +320 263 496 247 1 +391 942 703 355 0 +4 142 340 259 0 +233 488 798 732 1 +4 101 233 142 0 +803 430 183 664 0 +819 370 264 542 0 +316 855 427 75 0 +922 215 312 920 0 +143 373 315 79 0 +128 783 264 339 1 +370 560 953 786 0 +404 430 2 183 0 +275 705 372 136 0 +270 197 567 133 1 +509 824 667 442 0 +85 433 17 446 0 +633 107 384 536 0 +537 754 487 426 1 +906 501 1004 228 1 +516 650 875 253 1 +327 904 240 555 0 +365 764 1005 107 1 +82 447 175 235 1 +645 516 386 713 0 +902 436 695 629 1 +810 436 398 863 0 +82 447 235 102 0 +228 913 1004 99 1 +70 142 732 73 1 +913 1004 501 228 1 +441 533 102 235 1 +462 13 25 383 0 +974 391 128 942 0 +762 133 554 182 1 +748 133 546 762 0 +536 764 365 107 0 +536 365 633 107 0 +932 172 88 101 1 +271 753 712 558 1 +941 303 667 69 0 +57 1018 30 58 0 +256 748 780 334 0 +221 644 655 572 1 +452 719 273 714 1 +569 955 261 351 0 +209 556 899 305 1 +899 209 79 736 0 +193 179 267 342 1 +708 258 770 973 0 +223 933 251 932 1 +265 497 172 230 0 +334 299 960 256 0 +473 424 329 586 1 +48 641 927 719 0 +756 90 556 899 1 +875 650 558 718 1 +178 678 371 306 1 +140 679 457 619 1 +437 535 341 490 1 +183 664 176 900 0 +702 860 775 1028 0 +219 841 695 472 0 +680 315 242 190 1 +190 143 315 242 0 +680 242 90 190 1 +148 190 90 242 1 +148 242 90 756 1 +798 172 674 251 0 +233 172 674 798 0 +233 674 898 798 0 +233 172 798 251 0 +610 322 675 797 1 +793 782 328 377 1 +802 600 821 467 0 +855 316 260 75 0 +120 966 704 965 1 +615 225 244 612 0 +615 244 123 612 0 +155 420 79 153 0 +895 603 735 1007 1 +667 249 303 627 0 +798 251 188 95 0 +537 444 244 675 0 +244 426 537 675 0 +795 250 797 376 1 +76 408 409 539 0 +827 106 243 796 1 +42 99 244 500 0 +244 99 537 500 0 +500 426 537 244 0 +244 99 84 537 0 +84 537 123 244 0 +537 444 123 244 0 +615 244 84 123 0 +84 615 42 244 0 +615 9 42 244 0 +42 99 84 244 0 +337 394 509 200 0 +1016 687 220 240 1 +1010 495 155 260 1 +510 430 2 404 0 +794 170 106 675 0 +202 952 498 781 0 +325 432 294 349 1 +495 933 95 319 1 +157 724 161 886 0 +194 836 883 999 0 +643 617 92 366 0 +60 96 50 833 0 +724 161 727 157 1 +383 462 279 272 1 +970 15 16 18 0 +427 603 81 236 1 +200 303 627 667 0 +795 376 797 225 1 +313 199 87 78 0 +734 127 114 227 1 +70 488 831 143 1 +742 548 946 131 1 +838 254 983 970 0 +494 256 210 204 0 +677 897 119 241 1 +182 345 206 130 1 +136 94 737 154 1 +901 390 977 447 0 +503 549 553 747 1 +192 173 789 505 0 +17 433 30 32 0 +579 617 366 120 0 +909 124 112 751 0 +744 736 563 94 0 +563 736 79 1013 1 +785 718 650 253 0 +716 631 694 924 0 +212 129 746 548 1 +963 948 839 775 0 +326 672 294 852 0 +298 820 1 372 0 +704 966 69 249 1 +775 240 576 226 1 +425 252 796 440 0 +473 795 793 328 0 +116 732 1014 5 1 +681 142 126 611 1 +207 747 553 187 1 +318 742 302 936 0 +362 302 548 742 0 +402 296 689 908 1 +312 737 144 205 1 +436 632 224 696 0 +619 679 904 686 0 +875 715 587 558 1 +145 495 316 260 0 +335 198 914 186 1 +762 133 749 554 1 +815 152 731 605 1 +299 743 960 137 0 +3 990 764 480 0 +4 336 261 259 1 +917 603 671 561 1 +131 921 739 962 1 +575 244 861 833 0 +90 556 387 584 0 +977 435 872 160 1 +283 968 398 692 0 +675 106 377 790 1 +950 502 364 335 1 +905 788 823 408 0 +1027 528 442 69 1 +763 103 1012 901 1 +335 494 198 186 0 +742 969 946 310 1 +279 451 9 49 0 +1008 167 1011 166 1 +738 600 465 547 0 +716 924 694 276 1 +211 589 820 218 0 +94 299 192 461 0 +139 4 202 898 1 +681 126 608 324 1 +692 392 283 660 1 +427 252 792 682 0 +280 759 587 449 1 +7 73 135 177 0 +405 815 317 731 1 +341 316 260 855 0 +932 599 1004 734 1 +532 86 441 168 1 +246 120 617 579 0 +441 86 533 168 1 +297 1 176 262 0 +458 938 688 510 1 +916 365 236 766 0 +409 408 822 229 0 +218 729 922 625 1 +427 81 959 236 0 +398 436 695 392 1 +258 253 913 955 0 +297 486 176 489 1 +118 539 439 229 0 +432 620 663 528 1 +992 784 712 484 0 +578 302 72 962 1 +1011 103 1012 763 1 +850 309 952 848 1 +7 139 73 848 0 +964 781 544 358 1 +146 845 431 760 1 +491 868 566 742 0 +117 827 224 793 1 +133 554 182 270 1 +80 124 698 909 1 +384 438 632 146 0 +845 431 1012 895 1 +760 1012 536 895 1 +894 125 656 249 1 +1016 240 115 807 1 +993 753 994 929 0 +993 896 98 753 0 +206 137 743 189 0 +182 554 743 206 0 +3 764 895 1011 1 +749 305 570 141 0 +417 420 155 849 0 +369 616 237 690 0 +961 959 316 269 0 +964 708 781 577 1 +177 165 726 656 1 +191 756 133 148 0 +271 712 449 558 1 +719 385 927 925 0 +618 116 732 284 1 +70 831 371 143 0 +220 1016 407 951 1 +731 932 223 172 1 +811 384 632 146 0 +130 749 345 141 0 +194 14 988 67 0 +180 164 494 941 1 +323 574 226 547 0 +76 613 409 380 0 +796 628 367 609 0 +690 677 323 802 1 +901 390 691 977 0 +369 802 821 89 1 +773 208 360 1022 0 +346 806 278 459 1 +839 576 92 366 0 +838 970 934 36 0 +724 910 986 886 0 +986 910 475 886 1 +986 999 886 475 1 +618 466 732 636 1 +870 888 980 644 1 +223 933 1005 495 1 +334 743 570 960 0 +1010 151 1005 316 1 +1012 3 1011 763 1 +611 685 271 121 0 +324 683 126 140 0 +903 604 430 171 1 +318 685 91 131 0 +687 1016 115 807 0 +928 455 281 642 1 +364 335 835 950 0 +402 805 25 389 0 +704 579 246 69 1 +5 734 114 227 1 +615 9 244 60 0 +146 1012 239 429 1 +766 236 531 289 0 +339 773 947 357 0 +1008 1009 1006 606 1 +790 106 377 827 0 +231 86 532 168 1 +723 157 630 161 0 +306 320 139 678 1 +142 259 568 611 0 +802 467 821 89 0 +169 232 122 993 0 +502 295 907 216 0 +793 421 224 665 1 +782 106 827 706 0 +249 667 69 530 1 +805 543 513 296 1 +657 606 168 71 1 +382 425 767 628 0 +976 543 513 594 0 +156 190 918 726 0 +788 469 408 676 1 +533 404 688 903 0 +706 782 377 328 0 +515 809 633 105 1 +604 1006 1011 171 1 +590 535 916 151 0 +632 425 243 108 1 +815 605 74 106 0 +154 215 552 312 0 +96 1017 924 659 0 +781 302 207 338 0 +868 759 566 865 1 +481 910 996 986 1 +400 504 593 900 1 +267 342 685 147 0 +631 439 666 606 1 +382 425 628 796 0 +337 711 181 282 0 +1012 229 239 82 1 +1010 1003 488 933 1 +167 2 234 443 1 +501 88 751 1004 1 +29 445 433 32 0 +706 106 827 424 0 +305 762 749 570 1 +507 725 453 660 0 +814 695 397 629 1 +337 800 181 381 0 +463 764 692 365 0 +786 75 979 560 0 +5 86 443 385 0 +570 762 749 743 1 +215 737 552 312 0 +1011 1005 1010 764 1 +103 872 526 171 0 +847 195 302 781 0 +361 198 502 335 1 +393 807 679 140 0 +143 831 373 79 0 +299 1013 505 137 1 +787 818 493 448 1 +692 591 479 725 0 +1009 439 1006 606 1 +103 977 872 171 0 +470 951 284 1016 0 +739 198 72 216 1 +537 444 110 123 1 +192 672 1 298 0 +467 369 89 452 1 +1023 725 507 506 0 +48 31 641 719 0 +46 641 927 48 0 +428 851 1010 998 1 +584 680 245 90 0 +262 161 630 492 0 +697 718 569 906 0 +431 670 146 1012 1 +446 71 634 669 0 +47 292 21 67 0 +320 674 188 798 0 +788 905 814 408 0 +944 753 697 396 0 +350 769 853 209 1 +827 322 243 106 1 +513 389 25 56 0 +176 2 183 404 0 +924 534 631 694 0 +831 448 395 155 0 +691 809 597 901 0 +295 180 555 502 0 +242 245 90 673 1 +186 214 747 210 0 +176 234 2 404 0 +614 183 2 430 0 +648 971 347 844 1 +872 506 159 622 1 +256 381 573 254 0 +576 643 92 366 0 +832 40 939 880 0 +666 446 17 58 0 +596 403 512 818 0 +992 271 712 449 1 +457 948 608 656 1 +527 384 696 146 1 +796 252 152 440 0 +97 664 492 630 0 +524 913 185 228 0 +673 242 79 899 0 +608 839 963 948 1 +473 328 421 621 1 +223 251 172 932 1 +448 831 395 373 0 +493 315 448 373 1 +159 3 991 480 0 +544 703 387 355 0 +514 219 695 659 0 +208 658 635 163 0 +407 951 467 1015 1 +140 393 608 457 0 +771 528 663 547 0 +527 905 809 429 1 +703 556 387 355 0 +634 669 532 66 0 +1022 163 208 622 0 +135 242 197 141 0 +846 1000 285 955 0 +194 836 999 988 0 +242 143 79 141 0 +788 1018 823 408 0 +1023 435 506 977 1 +535 916 560 590 1 +946 491 566 742 0 +837 211 264 557 1 +1020 1027 442 530 1 +728 184 567 750 1 +231 86 441 532 1 +225 469 248 612 0 +195 302 781 338 0 +324 611 126 683 0 +565 548 943 969 0 +70 233 898 798 0 +557 357 947 840 0 +740 840 357 557 0 +569 718 261 955 0 +340 4 259 336 1 +596 512 448 818 1 +70 233 4 898 0 +323 528 109 246 1 +273 884 714 640 1 +164 198 72 739 1 +941 180 574 323 0 +319 508 403 145 0 +804 406 623 691 1 +935 1022 766 996 0 +244 790 795 422 0 +928 642 281 784 1 +19 939 21 47 0 +985 875 587 558 0 +223 319 251 933 1 +223 319 933 495 1 +610 322 797 830 1 +813 129 196 356 1 +94 1013 192 736 1 +409 613 408 380 0 +117 830 793 250 1 +743 189 423 282 0 +29 433 446 32 0 +29 100 446 433 0 +329 328 782 706 1 +72 707 138 332 1 +661 173 432 1020 0 +540 9 6 445 0 +1004 127 733 734 1 +446 29 17 58 0 +822 676 416 408 0 +92 237 366 617 0 +168 231 122 657 1 +787 371 448 315 1 +178 787 448 315 1 +178 448 680 315 1 +448 493 680 315 1 +787 493 680 448 1 +178 787 680 448 1 +656 608 140 324 1 +814 778 659 1017 0 +278 911 388 454 0 +661 401 595 442 1 +876 1002 516 645 0 +52 688 31 641 0 +52 13 273 64 0 +938 802 452 89 1 +5 452 385 234 0 +865 975 450 602 0 +491 759 449 741 1 +411 468 1 820 0 +449 911 388 272 0 +81 603 671 917 1 +254 158 352 721 0 +810 398 695 514 1 +16 970 18 67 0 +805 13 273 52 0 +721 912 254 158 0 +910 885 723 160 1 +597 809 105 1025 1 +931 571 346 389 0 +1016 220 407 240 1 +281 929 346 931 0 +364 835 314 950 0 +364 335 314 835 0 +517 472 19 649 0 +950 335 835 361 1 +616 452 938 369 0 +275 94 144 136 0 +789 461 254 275 1 +82 1025 901 456 0 +592 385 533 927 0 +254 352 275 721 1 +1025 691 597 901 0 +862 879 587 985 1 +941 494 835 314 1 +912 465 158 721 0 +212 129 638 301 0 +603 917 236 107 1 +603 561 917 107 1 +907 638 699 301 0 +310 772 602 757 0 +397 219 514 659 0 +975 888 867 450 0 +451 717 279 386 1 +1004 88 731 913 1 +1024 875 519 652 0 +879 878 651 587 1 +82 456 235 175 0 +374 661 624 824 1 +490 953 269 75 1 +442 941 667 69 0 +826 421 621 473 0 +692 107 384 633 0 +696 633 811 384 1 +259 568 611 685 0 +224 329 581 363 0 +29 9 445 32 0 +327 180 240 574 0 +1017 924 659 814 0 +549 748 256 300 0 +135 143 73 306 0 +98 127 733 751 1 +689 738 908 638 1 +192 789 372 275 0 +769 556 355 209 1 +467 929 1015 896 0 +690 802 369 938 1 +616 369 938 690 0 +188 798 371 320 0 +511 688 400 52 0 +43 721 926 465 0 +198 494 72 914 0 +208 552 312 625 0 +902 905 239 105 1 +555 91 686 134 1 +566 91 915 685 0 +452 938 234 616 0 +602 296 908 757 1 +748 756 546 133 0 +748 549 546 756 0 +317 1026 287 818 0 +133 756 546 305 1 +585 174 331 414 1 +254 800 529 352 0 +90 387 245 584 0 +403 1026 145 317 0 +704 579 69 966 1 +593 803 630 727 0 +436 692 811 633 1 +87 162 344 308 1 +178 190 680 148 1 +131 739 91 302 1 +810 607 291 586 0 +782 827 709 424 0 +599 932 88 101 1 +944 569 718 753 0 +262 325 852 958 1 +808 13 571 462 0 +187 138 553 207 0 +494 300 256 204 0 +828 612 414 419 0 +605 440 735 170 1 +14 970 1019 51 0 +524 979 493 818 0 +747 300 549 214 0 +164 300 204 150 1 +959 81 531 236 0 +146 108 845 359 0 +690 938 897 802 1 +710 772 777 310 0 +338 578 943 777 0 +611 257 685 683 0 +446 175 606 71 1 +589 492 729 218 0 +586 841 291 778 1 +139 340 848 202 1 +340 848 70 139 0 +387 899 355 556 1 +1014 167 234 5 1 +5 385 443 234 0 +531 671 81 252 1 +340 73 70 848 0 +946 550 131 548 1 +566 741 761 356 1 +238 265 172 230 0 +771 180 574 547 0 +877 880 19 54 0 +548 962 578 746 1 +934 354 832 292 0 +552 311 144 333 1 +381 418 461 624 0 +202 4 340 336 1 +139 4 340 202 1 +850 259 681 257 0 +168 86 533 604 1 +208 93 635 311 1 +204 300 334 748 0 +362 195 772 338 1 +98 569 944 753 0 +295 739 907 216 0 +207 302 332 338 0 +976 543 594 450 0 +388 911 277 454 0 +908 805 467 738 0 +415 621 700 665 0 +951 576 821 369 1 +393 284 115 807 0 +287 11 982 63 0 +838 210 747 214 0 +913 501 906 228 0 +497 815 405 731 1 +749 270 554 133 1 +186 494 210 204 0 +946 550 91 131 0 +796 152 815 440 0 +259 351 124 568 0 +358 772 777 710 0 +938 89 897 802 1 +390 476 102 456 0 +934 18 292 47 0 +226 323 617 574 1 +920 83 625 922 1 +741 806 255 761 1 +148 918 567 750 1 +955 501 253 906 0 +922 83 625 492 1 +214 556 549 756 0 +552 922 321 154 0 +652 396 753 911 1 +952 309 850 257 0 +850 257 203 952 1 +1008 1003 167 166 1 +154 737 552 215 0 +379 731 815 497 1 +165 92 237 366 1 +177 135 726 165 1 +177 73 135 165 1 +923 313 217 78 0 +217 313 87 78 0 +73 165 143 135 1 +148 313 217 923 0 +148 923 217 191 0 +729 820 372 321 0 +705 922 729 321 0 +705 729 372 321 0 +307 165 839 284 1 +820 468 729 492 0 +220 467 805 459 0 +1015 467 220 459 0 +904 459 1015 220 0 +220 904 134 1015 0 +220 1015 134 687 0 +807 220 134 687 0 +807 904 134 220 0 +687 470 220 1015 1 +470 951 220 1015 1 +470 1016 220 951 1 +687 1016 220 470 1 +572 870 645 522 1 +44 24 221 61 0 +49 221 24 61 0 +49 39 221 61 0 +39 28 221 61 0 +42 524 24 49 0 +524 221 24 49 0 +39 28 644 221 0 +221 39 1021 644 0 +164 619 656 125 1 +860 656 948 125 1 +963 656 948 860 1 +221 39 274 1021 0 +221 39 717 274 0 +978 221 717 274 0 +221 717 451 978 0 +177 344 268 656 1 +394 894 627 460 1 +42 451 221 49 0 +49 279 451 221 0 +221 279 451 717 0 +49 279 221 717 0 +49 39 717 221 0 +572 522 222 653 0 +718 261 271 685 0 +806 272 388 278 0 +346 806 459 693 1 +108 613 409 735 1 +538 794 675 444 0 +193 342 147 304 0 +755 264 370 542 0 +737 744 144 205 1 +692 479 365 725 0 +341 961 316 855 0 +407 467 600 738 0 +549 748 546 350 0 +891 912 36 62 0 +899 305 79 209 0 +946 685 91 566 0 +96 1018 666 631 0 +238 770 856 351 1 +1014 489 1013 165 1 +268 179 344 203 0 +143 373 831 315 0 +581 706 782 424 1 +853 769 954 209 1 +233 172 898 674 0 +760 845 895 949 1 +158 547 926 465 0 +313 498 199 78 0 +933 488 95 251 1 +390 691 623 812 1 +358 343 559 859 0 +5 114 443 86 0 +3 483 725 536 0 +904 134 113 686 1 +806 278 389 543 0 +722 658 635 625 0 +438 531 662 425 1 +187 90 556 756 0 +421 700 224 665 1 +498 306 178 313 1 +313 306 178 190 1 +350 556 214 769 0 +289 628 382 767 0 +136 730 1 489 1 +114 714 817 930 0 +634 71 532 669 0 +1019 723 589 886 0 +790 377 610 328 0 +658 161 727 724 1 +580 735 613 110 1 +887 492 149 881 1 +567 184 197 130 0 +920 635 201 312 0 +199 308 304 8 1 +330 325 768 349 1 +617 690 323 802 1 +46 31 641 48 0 +718 501 569 906 0 +366 237 120 617 0 +962 72 739 302 1 +131 962 739 302 1 +458 510 688 592 1 +554 345 743 206 0 +941 150 314 303 1 +179 342 683 267 0 +789 461 192 624 0 +921 638 907 301 0 +212 638 921 301 0 +362 742 286 936 0 +180 361 198 216 1 +211 820 372 218 0 +306 498 139 7 1 +683 267 685 147 0 +449 981 967 741 0 +737 94 744 563 1 +220 467 407 738 0 +677 620 109 528 1 +109 677 326 620 1 +563 752 79 899 0 +922 920 312 625 0 +153 899 79 752 0 +877 22 982 59 0 +613 735 799 538 1 +83 998 437 201 0 +382 531 252 425 0 +810 586 700 863 0 +479 151 365 478 0 +902 527 905 105 1 +341 535 269 490 1 +943 777 772 310 0 +783 752 942 391 0 +618 227 169 127 0 +27 877 22 982 0 +707 503 553 747 1 +772 943 358 777 0 +919 503 213 745 1 +553 549 187 214 1 +348 285 834 864 0 +781 309 336 952 0 +500 524 258 410 0 +7 190 135 306 0 +641 592 688 927 0 +1008 166 1011 1006 1 +677 504 620 547 0 +758 916 959 939 0 +939 758 531 959 0 +591 692 453 725 0 +939 916 959 766 0 +959 916 236 766 0 +505 1013 173 165 1 +1013 672 173 165 1 +326 504 900 97 1 +513 543 389 594 0 +400 241 504 900 1 +326 241 900 504 1 +326 504 677 241 1 +677 897 241 504 0 +326 620 677 504 1 +527 905 1025 809 1 +939 959 531 236 0 +1014 489 165 672 1 +1014 77 489 672 1 +137 141 505 626 1 +399 137 505 626 1 +399 401 626 505 0 +505 626 661 401 0 +374 505 661 401 0 +399 401 505 374 0 +299 137 505 399 1 +986 481 883 475 1 +385 592 234 510 0 +592 938 510 385 0 +508 145 684 405 0 +791 508 405 317 0 +76 1007 735 580 1 +733 127 1004 751 1 +599 101 88 124 0 +406 506 429 809 0 +791 508 684 405 0 +403 145 508 405 0 +558 911 928 449 1 +768 158 349 547 0 +460 394 509 627 0 +949 735 845 895 1 +561 895 949 760 1 +337 394 181 509 0 +515 809 105 597 1 +691 977 809 103 0 +768 262 593 958 0 +234 430 2 510 0 +511 89 273 738 0 +897 89 511 738 0 +547 897 511 738 0 +897 89 458 511 0 +511 89 458 273 0 +897 458 688 511 0 +897 510 511 688 1 +511 510 404 688 1 +511 688 404 803 0 +511 404 119 803 1 +511 510 119 404 1 +897 510 119 511 1 +803 511 688 400 0 +504 241 511 547 0 +541 868 878 651 0 +56 389 874 62 0 +56 874 383 62 0 +1024 272 449 806 0 +95 319 508 512 0 +512 319 508 403 0 +976 450 274 978 1 +866 942 128 854 0 +105 633 515 696 1 +515 633 811 696 1 +515 811 436 696 1 +902 515 436 696 1 +105 515 902 696 1 +812 515 902 105 1 +812 392 902 515 1 +695 515 902 392 1 +695 436 515 392 1 +392 436 515 660 1 +660 633 436 515 1 +515 633 436 811 1 +660 429 633 515 0 +406 392 515 660 1 +406 392 623 515 1 +623 392 812 515 1 +695 436 902 515 1 +516 253 386 451 0 +713 253 516 451 0 +645 253 516 713 0 +785 715 1002 650 1 +517 833 12 37 0 +12 517 37 57 0 +50 37 517 57 0 +50 517 96 57 0 +12 96 517 57 0 +517 50 96 833 0 +833 517 412 96 1 +517 649 412 96 1 +96 649 472 517 1 +96 924 517 472 0 +517 924 716 472 0 +96 924 716 517 0 +833 649 412 517 1 +649 877 517 833 0 +649 347 517 877 0 +37 50 517 833 0 +518 541 967 651 1 +890 653 525 980 0 +222 653 522 890 0 +462 519 386 272 1 +462 571 519 272 1 +272 571 519 911 1 +519 462 808 571 1 +386 462 808 519 1 +318 520 651 957 0 +318 491 520 957 0 +318 491 651 520 0 +651 491 879 520 0 +651 879 862 520 1 +862 879 985 520 1 +520 651 518 862 0 +1001 518 1000 654 0 +645 862 1001 654 0 +955 336 541 520 0 +336 309 541 520 0 +336 309 520 261 0 +261 336 955 520 0 +222 890 522 525 1 +525 967 864 653 0 +44 221 523 891 0 +980 967 864 525 0 +654 253 521 185 0 +391 24 370 523 0 +523 647 869 370 0 +523 858 647 370 0 +370 523 858 544 0 +858 523 964 544 0 +544 523 964 577 0 +523 653 964 577 0 +111 9 42 615 0 +935 481 840 1022 0 +724 910 157 477 1 +56 513 389 62 0 +103 526 434 171 0 +763 901 1012 429 1 +70 798 831 488 1 +373 315 79 242 0 +210 937 290 838 1 +210 974 866 942 0 +725 764 463 536 0 +819 899 355 387 1 +1012 103 1006 447 1 +83 997 887 998 1 +46 31 476 641 0 +566 356 946 969 1 +279 462 386 272 1 +943 548 338 777 0 +657 446 606 71 1 +920 312 201 215 0 +169 122 231 817 0 +205 752 563 744 0 +569 98 906 501 1 +327 113 904 555 0 +666 118 439 631 0 +890 980 222 645 0 +771 502 364 950 1 +320 263 898 496 1 +614 1011 995 434 1 +899 90 242 305 1 +708 858 496 247 0 +552 737 144 312 1 +385 86 443 234 0 +193 179 342 344 1 +447 103 1006 1011 1 +761 464 908 212 0 +560 758 542 311 0 +149 664 183 614 0 +732 116 92 284 1 +1007 731 487 166 1 +334 299 256 381 0 +34 517 716 276 0 +495 1010 488 933 1 +352 529 349 158 0 +319 145 403 596 0 +938 802 369 452 1 +947 773 840 357 0 +696 436 902 629 1 +146 359 845 949 0 +827 367 224 609 1 +489 77 1 672 1 +357 208 773 840 0 +122 232 445 540 0 +92 616 237 369 0 +513 543 689 296 0 +194 883 935 475 0 +529 789 254 352 1 +451 253 386 185 0 +772 348 565 834 0 +270 130 182 750 1 +268 203 681 179 0 +258 500 562 564 0 +687 121 753 134 0 +629 810 436 695 1 +794 170 675 444 0 +292 15 934 970 0 +765 615 111 104 0 +393 115 608 457 0 +84 537 110 123 1 +583 331 174 580 1 +961 316 1010 260 1 +629 586 778 621 0 +797 444 110 538 0 +127 733 169 232 1 +777 548 578 710 1 +360 758 773 766 0 +952 199 498 781 0 +3 103 434 1011 1 +187 584 214 556 0 +221 655 870 572 1 +992 484 545 346 0 +314 337 800 824 0 +612 419 248 244 0 +314 337 824 200 0 +941 204 494 314 1 +489 1 176 297 1 +228 1004 111 99 1 +991 882 990 480 1 +991 722 882 480 1 +1017 778 659 219 0 +399 374 418 423 0 +732 142 165 73 1 +499 9 6 540 0 +205 563 153 744 0 +618 227 732 116 1 +469 248 1018 408 1 +520 309 541 957 0 +7 162 156 308 0 +239 229 534 82 1 +1021 28 39 62 0 +546 133 749 762 1 +413 379 317 405 0 +621 825 586 778 1 +788 376 826 825 0 +299 423 399 418 0 +756 187 90 148 0 +191 187 756 148 0 +916 93 360 311 1 +503 138 553 745 1 +304 257 342 957 0 +697 571 396 652 1 +229 539 534 1012 1 +170 426 605 106 0 +605 426 74 106 0 +148 197 756 133 1 +305 756 749 133 1 +756 197 749 133 1 +180 494 198 361 1 +262 630 97 492 0 +527 670 696 665 0 +912 23 36 62 0 +203 257 681 179 0 +254 573 288 275 0 +595 667 530 442 1 +692 384 438 811 0 +125 574 1028 69 1 +1026 75 145 682 0 +205 635 560 311 1 +635 93 560 311 1 +107 438 561 917 0 +1012 431 539 1006 1 +133 270 182 750 1 +937 557 354 836 1 +144 299 954 94 0 +913 88 856 501 0 +783 333 573 128 0 +212 921 134 196 0 +692 436 283 392 1 +57 96 1018 58 0 +20 593 31 52 0 +146 108 359 632 0 +268 324 683 179 0 +785 955 718 253 0 +153 752 79 563 0 +360 93 208 311 1 +82 534 175 1006 1 +146 536 763 429 1 +1013 736 79 141 1 +453 392 804 507 0 +212 464 908 638 0 +831 596 448 155 0 +845 108 940 359 0 +9 185 906 228 0 +305 133 749 546 1 +75 786 155 849 0 +913 253 185 906 0 +805 402 467 738 0 +1027 668 246 965 0 +738 402 601 689 1 +148 190 242 197 1 +151 959 269 535 0 +951 369 821 467 1 +216 551 962 301 1 +350 853 256 209 1 +190 143 242 135 0 +190 242 197 135 0 +97 803 900 664 0 +70 898 4 139 0 +135 143 242 141 0 +528 677 620 547 0 +528 323 677 547 0 +192 672 173 1013 1 +76 409 431 539 0 +76 580 613 779 0 +247 787 818 493 0 +549 556 214 350 0 +970 15 934 36 0 +898 238 770 353 1 +209 960 736 853 0 +898 353 770 496 1 +5 1008 114 734 1 +196 129 761 212 1 +187 556 214 756 0 +565 943 772 310 0 +98 733 1004 751 1 +1012 1011 895 1006 1 +318 541 936 846 0 +799 322 243 378 1 +733 122 100 657 1 +307 142 165 284 1 +244 426 675 790 0 +740 208 333 773 1 +681 257 611 683 0 +181 374 418 824 1 +574 180 125 327 0 +42 524 99 500 0 +344 179 342 203 1 +897 89 688 458 0 +180 555 502 739 0 +478 622 483 479 0 +340 956 848 202 1 +202 952 848 199 1 +498 202 848 199 1 +139 202 848 498 1 +479 289 591 692 0 +580 76 1009 588 1 +327 180 113 555 0 +598 406 809 977 0 +89 938 688 458 1 +549 503 553 213 1 +300 549 748 213 0 +278 462 389 383 0 +205 590 953 560 1 +212 550 921 196 0 +538 170 794 444 0 +859 343 747 132 0 +900 664 176 97 0 +209 305 79 736 0 +626 173 505 661 0 +853 299 736 954 0 +550 212 746 548 1 +743 299 423 189 0 +805 296 513 908 1 +117 322 830 378 1 +806 388 255 346 1 +773 740 208 357 0 +947 557 755 264 1 +378 676 799 830 0 +700 810 629 586 0 +80 284 126 687 0 +954 744 752 205 0 +344 342 304 203 1 +480 995 997 428 0 +87 344 304 308 1 +186 503 914 747 0 +373 245 242 673 1 +222 525 522 980 1 +335 198 502 914 1 +335 914 502 364 1 +914 503 72 747 0 +344 203 304 308 1 +462 279 185 808 1 +60 833 50 65 0 +413 791 379 403 0 +146 1012 670 239 1 +918 184 197 567 0 +165 1014 237 92 1 +180 494 164 198 1 +701 348 362 772 1 +385 86 234 592 0 +322 794 675 538 0 +182 554 206 345 1 +308 203 304 8 1 +554 130 182 270 1 +237 690 109 617 0 +412 1017 825 96 0 +259 261 568 685 0 +144 333 205 854 0 +612 244 248 225 0 +749 197 270 133 1 +620 958 349 547 0 +350 556 209 305 1 +852 958 504 97 1 +70 798 371 831 0 +630 991 474 881 1 +772 834 565 867 0 +373 155 673 79 0 +822 613 378 408 0 +591 1022 766 479 0 +85 666 17 58 0 +272 278 389 383 0 +164 268 656 683 1 +867 981 969 865 0 +505 1013 165 141 1 +125 327 1028 574 1 +758 311 360 333 1 +783 288 211 128 1 +164 460 150 303 1 +477 872 526 159 1 +391 290 264 819 0 +5 167 1008 734 1 +43 1019 593 768 0 +323 579 617 574 1 +131 685 91 946 0 +730 79 490 155 1 +427 792 81 603 1 +694 105 812 902 1 +904 679 134 686 0 +1019 262 593 768 0 +196 129 212 548 1 +216 907 551 301 0 +665 700 629 621 0 +956 340 142 259 0 +528 620 663 547 0 +148 918 197 567 1 +569 98 80 753 0 +668 672 165 173 1 +1028 327 775 574 1 +741 255 545 761 1 +210 934 290 942 0 +138 302 332 207 0 +250 376 793 473 0 +42 244 27 68 0 +252 792 152 440 0 +431 1012 146 760 1 +732 1003 1014 5 1 +992 712 545 484 0 +298 325 411 330 1 +6 9 615 104 0 +104 9 615 60 0 +409 108 431 670 0 +174 615 225 60 0 +174 104 615 60 0 +332 207 132 553 1 +941 180 323 771 0 +615 612 123 174 0 +807 220 687 240 1 +925 669 532 441 0 +142 4 124 259 0 +193 267 147 342 0 +111 615 42 84 0 +705 658 625 740 0 +523 934 391 44 0 +1009 733 1004 6 1 +669 71 666 66 0 +577 781 358 338 1 +515 429 633 809 1 +149 486 995 1011 1 +698 124 618 909 1 +756 899 556 305 1 +756 90 899 305 1 +368 232 540 733 1 +733 1009 1004 1008 1 +110 1007 580 735 1 +822 108 670 665 0 +594 272 389 383 0 +427 959 758 639 0 +345 743 137 749 0 +882 590 998 987 0 +608 126 393 140 0 +931 13 346 571 0 +1011 614 604 171 1 +748 762 780 182 0 +354 290 934 832 1 +143 488 79 1013 1 +760 1012 845 431 1 +962 746 301 551 1 +661 432 330 663 1 +531 365 236 671 0 +744 954 736 94 0 +661 330 529 663 1 +415 229 905 670 0 +807 904 220 240 0 +382 425 796 632 1 +6 765 111 104 0 +6 9 765 615 0 +6 615 765 104 0 +24 1026 287 979 0 +55 871 476 482 0 +126 807 80 687 0 +621 473 329 586 1 +650 261 718 955 0 +71 657 634 532 0 +603 1005 236 959 1 +1019 266 768 926 0 +384 107 438 760 0 +791 508 403 375 0 +961 151 1010 316 1 +261 520 955 785 0 +897 938 119 510 1 +757 358 559 710 0 +162 177 344 308 1 +547 738 802 89 0 +114 714 930 86 0 +741 806 813 356 0 +408 248 380 676 1 +272 462 278 383 0 +120 965 165 894 1 +687 1016 284 115 0 +632 108 696 146 0 +255 346 545 693 0 +397 514 695 659 0 +527 670 146 696 1 +795 422 328 473 0 +561 107 603 895 1 +377 794 106 675 1 +730 94 490 563 1 +533 604 903 102 1 +3 103 1011 763 1 +678 320 371 306 1 +42 244 60 65 0 +509 401 824 442 1 +244 42 27 65 0 +193 179 683 267 1 +244 9 42 60 0 +593 803 31 400 0 +457 115 608 948 0 +604 614 430 171 1 +615 244 225 60 0 +434 3 991 103 0 +407 555 240 904 0 +450 806 741 865 0 +203 342 257 179 0 +257 342 681 179 0 +205 635 590 560 1 +635 93 590 560 1 +590 916 560 93 1 +988 482 21 67 0 +703 355 214 556 0 +211 740 783 357 1 +763 103 901 429 1 +134 904 212 196 0 +507 506 725 660 0 +1013 137 736 141 1 +662 632 224 436 0 +704 249 69 530 1 +438 425 662 632 1 +300 503 549 213 0 +713 516 386 451 0 +982 35 880 54 0 +673 647 373 245 1 +124 101 732 599 1 +409 613 822 408 0 +189 206 394 282 1 +282 189 816 394 0 +634 100 29 122 0 +657 100 634 122 0 +122 657 231 634 1 +446 100 634 657 0 +71 657 446 634 0 +446 100 29 634 0 +148 217 728 191 0 +627 164 303 460 1 +882 722 987 480 1 +566 969 946 742 1 +144 954 744 94 0 +560 639 758 916 0 +637 699 757 559 0 +757 637 559 358 0 +637 343 559 358 0 +757 772 637 358 0 +145 319 684 223 1 +365 603 236 107 1 +365 1005 236 603 1 +977 406 809 506 0 +560 639 916 535 1 +646 435 1023 977 1 +757 356 129 602 0 +297 922 729 492 1 +427 639 758 560 0 +682 639 427 560 0 +682 75 639 560 0 +682 75 427 639 0 +882 987 998 428 0 +991 3 995 480 0 +480 3 995 428 0 +538 444 735 170 1 +108 799 735 243 1 +720 642 784 931 1 +720 571 642 931 0 +851 882 437 998 0 +433 733 1009 6 1 +599 1004 88 932 1 +571 455 931 396 0 +231 114 817 930 0 +467 369 452 485 1 +485 5 369 452 0 +720 571 931 454 0 +1007 539 1006 1009 1 +485 5 452 714 0 +925 719 273 640 0 +640 719 273 64 0 +925 719 640 64 0 +925 48 64 640 0 +714 86 385 930 0 +930 86 385 925 0 +1022 479 885 989 1 +591 885 21 996 0 +991 3 434 995 0 +714 930 385 925 0 +930 925 273 640 1 +925 86 441 930 0 +653 654 708 972 0 +654 258 353 708 0 +726 177 656 162 1 +815 223 317 731 1 +152 223 603 682 1 +973 653 654 285 0 +42 221 524 49 0 +815 152 317 223 1 +815 152 223 731 1 +249 667 894 627 1 +223 1005 427 495 1 +894 164 125 249 1 +517 833 877 54 0 +517 34 12 833 0 +34 833 517 54 0 +713 876 386 645 0 +713 253 451 645 0 +656 963 702 860 1 +726 656 164 162 1 +177 307 656 268 1 +684 319 251 223 1 +370 673 647 417 1 +862 890 654 645 0 +648 287 844 843 1 +648 767 287 843 1 +945 767 648 843 1 +648 287 971 844 1 +880 971 648 287 1 +651 491 280 879 0 +945 19 841 649 0 +844 945 841 649 1 +844 649 841 575 1 +575 778 649 841 1 +575 778 1017 649 1 +29 640 64 66 0 +806 594 278 543 0 +439 1009 588 776 1 +490 953 849 153 1 +798 251 95 488 1 +366 963 839 775 0 +580 76 1007 1009 1 +76 539 1007 1009 1 +490 79 563 153 1 +437 151 961 535 0 +549 553 187 745 1 +998 997 887 428 1 +54 877 982 59 0 +631 534 175 82 0 +775 240 115 576 1 +800 158 529 352 0 +146 670 527 905 1 +388 449 992 277 1 +937 836 820 211 0 +273 13 640 64 0 +954 209 899 736 0 +1019 926 10 51 0 +565 548 362 943 0 +692 863 398 436 0 +158 663 349 547 0 +529 663 349 158 0 +789 173 298 661 0 +963 656 366 839 1 +972 293 708 195 0 +905 408 823 229 0 +34 877 19 54 0 +132 747 553 207 1 +702 860 966 249 1 +362 936 565 348 1 +689 402 601 513 0 +788 408 814 826 0 +632 628 224 665 1 +664 430 614 903 0 +145 260 316 75 0 +907 699 551 301 0 +1028 125 69 249 1 +781 304 952 78 0 +952 304 199 78 0 +465 926 768 547 0 +956 309 848 202 1 +758 916 360 311 1 +807 121 80 687 0 +253 501 718 906 0 +666 71 446 66 0 +846 336 770 708 0 +896 753 929 1015 0 +618 909 466 698 1 +898 4 202 496 1 +820 468 321 729 0 +83 881 997 987 1 +905 823 439 229 0 +780 762 743 182 0 +527 415 905 670 0 +808 396 571 13 0 +1026 75 682 560 0 +879 1002 985 785 1 +593 262 97 958 0 +236 603 81 917 1 +466 909 636 698 1 +935 475 21 194 0 +1000 285 955 258 0 +534 631 439 229 0 +299 399 624 418 0 +474 171 526 477 0 +474 477 526 727 0 +502 295 914 551 1 +598 804 390 691 1 +664 903 614 171 0 +945 648 844 843 1 +85 446 17 666 0 +175 71 446 666 0 +180 494 361 835 1 +692 725 365 764 0 +836 557 354 935 1 +76 580 779 331 0 +138 207 332 553 0 +696 224 436 810 0 +1007 1005 166 895 1 +310 757 129 746 0 +828 419 414 110 0 +858 678 496 247 0 +858 680 678 787 0 +60 412 96 833 0 +888 834 653 975 0 +320 674 247 188 1 +1019 20 593 262 0 +247 678 496 320 1 +314 150 204 337 1 +294 672 325 852 0 +1 136 372 820 0 +161 658 630 589 1 +616 77 237 690 0 +760 895 536 107 1 +616 119 77 690 0 +119 677 690 897 1 +294 620 504 958 1 +619 140 679 801 0 +969 356 946 310 1 +431 108 146 670 0 +410 258 562 230 0 +539 670 431 229 0 +539 1006 1009 439 1 +531 438 662 671 0 +169 168 122 733 1 +272 571 278 462 0 +969 868 566 865 1 +929 753 396 281 0 +1007 166 1009 1006 1 +488 495 155 1010 1 +100 446 1009 733 1 +583 487 174 615 1 +379 829 24 74 0 +238 172 233 101 0 +238 88 172 101 0 +223 1005 166 1007 1 +668 672 173 432 0 +672 325 173 432 0 +295 907 559 551 1 +502 907 295 551 1 +338 302 332 548 0 +350 256 780 334 0 +256 300 334 204 0 +109 77 672 326 0 +502 295 186 914 1 +135 165 1013 141 1 +470 951 1015 896 1 +531 438 671 252 1 +848 309 952 202 1 +894 173 165 141 1 +917 438 365 107 0 +952 257 203 304 1 +82 606 175 447 1 +742 868 566 969 1 +683 685 121 147 0 +1016 576 407 951 1 +566 761 196 356 1 +98 127 368 733 1 +24 391 370 832 0 +399 374 423 816 0 +170 426 675 444 0 +170 426 106 675 0 +178 371 315 306 1 +489 672 1 192 1 +342 257 685 957 0 +782 609 224 329 1 +577 781 964 358 1 +242 680 90 245 1 +748 546 780 762 0 +681 259 142 611 0 +447 1011 1006 171 1 +681 611 126 324 0 +180 494 835 941 1 +306 178 678 498 1 +306 678 139 498 1 +139 202 498 678 1 +243 170 106 794 0 +326 852 504 97 1 +546 756 556 305 1 +209 853 736 954 0 +459 545 346 693 0 +326 677 119 241 1 +852 294 504 958 1 +346 389 805 459 0 +441 604 533 235 1 +70 320 898 139 0 +952 309 336 202 0 +560 758 832 755 0 +769 355 752 954 1 +307 126 608 681 1 +164 494 72 198 1 +795 422 473 825 0 +164 619 801 656 1 +776 580 1009 588 1 +639 560 953 535 1 +718 652 753 558 1 +611 259 685 257 0 +109 294 668 1027 0 +284 687 115 807 0 +783 311 819 542 0 +682 792 152 252 0 +117 793 224 665 1 +412 825 788 96 0 +585 588 776 774 0 +412 244 422 575 0 +206 137 189 345 1 +554 743 345 749 0 +691 809 901 103 0 +752 954 563 744 0 +617 802 323 226 1 +611 271 80 121 0 +271 915 753 121 0 +546 350 334 570 1 +271 685 915 121 0 +700 586 629 621 0 +216 502 551 907 0 +7 848 8 199 1 +685 91 121 686 1 +323 802 677 547 0 +848 952 8 199 1 +486 887 995 1011 1 +989 872 163 622 1 +258 353 238 410 1 +692 384 811 633 0 +323 547 226 802 0 +238 410 265 230 0 +410 562 497 230 0 +808 9 185 697 0 +90 673 387 899 1 +80 121 753 687 0 +56 389 383 874 0 +714 5 385 86 0 +199 952 8 304 1 +781 952 199 78 0 +594 274 874 976 1 +952 304 781 195 0 +471 1018 30 60 0 +338 332 132 578 0 +963 775 860 948 0 +149 167 486 1011 1 +928 281 753 712 1 +789 352 721 275 1 +656 125 860 249 1 +247 787 375 818 0 +925 927 719 48 0 +803 593 97 900 0 +533 903 688 102 0 +277 784 992 484 1 +262 161 589 468 0 +120 579 704 966 0 +896 369 467 485 1 +529 461 254 789 1 +674 684 405 791 0 +577 701 653 972 0 +701 973 653 972 0 +24 524 818 979 0 +181 401 824 509 1 +479 1022 360 622 0 +389 543 459 693 1 +561 107 895 760 1 +766 939 755 354 1 +290 838 934 210 1 +581 843 767 289 0 +775 643 576 366 0 +410 74 379 562 0 +512 508 188 403 0 +401 661 824 442 1 +831 95 188 512 0 +904 545 459 693 0 +536 760 384 146 0 +5 616 234 1014 1 +904 693 459 908 0 +13 717 9 39 0 +814 905 902 527 0 +654 708 353 247 0 +679 327 948 457 1 +294 432 620 349 1 +998 486 1010 428 1 +869 395 979 786 1 +718 569 80 753 0 +694 534 631 82 0 +239 534 694 82 0 +390 871 646 977 0 +741 813 761 356 1 +252 671 81 603 1 +761 129 196 813 1 +210 983 937 838 1 +629 778 814 621 0 +527 629 814 621 0 +393 115 457 948 0 +761 813 196 356 1 +741 806 761 813 1 +465 25 43 56 0 +105 239 902 694 0 +239 534 902 694 0 +579 1028 643 574 1 +458 592 688 641 1 +430 443 167 604 1 +321 920 154 922 1 +187 680 584 90 0 +323 246 574 69 1 +664 727 903 171 0 +688 404 592 510 0 +631 823 439 905 0 +90 680 148 187 0 +680 178 148 187 0 +752 209 899 954 0 +954 355 752 209 1 +23 721 10 43 0 +591 453 804 1023 0 +128 866 264 974 1 +911 455 281 928 1 +399 816 401 374 0 +271 753 80 121 0 +780 334 570 546 1 +458 938 510 592 1 +673 786 373 647 1 +42 9 185 451 0 +21 482 871 55 0 +433 100 733 445 1 +94 736 192 299 1 +659 924 694 902 1 +432 1020 857 1027 0 +986 883 999 475 1 +902 534 924 694 0 +615 471 612 174 0 +463 725 692 764 0 +45 482 46 55 0 +349 663 620 547 0 +855 961 316 269 0 +128 211 357 339 1 +318 131 302 742 0 +886 986 589 211 0 +146 940 431 845 0 +196 129 548 310 1 +700 329 224 863 0 +453 392 507 660 1 +743 762 554 182 1 +553 214 187 747 1 +89 719 458 273 0 +503 300 549 747 0 +196 550 91 946 0 +1008 168 606 604 1 +960 743 570 137 0 +866 256 288 837 0 +350 780 546 334 0 +102 447 604 903 1 +435 392 21 804 0 +360 208 93 1022 0 +756 197 242 305 1 +299 192 505 736 1 +680 178 678 787 0 +105 633 696 527 1 +365 107 438 692 0 +107 438 760 561 0 +358 859 559 710 0 +298 266 820 926 1 +376 676 797 469 1 +768 352 330 349 0 +560 916 311 93 1 +615 487 111 104 1 +192 505 789 624 0 +340 259 956 336 1 +850 309 259 257 0 +756 556 549 546 0 +116 369 92 951 0 +187 214 549 756 0 +442 528 663 771 0 +43 1019 10 51 0 +318 491 566 946 0 +404 510 430 592 0 +362 286 969 565 0 +358 943 132 710 0 +4 351 124 259 0 +80 687 753 896 0 +419 444 110 797 0 +743 137 299 189 0 +352 529 330 349 0 +566 741 356 759 1 +491 715 271 449 1 +921 550 134 196 0 +96 924 666 716 0 +276 472 659 219 0 +475 435 988 482 0 +865 772 975 602 0 +639 560 75 953 0 +362 302 338 548 0 +514 607 695 219 0 +743 762 749 554 1 +770 336 846 955 0 +254 158 800 352 0 +5 452 234 616 0 +749 197 141 130 0 +550 739 91 131 1 +373 417 786 673 0 +186 494 747 300 0 +747 494 503 300 0 +550 746 131 548 1 +305 197 141 749 0 +956 259 142 681 0 +76 735 613 580 1 +43 926 1019 465 0 +954 299 736 94 0 +820 411 468 1019 0 +186 494 503 747 0 +806 594 272 278 0 +148 750 197 133 1 +117 322 793 830 1 +231 817 122 634 0 +537 99 84 754 0 +84 754 99 111 0 +500 99 537 754 0 +998 590 437 201 0 +501 751 568 569 0 +76 118 408 539 0 +369 690 237 617 0 +867 286 969 981 0 +950 835 314 361 0 +253 185 652 386 1 +937 557 755 354 1 +299 743 334 960 0 +260 495 155 75 0 +717 383 594 874 1 +269 639 953 535 1 +355 769 214 556 0 +893 889 644 892 1 +663 1027 528 1020 1 +466 732 734 599 1 +496 247 263 353 0 +789 661 298 330 1 +117 377 827 793 1 +550 91 134 196 0 +665 629 415 621 0 +234 77 1014 616 1 +237 1014 165 672 1 +781 207 847 78 0 +268 681 324 179 0 +220 1015 407 467 0 +589 492 820 729 0 +350 256 960 209 1 +570 350 960 209 1 +951 369 92 576 0 +76 118 380 409 0 +739 91 134 550 0 +944 9 499 540 0 +689 601 976 62 0 +70 798 898 320 0 +871 435 977 160 1 +126 801 807 140 0 +570 305 137 141 0 +408 676 416 826 0 +885 435 482 160 1 +600 180 555 295 0 +913 955 856 258 0 +1010 316 495 260 1 +314 150 337 200 1 +812 515 597 691 1 +944 569 906 697 0 +953 590 535 560 1 +550 921 739 131 1 +318 541 742 936 0 +921 212 301 746 1 +751 98 909 569 0 +553 549 214 747 1 +786 560 979 832 0 +847 207 138 78 0 +560 758 311 916 1 +339 773 766 947 0 +153 420 79 899 0 +675 444 244 797 0 +355 556 899 209 1 +955 253 913 906 0 +530 894 857 965 1 +25 805 402 52 0 +894 656 966 249 1 +186 300 747 214 0 +702 1028 579 966 0 +307 268 344 203 0 +802 897 677 547 0 +124 88 599 751 0 +101 599 734 732 1 +851 764 1010 151 1 +136 489 1 192 1 +472 19 276 34 0 +370 647 979 786 0 +370 417 647 786 0 +148 567 197 750 1 +135 165 143 1013 1 +1012 1006 534 82 1 +505 192 1013 736 1 +604 1008 1011 1006 1 +605 796 815 440 0 +912 465 721 43 0 +696 632 224 665 0 +1013 141 505 137 1 +135 1013 143 141 1 +143 1013 79 141 1 +437 961 1010 260 1 +262 852 97 958 1 +765 9 111 615 0 +6 9 499 765 0 +499 9 228 765 0 +369 802 617 226 1 +92 576 369 617 0 +92 369 237 617 0 +952 309 257 304 0 +499 540 6 765 1 +576 369 617 226 1 +785 261 650 955 0 +544 207 343 358 1 +104 433 30 583 0 +157 910 886 723 0 +731 1004 166 932 1 +166 167 1011 1005 1 +292 354 832 47 0 +546 556 350 305 1 +314 941 200 442 0 +500 258 562 410 0 +653 572 654 222 0 +790 982 106 971 0 +166 731 487 1004 1 +382 796 628 632 1 +314 950 941 771 0 +14 16 970 51 0 +774 439 666 118 0 +488 831 95 798 1 +663 1020 528 442 1 +876 587 967 1024 0 +811 438 632 384 0 +692 107 438 384 0 +16 970 10 721 0 +822 416 117 415 0 +631 118 439 823 0 +820 136 372 321 0 +908 693 212 196 0 +520 879 985 1001 1 +545 761 693 196 0 +146 108 431 940 0 +847 304 195 781 0 +114 5 714 86 0 +914 746 551 559 0 +351 501 568 569 0 +255 693 545 761 0 +198 494 914 186 0 +935 840 354 766 1 +679 904 807 240 0 +385 86 592 533 0 +934 292 832 47 0 +915 741 566 759 1 +540 733 6 765 1 +506 3 159 763 0 +248 419 828 797 0 +90 899 387 556 1 +186 494 914 503 0 +100 446 606 657 1 +727 171 477 160 0 +195 772 577 701 1 +186 364 337 254 0 +693 761 212 196 0 +529 663 330 349 0 +330 432 349 663 1 +500 426 790 74 0 +790 426 675 74 0 +583 774 582 174 0 +583 776 85 774 0 +533 430 404 903 0 +846 936 362 348 1 +327 240 115 775 1 +463 905 527 429 1 +577 358 544 343 0 +772 358 577 343 0 +225 469 1018 788 0 +327 240 775 226 1 +731 1007 487 426 1 +776 439 666 774 0 +151 590 535 437 0 +946 356 196 310 1 +757 772 710 310 0 +93 590 916 151 0 +187 584 703 214 0 +323 246 579 574 1 +1022 208 93 622 0 +44 221 891 61 0 +808 540 944 368 0 +210 290 974 391 0 +548 129 746 777 1 +185 462 808 386 1 +104 583 30 174 0 +104 583 174 615 1 +415 629 527 621 0 +774 776 85 666 0 +680 190 90 148 1 +360 333 208 542 1 +178 315 680 190 1 +125 113 619 327 0 +125 180 113 327 0 +742 310 946 548 1 +707 503 138 553 1 +206 189 711 282 0 +166 895 1011 1006 1 +298 266 411 820 1 +875 253 652 516 0 +42 74 790 68 0 +337 210 254 256 0 +204 210 337 256 0 +910 160 157 477 1 +914 912 186 559 0 +702 860 1028 966 1 +426 605 444 170 1 +244 419 248 797 0 +330 661 298 432 1 +298 432 325 330 1 +777 129 746 310 1 +332 707 138 553 1 +710 548 578 746 1 +906 98 944 368 1 +548 129 777 310 1 +314 303 200 941 1 +69 941 125 574 0 +670 665 415 822 0 +208 311 552 333 1 +329 706 782 581 1 +76 118 409 408 0 +775 1028 366 702 0 +758 311 333 542 1 +942 752 783 333 0 +419 582 118 828 1 +823 419 118 828 1 +341 961 269 535 0 +696 384 811 146 0 +548 742 310 969 1 +953 560 75 786 0 +681 342 257 683 0 +304 957 342 147 0 +318 91 847 302 1 +342 957 685 147 0 +955 846 770 285 0 +898 770 4 496 1 +282 816 181 394 0 +943 548 777 310 0 +428 1011 1010 764 1 +203 850 681 257 0 +34 472 517 276 0 +426 1007 444 735 1 +770 336 496 202 0 +770 4 496 336 1 +257 342 685 683 0 +322 243 106 794 1 +221 24 523 524 0 +331 588 774 118 0 +941 180 125 574 0 +949 735 895 603 1 +332 302 72 578 1 +770 202 496 678 0 +195 701 362 772 1 +373 493 680 245 1 +970 14 194 67 0 +827 106 796 609 0 +906 944 499 368 1 +801 619 113 686 1 +624 661 789 529 1 +192 173 298 789 0 +208 722 93 163 0 +585 331 174 583 1 +656 165 366 839 1 +265 497 674 684 0 +99 913 564 228 0 +748 780 743 182 0 +4 340 70 139 0 +153 819 953 849 0 +73 848 307 8 0 +7 848 73 8 0 +75 786 849 953 0 +142 73 70 340 0 +4 142 70 340 0 +298 411 1 820 0 +153 819 849 420 0 +461 299 505 624 0 +482 885 475 435 0 +1003 1008 932 166 1 +179 342 681 683 0 +258 564 562 230 0 +345 137 743 206 0 +207 132 747 343 1 +482 476 435 871 0 +705 333 552 573 1 +980 525 864 653 0 +943 578 132 777 0 +932 933 233 1003 1 +63 982 971 68 0 +373 680 242 245 1 +149 614 1011 995 1 +542 773 758 339 0 +397 219 659 778 0 +771 502 361 180 0 +343 207 132 358 1 +773 758 339 766 0 +929 484 346 712 0 +308 177 344 8 0 +307 344 177 8 0 +307 203 344 8 0 +308 344 203 8 1 +739 216 962 301 1 +520 541 955 1000 0 +233 251 488 933 1 +856 770 955 351 1 +913 501 856 955 0 +506 660 429 725 0 +87 193 304 344 1 +193 342 304 344 1 +551 699 746 301 0 +618 124 466 909 1 +584 703 214 556 0 +237 672 165 668 1 +771 574 323 547 0 +770 336 955 261 0 +427 269 959 639 0 +102 927 925 48 0 +274 1021 39 62 0 +105 696 902 527 1 +945 767 842 648 1 +645 522 222 572 1 +536 107 384 760 0 +984 363 607 945 1 +521 654 572 645 1 +145 319 223 495 1 +981 280 759 587 0 +194 836 354 935 1 +594 450 274 976 1 +145 682 427 223 1 +398 968 695 514 0 +76 779 380 118 0 +527 696 902 629 1 +70 798 320 371 0 +70 320 306 371 0 +970 16 10 51 0 +722 630 881 991 1 +373 869 493 245 1 +464 129 757 638 0 +810 291 514 397 0 +354 947 755 766 1 +354 290 832 755 1 +863 329 363 984 0 +450 806 865 602 0 +684 251 172 223 1 +837 288 211 275 0 +294 109 620 528 1 +523 869 524 370 0 +4 261 336 770 1 +336 309 261 259 0 +307 956 142 681 0 +94 1013 136 192 1 +4 351 261 770 1 +849 260 155 75 1 +351 88 124 568 0 +351 88 101 124 0 +4 351 101 124 0 +4 351 233 101 0 +351 238 233 101 0 +351 88 238 101 0 +487 1007 166 1009 1 +296 689 908 757 1 +233 238 351 898 0 +233 351 4 898 0 +337 256 254 334 0 +913 501 955 906 0 +186 300 210 256 0 +186 256 210 494 0 +186 300 256 494 0 +257 309 957 304 0 +681 259 611 257 0 +581 709 609 767 0 +675 74 106 790 0 +833 244 27 65 0 +262 589 161 492 0 +610 830 797 250 1 +419 612 582 828 1 +573 705 275 136 0 +793 322 377 610 1 +865 806 741 602 0 +787 678 247 320 1 +178 787 315 371 1 +678 320 787 371 1 +178 678 787 371 1 +357 740 783 773 1 +783 773 542 357 1 +358 207 132 338 1 +358 207 338 781 1 +149 614 486 167 1 +204 711 337 150 0 +544 207 358 781 1 +438 425 632 359 1 +604 447 1006 171 1 +781 952 336 202 0 +146 359 760 438 0 +294 325 672 432 0 +202 199 498 952 0 +180 361 771 941 0 +903 447 604 171 1 +303 125 941 180 1 +927 385 533 441 0 +664 727 474 630 0 +34 517 877 54 0 +937 211 837 557 1 +169 231 168 114 1 +362 348 565 772 1 +747 707 859 132 0 +293 846 708 195 0 +821 576 226 369 1 +519 985 558 875 0 +778 844 841 575 1 +278 806 389 459 1 +100 606 733 168 1 +733 606 1008 168 1 +290 937 354 838 1 +774 585 331 414 1 +491 741 915 759 1 +19 347 648 880 0 +186 494 364 335 0 +364 494 204 335 0 +364 335 204 314 0 +337 364 204 314 0 +186 364 204 337 0 +186 494 204 364 0 +174 225 471 60 0 +936 285 834 348 1 +117 830 250 416 1 +486 887 1010 428 1 +915 685 491 566 0 +278 571 389 462 0 +908 761 212 693 0 +662 438 365 671 0 +918 190 148 197 1 +531 662 365 671 0 +904 693 908 196 0 +904 545 693 196 0 +917 438 561 671 0 +671 438 365 917 0 +790 827 377 782 0 +902 814 631 905 0 +128 942 783 854 0 +99 754 731 487 1 +1009 487 583 615 1 +434 614 1011 171 1 +1011 3 995 434 1 +1005 959 427 316 1 +495 1005 427 316 1 +699 746 559 551 0 +638 129 699 301 0 +176 234 404 900 0 +766 840 773 1022 0 +80 909 698 98 0 +959 639 269 535 0 +738 638 637 907 1 +638 699 637 907 1 +80 698 896 98 0 +900 234 404 119 0 +804 276 623 392 0 +127 232 169 368 0 +127 368 169 98 0 +695 19 392 276 0 +842 843 945 363 1 +309 304 952 195 0 +116 5 616 369 0 +766 354 21 939 0 +755 947 339 766 1 +966 1028 69 249 1 +858 787 678 247 0 +451 279 185 386 1 +83 492 149 887 1 +7 135 162 177 0 +123 444 612 419 0 +1024 587 558 985 0 +870 655 1021 644 1 +832 11 287 63 0 +577 972 708 195 1 +210 866 983 256 0 +772 338 358 943 1 +362 548 338 943 0 +358 338 132 943 0 +607 842 945 363 1 +276 19 392 804 0 +661 1020 663 442 1 +661 432 663 1020 1 +264 783 974 391 0 +988 435 21 482 0 +329 706 581 424 1 +601 638 757 637 1 +408 905 814 527 0 +1 852 468 325 0 +821 802 369 226 1 +284 92 1016 951 0 +827 665 367 796 1 +701 293 972 195 1 +389 462 25 383 0 +577 701 972 195 1 +247 787 188 375 1 +894 702 966 656 1 +882 480 987 997 0 +250 795 793 376 0 +675 377 610 790 1 +377 322 106 794 1 +380 828 797 248 0 +387 673 420 899 1 +956 259 681 850 0 +380 828 613 799 0 +833 225 412 244 0 +337 711 282 150 0 +244 790 575 861 0 +822 243 665 378 1 +409 378 822 613 1 +153 819 899 752 0 +1 136 820 321 0 +225 244 795 412 0 +244 469 248 225 0 +937 211 557 836 0 +707 332 72 578 1 +98 896 80 753 0 +804 392 406 660 1 +530 965 1027 704 0 +25 13 805 52 0 +600 295 559 547 1 +827 796 367 609 1 +527 463 696 384 1 +806 693 346 255 1 +82 103 1012 447 1 +944 540 499 368 0 +683 656 801 140 1 +511 273 458 738 0 +346 278 389 459 1 +278 389 454 346 0 +805 543 908 693 1 +506 507 1023 406 0 +815 403 379 317 0 +318 685 946 566 0 +905 229 239 670 1 +459 693 805 908 0 +656 702 966 249 1 +663 432 1027 1020 1 +724 157 526 477 1 +861 244 27 833 0 +772 195 577 338 1 +577 195 781 338 1 +772 577 358 338 1 +702 894 120 656 1 +370 560 755 542 0 +786 560 755 370 0 +262 852 176 97 0 +326 900 852 97 0 +937 820 372 211 0 +354 838 934 290 1 +757 129 746 699 0 +748 191 182 711 1 +164 150 941 303 1 +693 761 464 908 0 +43 23 465 56 0 +790 106 827 782 0 +836 481 935 883 0 +904 113 134 555 1 +481 989 163 1022 0 +134 545 904 196 0 +360 1022 93 622 0 +655 221 1021 644 0 +806 693 761 813 1 +700 621 329 586 1 +911 571 720 272 0 +176 77 234 900 0 +80 732 124 142 1 +908 464 757 638 1 +405 731 317 223 1 +315 493 680 373 1 +629 397 778 291 0 +837 128 211 288 1 +621 328 329 473 1 +1002 650 875 516 1 +1002 715 875 650 1 +934 15 292 18 0 +670 108 696 665 0 +963 839 608 656 1 +244 790 982 68 0 +939 354 21 47 0 +619 904 679 240 0 +619 113 904 240 0 +327 113 240 904 0 +265 410 497 230 0 +118 380 408 823 0 +878 280 981 587 1 +22 833 12 54 0 +662 382 425 531 1 +591 725 1023 506 1 +631 905 439 229 0 +905 631 534 229 0 +239 905 534 229 0 +239 902 534 905 0 +902 631 534 905 0 +728 217 750 191 0 +298 330 352 789 1 +486 1010 1011 167 1 +177 73 656 307 1 +9 185 499 906 0 +637 638 757 699 1 +914 494 72 503 0 +741 602 806 356 0 +909 569 80 568 0 +751 569 909 568 0 +909 98 80 569 0 +699 129 746 301 0 +276 219 659 695 0 +552 922 312 625 0 +904 908 212 196 0 +576 617 92 643 0 +401 667 595 442 1 +697 253 718 906 0 +555 904 738 908 0 +661 595 1020 442 1 +632 108 665 696 0 +361 835 198 335 1 +527 629 902 814 1 +388 449 277 911 0 +164 204 494 941 1 +826 408 814 527 0 +176 852 900 97 0 +247 375 188 791 1 +702 656 860 249 1 +824 200 667 442 0 +964 653 972 577 0 +123 174 414 331 1 +109 677 690 326 1 +602 464 129 757 0 +690 323 109 617 1 +677 323 109 690 1 +638 129 757 699 0 +858 245 647 370 0 +466 636 909 112 0 +547 180 600 295 0 +321 1 489 297 1 +184 726 918 141 0 +918 726 197 141 0 +148 728 750 191 0 +724 910 477 163 1 +481 163 208 1022 0 +727 477 526 157 1 +159 478 483 990 1 +980 1001 876 645 0 +72 962 914 859 0 +747 707 72 859 0 +522 888 980 525 1 +976 1021 874 62 0 +873 450 892 891 0 +975 889 892 891 1 +83 881 887 997 1 +559 747 343 912 0 +771 502 914 364 1 +196 91 915 566 0 +196 915 545 566 0 +545 741 566 915 1 +461 94 144 275 0 +389 383 25 56 0 +3 764 483 536 0 +432 1027 294 528 1 +753 915 545 134 0 +134 915 545 196 0 +134 91 915 196 0 +134 91 121 915 0 +753 121 915 134 0 +177 344 656 164 1 +451 9 185 279 0 +411 325 468 768 1 +1019 411 468 768 1 +522 644 888 893 1 +184 918 197 141 0 +729 492 922 625 1 +745 549 213 919 0 +213 549 748 919 0 +748 549 756 919 0 +549 187 756 919 0 +745 187 549 919 0 +748 756 133 919 0 +300 213 748 919 0 +919 138 503 745 1 +924 814 631 902 0 +659 814 924 902 1 +72 138 503 919 1 +83 635 201 920 0 +731 932 172 88 1 +83 625 635 920 0 +165 284 92 839 1 +138 923 745 919 1 +138 923 187 745 0 +134 904 921 212 0 +921 904 908 212 0 +555 904 908 921 0 +465 402 25 601 0 +555 134 921 739 0 +134 904 555 921 0 +601 402 25 513 0 +216 739 907 921 0 +908 921 638 907 0 +552 154 312 922 0 +154 215 312 922 0 +138 78 187 923 0 +187 313 923 78 0 +211 589 218 705 0 +218 589 625 705 0 +904 805 220 908 0 +291 607 219 841 0 +191 923 187 148 0 +187 313 148 923 0 +397 291 514 219 0 +904 459 220 805 0 +924 1018 631 823 0 +924 788 1018 823 0 +814 788 924 823 0 +1017 788 924 814 0 +1017 788 1018 924 0 +96 1018 924 1017 0 +96 1018 631 924 0 +96 631 666 924 0 +277 928 784 720 1 +558 911 753 928 1 +911 281 753 928 1 +590 953 490 205 1 +558 928 753 712 1 +558 928 712 449 1 +712 928 277 449 1 +775 643 366 1028 0 +714 385 719 925 1 +714 719 273 925 1 +734 466 599 112 1 +102 925 669 48 0 +102 441 669 925 0 +458 927 641 719 0 +52 688 641 719 0 +486 176 2 183 1 +486 183 2 614 1 +490 953 153 205 1 +490 744 205 153 1 +486 887 1011 1010 1 +83 887 486 998 1 +885 435 21 475 0 +808 9 994 396 0 +13 9 396 994 0 +396 13 994 571 0 +396 994 931 571 0 +996 885 21 475 0 +885 910 996 989 1 +723 885 475 482 1 +991 995 434 881 0 +467 929 805 459 0 +467 929 459 1015 0 +929 346 459 1015 0 +474 434 995 881 0 +1022 479 591 885 1 +479 885 725 591 1 +1022 885 591 996 0 +725 885 506 591 1 +234 176 2 486 1 +1022 989 885 996 1 +618 124 732 466 1 +732 5 116 227 1 +425 735 440 170 1 +124 732 466 599 1 +70 101 732 142 1 +114 734 169 127 1 +636 734 227 127 1 +618 732 227 636 1 +732 466 227 636 1 +735 170 799 538 1 +1009 85 433 583 1 +85 776 583 1009 1 +776 331 1009 580 1 +387 899 420 819 1 +513 594 389 874 0 +218 820 372 729 0 +549 556 350 546 0 +292 194 21 67 0 +205 752 153 563 0 +1003 166 932 933 1 +511 803 119 241 1 +180 502 216 739 0 +427 639 75 269 0 +104 1009 583 615 1 +108 735 409 940 1 +108 735 940 359 1 +180 502 361 216 1 +941 835 361 314 0 +970 983 837 275 0 +946 566 91 196 0 +172 265 674 684 0 +172 497 265 684 0 +545 761 196 566 1 +545 741 761 566 1 +211 357 339 947 1 +211 357 947 557 1 +360 916 758 766 0 +671 365 236 917 0 +918 190 197 135 0 +29 634 640 66 0 +264 211 947 557 1 +388 449 255 992 1 +961 316 260 341 0 +961 151 269 535 0 +570 305 736 137 0 +568 88 751 501 0 +261 351 955 770 1 +961 151 959 269 0 +124 88 751 568 0 +766 479 289 591 0 +142 124 80 568 1 +473 706 825 422 1 +142 568 80 611 1 +277 928 712 784 1 +186 771 364 158 1 +501 98 751 569 1 +743 570 137 749 0 +437 961 341 535 0 +437 961 260 341 1 +780 570 743 762 1 +780 546 570 762 1 +305 546 762 570 1 +546 350 570 305 1 +570 350 209 305 1 +209 305 736 570 0 +601 25 465 56 0 +650 491 715 271 0 +561 603 949 895 1 +423 299 334 418 0 +909 751 698 98 0 +698 751 127 98 0 +145 223 427 495 1 +105 809 633 527 1 +980 862 1001 645 0 +833 22 12 37 0 +833 34 12 54 0 +281 929 994 396 0 +358 943 710 777 0 +19 766 21 939 0 +318 685 131 946 0 +618 698 227 127 0 +335 494 204 835 0 +629 291 778 586 0 +83 722 881 987 1 +559 747 912 186 0 +809 429 901 103 1 +246 579 574 69 1 +136 737 573 552 0 +713 980 876 645 0 +136 737 144 573 0 +782 827 609 709 1 +581 782 609 709 1 +478 590 151 851 0 +757 772 358 710 0 +371 143 315 306 0 +793 827 609 782 1 +226 574 617 643 1 +174 585 583 774 0 +338 332 578 548 0 +338 578 777 548 0 +827 106 609 709 0 +789 352 298 372 1 +938 119 234 616 0 +664 171 474 727 0 +192 789 298 372 0 +925 385 927 441 0 +410 353 238 265 1 +1 192 372 136 0 +969 548 943 310 0 +565 969 943 310 0 +244 790 861 982 0 +626 173 1020 857 0 +626 857 1020 530 0 +731 223 932 166 1 +292 15 970 18 0 +740 333 705 783 1 +740 208 705 333 1 +605 796 440 170 0 +106 796 605 170 0 +645 222 654 572 1 +683 656 140 324 1 +417 673 647 786 1 +644 28 1021 892 0 +977 171 871 476 0 +871 171 447 476 0 +476 871 977 160 1 +715 280 587 449 1 +449 992 545 255 1 +906 368 499 1004 1 +790 106 782 706 0 +722 658 163 635 0 +513 976 874 62 0 +757 710 746 310 0 +998 851 1010 437 1 +1012 901 239 429 1 +299 736 505 1013 1 +407 600 226 240 0 +240 180 600 226 0 +574 180 226 600 0 +846 309 195 304 0 +957 846 195 304 0 +615 1009 487 104 1 +1011 103 1006 1012 1 +314 941 442 771 0 +941 528 442 771 0 +69 528 442 941 0 +771 502 950 361 1 +792 440 603 605 1 +710 859 962 578 1 +618 466 636 698 1 +13 279 9 717 0 +619 948 457 656 1 +187 584 178 313 0 +187 584 313 78 0 +584 498 313 78 0 +584 199 498 78 0 +781 199 584 78 0 +584 207 781 78 0 +138 207 584 78 0 +138 584 187 78 0 +138 207 187 584 0 +366 165 92 839 1 +584 207 343 544 1 +211 658 589 705 0 +705 208 552 333 1 +589 658 625 705 0 +276 472 219 695 0 +781 199 498 584 0 +358 343 859 132 0 +710 777 746 310 0 +1003 167 1014 5 1 +368 540 499 1004 1 +636 112 734 127 1 +906 1004 499 228 1 +732 116 1014 92 1 +70 798 488 732 1 +851 961 1010 437 1 +751 734 127 1004 1 +732 488 1014 1003 1 +734 733 169 127 1 +1005 764 365 151 1 +118 76 588 539 0 +331 76 588 118 0 +585 331 776 588 0 +478 851 764 882 0 +180 164 941 303 1 +866 837 264 974 1 +804 283 591 392 0 +804 591 435 392 0 +124 599 466 112 0 +363 289 863 968 0 +27 833 22 877 0 +108 799 613 735 1 +895 764 536 107 1 +536 3 895 1012 1 +148 156 918 728 1 +726 135 197 141 0 +604 1008 167 1011 1 +162 135 726 177 0 +728 313 87 217 0 +290 819 370 264 0 +755 290 370 264 0 +591 692 283 453 0 +804 453 591 283 0 +614 604 167 1011 1 +435 591 804 1023 0 +977 160 872 171 0 +450 1024 967 449 0 +262 723 630 161 0 +156 135 726 162 0 +156 190 726 135 0 +97 630 593 664 0 +593 630 803 664 0 +97 593 803 664 0 +987 590 998 201 0 +661 173 1020 626 0 +1025 239 694 82 0 +253 501 955 718 0 +831 95 512 596 0 +831 596 512 448 0 +432 857 668 1027 0 +598 507 804 406 0 +406 804 598 691 1 +691 406 809 598 0 +450 594 1024 806 0 +1024 449 741 806 0 +450 1024 741 806 0 +594 272 1024 806 0 +763 536 146 1012 1 +466 732 227 734 1 +751 112 127 734 1 +1004 765 499 228 1 +1004 540 499 765 1 +606 447 235 175 1 +605 815 152 440 0 +167 443 234 5 1 +446 100 1009 433 1 +1012 536 146 760 1 +111 1004 765 6 1 +738 555 600 904 0 +555 738 600 908 0 +738 908 638 600 0 +600 908 638 907 0 +738 600 638 907 0 +738 907 637 600 1 +637 699 600 907 1 +600 699 559 907 1 +637 699 559 600 1 +637 600 559 465 1 +738 600 637 465 1 +908 600 921 907 0 +600 739 921 907 0 +600 555 921 739 0 +908 555 921 600 0 +407 555 600 240 0 +240 180 555 600 0 +806 602 813 356 0 +806 602 693 813 1 +602 464 693 813 1 +602 908 693 464 1 +543 908 693 602 1 +806 543 693 602 1 +450 806 602 543 0 +598 406 977 506 0 +149 664 297 183 1 +149 83 297 492 1 +664 297 176 97 0 +492 262 297 97 0 +664 492 297 97 0 +297 262 176 97 0 +128 854 288 866 0 +666 175 606 446 1 +666 606 85 446 1 +682 152 792 603 1 +505 192 173 1013 1 +488 730 79 1013 1 +365 1005 603 107 1 +733 446 1009 606 1 +100 446 733 606 1 +82 1006 175 606 1 +534 1006 606 175 1 +534 606 631 175 1 +631 606 666 175 1 +534 1006 631 606 1 +734 88 112 599 1 +845 735 940 1007 1 +613 110 538 799 0 +389 13 25 462 0 +69 941 574 323 0 +251 684 188 95 0 +251 319 684 95 0 +751 88 112 1004 1 +1003 5 732 734 1 +810 863 398 514 0 +829 353 410 265 1 +1017 788 814 826 0 +751 112 734 1004 1 +636 466 734 112 1 +735 170 425 243 1 +172 684 674 251 0 +674 684 188 251 0 +334 381 256 254 0 +491 759 280 449 1 +506 646 598 406 0 +445 232 733 540 1 +259 309 685 257 0 +83 722 635 625 0 +771 914 186 364 1 +913 906 185 228 0 +254 288 837 275 0 +335 914 364 186 1 +155 95 495 488 1 +854 942 783 333 0 +882 851 764 428 0 +294 109 326 620 1 +326 294 504 852 1 +942 210 214 769 0 +318 936 302 846 0 +779 110 613 414 0 +132 332 707 578 1 +675 790 610 244 1 +708 524 653 964 0 +187 703 747 214 1 +327 574 240 226 0 +662 382 628 632 1 +341 855 260 75 1 +450 967 876 888 0 +941 667 200 442 0 +552 321 705 136 0 +974 937 290 210 1 +790 106 844 971 0 +152 317 223 682 1 +42 790 244 68 0 +549 748 350 256 0 +350 748 780 256 0 +549 256 350 769 0 +549 769 214 256 0 +214 769 210 256 0 +166 1008 1004 1009 1 +155 79 490 153 1 +1014 616 237 92 1 +432 173 857 1020 0 +219 607 695 841 0 +109 690 77 326 0 +238 770 353 258 1 +266 330 768 352 0 +939 959 236 766 0 +273 688 402 52 0 +805 273 402 52 0 +569 261 568 351 0 +718 501 955 569 0 +768 325 262 958 1 +645 521 451 713 0 +229 118 408 823 0 +42 521 524 221 0 +931 484 346 281 0 +158 502 186 771 1 +690 677 119 326 1 +1025 812 901 456 0 +858 787 247 493 0 +626 1020 595 530 0 +601 738 638 637 1 +539 118 408 229 0 +661 1020 595 626 0 +43 1019 768 465 0 +117 665 827 796 1 +954 854 205 752 0 +350 769 256 853 1 +60 225 412 833 0 +264 783 542 339 1 +898 265 238 353 1 +898 172 238 265 0 +898 172 265 674 0 +373 155 417 673 0 +474 664 614 171 0 +268 307 608 324 1 +307 681 324 268 0 +307 203 681 268 0 +573 705 211 275 0 +937 837 211 275 0 +917 365 236 107 1 +856 770 258 955 1 +567 750 130 270 1 +130 749 270 345 0 +270 749 554 345 0 +130 270 554 345 0 +871 435 1023 646 0 +491 271 915 449 1 +276 623 716 55 0 +474 171 477 727 0 +278 454 388 346 1 +172 251 233 932 1 +456 694 276 716 1 +956 259 309 336 1 +340 956 309 336 1 +340 309 956 202 1 +820 721 372 926 0 +458 592 927 385 1 +688 592 404 927 0 +688 273 458 719 0 +52 688 719 273 0 +427 81 758 959 0 +271 491 915 685 0 +1024 272 386 519 1 +477 872 159 622 1 +716 34 276 55 0 +611 568 271 685 0 +611 568 80 271 0 +52 273 719 64 0 +806 278 388 346 1 +787 512 448 371 1 +371 831 512 448 0 +925 441 532 930 0 +485 951 896 369 0 +1015 929 346 712 0 +787 512 818 448 1 +702 643 366 579 0 +411 325 1 468 0 +715 587 558 449 1 +35 11 880 40 0 +472 659 924 276 0 +1016 576 92 839 0 +621 778 814 1017 0 +621 473 586 825 1 +1017 473 621 825 0 +1 852 262 468 0 +43 20 1019 51 0 +476 160 477 157 0 +688 641 533 102 0 +641 927 533 102 0 +688 927 533 641 0 +911 571 642 720 0 +1028 775 643 574 1 +505 165 173 141 1 +1023 453 507 725 0 +277 784 712 992 1 +449 277 712 992 1 +276 812 623 392 1 +276 902 812 392 1 +276 902 392 695 1 +902 695 276 814 1 +276 695 659 814 1 +902 276 659 814 1 +694 902 276 659 1 +717 383 279 386 1 +290 934 391 942 0 +126 687 284 807 0 +630 881 474 664 1 +694 902 812 276 1 +694 812 623 276 1 +456 623 276 694 1 +435 804 276 623 0 +435 276 21 623 0 +435 804 21 276 0 +804 19 21 276 0 +517 96 12 716 0 +911 396 753 281 1 +642 784 931 281 0 +911 642 928 720 0 +1009 331 583 580 1 +172 932 233 101 1 +115 576 1016 839 0 +571 455 642 931 0 +911 396 281 455 1 +337 282 394 460 0 +337 150 282 460 0 +134 712 687 545 0 +687 240 1016 807 1 +134 753 712 545 0 +368 993 98 944 0 +944 993 98 753 0 +915 753 545 712 0 +915 753 712 271 0 +820 468 1 321 0 +485 930 640 817 1 +20 43 593 52 0 +804 453 283 392 0 +174 471 30 60 0 +731 152 603 605 1 +142 611 80 284 1 +284 611 80 126 1 +142 611 284 126 1 +284 142 126 681 1 +307 284 126 681 1 +307 142 284 681 1 +114 86 231 168 1 +114 168 733 1008 1 +621 778 1017 825 1 +575 778 825 1017 1 +608 284 839 115 0 +608 284 115 393 0 +608 126 284 393 0 +608 126 839 284 1 +307 839 126 284 1 +1027 246 109 528 1 +1027 668 109 246 0 +287 818 815 317 0 +317 152 815 287 0 +287 152 815 796 0 +287 796 815 106 0 +287 815 74 106 0 +846 973 936 348 1 +590 635 205 490 1 +843 287 844 424 1 +581 424 287 843 0 +581 287 767 843 0 +934 523 891 44 0 +934 891 36 44 0 +654 1001 955 258 0 +881 625 589 722 1 +83 625 881 722 1 +984 841 607 291 1 +996 1022 766 591 0 +586 841 984 291 1 +837 983 974 866 1 +881 589 630 722 1 +964 972 708 577 0 +682 832 767 287 0 +287 682 252 767 0 +252 425 287 767 0 +767 425 287 628 0 +287 425 796 628 0 +767 287 796 628 0 +796 767 609 287 0 +709 287 609 767 0 +581 287 709 767 0 +581 424 709 287 0 +709 106 287 424 0 +709 106 609 287 0 +609 796 287 106 0 +252 425 796 287 0 +152 287 252 796 0 +152 682 252 287 0 +152 682 287 317 0 +287 379 74 815 0 +287 403 379 815 0 +287 403 815 818 0 +287 818 375 403 0 +287 403 375 413 0 +24 287 375 413 0 +413 829 24 287 0 +287 829 24 379 0 +24 379 74 287 0 +413 829 287 379 0 +413 403 379 287 0 +24 818 375 287 0 +295 600 907 739 0 +555 600 295 739 0 +547 295 912 158 1 +912 295 186 158 1 +295 502 186 158 1 +295 502 158 771 1 +547 295 158 771 1 +547 295 771 180 0 +295 502 771 180 0 +297 664 176 183 0 +487 580 123 110 1 +497 731 405 684 1 +297 83 920 922 1 +297 920 321 922 1 +297 922 321 729 1 +729 468 321 297 0 +468 297 1 321 0 +468 262 1 297 0 +117 415 793 665 1 +790 422 706 328 0 +117 665 822 415 1 +118 774 331 779 1 +76 331 779 118 0 +876 1002 386 516 0 +187 90 584 556 0 +656 140 608 457 1 +790 106 706 424 0 +350 748 546 780 0 +552 333 144 573 1 +72 503 138 707 1 +63 982 287 971 0 +581 782 709 424 1 +661 663 529 824 1 +814 788 823 905 0 +148 313 728 217 0 +824 661 624 529 1 +99 754 487 111 1 +588 439 774 118 0 +776 331 585 583 1 +271 715 558 449 1 +702 579 366 120 0 +54 22 833 877 0 +194 988 21 67 0 +881 995 149 887 0 +853 299 954 256 0 +848 340 142 956 0 +73 142 848 340 0 +585 331 588 774 0 +666 439 776 1009 1 +399 374 624 418 0 +195 309 336 781 0 +827 106 709 424 0 +781 202 770 678 0 +781 770 496 678 0 +706 424 473 825 1 +615 487 174 123 1 +781 202 678 498 0 +848 307 850 956 0 +640 48 64 66 0 +747 503 72 707 0 +278 272 389 594 0 +960 299 853 256 0 +768 325 958 349 1 +882 590 437 998 0 +758 81 531 959 0 +906 98 368 1004 1 +349 325 958 620 1 +588 76 331 580 0 +776 588 331 580 1 +309 952 781 195 0 +489 486 234 1014 1 +373 831 395 155 0 +143 831 371 315 0 +822 408 416 415 0 +790 782 377 706 0 +412 376 788 825 0 +819 311 560 542 0 +337 282 181 394 0 +634 122 994 817 0 +530 704 1027 69 1 +311 752 819 205 0 +798 95 188 831 0 +311 819 153 205 0 +392 19 21 804 0 +530 1027 442 69 1 +954 736 563 744 0 +418 299 461 624 0 +725 660 429 453 0 +951 369 467 896 1 +403 787 512 818 1 +787 188 371 320 1 +161 589 630 492 0 +362 969 548 565 0 +563 954 79 736 0 +409 735 76 940 1 +1018 85 30 58 0 +733 232 100 122 1 +42 500 790 74 0 +42 500 244 790 0 +500 426 244 790 0 +593 958 97 504 0 +287 74 24 971 0 +766 935 21 354 0 +264 339 542 755 0 +823 774 1018 666 0 +790 74 106 982 0 +70 371 306 143 0 +247 188 674 791 1 +656 894 120 366 1 +108 799 378 613 1 +793 377 328 610 0 +377 322 794 675 1 +610 322 377 675 1 +248 828 823 380 1 +795 610 793 328 0 +795 790 610 328 0 +244 790 610 795 1 +389 13 462 571 0 +775 226 576 643 1 +250 610 793 795 0 +106 243 796 170 0 +814 823 631 905 0 +117 665 796 243 1 +43 20 593 1019 0 +823 118 666 631 0 +823 774 666 118 0 +632 425 796 243 1 +235 168 71 669 1 +387 673 245 370 1 +632 628 665 796 1 +796 665 224 628 1 +796 628 224 367 1 +367 665 224 796 1 +822 229 415 670 0 +559 343 747 859 0 +705 783 573 288 1 +705 783 288 211 1 +586 984 700 863 0 +249 667 530 894 1 +244 444 419 797 0 +829 263 375 247 0 +663 432 528 1027 1 +234 486 167 1014 1 +705 288 573 211 1 +243 170 794 799 0 +322 243 794 799 0 +354 194 21 292 0 +741 388 255 806 1 +789 352 275 254 1 +421 328 700 621 1 +825 424 586 778 1 +147 683 801 121 1 +683 121 611 801 0 +683 611 126 801 0 +683 801 126 140 0 +690 677 802 897 1 +835 494 204 314 1 +988 723 475 482 1 +803 119 241 900 1 +828 612 779 414 1 +779 414 613 828 0 +779 774 414 612 1 +818 1026 403 317 0 +95 508 188 512 0 +181 401 374 824 1 +724 658 161 589 0 +1027 294 668 432 0 +181 816 374 401 1 +401 661 374 824 1 +508 188 403 375 1 +660 406 429 809 0 +645 876 386 516 0 +181 816 401 509 1 +405 145 684 317 1 +124 732 101 142 1 +674 684 497 405 0 +791 188 508 375 1 +283 392 453 660 1 +822 408 378 676 0 +452 592 458 385 1 +663 771 824 442 0 +771 314 824 442 0 +518 651 967 862 1 +821 369 89 467 1 +23 912 721 43 0 +807 679 140 801 0 +388 277 992 484 1 +459 543 805 693 1 +115 1016 284 839 0 +679 904 134 807 0 +686 679 134 807 0 +686 807 134 121 0 +686 679 807 121 0 +807 679 801 121 0 +611 121 807 801 0 +126 611 807 801 0 +126 611 80 807 0 +611 121 80 807 0 +697 808 944 396 0 +414 580 779 110 1 +108 243 822 378 1 +13 717 383 462 0 +404 430 803 903 0 +930 441 532 231 0 +272 911 278 454 0 +803 241 511 400 0 +326 620 504 294 1 +575 844 825 778 1 +416 830 797 676 1 +146 905 384 429 1 +421 416 117 250 0 +250 793 117 421 0 +450 876 967 1024 0 +629 696 436 810 1 +665 810 696 629 0 +665 224 696 810 0 +379 815 317 405 1 +116 1014 616 5 1 +785 650 516 253 0 +436 811 632 696 0 +662 811 632 436 0 +662 811 436 692 0 +662 438 811 692 0 +272 519 1024 449 0 +662 438 632 811 0 +963 608 948 656 1 +544 387 370 391 0 +457 679 393 948 1 +140 679 393 457 1 +862 587 967 985 0 +790 844 982 971 0 +982 880 877 54 0 +843 945 363 984 1 +370 819 391 387 0 +689 976 513 62 0 +654 890 222 645 0 +412 244 795 422 0 +647 869 979 786 0 +80 618 124 732 1 +533 430 903 604 1 +495 488 95 933 1 +1010 933 167 1003 1 +166 933 167 1005 1 +80 284 732 142 1 +732 488 165 1014 1 +732 932 233 1003 1 +1003 932 1008 734 1 +181 200 509 824 0 +508 403 405 317 0 +547 897 241 511 0 +428 3 995 1011 1 +964 653 708 972 0 +591 289 283 692 0 +46 641 102 927 0 +897 511 119 241 1 +536 463 633 365 0 +454 931 346 389 0 +451 876 386 713 1 +810 607 863 514 0 +384 905 527 463 1 +527 429 633 463 1 +90 673 245 387 1 +602 908 464 757 1 +720 571 454 272 0 +806 543 389 693 1 +471 225 1018 60 0 +389 543 805 459 1 +487 166 1004 1009 1 +935 840 766 1022 0 +848 307 203 850 0 +452 938 458 592 1 +108 378 409 613 1 +117 827 243 796 1 +471 612 582 419 0 +471 582 823 419 1 +683 268 656 324 1 +188 508 684 791 0 +83 486 730 998 1 +998 887 486 428 1 +993 485 929 994 1 +994 753 396 929 0 +640 13 346 994 0 +994 13 346 931 0 +281 929 931 994 0 +930 86 441 231 0 +231 114 930 86 0 +455 396 281 931 0 +866 837 983 254 0 +284 116 92 951 0 +275 721 372 937 0 +695 436 398 810 1 +397 778 659 814 0 +623 515 812 691 1 +814 695 659 397 1 +454 571 389 278 0 +842 767 945 843 1 +970 194 292 67 0 +971 106 844 424 0 +1001 1000 955 258 0 +474 434 149 995 0 +929 994 346 931 0 +281 994 931 396 0 +149 614 995 434 1 +1013 489 136 192 1 +971 287 74 106 0 +640 13 994 64 0 +994 13 29 64 0 +640 994 29 64 0 +634 994 29 640 0 +169 114 817 231 0 +441 168 533 604 1 +441 604 235 168 1 +730 1010 486 1003 1 +796 243 665 822 1 +632 796 665 822 1 +632 822 665 108 1 +632 243 822 108 1 +632 243 796 822 1 +793 377 827 782 1 +480 882 764 428 0 +790 575 706 422 0 +783 573 288 128 1 +1010 1005 167 933 1 +409 822 670 229 0 +539 409 431 670 0 +940 108 431 409 0 +76 940 431 409 0 +621 826 814 527 0 +416 822 378 676 0 +108 378 822 409 1 +500 410 562 74 0 +409 108 670 822 0 +409 118 380 408 0 +539 409 670 229 0 +1018 823 666 631 0 +827 665 224 367 1 +117 665 224 827 1 +117 322 243 827 1 +117 322 827 377 1 +823 828 118 380 1 +380 828 118 779 1 +828 582 118 779 1 +582 774 779 828 1 +465 891 601 62 0 +489 486 1014 1003 1 +779 828 613 380 0 +598 646 506 977 0 +266 411 768 330 1 +826 469 676 376 1 +779 774 331 414 1 +585 174 414 612 1 +123 174 612 414 1 +898 674 265 829 1 +898 265 353 829 1 +672 411 1 298 0 +672 325 411 298 0 +298 411 266 330 1 +672 325 1 411 0 +816 374 423 181 1 +423 189 399 816 0 +797 248 469 676 0 +123 331 414 580 1 +798 831 188 371 0 +1006 447 604 606 1 +832 939 755 758 0 +427 939 832 758 0 +560 758 427 832 0 +682 560 427 832 0 +427 832 252 682 0 +832 682 767 252 0 +767 832 252 382 0 +832 531 252 382 0 +767 531 832 382 0 +939 531 832 767 0 +778 945 844 424 1 +755 832 370 290 0 +432 294 620 528 1 +860 125 1028 249 1 +966 860 1028 249 1 +294 672 668 432 0 +24 44 832 63 0 +44 41 832 63 0 +41 11 832 63 0 +40 11 832 41 0 +832 40 41 47 0 +934 832 41 47 0 +974 783 128 391 0 +832 354 939 47 0 +939 40 832 47 0 +810 397 629 291 0 +47 18 292 67 0 +832 44 391 934 0 +44 41 934 832 0 +24 44 391 832 0 +810 607 514 291 0 +195 846 362 293 1 +851 590 437 882 0 +1027 704 246 69 1 +1027 109 294 528 1 +456 1025 812 694 0 +1025 105 812 694 0 +271 718 80 753 0 +945 843 844 424 1 +807 240 393 679 1 +721 158 352 926 0 +697 253 906 185 0 +449 272 388 806 0 +593 504 97 900 1 +826 376 676 416 1 +706 424 825 422 1 +665 700 224 810 0 +665 810 629 700 0 +422 424 825 844 1 +575 422 825 844 1 +782 328 329 700 1 +700 328 329 621 1 +706 424 422 575 1 +826 376 416 250 1 +782 329 224 700 1 +132 859 710 578 0 +947 773 766 840 0 +914 747 72 859 0 +983 254 837 275 0 +790 844 575 861 0 +970 254 983 275 0 +692 662 863 436 0 +573 552 705 136 0 +276 19 21 34 0 +968 289 863 692 0 +803 727 903 664 0 +803 630 727 664 0 +161 630 727 157 0 +218 492 729 625 1 +918 184 567 728 1 +881 995 887 997 0 +388 484 255 346 1 +577 964 544 358 1 +790 844 861 982 0 +982 844 861 971 0 +775 576 839 366 0 +703 207 747 343 1 +703 207 343 584 1 +584 343 703 544 1 +914 747 859 559 0 +584 556 387 703 0 +187 207 703 584 1 +187 207 747 703 1 +882 480 997 428 0 +3 990 159 483 0 +891 28 36 44 0 +891 892 601 62 0 +965 668 246 120 0 +708 293 973 846 0 +283 398 968 695 0 +302 207 138 847 0 +72 847 302 138 1 +318 195 302 847 0 +847 91 739 302 1 +708 336 770 202 0 +781 708 770 202 0 +781 336 708 202 0 +195 336 708 781 0 +577 708 781 195 1 +973 258 770 285 0 +781 207 302 847 0 +1005 1011 895 764 1 +858 680 493 245 0 +653 523 522 525 1 +710 746 859 559 0 +859 962 914 559 0 +859 746 962 559 0 +358 859 710 132 0 +353 708 496 247 0 +656 839 608 307 1 +109 672 294 326 0 +353 258 770 708 0 +353 770 496 708 0 +708 770 496 781 0 +781 678 496 708 0 +704 965 246 120 0 +757 710 559 699 0 +710 746 559 699 0 +757 746 710 699 0 +777 548 710 746 1 +849 490 153 155 1 +895 3 1011 1012 1 +182 206 743 711 0 +206 189 743 711 0 +730 1010 155 490 1 +262 468 589 492 0 +334 711 181 337 0 +204 711 334 337 0 +204 748 334 711 0 +334 748 780 711 0 +780 748 743 711 0 +334 780 743 711 0 +204 300 748 711 0 +300 191 748 711 1 +1015 753 929 712 0 +524 654 253 258 0 +52 719 31 64 0 +48 31 719 64 0 +654 653 890 285 0 +53 716 45 55 0 +53 34 716 55 0 +34 716 12 53 0 +716 96 12 53 0 +53 716 96 58 0 +96 716 666 58 0 +666 716 175 58 0 +58 716 175 66 0 +716 669 175 66 0 +716 48 669 66 0 +58 48 716 66 0 +48 716 26 58 0 +53 26 716 58 0 +26 716 45 53 0 +26 456 45 716 0 +163 477 159 622 1 +623 390 456 716 0 +276 623 456 716 0 +48 456 26 716 0 +456 48 669 716 0 +235 456 669 716 0 +235 716 669 175 0 +235 456 716 175 0 +82 716 456 175 0 +716 631 175 82 0 +694 631 716 82 0 +82 694 456 716 0 +385 86 441 925 0 +702 1028 366 643 0 +940 845 1007 431 1 +666 631 175 716 0 +826 376 421 473 0 +568 718 271 685 0 +568 261 718 685 0 +569 718 568 261 0 +568 569 80 718 0 +568 718 80 271 0 +944 569 697 718 0 +298 926 820 372 1 +721 970 926 820 0 +820 266 1019 926 0 +926 266 768 352 0 +298 266 926 352 1 +926 721 372 352 1 +298 926 372 352 1 +928 911 277 449 1 +911 928 277 720 0 +452 458 719 385 1 +452 385 719 714 1 +721 926 10 43 0 +721 158 926 465 0 +452 458 89 719 1 +721 836 820 937 0 +971 74 24 68 0 +701 973 972 293 0 +983 866 254 256 0 +210 983 254 256 0 +63 287 24 971 0 +23 912 254 721 0 +972 293 973 708 0 +16 721 10 23 0 +997 995 887 428 0 +701 348 973 293 0 +63 971 24 68 0 +927 441 533 102 0 +789 352 372 721 1 +46 927 102 48 0 +3 159 990 480 0 +479 478 365 483 0 +3 764 990 483 0 +481 1022 357 840 0 +1000 541 864 518 1 +143 488 1013 165 1 +888 967 876 525 0 +910 477 989 872 1 +989 477 163 872 1 +481 910 163 989 0 +476 447 390 102 0 +903 447 476 102 0 +688 102 903 476 0 +836 481 883 986 0 +872 506 526 159 0 +476 31 688 641 0 +159 991 990 480 0 +766 1022 360 479 0 +93 916 360 479 0 +360 916 766 479 0 +476 477 727 157 0 +722 93 478 590 0 +169 993 98 368 0 +450 888 867 967 0 +915 271 712 992 1 +93 151 916 479 0 +476 160 727 477 0 +894 135 165 726 1 +910 723 157 160 1 +725 453 429 463 0 +468 723 589 1019 0 +262 723 468 1019 0 +20 262 1019 723 0 +593 20 723 262 0 +593 723 97 262 0 +630 262 97 723 0 +97 593 630 723 0 +563 1013 730 94 1 +1013 730 136 489 1 +563 736 1013 94 1 +100 606 168 657 1 +666 776 85 1009 1 +487 1007 110 444 1 +537 426 487 444 1 +447 103 1011 171 1 +537 754 84 487 1 +615 487 123 84 1 +84 487 754 111 1 +84 537 487 110 1 +84 487 123 110 1 +487 580 174 123 1 +154 1 730 321 1 +321 920 730 154 1 +1014 116 616 92 1 +341 260 490 75 1 +490 535 269 953 1 +136 730 94 154 1 +1 730 136 154 1 +537 487 110 444 1 +297 920 730 321 1 +487 426 1007 444 1 +730 79 563 490 1 +167 1003 1008 734 1 +490 1010 155 260 1 +169 231 122 168 1 +932 1004 166 734 1 +1003 489 730 488 1 +735 603 792 440 1 +252 735 792 440 1 +425 735 252 440 1 +425 735 531 252 1 +735 438 531 252 1 +438 252 735 671 1 +735 252 603 671 1 +735 603 561 671 1 +438 735 561 671 1 +438 359 561 735 1 +561 359 949 735 1 +561 735 949 603 1 +425 438 735 359 1 +359 425 632 735 1 +735 425 632 108 1 +359 735 632 108 1 +425 438 531 735 1 +252 603 792 735 1 +307 126 839 608 1 +962 859 72 578 1 +325 294 958 620 1 +846 541 936 285 0 +115 576 839 775 0 +552 705 625 740 0 +169 168 733 114 1 +697 9 499 944 0 +944 185 499 697 0 +906 185 499 944 0 +98 569 906 944 1 +808 9 944 540 0 +565 362 772 943 1 +943 362 772 338 1 +472 19 695 276 0 +299 137 399 189 0 +704 120 246 579 0 +36 33 934 44 0 +41 934 33 44 0 +937 983 837 970 0 +250 376 473 421 0 +362 286 565 936 0 +194 937 354 836 1 +837 937 974 983 1 +721 820 372 937 0 +329 843 363 984 1 +478 93 622 590 0 +474 881 149 664 1 +473 706 329 424 1 +24 832 287 63 0 +950 502 335 361 1 +314 361 941 950 0 +41 18 934 47 0 +973 285 770 846 0 +974 557 755 937 1 +264 557 755 974 1 +937 837 974 557 1 +18 934 15 38 0 +934 33 15 38 0 +38 934 33 41 0 +38 18 934 41 0 +33 934 15 36 0 +608 115 839 948 0 +948 327 775 860 1 +310 865 356 602 0 +293 348 362 701 1 +708 973 770 846 0 +318 846 302 195 0 +950 361 941 771 0 +211 658 705 740 0 +740 783 705 211 1 +906 185 944 697 0 +791 413 317 405 0 +375 791 413 403 0 +60 225 833 244 0 +37 50 833 65 0 +939 81 531 758 0 +144 573 333 854 0 +766 939 531 236 0 +573 128 333 854 0 +758 916 939 766 0 +939 339 758 766 0 +939 339 766 755 0 +542 339 939 755 0 +542 939 758 755 0 +60 244 833 65 0 +427 81 939 758 0 +542 339 758 939 0 +209 570 736 960 0 +13 9 279 808 0 +941 303 200 667 0 +204 150 314 941 1 +490 260 849 75 1 +490 953 75 849 1 +717 279 9 49 0 +303 125 249 941 0 +668 173 165 857 1 +238 258 410 856 0 +856 88 238 351 0 +929 896 993 753 0 +714 930 640 485 1 +785 955 253 516 0 +697 9 944 808 0 +1027 246 528 69 1 +722 881 480 991 1 +881 492 149 664 1 +146 108 940 845 0 +731 223 684 172 1 +288 573 211 275 0 +367 289 581 767 0 +790 106 424 844 0 +970 292 18 67 0 +881 492 630 589 1 +103 506 526 872 0 +630 492 881 664 1 +790 844 706 575 0 +844 424 706 575 0 +912 547 559 295 1 +210 391 974 942 0 +844 424 825 778 1 +807 240 115 393 1 +480 990 764 882 0 +354 557 755 947 1 +878 651 280 879 0 +593 400 31 52 0 +21 276 34 55 0 +354 840 947 766 1 +354 557 947 840 1 +592 86 430 533 0 +790 74 982 68 0 +725 692 453 463 0 +982 74 106 971 0 +1019 820 926 970 0 +948 115 775 327 1 +679 115 948 327 1 +307 848 142 956 0 +957 309 846 304 0 +846 309 336 195 0 +604 447 235 606 1 +604 443 86 430 1 +98 501 751 1004 1 +1004 88 734 599 1 +906 98 1004 501 1 +541 742 936 286 0 +533 86 430 604 1 +431 670 1012 229 1 +325 852 958 294 1 +760 949 561 438 0 +949 359 561 438 1 +760 359 949 438 0 +146 359 949 760 0 +398 607 968 514 0 +100 232 733 445 1 +849 786 155 417 0 +851 151 365 764 0 +193 304 147 957 0 +8 307 203 848 0 +290 934 832 391 0 +205 560 953 311 1 +953 311 560 819 0 +819 560 953 370 0 +153 311 953 819 0 +205 953 153 311 1 +1023 453 804 507 0 +991 722 478 882 1 +8 848 850 952 1 +956 309 850 848 1 +563 899 79 954 0 +563 752 899 954 0 +1 672 852 325 0 +961 151 316 959 0 +144 299 256 954 0 +144 256 573 954 0 +855 269 427 75 0 +316 959 855 269 0 +341 961 855 269 0 +855 959 427 269 0 +316 959 427 855 0 +238 770 258 856 1 +856 88 351 501 0 +128 854 783 333 0 +769 355 954 209 1 +34 517 12 716 0 +849 786 417 953 0 +849 819 953 417 0 +420 819 849 417 0 +193 304 957 847 0 +957 304 195 847 0 +193 304 847 78 0 +652 185 697 808 1 +652 571 396 911 1 +261 957 785 491 0 +261 491 271 957 0 +957 491 271 685 0 +261 957 271 685 0 +957 261 259 685 0 +309 957 259 685 0 +309 261 259 957 0 +521 978 451 713 0 +652 808 697 571 1 +957 491 685 566 0 +318 957 685 566 0 +318 491 957 566 0 +651 520 541 957 0 +847 304 781 78 0 +640 532 925 66 0 +151 916 959 535 0 +916 151 959 365 0 +439 539 1006 534 1 +1010 764 1005 151 1 +916 959 236 365 0 +634 532 640 66 0 +550 746 962 131 1 +550 962 921 131 1 +550 746 921 962 1 +746 301 921 962 1 +548 962 131 302 1 +548 302 578 962 1 +948 327 860 125 1 +962 746 914 559 0 +72 962 198 914 0 +962 551 198 914 0 +962 746 551 914 0 +216 198 962 551 1 +216 198 72 962 1 +739 216 72 962 1 +859 707 72 578 1 +132 707 859 578 0 +653 858 524 523 0 +963 775 702 860 0 +491 759 915 868 1 +224 329 363 863 0 +937 838 983 970 0 +244 861 27 68 0 +880 40 939 47 0 +120 579 966 702 0 +645 870 521 713 0 +128 837 264 866 1 +541 742 286 868 0 +969 759 868 865 1 +474 434 881 991 0 +982 27 861 68 0 +882 998 851 428 0 +597 809 1025 901 0 +450 967 741 449 0 +210 854 866 256 0 +984 329 700 863 0 +210 942 866 854 0 +866 837 254 256 0 +586 984 607 291 0 +841 984 607 945 1 +586 329 700 984 0 +491 759 868 280 1 +810 224 436 863 0 +54 982 35 59 0 +968 289 766 939 0 +19 968 766 939 0 +19 968 939 47 0 +968 842 939 47 0 +19 842 968 47 0 +842 19 968 841 0 +968 19 695 841 0 +607 968 695 841 0 +607 842 968 841 0 +842 363 607 968 1 +19 695 392 968 0 +392 283 968 695 0 +283 392 968 591 0 +968 392 21 591 0 +968 591 21 766 0 +19 968 21 766 0 +19 392 21 968 0 +766 289 968 591 0 +23 970 838 36 0 +23 15 970 36 0 +15 970 16 23 0 +16 970 721 23 0 +721 970 254 23 0 +23 970 254 912 0 +912 970 254 186 0 +970 838 254 186 0 +912 838 970 186 0 +23 838 970 912 0 +586 984 863 607 0 +863 984 363 607 1 +937 970 837 275 0 +721 970 937 275 0 +275 970 254 721 0 +970 836 721 937 0 +194 836 970 937 0 +194 838 937 970 1 +843 945 984 586 1 +970 194 838 292 1 +292 970 934 838 0 +970 836 820 721 0 +591 453 1023 725 0 +846 285 936 973 1 +974 837 264 557 1 +867 541 967 864 1 +264 783 128 974 0 +517 472 716 276 0 +879 715 587 985 1 +286 868 759 981 0 +692 662 289 863 0 +289 662 224 863 0 +363 289 224 863 0 +652 911 753 558 1 +280 491 715 879 0 +356 865 741 602 0 +863 607 398 514 0 +892 28 1021 62 0 +1002 516 652 386 0 +854 256 288 866 0 +892 450 975 891 0 +149 492 297 664 1 +297 83 922 492 1 +103 447 977 171 0 +910 160 477 872 1 +103 447 901 977 0 +691 390 598 977 0 +103 901 691 977 0 +874 274 383 62 0 +874 594 389 383 0 +564 913 524 228 0 +99 564 524 228 0 +99 500 524 564 0 +42 99 524 228 0 +521 524 572 654 1 +572 653 654 524 0 +708 654 653 524 0 +708 524 247 654 0 +524 263 829 247 0 +405 731 223 684 1 +891 221 523 889 0 +684 317 145 223 1 +682 603 427 223 1 +223 317 145 682 1 +572 523 221 889 0 +405 223 317 684 1 +889 644 522 975 1 +525 523 522 975 1 +875 516 652 1002 0 +866 974 128 942 0 +894 184 726 164 1 +729 468 297 492 0 +130 184 894 164 1 +130 164 894 206 1 +206 164 894 282 1 +524 375 818 247 0 +653 523 525 975 0 +389 513 874 62 0 +851 478 590 882 0 +524 353 263 247 0 +654 353 524 247 0 +42 521 185 524 0 +42 524 185 228 0 +654 524 185 521 0 +19 880 842 47 0 +878 868 981 280 0 +286 868 981 878 0 +27 982 22 59 0 +541 868 286 878 0 +27 833 877 982 0 +557 986 211 740 0 +986 658 211 740 0 +481 658 986 740 0 +557 481 986 740 0 +836 986 557 481 0 +802 738 884 89 0 +658 986 724 481 0 +986 910 724 481 0 +882 997 987 428 0 +940 1007 76 431 1 +76 539 431 1007 1 +888 873 713 450 1 +910 160 872 989 1 +55 988 14 67 0 +55 482 988 67 0 +46 482 988 55 0 +46 988 14 55 0 +20 988 14 46 0 +476 988 20 46 0 +46 988 482 476 0 +988 723 482 476 0 +476 723 20 988 0 +20 723 14 988 0 +194 475 21 988 0 +475 435 21 988 0 +273 884 452 714 1 +884 485 714 640 1 +884 452 89 273 1 +467 452 89 884 1 +802 884 467 89 0 +273 89 884 738 0 +888 834 867 967 0 +991 3 506 103 0 +991 506 526 103 0 +434 991 526 103 0 +159 506 526 991 0 +991 163 526 159 1 +159 163 478 991 1 +991 163 478 722 1 +658 163 991 722 1 +658 630 722 991 1 +658 630 991 161 1 +991 630 727 161 1 +658 991 727 161 1 +658 724 727 991 1 +727 724 526 991 1 +991 724 526 163 1 +658 724 991 163 1 +474 727 526 991 1 +474 727 991 630 1 +159 478 990 991 1 +159 3 506 991 0 +227 993 618 169 0 +993 618 169 127 0 +993 127 169 98 0 +828 110 538 797 0 +828 774 779 612 1 +417 420 819 370 0 +582 774 828 612 1 +117 322 377 793 1 +799 380 828 797 0 +828 110 613 799 0 +799 828 538 797 0 +789 721 372 275 1 +887 428 1011 1010 1 +1012 103 82 901 1 +1012 901 82 239 1 +670 665 527 415 0 +378 830 799 322 0 +830 676 799 322 0 +416 376 676 250 1 +454 571 931 389 0 +721 970 10 926 0 +926 352 768 547 0 +897 938 510 688 1 +829 263 353 496 1 +613 380 799 378 0 +380 676 799 378 0 +613 676 380 378 0 +676 799 797 380 0 +898 263 829 496 1 +898 674 829 263 1 +412 795 376 825 0 +676 380 797 248 0 +539 408 409 229 0 +282 423 181 816 0 +898 829 353 496 1 +76 779 613 380 0 +911 720 454 272 0 +1019 926 768 465 0 +702 1028 643 579 0 +337 254 381 334 0 +337 254 800 381 0 +529 381 800 254 1 +529 624 800 381 1 +536 764 463 365 0 +383 13 25 56 0 +3 725 463 536 0 +522 888 525 893 1 +313 156 728 87 1 +1024 519 386 652 0 +882 478 590 722 0 +463 660 429 633 0 +39 13 383 62 0 +56 383 13 62 0 +452 802 369 89 1 +573 275 144 136 0 +836 986 886 211 0 +463 692 633 365 0 +491 280 715 449 1 +453 660 463 633 0 +383 279 386 272 1 +390 804 623 691 1 +3 725 429 463 0 +21 435 871 482 0 +927 592 404 533 0 +885 591 1023 506 1 +385 86 533 441 0 +504 241 400 511 0 +394 816 181 509 0 +774 585 414 612 1 +403 145 405 317 0 +414 110 613 828 0 +1016 92 576 951 0 +693 761 813 464 0 +967 888 653 525 0 +692 660 453 633 0 +813 761 129 464 0 +150 460 200 303 1 +452 938 592 385 0 +460 627 200 303 1 +643 226 576 617 1 +226 574 643 775 1 +579 643 617 574 1 +346 13 389 571 0 +696 463 633 384 1 +805 13 25 389 0 +509 200 667 824 0 +403 791 379 317 0 +346 13 805 389 0 +272 911 388 278 0 +463 692 453 633 0 +911 571 396 455 1 +918 728 567 750 1 +319 684 508 145 0 +684 319 508 95 0 +684 508 188 95 0 +738 402 465 601 0 +818 858 247 493 0 +901 812 691 390 0 +679 327 457 619 1 +163 93 622 722 0 +452 938 89 458 1 +740 481 357 840 0 +457 327 948 619 1 +936 541 867 834 1 +391 819 264 542 0 +783 391 264 542 0 +783 819 391 542 0 +783 311 391 819 0 +391 311 752 819 0 +752 819 355 391 1 +391 752 311 333 0 +783 391 311 333 0 +783 752 391 333 0 +473 424 586 825 1 +961 151 851 1010 1 +871 435 646 977 1 +654 285 258 973 0 +419 612 414 110 0 +310 865 602 772 0 +449 981 587 967 0 +800 624 418 381 1 +418 824 624 800 1 +418 374 624 824 1 +939 832 755 354 1 +176 404 183 900 0 +404 803 183 900 0 +812 515 105 597 1 +515 809 597 691 0 +900 404 803 119 0 +915 449 545 741 1 +463 536 633 384 0 +810 291 629 586 0 +786 560 832 755 0 +741 449 388 806 0 +449 255 545 741 1 +519 808 652 571 1 +83 987 998 201 0 +994 13 931 571 0 +525 888 653 975 0 +83 987 997 998 1 +998 987 997 428 0 +888 876 980 525 0 +911 571 455 642 0 +911 455 928 642 0 +991 995 881 480 0 +13 9 808 396 0 +989 1022 479 622 0 +455 931 281 642 0 +697 808 396 571 1 +142 732 165 284 1 +210 290 391 942 0 +973 285 936 348 1 +936 867 565 834 1 +837 256 288 254 0 +329 843 581 363 0 +329 424 581 843 1 +876 1001 985 1002 0 +809 506 429 103 0 +429 901 239 1025 1 +239 901 82 1025 0 +461 299 192 505 0 +407 951 821 467 1 +24 818 287 1026 0 +400 688 31 52 0 +527 1025 105 809 1 +82 1025 456 694 0 +812 691 597 1025 0 +812 597 105 1025 0 +105 239 694 1025 0 +806 450 594 543 0 +803 688 31 400 0 +403 787 188 512 1 +461 505 192 624 0 +299 399 505 624 0 +399 374 505 624 0 +399 189 401 816 1 +404 119 234 510 0 +845 431 895 1007 1 +402 689 738 908 1 +810 514 695 397 1 +354 292 934 838 1 +275 705 211 372 0 +459 806 389 693 1 +375 787 188 403 1 +95 596 319 512 0 +319 145 596 495 0 +56 689 513 62 0 +871 390 476 447 0 +427 1005 603 959 1 +402 389 25 513 0 +310 356 757 602 0 +402 513 805 389 0 +513 543 805 389 1 +1007 539 431 895 1 +509 667 401 442 1 +107 1005 603 895 1 +831 95 596 155 0 +95 495 319 596 0 +530 857 1027 965 0 +375 787 403 818 0 +224 289 363 367 0 +420 673 79 899 0 +123 580 414 110 1 +123 414 612 110 0 +365 662 289 692 0 +428 1010 851 764 1 +803 430 404 183 0 +791 403 508 317 0 +460 509 200 627 0 +406 507 804 660 1 +507 392 804 660 1 +460 394 200 509 0 +95 495 596 155 0 +805 513 402 908 1 +509 200 627 667 0 +804 392 623 406 1 +1019 820 589 468 0 +192 789 275 461 0 +601 465 738 637 1 +977 506 809 103 0 +407 576 226 821 1 +951 576 407 821 1 +621 1017 814 826 0 +471 174 582 612 0 +434 526 474 171 0 +788 826 1017 825 0 +576 407 226 240 1 +689 513 601 56 0 +493 395 1026 979 1 +160 171 977 476 0 +689 638 757 601 1 +691 598 809 977 0 +96 788 1017 825 0 +461 94 275 136 0 +192 461 275 136 0 +192 275 372 136 0 +1019 20 14 51 0 +474 995 149 881 0 +410 42 24 74 0 +829 410 24 74 0 +829 74 379 410 0 +656 894 726 164 1 +702 963 656 366 1 +702 656 120 366 1 +656 140 457 619 1 +225 376 788 412 0 +225 795 376 412 0 +1018 666 85 58 0 +833 412 575 244 0 +674 413 405 497 0 +413 379 405 497 0 +410 379 413 497 0 +265 410 413 497 0 +674 265 413 497 0 +674 829 413 265 1 +265 410 829 413 0 +410 379 829 413 0 +674 263 413 829 1 +413 263 375 829 0 +375 829 24 413 0 +247 263 375 413 0 +247 413 375 791 0 +247 263 413 791 0 +674 263 791 413 1 +905 408 415 527 0 +795 790 328 422 0 +8 848 203 850 0 +711 423 181 282 0 +711 743 423 282 0 +575 424 422 844 1 +417 370 953 786 0 +229 408 822 415 0 +229 408 415 905 0 +416 378 830 676 0 +117 378 830 416 0 +117 822 378 416 0 +648 287 842 880 0 +880 971 347 648 1 +648 767 842 287 0 +415 700 421 665 0 +373 395 786 417 0 +395 155 786 417 0 +307 203 850 681 0 +373 155 395 417 0 +615 225 471 174 0 +468 852 262 325 0 +522 870 645 980 1 +334 299 381 418 0 +381 299 461 418 0 +337 381 418 334 0 +337 418 181 334 0 +468 820 589 492 0 +337 381 181 418 0 +800 418 181 381 0 +181 824 418 800 1 +841 19 695 472 0 +823 582 118 419 1 +387 420 370 819 1 +387 673 370 420 1 +417 673 420 370 1 +417 673 155 420 0 +155 673 79 420 0 +622 590 151 478 0 +149 664 614 474 0 +434 474 614 171 0 +478 882 764 990 0 +793 328 782 421 1 +421 328 782 700 1 +782 700 224 421 1 +421 609 224 782 1 +793 609 421 782 1 +793 609 224 421 1 +991 478 990 882 1 +376 250 826 421 0 +826 416 421 250 0 +415 416 421 826 0 +408 826 415 421 0 +408 421 415 527 0 +421 621 415 527 0 +826 621 421 527 0 +408 826 421 527 0 +415 416 117 421 0 +334 423 181 711 0 +334 743 423 711 0 +743 299 334 423 0 +376 469 797 225 1 +472 924 716 276 0 +634 930 817 640 0 +657 71 168 532 1 +640 532 930 925 0 +1015 712 346 545 0 +545 1015 904 346 0 +904 1015 459 346 0 +788 225 469 376 1 +788 469 826 376 1 +244 797 469 225 0 +134 1015 904 545 0 +134 687 1015 545 0 +687 712 1015 545 0 +687 753 1015 712 0 +687 753 896 1015 0 +471 419 823 828 1 +177 73 165 656 1 +1019 468 262 768 0 +468 325 262 768 1 +408 1018 823 380 1 +1018 248 823 380 1 +408 248 1018 380 1 +80 470 687 896 0 +80 470 284 687 0 +225 412 788 1018 0 +1018 412 788 96 0 +96 788 1018 1017 0 +925 48 532 669 0 +532 48 925 66 0 +60 1018 96 412 0 +60 225 1018 412 0 +967 878 981 587 1 +541 742 868 651 0 +1018 96 30 60 0 +57 96 30 1018 0 +220 951 407 1015 1 +904 908 220 738 0 +220 805 467 908 0 +908 467 220 738 0 +618 116 470 896 0 +760 845 1012 895 1 +935 883 481 1022 0 +3 480 764 428 0 +1000 336 541 955 0 +3 159 429 725 0 +766 479 236 289 0 +646 1023 506 977 0 +836 211 557 986 0 +169 993 368 232 0 +876 888 713 450 1 +983 937 974 210 1 +141 130 184 726 1 +184 156 918 726 0 +318 491 742 651 0 +932 251 233 933 1 +986 724 161 589 0 +982 27 833 861 0 +47 19 880 54 0 +842 880 939 47 0 +1026 560 682 979 0 +870 1021 978 713 1 +979 395 1026 786 0 +786 75 1026 979 0 +979 560 682 832 0 +647 869 373 245 1 +645 870 713 980 1 +893 892 1021 873 0 +468 262 297 492 0 +766 773 360 1022 0 +1024 587 967 449 0 +587 558 449 1024 0 +1001 862 518 654 0 +1024 876 1002 386 0 +261 520 785 957 0 +185 524 253 258 0 +810 586 863 607 0 +383 272 386 1024 1 +1024 383 717 386 1 +451 1024 717 386 1 +451 1024 594 717 1 +1024 383 594 717 1 +383 272 1024 594 1 +451 274 594 1024 1 +785 1001 955 654 0 +607 363 863 968 1 +527 905 105 1025 1 +905 239 105 1025 1 +155 1026 786 75 0 +155 495 1026 75 0 +1026 495 145 75 0 +495 145 596 1026 0 +403 145 1026 596 0 +403 1026 818 596 0 +493 596 818 1026 1 +524 353 829 263 0 +977 390 871 447 0 +506 1023 646 406 0 +155 395 786 1026 0 +596 1026 395 155 0 +596 495 1026 155 0 +1026 448 596 395 1 +493 448 1026 395 1 +493 448 596 1026 1 +223 603 427 1005 1 +717 279 383 462 0 +235 456 102 669 0 +456 48 102 669 0 +102 456 46 48 0 +456 26 46 48 0 +893 450 975 892 0 +45 476 482 55 0 +1023 507 598 406 0 +886 970 820 1019 0 +390 447 456 102 0 +456 447 82 102 0 +82 456 102 235 0 +82 456 901 447 0 +901 456 390 447 0 +901 812 390 456 0 +390 623 456 812 1 +456 623 694 812 1 +886 589 820 211 0 +211 658 986 589 0 +682 832 287 1026 0 +880 35 40 54 0 +873 1021 976 62 0 +1024 519 558 449 0 +944 718 697 753 0 +904 545 346 459 0 +415 408 416 826 0 +692 283 453 660 1 +337 460 394 200 0 +337 150 460 200 0 +21 623 276 55 0 +192 94 461 136 0 +13 279 717 462 0 +717 383 274 39 0 +573 299 144 461 0 +299 94 144 461 0 +256 299 573 461 0 +256 461 573 381 0 +573 381 461 254 0 +529 381 254 461 1 +529 624 381 461 1 +123 444 419 244 0 +256 299 461 381 0 +519 911 558 449 0 +592 86 234 430 0 +506 507 429 660 0 +506 406 429 507 0 +507 406 429 660 0 +453 660 429 463 0 +1010 1005 1011 167 1 +463 3 763 429 0 +536 463 763 429 0 +429 536 463 146 1 +463 536 384 146 1 +429 463 384 146 1 +384 905 463 429 1 +536 3 763 463 0 +93 479 360 622 0 +527 463 633 696 1 +872 477 163 622 1 +56 601 689 62 0 +547 559 465 912 1 +465 559 637 912 0 +56 465 601 62 0 +912 547 158 465 0 +928 642 784 720 1 +169 232 733 122 1 +958 465 768 547 0 +958 504 465 547 0 +504 511 465 547 0 +547 511 465 738 0 +511 458 465 738 0 +458 465 738 273 0 +273 465 738 402 0 +483 478 764 990 0 +689 543 513 976 0 +25 402 465 52 0 +402 688 465 52 0 +465 688 511 52 0 +465 511 400 52 0 +465 400 593 52 0 +465 593 43 52 0 +25 465 43 52 0 +465 768 43 593 0 +958 593 768 465 0 +958 504 593 465 0 +465 400 504 593 0 +504 511 400 465 0 +867 981 865 967 0 +635 590 722 201 0 +208 635 722 163 0 +635 93 722 590 0 +43 23 912 465 0 +83 635 722 201 0 +511 458 688 465 0 +458 688 465 273 0 +273 688 465 402 0 +128 866 288 837 0 +714 930 273 640 1 +458 592 641 927 1 +80 618 284 470 0 +618 116 284 470 0 +470 116 284 951 0 +248 419 471 828 1 +248 612 471 419 0 +469 471 248 612 0 +225 471 469 612 0 +615 225 612 471 0 +225 469 471 1018 0 +469 248 471 1018 0 +1018 248 471 823 1 +823 774 471 1018 0 +1018 774 471 666 0 +471 774 85 666 0 +1018 471 85 666 0 +85 1018 30 471 0 +85 471 30 583 0 +583 471 30 174 0 +583 582 471 174 0 +85 582 471 583 0 +582 774 85 471 0 +823 774 582 471 0 +1014 486 167 1003 1 +715 650 558 875 1 +864 541 967 518 1 +645 1001 516 654 0 +654 1000 1001 258 0 +486 1010 167 1003 1 +523 889 522 975 1 +96 659 924 472 0 +1017 472 659 96 0 +650 261 271 718 0 +650 271 558 718 1 +785 650 718 955 0 +785 261 491 650 0 +650 261 491 271 0 +715 271 558 650 1 +785 491 715 650 0 +862 879 651 587 1 +651 868 878 491 0 +651 742 868 491 0 +904 220 407 738 0 +476 482 160 723 1 +886 986 161 589 0 +884 402 273 738 0 +805 402 273 884 0 +881 722 480 997 1 +103 506 872 977 0 +929 281 484 712 0 +622 725 506 483 1 +483 163 622 478 1 +159 163 622 483 1 +483 725 506 159 1 +194 988 883 475 0 +836 886 820 211 0 +977 435 506 872 1 +476 26 45 46 0 +26 476 456 46 0 +622 483 506 159 1 +1022 989 163 622 0 +31 476 20 46 0 +20 476 31 593 0 +476 803 31 593 0 +593 803 727 476 0 +803 903 727 476 0 +727 476 903 171 0 +476 171 447 903 0 +978 274 451 713 1 +476 435 871 160 1 +159 163 483 478 1 +997 722 480 987 1 +370 869 979 647 0 +513 594 874 976 0 +24 370 979 832 0 +979 1026 287 832 0 +483 479 725 764 0 +1026 979 682 832 0 +483 478 365 764 0 +723 160 476 157 0 +478 151 365 851 0 +723 476 727 157 0 +593 476 727 723 0 +20 723 476 593 0 +727 160 476 171 0 +479 483 365 764 0 +477 171 526 872 0 +476 404 803 903 0 +688 404 476 903 0 +688 404 803 476 0 +31 688 803 476 0 +365 289 479 692 0 +227 114 993 169 0 +993 114 817 169 0 +194 836 935 883 0 +454 931 484 346 0 +740 481 840 557 0 +557 840 935 481 0 +836 557 935 481 0 +539 1009 588 439 1 +740 658 163 481 0 +658 481 724 163 0 +481 910 724 163 0 +654 285 1000 258 0 +740 163 208 481 0 +989 506 872 622 1 +45 476 46 482 0 +28 891 36 62 0 +1019 886 589 820 0 +476 435 160 482 1 +723 886 161 589 0 +784 281 712 484 0 +277 720 784 484 1 +720 931 784 484 1 +931 784 484 281 0 +720 931 484 454 1 +277 720 484 454 1 +388 277 484 454 1 +988 14 886 723 0 +993 994 122 817 0 +634 994 640 817 0 +993 485 994 817 1 +114 485 817 714 0 +714 930 485 817 1 +114 5 485 714 0 +116 5 485 114 0 +640 994 485 817 1 +116 5 369 485 0 +116 951 485 369 0 +116 951 896 485 0 +896 485 467 929 1 +435 885 1023 506 1 +872 435 506 885 1 +872 435 885 160 1 +989 160 872 885 1 +910 885 160 989 1 +998 486 730 1010 1 +730 83 920 486 1 +486 83 920 297 1 +730 486 920 297 1 +312 744 205 490 1 +312 737 744 490 1 +737 563 744 490 1 +490 635 205 312 1 +486 297 176 183 1 +149 297 486 183 1 +149 183 486 614 1 +149 83 486 297 1 +83 887 149 486 1 +149 887 995 486 1 +490 94 737 563 1 +487 1007 580 110 1 +487 580 1007 1009 1 +5 1003 167 734 1 +1009 580 583 487 1 +583 580 174 487 1 +730 488 155 1010 1 +730 488 1010 1003 1 +490 563 744 153 1 +488 730 155 79 1 +831 488 155 79 1 +730 1003 486 489 1 +297 730 486 489 1 +297 730 489 321 1 +488 489 1013 1014 1 +1003 489 488 1014 1 +488 1014 1013 165 1 +77 176 234 489 1 +1 489 176 77 1 +490 260 155 849 1 +437 1010 490 260 1 +437 260 490 341 1 +998 1010 490 437 1 +83 490 437 998 1 +83 730 490 998 1 +998 1010 730 490 1 +83 490 730 920 1 +920 154 490 730 1 +154 94 490 730 1 +154 94 737 490 1 +154 490 737 215 1 +312 737 490 215 1 +201 312 490 215 1 +920 201 490 215 1 +920 154 215 490 1 +83 201 490 920 1 +83 201 437 490 1 +437 590 490 201 1 +201 635 590 490 1 +201 635 490 312 1 +437 590 535 490 1 +490 535 953 590 1 +939 531 81 832 0 +832 531 81 252 0 +427 832 81 252 0 +427 939 81 832 0 +362 742 969 286 0 +128 211 264 837 1 +656 344 268 164 1 +290 264 974 391 0 +866 983 974 210 1 +517 347 19 877 0 +838 337 254 186 0 +186 204 838 337 0 +838 204 210 337 0 +210 337 254 838 0 +873 892 1021 62 0 +656 307 608 268 1 +886 14 1019 723 0 +728 217 184 750 1 +728 87 184 217 1 +728 162 184 87 1 +722 589 630 658 1 +195 293 362 701 1 +838 937 354 194 1 +451 1024 386 876 1 +329 843 984 586 1 +186 204 210 838 0 +186 210 747 838 0 +982 74 971 68 0 +404 592 430 533 0 +55 21 482 67 0 +886 910 475 723 1 +935 557 354 840 1 +287 106 971 424 0 +287 971 844 424 0 +586 424 841 778 1 +841 424 945 778 1 +82 1012 1006 447 1 +473 328 329 706 1 +878 491 280 651 0 +329 424 843 586 1 +250 473 793 421 0 +843 424 945 586 1 +220 407 240 904 0 +354 194 292 838 1 +166 1004 1008 734 1 +985 587 876 1024 0 +586 424 945 841 1 +982 833 877 861 0 +96 666 1018 58 0 +149 474 614 434 0 +945 19 842 841 0 +607 945 842 841 0 +766 996 21 935 0 +892 873 976 62 0 +126 284 393 807 0 +928 281 712 784 1 +650 718 875 652 1 +295 912 186 914 1 +600 907 559 295 1 +295 912 914 559 1 +524 858 869 523 0 +842 289 843 363 1 +531 289 236 365 0 +531 662 289 365 0 +662 382 531 289 0 +367 628 289 767 0 +842 767 843 289 1 +16 14 970 67 0 +289 767 531 939 0 +169 993 122 817 0 +766 289 531 939 0 +289 382 531 767 0 +662 628 382 289 0 +224 628 662 289 0 +224 628 289 367 0 +367 363 581 289 0 +581 843 289 363 0 +109 672 668 294 0 +778 945 841 844 1 +423 374 418 181 1 +790 424 706 844 0 +936 362 302 846 0 +318 847 846 195 0 +847 957 846 195 0 +318 957 846 847 0 +957 318 685 847 1 +318 91 685 847 1 +165 237 668 120 1 +957 847 685 147 1 +193 957 147 847 0 +366 237 165 120 1 +120 965 668 165 1 +165 965 668 857 1 +724 477 526 163 1 +20 1019 14 723 0 +910 477 163 989 1 +766 365 236 479 0 +851 590 151 437 0 +479 365 236 289 0 +734 5 732 227 1 +1 672 176 852 0 +672 77 176 852 0 +176 77 900 852 0 +326 77 852 900 0 +326 77 672 852 0 +769 854 954 752 1 +769 942 854 752 1 +854 942 333 752 0 +210 769 942 854 0 +210 769 854 256 0 +769 854 256 954 1 +256 854 573 954 0 +144 573 854 954 0 +144 744 954 854 0 +854 744 954 205 0 +144 744 854 205 0 +854 256 573 288 0 +128 854 573 288 0 +565 975 867 865 0 +834 867 967 864 0 +772 867 565 975 0 +867 975 450 865 0 +856 258 410 230 0 +238 856 410 230 0 +230 88 238 856 0 +230 88 856 564 0 +564 88 856 913 0 +230 856 258 564 0 +845 895 735 1007 1 +39 28 1021 644 0 +432 173 668 857 0 +982 877 347 861 1 +544 964 858 781 1 +964 708 858 781 0 +781 858 678 708 0 +708 678 496 858 0 +781 678 858 498 0 +858 678 584 498 0 +781 858 584 498 0 +584 207 858 781 0 +858 207 544 781 1 +584 207 544 858 1 +544 584 858 703 0 +858 584 387 703 0 +544 858 387 703 0 +544 858 370 387 0 +370 858 245 387 0 +858 584 245 387 0 +584 680 858 245 0 +584 178 858 680 0 +858 178 678 680 0 +584 178 678 858 0 +981 868 759 280 0 +865 981 969 759 0 +449 759 981 741 0 +986 658 724 589 0 +489 672 1013 165 1 +981 865 967 741 0 +981 759 865 741 0 +368 127 232 733 1 +935 883 996 475 0 +450 967 865 741 0 +968 863 398 692 0 +863 968 398 607 0 +491 868 915 566 1 +286 742 969 868 0 +868 759 915 566 1 +565 772 975 865 0 +310 565 865 772 0 +565 969 310 865 0 +969 865 356 310 1 +969 865 566 356 1 +865 759 566 356 1 +865 759 356 741 1 +883 475 481 996 1 +858 245 493 869 0 +982 11 59 63 0 +982 861 347 971 1 +286 969 759 868 0 +450 867 865 967 0 +59 27 982 68 0 +244 982 861 68 0 +957 491 520 785 0 +936 541 286 867 1 +936 286 565 867 1 +565 286 969 867 0 +11 35 982 59 0 +565 867 969 865 0 +63 59 982 68 0 +772 834 867 975 0 +261 309 520 957 0 +19 880 648 842 0 +44 24 391 523 0 +869 373 395 786 1 +19 648 945 842 0 +493 373 395 869 1 +524 829 353 410 0 +390 646 598 977 0 +646 804 390 598 0 +656 165 726 894 1 +972 973 654 708 0 +731 603 223 1007 1 +152 731 603 223 1 +223 603 1005 1007 1 +656 177 164 162 1 +973 258 654 708 0 +572 889 221 644 0 +653 973 654 972 0 +164 656 801 683 1 +3 483 159 725 0 +871 476 45 55 0 +716 871 45 55 0 +623 871 716 55 0 +21 871 623 55 0 +483 764 725 536 0 +21 435 623 871 0 +435 804 623 871 0 +871 804 623 390 0 +623 390 716 871 0 +456 390 871 716 0 +456 871 45 716 0 +456 26 45 871 0 +871 26 45 476 0 +456 26 871 476 0 +456 390 476 871 0 +435 804 871 1023 0 +858 245 869 647 0 +977 171 447 871 0 +894 173 857 165 1 +689 892 976 601 0 +689 976 892 891 0 +892 976 873 891 0 +976 450 978 873 1 +873 978 713 450 1 +108 735 425 243 1 +1021 978 713 873 1 +873 978 274 1021 1 +976 873 274 1021 0 +976 978 274 873 1 +893 873 888 450 1 +870 893 888 644 1 +221 28 644 892 0 +165 965 857 894 1 +870 1021 893 644 1 +451 717 594 874 1 +451 874 594 274 1 +451 717 874 274 1 +717 383 874 274 0 +268 608 656 324 1 +651 878 967 587 1 +862 651 967 587 1 +34 517 19 877 0 +1024 985 519 875 0 +646 1023 598 406 0 +34 472 19 517 0 +871 804 390 646 0 +871 804 646 1023 0 +1023 804 646 598 0 +221 892 644 891 0 +892 889 644 891 0 +601 892 976 62 0 +978 876 713 450 1 +978 274 876 450 1 +876 274 594 450 1 +1024 876 594 450 1 +1024 274 594 876 1 +451 274 1024 876 1 +451 274 876 713 1 +978 274 713 876 1 +891 28 892 62 0 +221 28 892 891 0 +654 955 253 258 0 +876 967 980 525 0 +980 967 876 864 0 +876 967 862 864 0 +980 876 862 864 0 +862 985 967 876 0 +985 587 967 876 0 +40 11 880 832 0 +878 868 280 491 0 +520 491 879 785 0 +875 718 558 652 1 +867 541 878 967 1 +867 878 981 967 1 +867 286 981 878 1 +867 541 286 878 1 +280 715 587 879 1 +878 280 587 879 1 +880 11 287 832 0 +767 832 880 287 0 +767 880 842 287 0 +841 649 19 472 0 +893 888 525 975 1 +841 778 649 472 1 +649 778 1017 472 1 +472 1017 649 96 1 +982 971 880 287 0 +982 11 287 880 0 +35 11 982 880 0 +982 971 347 880 1 +982 347 877 880 0 +877 347 19 880 0 +767 880 939 842 0 +767 832 939 880 0 +83 492 881 625 1 +881 492 589 625 1 +996 475 21 935 0 +640 13 884 346 0 +884 13 805 346 0 +884 346 805 459 0 +929 884 805 459 0 +884 346 459 929 0 +994 346 884 929 0 +884 929 485 994 1 +640 884 485 994 1 +640 346 884 994 0 +884 467 485 929 1 +805 884 929 467 0 +805 402 884 467 0 +467 402 884 738 0 +802 738 467 884 0 +467 452 884 485 1 +273 13 805 884 0 +989 885 506 725 1 +989 885 872 506 1 +435 591 1023 885 0 +591 435 21 885 0 +886 999 988 475 1 +836 886 999 988 0 +836 194 886 988 0 +886 194 970 988 0 +970 14 886 988 0 +970 14 1019 886 0 +836 194 970 886 0 +836 986 999 886 0 +157 910 724 886 0 +965 894 704 530 1 +1021 873 713 888 1 +870 1021 713 888 1 +870 888 713 980 1 +980 888 713 876 1 +965 966 704 894 1 +894 249 704 530 1 +966 249 704 894 1 +120 894 966 965 1 +967 834 653 888 0 +654 653 222 890 0 +862 864 518 890 0 +221 28 891 61 0 +44 891 28 61 0 +975 889 644 893 1 +522 644 893 975 1 +523 934 891 391 0 +891 934 942 391 0 +703 891 942 391 0 +703 523 891 391 0 +891 703 544 523 0 +891 523 544 577 0 +343 891 544 577 0 +343 891 577 772 0 +577 891 701 772 0 +891 653 701 772 0 +772 653 834 891 0 +891 653 834 975 0 +772 891 834 975 0 +975 772 891 602 0 +891 772 757 602 0 +296 891 757 602 0 +296 891 602 543 0 +891 450 602 543 0 +976 450 891 543 0 +689 976 891 543 0 +689 891 296 543 0 +689 891 637 296 0 +637 891 757 296 0 +637 772 757 891 0 +772 891 637 358 0 +891 343 637 358 0 +772 343 891 358 0 +559 343 637 891 0 +559 891 637 912 0 +912 637 465 891 0 +637 891 601 465 0 +637 891 689 601 0 +975 893 888 450 0 +893 1021 888 873 1 +976 450 873 891 0 +644 892 1021 893 0 +975 450 602 891 0 +559 343 891 912 0 +343 747 891 912 0 +186 891 747 912 0 +186 838 891 912 0 +912 838 891 36 0 +36 934 838 891 0 +934 210 838 891 0 +891 210 838 214 0 +891 838 747 214 0 +703 891 747 214 0 +703 934 891 214 0 +934 210 891 214 0 +703 934 942 891 0 +343 747 703 891 0 +343 703 544 891 0 +186 838 747 891 0 +523 975 653 891 0 +523 653 701 891 0 +577 523 701 891 0 +401 894 595 667 1 +401 626 595 894 1 +595 626 530 894 1 +530 626 857 894 1 +626 173 857 894 1 +505 894 173 626 1 +505 141 894 626 1 +894 141 137 626 1 +399 894 137 626 1 +399 894 626 401 1 +399 189 894 401 1 +189 894 137 399 1 +189 141 137 894 1 +894 345 189 141 1 +130 345 894 141 1 +130 894 726 141 1 +141 135 894 726 1 +130 184 726 894 1 +130 345 206 894 1 +206 345 189 894 1 +505 141 173 894 1 +254 364 800 158 0 +186 364 254 158 0 +186 158 254 912 0 +208 635 93 722 0 +364 314 337 158 0 +158 824 800 529 0 +663 158 529 824 0 +663 771 158 824 0 +663 547 158 771 0 +402 513 689 296 1 +768 352 349 158 0 +711 282 150 164 1 +300 164 711 150 1 +881 722 997 987 1 +313 156 148 728 1 +156 162 184 728 1 +918 156 184 728 1 +156 726 184 162 0 +726 190 918 135 0 +194 14 970 988 0 +211 218 729 705 0 +211 218 372 729 0 +705 922 218 729 0 +595 894 530 667 1 +975 834 867 888 0 +5 443 1008 167 1 +717 274 451 978 0 +479 93 151 590 0 +622 479 151 590 0 +124 599 112 751 0 +599 88 112 751 1 +604 443 167 1008 1 +722 590 987 201 0 +912 891 465 62 0 +149 614 167 1011 1 +740 658 208 163 0 +262 161 468 723 0 +148 728 918 750 1 +481 1022 208 357 0 +159 506 429 725 0 +164 739 302 847 1 +72 164 302 847 1 +72 164 847 138 1 +164 78 847 138 1 +164 78 138 923 1 +164 923 138 919 1 +72 164 138 919 1 +72 164 919 300 1 +300 164 919 191 1 +164 923 919 191 1 +923 217 191 164 1 +750 217 164 191 1 +750 164 182 191 1 +164 711 182 191 1 +300 191 711 164 1 +164 206 182 711 1 +206 164 282 711 1 +1007 539 895 1006 1 +3 764 536 895 1 +1012 431 1006 895 1 +164 130 182 206 1 +750 130 182 164 1 +750 164 567 130 1 +164 184 567 130 1 +895 539 431 1006 1 +184 726 164 162 1 +162 177 164 344 1 +344 268 164 179 1 +164 268 683 179 1 +193 164 683 179 1 +193 344 164 179 1 +87 344 164 193 1 +87 193 164 78 1 +193 847 164 78 1 +193 147 164 847 1 +147 164 847 685 1 +847 91 685 164 1 +164 91 685 686 1 +164 121 686 685 1 +147 121 164 685 1 +147 801 164 121 1 +164 801 686 121 1 +164 801 113 686 1 +555 164 113 686 1 +555 91 164 686 1 +164 555 739 91 1 +847 164 739 91 1 +164 555 180 739 1 +180 198 164 739 1 +164 113 180 555 1 +164 619 113 801 1 +164 683 801 147 1 +193 683 164 147 1 +249 125 303 164 1 +249 164 303 627 1 +1007 895 166 1006 1 +164 125 113 619 1 +87 164 217 78 1 +923 217 164 78 1 +87 164 184 217 1 +750 184 164 217 1 +750 184 567 164 1 +87 162 184 164 1 +87 344 162 164 1 +164 494 300 72 1 +494 300 204 164 1 +575 1017 412 649 1 +833 575 412 649 1 +575 649 833 861 1 +877 833 649 861 1 +877 649 347 861 1 +649 347 861 844 1 +575 649 861 844 1 +649 648 347 844 1 +945 648 649 844 1 +19 649 945 648 0 +19 347 649 648 0 +975 889 893 892 1 +541 878 967 651 1 +519 875 558 652 0 +318 651 541 957 0 +521 253 451 185 0 +645 654 451 521 0 +870 978 521 713 0 +870 521 572 645 1 +654 253 451 521 0 +870 221 521 978 0 +870 221 572 521 1 +521 221 451 978 0 +42 521 221 451 0 +42 185 521 451 0 +650 652 875 253 1 +650 718 652 253 1 +652 253 718 697 1 +753 652 718 697 1 +697 396 753 652 1 +253 185 697 652 1 +862 980 890 645 0 +394 894 816 509 1 +858 524 818 247 0 +858 524 493 818 0 +701 653 348 772 0 +772 348 834 653 0 +348 864 834 653 0 +967 834 864 653 0 +522 893 525 975 1 +386 808 652 519 1 +519 571 652 911 1 +656 619 801 140 1 +973 348 653 285 0 +348 285 864 653 0 +519 911 652 558 1 +701 348 653 973 0 +524 829 375 247 0 +500 258 524 564 0 +564 258 524 913 0 +185 654 253 524 0 +654 524 353 258 0 +524 410 353 258 0 +500 524 410 74 0 +500 42 524 74 0 +524 829 24 375 0 +524 42 24 410 0 +24 524 979 370 0 +24 523 524 370 0 +524 869 979 370 0 +655 221 274 1021 0 +978 655 274 1021 0 +164 656 894 125 1 +870 655 978 1021 0 +870 221 978 655 0 +978 221 274 655 0 +524 858 653 964 0 +524 42 410 74 0 +708 858 524 964 0 +524 258 185 913 0 +522 870 980 644 1 +572 870 522 644 1 +1000 864 285 890 0 +645 253 451 654 0 +645 516 253 654 0 +516 955 253 654 0 +785 955 516 654 0 +1024 1002 652 386 0 +1024 985 558 519 0 +272 911 519 449 0 +879 715 1002 785 1 +221 891 644 889 0 +645 980 222 522 1 +698 127 993 98 0 +698 993 896 98 0 +698 618 896 993 0 +116 993 896 618 0 +227 993 116 618 0 +227 114 116 993 0 +993 114 116 485 0 +116 485 896 993 0 +896 485 929 993 1 +996 910 481 989 1 +993 114 485 817 0 +698 618 993 127 0 +479 989 725 885 1 +723 910 475 885 1 +475 910 996 885 1 +13 9 994 29 0 +994 9 540 29 0 +994 540 445 29 0 +122 994 445 29 0 +634 122 29 994 0 +122 540 445 994 0 +122 232 540 994 0 +994 232 540 368 0 +808 994 540 368 0 +994 808 944 368 0 +993 994 944 368 0 +993 994 368 232 0 +993 232 122 994 0 +944 753 994 993 0 +944 753 396 994 0 +396 808 944 994 0 +808 9 540 994 0 +651 541 1000 518 0 +651 1000 520 518 0 +1024 985 1002 876 0 +1002 1001 985 785 1 +651 541 520 1000 0 +834 541 864 1000 1 +834 1000 864 285 1 +936 1000 834 285 1 +936 541 1000 285 1 +846 1000 541 285 0 +846 336 541 1000 0 +936 541 834 1000 1 +980 862 876 1001 0 +876 862 985 1001 0 +520 862 518 1001 0 +520 518 1000 1001 0 +520 1000 955 1001 0 +785 520 955 1001 0 +520 879 1001 785 1 +1002 1001 516 645 0 +876 1001 1002 645 0 +516 1001 1002 785 0 +785 650 1002 516 1 +1024 1002 875 652 0 +1024 985 875 1002 0 +1002 715 985 875 1 +879 715 985 1002 1 +114 733 169 734 1 +104 1009 111 6 1 +104 433 1009 6 1 +1009 1004 111 6 1 +604 606 235 168 1 +606 175 235 71 1 +74 731 754 426 1 +500 74 562 731 1 +500 731 99 754 1 +831 95 155 488 1 +230 731 172 88 1 +562 731 379 497 1 +233 251 798 488 1 +74 815 731 426 1 +168 606 235 71 1 +1005 223 932 933 1 +76 539 1009 588 1 +488 730 1013 489 1 +634 657 231 168 1 +669 168 71 532 1 +731 564 230 500 1 +101 599 932 734 1 +99 564 731 500 1 +634 657 168 532 1 +114 443 86 168 1 +114 443 168 1008 1 +168 443 86 604 1 +1008 443 168 604 1 +733 1004 6 765 1 +433 445 733 6 1 +540 1004 733 765 1 +368 733 540 1004 1 +776 331 583 1009 1 +233 933 488 1003 1 +233 1003 488 732 1 +959 1005 365 151 1 +82 1006 606 447 1 +104 1009 433 583 1 +733 1009 1008 606 1 +430 167 2 614 1 +101 734 932 732 1 +488 79 831 143 1 +110 444 735 538 1 +102 447 235 604 1 +733 168 122 657 1 +605 735 444 170 1 +792 605 603 152 1 +365 959 236 1005 1 +70 165 488 143 1 +1008 733 114 734 1 +5 443 114 1008 1 +932 166 1008 734 1 +99 731 564 913 1 +731 88 564 913 1 +110 444 1007 735 1 +603 440 735 605 1 +426 735 444 605 1 +497 731 684 172 1 +562 74 379 731 1 +379 74 815 731 1 +731 88 230 564 1 +487 1004 111 1009 1 +84 487 111 615 1 +99 487 1004 111 1 +99 731 1004 487 1 +500 731 562 230 1 +562 731 497 230 1 +426 1007 735 605 1 +845 359 940 735 1 +500 731 754 74 1 +577 653 701 523 0 +858 653 964 523 0 +222 890 525 980 1 +523 858 869 647 0 +975 889 891 523 1 +518 864 1000 890 0 +890 864 285 653 0 +862 864 890 980 0 +890 864 653 980 0 +518 1000 654 890 0 +862 518 654 890 0 +1000 285 654 890 0 +44 24 523 221 0 +572 653 523 522 0 +572 522 889 644 0 +544 703 391 523 0 +394 189 816 894 1 +894 189 816 401 1 +509 894 816 401 1 +627 667 894 509 1 +894 667 401 509 1 +394 894 509 627 1 +120 702 966 894 1 +894 165 120 366 1 +627 894 164 460 1 +394 282 894 460 1 +394 206 894 282 1 +894 282 164 460 1 +391 523 370 544 0 +708 858 247 524 0 +858 869 493 524 0 +524 869 493 979 0 +End diff --git a/Documentation/doc/Documentation/packages.txt b/Documentation/doc/Documentation/packages.txt index ae1d9c9ab0b..aa061c842d8 100644 --- a/Documentation/doc/Documentation/packages.txt +++ b/Documentation/doc/Documentation/packages.txt @@ -90,6 +90,7 @@ \package_listing{Mesh_2} \package_listing{Surface_mesher} \package_listing{Skin_surface_3} +\package_listing{SMDS_3} \package_listing{Mesh_3} \package_listing{Tetrahedral_remeshing} \package_listing{Periodic_3_mesh_3} diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 74c86d2e2bc..10b9387df06 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -2,6 +2,19 @@ Release History =============== +[Release 5.6](https://github.com/CGAL/cgal/releases/tag/v5.6) +----------- + +Release date: Dec 2022 + +### [3D Simplicial Mesh Data Structure](https://doc.cgal.org/5.6/Manual/packages.html#PkgSMDS3) (new package) + +- This new package wraps all the existing code that deals with a `MeshComplex_3InTriangulation_3` + to describe 3D simplicial meshess, and makes the data structure independent + from the tetrahedral mesh generation package. + + + [Release 5.5](https://github.com/CGAL/cgal/releases/tag/v5.5) ----------- @@ -247,6 +260,7 @@ Release date: January 2022 - Added support for the [OSQP solver](https://osqp.org/). This solver enables to efficiently compute the convex Quadratic Programming (QP) problems arising in the context of several packages. + [Release 5.3](https://github.com/CGAL/cgal/releases/tag/v5.3) ----------- diff --git a/Installation/include/CGAL/SMDS_3/Mesh_complex_3_in_triangulation_3_fwd.h b/Installation/include/CGAL/SMDS_3/Mesh_complex_3_in_triangulation_3_fwd.h new file mode 100644 index 00000000000..9b0c2d1e38e --- /dev/null +++ b/Installation/include/CGAL/SMDS_3/Mesh_complex_3_in_triangulation_3_fwd.h @@ -0,0 +1,53 @@ +// Copyright (C) 2020 GeometryFactory Sarl +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// + +#ifndef CGAL_SMDS_3_MESH_COMPLEX_3_IN_TRIANGULATION_3_FWD_H +#define CGAL_SMDS_3_MESH_COMPLEX_3_IN_TRIANGULATION_3_FWD_H + +/// \file Mesh_complex_3_in_triangulation_3_fwd.h +/// Forward declarations of the SMDS_3 package. + +#ifndef DOXYGEN_RUNNING +namespace CGAL { + +// fwdS for the public interface +template +class Mesh_complex_3_in_triangulation_3; + +namespace IO { + template + void output_to_medit(std::ostream& os, + const C3T3& c3t3, + bool rebind = false, + bool show_patches = false +#ifndef DOXYGEN_RUNNING + , bool all_vertices = true + , bool all_cells = false +#endif + ); +} //namespace IO + +namespace SMDS_3 { + + template + bool build_triangulation_from_file(std::istream& is, + Tr& tr, + bool verbose = false, + bool replace_domain_0 = false, + bool allow_non_manifold = false); + +} // namespace SMDS_3 +} // namespace CGAL +#endif + +#endif /* CGAL_SMDS_3_MESH_COMPLEX_3_IN_TRIANGULATION_3_FWD_H */ + + diff --git a/Installation/include/CGAL/license/SMDS_3.h b/Installation/include/CGAL/license/SMDS_3.h new file mode 100644 index 00000000000..6191918e010 --- /dev/null +++ b/Installation/include/CGAL/license/SMDS_3.h @@ -0,0 +1,54 @@ +// Copyright (c) 2016 GeometryFactory SARL (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Andreas Fabri +// +// Warning: this file is generated, see include/CGAL/licence/README.md + +#ifndef CGAL_LICENSE_SMDS_3_H +#define CGAL_LICENSE_SMDS_3_H + +#include +#include + +#ifdef CGAL_SMDS_3_COMMERCIAL_LICENSE + +# if CGAL_SMDS_3_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE + +# if defined(CGAL_LICENSE_WARNING) + + CGAL_pragma_warning("Your commercial license for CGAL does not cover " + "this release of the 3D Mesh Data Structure package.") +# endif + +# ifdef CGAL_LICENSE_ERROR +# error "Your commercial license for CGAL does not cover this release \ + of the 3D Mesh Data Structure package. \ + You get this error, as you defined CGAL_LICENSE_ERROR." +# endif // CGAL_LICENSE_ERROR + +# endif // CGAL_SMDS_3_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE + +#else // no CGAL_SMDS_3_COMMERCIAL_LICENSE + +# if defined(CGAL_LICENSE_WARNING) + CGAL_pragma_warning("\nThe macro CGAL_SMDS_3_COMMERCIAL_LICENSE is not defined." + "\nYou use the CGAL 3D Simplicial Mesh Data Structure package under " + "the terms of the GPLv3+.") +# endif // CGAL_LICENSE_WARNING + +# ifdef CGAL_LICENSE_ERROR +# error "The macro CGAL_SMDS_3_COMMERCIAL_LICENSE is not defined.\ + You use the CGAL 3D Simplicial Mesh Data Structure package under the terms of \ + the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR." +# endif // CGAL_LICENSE_ERROR + +#endif // no CGAL_SMDS_3_COMMERCIAL_LICENSE + +#endif // CGAL_LICENSE_SMDS_3_H diff --git a/Installation/include/CGAL/license/gpl_package_list.txt b/Installation/include/CGAL/license/gpl_package_list.txt index 28c3cd25f87..f023d48f375 100644 --- a/Installation/include/CGAL/license/gpl_package_list.txt +++ b/Installation/include/CGAL/license/gpl_package_list.txt @@ -91,6 +91,7 @@ Surface_sweep_2 2D Intersection of Curves TDS_2 2D Triangulation Data Structure TDS_3 3D Triangulation Data Structure Three Three +SMDS_3 3D Simplicial Mesh Data Structure Triangulation_2 2D Triangulation Triangulation_on_sphere_2 2D Triangulation on Sphere Triangulation_3 3D Triangulations diff --git a/Mesh_3/doc/Mesh_3/CGAL/Compact_mesh_cell_base_3.h b/Mesh_3/doc/Mesh_3/CGAL/Compact_mesh_cell_base_3.h deleted file mode 100644 index 8e91b271375..00000000000 --- a/Mesh_3/doc/Mesh_3/CGAL/Compact_mesh_cell_base_3.h +++ /dev/null @@ -1,34 +0,0 @@ -namespace CGAL { - -/*! -\ingroup PkgMesh3MeshClasses - -The class `Compact_mesh_cell_base_3` is a model of the concept `MeshCellBase_3`. -It is designed to serve as cell base class for the 3D triangulation -used in the 3D mesh generation process. It is more compact in memory than -`Mesh_cell_base_3`. - -\tparam Gt is the geometric traits class. -It has to be a model of the concept `MeshTriangulationTraits_3`. - -\tparam MD provides the types of indices used to identify -the faces of the input complex. It has to be a model -of the concept `MeshDomain_3`. - -\tparam Tds is the triangulation data structure class to which cells -belong. That parameter is only used by the rebind mechanism (see -`::TriangulationDSCellBase_3::Rebind_TDS`). Users should always use the -default parameter value `void`. - -\cgalModels `MeshCellBase_3` - -\sa `CGAL::Mesh_complex_3_in_triangulation_3` -\sa `CGAL::Mesh_cell_base_3` - -*/ -template< typename Gt, typename MD, typename Tds = void > -class Compact_mesh_cell_base_3 { -public: - -}; /* end Compact_mesh_cell_base_3 */ -} /* end namespace CGAL */ diff --git a/Mesh_3/doc/Mesh_3/CGAL/IO/File_avizo.h b/Mesh_3/doc/Mesh_3/CGAL/IO/File_avizo.h deleted file mode 100644 index f4f679a9eb5..00000000000 --- a/Mesh_3/doc/Mesh_3/CGAL/IO/File_avizo.h +++ /dev/null @@ -1,14 +0,0 @@ -namespace CGAL{ -namespace IO { -/** - * \ingroup PkgMesh3IOFunctions - * @brief outputs mesh to avizo format - * @param os the stream - * @param c3t3 the mesh complex - * \see \ref IOStreamAvizo - */ -template -void -output_to_avizo(std::ostream& os, - const C3T3& c3t3); -}} diff --git a/Mesh_3/doc/Mesh_3/CGAL/IO/File_medit.h b/Mesh_3/doc/Mesh_3/CGAL/IO/File_medit.h deleted file mode 100644 index bdbb7e0d01e..00000000000 --- a/Mesh_3/doc/Mesh_3/CGAL/IO/File_medit.h +++ /dev/null @@ -1,21 +0,0 @@ -namespace CGAL { -namespace IO { -/// \ingroup PkgMesh3IOFunctions -/// -/// \brief outputs a mesh complex to the medit (`.mesh`) file format. -/// See \cgalCite{frey:inria-00069921} for a comprehensive description of this file format. -/// -/// \param os the output stream -/// \param c3t3 the mesh complex -/// \param rebind if set to `true`, labels of cells are rebinded into `[1..nb_of_labels]` -/// \param show_patches if set to `true`, patches are labeled with different labels than -/// cells. If set to `false`, each surface facet is written twice, -/// using the label of each adjacent cell. -/// -template -void output_to_medit(std::ostream& os, - const C3T3& c3t3, - bool rebind = false, - bool show_patches = false); - -}} // end namespace CGAL::IO diff --git a/Mesh_3/doc/Mesh_3/CGAL/IO/File_tetgen.h b/Mesh_3/doc/Mesh_3/CGAL/IO/File_tetgen.h deleted file mode 100644 index 8294618586b..00000000000 --- a/Mesh_3/doc/Mesh_3/CGAL/IO/File_tetgen.h +++ /dev/null @@ -1,20 +0,0 @@ -namespace CGAL{ -namespace IO { -/** - * \ingroup PkgMesh3IOFunctions - * @brief outputs a mesh complex to tetgen format - * @param filename the path to the output file - * @param c3t3 the mesh - * @param rebind if true, labels of cells are rebinded into [1..nb_of_labels] - * @param show_patches if true, patches are labeled with different labels than - * cells. If false, each surface facet is written twice, using label of - * each adjacent cell. - * \see \ref IOStreamTetgen - */ -template -void -output_to_tetgen(std::string filename, - const C3T3& c3t3, - bool rebind = false, - bool show_patches = false); -} } diff --git a/Mesh_3/doc/Mesh_3/CGAL/IO/facets_in_complex_3_to_triangle_mesh.h b/Mesh_3/doc/Mesh_3/CGAL/IO/facets_in_complex_3_to_triangle_mesh.h deleted file mode 100644 index b672d4d3273..00000000000 --- a/Mesh_3/doc/Mesh_3/CGAL/IO/facets_in_complex_3_to_triangle_mesh.h +++ /dev/null @@ -1,16 +0,0 @@ -namespace CGAL { -//! \ingroup PkgMesh3Functions -//! -//! \brief builds a `TriangleMesh` from the surface facets, with a consistent orientation at the interface of two subdomains. -//! -//! This function exports the surface as a `TriangleMesh` and appends it to `graph`, using -//! `orient_polygon_soup()`. -//! -//! @tparam C3T3 a model of `MeshComplexWithFeatures_3InTriangulation_3`. -//! @tparam TriangleMesh a model of `MutableFaceGraph` with an internal point property map. The point type should be compatible with the one used in `C3T3`. -//! -//! @param c3t3 an instance of `C3T3`. -//! @param graph an instance of `TriangleMesh`. -template -void facets_in_complex_3_to_triangle_mesh(const C3T3& c3t3, TriangleMesh& graph); -} diff --git a/Mesh_3/doc/Mesh_3/CGAL/IO/output_to_vtu.h b/Mesh_3/doc/Mesh_3/CGAL/IO/output_to_vtu.h deleted file mode 100644 index e1d9d87e4a9..00000000000 --- a/Mesh_3/doc/Mesh_3/CGAL/IO/output_to_vtu.h +++ /dev/null @@ -1,18 +0,0 @@ -namespace CGAL{ -namespace IO { -//! \ingroup PkgMesh3IOFunctions -//! -//! \brief writes a tetrahedron mesh using the `UnstructuredGrid` XML format. -//! -//! \tparam C3T3 a model of `MeshComplexWithFeatures_3InTriangulation_3`. -//! -//! \param os the stream used for writing. -//! \param c3t3 the instance of `C3T3` to be written. -//! \param mode decides if the data should be written in binary (`IO::BINARY`) -//! or in ASCII (`IO::ASCII`). -//! -template -void output_to_vtu(std::ostream& os, - const C3T3& c3t3, - IO::Mode mode = BINARY); -} } diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_cell_base_3.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_cell_base_3.h deleted file mode 100644 index b20e0426d83..00000000000 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_cell_base_3.h +++ /dev/null @@ -1,40 +0,0 @@ - -namespace CGAL { - - -/*! -\ingroup PkgMesh3MeshClasses - - -The class `Mesh_cell_base_3` is a model of the concept `MeshCellBase_3`. -It is designed to serve as cell base class for the 3D triangulation -used in the 3D mesh generation process. - -\tparam Gt is the geometric traits class. -It has to be a model of the concept `MeshTriangulationTraits_3`. - -\tparam MD provides the types of indices used to identify -the faces of the input complex. It has to be a model -of the concept `MeshDomain_3`. - -\tparam Cb is the cell base class. It has to be a model -of the concept `RegularTriangulationCellBaseWithWeightedCircumcenter_3` and defaults to -`Regular_triangulation_cell_base_with_weighted_circumcenter_3`. - -\cgalModels `MeshCellBase_3` - -\sa `CGAL::Mesh_complex_3_in_triangulation_3` -\sa `CGAL::Compact_mesh_cell_base_3` - -*/ -template< typename Gt, typename MD, typename Cb > -class Mesh_cell_base_3 : public Cb { -public: - -}; /* end Mesh_cell_base_3 */ -} /* end namespace CGAL */ diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_complex_3_in_triangulation_3.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_complex_3_in_triangulation_3.h deleted file mode 100644 index fad13d11a51..00000000000 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_complex_3_in_triangulation_3.h +++ /dev/null @@ -1,119 +0,0 @@ -namespace CGAL { - -/*! -\ingroup PkgMesh3MeshClasses - -The class `Mesh_complex_3_in_triangulation_3` implements a data structure -to store the 3D restricted Delaunay triangulation used by a mesh -generation process. - -This class is a model of the concept -`MeshComplexWithFeatures_3InTriangulation_3`. - - -\tparam Tr can be instantiated with any 3D -regular triangulation of \cgal provided that its -vertex and cell base class are models of the concepts -`MeshVertexBase_3` and `MeshCellBase_3`, respectively. - -\tparam CornerIndex is the type of the indices for corners. It must match the `Corner_index` of the model -of the `MeshDomainWithFeatures_3` concept used for mesh generation. - -\tparam CurveIndex is the type of the indices for curves. -It must match the `Curve_index` types of the model -of the `MeshDomainWithFeatures_3` concept used for mesh generation. - -Those two last template parameters defaults to `int`, so that they can be ignored -if the domain used for mesh generation does not include 0 and 1-dimensionnal features (i.e -is a model of the concept `MeshDomain_3`). - -\cgalModels `MeshComplexWithFeatures_3InTriangulation_3` - -\sa `CGAL::make_mesh_3()` -\sa `CGAL::refine_mesh_3()` -\sa `MeshComplex_3InTriangulation_3` -\sa `MeshComplexWithFeatures_3InTriangulation_3` -\sa `MeshCellBase_3`, -\sa `MeshVertexBase_3` - -*/ -template< typename Tr, typename CornerIndex, typename CurveIndex > -class Mesh_complex_3_in_triangulation_3 { -public: - -/// \name Types -/// @{ - -/*! -%Index type. -*/ -typedef Tr::Vertex::Index Index; - -/*! -Surface index type. -*/ -typedef Tr::Cell::Surface_patch_index Surface_patch_index; - -/*! -Subdomain index type. -*/ -typedef Tr::Cell::Subdomain_index Subdomain_index; - -/*! - Corner index type. -*/ -typedef CornerIndex Corner_index; - -/*! -Curve index type. -*/ -typedef CurveIndex Curve_index; - -/// @} - -/// \name Operations -/// @{ - -/*! - The tetrahedral mesh generation algorithm implemented in `CGAL::make_mesh_3()` - and `CGAL::refine_mesh_3()` does not guarantee that all the points inserted - by the algorithm are actually present in the final mesh. - - In most cases, all points are used, but if the geometry of the object - has small features, compared to the size of the simplices (triangles and tetrahedra), - it might be that the Delaunay facets that are selected in the restricted Delaunay - triangulation miss some vertices of the triangulation. - The concurrent version of the tetrahedral mesh generation algorithm - also inserts a small set of auxiliary vertices that belong to the triangulation - but are isolated from the complex at the end of the meshing process. - - This function removes these so-called \em isolated vertices, that belong to the - triangulation but not to any cell of the `C3T3`, from the triangulation. -*/ -void remove_isolated_vertices(); - -/*! -Outputs the mesh to `os` -in medit format. -*/ -void output_to_medit(std::ofstream& os); - -/** - * Outputs the outer boundary of the entire domain with facets oriented outward. - */ -std::ostream& output_boundary_to_off(std::ostream& out) const; - -/** - * Outputs the outer boundary of the selected subdomain with facets oriented outward. - */ -std::ostream& output_boundary_to_off(std::ostream& out, Subdomain_index subdomain) const; - -/** - * Outputs the surface facets with a consistent orientation at the interface of two subdomains. - */ -std::ostream& output_facets_in_complex_to_off(std::ostream& out) const; - -/// @} - -}; /* end Mesh_complex_3_in_triangulation_3 */ -} /* end namespace CGAL */ diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_vertex_base_3.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_vertex_base_3.h deleted file mode 100644 index b0112fcc53a..00000000000 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_vertex_base_3.h +++ /dev/null @@ -1,32 +0,0 @@ -namespace CGAL { - -/*! -\ingroup PkgMesh3MeshClasses - -The class `Mesh_vertex_base_3` is a model of the concept `MeshVertexBase_3`. -It is designed to serve as vertex base class for the 3D triangulation -used in a 3D mesh generation process. - -\tparam Gt is the geometric traits class. -It must be a model of the concept `MeshTriangulationTraits_3`. - -\tparam MD provides the types of indices -used to identify -the faces of the input complex. It must be a model -of the concept `MeshDomain_3`. - -\tparam Vb is the vertex base class. It has to be a model -of the concept `RegularTriangulationVertexBase_3` and defaults to -`Regular_triangulation_vertex_base_3`. - -\cgalModels `MeshVertexBase_3` - -\sa `CGAL::Mesh_complex_3_in_triangulation_3` - -*/ -template< typename Gt, typename MD, typename Vb > -class Mesh_vertex_base_3 : public Vb { -public: - -}; /* end Mesh_vertex_base_3 */ -} /* end namespace CGAL */ diff --git a/Mesh_3/doc/Mesh_3/CGAL/make_mesh_3.h b/Mesh_3/doc/Mesh_3/CGAL/make_mesh_3.h index 08bd5ee1761..312b556343f 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/make_mesh_3.h +++ b/Mesh_3/doc/Mesh_3/CGAL/make_mesh_3.h @@ -33,7 +33,10 @@ traverse the resulting mesh data structure or can be written to a file \tparam C3T3 is required to be a model of -the concept `MeshComplex_3InTriangulation_3`. This is the return type. +the concept `MeshComplex_3InTriangulation_3`, +and a model of `MeshComplexWithFeatures_3InTriangulation_3` +if the domain is a model of `MeshDomainWithFeatures_3`. +This is the return type. The type `C3T3` is in particular required to provide a nested type `C3T3::Triangulation` for the 3D triangulation embedding the mesh. The vertex and cell base classes of the diff --git a/Mesh_3/doc/Mesh_3/CGAL/refine_mesh_3.h b/Mesh_3/doc/Mesh_3/CGAL/refine_mesh_3.h index 25ddc7311ed..afeebe8c634 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/refine_mesh_3.h +++ b/Mesh_3/doc/Mesh_3/CGAL/refine_mesh_3.h @@ -39,7 +39,9 @@ not change from one refinement to the next one. \tparam C3T3 is required to be a model of the concept -`MeshComplex_3InTriangulation_3`. +`MeshComplex_3InTriangulation_3`, +and a model of `MeshComplexWithFeatures_3InTriangulation_3` +if the domain is a model of `MeshDomainWithFeatures_3`. The argument `c3t3` is passed by reference as this object is modified by the refinement process. As the refinement process only adds points to the triangulation, all diff --git a/Mesh_3/doc/Mesh_3/Concepts/MeshCellBase_3.h b/Mesh_3/doc/Mesh_3/Concepts/MeshCellBase_3.h index d9037a2151b..a6ba2ba7d6f 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/MeshCellBase_3.h +++ b/Mesh_3/doc/Mesh_3/Concepts/MeshCellBase_3.h @@ -5,7 +5,8 @@ The concept `MeshCellBase_3` describes the requirements for the `Cell` type of the triangulation used in the 3D mesh generation process. The type `MeshCellBase_3` -refines the concept `RegularTriangulationCellBaseWithWeightedCircumcenter_3` +refines the concepts `SimplicialMeshCellBase_3` and +`RegularTriangulationCellBaseWithWeightedCircumcenter_3` and must be copy constructible. The concept `MeshCellBase_3` includes a way to store and retrieve @@ -40,6 +41,7 @@ and `is_facet_visited(1)` in parallel must be safe) Moreover, the parallel algorithms require an erase counter in each cell (see below). +\cgalRefines `SimplicialMeshCellBase_3` \cgalRefines `RegularTriangulationCellBaseWithWeightedCircumcenter_3` \cgalRefines `CopyConstructible` @@ -172,9 +174,25 @@ void increment_erase_counter(); /*! \name Internal These functions are used internally by mesh optimizers. The class should provide storage, accessors and modificators for two `Vertex_handle` -and two `Cell_handle`.*/ +and two `Cell_handle`, and a cache value for sliverity.*/ /// @{ +/*! +*/ +void set_sliver_value(double value); + +/*! +*/ +double sliver_value() const; + +/*! +*/ +bool is_cache_valid() const; + +/*! +*/ +void reset_cache_validity() const; + /*! */ diff --git a/Mesh_3/doc/Mesh_3/Concepts/MeshDomain_3.h b/Mesh_3/doc/Mesh_3/Concepts/MeshDomain_3.h index fe2749b913c..240f9b0f1fb 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/MeshDomain_3.h +++ b/Mesh_3/doc/Mesh_3/Concepts/MeshDomain_3.h @@ -124,7 +124,7 @@ following operators: `template`
-`OutputIterator operator()(int n, OutputIterator pts)` +`OutputIterator operator()(OutputIterator pts, int n)` Those two operators output a set of (`n`) surface points to the output iterator `pts`, as objects of type `std::pair` - `CGAL::Mesh_triangulation_3` - `CGAL::Mesh_vertex_base_3` - `CGAL::Compact_mesh_cell_base_3` @@ -114,7 +111,6 @@ and their associated classes: - `CGAL::perturb_mesh_3()` - `CGAL::lloyd_optimize_mesh_3()` - `CGAL::odt_optimize_mesh_3()` -- `CGAL::facets_in_complex_3_to_triangle_mesh()` - `CGAL::Mesh_3::generate_label_weights()` \cgalCRPSection{CGAL::parameters Functions} @@ -137,9 +133,4 @@ and their associated classes: - `CGAL::Mesh_optimization_return_code` - `CGAL::Mesh_facet_topology` - -\cgalCRPSection{Input/Output Functions} -- `CGAL::IO::output_to_medit()` -- `CGAL::IO::output_to_vtu()` */ - diff --git a/Mesh_3/doc/Mesh_3/dependencies b/Mesh_3/doc/Mesh_3/dependencies index 8dc427e241e..be614f85b31 100644 --- a/Mesh_3/doc/Mesh_3/dependencies +++ b/Mesh_3/doc/Mesh_3/dependencies @@ -13,3 +13,5 @@ Polyhedron Miscellany Mesh_2 Polygon_mesh_processing +SMDS_3 + diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp index 40dddc6a1a9..fa7e38b7dca 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp @@ -49,7 +49,8 @@ int main(int argc, char*argv[]) // Output std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp index 3ead928edf7..1c99e0379f1 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp @@ -81,7 +81,8 @@ int main(int argc, char*argv[]) // Output std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp index 8bf9f62710a..a42b1144a0a 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp @@ -97,7 +97,8 @@ int main(int argc, char* argv[]) // Output std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp index d573dde7c96..dbae9919419 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp @@ -54,7 +54,8 @@ int main(int argc, char* argv[]) // Output std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp index 051f07dba4c..c7f205091ba 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp @@ -63,7 +63,8 @@ int main(int argc, char* argv[]) // Output std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index 5b0a8a23196..fcf5d94744d 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp index 3f8a0fe362a..877fa104635 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp @@ -102,7 +102,8 @@ int main(int argc, char* argv[]) // Output std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image.cpp index f6b072b3dcd..0374a315707 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_weighted_image.cpp @@ -59,7 +59,9 @@ int main(int argc, char* argv[]) // Output std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); + std::ofstream bin_file("out.binary.cgal", std::ios_base::binary); CGAL::IO::save_binary_file(bin_file, c3t3); diff --git a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp index 12216cc2cbd..90577147ecb 100644 --- a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp @@ -91,7 +91,8 @@ int main() // Output std::ofstream medit_file("out_cubes_intersection.mesh"); - CGAL::IO::output_to_medit(medit_file, c3t3); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp index 61d2d78d993..fd9f1780c62 100644 --- a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp @@ -178,7 +178,8 @@ int main() // Output std::ofstream medit_file("out_cubes_intersection_with_features.mesh"); - CGAL::IO::output_to_medit(medit_file, c3t3); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp b/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp index c638395342c..c0ba926d412 100644 --- a/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp @@ -13,7 +13,7 @@ #include // Ouput -#include +#include // Read 1D features from input file #include "read_polylines.h" diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp index d8790c25fd3..4d9187f5692 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp @@ -67,7 +67,7 @@ int main() // Output std::ofstream medit_file("out.mesh"); - CGAL::IO::output_to_medit(medit_file, c3t3); + CGAL::IO::write_MEDIT(medit_file, c3t3); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp index 6d50993bbdd..e3ec7922475 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp @@ -69,7 +69,8 @@ int main() // Output std::ofstream medit_file("out.mesh"); - CGAL::IO::output_to_medit(medit_file, c3t3); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp index 9e28374783e..da98a23a98c 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp @@ -55,7 +55,7 @@ int main() // Output std::ofstream medit_file("out_wo.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); medit_file.close(); // Perturbation (5s, 12degree) @@ -66,7 +66,8 @@ int main() // Output medit_file.open("out_optimized.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp index 4521c606724..2e318913c84 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp @@ -52,7 +52,8 @@ int main() // Output std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp index 3eaa7ce389f..61c3952bb68 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp @@ -69,7 +69,8 @@ int main() // Output std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp b/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp index 9f72d6c276a..4d0e36ff5d3 100644 --- a/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp @@ -59,10 +59,12 @@ int main(int argc, char* argv[]) // Output std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); std::ofstream medit_file_bis("out_bis.mesh"); - c3t3_bis.output_to_medit(medit_file_bis); + CGAL::IO::write_MEDIT(medit_file_bis, c3t3_bis); + medit_file_bis.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp b/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp index e4a6e6a5dcb..b4db268fc59 100644 --- a/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp @@ -59,10 +59,12 @@ int main(int argc, char*argv[]) // Output std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); std::ofstream medit_file_bis("out_bis.mesh"); - c3t3_bis.output_to_medit(medit_file_bis); + CGAL::IO::write_MEDIT(medit_file_bis, c3t3_bis); + medit_file_bis.close(); return 0; } diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex.cpp index 134092b3fba..eaee6876dc8 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex.cpp @@ -80,7 +80,8 @@ int main() // Output std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return EXIT_SUCCESS; } diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex_sm.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex_sm.cpp index 789b5737892..bc4b4821dca 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex_sm.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex_sm.cpp @@ -109,7 +109,8 @@ int main() //// Output //std::ofstream medit_file("out.mesh"); - //c3t3.output_to_medit(medit_file); + //CGAL::IO::write_MEDIT(medit_file, c3t3); + //medit_file.close(); return EXIT_SUCCESS; } diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain.cpp index f5cf67e0204..eb24c7ef70a 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain.cpp @@ -8,6 +8,7 @@ #include #include #include +#include // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; @@ -61,7 +62,7 @@ int main(int argc, char*argv[]) // Output std::ofstream medit_file("out_1.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); medit_file.close(); // Set tetrahedron size (keep cell_radius_edge_ratio), ignore facets @@ -72,7 +73,8 @@ int main(int argc, char*argv[]) // Output medit_file.open("out_2.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return EXIT_SUCCESS; } diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_sm.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_sm.cpp index 7cb6dda697d..c7ab9c43a4d 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_sm.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_sm.cpp @@ -61,7 +61,7 @@ int main(int argc, char*argv[]) // Output std::ofstream medit_file("out_1.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); medit_file.close(); // Set tetrahedron size (keep cell_radius_edge_ratio), ignore facets @@ -72,7 +72,8 @@ int main(int argc, char*argv[]) // Output medit_file.open("out_2.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return EXIT_SUCCESS; } diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features.cpp index 75b7e82e6d1..c6b092e5db1 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features.cpp @@ -66,7 +66,7 @@ int main(int argc, char*argv[]) std::ofstream file("out.vtu"); CGAL::IO::output_to_vtu(file, c3t3); // Could be replaced by: - // c3t3.output_to_medit(file); + // CGAL::IO::write_MEDIT(file, c3t3); return EXIT_SUCCESS; } diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features_sm.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features_sm.cpp index 435a205fe34..a05a3aa1669 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features_sm.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_features_sm.cpp @@ -67,7 +67,7 @@ int main(int argc, char*argv[]) std::ofstream file("out-sm.vtu"); CGAL::IO::output_to_vtu(file, c3t3, CGAL::IO::ASCII); // Could be replaced by: - // c3t3.output_to_medit(file); + // CGAL::IO::write_MEDIT(file, c3t3); return EXIT_SUCCESS; } diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_lipschitz_sizing.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_lipschitz_sizing.cpp index 1054a00baeb..d6ab36133bc 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_lipschitz_sizing.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain_with_lipschitz_sizing.cpp @@ -80,7 +80,8 @@ int main(int argc, char*argv[]) // Output std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); + medit_file.close(); return EXIT_SUCCESS; } diff --git a/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp b/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp index bdc5ac62e7a..7458ae88390 100644 --- a/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp @@ -88,7 +88,7 @@ int main() CGAL::parameters::no_features()); std::ofstream medit_file("out-no-protection.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); medit_file.close(); c3t3.clear(); @@ -97,7 +97,7 @@ int main() // Output medit_file.open("out-with-protection.mesh"); - c3t3.output_to_medit(medit_file); + CGAL::IO::write_MEDIT(medit_file, c3t3); medit_file.close(); return 0; diff --git a/Mesh_3/include/CGAL/Compact_mesh_cell_base_3.h b/Mesh_3/include/CGAL/Compact_mesh_cell_base_3.h index bbd0d96de83..0283d6268d8 100644 --- a/Mesh_3/include/CGAL/Compact_mesh_cell_base_3.h +++ b/Mesh_3/include/CGAL/Compact_mesh_cell_base_3.h @@ -16,7 +16,6 @@ #include - #include #include @@ -28,7 +27,7 @@ #include #include -#include +#include #include @@ -709,6 +708,32 @@ public: }; // end class Compact_mesh_cell_3 +/*! +\ingroup PkgMesh3MeshClasses + +The class `Compact_mesh_cell_base_3` is a model of the concept `MeshCellBase_3`. +It is designed to serve as cell base class for the 3D triangulation +used in the 3D mesh generation process. It is more compact in memory than +`Mesh_cell_base_3`. + +\tparam GT is the geometric traits class. +It has to be a model of the concept `MeshTriangulationTraits_3`. + +\tparam MD provides the types of indices used to identify +the faces of the input complex. It has to be a model +of the concept `MeshDomain_3`. + +\tparam TDS is the triangulation data structure class to which cells +belong. That parameter is only used by the rebind mechanism (see +`::TriangulationDSCellBase_3::Rebind_TDS`). Users should always use the +default parameter value `void`. + +\cgalModels `MeshCellBase_3` + +\sa `CGAL::Mesh_complex_3_in_triangulation_3` +\sa `CGAL::Mesh_cell_base_3` + +*/ template< class GT, class MD, class TDS = void > diff --git a/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h b/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h index c093cc52119..5acc5b01507 100644 --- a/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h @@ -33,8 +33,8 @@ #include -#include -#include +#include +#include // support for `CGAL::Image_3` #include diff --git a/Mesh_3/include/CGAL/Mesh_3/Dump_c3t3.h b/Mesh_3/include/CGAL/Mesh_3/Dump_c3t3.h index 5a798e665e0..47f6d237051 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Dump_c3t3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Dump_c3t3.h @@ -13,126 +13,8 @@ #ifndef CGAL_MESH_3_DUMP_C3T3_H #define CGAL_MESH_3_DUMP_C3T3_H -#include +#include -#include - -#include -#include -#include - -#include - -#include -#include - -namespace CGAL { - -template ::value && - is_streamable::value - && - (is_streamable::value || - Output_rep::is_specialized) - && - (is_streamable::value || - Output_rep::is_specialized) - > -struct Dump_c3t3 { - void dump_c3t3(const C3t3& c3t3, std::string prefix) const - { - std::clog<<"======dump c3t3===== to: " << prefix << std::endl; - std::ofstream medit_file((prefix+".mesh").c_str()); - medit_file.precision(17); - CGAL::IO::output_to_medit(medit_file, c3t3, false /*rebind*/, true /*show_patches*/); - medit_file.close(); - - std::string bin_filename = prefix; - bin_filename += ".binary.cgal"; - std::ofstream bin_file(bin_filename.c_str(), - std::ios_base::binary | std::ios_base::out); - std::string signature = CGAL::Get_io_signature()(); - CGAL_assertion(signature != std::string()); - bin_file << "binary CGAL c3t3 " << signature << "\n"; - CGAL::IO::set_binary_mode(bin_file); - bin_file << c3t3; - } -}; // end struct template Dump_c3t3 - -template -struct Dump_c3t3 -{ - void dump_c3t3(const C3t3&, std::string) { - std::cerr << "Warning " << __FILE__ << ":" << __LINE__ << "\n" - << " the c3t3 object of following type:\n" - << typeid(C3t3).name() << std::endl - << " cannot be dumped because some types are not streamable:\n"; - if(!is_streamable::value) { - std::cerr << " - C3t3::Triangulation::Vertex is not streamble\n"; - std::cerr << " " - << typeid(typename C3t3::Triangulation::Vertex).name() - << "\n"; - } - - if(!is_streamable::value) { - std::cerr << " - C3t3::Triangulation::Cell is not streamble\n"; - std::cerr << " " - << typeid(typename C3t3::Triangulation::Cell).name() - << "\n"; - } - - if(!is_streamable::value && - !CGAL::Output_rep::is_specialized) - { - std::cerr << " - C3t3::Surface_patch_index is not streamable\n"; - std::cerr << " " - << typeid(typename C3t3::Surface_patch_index).name() - << "\n"; - } - if(!is_streamable::value && - !CGAL::Output_rep::is_specialized) - { - std::cerr << " - C3t3::Subdomain_index is not streamable\n"; - std::cerr << " " - << typeid(typename C3t3::Subdomain_index).name() - << "\n"; - } - } -}; // end struct template specialization Dump_c3t3 - -template -void dump_c3t3_edges(const C3t3& c3t3, std::string prefix) -{ - typename C3t3::Triangulation::Geom_traits::Construct_point_3 cp = - c3t3.triangulation().geom_traits().construct_point_3_object(); - - std::ofstream file((prefix+".polylines.txt").c_str()); - file.precision(17); - for(typename C3t3::Edges_in_complex_iterator - edge_it = c3t3.edges_in_complex_begin(), - end = c3t3.edges_in_complex_end(); - edge_it != end; ++edge_it) - { - const typename C3t3::Triangulation::Cell_handle c = edge_it->first; - const int i = edge_it->second; - const int j = edge_it->third; - const typename C3t3::Triangulation::Weighted_point& ei = c3t3.triangulation().point(c, i); - const typename C3t3::Triangulation::Weighted_point& ej = c3t3.triangulation().point(c, j); - file << "2 " << cp(ei) << " " << cp(ej) << "\n"; - } -} -template -void dump_c3t3(const C3t3& c3t3, std::string prefix) -{ - if(!prefix.empty()) { - Dump_c3t3 dump; - dump.dump_c3t3(c3t3, prefix); - } -} - -} // end namespace CGAL - -#include +#include #endif // CGAL_MESH_3_DUMP_C3T3_H diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_base.h b/Mesh_3/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_base.h deleted file mode 100644 index 7511346f1f3..00000000000 --- a/Mesh_3/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_base.h +++ /dev/null @@ -1,1161 +0,0 @@ -// Copyright (c) 2003-2009 INRIA Sophia-Antipolis (France). -// Copyright (c) 2013 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Laurent Rineau, Stéphane Tayeb -// -//****************************************************************************** -// File Description : Implements class Mesh_complex_3_in_triangulation_3. -//****************************************************************************** - -#ifndef CGAL_MESH_3_MESH_COMPLEX_3_IN_TRIANGULATION_3_BASE_H -#define CGAL_MESH_3_MESH_COMPLEX_3_IN_TRIANGULATION_3_BASE_H - -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - - -#ifdef CGAL_LINKED_WITH_TBB - #include - #include - -namespace CGAL { - template < class DSC, bool Const > - std::size_t tbb_hasher(const CGAL::internal::CC_iterator& it) - { - return CGAL::internal::hash_value(it); - } - - - // As Marc Glisse pointed out the TBB hash of a std::pair is - // simplistic and leads to the - // TBB Warning: Performance is not optimal because the hash function - // produces bad randomness in lower bits in class - // tbb::interface5::concurrent_hash_map - template < class DSC, bool Const > - std::size_t tbb_hasher(const std::pair, - CGAL::internal::CC_iterator >& p) - { - return boost::hash, - CGAL::internal::CC_iterator > >()(p); - } - - struct Hash_compare_for_TBB { - template < class DSC, bool Const > - std::size_t hash(const std::pair, - CGAL::internal::CC_iterator >& p) const - { - return tbb_hasher(p); - } - template < class DSC, bool Const > - std::size_t operator()(const CGAL::internal::CC_iterator& it) - { - return CGAL::internal::hash_value(it); - } - template - bool equal(const T& v1, const T& v2) const { - return v1 == v2; - } - }; -} -#endif - -namespace CGAL { -namespace Mesh_3 { - - namespace details { - - template - class C3t3_helper_class - { - protected: - typedef typename Tr::Vertex_handle Vertex_handle; - typedef typename Tr::Cell_handle Cell_handle; - typedef typename Tr::Facet Facet; - typedef typename Tr::Edge Edge; - - typedef std::pair Pair_of_vertices; - - // computes and return an ordered pair of Vertex - Pair_of_vertices - make_ordered_pair(const Vertex_handle vh1, const Vertex_handle vh2) const { - if (vh1 < vh2) { - return std::make_pair(vh1, vh2); - } - else { - return std::make_pair(vh2, vh1); - } - } - - // same from an Edge - Pair_of_vertices - make_ordered_pair(const Edge e) const { - return make_ordered_pair(e.first->vertex(e.second), - e.first->vertex(e.third)); - } - - Facet canonical_facet(Cell_handle c, int i) const { - Cell_handle c2 = c->neighbor(i); - return (c2 < c) ? std::make_pair(c2,c2->index(c)) : std::make_pair(c,i); - } - - }; // end class template C3t3_helper_class - - } // end namespace Mesh_3::details - -/** - * @class Mesh_complex_3_in_triangulation_3_base - * @brief A data-structure to represent and maintain a 3D complex embedded - * in a 3D triangulation. - */ -template -class Mesh_complex_3_in_triangulation_3_base - : public details::C3t3_helper_class -{ - typedef Mesh_complex_3_in_triangulation_3_base Self; - typedef details::C3t3_helper_class Base; - -public: - // Triangulation types - typedef Tr Triangulation; - typedef typename Tr::Vertex_handle Vertex_handle; - typedef typename Tr::Cell_handle Cell_handle; - typedef typename Tr::Facet Facet; - typedef typename Tr::Edge Edge; - typedef typename Tr::size_type size_type; - - typedef CGAL::Hash_handles_with_or_without_timestamps Hash_fct; - - // Indices types - typedef typename Tr::Cell::Subdomain_index Subdomain_index; - typedef typename Tr::Cell::Surface_patch_index Surface_patch_index; - typedef typename Tr::Vertex::Index Index; - - enum Face_status{ NOT_IN_COMPLEX = 0, - ISOLATED = 1, // - An ISOLATED edge is a marked edge, - // without any incident facets. - BOUNDARY, // - An edge is on BOUNDARY if it has only - // one incident facet. - // - A vertex is on BOUNDARY if all its - // incident edges are REGULAR or on - // BOUNDARY, at least one is on - // BOUNDARY, and the incident facets - // form only one connected component. - REGULAR, // - A facet that is in the complex is - // REGULAR. - // - An edge is REGULAR if it has - // exactly two incident facets. - // - A vertex is REGULAR if all it - // incident edges are REGULAR, and the - // incident facets form only one - // connected component. - SINGULAR}; // - SINGULAR is for all other cases. - - //------------------------------------------------------- - // Constructors / Destructors - //------------------------------------------------------- - /** - * @brief Constructor - * Builds an empty 3D complex. - */ - Mesh_complex_3_in_triangulation_3_base() - : Base() - , tr_() - , edge_facet_counter_() //TODO: parallel! - , manifold_info_initialized_(false) //TODO: parallel! - { - // We don't put it in the initialization list because - // std::atomic has no contructors - number_of_facets_ = 0; - number_of_cells_ = 0; - } - - /// Copy constructor - Mesh_complex_3_in_triangulation_3_base(const Self& rhs) - : Base() - , tr_(rhs.tr_) - , edge_facet_counter_(rhs.edge_facet_counter_) - , manifold_info_initialized_(rhs.manifold_info_initialized_) - { - Init_number_of_elements init; - init(number_of_facets_, rhs.number_of_facets_); - init(number_of_cells_, rhs.number_of_cells_); - } - - /// Move constructor - Mesh_complex_3_in_triangulation_3_base(Self&& rhs) - : Base() - , tr_(std::move(rhs.tr_)) - , edge_facet_counter_(std::move(rhs.edge_facet_counter_)) - , manifold_info_initialized_(std::exchange(rhs.manifold_info_initialized_, false)) - { - Init_number_of_elements init; - init(number_of_facets_, rhs.number_of_facets_); - init(number_of_cells_, rhs.number_of_cells_); - init(rhs.number_of_facets_); // set to 0 - init(rhs.number_of_cells_); // set to 0 - } - - /// Destructor - ~Mesh_complex_3_in_triangulation_3_base() {} - - void clear() { - number_of_cells_ = 0; - number_of_facets_ = 0; - clear_manifold_info(); - tr_.clear(); - } - - /// Assignment operator - Self& operator=(Self rhs) - { - swap(rhs); - return *this; - } - - /// Assignment operator, also serves as move-assignment - Self& operator=(Self&& rhs) - { - swap(rhs); - return *this; - } - - /// Returns the reference to the triangulation - Triangulation& triangulation() { return tr_; } - /// Returns a const reference to the triangulation - const Triangulation& triangulation() const { return tr_; } - - - /// Adds facet \c facet to the 2D complex, with surface index \c index - void add_to_complex(const Facet& facet, const Surface_patch_index& index) - { - add_to_complex(facet.first, facet.second, index); - } - - /// Adds facet(\c cell, \c i) to the 2D complex, with surface index \c index - void add_to_complex(const Cell_handle& cell, - const int i, - const Surface_patch_index& index); - - /// Removes facet \c facet from 2D complex - void remove_from_complex(const Facet& facet); - - /// Removes facet(\c cell, \c i) from 2D complex - void remove_from_complex(const Cell_handle& c, const int i) { - remove_from_complex(Facet(c, i)); - } - - /// Sets surface index of facet \c facet to \c index - void set_surface_patch_index(const Facet& f, const Surface_patch_index& index) - { - set_surface_patch_index(f.first, f.second, index); - } - - /// Sets surface index of facet(\c cell, \c i) to \c index - void set_surface_patch_index(const Cell_handle& cell, - const int i, - const Surface_patch_index& index) const - { - cell->set_surface_patch_index(i, index); - } - - /// Returns `NOT_IN_COMPLEX`, `BOUNDARY`, `REGULAR`, or `SINGULAR`, - /// depending on the number of incident facets in the complex, and the - /// number of connected components of its link - Face_status face_status(const Vertex_handle v) const - { - if(!manifold_info_initialized_) init_manifold_info(); - const std::size_t n = v->cached_number_of_incident_facets(); - - if(n == 0) return NOT_IN_COMPLEX; - - //test incident edges for REGULARITY and count BOUNDARY edges - typename std::vector edges; - edges.reserve(64); - if(tr_.is_parallel()) { - tr_.incident_edges_threadsafe(v, std::back_inserter(edges)); - } else { - tr_.incident_edges(v, std::back_inserter(edges)); - } - int number_of_boundary_incident_edges = 0; // could be a bool - for (typename std::vector::iterator - eit=edges.begin(), end = edges.end(); - eit != end; eit++) - { - switch( face_status(*eit) ) - { - case NOT_IN_COMPLEX: case REGULAR: break; - case BOUNDARY: ++number_of_boundary_incident_edges; break; - default : -#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS - std::cerr << "singular edge...\n"; - std::cerr << tr_.point(v) << std::endl; -#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS - return SINGULAR; - } - } - - // From here all incident edges (in complex) are REGULAR or BOUNDARY. - const std::size_t nb_components = union_find_of_incident_facets(v); - if(nb_components > 1) { -#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS - std::cerr << "singular vertex: nb_components=" << nb_components << std::endl; - std::cerr << tr_.point(v) << std::endl; -#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS - return SINGULAR; - } - else { // REGULAR OR BOUNDARY -#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS - std::cerr << "regular or boundary: " << tr_.point(v) << std::endl; -#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS - if (number_of_boundary_incident_edges != 0) - return BOUNDARY; - else - return REGULAR; - } - } - - /// This function should be called only when incident edges - /// are known to be REGULAR OR BOUNDARY - bool is_regular_or_boundary_for_vertices(Vertex_handle v) const { - return union_find_of_incident_facets(v) == 1; - } - - /// Returns `NOT_IN_COMPLEX`, `BOUNDARY`, `REGULAR`, or `SINGULAR`, - /// depending on the number of incident facets in the complex - Face_status face_status(const Edge& edge) const - { - if(!manifold_info_initialized_) init_manifold_info(); - -#ifdef CGAL_LINKED_WITH_TBB - typename Edge_facet_counter::const_accessor accessor; - if(!edge_facet_counter_.find(accessor, - this->make_ordered_pair(edge))) - return NOT_IN_COMPLEX; - switch(accessor->second) -#else // not CGAL_LINKED_WITH_TBB - switch(edge_facet_counter_[this->make_ordered_pair(edge)]) -#endif // not CGAL_LINKED_WITH_TBB - { - case 0: return NOT_IN_COMPLEX; - case 1: return BOUNDARY; - case 2: return REGULAR; - default: return SINGULAR; - } - } - - /// Returns true if the vertex \c v has is incident to at least a facet - /// of the complex - bool has_incident_facets_in_complex(const Vertex_handle& v) const - { - if(!manifold_info_initialized_) init_manifold_info(); - return v->cached_number_of_incident_facets() > 0; - } - - /// Returns true if facet \c facet is in complex - bool is_in_complex(const Facet& facet) const - { - return is_in_complex(facet.first, facet.second); - } - - /// Returns true if facet (\c cell, \c i) is in 2D complex - bool is_in_complex(const Cell_handle& cell, const int i) const - { - return ( cell->is_facet_on_surface(i) ); - } - - /// Returns surface index of facet \c f - Surface_patch_index surface_patch_index(const Facet& f) const - { - return surface_patch_index(f.first,f.second); - } - - /// Returns surface index of facet(\c cell, \c i) - Surface_patch_index surface_patch_index(const Cell_handle& cell, - const int i) const - { - return cell->surface_patch_index(i); - } - - /// Returns the number of surface facets of the mesh - size_type number_of_facets_in_complex() const { return number_of_facets_; } - - /// Adds cell \c cell to the 3D complex, with subdomain index \c index - void add_to_complex(const Cell_handle& cell, const Subdomain_index& index) - { - CGAL_precondition( !( index == Subdomain_index() ) ); - - if ( ! is_in_complex(cell) ) - { - set_subdomain_index(cell, index); - ++number_of_cells_; - } - } - - /// Removes cell \c cell from the 3D complex - void remove_from_complex(const Cell_handle& cell) - { - if ( is_in_complex(cell) ) - { - set_subdomain_index(cell, Subdomain_index()); - --number_of_cells_; - } - } - - - /// Sets subdomain index of cell \c cell to \c index - void set_subdomain_index(const Cell_handle& cell, - const Subdomain_index& index) const - { - cell->set_subdomain_index(index); - } - - /// Sets index of vertex \c vertex to \c index - void set_index(const Vertex_handle& vertex, const Index& index) const - { - vertex->set_index(index); - } - - /// Sets dimension of vertex \c vertex to \c dimension - void set_dimension(const Vertex_handle& vertex, int dimension) const - { - vertex->set_dimension(dimension); - } - - /// Returns the number of cells which belongs to the 3D complex - size_type number_of_cells_in_complex() const - { - return number_of_cells_; - } - - /// Returns \c true if cell \c cell belongs to the 3D complex - bool is_in_complex(const Cell_handle& cell) const - { - return !( subdomain_index(cell) == Subdomain_index() ); - } - - /// Returns the subdomain index of cell \c cell - Subdomain_index subdomain_index(const Cell_handle& cell) const - { - return cell->subdomain_index(); - } - - /// Returns the dimension of the lowest dimensional face of the input 3D - /// complex that contains the vertex - int in_dimension(const Vertex_handle& v) const { return v->in_dimension(); } - - /// Returns the index of vertex \c v - Index index(const Vertex_handle& v) const { return v->index(); } - - /// Outputs the mesh to medit - void output_to_medit(std::ostream& os, - bool rebind = true, - bool show_patches = false) const - { - // Call global function - CGAL::IO::output_to_medit(os,*this,rebind,show_patches); - } - - /// Outputs the mesh to maya - void output_to_maya(std::ostream& os, - bool surfaceOnly = true) const - { - // Call global function - CGAL::IO::output_to_maya(os,*this,surfaceOnly); - } - - //------------------------------------------------------- - // Undocumented features - //------------------------------------------------------- - /** - * @brief insert \c [first,last[ in the triangulation (with dimension 2) - * @param first the iterator on the first point to insert - * @param last the iterator past the last point to insert - * - * InputIterator value type must be \c std::pair - */ - template - void insert_surface_points(InputIterator first, InputIterator last) - { - typename Tr::Geom_traits::Construct_weighted_point_3 cwp = - tr_.geom_traits().construct_weighted_point_3_object(); - - while ( first != last ) - { - Vertex_handle vertex = tr_.insert(cwp((*first).first)); - vertex->set_index((*first).second); - vertex->set_dimension(2); - ++first; - } - } - - /** - * @brief insert \c [first,last[ in the triangulation (with dimension 2 and - * index \c default_index) - * @param first the iterator on the first point to insert - * @param last the iterator past the last point to insert - * @param default_index the index to be used to insert points - * - * InputIterator value type must be \c Tr::Point - */ - template - void insert_surface_points(InputIterator first, - InputIterator last, - const Index& default_index) - { - typename Tr::Geom_traits::Construct_weighted_point_3 cwp = - tr_.geom_traits().construct_weighted_point_3_object(); - - while ( first != last ) - { - Vertex_handle vertex = tr_.insert(cwp(*first)); - vertex->set_index(default_index); - vertex->set_dimension(2); - ++first; - } - } - - /// Swaps this & rhs - void swap(Self& rhs) - { - Swap_elements swapper; - swapper(rhs.number_of_facets_, number_of_facets_); - tr_.swap(rhs.tr_); - swapper(rhs.number_of_cells_, number_of_cells_); - } - - /// Returns bbox - Bbox_3 bbox() const; - - void clear_cells_and_facets_from_c3t3() { - for(typename Tr::Finite_cells_iterator - cit = this->triangulation().finite_cells_begin(), - end = this->triangulation().finite_cells_end(); - cit != end; ++cit) - { - set_subdomain_index(cit, Subdomain_index()); - } - this->number_of_cells_ = 0; - for(typename Tr::Finite_facets_iterator - fit = this->triangulation().finite_facets_begin(), - end = this->triangulation().finite_facets_end(); - fit != end; ++fit) - { - Facet facet = *fit; - set_surface_patch_index(facet.first, facet.second, Surface_patch_index()); - if(this->triangulation().dimension() > 2) { - Facet mirror = tr_.mirror_facet(facet); - set_surface_patch_index(mirror.first, mirror.second, Surface_patch_index()); - } - } - this->number_of_facets_ = 0; - clear_manifold_info(); - } - - void clear_manifold_info() { - edge_facet_counter_.clear(); - manifold_info_initialized_ = false; - } - -private: - void init_manifold_info() const { - for(typename Tr::All_vertices_iterator - vit = triangulation().finite_vertices_begin(), - end = triangulation().finite_vertices_end(); - vit != end; ++vit) - { - vit->set_c2t3_cache(0, (std::numeric_limits::max)()); - } - - edge_facet_counter_.clear(); - - for(typename Tr::Finite_facets_iterator - fit = triangulation().finite_facets_begin(), - end = triangulation().finite_facets_end(); - fit != end; ++fit) - { - if ( is_in_complex(*fit) ) { - const Cell_handle cell = fit->first; - const int i = fit->second; - for(int j = 0; j < 3; ++j) - { - const int edge_index_va = tr_.vertex_triple_index(i, j); - const int edge_index_vb = tr_.vertex_triple_index(i, (j == 2) ? 0 : (j+1)); - const Vertex_handle edge_va = cell->vertex(edge_index_va); - const Vertex_handle edge_vb = cell->vertex(edge_index_vb); -#ifndef CGAL_LINKED_WITH_TBB - ++edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)]; -#else // CGAL_LINKED_WITH_TBB - { - typename Edge_facet_counter::accessor accessor; - edge_facet_counter_.insert(accessor, - this->make_ordered_pair(edge_va, edge_vb)); - ++accessor->second; - } -#endif // CGAL_LINKED_WITH_TBB - - const std::size_t n = edge_va->cached_number_of_incident_facets(); - edge_va->set_c2t3_cache(n+1, (std::numeric_limits::max)()); - } - } - } - manifold_info_initialized_ = true; - } - - /// Extract the subset `F` of facets of the complex incident to `v` and - /// return the number of connected component of the adjacency graph of `F`. - std::size_t union_find_of_incident_facets(const Vertex_handle v) const - { - if( v->is_c2t3_cache_valid() ) - { - const std::size_t n = v->cached_number_of_components(); - if(n != (std::numeric_limits::max)()) return n; - } - - Union_find facets; - { // fill the union find - std::vector non_filtered_facets; - if(tr_.is_parallel()) { - tr_.incident_facets_threadsafe(v, std::back_inserter(non_filtered_facets)); - } else { - tr_.incident_facets(v, std::back_inserter(non_filtered_facets)); - } - - for(typename std::vector::iterator - fit = non_filtered_facets.begin(), - end = non_filtered_facets.end(); - fit != end; ++fit) - { - if(is_in_complex(*fit)) facets.push_back(*fit); - } - } - - typedef boost::unordered_map::handle, - Hash_fct> Vertex_set_map; - typedef typename Vertex_set_map::iterator Vertex_set_map_iterator; - - Vertex_set_map vsmap; - - for(typename Union_find::iterator - it = facets.begin(), end = facets.end(); - it != end; ++it) - { - const Cell_handle& ch = (*it).first; - const int& i = (*it).second; - for(int j=0; j < 3; ++j) { - const Vertex_handle w = ch->vertex(tr_.vertex_triple_index(i,j)); - if(w != v){ - Vertex_set_map_iterator vsm_it = vsmap.find(w); - if(vsm_it != vsmap.end()){ - facets.unify_sets(vsm_it->second, it); - } else { - vsmap.insert(std::make_pair(w, it)); - } - } - } - } - const std::size_t nb_components = facets.number_of_sets(); - - const std::size_t n = v->cached_number_of_incident_facets(); - v->set_c2t3_cache(n, nb_components); - return nb_components; - } - - //------------------------------------------------------- - // Traversal - //------------------------------------------------------- -private: - typedef Mesh_3::internal::Iterator_not_in_complex Iterator_not_in_complex; - - class Facet_iterator_not_in_complex - { - const Self* c3t3_; - Surface_patch_index index_; //need by SWIG: should be const Surface_patch_index - public: - Facet_iterator_not_in_complex(){} //need by SWIG - Facet_iterator_not_in_complex(const Self& c3t3, - const Surface_patch_index& index = Surface_patch_index()) - : c3t3_(&c3t3) - , index_(index) { } - - template - bool operator()(Iterator it) const - { - if ( index_ == Surface_patch_index() ) { return ! c3t3_->is_in_complex(*it); } - else { return !( c3t3_->surface_patch_index(*it) == index_ ); } - } - }; - - /** - * @class Cell_not_in_complex - * @brief A class to filter cells which do not belong to the complex - */ - class Cell_not_in_complex - { - const Self* r_self_; - Subdomain_index index_;//needed by SWIG, should be const Subdomain_index - public: - Cell_not_in_complex(){}//needed by SWIG - Cell_not_in_complex(const Self& self, - const Subdomain_index& index = Subdomain_index()) - : r_self_(&self) - , index_(index) { } - - bool operator()(Cell_handle ch) const - { - if ( index_ == Subdomain_index() ) { return !r_self_->is_in_complex(ch); } - else { return !( r_self_->subdomain_index(ch) == index_ ); } - } - }; // end class Cell_not_in_complex - -public: - /// Iterator type to visit the facets of the 2D complex. - typedef Filter_iterator< - typename Triangulation::Finite_facets_iterator, - Facet_iterator_not_in_complex > Facets_in_complex_iterator; - - /// Returns a Facets_in_complex_iterator to the first facet of the 2D complex - Facets_in_complex_iterator facets_in_complex_begin() const - { - return CGAL::filter_iterator(tr_.finite_facets_end(), - Facet_iterator_not_in_complex(*this), - tr_.finite_facets_begin()); - } - - /// Returns a Facets_in_complex_iterator to the first facet of the 2D complex - Facets_in_complex_iterator - facets_in_complex_begin(const Surface_patch_index& index) const - { - return CGAL::filter_iterator(tr_.finite_facets_end(), - Facet_iterator_not_in_complex(*this,index), - tr_.finite_facets_begin()); - } - - /// Returns past-the-end iterator on facet of the 2D complex - Facets_in_complex_iterator facets_in_complex_end(const Surface_patch_index = Surface_patch_index()) const - { - return CGAL::filter_iterator(tr_.finite_facets_end(), - Facet_iterator_not_in_complex(*this)); - } - - /** - * @class Cells_in_complex_iterator - * @brief Iterator type to visit the cells of triangulation belonging - * to the 3D complex - * - * This class is usefull to ensure that Cells_in_complex_iterator is convertible - * to Cell_handle - */ - class Cells_in_complex_iterator : - public Filter_iterator - { - private: - typedef typename Triangulation::Finite_cells_iterator Tr_iterator; - typedef Filter_iterator Base; - typedef Cells_in_complex_iterator Self; - - public: - Cells_in_complex_iterator() : Base() { } - Cells_in_complex_iterator(Base i) : Base(i) { } - - Self& operator++() { Base::operator++(); return *this; } - Self& operator--() { Base::operator--(); return *this; } - Self operator++(int) { Self tmp(*this); ++(*this); return tmp; } - Self operator--(int) { Self tmp(*this); --(*this); return tmp; } - - operator Cell_handle() const { return Cell_handle(this->base()); } - }; // end class Cells_in_complex_iterator - - - /// Returns a \c Cells_in_complex_iterator to the first cell of the 3D complex - Cells_in_complex_iterator cells_in_complex_begin() const - { - return CGAL::filter_iterator(tr_.finite_cells_end(), - Cell_not_in_complex(*this), - tr_.finite_cells_begin()); - } - - /// Returns a \c Cells_in_complex_iterator to the first cell of the 3D complex - Cells_in_complex_iterator - cells_in_complex_begin(const Subdomain_index& index) const - { - return CGAL::filter_iterator(tr_.finite_cells_end(), - Cell_not_in_complex(*this,index), - tr_.finite_cells_begin()); - } - - /// Returns the past-the-end iterator for the cells of the 3D complex - Cells_in_complex_iterator cells_in_complex_end() const - { - return CGAL::filter_iterator(tr_.finite_cells_end(), - Cell_not_in_complex(*this)); - } - - // ----------------------------------- - // Backward Compatibility - // ----------------------------------- -#ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX - typedef Surface_patch_index Surface_index; - - void set_surface_index(const Facet& f, const Surface_index& index) - { set_surface_patch_index(f, index); } - - void set_surface_index(const Cell_handle& c, const int i, const Surface_index& index) - { set_surface_patch_index(c,i,index); } - - Surface_index surface_index(const Facet& f) const - { return surface_patch_index(f); } - - Surface_index surface_index(const Cell_handle& c, const int i) const - { return surface_patch_index(c,i); } -#endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX - -#ifndef CGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS - typedef Facets_in_complex_iterator Facet_iterator; - typedef Cells_in_complex_iterator Cell_iterator; - - Facet_iterator facets_begin() const - { return facets_in_complex_begin(); } - - Facet_iterator facets_end() const - { return facets_in_complex_end(); } - - Cell_iterator cells_begin() const - { return cells_in_complex_begin(); } - - Cell_iterator cells_end() const - { return cells_in_complex_end(); } -#endif // CGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS - // ----------------------------------- - // End backward Compatibility - // ----------------------------------- - - size_type number_of_facets() const - { return number_of_facets_in_complex(); } - - size_type number_of_cells() const - { return number_of_cells_in_complex(); } - -public: - template - friend - std::istream & - operator>> (std::istream& is, - Mesh_complex_3_in_triangulation_3_base &c3t3); - - void rescan_after_load_of_triangulation(); - - static - std::string io_signature() - { - return - Get_io_signature()(); - } -private: - - // Sequential: non-atomic - // "dummy" is here to allow the specialization (see below) - // See http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/285ab1eec49e1cb6 - template - struct Number_of_elements - { - typedef size_type type; - }; - - template - struct Init_number_of_elements - { - template - void operator()(T& a, const T& b) - { - a = b; - } - template - void operator()(T& a) - { - a = 0; - } - }; - - template - struct Swap_elements - { - template - void operator()(T& a, T& b) - { - std::swap(a, b); - } - }; -#ifdef CGAL_LINKED_WITH_TBB - // Parallel: atomic - template - struct Number_of_elements - { - typedef std::atomic type; - }; - - template - struct Init_number_of_elements - { - template - void operator()(T& a, const T& b) - { - a = b.load(); - } - template - void operator()(T& a) - { - a = 0; - } - }; - - template - struct Swap_elements - { - template - void operator()(T& a, T& b) - { - T tmp; - tmp.exchange(a); - a.exchange(b); - b.exchange(tmp); - } - }; -#endif // CGAL_LINKED_WITH_TBB - - // Private date members - Triangulation tr_; - - typedef typename Base::Pair_of_vertices Pair_of_vertices; -#ifdef CGAL_LINKED_WITH_TBB - typedef tbb::concurrent_hash_map Edge_facet_counter; -#else // not CGAL_LINKED_WITH_TBB - typedef std::map Edge_facet_counter; -#endif // not CGAL_LINKED_WITH_TBB - - mutable Edge_facet_counter edge_facet_counter_; - - typename Number_of_elements::type number_of_facets_; - typename Number_of_elements::type number_of_cells_; - - mutable bool manifold_info_initialized_; -}; // end class Mesh_complex_3_in_triangulation_3_base - - -template -void -Mesh_complex_3_in_triangulation_3_base::add_to_complex( - const Cell_handle& cell, - const int i, - const Surface_patch_index& index) -{ - CGAL_precondition( !( index == Surface_patch_index() ) ); - - if ( ! is_in_complex(cell,i) ) - { - Facet mirror = tr_.mirror_facet(std::make_pair(cell,i)); - set_surface_patch_index(cell, i, index); - set_surface_patch_index(mirror.first, mirror.second, index); - ++number_of_facets_; - if(manifold_info_initialized_) { - for(int j = 0; j < 3; ++j) - { - int edge_index_va = tr_.vertex_triple_index(i, j); - int edge_index_vb = tr_.vertex_triple_index(i, (j == 2) ? 0 : (j+1)); - Vertex_handle edge_va = cell->vertex(edge_index_va); - Vertex_handle edge_vb = cell->vertex(edge_index_vb); -#ifdef CGAL_LINKED_WITH_TBB - { - typename Edge_facet_counter::accessor accessor; - edge_facet_counter_.insert(accessor, - this->make_ordered_pair(edge_va, edge_vb)); - ++accessor->second; - } -#else // not CGAL_LINKED_WITH_TBB - ++edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)]; -#endif // not CGAL_LINKED_WITH_TBB - - const std::size_t n = edge_va->cached_number_of_incident_facets(); - const std::size_t m = edge_va->cached_number_of_components(); - edge_va->set_c2t3_cache(n+1, m); - } - const int dimension_plus_1 = tr_.dimension() + 1; - // update c2t3 for vertices of f - for (int j = 0; j < dimension_plus_1; j++) { - if (j != i) { -#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS - if(cell->vertex(j)->is_c2t3_cache_valid()) - std::cerr << "(" << tr_.point(cell, j) << ")->invalidate_c2t3_cache()\n"; -#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS - cell->vertex(j)->invalidate_c2t3_cache(); - } - } - } - } -} - - -template -void -Mesh_complex_3_in_triangulation_3_base::remove_from_complex(const Facet& facet) -{ - if ( is_in_complex(facet) ) - { - Facet mirror = tr_.mirror_facet(facet); - set_surface_patch_index(facet.first, facet.second, Surface_patch_index()); - set_surface_patch_index(mirror.first, mirror.second, Surface_patch_index()); - --number_of_facets_; - if(manifold_info_initialized_) { - const Cell_handle cell = facet.first; - const int i = facet.second; - for(int j = 0; j < 3; ++j) - { - const int edge_index_va = tr_.vertex_triple_index(i, j); - const int edge_index_vb = tr_.vertex_triple_index(i, (j == 2) ? 0 : (j+1)); - const Vertex_handle edge_va = cell->vertex(edge_index_va); - const Vertex_handle edge_vb = cell->vertex(edge_index_vb); -#ifdef CGAL_LINKED_WITH_TBB - { - typename Edge_facet_counter::accessor accessor; - edge_facet_counter_.insert(accessor, - this->make_ordered_pair(edge_va, edge_vb)); - --accessor->second; - } -#else // not CGAL_LINKED_WITH_TBB - --edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)]; -#endif // not CGAL_LINKED_WITH_TBB - - const std::size_t n = edge_va->cached_number_of_incident_facets(); - CGAL_assertion(n>0); - const std::size_t m = edge_va->cached_number_of_components(); - edge_va->set_c2t3_cache(n-1, m); - } - const int dimension_plus_1 = tr_.dimension() + 1; - // update c2t3 for vertices of f - for (int j = 0; j < dimension_plus_1; j++) { - if (j != facet.second) { -#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS - if(cell->vertex(j)->is_c2t3_cache_valid()) - std::cerr << "(" << tr_.point(cell, j) << ")->invalidate_c2t3_cache()\n"; -#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS - cell->vertex(j)->invalidate_c2t3_cache(); - } - } - } - } -} - - -// ----------------------------------- -// Undocumented -// ----------------------------------- -template -Bbox_3 -Mesh_complex_3_in_triangulation_3_base:: -bbox() const -{ - if ( 0 == triangulation().number_of_vertices() ) - { - return Bbox_3(); - } - - typename Tr::Finite_vertices_iterator vit = tr_.finite_vertices_begin(); - Bbox_3 result = tr_.point(vit++).bbox(); - - for(typename Tr::Finite_vertices_iterator end = tr_.finite_vertices_end(); - vit != end ; ++vit) - { - result = result + tr_.point(vit).bbox(); - } - - return result; -} - -template -std::ostream & -operator<< (std::ostream& os, - const Mesh_complex_3_in_triangulation_3_base &c3t3) -{ - return os << c3t3.triangulation(); -} - - -template -std::istream & -operator>> (std::istream& is, - Mesh_complex_3_in_triangulation_3_base &c3t3) -{ - c3t3.clear(); - is >> c3t3.triangulation(); - - if(!is) { - c3t3.clear(); - return is; - } - - c3t3.rescan_after_load_of_triangulation(); - return is; -} - -template -void -Mesh_complex_3_in_triangulation_3_base:: -rescan_after_load_of_triangulation() { - this->number_of_facets_ = 0; - for(typename Tr::Finite_facets_iterator - fit = this->triangulation().finite_facets_begin(), - end = this->triangulation().finite_facets_end(); - fit != end; ++fit) - { - if ( this->is_in_complex(*fit) ) { - ++this->number_of_facets_; - } - } - - this->number_of_cells_ = 0; - for(typename Tr::Finite_cells_iterator - cit = this->triangulation().finite_cells_begin(), - end = this->triangulation().finite_cells_end(); - cit != end; ++cit) - { - if ( this->is_in_complex(cit) ) { - ++this->number_of_cells_; - } - } -} - -} // end namespace Mesh_3 -} // end namespace CGAL - -#include - -#endif // CGAL_MESH_3_MESH_COMPLEX_3_IN_TRIANGULATION_3_BASE_H diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesh_surface_cell_base_3.h b/Mesh_3/include/CGAL/Mesh_3/Mesh_surface_cell_base_3.h index 3e5437c8244..f0db722f898 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Mesh_surface_cell_base_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Mesh_surface_cell_base_3.h @@ -18,13 +18,13 @@ #ifndef CGAL_MESH_3_MESH_SURFACE_CELL_BASE_3_H #define CGAL_MESH_3_MESH_SURFACE_CELL_BASE_3_H -#include +#include #include #include -#include +#include #ifdef CGAL_LINKED_WITH_TBB # include diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h index 2ba606c5de3..1a13e725a44 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h @@ -36,7 +36,7 @@ #include -#include +#include #include #include diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index e7877ab6635..767240429c2 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -28,11 +28,11 @@ #include #include -#include +#include #ifdef CGAL_MESH_3_DUMP_FEATURES_PROTECTION_ITERATIONS # include #endif -#include +#include #include #include #include @@ -108,7 +108,7 @@ void debug_dump_c3t3(const std::string filename, const C3t3& c3t3) template class Protect_edges_sizing_field - : public CGAL::Mesh_3::internal::Debug_messages_tools + : public CGAL::SMDS_3::internal::Debug_messages_tools { typedef Protect_edges_sizing_field Self; diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h index eef04d11b70..2f0db096e09 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h @@ -38,7 +38,7 @@ #ifdef CGAL_MESH_3_PROFILING #include #endif -#include +#include #include diff --git a/Mesh_3/include/CGAL/Mesh_3/config.h b/Mesh_3/include/CGAL/Mesh_3/config.h index ccb05647ef5..6fc06788902 100644 --- a/Mesh_3/include/CGAL/Mesh_3/config.h +++ b/Mesh_3/include/CGAL/Mesh_3/config.h @@ -12,21 +12,20 @@ #ifndef CGAL_MESH_3_CONFIG_H #define CGAL_MESH_3_CONFIG_H 1 -#include - +#include #include //#define CGAL_MESH_3_VERBOSE 1 // Use optimisations of Mesh_3 -# define CGAL_INTRUSIVE_LIST 1 # define CGAL_CONSTRUCT_INTRUSIVE_LIST_RANGE_CONSTRUCTOR 1 # define CGAL_MESH_3_NEW_GET_FACETS 1 # define CGAL_MESH_3_GET_FACETS_USING_INTRUSIVE_LIST 1 # define CGAL_MESH_3_SIZING_FIELD_INEXACT_LOCATE 1 # define FORCE_STRUCTURAL_FILTERING 1 # define CGAL_NEW_INCIDENT_SLIVERS 1 +# define CGAL_INTRUSIVE_LIST 1 //experimental # define CGAL_FASTER_BUILD_QUEUE 1 diff --git a/Mesh_3/include/CGAL/Mesh_3/internal/check_weights.h b/Mesh_3/include/CGAL/Mesh_3/internal/check_weights.h index 2b8a505d725..4d228953ad5 100644 --- a/Mesh_3/include/CGAL/Mesh_3/internal/check_weights.h +++ b/Mesh_3/include/CGAL/Mesh_3/internal/check_weights.h @@ -22,7 +22,7 @@ #include #include -#include +#include #include namespace CGAL { diff --git a/Mesh_3/include/CGAL/Mesh_3/io_signature.h b/Mesh_3/include/CGAL/Mesh_3/io_signature.h index 2c0f02ab3b0..5b43ac9c69b 100644 --- a/Mesh_3/include/CGAL/Mesh_3/io_signature.h +++ b/Mesh_3/include/CGAL/Mesh_3/io_signature.h @@ -13,351 +13,8 @@ #ifndef CGAL_MESH_3_IO_SIGNATURE_H #define CGAL_MESH_3_IO_SIGNATURE_H -#include - -#define CGAL_MESH_3_IO_H // the old include macro, tested by other files - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CGAL_PERIODIC_3_MESH_3_CONFIG_H -#include -#include -#endif - -#include -#include -#include - -namespace CGAL { - -// SFINAE test -template -class has_io_signature -{ -private: - template struct helper; - template static char check(helper<&V::io_signature> *); - template static char (&check(...))[2]; - -public: - enum { value = (sizeof(check(0)) == sizeof(char)) }; -}; - -template -struct Get_io_signature_aux -{ - std::string operator() () const - { - return T::io_signature(); - } -}; // end struct template Get_io_signature_aux - -template -struct Get_io_signature_aux -{ - std::string operator()() const - { - std::cerr << "Type without signature: " << typeid(T).name() << std::endl; - return std::string(); - } -}; // end template partial specialization Get_io_signature_aux - - -template -struct Get_io_signature - : public Get_io_signature_aux< - T, - (has_io_signature::value || - has_io_signature::value || - has_io_signature::value ) // signature for - // static mem func - > -{ -}; - -template <> -struct Get_io_signature -{ - std::string operator()() { - return "i"; - } -}; - -template <> -struct Get_io_signature -{ - std::string operator()() { - return "ui"; - } -}; - -template <> -struct Get_io_signature -{ - std::string operator()() { - return "c"; - } -}; - -template <> -struct Get_io_signature -{ - std::string operator()() { - return "uc"; - } -}; - -template <> -struct Get_io_signature -{ - std::string operator()() { - return "sc"; - } -}; - -template <> -struct Get_io_signature -{ - std::string operator()() { - return "s"; - } -}; - -template <> -struct Get_io_signature -{ - std::string operator()() { - return "us"; - } -}; - -template <> -struct Get_io_signature -{ - std::string operator()() { - return "d"; - } -}; - -template -struct Get_io_signature > -{ - std::string operator()() { - return std::string("boost::variant<") + - Get_io_signature()() + "," + - Get_io_signature()() + ">"; - } -}; - -template -struct Get_io_signature > -{ - std::string operator()() { - return std::string("std::pair<") + - Get_io_signature()() + "," + - Get_io_signature()() + ">"; - } -}; - -template -struct Get_io_signature > -{ - std::string operator()() { - return std::string("std::pair<") + - Get_io_signature()() + "," + - Get_io_signature()() + ">"; - } -}; - -template -struct Get_io_signature > -{ - std::string operator()() { - return std::string("boost::variant<") + - Get_io_signature()() + "," + - Get_io_signature()() + "," + - Get_io_signature()() + ">"; - } -}; - -template -struct Get_io_signature > -{ - std::string operator()() { - return std::string("boost::variant<") + - Get_io_signature()() + "," + - Get_io_signature()() + "," + - Get_io_signature()() + "," + - Get_io_signature()() + ">"; - } -}; - -template -struct Get_io_signature > -{ - std::string operator()() { - return "Point_3"; - } -}; - -template -struct Get_io_signature > -{ - std::string operator()() { - return std::string("Weighted_point<") + Get_io_signature >()() + ">"; - } -}; - -#ifdef CGAL_TRIANGULATION_3_H -template -struct -Get_io_signature > -{ - std::string operator()() { - return std::string("Triangulation_3(") + - Get_io_signature()() + - ",Vb(" + Get_io_signature()() + - "),Cb(" + Get_io_signature()() + - "))"; - } -}; -#endif - -#ifdef CGAL_DELAUNAY_TRIANGULATION_3_H -template -struct -Get_io_signature > -{ - std::string operator()() { - return Get_io_signature >()(); - } -}; -#endif - -#ifdef CGAL_REGULAR_TRIANGULATION_3_H -template -struct -Get_io_signature > -{ - std::string operator()() { - return Get_io_signature >()(); - } -}; -#endif - -#ifdef CGAL_PERIODIC_3_TRIANGULATION_3_H -template -struct -Get_io_signature > -{ - std::string operator()() { - return std::string("Periodic_3_triangulation_3(") + - Get_io_signature()() + - ",Vb(" + Get_io_signature()() + - "),Cb(" + Get_io_signature()() + - "))"; - } -}; -#endif - -#ifdef CGAL_PERIODIC_3_REGULAR_TRIANGULATION_3_H -template -struct -Get_io_signature > -{ - std::string operator()() { - return Get_io_signature >()(); - } -}; -#endif - -#ifdef CGAL_TRIANGULATION_VERTEX_BASE_3_H -template -struct Get_io_signature > -{ - std::string operator()() { - return "Tvb_3"; - } -}; -#endif - -#ifdef CGAL_REGULAR_TRIANGULATION_VERTEX_BASE_3_H -template -struct Get_io_signature > -{ - // identical to Triangulation_vertex_base_3 - std::string operator()() { - return "Tvb_3"; - } -}; -#endif - -#ifdef CGAL_TRIANGULATION_VERTEX_BASE_WITH_INFO_3_H -template -struct -Get_io_signature > -{ - std::string operator()() { - return Get_io_signature()(); - } -}; -#endif - -#ifdef CGAL_TRIANGULATION_CELL_BASE_3_H -template -struct -Get_io_signature > -{ - std::string operator()() { - return "Tcb_3"; - } -}; -#endif - -#ifdef CGAL_TRIANGULATION_CELL_BASE_WITH_INFO_3_H -template -struct -Get_io_signature > -{ - std::string operator()() { - return Get_io_signature()(); - } -}; -#endif - -#ifdef CGAL_REGULAR_TRIANGULATION_CELL_BASE_3_H -template -struct -Get_io_signature > -{ - std::string operator()() { - return "RTcb_3"; - } -}; -#endif - -#ifdef CGAL_REGULAR_TRIANGULATION_CELL_BASE_WITH_CIRCUMCENTER_3_H -template -struct -Get_io_signature > -{ - std::string operator()() { - return "RTWWCcb_3"; - } -}; -#endif - -} // end namespace CGAL +#include +#include #endif // CGAL_MESH_3_IO_SIGNATURE_H diff --git a/Mesh_3/include/CGAL/Mesh_cell_base_3.h b/Mesh_3/include/CGAL/Mesh_cell_base_3.h index b620a78f86d..787124c3ec7 100644 --- a/Mesh_3/include/CGAL/Mesh_cell_base_3.h +++ b/Mesh_3/include/CGAL/Mesh_cell_base_3.h @@ -15,7 +15,7 @@ #ifndef CGAL_MESH_CELL_BASE_3_H #define CGAL_MESH_CELL_BASE_3_H -#include +#include // #define CGAL_DEPRECATED_HEADER "" @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include @@ -95,14 +95,46 @@ protected: // Class Mesh_cell_base_3 // Cell base class used in 3D meshing process. // Adds information to Cb about the cell of the input complex containing it +/*! +\ingroup PkgMesh3MeshClasses + + +The class `Mesh_cell_base_3` is a model of the concept `MeshCellBase_3`. +It is designed to serve as cell base class for the 3D triangulation +used in the 3D mesh generation process. + +\tparam GT is the geometric traits class. +It has to be a model of the concept `MeshTriangulationTraits_3`. + +\tparam MD provides the types of indices used to identify +the faces of the input complex. It has to be a model +of the concept `MeshDomain_3`. + +\tparam Cb is the cell base class. It has to be a model +of the concept `RegularTriangulationCellBaseWithWeightedCircumcenter_3` and defaults to +`Regular_triangulation_cell_base_with_weighted_circumcenter_3`. + +\cgalModels `MeshCellBase_3` + +\sa `CGAL::Mesh_complex_3_in_triangulation_3` +\sa `CGAL::Compact_mesh_cell_base_3` + +*/ template< class GT, class MD, class Cb= CGAL::Regular_triangulation_cell_base_with_weighted_circumcenter_3< GT, CGAL::Regular_triangulation_cell_base_3 > > class Mesh_cell_base_3 -: public Mesh_3::Mesh_surface_cell_base_3, - public Mesh_cell_base_3_base< +: public Mesh_3::Mesh_surface_cell_base_3 +#ifndef DOXYGEN_RUNNING +, public Mesh_cell_base_3_base< typename Mesh_3::Mesh_surface_cell_base_3::Tds::Concurrency_tag> +#endif { typedef typename GT::FT FT; diff --git a/Mesh_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h b/Mesh_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h deleted file mode 100644 index b887a6b6223..00000000000 --- a/Mesh_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h +++ /dev/null @@ -1,857 +0,0 @@ -// Copyright (c) 2009-2014 INRIA Sophia-Antipolis (France). -// Copyright (c) 2010-2013 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Stephane Tayeb, Clement Jamin -// -//****************************************************************************** -// File Description : -//****************************************************************************** - -#ifndef CGAL_MESH_COMPLEX_3_IN_TRIANGULATION_3_H -#define CGAL_MESH_COMPLEX_3_IN_TRIANGULATION_3_H - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace CGAL { - - -template -class Mesh_complex_3_in_triangulation_3 : - public Mesh_3::Mesh_complex_3_in_triangulation_3_base< - Tr, typename Tr::Concurrency_tag> - , public CGAL::Mesh_3::internal::Debug_messages_tools -{ -public: - typedef typename Tr::Concurrency_tag Concurrency_tag; - -private: - typedef Mesh_complex_3_in_triangulation_3< - Tr,CornerIndex,CurveIndex> Self; - typedef Mesh_3::Mesh_complex_3_in_triangulation_3_base< - Tr,Concurrency_tag> Base; - -public: - typedef typename Base::size_type size_type; - - typedef typename Tr::Point Point; - typedef typename Base::Edge Edge; - typedef typename Base::Facet Facet; - typedef typename Base::Vertex_handle Vertex_handle; - typedef typename Base::Cell_handle Cell_handle; - typedef CornerIndex Corner_index; - typedef CurveIndex Curve_index; - - typedef CGAL::Hash_handles_with_or_without_timestamps Hash_fct; - -#ifndef CGAL_NO_DEPRECATED_CODE - typedef CurveIndex Curve_segment_index; -#endif - - typedef typename Base::Triangulation Triangulation; - typedef typename Base::Subdomain_index Subdomain_index; - - using Base::surface_patch_index; - -private: - // Type to store the edges: - // - a set of std::pair (ordered at insertion) - // - which allows fast lookup from one Vertex_handle - // - each element of the set has an associated info (Curve_index) value - typedef boost::bimaps::bimap< - boost::bimaps::multiset_of, - boost::bimaps::multiset_of, - boost::bimaps::set_of_relation<>, - boost::bimaps::with_info > Edge_map; - - typedef typename Edge_map::value_type Internal_edge; - - // Type to store the corners - typedef boost::unordered_map Corner_map; - - // Type to store far vertices - typedef std::vector Far_vertices_vec; - -public: - /** - * Constructor - */ - Mesh_complex_3_in_triangulation_3() = default; - - /** - * Copy constructor - */ - Mesh_complex_3_in_triangulation_3(const Self& rhs); - - /** - * Move constructor - */ - Mesh_complex_3_in_triangulation_3(Self&& rhs) - : Base(std::move(rhs)) - , edges_(std::move(rhs.edges_)) - , corners_(std::move(rhs.corners_)) - , far_vertices_(std::move(rhs.far_vertices_)) - {} - - /** - * Assignement operator, also serves as move-assignement - */ - Self& operator=(Self rhs) - { - swap(rhs); - return *this; - } - - /** - * Swaps this & rhs - */ - void swap(Self& rhs) - { - Base::swap(rhs); - edges_.swap(rhs.edges_); - corners_.swap(rhs.corners_); - far_vertices_.swap(rhs.far_vertices_); - } - - /** - * Clears data of c3t3 - */ - void clear() - { - Base::clear(); - edges_.clear(); - corners_.clear(); - far_vertices_.clear(); - } - - /// Import Base functions - using Base::is_in_complex; - using Base::add_to_complex; - using Base::remove_from_complex; - using Base::triangulation; - using Base::set_surface_patch_index; - - - - /** - * Add edge e to complex, with Curve_index index - */ - void add_to_complex(const Edge& e, - const Curve_index& index) - { - add_to_complex(e.first->vertex(e.second), - e.first->vertex(e.third), - index); - } - - /** - * Add edge (v1,v2) to complex, with Curve_index index - */ - void add_to_complex(const Vertex_handle& v1, - const Vertex_handle& v2, - const Curve_index& index) - { - add_to_complex(make_internal_edge(v1,v2), index); - } - - /** - * Mark vertex \c v as a corner of the complex - */ - void add_to_complex(const Vertex_handle& v, const Corner_index& index) - { - v->set_dimension(0); - corners_.insert(std::make_pair(v,index)); - } - - /** - * Remove edge \c e from complex - */ - void remove_from_complex(const Edge& e) - { - remove_from_complex(e.first->vertex(e.second), e.first->vertex(e.third)); - } - - /** - * Remove edge (v1,v2) from complex - */ - void remove_from_complex(const Vertex_handle& v1, const Vertex_handle& v2) - { - remove_from_complex(make_internal_edge(v1,v2)); - } - - /** - * Remove vertex \c v from complex - */ - void remove_from_complex(const Vertex_handle& v) - { - corners_.erase(v); - v->set_dimension(-1); - } - - std::size_t number_of_far_points() const - { - return far_vertices_.size(); - } - - void add_far_point(const Point &p) - { - far_vertices_.push_back(triangulation().insert(p)); - } - - void add_far_point(Vertex_handle vh) - { - far_vertices_.push_back(vh); - } - - void remove_isolated_vertex(Vertex_handle v) - { - Triangulation& tr = triangulation(); - - std::vector new_cells; - new_cells.reserve(32); - tr.remove_and_give_new_cells(v, std::back_inserter(new_cells)); - - typename std::vector::iterator nc_it = new_cells.begin(); - typename std::vector::iterator nc_it_end = new_cells.end(); - for (; nc_it != nc_it_end; ++nc_it) - { - Cell_handle c = *nc_it; - for (int i = 0; i < 4; ++i) - { - Facet mirror_facet = tr.mirror_facet(std::make_pair(c, i)); - if (is_in_complex(mirror_facet)) - { - set_surface_patch_index(c, i, - surface_patch_index(mirror_facet)); - c->set_facet_surface_center(i, - mirror_facet.first->get_facet_surface_center(mirror_facet.second)); - } - } - /*int i_inf; - if (c->has_vertex(tr.infinite_vertex(), i_inf)) - { - Facet mirror_facet = tr.mirror_facet(std::make_pair(c, i_inf)); - if (is_in_complex(mirror_facet)) - { - set_surface_patch_index(c, i_inf, - surface_patch_index(mirror_facet)); - } - }*/ - } - } - - void remove_far_points() - { - //triangulation().remove(far_vertices_.begin(), far_vertices_.end()); - typename Far_vertices_vec::const_iterator it = far_vertices_.begin(); - typename Far_vertices_vec::const_iterator it_end = far_vertices_.end(); - for ( ; it != it_end ; ++it) - { - remove_isolated_vertex(*it); - } - far_vertices_.clear(); - } - - void remove_isolated_vertices() - { - Triangulation& tr = triangulation(); - for (Vertex_handle v : tr.finite_vertex_handles()) - v->set_meshing_info(0); - - for (typename Base::Cells_in_complex_iterator c = this->cells_in_complex_begin(); - c != this->cells_in_complex_end(); - ++c) - { - for (int i = 0; i < 4; ++i) - { - Vertex_handle vi = c->vertex(i); - vi->set_meshing_info(vi->meshing_info() + 1); - } - } - - for (typename Base::Facets_in_complex_iterator fit = this->facets_in_complex_begin(); - fit != this->facets_in_complex_end(); - ++fit) - { - Facet f = *fit; - for (int i = 1; i < 4; ++i) - { - Vertex_handle vi = f.first->vertex((f.second + i) % 4); - vi->set_meshing_info(vi->meshing_info() + 1); - } - } - - std::vector isolated; - for (Vertex_handle v : tr.finite_vertex_handles()) - { - if (v->meshing_info() == 0.) - isolated.push_back(v); - } - -#ifdef CGAL_MESH_3_VERBOSE - std::cout << "Remove " << isolated.size() << " isolated vertices..."; - std::cout.flush(); -#endif - - CGAL_assertion(far_vertices_.size() <= isolated.size()); - far_vertices_.clear(); - - for (Vertex_handle v : isolated) - remove_isolated_vertex(v); - -#ifdef CGAL_MESH_3_VERBOSE - std::cout << "\nRemove " << isolated.size() << " isolated vertices done." << std::endl; -#endif - } - - /** - * Returns the number of edges of c3t3 - */ - size_type number_of_edges_in_complex() const - { - return edges_.size(); - } - size_type number_of_edges() const - { - return edges_.size(); - } - - /** - * Returns the number of corners of c3t3 - */ - size_type number_of_vertices_in_complex() const - { - return corners_.size(); - } - size_type number_of_corners() const - { - return corners_.size(); - } - - void rescan_after_load_of_triangulation(); - - /** - * Returns true if edge \c e is in complex - */ - bool is_in_complex(const Edge& e) const - { - return is_in_complex(e.first->vertex(e.second), e.first->vertex(e.third)); - } - - /** - * Returns true if edge (v1,v2) is in C3T3 - */ - bool is_in_complex(const Vertex_handle& v1, const Vertex_handle& v2) const - { - return is_in_complex(make_internal_edge(v1,v2)); - } - - /** - * Returns true if \c v is a 0-dimensionnal feature in the c3t3 - */ - bool is_in_complex(const Vertex_handle& v) const - { - return (corners_.find(v) != corners_.end()); - } - - /** - * Returns Curve_index of edge \c e - */ - Curve_index curve_index(const Edge& e) const - { - return curve_index(e.first->vertex(e.second), - e.first->vertex(e.third)); - } - - Curve_index curve_index(const Vertex_handle& v1, - const Vertex_handle& v2) const - { - return curve_index(make_internal_edge(v1,v2)); - } - -#ifndef CGAL_NO_DEPRECATED_CODE - CGAL_DEPRECATED - Curve_index curve_segment_index(const Edge& e) const - { - return curve_index(e); - } - - CGAL_DEPRECATED - Curve_index curve_segment_index(const Vertex_handle& v1, - const Vertex_handle& v2) const - { - return curve_index(v1, v2); - } -#endif // CGAL_NO_DEPRECATED_CODE - - /** - * Returns Corner_index of vertex \c v - */ - Corner_index corner_index(const Vertex_handle& v) const - { - typename Corner_map::const_iterator it = corners_.find(v); - if ( corners_.end() != it ) { return it->second; } - return Corner_index(); - } - - /** - * Outputs the outer boundary of the entire domain with facets oriented outward. - */ - std::ostream& output_boundary_to_off(std::ostream& out) const - { - internal::output_boundary_of_c3t3_to_off(*this, 0, out, false); - return out; - } - - /** - * Outputs the outer boundary of the selected subdomain with facets oriented outward. - */ - std::ostream& output_boundary_to_off(std::ostream& out, Subdomain_index subdomain) const - { - output_boundary_of_c3t3_to_off(*this, subdomain, out); - return out; - } - - /** - * Outputs the surface facets with a consistent orientation at the interface of two subdomains. - */ - std::ostream& output_facets_in_complex_to_off(std::ostream& out) const - { - internal::output_facets_in_complex_to_off(*this, out); - return out; - } - - /** - * Fills \c out with incident edges (1-dimensional features of \c v. - * OutputIterator value type is std::pair - * \pre v->in_dimension() < 2 - */ - template - OutputIterator - adjacent_vertices_in_complex(const Vertex_handle& v, OutputIterator out) const; - - // ----------------------------------- - // Undocumented - // ----------------------------------- - - /** - * Returns true if c3t3 is valid - */ - bool is_valid(bool verbose = false) const; - - // ----------------------------------- - // Complex traversal - // ----------------------------------- -private: - class Edge_iterator_not_in_complex - { - const Self& c3t3_; - const Curve_index index_; - public: - Edge_iterator_not_in_complex(const Self& c3t3, - const Curve_index& index = Curve_index()) - : c3t3_(c3t3) - , index_(index) { } - - template - bool operator()(Iterator it) const - { - if ( index_ == Curve_index() ) { return ! c3t3_.is_in_complex(*it); } - else { return c3t3_.curve_index(*it) != index_; } - } - }; - - class Vertex_iterator_not_in_complex - { - const Self& c3t3_; - const Corner_index index_; - public: - Vertex_iterator_not_in_complex(const Self& c3t3, - const Corner_index& index = Corner_index()) - : c3t3_(c3t3) - , index_(index) { } - - template - bool operator()(const ItMap it) const - { - if ( index_ == Corner_index() ) { return false; } - else { return it->second != index_; } - } - }; - - // Filtered iterator - typedef Filter_iterator< - typename Corner_map::const_iterator, - Vertex_iterator_not_in_complex > Vertex_map_filter_iterator; - - // Iterator type to get the first element of pair - typedef boost::transform_iterator < - Mesh_3::internal::First_of, - Vertex_map_filter_iterator > Vertex_map_iterator_first; - - // Iterator type to remove a level of referencing - class Vertex_map_iterator_first_dereference - : public boost::iterator_adaptor < - Vertex_map_iterator_first_dereference, - Vertex_map_iterator_first, - typename Vertex_map_iterator_first::value_type::value_type, - boost::use_default, - typename Vertex_map_iterator_first::value_type::reference > - { - typedef Vertex_map_iterator_first_dereference Self; - typedef boost::iterator_adaptor < - Vertex_map_iterator_first_dereference, - Vertex_map_iterator_first, - typename Vertex_map_iterator_first::value_type::value_type, - boost::use_default, - typename Vertex_map_iterator_first::value_type::reference > iterator_adaptor_; - public: - typedef typename Vertex_map_iterator_first::reference pointer; - typedef typename iterator_adaptor_::reference reference; - - Vertex_map_iterator_first_dereference() : Self::iterator_adaptor_() { } - - template < typename Iterator > - Vertex_map_iterator_first_dereference(Iterator i) - : Self::iterator_adaptor_(typename Self::iterator_adaptor_::base_type(i)) - { } - - pointer operator->() const { return *(this->base()); } - reference operator*() const { return **(this->base()); } - - operator Vertex_handle() { return Vertex_handle(*(this->base())); } - }; - -public: - /// Iterator type to visit the edges of the 1D complex. - typedef Filter_iterator< - typename Triangulation::Finite_edges_iterator, - Edge_iterator_not_in_complex > Edges_in_complex_iterator; - - /// Returns a Facets_in_complex_iterator to the first facet of the 1D complex - Edges_in_complex_iterator edges_in_complex_begin() const - { - return CGAL::filter_iterator(this->triangulation().finite_edges_end(), - Edge_iterator_not_in_complex(*this), - this->triangulation().finite_edges_begin()); - } - - /// Returns a Facets_in_complex_iterator to the first facet of the 1D complex - Edges_in_complex_iterator - edges_in_complex_begin(const Curve_index& index) const - { - return CGAL::filter_iterator(this->triangulation().finite_edges_end(), - Edge_iterator_not_in_complex(*this,index), - this->triangulation().finite_edges_begin()); - } - - /// Returns past-the-end iterator on facet of the 1D complex - Edges_in_complex_iterator edges_in_complex_end(const Curve_index& = Curve_index()) const - { - return CGAL::filter_iterator(this->triangulation().finite_edges_end(), - Edge_iterator_not_in_complex(*this)); - } - - /// Iterator type to visit the edges of the 0D complex. - typedef Vertex_map_iterator_first_dereference Vertices_in_complex_iterator; - - /// Returns a Vertices_in_complex_iterator to the first vertex of the 0D complex - Vertices_in_complex_iterator vertices_in_complex_begin() const - { - return CGAL::filter_iterator(corners_.end(), - Vertex_iterator_not_in_complex(*this), - corners_.begin()); - } - - /// Returns a Vertices_in_complex_iterator to the first vertex of the 0D complex - Vertices_in_complex_iterator - vertices_in_complex_begin(const Corner_index& index) const - { - return CGAL::filter_iterator(corners_.end(), - Vertex_iterator_not_in_complex(*this,index), - corners_.begin()); - } - - /// Returns past-the-end iterator on facet of the 0D complex - Vertices_in_complex_iterator vertices_in_complex_end() const - { - return CGAL::filter_iterator(corners_.end(), - Vertex_iterator_not_in_complex(*this)); - } - - -private: - /** - * Creates an Internal_edge object (i.e a pair of ordered Vertex_handle) - */ - Internal_edge make_internal_edge(const Vertex_handle& v1, - const Vertex_handle& v2) const - { - if ( v1 < v2 ) { return Internal_edge(v1,v2); } - else { return Internal_edge(v2,v1); } - } - - /** - * Returns true if \c edge is in C3T3 - */ - bool is_in_complex(const Internal_edge& edge) const - { - return (curve_index(edge) != Curve_index() ); - } - - /** - * Add edge \c edge to complex, with Curve_index index - */ - void add_to_complex(const Internal_edge& edge, const Curve_index& index) - { - CGAL_precondition(!is_in_complex(edge)); -#if CGAL_MESH_3_PROTECTION_DEBUG & 1 - std::cerr << "Add edge ( " << disp_vert(edge.left) - << " , " << disp_vert(edge.right) << " ), curve_index=" << index - << " to c3t3.\n"; -#endif // CGAL_MESH_3_PROTECTION_DEBUG - std::pair it = edges_.insert(edge); - it.first->info = index; - } - - /** - * Remove edge \c edge from complex - */ - void remove_from_complex(const Internal_edge& edge) - { - edges_.erase(edge); - } - - /** - * Returns Curve_index of edge \c edge - */ - Curve_index curve_index(const Internal_edge& edge) const - { - typename Edge_map::const_iterator it = edges_.find(edge); - if ( edges_.end() != it ) { return it->info; } - return Curve_index(); - } - -private: - Edge_map edges_; - Corner_map corners_; - Far_vertices_vec far_vertices_; -}; - - -template -Mesh_complex_3_in_triangulation_3:: -Mesh_complex_3_in_triangulation_3(const Self& rhs) - : Base(rhs) - , edges_() - , corners_() -{ - // Copy edges - for ( typename Edge_map::const_iterator it = rhs.edges_.begin(), - end = rhs.edges_.end() ; it != end ; ++it ) - { - const Vertex_handle& va = it->right; - const Vertex_handle& vb = it->left; - - Vertex_handle new_va; - this->triangulation().is_vertex(rhs.triangulation().point(va), new_va); - - Vertex_handle new_vb; - this->triangulation().is_vertex(rhs.triangulation().point(vb), new_vb); - - this->add_to_complex(make_internal_edge(new_va,new_vb), it->info); - } - - // Copy corners - for ( typename Corner_map::const_iterator it = rhs.corners_.begin(), - end = rhs.corners_.end() ; it != end ; ++it ) - { - Vertex_handle new_v; - this->triangulation().is_vertex(rhs.triangulation().point(it->first), new_v); - this->add_to_complex(new_v, it->second); - } - - // Parse vertices to identify far vertices - if (rhs.far_vertices_.size() > 0) - { - Triangulation &tr = triangulation(); - typename Tr::Finite_vertices_iterator vit = tr.finite_vertices_begin(); - for(typename Tr::Finite_vertices_iterator end = tr.finite_vertices_end(); - vit != end ; ++vit) - { - if (vit->in_dimension() == -1) - far_vertices_.push_back(vit); - } - CGAL_assertion(far_vertices_.size() == rhs.far_vertices_.size()); - } -} - - -template -template -OutputIterator -Mesh_complex_3_in_triangulation_3:: -adjacent_vertices_in_complex(const Vertex_handle& v, OutputIterator out) const -{ - CGAL_precondition(v->in_dimension() < 2); - - typedef typename Edge_map::right_const_iterator Rcit; - typedef typename Edge_map::left_const_iterator Lcit; - - // Add edges containing v is on the left - std::pair range_right = edges_.right.equal_range(v); - for ( Rcit rit = range_right.first ; rit != range_right.second ; ++rit ) - { - *out++ = std::make_pair(rit->second, rit->info); - } - - // Add edges containing v on the right - std::pair range_left = edges_.left.equal_range(v); - for ( Lcit lit = range_left.first ; lit != range_left.second ; ++lit ) - { - *out++ = std::make_pair(lit->second, lit->info); - } - - return out; -} - - -template -bool -Mesh_complex_3_in_triangulation_3:: -is_valid(bool verbose) const -{ - typedef typename Tr::Weighted_point Weighted_point; - typedef boost::unordered_map Vertex_map; - - Vertex_map vertex_map; - - // Fill map counting neighbor number for each vertex of an edge - for ( typename Edge_map::const_iterator it = edges_.begin(), - end = edges_.end() ; it != end ; ++it ) - { - const Vertex_handle& v1 = it->right; - if ( vertex_map.find(v1) == vertex_map.end() ) { vertex_map[v1] = 1; } - else { vertex_map[v1] += 1; } - - const Vertex_handle& v2 = it->left; - if ( vertex_map.find(v2) == vertex_map.end() ) { vertex_map[v2] = 1; } - else { vertex_map[v2] += 1; } - } - - // Verify that each vertex has 2 neighbors if it's not a corner - for ( typename Vertex_map::iterator vit = vertex_map.begin(), - vend = vertex_map.end() ; vit != vend ; ++vit ) - { - if ( vit->first->in_dimension() != 0 && vit->second != 2 ) - { - if(verbose) - std::cerr << "Validity error: vertex " << (void*)(&*vit->first) - << " (" << this->triangulation().point(vit->first) << ") " - << "is not a corner (dimension " << vit->first->in_dimension() - << ") but has " << vit->second << " neighbor(s)!\n"; - return false; - } - } - - // Verify that balls of each edge intersect - for ( typename Edge_map::const_iterator it = edges_.begin(), - end = edges_.end() ; it != end ; ++it ) - { - typename Tr::Geom_traits::Compute_weight_3 cw = - this->triangulation().geom_traits().compute_weight_3_object(); - typename Tr::Geom_traits::Construct_point_3 cp = - this->triangulation().geom_traits().construct_point_3_object(); - typename Tr::Geom_traits::Construct_sphere_3 sphere = - this->triangulation().geom_traits().construct_sphere_3_object(); - typename Tr::Geom_traits::Do_intersect_3 do_intersect = - this->triangulation().geom_traits().do_intersect_3_object(); - - const Weighted_point& itrwp = this->triangulation().point(it->right); - const Weighted_point& itlwp = this->triangulation().point(it->left); - - if ( ! do_intersect(sphere(cp(itrwp), cw(itrwp)), sphere(cp(itlwp), cw(itlwp))) ) - { - std::cerr << "Points p[" << disp_vert(it->right) << "], dim=" << it->right->in_dimension() - << " and q[" << disp_vert(it->left) << "], dim=" << it->left->in_dimension() - << " form an edge but do not intersect !\n"; - return false; - } - } - - return true; -} - -template -void -Mesh_complex_3_in_triangulation_3:: -rescan_after_load_of_triangulation() { - corners_.clear(); - for(typename Tr::Finite_vertices_iterator - vit = this->triangulation().finite_vertices_begin(), - end = this->triangulation().finite_vertices_end(); - vit != end; ++vit) - { - if ( vit->in_dimension() == 0 ) { - add_to_complex(vit, Corner_index(1)); - } - } - Base::rescan_after_load_of_triangulation(); -} - -template -std::ostream & -operator<< (std::ostream& os, - const Mesh_complex_3_in_triangulation_3 &c3t3) -{ - // TODO: implement edge saving - typedef typename Mesh_complex_3_in_triangulation_3::Concurrency_tag Concurrency_tag; - return os << static_cast< - const Mesh_3::Mesh_complex_3_in_triangulation_3_base&>(c3t3); -} - - -template -std::istream & -operator>> (std::istream& is, - Mesh_complex_3_in_triangulation_3 &c3t3) -{ - // TODO: implement edge loading - typedef typename Mesh_complex_3_in_triangulation_3::Concurrency_tag Concurrency_tag; - is >> static_cast< - Mesh_3::Mesh_complex_3_in_triangulation_3_base&>(c3t3); - c3t3.rescan_after_load_of_triangulation(); - return is; -} - -} //namespace CGAL - -#include - -#endif // CGAL_MESH_COMPLEX_3_IN_TRIANGULATION_3_H diff --git a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h index 67006e8bbea..e9a58de83d5 100644 --- a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h +++ b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/Mesh_3/include/CGAL/Mesh_triangulation_3.h b/Mesh_3/include/CGAL/Mesh_triangulation_3.h index 68e168b6e00..8d8012806c7 100644 --- a/Mesh_3/include/CGAL/Mesh_triangulation_3.h +++ b/Mesh_3/include/CGAL/Mesh_triangulation_3.h @@ -28,7 +28,7 @@ #include #include -#include +#include namespace CGAL { diff --git a/Mesh_3/include/CGAL/Mesh_vertex_base_3.h b/Mesh_3/include/CGAL/Mesh_vertex_base_3.h index c7e79141f73..3ab58a03384 100644 --- a/Mesh_3/include/CGAL/Mesh_vertex_base_3.h +++ b/Mesh_3/include/CGAL/Mesh_vertex_base_3.h @@ -20,12 +20,12 @@ #ifndef CGAL_COMPACT_MESH_VERTEX_BASE_3_H #define CGAL_COMPACT_MESH_VERTEX_BASE_3_H -#include +#include #include -#include -#include +#include +#include #include #include #include @@ -289,6 +289,30 @@ public: } }; // end class Mesh_vertex_3 + +/*! +\ingroup PkgMesh3MeshClasses + +The class `Mesh_vertex_base_3` is a model of the concept `MeshVertexBase_3`. +It is designed to serve as vertex base class for the 3D triangulation +used in a 3D mesh generation process. + +\tparam GT is the geometric traits class. +It must be a model of the concept `MeshTriangulationTraits_3`. + +\tparam MD provides the types of indices +used to identify +the faces of the input complex. It must be a model +of the concept `MeshDomain_3`. + +\tparam Vb is the vertex base class. It has to be a model +of the concept `RegularTriangulationVertexBase_3` and defaults to +`Regular_triangulation_vertex_base_3`. + +\cgalModels `MeshVertexBase_3` + +\sa `CGAL::Mesh_complex_3_in_triangulation_3` +*/ template > diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h index 91c5e57e7e3..96743cc70e3 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h @@ -59,9 +59,9 @@ // To handle I/O for Surface_patch_index if that is a pair of `int` (the // default) -#include +#include -#include +#include namespace CGAL { diff --git a/Mesh_3/include/CGAL/facets_in_complex_3_to_triangle_mesh.h b/Mesh_3/include/CGAL/facets_in_complex_3_to_triangle_mesh.h deleted file mode 100644 index 1262ef6f74a..00000000000 --- a/Mesh_3/include/CGAL/facets_in_complex_3_to_triangle_mesh.h +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright (c) 2009-2017 GeometryFactory (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Maxime Gimeno, -// Mael Rouxel-Labbé - -#ifndef CGAL_FACETS_IN_COMPLEX_3_TO_TRIANGLE_MESH_H -#define CGAL_FACETS_IN_COMPLEX_3_TO_TRIANGLE_MESH_H - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -namespace CGAL { - -namespace Mesh_3 { - -namespace internal { - -template -void resize(Polygon& p, std::size_t size) -{ - p.resize(size); -} - -template -void resize(std::array&, std::size_t CGAL_assertion_code(size)) -{ - CGAL_assertion(size == N); -} - -template -void facets_in_complex_3_to_triangle_soup(const C3T3& c3t3, - const typename C3T3::Subdomain_index sd_index, - PointContainer& points, - FaceContainer& faces, - const bool normals_point_outside_of_the_subdomain = true, - const bool export_all_facets = false) -{ - typedef typename PointContainer::value_type Point_3; - typedef typename FaceContainer::value_type Face; - - typedef typename C3T3::Triangulation Tr; - - typedef typename Tr::Cell_handle Cell_handle; - typedef typename Tr::Weighted_point Weighted_point; - - typedef typename C3T3::Facets_in_complex_iterator Ficit; - - typedef std::unordered_map PIM; - - typedef typename C3T3::size_type size_type; - - // triangulation point to range point - CGAL::Cartesian_converter::type, - typename CGAL::Kernel_traits::type> t2r; - - size_type nf = c3t3.number_of_facets_in_complex(); - faces.reserve(faces.size() + nf); - points.reserve(points.size() + nf/2); // approximating Euler - - PIM p_to_ids; - std::size_t inum = 0; - - for(Ficit fit = c3t3.facets_in_complex_begin(), - end = c3t3.facets_in_complex_end(); fit != end; ++fit) - { - Cell_handle c = fit->first; - int s = fit->second; - Face f; - resize(f, 3); - - typename C3T3::Subdomain_index cell_sdi = c3t3.subdomain_index(c); - typename C3T3::Subdomain_index opp_sdi = c3t3.subdomain_index(c->neighbor(s)); - - if(!export_all_facets && cell_sdi != sd_index && opp_sdi != sd_index) - continue; - - for(std::size_t i=1; i<4; ++i) - { - CGAL_assertion_code(typedef typename Tr::Vertex_handle Vertex_handle;) - CGAL_assertion_code(Vertex_handle v = c->vertex((s+i)&3);) - CGAL_assertion(v != Vertex_handle() && !c3t3.triangulation().is_infinite(v)); - - const Weighted_point& wp = c3t3.triangulation().point(c, (s+i)&3); - const Point_3& bp = t2r(c3t3.triangulation().geom_traits().construct_point_3_object()(wp)); - - auto insertion_res = p_to_ids.emplace(bp, inum); - if(insertion_res.second) // new point - { - points.push_back(bp); - ++inum; - } - - f[i-1] = insertion_res.first->second; - } - - if(export_all_facets) - { - if((cell_sdi > opp_sdi) == (s%2 == 1)) - std::swap(f[0], f[1]); - } - else - { - if(((cell_sdi == sd_index) == (s%2 == 1)) == normals_point_outside_of_the_subdomain) - std::swap(f[0], f[1]); - } - - faces.push_back(f); - } -} - -template -void facets_in_complex_3_to_triangle_soup(const C3T3& c3t3, - PointContainer& points, - FaceContainer& faces) -{ - typedef typename C3T3::Subdomain_index Subdomain_index; - Subdomain_index useless = Subdomain_index(); - facets_in_complex_3_to_triangle_soup(c3t3, useless, points, faces, - true/*point outward*/, true /*extract all facets*/); -} - -} // end namespace internal - -} // end namespace Mesh_3 - -//! \ingroup PkgMesh3Functions -//! -//! \brief builds a `TriangleMesh` from the surface facets, with a consistent orientation -//! at the interface of two subdomains. -//! -//! This function exports the surface as a `TriangleMesh` and appends it to `graph`, using -//! `orient_polygon_soup()`. -//! -//! @tparam C3T3 a model of `MeshComplexWithFeatures_3InTriangulation_3`. -//! @tparam TriangleMesh a model of `MutableFaceGraph` with an internal point property map. -//! The point type should be compatible with the one used in `C3T3`. -//! -//! @param c3t3 an instance of `C3T3`. -//! @param graph an instance of `TriangleMesh`. -template -void facets_in_complex_3_to_triangle_mesh(const C3T3& c3t3, TriangleMesh& graph) -{ - namespace PMP = CGAL::Polygon_mesh_processing; - - typedef typename boost::property_map::type VertexPointMap; - typedef typename boost::property_traits::value_type Point_3; - - typedef std::array Face; - - std::vector faces; - std::vector points; - - Mesh_3::internal::facets_in_complex_3_to_triangle_soup(c3t3, points, faces); - - if(!PMP::is_polygon_soup_a_polygon_mesh(faces)) - PMP::orient_polygon_soup(points, faces); - CGAL_postcondition(PMP::is_polygon_soup_a_polygon_mesh(faces)); - - PMP::polygon_soup_to_polygon_mesh(points, faces, graph); -} - -} // namespace CGAL - -#endif // CGAL_FACETS_IN_COMPLEX_3_TO_TRIANGLE_MESH_H diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index a75e120da69..39acb952459 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/Mesh_3/include/CGAL/refine_mesh_3.h b/Mesh_3/include/CGAL/refine_mesh_3.h index 0c1e550f41e..bfa15f78f06 100644 --- a/Mesh_3/include/CGAL/refine_mesh_3.h +++ b/Mesh_3/include/CGAL/refine_mesh_3.h @@ -24,10 +24,10 @@ #include #include #include -#include #include #include #include +#include #include diff --git a/Mesh_3/package_info/Mesh_3/dependencies b/Mesh_3/package_info/Mesh_3/dependencies index e616acd30b8..65eec56b360 100644 --- a/Mesh_3/package_info/Mesh_3/dependencies +++ b/Mesh_3/package_info/Mesh_3/dependencies @@ -31,6 +31,7 @@ Principal_component_analysis_LGPL Profiling_tools Property_map Random_numbers +SMDS_3 STL_Extension Solver_interface Spatial_searching diff --git a/Mesh_3/test/Mesh_3/CMakeLists.txt b/Mesh_3/test/Mesh_3/CMakeLists.txt index 40643d7538c..3f91ea357bd 100644 --- a/Mesh_3/test/Mesh_3/CMakeLists.txt +++ b/Mesh_3/test/Mesh_3/CMakeLists.txt @@ -23,16 +23,12 @@ if ( CGAL_FOUND ) endif() create_single_source_cgal_program( "test_boost_has_xxx.cpp" ) - create_single_source_cgal_program( "test_c3t3.cpp" ) create_single_source_cgal_program( "test_mesh_capsule_var_distance_bound.cpp" ) create_single_source_cgal_program( "test_implicit_multi_domain_to_labeling_function_wrapper.cpp" ) - create_single_source_cgal_program( "test_c3t3_io.cpp" ) - create_single_source_cgal_program( "test_c3t3_with_features.cpp" ) create_single_source_cgal_program( "test_criteria.cpp" ) create_single_source_cgal_program( "test_domain_with_polyline_features.cpp" ) create_single_source_cgal_program( "test_labeled_mesh_domain_3.cpp" ) create_single_source_cgal_program( "test_mesh_criteria_creation.cpp" ) - create_single_source_cgal_program( "test_c3t3_into_facegraph.cpp" ) create_single_source_cgal_program( "test_without_detect_features.cpp" ) if(CGAL_ImageIO_USE_ZLIB) create_single_source_cgal_program( "test_meshing_3D_image.cpp" ) @@ -52,7 +48,6 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "test_meshing_unit_tetrahedron.cpp" ) create_single_source_cgal_program( "test_meshing_with_default_edge_size.cpp" ) create_single_source_cgal_program( "test_meshing_determinism.cpp" ) - create_single_source_cgal_program( "test_c3t3_extract_subdomains_boundaries.cpp" ) create_single_source_cgal_program( "test_mesh_3_issue_1554.cpp" ) create_single_source_cgal_program( "test_mesh_polyhedral_domain_with_features_deprecated.cpp" ) create_single_source_cgal_program( "test_meshing_with_one_step.cpp" ) @@ -60,16 +55,12 @@ if ( CGAL_FOUND ) foreach(target test_boost_has_xxx - test_c3t3 test_mesh_capsule_var_distance_bound test_implicit_multi_domain_to_labeling_function_wrapper - test_c3t3_io - test_c3t3_with_features test_criteria test_domain_with_polyline_features test_labeled_mesh_domain_3 test_mesh_criteria_creation - test_c3t3_into_facegraph test_without_detect_features test_meshing_3D_image test_meshing_3D_image_deprecated @@ -85,7 +76,6 @@ if ( CGAL_FOUND ) test_meshing_unit_tetrahedron test_meshing_with_default_edge_size test_meshing_determinism - test_c3t3_extract_subdomains_boundaries test_mesh_3_issue_1554 test_mesh_polyhedral_domain_with_features_deprecated test_mesh_cell_base_3 diff --git a/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp b/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp index 68de83c5e41..03b91d15d8c 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp @@ -60,9 +60,10 @@ int main() // Mesh generation C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria); - // Output - std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); +// // Output +// std::ofstream medit_file("out.mesh"); +// CGAL::IO::write_MEDIT(medit_file, c3t3); +// medit_file.close(); return 0; } diff --git a/Mesh_3/test/Mesh_3/test_mesh_cell_base_3.cpp b/Mesh_3/test/Mesh_3/test_mesh_cell_base_3.cpp index d4b01ec740a..8e3e650625c 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_cell_base_3.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_cell_base_3.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include @@ -49,7 +49,7 @@ int main (int argc, char** argv){ return 1; } C3t3 c3t3; - if(CGAL::build_triangulation_from_file(in, c3t3.triangulation())) + if(CGAL::SMDS_3::build_triangulation_from_file(in, c3t3.triangulation())) { for( C3t3::Triangulation::Finite_cells_iterator cit = c3t3.triangulation().finite_cells_begin(); diff --git a/Mesh_3/test/Mesh_3/test_mesh_polyhedral_domain_with_features_deprecated.cpp b/Mesh_3/test/Mesh_3/test_mesh_polyhedral_domain_with_features_deprecated.cpp index 6642e03693c..9827a5f2b68 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_polyhedral_domain_with_features_deprecated.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_polyhedral_domain_with_features_deprecated.cpp @@ -44,7 +44,10 @@ int main() // Mesh generation C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria); - // Output - std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); +// // Output +// std::ofstream medit_file("out.mesh"); +// CGAL::IO::write_MEDIT(medit_file, c3t3); +// medit_file.close(); + + return EXIT_SUCCESS; } diff --git a/Mesh_3/test/Mesh_3/test_meshing_determinism.cpp b/Mesh_3/test/Mesh_3/test_meshing_determinism.cpp index d359509388f..ef92a338025 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_determinism.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_determinism.cpp @@ -76,7 +76,7 @@ void test() no_perturb(), no_exude()); std::ostringstream oss; - c3t3.output_to_medit(oss); + CGAL::IO::write_MEDIT(oss, c3t3); output_c3t3.push_back(oss.str()); //[5*i] oss.clear(); Polyhedron out_poly; @@ -88,7 +88,7 @@ void test() //LLOYD (1) CGAL::lloyd_optimize_mesh_3(c3t3, domain, max_iteration_number = nb_lloyd); - c3t3.output_to_medit(oss); + CGAL::IO::write_MEDIT(oss, c3t3); output_c3t3.push_back(oss.str());//[i*5+1] oss.clear(); CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); @@ -99,7 +99,7 @@ void test() //ODT (2) CGAL::odt_optimize_mesh_3(c3t3, domain, max_iteration_number = nb_odt); - c3t3.output_to_medit(oss); + CGAL::IO::write_MEDIT(oss, c3t3); output_c3t3.push_back(oss.str());//[i*5+2] oss.clear(); CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); @@ -110,7 +110,7 @@ void test() //PERTURB (3) CGAL::perturb_mesh_3(c3t3, domain, sliver_bound=perturb_bound); - c3t3.output_to_medit(oss); + CGAL::IO::write_MEDIT(oss, c3t3); output_c3t3.push_back(oss.str());//[i*5+3] oss.clear(); CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); @@ -121,7 +121,7 @@ void test() //EXUDE (4) CGAL::exude_mesh_3(c3t3, sliver_bound=exude_bound); - c3t3.output_to_medit(oss); + CGAL::IO::write_MEDIT(oss, c3t3); output_c3t3.push_back(oss.str());//[i*5+4] oss.clear(); CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly); diff --git a/Mesh_3/test/Mesh_3/test_meshing_polyhedron.cpp b/Mesh_3/test/Mesh_3/test_meshing_polyhedron.cpp index b758086448e..3f8b51cf7c4 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_polyhedron.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_polyhedron.cpp @@ -15,14 +15,14 @@ // File Description : //****************************************************************************** -#include +#include #include "test_meshing_utilities.h" #include #include #include -#include +#include #include diff --git a/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp b/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp index 9babdd1a160..5cfdd17ca79 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp @@ -136,7 +136,7 @@ struct Polyhedron_with_features_tester : public Tester Polyhedral_tag()); //, 1099, 1099, 1158, 1158, 4902, 4902); std::ofstream out_medit("test-medit.mesh"); - CGAL::IO::output_to_medit(out_medit, c3t3); + CGAL::IO::write_MEDIT(out_medit, c3t3); CGAL::IO::output_to_tetgen("test-tetgen", c3t3); std::ofstream out_binary("test-binary.mesh.cgal", std::ios_base::out|std::ios_base::binary); diff --git a/Mesh_3/test/Mesh_3/test_meshing_polylines_only.cpp b/Mesh_3/test/Mesh_3/test_meshing_polylines_only.cpp index a8ad7dfc6a9..8dd7e0cbcb3 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_polylines_only.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_polylines_only.cpp @@ -89,11 +89,12 @@ int main(int argc, char** argv) // CGAL::Mesh_3::internal::init_c3t3_with_features(c3t3, domain, criteria); - // Output - std::ofstream medit_file("out-mesh-polylines.mesh"); - c3t3.output_to_medit(medit_file); - std::ofstream binary_file("out-mesh-polylines.binary.cgal", std::ios::binary|std::ios::out); - CGAL::IO::save_binary_file(binary_file, c3t3); +// // Output +// std::ofstream medit_file("out-mesh-polylines.mesh"); +// CGAL::IO::write_MEDIT(medit_file, c3t3); +// std::ofstream binary_file("out-mesh-polylines.binary.cgal", std::ios::binary|std::ios::out); +// CGAL::IO::save_binary_file(binary_file, c3t3); + std::cout << "Number of vertices in c3t3: " << c3t3.triangulation().number_of_vertices() << std::endl; assert(c3t3.triangulation().number_of_vertices() > 900); diff --git a/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp b/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp index 85989f0e485..5781f445050 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_unit_tetrahedron.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include diff --git a/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp b/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp index aa0ace6255a..19199d8e08f 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp @@ -72,9 +72,10 @@ int main(int argc, char*argv[]) assert(c3t3.triangulation().number_of_vertices() > 200); // Output mesher.display_number_of_bad_elements(); - std::ofstream medit_file("out.mesh"); - c3t3.output_to_medit(medit_file); - medit_file.close(); + +// std::ofstream medit_file("out.mesh"); +// CGAL::IO::write_MEDIT(medit_file, c3t3); +// medit_file.close(); return EXIT_SUCCESS; } diff --git a/Mesh_3/test/Mesh_3/test_without_detect_features.cpp b/Mesh_3/test/Mesh_3/test_without_detect_features.cpp index 92fb2129ff3..2e5c76606d1 100644 --- a/Mesh_3/test/Mesh_3/test_without_detect_features.cpp +++ b/Mesh_3/test/Mesh_3/test_without_detect_features.cpp @@ -22,7 +22,7 @@ struct Tester { // Criteria typedef CGAL::Mesh_criteria_3 Mesh_criteria; - int operator()(const std::string fname, const std::string out_fname) + int operator()(const std::string fname, const std::string /*out_fname*/) { std::ifstream input(fname); using namespace CGAL::parameters; @@ -52,9 +52,10 @@ struct Tester { // Mesh generation C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria); - // Output - std::ofstream medit_file(out_fname); - c3t3.output_to_medit(medit_file); +// // Output +// std::ofstream medit_file(out_fname); +// CGAL::IO::write_MEDIT(medit_file, c3t3); + return EXIT_SUCCESS; } }; diff --git a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/IO/File_medit.h b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/IO/File_medit.h index dda69561ff2..260f521d03b 100644 --- a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/IO/File_medit.h +++ b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/IO/File_medit.h @@ -308,7 +308,7 @@ void output_to_medit(std::ostream& os, #endif CGAL_precondition(c3t3.triangulation().is_1_cover()); - typedef CGAL::Mesh_3::Medit_pmap_generator Generator; + typedef CGAL::SMDS_3::Medit_pmap_generator Generator; typedef typename Generator::Cell_pmap Cell_pmap; typedef typename Generator::Facet_pmap Facet_pmap; typedef typename Generator::Facet_pmap_twice Facet_pmap_twice; diff --git a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h index 5be36b550e6..9c4d91afea9 100644 --- a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h +++ b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h @@ -31,12 +31,12 @@ #include -#include +#include #ifdef CGAL_MESH_3_DUMP_FEATURES_PROTECTION_ITERATIONS #include #endif #include -#include +#include #include #include @@ -75,7 +75,7 @@ namespace Periodic_3_mesh_3 { template class Protect_edges_sizing_field - : public CGAL::Mesh_3::internal::Debug_messages_tools + : public CGAL::SMDS_3::internal::Debug_messages_tools { typedef Protect_edges_sizing_field Self; diff --git a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_triangulation_3.h b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_triangulation_3.h index e977701c77b..64f113fa331 100644 --- a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_triangulation_3.h +++ b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_triangulation_3.h @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/Periodic_3_mesh_3/include/CGAL/refine_periodic_3_mesh_3.h b/Periodic_3_mesh_3/include/CGAL/refine_periodic_3_mesh_3.h index acb3b35decd..de1b05fbf0a 100644 --- a/Periodic_3_mesh_3/include/CGAL/refine_periodic_3_mesh_3.h +++ b/Periodic_3_mesh_3/include/CGAL/refine_periodic_3_mesh_3.h @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include #include diff --git a/Periodic_3_mesh_3/package_info/Periodic_3_mesh_3/dependencies b/Periodic_3_mesh_3/package_info/Periodic_3_mesh_3/dependencies index 7fb9ae91209..daab68c8c70 100644 --- a/Periodic_3_mesh_3/package_info/Periodic_3_mesh_3/dependencies +++ b/Periodic_3_mesh_3/package_info/Periodic_3_mesh_3/dependencies @@ -22,6 +22,7 @@ Modular_arithmetic Number_types Periodic_3_mesh_3 Periodic_3_triangulation_3 +Polygon_mesh_processing Principal_component_analysis Principal_component_analysis_LGPL Profiling_tools @@ -31,6 +32,8 @@ STL_Extension Solver_interface Spatial_sorting Stream_support +SMDS_3 TDS_3 Triangulation_3 Union_find + diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h index 45f76b3aa71..2360904b966 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -74,9 +75,13 @@ public: m_pm(pm) { } - template + template //polygonindex-2-face void operator()(PolygonMesh& pmesh, VertexPointMap vpm, + V2V i2v, + F2F i2f, const bool insert_isolated_vertices = true) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -109,6 +114,7 @@ public: vertices[i] = add_vertex(pmesh); PM_Point pi = convert_to_pm_point(get(m_pm, m_points[i])); put(vpm, vertices[i], pi); + *i2v++ = std::make_pair(i, vertices[i]); } for(std::size_t i = 0, end = m_polygons.size(); i < end; ++i) @@ -121,9 +127,10 @@ public: for(std::size_t j = 0; j < size; ++j) vr[j] = vertices[polygon[j] ]; - CGAL_assertion_code(typename boost::graph_traits::face_descriptor fd =) + typename boost::graph_traits::face_descriptor fd = CGAL::Euler::add_face(vr, pmesh); CGAL_assertion(fd != boost::graph_traits::null_face()); + *i2f++ = std::make_pair(i, fd); } } @@ -131,7 +138,11 @@ public: void operator()(PolygonMesh& pmesh, const bool insert_isolated_vertices = true) { - return operator()(pmesh, get(CGAL::vertex_point, pmesh), insert_isolated_vertices); + return operator()(pmesh, + get(CGAL::vertex_point, pmesh), + CGAL::Emptyset_iterator(), + CGAL::Emptyset_iterator(), + insert_isolated_vertices); } private: @@ -250,6 +261,23 @@ bool is_polygon_soup_a_polygon_mesh(const PolygonRange& polygons) * of the vertex point map associated to the polygon mesh} * \cgalParamDefault{`CGAL::Identity_property_map`} * \cgalParamNEnd +* +* \cgalParamNBegin{point_to_vertex_output_iterator} +* \cgalParamDescription{an `OutputIterator` containing the pairs source-vertex-index +* from `points`, target-vertex.} +* \cgalParamType{a class model of `OutputIterator` accepting +* `std::pair::%vertex_descriptor>`} +* \cgalParamDefault{`Emptyset_iterator`} +* \cgalParamNEnd +* +* \cgalParamNBegin{polygon_to_face_output_iterator} +* \cgalParamDescription{an `OutputIterator` containing the pairs polygon-index +* from `polygons`, target-face.} +* \cgalParamType{a class model of `OutputIterator` accepting +* `std::pair::%face_descriptor>`} +* \cgalParamDefault{`Emptyset_iterator`} +* \cgalParamNEnd +* * \cgalNamedParamsEnd * * @param np_pm an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below @@ -292,7 +320,11 @@ void polygon_soup_to_polygon_mesh(const PointRange& points, get_property_map(CGAL::vertex_point, out)); internal::PS_to_PM_converter converter(points, polygons, pm); - converter(out, vpm); + converter(out, vpm, + choose_parameter(get_parameter(np_ps, internal_np::point_to_vertex_output_iterator), + impl::make_functor(get_parameter(np_ps, internal_np::vertex_to_vertex_map))), + choose_parameter(get_parameter(np_ps, internal_np::polygon_to_face_output_iterator), + impl::make_functor(get_parameter(np_ps, internal_np::face_to_face_map)))); } } // namespace Polygon_mesh_processing diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp index 04af9bf3621..28a0be5359e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp @@ -10,7 +10,7 @@ // Jane Tournois // -#include +#include #include #include "Scene_surface_mesh_item.h" @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include @@ -377,7 +377,7 @@ public: if (is_c3t3) { typedef std::array Facet; // 3 = id - typedef std::array Tet_with_ref; // first 4 = id, fifth = reference + typedef std::array Tet; // first 4 = id, fifth = reference Scene_c3t3_item* c3t3_item = new Scene_c3t3_item(); c3t3_item->set_valid(false); //build a triangulation from data: @@ -388,7 +388,8 @@ public: double *p = dataP->GetPoint(i); points.push_back(Tr::Point(p[0],p[1],p[2])); } - std::vector finite_cells; + std::vector finite_cells; + std::vector subdomains; bool has_mesh_domain = data->GetCellData()->HasArray("MeshDomain"); vtkDataArray* domains = data->GetCellData()->GetArray("MeshDomain"); for(int i = 0; i< data->GetNumberOfCells(); ++i) @@ -396,12 +397,15 @@ public: if(data->GetCellType(i) != 10 ) continue; vtkIdList* pids = data->GetCell(i)->GetPointIds(); - Tet_with_ref cell; + Tet cell; for(int j = 0; j<4; ++j) cell[j] = pids->GetId(j); - cell[4] = has_mesh_domain ? static_cast(domains->GetComponent(i,0)) - :1; finite_cells.push_back(cell); + + const auto si = has_mesh_domain + ? static_cast(domains->GetComponent(i, 0)) + : 1; + subdomains.push_back(si); } std::map border_facets; //Preprocessing for build_triangulation @@ -420,9 +424,11 @@ public: std::swap(finite_cells[i][1], finite_cells[i][3]); } } - std::vector new_vertices; - CGAL::build_triangulation(c3t3_item->c3t3().triangulation(), - points, finite_cells, border_facets, new_vertices); + + CGAL::SMDS_3::build_triangulation_with_subdomains_range( + c3t3_item->c3t3().triangulation(), + points, finite_cells, subdomains, border_facets, + false, false, true); for( C3t3::Triangulation::Finite_cells_iterator cit = c3t3_item->c3t3().triangulation().finite_cells_begin(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp index 755e5e8730e..3f2b08782fb 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp @@ -1,6 +1,6 @@ -#include +#include #include "Scene_c3t3_item.h" -#include +#include #include #include #include @@ -129,13 +129,11 @@ Polyhedron_demo_c3t3_binary_io_plugin::load( item->setName(fileinfo.baseName()); item->set_valid(false); - if(CGAL::build_triangulation_from_file(in, item->c3t3().triangulation(), true)) + if(CGAL::SMDS_3::build_triangulation_from_file(in, item->c3t3().triangulation(), + /*verbose = */true, /*replace_subdomain_0 = */false, /*allow_non_manifold = */true)) { item->c3t3().rescan_after_load_of_triangulation(); //fix counters for facets and cells - for( C3t3::Triangulation::Finite_cells_iterator - cit = item->c3t3().triangulation().finite_cells_begin(); - cit != item->c3t3().triangulation().finite_cells_end(); - ++cit) + for( C3t3::Cell_handle cit : item->c3t3().triangulation().finite_cell_handles()) { CGAL_assertion(cit->subdomain_index() >= 0); if(cit->subdomain_index() != C3t3::Triangulation::Cell::Subdomain_index()) @@ -152,22 +150,19 @@ Polyhedron_demo_c3t3_binary_io_plugin::load( //if there is no facet in the complex, we add the border facets. if(item->c3t3().number_of_facets_in_complex() == 0) { - for( C3t3::Triangulation::Finite_facets_iterator - fit = item->c3t3().triangulation().finite_facets_begin(); - fit != item->c3t3().triangulation().finite_facets_end(); - ++fit) + for( C3t3::Facet fit : item->c3t3().triangulation().finite_facets()) { typedef C3t3::Triangulation::Cell_handle Cell_handle; - Cell_handle c = fit->first; - Cell_handle nc = c->neighbor(fit->second); + Cell_handle c = fit.first; + Cell_handle nc = c->neighbor(fit.second); // By definition, Subdomain_index() is supposed to be the id of the exterior if(c->subdomain_index() != C3t3::Triangulation::Cell::Subdomain_index() && nc->subdomain_index() == C3t3::Triangulation::Cell::Subdomain_index()) { // Color the border facet with the index of its cell - item->c3t3().add_to_complex(c, fit->second, c->subdomain_index()); + item->c3t3().add_to_complex(c, fit.second, c->subdomain_index()); } } } @@ -236,7 +231,9 @@ save(QFileInfo fileinfo, QList &items) else if (fileinfo.suffix() == "mesh") { std::ofstream medit_file (qPrintable(path)); - c3t3_item->c3t3().output_to_medit(medit_file,true,true); + CGAL::IO::write_MEDIT(medit_file, c3t3_item->c3t3(), + CGAL::parameters::rebind_labels(true) + .show_patches(true)); items.pop_front(); return true; } diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp index ba71e754425..7f1389b8ba4 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp @@ -210,9 +210,18 @@ bool Scene_c3t3_item::is_facet_oriented(const T3::Facet& f)const return (index % 2 == 1) == d->c3t3.is_in_complex(cell); } +QString Scene_c3t3_item::toolTip() const { + return tr("

3D complex in a 3D triangulation

" + "

Number of vertices: %1
" + "Number of surface facets: %2
" + "Number of volume tetrahedra: %3

%4") + .arg(c3t3().triangulation().number_of_vertices()) + .arg(c3t3().number_of_facets_in_complex()) + .arg(c3t3().number_of_cells_in_complex()) + .arg(property("toolTip").toString()); +} QMenu* Scene_c3t3_item::contextMenu() { - const char* prop_name = "Menu modified by Scene_c3t3_item."; QMenu* menu = Scene_triangulation_3_item::contextMenu(); @@ -278,6 +287,26 @@ bool Scene_c3t3_item::load_binary(std::istream& is) return false; } +void Scene_c3t3_item::compute_bbox() const +{ + if (isEmpty()) + _bbox = Bbox(); + else + { + CGAL::Bbox_3 result;//default is [+infinity; -infinity] + for (Tr::Cell_handle c : c3t3().cells_in_complex()) + { + Tr::Vertex_handle v = (c->vertex(0) != c3t3().triangulation().infinite_vertex()) + ? c->vertex(0) + : c->vertex(1); + result += v->point().bbox(); + } + _bbox = Bbox(result.xmin(), result.ymin(), result.zmin(), + result.xmax(), result.ymax(), result.zmax()); + } +} + + void Scene_c3t3_item::export_facets_in_complex() { SMesh outmesh; diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h index ea3a5572e10..834f3527edc 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h @@ -59,6 +59,8 @@ using namespace CGAL::Three; } bool load_binary(std::istream& is) override; + void compute_bbox() const override; + bool is_valid() const;//true if the c3t3 is correct, false if it was made from a .mesh, for example void set_valid(bool); QMenu* contextMenu() override; @@ -95,6 +97,7 @@ using namespace CGAL::Three; bool do_take_vertex(const T3::Vertex_handle &)const override; bool is_facet_oriented(const T3::Facet&)const override; bool is_surface()const override; + QString toolTip() const override; void common_constructor(bool is_surface); }; diff --git a/Mesh_3/doc/Mesh_3/Concepts/MeshComplexWithFeatures_3InTriangulation_3.h b/SMDS_3/doc/SMDS_3/Concepts/MeshComplexWithFeatures_3InTriangulation_3.h similarity index 99% rename from Mesh_3/doc/Mesh_3/Concepts/MeshComplexWithFeatures_3InTriangulation_3.h rename to SMDS_3/doc/SMDS_3/Concepts/MeshComplexWithFeatures_3InTriangulation_3.h index 50b2751ac74..f97cdcb318b 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/MeshComplexWithFeatures_3InTriangulation_3.h +++ b/SMDS_3/doc/SMDS_3/Concepts/MeshComplexWithFeatures_3InTriangulation_3.h @@ -1,5 +1,5 @@ /*! -\ingroup PkgMesh3Concepts +\ingroup PkgSMDS3Concepts \cgalConcept The concept `MeshComplexWithFeatures_3InTriangulation_3` describes a data structure diff --git a/Mesh_3/doc/Mesh_3/Concepts/MeshComplex_3InTriangulation_3.h b/SMDS_3/doc/SMDS_3/Concepts/MeshComplex_3InTriangulation_3.h similarity index 99% rename from Mesh_3/doc/Mesh_3/Concepts/MeshComplex_3InTriangulation_3.h rename to SMDS_3/doc/SMDS_3/Concepts/MeshComplex_3InTriangulation_3.h index 3d3e28c7e2f..c3b1696a58d 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/MeshComplex_3InTriangulation_3.h +++ b/SMDS_3/doc/SMDS_3/Concepts/MeshComplex_3InTriangulation_3.h @@ -1,5 +1,5 @@ /*! -\ingroup PkgMesh3Concepts +\ingroup PkgSMDS3Concepts \cgalConcept The concept `MeshComplex_3InTriangulation_3` describes a data structure @@ -46,7 +46,7 @@ The data structure encodes the final mesh at the end of the meshing process. \sa `MeshDomain_3` \sa `MeshComplexWithFeatures_3InTriangulation_3` -\sa `CGAL::make_mesh_3()` +\sa \link CGAL::make_mesh_3() `CGAL::make_mesh_3()`\endlink */ diff --git a/SMDS_3/doc/SMDS_3/Concepts/SimplicialMeshCellBase_3.h b/SMDS_3/doc/SMDS_3/Concepts/SimplicialMeshCellBase_3.h new file mode 100644 index 00000000000..4ac54ef66db --- /dev/null +++ b/SMDS_3/doc/SMDS_3/Concepts/SimplicialMeshCellBase_3.h @@ -0,0 +1,80 @@ +/*! +\ingroup PkgSMDS3Concepts +\cgalConcept + +The concept `SimplicialMeshCellBase_3` describes the requirements +for the `TriangulationDataStructure_3::Cell` type of the triangulation +used in the 3D simplicial mesh data structure. The type `SimplicialMeshCellBase_3` +refines the concept `TriangulationCellBase_3` +and must be copy constructible. +The concept `SimplicialMeshCellBase_3` +includes a way to store and retrieve +if a given cell of the triangulation is inside a subdomain or not, +and which subdomain it belongs to +in case of a multi-domain. + +Moreover, this concept adds four markers per cell to mark the facets +of the triangulation that are surface facets. + +\cgalRefines `TriangulationCellBase_3 ` +\cgalRefines `CopyConstructible` + +\cgalHasModel `CGAL::Compact_mesh_cell_base_3` +\cgalHasModel `CGAL::Mesh_cell_base_3` +\cgalHasModel `CGAL::Simplicial_mesh_cell_base_3` +\cgalHasModel `CGAL::Tetrahedral_remeshing::Remeshing_cell_base_3` + +*/ + +class SimplicialMeshCellBase_3 { +public: + +/// \name Types +/// @{ + +/*! +Type of indices for cells of the mesh complex. +Must match the type `MeshDomain_3::Subdomain_index` in the context of mesh generation. +*/ +typedef unspecified_type Subdomain_index; + +/*! +Type of indices for surface patches of the mesh complex. +Must match the type `MeshDomain_3::Surface_patch_index` in the context of mesh generation. +*/ +typedef unspecified_type Surface_patch_index; + + +/// @} + +/// \name Operations +/// @{ + +/*! +returns the index of the input subdomain that contains the cell. +*/ +Subdomain_index subdomain_index(); + +/*! +Sets the subdomain index of the cell. +*/ +void set_subdomain_index(Subdomain_index index); + +/*! +returns `true` iff `facet(i)` is a surface facet. +*/ +bool is_facet_on_surface(int i); + +/*! +returns `Surface_patch_index` of facet `i`. +*/ +Surface_patch_index surface_patch_index(int i); + +/*! +sets `Surface_patch_index` of facet `i` to `index`. +*/ +void set_surface_patch_index(int i, Surface_patch_index index); + +/// @} + +}; /* end SimplicialMeshCellBase_3 */ diff --git a/SMDS_3/doc/SMDS_3/Concepts/SimplicialMeshVertexBase_3.h b/SMDS_3/doc/SMDS_3/Concepts/SimplicialMeshVertexBase_3.h new file mode 100644 index 00000000000..0ada434d3eb --- /dev/null +++ b/SMDS_3/doc/SMDS_3/Concepts/SimplicialMeshVertexBase_3.h @@ -0,0 +1,91 @@ +/*! +\ingroup PkgSMDS3Concepts +\cgalConcept + +The concept `SimplicialMeshVertexBase_3` describes the requirements +for the `Vertex` type of the triangulation +used in the 3D simplicial mesh data structure. The type `SimplicialMeshVertexBase_3` +refines the concept `TriangulationVertexBase_3`. +It provides additional members to store and retrieve +information about the location of the vertex with respect +to the input domain describing the discretized domain. +More specifically, the concept `SimplicialMeshVertexBase_3` provides read-write access +to an integer representing the dimension of the lowest dimensional face +of the input 3D complex on which the vertex lies, +and to an index characteristic of this face. + +\cgalRefines `TriangulationVertexBase_3` + +\cgalHasModel `CGAL::Mesh_vertex_base_3` +\cgalHasModel `CGAL::Simplicial_mesh_vertex_base_3` +\cgalHasModel `CGAL::Tetrahedral_remeshing::Remeshing_vertex_base_3` + +*/ + +class SimplicialMeshVertexBase_3 { +public: + +/// \name Types +/// @{ + +/*! +Index type. +*/ +typedef unspecified_type Index; + +/*! +Numerical type. +*/ +typedef unspecified_type FT; + +/// @} + +/// \name Operations +/// @{ + +/*! +Returns the dimension of the lowest dimensional face of the input 3D complex that contains the vertex. +*/ +int in_dimension() const; + +/*! +Sets the dimension of the lowest dimensional face of the input 3D complex that contains the vertex. +*/ +void set_dimension(int); + +/*! +Returns the index of the lowest dimensional face of the input 3D complex that contains the vertex. +*/ +Index index(); + +/*! +Sets the index of the lowest dimensional face of the input 3D complex that contains the vertex. +*/ +void set_index(Index); + +/*! +Returns `true` if the cache is valid. +*/ +bool is_c2t3_cache_valid(); + +/*! +Invalidates the cache. +*/ +void invalidate_c2t3_cache(); + +/*! +Returns the cached number of facets of the complex incident to the vertex. +*/ +int cached_number_of_incident_facets(); + +/*! +This method concerns the adjacency +graph of the facets of the complex incident to the vertex +and returns a cached value for the number of connected components this graph. +*/ +int cached_number_of_components(); + +/// @} + + +}; /* end SimplicialMeshVertexBase_3 */ diff --git a/SMDS_3/doc/SMDS_3/Doxyfile.in b/SMDS_3/doc/SMDS_3/Doxyfile.in new file mode 100644 index 00000000000..78025668400 --- /dev/null +++ b/SMDS_3/doc/SMDS_3/Doxyfile.in @@ -0,0 +1,12 @@ +@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} + +PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 3D Simplicial Mesh Data Structures" + +#custom options +EXTRACT_ALL = false +HIDE_UNDOC_CLASSES = true +HIDE_UNDOC_MEMBERS = true +WARN_IF_UNDOCUMENTED = false + +EXCLUDE = ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/internal/SMDS_3 + diff --git a/SMDS_3/doc/SMDS_3/PackageDescription.txt b/SMDS_3/doc/SMDS_3/PackageDescription.txt new file mode 100644 index 00000000000..8b5ad64a507 --- /dev/null +++ b/SMDS_3/doc/SMDS_3/PackageDescription.txt @@ -0,0 +1,78 @@ +/// \defgroup PkgSMDS3Ref 3D Simplicial Mesh Data Structures Reference + +/// \defgroup PkgSMDS3Concepts Concepts +/// \ingroup PkgSMDS3Ref +/// The main concepts of this package. + +/// \defgroup PkgSMDS3Classes Classes +/// \ingroup PkgSMDS3Ref +/// The classes describing a 3D simplicial mesh data structure. + +/// \defgroup PkgSMDS3Functions Functions +/// \ingroup PkgSMDS3Ref +/// The functions to work with the 3D mesh data structures. + +/// \defgroup PkgSMDS3ExportFunctions Export Functions +/// \ingroup PkgSMDS3Ref +/// The free functions that can be used to export meshes to given output file formats. + +/// \defgroup PkgSMDS3IOFunctions Input/Output Functions +/// \ingroup PkgSMDS3Ref +/// The free functions that can be used to read and write meshes. + +/*! +\addtogroup PkgSMDS3Ref +\cgalPkgDescriptionBegin{3D Simplicial Mesh Data Structure,PkgSMDS3} +\cgalPkgPicture{knot_small.png} + +\cgalPkgSummaryBegin +\cgalPkgAuthors{Pierre Alliez, Clément Jamin, Laurent Rineau, Stéphane Tayeb, Jane Tournois, Mariette Yvinec} +\cgalPkgDesc{This package provides a data structure to store three-dimensional + simplicial meshes and their subcomplexes. + It provides an API for tetrahedral meshes generated with %CGAL or not, + to be processed with %CGAL 3D mesh generation and remeshing algorithms, + along with iterators, IO functions, and additional helper functions. + } +\cgalPkgManuals{Chapter_3D_Simplicial_Mesh_Data_Structure,PkgSMDS3Ref} +\cgalPkgSummaryEnd + +\cgalPkgShortInfoBegin +\cgalPkgSince{5.6} +\cgalPkgDependsOn{\ref PkgTriangulation3} +\cgalPkgBib{cgal:ajrtty-mds3} +\cgalPkgLicense{\ref licensesGPL "GPL"} +\cgalPkgDemo{Polyhedron demo,polyhedron_3.zip} +\cgalPkgShortInfoEnd +\cgalPkgDescriptionEnd + +\cgalClassifedRefPages + +\cgalCRPSection{Concepts} + +- `MeshComplex_3InTriangulation_3` +- `MeshComplexWithFeatures_3InTriangulation_3` +- `SimplicialMeshCellBase_3` +- `SimplicialMeshVertexBase_3` + +\cgalCRPSection{Classes} + +- `CGAL::Mesh_complex_3_in_triangulation_3` +- `CGAL::Simplicial_mesh_vertex_base_3` +- `CGAL::Simplicial_mesh_cell_base_3` + +\cgalCRPSection{Function Templates} + +- `CGAL::facets_in_complex_3_to_triangle_mesh()` +- `CGAL::tetrahedron_soup_to_triangulation_3()` + +\cgalCRPSection{Input/Output Functions} + +- `CGAL::IO::write_MEDIT()` +- `CGAL::IO::read_MEDIT()` +- `CGAL::IO::output_to_vtu()` +- `CGAL::IO::output_to_tetgen()` +- `CGAL::IO::save_binary_file()` +- `CGAL::IO::load_binary_file()` +- `CGAL::IO::output_to_medit()` (deprecated) +*/ + diff --git a/SMDS_3/doc/SMDS_3/SMDS_3.txt b/SMDS_3/doc/SMDS_3/SMDS_3.txt new file mode 100644 index 00000000000..7fcd35d7336 --- /dev/null +++ b/SMDS_3/doc/SMDS_3/SMDS_3.txt @@ -0,0 +1,91 @@ +namespace CGAL { +/*! + +\mainpage User Manual +\anchor Chapter_3D_Simplicial_Mesh_Data_Structure +\anchor userchaptersmds3 +\authors Pierre Alliez, Clément Jamin, Laurent Rineau, Stéphane Tayeb, Jane Tournois, Mariette Yvinec +\cgalAutoToc + +\cgalFigureBegin{figure_tetmesh_knot,knot_full.jpg} +A multi-domain tetrahedral mesh generated from a polyhedral surface with multiple surface patches. +The complete triangulation is displayed, including cells that belong or do not +belong to the mesh complex, surface patches, and feature edges. +\cgalFigureEnd + + +\section SMDS_3_section_c3t3 Mesh Complex + +This package is devoted to the representation of 3-Dimensional simplicial mesh data structures. + +A 3D simplicial complex is composed of points, line segments, triangles, +tetrahedra, and their corresponding combinatorial description +(namely vertices, edges, faces and cells). +CGAL provides 3D triangulations, that describe +both the geometry and connectivity of a 3D simplicial complex, +implemented in the +the \ref PkgTriangulation3 and \ref PkgTDS3 packages. + +We introduce the concept of \em mesh \em complex, that encodes extra information +on top of a 3D triangulation to represent a valid simplicial +complex. A mesh complex describes four subcomplexes +of simplices +of the support 3D triangulation, per dimension from 0 to 3: +- corner vertices (0D), +- feature edges (1D), +- surface facets (2D), +- domain cells (3D). See Figure \cgalFigureRef{figure_c3t3_cells}. + +The concept `MeshComplex_3InTriangulation_3` is a data structure devised to +represent these three-dimensional complexes embedded in a `Triangulation_3`. + +\cgalFigureBegin{figure_c3t3_cells,c3t3_cells.jpg} +(Left and Middle) A multi-domain 3D mesh is represented by its tetrahedral cells, +with subdomain indices, and surface indices (depicted with different colors here). +(Right) The underlying `Triangulation_3` triangulates the whole convex hull of its vertices. +The cells that lie outside the meshing domain are drawn in wire frame. +\cgalFigureEnd + + +\section SMDS_3_section_examples Examples + +\subsection TetSoupExample From Tetrahedron Soup to Triangulation_3 + +In the first example of this section, we build a random +`Delaunay_triangulation_3` and use it to build a consistent though +connectivity-free tetrahedron soup. +The tetrahedron soup is then put back together in a +`CGAL::Tetrahedral_remeshing::Remeshing_triangulation_3` before +being set as the reference triangulation of a `Mesh_complex_3_in_triangulation_3`. + +\cgalExample{SMDS_3/tetrahedron_soup_to_c3t3_example.cpp} + + +\subsection IOExample Input/Output Example + +The example below illustrates how to use the IO functions +for reading and writing a triangulation with the `Medit` file format +(See \cgalCite{frey:inria-00069921} for a comprehensive description of this file format.). + +\cgalExample{SMDS_3/c3t3_example.cpp} + + +\subsection MoreExamples More Examples In Other Packages + +The `Mesh_complex_3_in_triangulation_3` is widely used in the \ref PkgMesh3 package. +Many more examples can be found in its \ref Mesh_3_section_examples section. + +The package \ref PkgTetrahedralRemeshing also makes use of the +`Mesh_complex_3_in_triangulation_3` since it serves as a post-processing for +tetrahedral mesh generation. Some examples can be found in the \ref secTetRemeshingExamples +section. + + +\section SMDS_3History Implementation History + +The code of the `MeshComplex_3InTriangulation_3` and its variants were initially part of the package \ref PkgMesh3. +With the meshing and remeshing processes becoming more versatile, it was moved to its own package in the +release 5.6 of \cgal. + +*/ +} /* namespace CGAL */ diff --git a/SMDS_3/doc/SMDS_3/dependencies b/SMDS_3/doc/SMDS_3/dependencies new file mode 100644 index 00000000000..bfc4a01dbe7 --- /dev/null +++ b/SMDS_3/doc/SMDS_3/dependencies @@ -0,0 +1,14 @@ +Manual +BGL +Kernel_23 +STL_Extension +Algebraic_foundations +Stream_support +Triangulation_3 +Periodic_3_triangulation_3 +TDS_3 +Polyhedron +Miscellany +Mesh_3 +Tetrahedral_remeshing +Polygon_mesh_processing diff --git a/SMDS_3/doc/SMDS_3/examples.txt b/SMDS_3/doc/SMDS_3/examples.txt new file mode 100644 index 00000000000..fe33a6e5c64 --- /dev/null +++ b/SMDS_3/doc/SMDS_3/examples.txt @@ -0,0 +1,4 @@ +/*! +\example SMDS_3/c3t3_example.cpp +\example SMDS_3/tetrahedron_soup_to_c3t3_example.cpp +*/ diff --git a/SMDS_3/doc/SMDS_3/fig/c3t3_cells.jpg b/SMDS_3/doc/SMDS_3/fig/c3t3_cells.jpg new file mode 100644 index 00000000000..62a8b2201cc Binary files /dev/null and b/SMDS_3/doc/SMDS_3/fig/c3t3_cells.jpg differ diff --git a/SMDS_3/doc/SMDS_3/fig/knot_full.jpg b/SMDS_3/doc/SMDS_3/fig/knot_full.jpg new file mode 100644 index 00000000000..f46488dfbe1 Binary files /dev/null and b/SMDS_3/doc/SMDS_3/fig/knot_full.jpg differ diff --git a/SMDS_3/doc/SMDS_3/fig/knot_small.png b/SMDS_3/doc/SMDS_3/fig/knot_small.png new file mode 100644 index 00000000000..1a1174466a6 Binary files /dev/null and b/SMDS_3/doc/SMDS_3/fig/knot_small.png differ diff --git a/SMDS_3/examples/SMDS_3/CMakeLists.txt b/SMDS_3/examples/SMDS_3/CMakeLists.txt new file mode 100644 index 00000000000..54bb8f0ecf1 --- /dev/null +++ b/SMDS_3/examples/SMDS_3/CMakeLists.txt @@ -0,0 +1,17 @@ +# Created by the script cgal_create_CMakeLists +# This is the CMake script for compiling a set of CGAL applications. + +cmake_minimum_required(VERSION 3.1...3.20) + +project(SMDS_3_Examples) + +# CGAL and its components +find_package(CGAL REQUIRED) + +# Boost and its components +find_package(Boost REQUIRED) + +# Creating entries for all C++ files with "main" routine +# ########################################################## +create_single_source_cgal_program( "c3t3_example.cpp" ) +create_single_source_cgal_program( "tetrahedron_soup_to_c3t3_example.cpp" ) diff --git a/SMDS_3/examples/SMDS_3/c3t3_example.cpp b/SMDS_3/examples/SMDS_3/c3t3_example.cpp new file mode 100644 index 00000000000..3b9de3190dd --- /dev/null +++ b/SMDS_3/examples/SMDS_3/c3t3_example.cpp @@ -0,0 +1,56 @@ +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + + +using K = CGAL::Exact_predicates_inexact_constructions_kernel; + +using Subdomain_index = int; +using Surface_patch_index = unsigned char; +using Curve_index = char; +using Corner_index = short; + +using Cb = CGAL::Simplicial_mesh_cell_base_3; +using Vb = CGAL::Simplicial_mesh_vertex_base_3; + +using Tds = CGAL::Triangulation_data_structure_3; +using Triangulation = CGAL::Triangulation_3; + +using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; + + +int main(int argc, char* argv[]) +{ + std::string filename = (argc > 1) ? std::string(argv[1]) + : CGAL::data_file_path("meshes/elephant.mesh"); + + Triangulation tr; + + std::ifstream is(filename, std::ios_base::in); + CGAL::IO::read_MEDIT(is, tr); + + // [call a remeshing algorithm] + + std::ofstream os("after_remeshing.mesh"); + CGAL::IO::write_MEDIT(os, tr, CGAL::parameters::all_vertices(true)); + os.close(); + + Triangulation tr2; + std::ifstream is2("after_remeshing.mesh"); + CGAL::IO::read_MEDIT(is2, tr2); + is2.close(); + + return EXIT_SUCCESS; +} diff --git a/SMDS_3/examples/SMDS_3/tetrahedron_soup_to_c3t3_example.cpp b/SMDS_3/examples/SMDS_3/tetrahedron_soup_to_c3t3_example.cpp new file mode 100644 index 00000000000..7492736d6f6 --- /dev/null +++ b/SMDS_3/examples/SMDS_3/tetrahedron_soup_to_c3t3_example.cpp @@ -0,0 +1,78 @@ +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +using K = CGAL::Exact_predicates_inexact_constructions_kernel; + +using DT3 = CGAL::Delaunay_triangulation_3; +using Remeshing_triangulation = CGAL::Tetrahedral_remeshing::Remeshing_triangulation_3; +using C3T3 = CGAL::Mesh_complex_3_in_triangulation_3; + +using Point_3 = K::Point_3; +using Tetrahedron_3 = K::Tetrahedron_3; +using Vertex_handle = DT3::Vertex_handle; +using Subdomain_index = C3T3::Subdomain_index; + +int main(int , char* []) +{ + const int nbv = 100; + + //a triangulation + DT3 delaunay; + std::unordered_map v2i; + std::vector points(nbv); + std::vector tetrahedra; + std::vector > tets_by_indices; + std::vector< Subdomain_index> subdomains; + + //insert random points + CGAL::Random_points_in_cube_3 randp(2.); + int i = 0; + while (i < nbv) + { + points[i] = *randp++; + Vertex_handle v = delaunay.insert(points[i]); + v2i[v] = i++; + } + + tetrahedra.reserve(delaunay.number_of_finite_cells()); + tets_by_indices.reserve(delaunay.number_of_finite_cells()); + subdomains.reserve(delaunay.number_of_finite_cells()); + for (DT3::Cell_handle c : delaunay.finite_cell_handles()) + { + tetrahedra.push_back(delaunay.tetrahedron(c)); + tets_by_indices.push_back( { v2i.at(c->vertex(0)), + v2i.at(c->vertex(1)), + v2i.at(c->vertex(2)), + v2i.at(c->vertex(3)) } ); + subdomains.push_back(Subdomain_index(1)); + } + + //build triangulation from tetrahedra + Remeshing_triangulation tr + = CGAL::tetrahedron_soup_to_triangulation_3(tetrahedra); + + //build triangulation from indices + Remeshing_triangulation tr2 + = CGAL::tetrahedron_soup_to_triangulation_3( + points, tets_by_indices, + CGAL::parameters::subdomain_indices(std::cref(subdomains))); + + //build a C3T3 + C3T3 c3t3; + c3t3.triangulation() = tr; + + std::ofstream ofs("c3t3_output.mesh"); + CGAL::IO::write_MEDIT(ofs, c3t3); + + return EXIT_SUCCESS; +} diff --git a/Mesh_3/include/CGAL/IO/Complex_3_in_triangulation_3_to_vtk.h b/SMDS_3/include/CGAL/IO/Complex_3_in_triangulation_3_to_vtk.h similarity index 100% rename from Mesh_3/include/CGAL/IO/Complex_3_in_triangulation_3_to_vtk.h rename to SMDS_3/include/CGAL/IO/Complex_3_in_triangulation_3_to_vtk.h diff --git a/Mesh_3/include/CGAL/IO/File_avizo.h b/SMDS_3/include/CGAL/IO/File_avizo.h similarity index 93% rename from Mesh_3/include/CGAL/IO/File_avizo.h rename to SMDS_3/include/CGAL/IO/File_avizo.h index f2b31d68d6c..6ad6530ceaa 100644 --- a/Mesh_3/include/CGAL/IO/File_avizo.h +++ b/SMDS_3/include/CGAL/IO/File_avizo.h @@ -13,7 +13,7 @@ #ifndef CGAL_IO_FILE_AVIZO_H #define CGAL_IO_FILE_AVIZO_H -#include +#include #include @@ -27,9 +27,11 @@ namespace CGAL { namespace IO { /** - * @brief outputs mesh to avizo format - * @param os the stream - * @param c3t3 the mesh + * @ingroup PkgSMDS3ExportFunctions + * @brief exports a mesh complex to the Avizo (`.am`) file format + * @tparam C3T3 a class model of `MeshComplex_3InTriangulation_3` + * @param os the output stream + * @param c3t3 the mesh complex * \see \ref IOStreamAvizo */ template diff --git a/Mesh_3/include/CGAL/IO/File_binary_mesh_3.h b/SMDS_3/include/CGAL/IO/File_binary_mesh_3.h similarity index 68% rename from Mesh_3/include/CGAL/IO/File_binary_mesh_3.h rename to SMDS_3/include/CGAL/IO/File_binary_mesh_3.h index a2a87ee45ca..e7363047a92 100644 --- a/Mesh_3/include/CGAL/IO/File_binary_mesh_3.h +++ b/SMDS_3/include/CGAL/IO/File_binary_mesh_3.h @@ -13,23 +13,38 @@ #ifndef CGAL_IO_FILE_BINARY_MESH_3_H #define CGAL_IO_FILE_BINARY_MESH_3_H -#include +#include #include #include #include -#include +#include namespace CGAL { namespace IO { + /** + * @ingroup PkgSMDS3IOFunctions + * @brief outputs a mesh complex to the CGAL binary file format (`.binary.cgal`). + * + * @tparam C3T3 Type of mesh complex, model of `MeshComplex_3InTriangulation_3` + * + * @param os the output stream, opened in binary mode + * @param c3t3 the mesh complex + * + * @sa `CGAL::IO::load_binary_file()` + */ template bool save_binary_file(std::ostream& os, - const C3T3& c3t3, - bool binary = true) + const C3T3& c3t3 +#ifdef DOXYGEN_RUNNING + ) +#else + , bool binary = true) +#endif { typedef typename C3T3::Triangulation::Geom_traits::FT FT; if(binary) os << "binary "; @@ -44,6 +59,17 @@ save_binary_file(std::ostream& os, // call operator!() twice, because operator bool() is C++11 } +/** + * @ingroup PkgSMDS3IOFunctions + * @brief loads a mesh complex from a file written in CGAL binary file format (`.binary.cgal`). + * + * @tparam C3T3 Type of mesh complex, model of `MeshComplex_3InTriangulation_3` + * + * @param is the input stream, opened in binary mode + * @param c3t3 the mesh complex + * + * @sa `CGAL::IO::save_binary_file()` + */ template bool load_binary_file(std::istream& is, C3T3& c3t3) { diff --git a/Mesh_3/include/CGAL/IO/File_maya.h b/SMDS_3/include/CGAL/IO/File_maya.h similarity index 99% rename from Mesh_3/include/CGAL/IO/File_maya.h rename to SMDS_3/include/CGAL/IO/File_maya.h index 4546132bb95..682f9540642 100644 --- a/Mesh_3/include/CGAL/IO/File_maya.h +++ b/SMDS_3/include/CGAL/IO/File_maya.h @@ -12,7 +12,7 @@ #ifndef CGAL_IO_FILE_MAYA_H #define CGAL_IO_FILE_MAYA_H -#include +#include #include #include diff --git a/Mesh_3/include/CGAL/IO/File_medit.h b/SMDS_3/include/CGAL/IO/File_medit.h similarity index 64% rename from Mesh_3/include/CGAL/IO/File_medit.h rename to SMDS_3/include/CGAL/IO/File_medit.h index 95585dc1b82..831dca9e121 100644 --- a/Mesh_3/include/CGAL/IO/File_medit.h +++ b/SMDS_3/include/CGAL/IO/File_medit.h @@ -14,10 +14,11 @@ #ifndef CGAL_IO_FILE_MEDIT_H #define CGAL_IO_FILE_MEDIT_H -#include +#include -#include -#include +#include +#include +#include #include #include @@ -26,16 +27,20 @@ #include #include +#include +#include + #include #include #include #include #include #include +#include namespace CGAL { -namespace Mesh_3 { +namespace SMDS_3 { //------------------------------------------------------- // Needed in verbose mode @@ -65,14 +70,9 @@ public: Rebind_cell_pmap(const C3T3& c3t3) : r_c3t3_(c3t3) { - typedef typename C3T3::Cells_in_complex_iterator Cell_iterator; + int index_counter = 1; - int first_index = 0; - int index_counter = first_index + 1; - - for( Cell_iterator cell_it = r_c3t3_.cells_in_complex_begin(); - cell_it != r_c3t3_.cells_in_complex_end(); - ++cell_it) + for( Cell_handle cell_it : r_c3t3_.cells_in_complex()) { // Add subdomain index in internal map if needed std::pair is_insert_successful = @@ -84,7 +84,7 @@ public: } // Rebind indices in alphanumeric order - index_counter = first_index + 1; + index_counter = 1; for ( typename Subdomain_map::iterator mit = subdomain_map_.begin() ; mit != subdomain_map_.end() ; ++mit ) @@ -125,7 +125,7 @@ private: if ( elt_it != subdomain_map_.end() ) return elt_it->second; else - return -1; + return 0; } private: @@ -170,12 +170,9 @@ public: size_type subdomain_number() const { - typedef typename C3T3::Cells_in_complex_iterator Cell_iterator; std::set subdomain_set; - for( Cell_iterator cell_it = r_c3t3_.cells_in_complex_begin(); - cell_it != r_c3t3_.cells_in_complex_end(); - ++cell_it) + for( Cell_handle cell_it : r_c3t3_.cells_in_complex()) { // Add subdomain index in set subdomain_set.insert(subdomain_index(cell_it)); @@ -214,30 +211,23 @@ public: : r_c3t3_(c3t3) , cell_pmap_(cell_pmap) { - typedef typename C3T3::Facets_in_complex_iterator Facet_iterator; - int first_index = 1; int index_counter = first_index; - for( Facet_iterator facet_it = r_c3t3_.facets_in_complex_begin(); - facet_it != r_c3t3_.facets_in_complex_end(); - ++facet_it) + for( Facet facet_it : r_c3t3_.facets_in_complex()) { // Add surface index in internal map if needed std::pair is_insert_successful = - surface_map_.insert(std::make_pair(r_c3t3_.surface_patch_index(*facet_it), + surface_map_.insert(std::make_pair(r_c3t3_.surface_patch_index(facet_it), index_counter)); if(is_insert_successful.second) ++index_counter; } // Find cell_pmap_ unused indices - typedef typename C3T3::Cells_in_complex_iterator Cell_iterator; std::set cell_label_set; - for( Cell_iterator cell_it = r_c3t3_.cells_in_complex_begin(); - cell_it != r_c3t3_.cells_in_complex_end(); - ++cell_it) + for( typename C3T3::Cell_handle cell_it : r_c3t3_.cells_in_complex()) { // Add subdomain index in set cell_label_set.insert(get(cell_pmap_, cell_it)); @@ -588,7 +578,7 @@ public: break; default: - // should not happen + // must not happen return -1; break; } @@ -703,7 +693,9 @@ struct Medit_pmap_generator template void output_to_medit(std::ostream& os, - const C3T3& c3t3) + const C3T3& c3t3, + const bool all_vertices, + const bool all_cells) { #ifdef CGAL_MESH_3_IO_VERBOSE std::cerr << "Output to medit:\n"; @@ -726,7 +718,9 @@ output_to_medit(std::ostream& os, facet_pmap, cell_pmap, facet_pmap_twice, - Generator().print_twice()); + Generator().print_twice(), + all_vertices, + all_cells); #ifdef CGAL_MESH_3_IO_VERBOSE std::cerr << "done.\n"; @@ -747,14 +741,14 @@ output_to_medit(std::ostream& os, const Facet_index_property_map& facet_pmap, const Cell_index_property_map& cell_pmap, const Facet_index_property_map_twice& facet_twice_pmap = Facet_index_property_map_twice(), - const bool print_each_facet_twice = false) + const bool print_each_facet_twice = false, + const bool all_vertices = true, + const bool all_cells = false) { typedef typename C3T3::Triangulation Tr; - typedef typename C3T3::Facets_in_complex_iterator Facet_iterator; - typedef typename C3T3::Cells_in_complex_iterator Cell_iterator; - typedef typename Tr::Finite_vertices_iterator Finite_vertices_iterator; typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Cell_handle Cell_handle; typedef typename Tr::Point Point; //can be weighted or not const Tr& tr = c3t3.triangulation(); @@ -770,32 +764,61 @@ output_to_medit(std::ostream& os, os << "MeshVersionFormatted 1\n" << "Dimension 3\n"; - + os << "# CGAL::Mesh_complex_3_in_triangulation_3\n"; //------------------------------------------------------- // Vertices //------------------------------------------------------- - os << "Vertices\n" << tr.number_of_vertices() << '\n'; - boost::unordered_map V; + std::unordered_map V; int inum = 1; - for( Finite_vertices_iterator vit = tr.finite_vertices_begin(); - vit != tr.finite_vertices_end(); - ++vit) + if (all_vertices || all_cells) { - V[vit] = inum++; - Point p = tr.point(vit); - os << CGAL::to_double(p.x()) << ' ' - << CGAL::to_double(p.y()) << ' ' - << CGAL::to_double(p.z()) << ' ' - << get(vertex_pmap, vit) - << '\n'; + os << "Vertices\n" << tr.number_of_vertices() << '\n'; + + for (typename Tr::Finite_vertices_iterator vit = tr.finite_vertices_begin(); + vit != tr.finite_vertices_end(); + ++vit) + { + V[vit] = inum++; + const Point& p = tr.point(vit); + os << CGAL::to_double(p.x()) << ' ' + << CGAL::to_double(p.y()) << ' ' + << CGAL::to_double(p.z()) << ' ' + << get(vertex_pmap, vit) + << '\n'; + } + } + else + { + std::ostringstream oss; + for (Cell_handle c : c3t3.cells_in_complex()) + { + for (int i = 0; i < 4; ++i) + { + Vertex_handle vit = c->vertex(i); + if (V.find(vit) == V.end()) + { + V[vit] = inum++; + const Point& p = tr.point(vit); + oss << CGAL::to_double(p.x()) << ' ' + << CGAL::to_double(p.y()) << ' ' + << CGAL::to_double(p.z()) << ' ' + << get(vertex_pmap, vit) + << '\n'; + } + } + } + os << "Vertices\n" << V.size() << "\n"; + os << oss.str(); } //------------------------------------------------------- // Facets //------------------------------------------------------- - typename C3T3::size_type number_of_triangles = c3t3.number_of_facets_in_complex(); + typename C3T3::size_type number_of_triangles + = std::distance(c3t3.facets_in_complex_begin(), + c3t3.facets_in_complex_end()); if ( print_each_facet_twice ) number_of_triangles += number_of_triangles; @@ -803,12 +826,8 @@ output_to_medit(std::ostream& os, os << "Triangles\n" << number_of_triangles << '\n'; - for( Facet_iterator fit = c3t3.facets_in_complex_begin(); - fit != c3t3.facets_in_complex_end(); - ++fit) + for(typename C3T3::Facet f : c3t3.facets_in_complex()) { - typename C3T3::Facet f = (*fit); - // Apply priority among subdomains, to get consistent facet orientation per subdomain-pair interface. if ( print_each_facet_twice ) { @@ -827,30 +846,47 @@ output_to_medit(std::ostream& os, std::swap(vh2, vh3); os << V[vh1] << ' ' << V[vh2] << ' ' << V[vh3] << ' '; - os << get(facet_pmap, *fit) << '\n'; + os << get(facet_pmap, f) << '\n'; // Print triangle again if needed, with opposite orientation if ( print_each_facet_twice ) { os << V[vh3] << ' ' << V[vh2] << ' ' << V[vh1] << ' '; - os << get(facet_twice_pmap, *fit) << '\n'; + os << get(facet_twice_pmap, f) << '\n'; } } //------------------------------------------------------- // Tetrahedra //------------------------------------------------------- + typename C3T3::size_type number_of_cells + = all_cells + ? c3t3.triangulation().number_of_finite_cells() + : std::distance(c3t3.cells_in_complex_begin(), c3t3.cells_in_complex_end());; os << "Tetrahedra\n" - << c3t3.number_of_cells_in_complex() << '\n'; + << number_of_cells << '\n'; - for( Cell_iterator cit = c3t3.cells_in_complex_begin() ; - cit != c3t3.cells_in_complex_end() ; - ++cit ) + if (all_cells) { - for (int i=0; i<4; i++) - os << V[cit->vertex(i)] << ' '; + for (auto cit = c3t3.triangulation().finite_cells_begin(); + cit != c3t3.triangulation().finite_cells_end(); + ++cit) + { + for (int i = 0; i < 4; i++) + os << V[cit->vertex(i)] << ' '; - os << get(cell_pmap, cit) << '\n'; + os << get(cell_pmap, cit) << '\n'; + } + } + else + { + for (Cell_handle cit : c3t3.cells_in_complex()) + { + for (int i = 0; i < 4; i++) + os << V[cit->vertex(i)] << ' '; + + os << get(cell_pmap, cit) << '\n'; + } } //------------------------------------------------------- @@ -865,53 +901,222 @@ output_to_medit(std::ostream& os, namespace IO { /** - * @brief outputs mesh to medit format - * @param os the stream - * @param c3t3 the mesh - * @param rebind if true, labels of cells are rebinded into [1..nb_of_labels] - * @param show_patches if true, patches are labeled with different labels than - * cells. If false, each surface facet is written twice, using label of - * each adjacent cell. + * @ingroup PkgSMDS3IOFunctions + * @deprecated This function is deprecated. Users should instead use `CGAL::IO::write_MEDIT()` + * @brief outputs a mesh complex to the medit (`.mesh`) file format. + See \cgalCite{frey:inria-00069921} for a comprehensive description of this file format. + * @param os the output stream + * @param c3t3 the mesh complex + * @param rebind if `true`, labels of cells are rebinded into `[1..nb_of_labels]` + * @param show_patches if `true`, patches are labeled with different labels than + * cells. If `false`, each surface facet is written twice, + * using the label of each adjacent cell. * \see \ref IOStreamMedit */ template void output_to_medit(std::ostream& os, const C3T3& c3t3, - bool rebind = false, - bool show_patches = false) + bool rebind, // = false, + bool show_patches // = false +#ifndef DOXYGEN_RUNNING + , bool all_vertices // = true + , bool all_cells // = false +#endif +) { if ( rebind ) { if ( show_patches ) - Mesh_3::output_to_medit(os,c3t3); + CGAL::SMDS_3::output_to_medit(os, c3t3, + all_vertices, all_cells); else - Mesh_3::output_to_medit(os,c3t3); + CGAL::SMDS_3::output_to_medit(os, c3t3, + all_vertices, all_cells); } else { if ( show_patches ) - Mesh_3::output_to_medit(os,c3t3); + CGAL::SMDS_3::output_to_medit(os, c3t3, + all_vertices, all_cells); else - Mesh_3::output_to_medit(os,c3t3); + CGAL::SMDS_3::output_to_medit(os, c3t3, + all_vertices, all_cells); } } - -template -void write_MEDIT(std::ostream& os, const T3& t3) +/** + * @ingroup PkgSMDS3IOFunctions + * @brief outputs a mesh complex to the medit (`.mesh`) file format. + * See \cgalCite{frey:inria-00069921} for a comprehensive description of this file format. + * @tparam T3 can be instantiated with any 3D triangulation of \cgal provided that its + * vertex and cell base class are models of the concepts `SimplicialMeshVertexBase_3` + * and `SimplicialMeshCellBase_3`, respectively. + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * @param os the output stream + * @param t3 the triangulation + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{all_cells} + * \cgalParamDescription{If `true`, all the cells in `t3` are written in `os`, + * whether they belong to the complex or not. + * Otherwise, only the cells `c` for which + * `c->subdomain_index() != Subdomain_index()` are written.} + * \cgalParamType{Boolean} + * \cgalParamDefault{`true`} + * \cgalParamExtra{This parameter must be set to `true` for the file to be readable by `read_MEDIT()`.} + * \cgalParamNEnd + * + * \cgalParamNBegin{all_vertices} + * \cgalParamDescription{If `true`, all the finite vertices in `t3` are written in `os`. + * Otherwise, only the vertices that belong to a cell `c` for which + * `c->subdomain_index() != Subdomain_index()` are written} + * \cgalParamType{Boolean} + * \cgalParamDefault{`true`} + * \cgalParamExtra{If `all_cells` is `true`, the value of this parameter is ignored and + all vertices are written in `os`. It must be + * set to `true` for the file to be readable by `read_MEDIT()`.} + * \cgalParamNEnd + * + * \cgalParamNBegin{rebind_labels} + * \cgalParamDescription{If `true`, labels of cells are rebinded into `[1..nb_of_labels]`} + * \cgalParamType{Boolean} + * \cgalParamDefault{`false`} + * \cgalParamNEnd + * + * \cgalParamNBegin{show_patches} + * \cgalParamDescription{If `true`, patches are labeled with different labels than + * cells. If `false`, each surface facet is written twice, + * using the label of each adjacent cell.} + * \cgalParamType{Boolean} + * \cgalParamDefault{`true`} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * \see \ref IOStreamMedit + */ +template +void write_MEDIT(std::ostream& os, + const T3& t3, + const NamedParameters& np = parameters::default_values()) { CGAL::Mesh_complex_3_in_triangulation_3 c3t3; c3t3.triangulation() = t3; c3t3.rescan_after_load_of_triangulation(); - output_to_medit(os, c3t3); + + using parameters::get_parameter; + using parameters::choose_parameter; + + bool rebind = choose_parameter(get_parameter(np, internal_np::rebind_labels), false);; + bool show_patches = choose_parameter(get_parameter(np, internal_np::show_patches), true); + bool all_c = choose_parameter(get_parameter(np, internal_np::all_cells), true); + bool all_v = all_c || choose_parameter(get_parameter(np, internal_np::all_vertices), true); + + output_to_medit(os, c3t3, rebind, show_patches, all_v, all_c); } +/** + * @ingroup PkgSMDS3IOFunctions + * @brief outputs a mesh complex to the medit (`.mesh`) file format. + * See \cgalCite{frey:inria-00069921} for a comprehensive description of this file format. + * @tparam T3 can be instantiated with any 3D triangulation of \cgal provided that its + * vertex and cell base class are models of the concepts `MeshVertexBase_3` and `MeshCellBase_3`, respectively. + * @tparam CornerIndex is the type of the indices for corners + * @tparam CurveIndex is the type of the indices for curves + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + + * @param os the output stream + * @param c3t3 the mesh complex + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{all_cells} + * \cgalParamDescription{If `true`, all the cells in `t3` are written in `os`, + * whether they belong to the complex or not. + * Otherwise, only the cells `c` for which + * `c->subdomain_index() != Subdomain_index()` are written.} + * \cgalParamType{Boolean} + * \cgalParamDefault{`true`} + * \cgalParamExtra{If the complex does not form a topological sphere, + * this parameter must be set to `true` for the file to be readable by `read_MEDIT()`. + * Otherwise the underlying triangulation data structure will not be valid.} + * \cgalParamNEnd + * + * \cgalParamNBegin{all_vertices} + * \cgalParamDescription{If `true`, all the vertices in `t3` are written in `os`. + * Otherwise, only the vertices that belong to a cell `c` for which + * `c->subdomain_index() != Subdomain_index()` are written} + * \cgalParamType{Boolean} + * \cgalParamDefault{`true`} + * \cgalParamExtra{If `all_cells` is `true`, the value of this parameter is ignored + and all vertices are written in `os`. If the complex does not + form a topological sphere, it must be + * set to `true` for the file to be readable by `read_MEDIT()`. + * Otherwise the underlying triangulation data structure will not be valid.} + * \cgalParamNEnd + * + * \cgalParamNBegin{rebind_labels} + * \cgalParamDescription{If `true`, labels of cells are rebinded into `[1..nb_of_labels]`} + * \cgalParamType{Boolean} + * \cgalParamDefault{`false`} + * \cgalParamNEnd + * + * \cgalParamNBegin{show_patches} + * \cgalParamDescription{If `true`, patches are labeled with different labels than + * cells. If `false`, each surface facet is written twice, + * using the label of each adjacent cell.} + * \cgalParamType{Boolean} + * \cgalParamDefault{`true`} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + * \see \ref IOStreamMedit + */ +template +void write_MEDIT(std::ostream& os, + const CGAL::Mesh_complex_3_in_triangulation_3& c3t3, + const NamedParameters& np = parameters::default_values()) +{ + return write_MEDIT(os, c3t3.triangulation(), np); +} + +/** + * @ingroup PkgSMDS3IOFunctions + * @brief reads a mesh complex written in the medit (`.mesh`) file format. + * See \cgalCite{frey:inria-00069921} for a comprehensive description of this file format. + * @tparam T3 can be instantiated with any 3D triangulation of \cgal provided that its + * vertex and cell base class are models of the concepts `MeshVertexBase_3` and `MeshCellBase_3`, + * respectively. + * + * @param in the input stream + * @param t3 the triangulation + * + * @returns `true` if the connectivity of the triangulation could be built consistently + * from \p in, + * and `false` if the triangulation is empty, or if the connectivity + * of \p t3 could not be built. + * If `false` is returned, \p t3 is empty when the function returns. + * + * This function reads the data about vertices, surface facets, and + * triangulation cells from `in`, and builds a valid `T3` from it. + * + * Note that a valid 3D triangulation of \cgal must have a valid + * data structure (see `TriangulationDataStructure_3 `), + * positively oriented cells, + * and cover the geometric convex hull of all points in `t3`. + */ template bool read_MEDIT(std::istream& in, T3& t3) { CGAL_assertion(!(!in)); - return CGAL::build_triangulation_from_file(in, t3); + bool b = CGAL::SMDS_3::build_triangulation_from_file(in, t3); + if(!b) + t3.clear(); + return b; } } // namespace IO diff --git a/Mesh_3/include/CGAL/IO/File_tetgen.h b/SMDS_3/include/CGAL/IO/File_tetgen.h similarity index 88% rename from Mesh_3/include/CGAL/IO/File_tetgen.h rename to SMDS_3/include/CGAL/IO/File_tetgen.h index 03fad2e7998..e35246a38a9 100644 --- a/Mesh_3/include/CGAL/IO/File_tetgen.h +++ b/SMDS_3/include/CGAL/IO/File_tetgen.h @@ -13,7 +13,7 @@ #ifndef CGAL_IO_FILE_TETGEN_H #define CGAL_IO_FILE_TETGEN_H -#include +#include #include #include @@ -25,7 +25,7 @@ namespace CGAL { -namespace Mesh_3 { +namespace SMDS_3 { template void @@ -185,10 +185,22 @@ output_to_tetgen(std::string filename, //------------------------------------------------------- } // end output_to_tetgen(...) -} // end namespace Mesh_3 +} // end namespace SMDS_3 namespace IO { + +/** + * \ingroup PkgSMDS3ExportFunctions + * @brief exports a mesh complex to tetgen format + * @param filename the path to the output files, without the extension. + * @param c3t3 the mesh complex + * @param rebind if true, labels of cells are rebinded into [1..nb_of_labels] + * @param show_patches if true, patches are labeled with different labels than + * cells. If false, each surface facet is written twice, using the label of + * each adjacent cell. + * \see \ref IOStreamTetgen + */ template void output_to_tetgen(std::string filename, @@ -199,16 +211,16 @@ output_to_tetgen(std::string filename, if ( rebind ) { if ( show_patches ) - Mesh_3::output_to_tetgen(filename,c3t3); + SMDS_3::output_to_tetgen(filename,c3t3); else - Mesh_3::output_to_tetgen(filename,c3t3); + SMDS_3::output_to_tetgen(filename,c3t3); } else { if ( show_patches ) - Mesh_3::output_to_tetgen(filename,c3t3); + SMDS_3::output_to_tetgen(filename,c3t3); else - Mesh_3::output_to_tetgen(filename,c3t3); + SMDS_3::output_to_tetgen(filename,c3t3); } } diff --git a/Mesh_3/include/CGAL/IO/facets_in_complex_3_to_triangle_mesh.h b/SMDS_3/include/CGAL/IO/facets_in_complex_3_to_triangle_mesh.h similarity index 94% rename from Mesh_3/include/CGAL/IO/facets_in_complex_3_to_triangle_mesh.h rename to SMDS_3/include/CGAL/IO/facets_in_complex_3_to_triangle_mesh.h index 84bc4f100f7..85819305e56 100644 --- a/Mesh_3/include/CGAL/IO/facets_in_complex_3_to_triangle_mesh.h +++ b/SMDS_3/include/CGAL/IO/facets_in_complex_3_to_triangle_mesh.h @@ -14,7 +14,7 @@ #ifndef CGAL_IO_FACETS_IN_COMPLEX_3_TO_TRIANGLE_MESH_H #define CGAL_IO_FACETS_IN_COMPLEX_3_TO_TRIANGLE_MESH_H -#include +#include #ifndef CGAL_NO_DEPRECATED_CODE #include diff --git a/Mesh_3/include/CGAL/IO/output_to_vtu.h b/SMDS_3/include/CGAL/IO/output_to_vtu.h similarity index 95% rename from Mesh_3/include/CGAL/IO/output_to_vtu.h rename to SMDS_3/include/CGAL/IO/output_to_vtu.h index d553ddfdfed..e78f1b680a2 100644 --- a/Mesh_3/include/CGAL/IO/output_to_vtu.h +++ b/SMDS_3/include/CGAL/IO/output_to_vtu.h @@ -14,7 +14,7 @@ #ifndef CGAL_OUTPUT_TO_VTU_H #define CGAL_OUTPUT_TO_VTU_H -#include +#include #include #include @@ -351,7 +351,19 @@ void output_to_vtu_with_attributes(std::ostream& os, } // namespace internal -//public API +//! \ingroup PkgSMDS3ExportFunctions +//! +//! \brief exports a tetrahedral mesh complex using the `UnstructuredGrid` XML format. +//! +//! \tparam C3T3 a model of `MeshComplexWithFeatures_3InTriangulation_3`. +//! +//! \param os the stream used for writing +//! \param c3t3 the mesh complex +//! \param mode decides if the data should be written in binary (`IO::BINARY`) +//! or in ASCII (`IO::ASCII`). +//! If the mode is binary, then the stream `os` must be opened in binary mode. +//! \see \ref IOStreamVTK +//! template void output_to_vtu(std::ostream& os, const C3T3& c3t3, diff --git a/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h b/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h new file mode 100644 index 00000000000..3ab95555707 --- /dev/null +++ b/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h @@ -0,0 +1,2100 @@ +// Copyright (c) 2009-2014 INRIA Sophia-Antipolis (France). +// Copyright (c) 2010-2013 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Stephane Tayeb, Clement Jamin +// +//****************************************************************************** +// File Description : +//****************************************************************************** + +#ifndef CGAL_MESH_COMPLEX_3_IN_TRIANGULATION_3_H +#define CGAL_MESH_COMPLEX_3_IN_TRIANGULATION_3_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +#ifdef CGAL_LINKED_WITH_TBB +#include +#include + +namespace CGAL { + template < class DSC, bool Const > + std::size_t tbb_hasher(const CGAL::internal::CC_iterator& it) + { + return CGAL::internal::hash_value(it); + } + + // As Marc Glisse pointed out the TBB hash of a std::pair is + // simplistic and leads to the + // TBB Warning: Performance is not optimal because the hash function + // produces bad randomness in lower bits in class + // tbb::interface5::concurrent_hash_map + template < class DSC, bool Const > + std::size_t tbb_hasher(const std::pair, + CGAL::internal::CC_iterator >& p) + { + return boost::hash, + CGAL::internal::CC_iterator > >()(p); + } + + struct Hash_compare_for_TBB { + template < class DSC, bool Const > + std::size_t hash(const std::pair, + CGAL::internal::CC_iterator >& p) const + { + return tbb_hasher(p); + } + template < class DSC, bool Const > + std::size_t operator()(const CGAL::internal::CC_iterator& it) + { + return CGAL::internal::hash_value(it); + } + template + bool equal(const T& v1, const T& v2) const { + return v1 == v2; + } + }; +}//end namespace CGAL +#endif + +namespace CGAL { + + namespace SMDS_3 { + + namespace details { + + template + class C3t3_helper_class + { + protected: + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Cell_handle Cell_handle; + typedef typename Tr::Facet Facet; + typedef typename Tr::Edge Edge; + + typedef std::pair Pair_of_vertices; + + // computes and returns an ordered pair of Vertex + Pair_of_vertices + make_ordered_pair(const Vertex_handle vh1, const Vertex_handle vh2) const { + if (vh1 < vh2) { + return std::make_pair(vh1, vh2); + } + else { + return std::make_pair(vh2, vh1); + } + } + // same from an Edge + Pair_of_vertices + make_ordered_pair(const Edge e) const { + return make_ordered_pair(e.first->vertex(e.second), + e.first->vertex(e.third)); + } + Facet canonical_facet(Cell_handle c, int i) const { + Cell_handle c2 = c->neighbor(i); + return (c2 < c) ? std::make_pair(c2, c2->index(c)) : std::make_pair(c, i); + } + }; // end class template C3t3_helper_class + + } // end namespace SMDS_3::details + } //end namesapce SMDS_3 + +/*! + \ingroup PkgSMDS3Classes + + \brief A data structure to represent and maintain a 3D complex embedded + in a 3D triangulation. + + The class `Mesh_complex_3_in_triangulation_3` implements a data structure + to store the 3D restricted Delaunay triangulation used by a mesh + generation process. + + This class is a model of the concept + `MeshComplexWithFeatures_3InTriangulation_3`. + + \tparam Tr can be instantiated with any 3D + triangulation of \cgal provided that its + vertex and cell base class are models of the concepts + `SimplicialMeshVertexBase_3` and `SimplicialMeshCellBase_3`, respectively. + + \tparam CornerIndex Type of indices for corners (i.e.\f$ 0\f$--dimensional features) + of the discretized geometric domain. + It must be a model of `CopyConstructible`, `Assignable`, `DefaultConstructible` and + `LessThanComparable`. + It must match the `Corner_index` of the model + of the `MeshDomainWithFeatures_3` concept when used for mesh generation. + + \tparam CurveIndex Type of indices for curves (i.e. \f$ 1\f$-dimensional features) + of the discretized geometric domain. + It must be a model of `CopyConstructible`, `Assignable`, `DefaultConstructible` and + `LessThanComparable`. The default constructed value must be the value for an edge which + does not approximate a 1-dimensional feature of the geometric domain. + It must match the `Curve_index` types of the model + of the `MeshDomainWithFeatures_3` concept when used for mesh generation. + + Those two last template parameters default to `int`, so that they can be ignored + if the domain used for mesh generation does not include 0 and 1-dimensionnal features (i.e + is only a model of the concept `MeshDomain_3`). + + \cgalModels `MeshComplexWithFeatures_3InTriangulation_3` + + \sa \link make_mesh_3() `CGAL::make_mesh_3()`\endlink + \sa \link refine_mesh_3() `CGAL::refine_mesh_3()`\endlink + \sa `MeshComplex_3InTriangulation_3` + \sa `MeshComplexWithFeatures_3InTriangulation_3` + \sa `SimplicialMeshCellBase_3`, + \sa `SimplicialMeshVertexBase_3` + +*/ +template +class Mesh_complex_3_in_triangulation_3 +#ifndef DOXYGEN_RUNNING + : public CGAL::SMDS_3::details::C3t3_helper_class + , public CGAL::SMDS_3::internal::Debug_messages_tools +#endif +{ +public: + typedef typename Tr::Concurrency_tag Concurrency_tag; + +private: + typedef Mesh_complex_3_in_triangulation_3< + Tr,CornerIndex,CurveIndex> Self; + typedef SMDS_3::details::C3t3_helper_class Base; + typedef CGAL::Hash_handles_with_or_without_timestamps Hash_fct; + +public: + +#ifndef CGAL_NO_DEPRECATED_CODE + typedef CurveIndex Curve_segment_index; +#endif + +/// \name Types +/// @{ + typedef Tr Triangulation; + typedef typename Tr::size_type size_type; + typedef typename Tr::Point Point; + typedef typename Tr::Edge Edge; + typedef typename Tr::Facet Facet; + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Cell_handle Cell_handle; + /*! + Index type. + */ + typedef typename Tr::Vertex::Index Index; + /*! + Surface index type. + */ + typedef typename Tr::Cell::Surface_patch_index Surface_patch_index; + /*! + Subdomain index type. + */ + typedef typename Tr::Cell::Subdomain_index Subdomain_index; + /*! + Corner index type. + */ + typedef CornerIndex Corner_index; + /*! + Curve index type. + */ + typedef CurveIndex Curve_index; +/// @} + + +private: + // Type to store the edges: + // - a set of std::pair (ordered at insertion) + // - which allows fast lookup from one Vertex_handle + // - each element of the set has an associated info (Curve_index) value + typedef boost::bimaps::bimap< + boost::bimaps::multiset_of, + boost::bimaps::multiset_of, + boost::bimaps::set_of_relation<>, + boost::bimaps::with_info > Edge_map; + + typedef typename Edge_map::value_type Internal_edge; + + // Type to store the corners + typedef boost::unordered_map Corner_map; + + // Type to store far vertices + typedef std::vector Far_vertices_vec; + +public: + enum Face_status { + NOT_IN_COMPLEX = 0, + ISOLATED = 1, // - An ISOLATED edge is a marked edge, + // without any incident facets. + BOUNDARY, // - An edge is on BOUNDARY if it has only + // one incident facet. + // - A vertex is on BOUNDARY if all its + // incident edges are REGULAR or on + // BOUNDARY, at least one is on + // BOUNDARY, and the incident facets + // form only one connected component. + REGULAR, // - A facet that is in the complex is + // REGULAR. + // - An edge is REGULAR if it has + // exactly two incident facets. + // - A vertex is REGULAR if all it + // incident edges are REGULAR, and the + // incident facets form only one + // connected component. + SINGULAR // - SINGULAR is for all other cases. + }; + +/// \name Creation +/// @{ + /** + * @brief Constructor + * builds an empty 3D complex. + */ + Mesh_complex_3_in_triangulation_3(); + /** + * Copy constructor + */ + Mesh_complex_3_in_triangulation_3(const Self& rhs); + + /** + * Move constructor + */ + Mesh_complex_3_in_triangulation_3(Self&& rhs); + + /** + * Assignement operator, also serves as move-assignement + */ + Self& operator=(Self rhs) + { + swap(rhs); + return *this; + } + + /** + * swaps `this` and `rhs` + */ + void swap(Self& rhs) + { + Swap_elements swapper; + swapper(rhs.number_of_facets_, number_of_facets_); + tr_.swap(rhs.tr_); + swapper(rhs.number_of_cells_, number_of_cells_); + + edges_.swap(rhs.edges_); + corners_.swap(rhs.corners_); + far_vertices_.swap(rhs.far_vertices_); + } + +/// @} + +/// \name Access Functions +/// @{ + /// returns a const reference to the triangulation + const Triangulation& triangulation() const { return tr_; } +/// @} + +/// \name Non const access +/// @{ + /// returns a reference to the triangulation + Triangulation& triangulation() { return tr_; } +/// @} + + +/// \name Modifiers +/// @{ + /** + * clears data of the complex + */ + void clear() + { + number_of_cells_ = 0; + number_of_facets_ = 0; + clear_manifold_info(); + tr_.clear(); + edges_.clear(); + corners_.clear(); + far_vertices_.clear(); + } + + /** adds cell \p cell to the 3D complex, with subdomain index \p index + */ + void add_to_complex(const Cell_handle& cell, const Subdomain_index& index) + { + CGAL_precondition(!(index == Subdomain_index())); + + if (!is_in_complex(cell)) + { + set_subdomain_index(cell, index); + ++number_of_cells_; + } + } + /** adds facet \p facet to the 2D complex, with surface index \p index + */ + void add_to_complex(const Facet& facet, const Surface_patch_index& index) + { + add_to_complex(facet.first, facet.second, index); + } + /** adds facet(\p cell, \p i) to the 2D complex, with surface index \p index + */ + void add_to_complex(const Cell_handle& cell, + const int i, + const Surface_patch_index& index); + + /** adds edge \p e to complex, with curve index \p index + */ + void add_to_complex(const Edge& e, + const Curve_index& index) + { + add_to_complex(e.first->vertex(e.second), + e.first->vertex(e.third), + index); + } + + /** + * adds edge (\p v1, \p v2) to the 1D complex, with `Curve_index` \p index + */ + void add_to_complex(const Vertex_handle& v1, + const Vertex_handle& v2, + const Curve_index& index) + { + add_to_complex(make_internal_edge(v1,v2), index); + } + + /** + * marks vertex \p v as a corner of the complex + */ + void add_to_complex(const Vertex_handle& v, const Corner_index& index) + { + v->set_dimension(0); + corners_.insert(std::make_pair(v,index)); + } + + /** removes cell \p cell from the 3D complex + */ + void remove_from_complex(const Cell_handle& cell) + { + if (is_in_complex(cell)) + { + set_subdomain_index(cell, Subdomain_index()); + --number_of_cells_; + } + } + /** removes facet \p facet from the 2D complex + */ + void remove_from_complex(const Facet& facet); + + /** removes facet(\p cell, \p i) from the 2D complex + */ + void remove_from_complex(const Cell_handle& c, const int i) { + remove_from_complex(Facet(c, i)); + } + /** + * removes edge \p e from the 1D complex + */ + void remove_from_complex(const Edge& e) + { + remove_from_complex(e.first->vertex(e.second), e.first->vertex(e.third)); + } + + /** + * removes edge (v1,v2) from the 1D complex + */ + void remove_from_complex(const Vertex_handle& v1, const Vertex_handle& v2) + { + remove_from_complex(make_internal_edge(v1,v2)); + } + + /** + * removes vertex \p v from the complex + */ + void remove_from_complex(const Vertex_handle& v) + { + corners_.erase(v); + v->set_dimension(-1); + } + + /** sets the index of vertex \p vertex to \p index + */ + void set_index(const Vertex_handle& vertex, const Index& index) const + { + vertex->set_index(index); + } + /** sets the surface index of facet \p facet to \p index + */ + void set_surface_patch_index(const Facet& f, const Surface_patch_index& index) + { + set_surface_patch_index(f.first, f.second, index); + } + /** sets the surface index of facet(\p cell, \p i) to \p index + */ + void set_surface_patch_index(const Cell_handle& cell, + const int i, + const Surface_patch_index& index) const + { + cell->set_surface_patch_index(i, index); + } + /** sets the subdomain index of cell \p cell to \p index + */ + void set_subdomain_index(const Cell_handle& cell, + const Subdomain_index& index) const + { + cell->set_subdomain_index(index); + } + /** sets the dimension of vertex \p vertex to \p dimension + */ + void set_dimension(const Vertex_handle& vertex, int dimension) const + { + vertex->set_dimension(dimension); + } +/// @} + +/// \name Queries on the identifier of the face complex including triangulation cells, facets, and vertices. +/// @{ + /** returns the index of vertex \p v + */ + Index index(const Vertex_handle& v) const { return v->index(); } + + /** returns the subdomain index of cell \p cell + */ + Subdomain_index subdomain_index(const Cell_handle& cell) const + { + return cell->subdomain_index(); + } + /** returns the surface index of facet \p f + */ + Surface_patch_index surface_patch_index(const Facet& f) const + { + return surface_patch_index(f.first, f.second); + } + + /** returns the surface index of facet(\p cell, \p i) + */ + Surface_patch_index surface_patch_index(const Cell_handle& cell, + const int i) const + { + return cell->surface_patch_index(i); + } + /** returns the dimension of the lowest dimensional face of the input 3D + * complex that contains the vertex + */ + int in_dimension(const Vertex_handle& v) const { return v->in_dimension(); } + + /** + * returns the curve index of edge \p e + */ + Curve_index curve_index(const Edge& e) const + { + return curve_index(e.first->vertex(e.second), + e.first->vertex(e.third)); + } + + /** + * returns the curve index of the edge formed by \p v1 and \p v2 + */ + Curve_index curve_index(const Vertex_handle& v1, + const Vertex_handle& v2) const + { + return curve_index(make_internal_edge(v1, v2)); + } + + /** + * returns the corner index of vertex \p v + */ + Corner_index corner_index(const Vertex_handle& v) const + { + typename Corner_map::const_iterator it = corners_.find(v); + if (corners_.end() != it) { return it->second; } + return Corner_index(); + } +/// @} + +#ifndef CGAL_NO_DEPRECATED_CODE + CGAL_DEPRECATED + Curve_index curve_segment_index(const Edge& e) const + { + return curve_index(e); + } + + CGAL_DEPRECATED + Curve_index curve_segment_index(const Vertex_handle& v1, + const Vertex_handle& v2) const + { + return curve_index(v1, v2); + } +#endif // CGAL_NO_DEPRECATED_CODE + + std::size_t number_of_far_points() const + { + return far_vertices_.size(); + } + + void add_far_point(const Point &p) + { + far_vertices_.push_back(triangulation().insert(p)); + } + + void add_far_point(Vertex_handle vh) + { + far_vertices_.push_back(vh); + } + + + void remove_isolated_vertex(Vertex_handle v) + { + Triangulation& tr = triangulation(); + + std::vector new_cells; + new_cells.reserve(32); + tr.remove_and_give_new_cells(v, std::back_inserter(new_cells)); + + typename std::vector::iterator nc_it = new_cells.begin(); + typename std::vector::iterator nc_it_end = new_cells.end(); + for (; nc_it != nc_it_end; ++nc_it) + { + Cell_handle c = *nc_it; + for (int i = 0; i < 4; ++i) + { + Facet mirror_facet = tr.mirror_facet(std::make_pair(c, i)); + if (is_in_complex(mirror_facet)) + { + set_surface_patch_index(c, i, + surface_patch_index(mirror_facet)); + c->set_facet_surface_center(i, + mirror_facet.first->get_facet_surface_center(mirror_facet.second)); + } + } + /*int i_inf; + if (c->has_vertex(tr.infinite_vertex(), i_inf)) + { + Facet mirror_facet = tr.mirror_facet(std::make_pair(c, i_inf)); + if (is_in_complex(mirror_facet)) + { + set_surface_patch_index(c, i_inf, + surface_patch_index(mirror_facet)); + } + }*/ + } + } + + void remove_far_points() + { + //triangulation().remove(far_vertices_.begin(), far_vertices_.end()); + typename Far_vertices_vec::const_iterator it = far_vertices_.begin(); + typename Far_vertices_vec::const_iterator it_end = far_vertices_.end(); + for (; it != it_end; ++it) + { + remove_isolated_vertex(*it); + } + far_vertices_.clear(); + } + + /*! + The tetrahedral mesh generation algorithm implemented in + \link make_mesh_3() `CGAL::make_mesh_3()`\endlink + and \link refine_mesh_3() `CGAL::refine_mesh_3()`\endlink + does not guarantee that all the points inserted + by the algorithm are actually present in the final mesh. + + In most cases, all points are used, but if the geometry of the object + has small features compared to the size of the simplices (triangles and tetrahedra), + it might be that the Delaunay facets that are selected in the restricted Delaunay + triangulation miss some vertices of the triangulation. + The concurrent version of the tetrahedral mesh generation algorithm + also inserts a small set of auxiliary vertices that belong to the triangulation + but are isolated from the complex at the end of the meshing process. + + This function removes these so-called \em isolated vertices, that belong to the + triangulation but not to any cell of the `C3T3`, from the triangulation. + */ + void remove_isolated_vertices() + { + Triangulation& tr = triangulation(); + for (Vertex_handle v : tr.finite_vertex_handles()) + v->set_meshing_info(0); + + for (Cell_handle c : this->cells_in_complex()) + { + for (int i = 0; i < 4; ++i) + { + Vertex_handle vi = c->vertex(i); + vi->set_meshing_info(vi->meshing_info() + 1); + } + } + + for (Facet f :this->facets_in_complex()) + { + for (int i = 1; i < 4; ++i) + { + Vertex_handle vi = f.first->vertex((f.second + i) % 4); + vi->set_meshing_info(vi->meshing_info() + 1); + } + } + + std::vector isolated; + for (Vertex_handle v : tr.finite_vertex_handles()) + { + if (v->meshing_info() == 0.) + isolated.push_back(v); + } + +#ifdef CGAL_MESH_3_VERBOSE + std::cout << "Remove " << isolated.size() << " isolated vertices..."; + std::cout.flush(); +#endif + + CGAL_assertion(far_vertices_.size() <= isolated.size()); + far_vertices_.clear(); + + for (Vertex_handle v : isolated) + remove_isolated_vertex(v); + +#ifdef CGAL_MESH_3_VERBOSE + std::cout << "\nRemove " << isolated.size() << " isolated vertices done." << std::endl; +#endif + } + + void rescan_after_load_of_triangulation(); + +/// \name Queries on the faces of the embedded complex +/// @{ + /** + * returns the number of cells which belong to the 3D complex + */ + size_type number_of_cells_in_complex() const { return number_of_cells_; } + /** + * returns the number of cells which belong to the 3D complex + */ + size_type number_of_cells() const + { + return number_of_cells_in_complex(); + } + /** + * returns the number of surface facets of the complex + */ + size_type number_of_facets_in_complex() const { return number_of_facets_; } + /** + * returns the number of surface facets of the complex + */ + size_type number_of_facets() const + { + return number_of_facets_in_complex(); + } + /** + * returns the number of edges of the complex + */ + size_type number_of_edges_in_complex() const + { + return edges_.size(); + } + /** + * returns the number of edges of the complex + */ + size_type number_of_edges() const + { + return edges_.size(); + } + /** + * returns the number of corners of the complex + */ + size_type number_of_vertices_in_complex() const + { + return corners_.size(); + } + /** + * returns the number of corners of the complex + */ + size_type number_of_corners() const + { + return corners_.size(); + } + /** + * returns \c true if cell \p cell belongs to the 3D complex + */ + bool is_in_complex(const Cell_handle& cell) const + { + return !(subdomain_index(cell) == Subdomain_index()); + } + /** returns true if facet \p facet belongs to the 2D complex + */ + bool is_in_complex(const Facet& facet) const + { + return is_in_complex(facet.first, facet.second); + } + + /** returns true if facet (\p cell, \p i) belongs to the 2D complex + */ + bool is_in_complex(const Cell_handle& cell, const int i) const + { + return (cell->is_facet_on_surface(i)); + } + /** + * returns true if edge \p e belongs to the 1D complex + */ + bool is_in_complex(const Edge& e) const + { + return is_in_complex(e.first->vertex(e.second), e.first->vertex(e.third)); + } + + /** + * returns true if edge (v1,v2) belongs to the 1D complex + */ + bool is_in_complex(const Vertex_handle& v1, const Vertex_handle& v2) const + { + return is_in_complex(make_internal_edge(v1,v2)); + } + + /** + * returns true if \p v is a 0-dimensionnal feature in the complex + */ + bool is_in_complex(const Vertex_handle& v) const + { + return (corners_.find(v) != corners_.end()); + } +/// @} + + + /// \name I/O Functions + /// @{ + /** + * outputs the outer boundary of the entire domain, with facets oriented outward. + */ + std::ostream& output_boundary_to_off(std::ostream& out) const + { + internal::output_boundary_of_c3t3_to_off(*this, 0, out, false); + return out; + } + + /** + * outputs the outer boundary of the selected subdomain, with facets oriented outward. + */ + std::ostream& output_boundary_to_off(std::ostream& out, Subdomain_index subdomain) const + { + output_boundary_of_c3t3_to_off(*this, subdomain, out); + return out; + } + + /** + * outputs the surface facets, with a consistent orientation at the interface of two subdomains. + */ + std::ostream& output_facets_in_complex_to_off(std::ostream& out) const + { + internal::output_facets_in_complex_to_off(*this, out); + return out; + } + + /*! + outputs the mesh to `os` + in Medit format. + */ +#ifdef DOXYGEN_RUNNING + void output_to_medit(std::ostream& os) const +#else + void output_to_medit(std::ostream& os, + bool rebind = true, + bool show_patches = false) const +#endif + { + // Call global function + bool all_vertices = true; + bool all_cells = false; + CGAL::IO::output_to_medit(os, *this, rebind, show_patches, + all_vertices, all_cells); + } + + void output_to_maya(std::ostream& os, bool surfaceOnly = true) const + { + // Call global function + CGAL::IO::output_to_maya(os, *this, surfaceOnly); + } + + /// @} + + /** + * fills \p out with incident edges (1-dimensional features of \p v). + * OutputIterator value type is std::pair + * \pre v->in_dimension() < 2 + */ + template + OutputIterator + adjacent_vertices_in_complex(const Vertex_handle& v, OutputIterator out) const; + + // ----------------------------------- + // Undocumented + // ----------------------------------- + + bool is_valid(bool verbose = false) const; + + // ----------------------------------- + // Complex traversal + // ----------------------------------- +private: + /** + * @class Cell_not_in_complex + * @brief A class to filter cells which do not belong to the complex + */ + class Cell_not_in_complex + { + const Self* r_self_; + Subdomain_index index_;//needed by SWIG, should be const Subdomain_index + public: + Cell_not_in_complex() {}//needed by SWIG + Cell_not_in_complex(const Self& self, + const Subdomain_index& index = Subdomain_index()) + : r_self_(&self) + , index_(index) { } + + bool operator()(Cell_handle ch) const + { + if (index_ == Subdomain_index()) { return !r_self_->is_in_complex(ch); } + else { return !(r_self_->subdomain_index(ch) == index_); } + } + }; // end class Cell_not_in_complex + + typedef SMDS_3::internal::Iterator_not_in_complex Iterator_not_in_complex; + + class Facet_iterator_not_in_complex + { + const Self* c3t3_; + Surface_patch_index index_; //need by SWIG: should be const Surface_patch_index + public: + Facet_iterator_not_in_complex() {} //need by SWIG + Facet_iterator_not_in_complex(const Self& c3t3, + const Surface_patch_index& index = Surface_patch_index()) + : c3t3_(&c3t3) + , index_(index) { } + + template + bool operator()(Iterator it) const + { + if (index_ == Surface_patch_index()) { return !c3t3_->is_in_complex(*it); } + else { return !(c3t3_->surface_patch_index(*it) == index_); } + } + }; + + class Edge_iterator_not_in_complex + { + const Self& c3t3_; + const Curve_index index_; + public: + Edge_iterator_not_in_complex(const Self& c3t3, + const Curve_index& index = Curve_index()) + : c3t3_(c3t3) + , index_(index) { } + + template + bool operator()(Iterator it) const + { + if ( index_ == Curve_index() ) { return ! c3t3_.is_in_complex(*it); } + else { return c3t3_.curve_index(*it) != index_; } + } + }; + + class Vertex_iterator_not_in_complex + { + const Self& c3t3_; + const Corner_index index_; + public: + Vertex_iterator_not_in_complex(const Self& c3t3, + const Corner_index& index = Corner_index()) + : c3t3_(c3t3) + , index_(index) { } + + template + bool operator()(const ItMap it) const + { + if ( index_ == Corner_index() ) { return false; } + else { return it->second != index_; } + } + }; + + // Filtered iterator + typedef Filter_iterator< + typename Corner_map::const_iterator, + Vertex_iterator_not_in_complex > Vertex_map_filter_iterator; + + // Iterator type to get the first element of pair + typedef boost::transform_iterator < + SMDS_3::internal::First_of, + Vertex_map_filter_iterator > Vertex_map_iterator_first; + + // Iterator type to remove a level of referencing + class Vertex_map_iterator_first_dereference + : public boost::iterator_adaptor < + Vertex_map_iterator_first_dereference, + Vertex_map_iterator_first, + typename Vertex_map_iterator_first::value_type::value_type, + boost::use_default, + typename Vertex_map_iterator_first::value_type::reference > + { + typedef Vertex_map_iterator_first_dereference Self; + typedef boost::iterator_adaptor < + Vertex_map_iterator_first_dereference, + Vertex_map_iterator_first, + typename Vertex_map_iterator_first::value_type::value_type, + boost::use_default, + typename Vertex_map_iterator_first::value_type::reference > iterator_adaptor_; + public: + typedef typename Vertex_map_iterator_first::reference pointer; + typedef typename iterator_adaptor_::reference reference; + + Vertex_map_iterator_first_dereference() : Self::iterator_adaptor_() { } + + template < typename Iterator > + Vertex_map_iterator_first_dereference(Iterator i) + : Self::iterator_adaptor_(typename Self::iterator_adaptor_::base_type(i)) + { } + + pointer operator->() const { return *(this->base()); } + reference operator*() const { return **(this->base()); } + + operator Vertex_handle() { return Vertex_handle(*(this->base())); } + }; + +public: +/// \name Traversal of the complex +/// @{ +#ifdef DOXYGEN_RUNNING + /// Iterator type to visit the cells of the 3D complex + typedef unspecified_type Cells_in_complex_iterator; + /// Iterator type to visit the facets of the 2D complex + typedef unspecified_type Facets_in_complex_iterator; + /// Iterator type to visit the edges of the 1D complex + typedef unspecified_type Edges_in_complex_iterator; + /// Iterator type to visit the vertices of the 0D complex + typedef unspecified_type Vertices_in_complex_iterator; + + /// Range type for iterating over all cells of the 3D complex, + /// with a nested type iterator that has as value type `Cell_handle`. + typedef Iterator_range Cells_in_complex; + /// Range type for iterating over all facets of the 2D complex, + /// with a nested type iterator that has as value type `Facet`. + typedef Iterator_range Facets_in_complex; + /// Range type for iterating over all cells of the 1D complex, + /// with a nested type iterator that has as value type `Edge`. + typedef Iterator_range Edges_in_complex; + /// Range type for iterating over all vertices of the 0D complex, + /// with a nested type iterator that has as value type `Vertex_handle`. + typedef Iterator_range Vertices_in_complex; + +#else + typedef Filter_iterator< + typename Triangulation::Finite_edges_iterator, + Edge_iterator_not_in_complex > Edges_in_complex_iterator; + typedef Vertex_map_iterator_first_dereference Vertices_in_complex_iterator; + typedef Filter_iterator< + typename Triangulation::Finite_facets_iterator, + Facet_iterator_not_in_complex > Facets_in_complex_iterator; + + /** + * @class Cells_in_complex_iterator + * @brief Iterator type to visit the cells of the triangulation that belong + * to the 3D complex + * + * This class is useful to ensure that Cells_in_complex_iterator is convertible + * to Cell_handle + */ + class Cells_in_complex_iterator : + public Filter_iterator + { + private: + typedef typename Triangulation::Finite_cells_iterator Tr_iterator; + typedef Filter_iterator Base; + typedef Cells_in_complex_iterator Self; + + public: + Cells_in_complex_iterator() : Base() { } + Cells_in_complex_iterator(Base i) : Base(i) { } + + Self& operator++() { Base::operator++(); return *this; } + Self& operator--() { Base::operator--(); return *this; } + Self operator++(int) { Self tmp(*this); ++(*this); return tmp; } + Self operator--(int) { Self tmp(*this); --(*this); return tmp; } + + operator Cell_handle() const { return Cell_handle(this->base()); } + }; // end class Cells_in_complex_iterator + + typedef Iterator_range > Vertices_in_complex; + typedef Iterator_range Edges_in_complex; + typedef Iterator_range Facets_in_complex; + typedef Iterator_range > Cells_in_complex; + +#endif + +/// \name Iterators +/// @{ + + /// returns a \c Cells_in_complex_iterator to the first cell of the 3D complex + Cells_in_complex_iterator cells_in_complex_begin() const + { + return CGAL::filter_iterator(tr_.finite_cells_end(), + Cell_not_in_complex(*this), + tr_.finite_cells_begin()); + } + + /// returns a \c Cells_in_complex_iterator to the first cell of the 3D complex + Cells_in_complex_iterator cells_in_complex_begin(const Subdomain_index& index) const + { + return CGAL::filter_iterator(tr_.finite_cells_end(), + Cell_not_in_complex(*this, index), + tr_.finite_cells_begin()); + } + + /// returns the past-the-end iterator for the cells of the 3D complex + Cells_in_complex_iterator cells_in_complex_end() const + { + return CGAL::filter_iterator(tr_.finite_cells_end(), + Cell_not_in_complex(*this)); + } + + /// returns a `Facets_in_complex_iterator` to the first facet of the 2D complex + Facets_in_complex_iterator facets_in_complex_begin() const + { + return CGAL::filter_iterator(tr_.finite_facets_end(), + Facet_iterator_not_in_complex(*this), + tr_.finite_facets_begin()); + } + + /// returns a `Facets_in_complex_iterator` to the first facet of the 2D complex + Facets_in_complex_iterator + facets_in_complex_begin(const Surface_patch_index& index) const + { + return CGAL::filter_iterator(tr_.finite_facets_end(), + Facet_iterator_not_in_complex(*this, index), + tr_.finite_facets_begin()); + } + + /// returns past-the-end iterator on facet of the 2D complex + Facets_in_complex_iterator facets_in_complex_end(const Surface_patch_index = Surface_patch_index()) const + { + return CGAL::filter_iterator(tr_.finite_facets_end(), + Facet_iterator_not_in_complex(*this)); + } + + /// returns a `Edges_in_complex_iterator` to the first edge of the 1D complex + Edges_in_complex_iterator edges_in_complex_begin() const + { + return CGAL::filter_iterator(this->triangulation().finite_edges_end(), + Edge_iterator_not_in_complex(*this), + this->triangulation().finite_edges_begin()); + } + + /// returns a `Edges_in_complex_iterator` to the first edge of the 1D complex + Edges_in_complex_iterator + edges_in_complex_begin(const Curve_index& index) const + { + return CGAL::filter_iterator(this->triangulation().finite_edges_end(), + Edge_iterator_not_in_complex(*this,index), + this->triangulation().finite_edges_begin()); + } + + /// returns past-the-end iterator on edges of the 1D complex + Edges_in_complex_iterator edges_in_complex_end(const Curve_index& = Curve_index()) const + { + return CGAL::filter_iterator(this->triangulation().finite_edges_end(), + Edge_iterator_not_in_complex(*this)); + } + + /// returns a `Vertices_in_complex_iterator` to the first vertex of the 0D complex + Vertices_in_complex_iterator vertices_in_complex_begin() const + { + return CGAL::filter_iterator(corners_.end(), + Vertex_iterator_not_in_complex(*this), + corners_.begin()); + } + + /// returns a `Vertices_in_complex_iterator` to the first vertex of the 0D complex + Vertices_in_complex_iterator + vertices_in_complex_begin(const Corner_index& index) const + { + return CGAL::filter_iterator(corners_.end(), + Vertex_iterator_not_in_complex(*this,index), + corners_.begin()); + } + + /// returns past-the-end iterator on vertices of the 0D complex + Vertices_in_complex_iterator vertices_in_complex_end() const + { + return CGAL::filter_iterator(corners_.end(), + Vertex_iterator_not_in_complex(*this)); + } + + /*! + returns a range of iterators over vertices of the 0D complex + \note The value type of `Vertices_in_complex::iterator` is `Vertex_handle`. + */ + Vertices_in_complex vertices_in_complex() const + { + return make_prevent_deref_range(vertices_in_complex_begin(), + vertices_in_complex_end()); + } + /*! + returns a range of iterators over the edges of the 1D complex, + starting at an arbitrary edge. + Returns an empty range when `t.dimension() < 2`. + */ + Edges_in_complex edges_in_complex() const + { + return Edges_in_complex(edges_in_complex_begin(), + edges_in_complex_end()); + } + /*! + returns a range of iterators over the facets of the 2D complex, + starting at an arbitrary facet. + Returns an empty range when `t.dimension() < 2`. + */ + Facets_in_complex facets_in_complex() const + { + return Facets_in_complex(facets_in_complex_begin(), + facets_in_complex_end()); + } + /*! + returns a range of iterators over cells of the 3D complex. + Returns an empty range when `triangulation().number_of_cells() == 0` + or complex is empty. + \note The value type of `Cells_in_complex::iterator` is `Cell_handle`. + */ + Cells_in_complex cells_in_complex() const + { + return make_prevent_deref_range(cells_in_complex_begin(), + cells_in_complex_end()); + } +/// @} + +public: + template + friend + std::istream& operator>>(std::istream& is, + Mesh_complex_3_in_triangulation_3& c3t3); + + static std::string io_signature() + { + return Get_io_signature()(); + } + + /** + * @cond SKIP_IN_MANUAL + * creates an `Internal_edge` object (i.e a pair of ordered `Vertex_handle`) + * @endcond + */ + Internal_edge make_internal_edge(const Vertex_handle& v1, + const Vertex_handle& v2) const + { + if ( v1 < v2 ) { return Internal_edge(v1,v2); } + else { return Internal_edge(v2,v1); } + } + + /** + * @cond SKIP_IN_MANUAL + * returns true if \p edge is in the 1D complex + * @endcond + */ + bool is_in_complex(const Internal_edge& edge) const + { + return (curve_index(edge) != Curve_index() ); + } + + /** + * @cond SKIP_IN_MANUAL + * adds edge \p edge to the 1D complex, with curve index `index` + * @endcond + */ + void add_to_complex(const Internal_edge& edge, const Curve_index& index) + { + CGAL_precondition(!is_in_complex(edge)); +#if CGAL_MESH_3_PROTECTION_DEBUG & 1 + std::cerr << "Add edge ( " << disp_vert(edge.left) + << " , " << disp_vert(edge.right) << " ), curve_index=" << index + << " to c3t3.\n"; +#endif // CGAL_MESH_3_PROTECTION_DEBUG + std::pair it = edges_.insert(edge); + it.first->info = index; + } + + /** + * @cond SKIP_IN_MANUAL + * removes edge \p edge from the 1D complex + * @endcond + */ + void remove_from_complex(const Internal_edge& edge) + { + edges_.erase(edge); + } + + /** + * @cond SKIP_IN_MANUAL + * returns the curve index of edge \p edge + * @endcond + */ + Curve_index curve_index(const Internal_edge& edge) const + { + typename Edge_map::const_iterator it = edges_.find(edge); + if ( edges_.end() != it ) { return it->info; } + return Curve_index(); + } + + /// @cond SKIP_IN_MANUAL + /// Returns `NOT_IN_COMPLEX`, `BOUNDARY`, `REGULAR`, or `SINGULAR`, + /// depending on the number of incident facets in the complex, and the + /// number of connected components of its link + /// @endcond + Face_status face_status(const Vertex_handle v) const + { + if (!manifold_info_initialized_) init_manifold_info(); + const std::size_t n = v->cached_number_of_incident_facets(); + + if (n == 0) return NOT_IN_COMPLEX; + + //test incident edges for REGULARITY and count BOUNDARY edges + typename std::vector edges; + edges.reserve(64); + if (tr_.is_parallel()) { + tr_.incident_edges_threadsafe(v, std::back_inserter(edges)); + } + else { + tr_.incident_edges(v, std::back_inserter(edges)); + } + int number_of_boundary_incident_edges = 0; // could be a bool + for (typename std::vector::iterator + eit = edges.begin(), end = edges.end(); + eit != end; eit++) + { + switch (face_status(*eit)) + { + case NOT_IN_COMPLEX: case REGULAR: break; + case BOUNDARY: ++number_of_boundary_incident_edges; break; + default: +#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS + std::cerr << "singular edge...\n"; + std::cerr << tr_.point(v) << std::endl; +#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS + return SINGULAR; + } + } + + // From here all incident edges (in complex) are REGULAR or BOUNDARY. + const std::size_t nb_components = union_find_of_incident_facets(v); + if (nb_components > 1) { +#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS + std::cerr << "singular vertex: nb_components=" << nb_components << std::endl; + std::cerr << tr_.point(v) << std::endl; +#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS + return SINGULAR; + } + else { // REGULAR OR BOUNDARY +#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS + std::cerr << "regular or boundary: " << tr_.point(v) << std::endl; +#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS + if (number_of_boundary_incident_edges != 0) + return BOUNDARY; + else + return REGULAR; + } + } + + /// @cond SKIP_IN_MANUAL + /// This function should be called only when incident edges + /// are known to be `REGULAR` or `BOUNDARY` + /// @endcond + bool is_regular_or_boundary_for_vertices(Vertex_handle v) const { + return union_find_of_incident_facets(v) == 1; + } + + /// @cond SKIP_IN_MANUAL + /// Returns `NOT_IN_COMPLEX`, `BOUNDARY`, `REGULAR`, or `SINGULAR`, + /// depending on the number of incident facets in the complex + /// @endcond + Face_status face_status(const Edge& edge) const + { + if (!manifold_info_initialized_) init_manifold_info(); + +#ifdef CGAL_LINKED_WITH_TBB + typename Edge_facet_counter::const_accessor accessor; + if (!edge_facet_counter_.find(accessor, + this->make_ordered_pair(edge))) + return NOT_IN_COMPLEX; + switch (accessor->second) +#else // not CGAL_LINKED_WITH_TBB + switch (edge_facet_counter_[this->make_ordered_pair(edge)]) +#endif // not CGAL_LINKED_WITH_TBB + { + case 0: return NOT_IN_COMPLEX; + case 1: return BOUNDARY; + case 2: return REGULAR; + default: return SINGULAR; + } + } + + /// Returns true if the vertex \p v has is incident to at least a facet + /// of the complex + bool has_incident_facets_in_complex(const Vertex_handle& v) const + { + if (!manifold_info_initialized_) init_manifold_info(); + return v->cached_number_of_incident_facets() > 0; + } + + /** + * @cond SKIP_IN_MANUAL + * @brief inserts \p [first,last[ in the triangulation (with dimension 2) + * @param first the iterator on the first point to insert + * @param last the iterator past the last point to insert + * + * InputIterator value type must be \c std::pair + * @endcond + */ + template + void insert_surface_points(InputIterator first, InputIterator last) + { + typename Tr::Geom_traits::Construct_weighted_point_3 cwp = + tr_.geom_traits().construct_weighted_point_3_object(); + + while (first != last) + { + Vertex_handle vertex = tr_.insert(cwp((*first).first)); + vertex->set_index((*first).second); + vertex->set_dimension(2); + ++first; + } + } + + /** + * @cond SKIP_IN_MANUAL + * @brief inserts \p [first,last[ in the triangulation (with dimension 2 and + * index \p default_index) + * @param first the iterator on the first point to insert + * @param last the iterator past the last point to insert + * @param default_index the index to be used to insert points + * + * InputIterator value type must be \c Tr::Point + * @endcond + */ + template + void insert_surface_points(InputIterator first, + InputIterator last, + const Index& default_index) + { + typename Tr::Geom_traits::Construct_weighted_point_3 cwp = + tr_.geom_traits().construct_weighted_point_3_object(); + + while (first != last) + { + Vertex_handle vertex = tr_.insert(cwp(*first)); + vertex->set_index(default_index); + vertex->set_dimension(2); + ++first; + } + } + + void clear_cells_and_facets_from_c3t3() { + for (typename Tr::Finite_cells_iterator + cit = this->triangulation().finite_cells_begin(), + end = this->triangulation().finite_cells_end(); + cit != end; ++cit) + { + set_subdomain_index(cit, Subdomain_index()); + } + this->number_of_cells_ = 0; + for (typename Tr::Finite_facets_iterator + fit = this->triangulation().finite_facets_begin(), + end = this->triangulation().finite_facets_end(); + fit != end; ++fit) + { + Facet facet = *fit; + set_surface_patch_index(facet.first, facet.second, Surface_patch_index()); + if (this->triangulation().dimension() > 2) { + Facet mirror = tr_.mirror_facet(facet); + set_surface_patch_index(mirror.first, mirror.second, Surface_patch_index()); + } + } + this->number_of_facets_ = 0; + clear_manifold_info(); + } + + void clear_manifold_info() { + edge_facet_counter_.clear(); + manifold_info_initialized_ = false; + } + + /** @cond SKIP_IN_MANUAL + * Returns bbox + * @endcond + */ + Bbox_3 bbox() const; + +private: + // Sequential: non-atomic + // "dummy" is here to allow the specialization (see below) + // See http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/285ab1eec49e1cb6 + template + struct Number_of_elements + { + typedef size_type type; + }; + + template + struct Init_number_of_elements + { + template + void operator()(T& a, const T& b) + { + a = b; + } + template + void operator()(T& a) + { + a = 0; + } + }; + + template + struct Swap_elements + { + template + void operator()(T& a, T& b) + { + std::swap(a, b); + } + }; +#ifdef CGAL_LINKED_WITH_TBB + // Parallel: atomic + template + struct Number_of_elements + { + typedef std::atomic type; + }; + + template + struct Init_number_of_elements + { + template + void operator()(T& a, const T& b) + { + a = b.load(); + } + template + void operator()(T& a) + { + a = 0; + } + }; + + template + struct Swap_elements + { + template + void operator()(T& a, T& b) + { + T tmp; + tmp.exchange(a); + a.exchange(b); + b.exchange(tmp); + } + }; +#endif // CGAL_LINKED_WITH_TBB + +private: + void init_manifold_info() const + { + for (typename Tr::All_vertices_iterator + vit = triangulation().finite_vertices_begin(), + end = triangulation().finite_vertices_end(); + vit != end; ++vit) + { + vit->set_c2t3_cache(0, (std::numeric_limits::max)()); + } + + edge_facet_counter_.clear(); + + for (typename Tr::Finite_facets_iterator + fit = triangulation().finite_facets_begin(), + end = triangulation().finite_facets_end(); + fit != end; ++fit) + { + if (is_in_complex(*fit)) { + const Cell_handle cell = fit->first; + const int i = fit->second; + for (int j = 0; j < 3; ++j) + { + const int edge_index_va = tr_.vertex_triple_index(i, j); + const int edge_index_vb = tr_.vertex_triple_index(i, (j == 2) ? 0 : (j + 1)); + const Vertex_handle edge_va = cell->vertex(edge_index_va); + const Vertex_handle edge_vb = cell->vertex(edge_index_vb); +#ifndef CGAL_LINKED_WITH_TBB + ++edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)]; +#else // CGAL_LINKED_WITH_TBB + { + typename Edge_facet_counter::accessor accessor; + edge_facet_counter_.insert(accessor, + this->make_ordered_pair(edge_va, edge_vb)); + ++accessor->second; + } +#endif // CGAL_LINKED_WITH_TBB + + const std::size_t n = edge_va->cached_number_of_incident_facets(); + edge_va->set_c2t3_cache(n + 1, (std::numeric_limits::max)()); + } + } + } + manifold_info_initialized_ = true; + } + + /// Extract the subset `F` of facets of the complex incident to `v` and + /// return the number of connected component of the adjacency graph of `F`. + std::size_t union_find_of_incident_facets(const Vertex_handle v) const + { + if (v->is_c2t3_cache_valid()) + { + const std::size_t n = v->cached_number_of_components(); + if (n != (std::numeric_limits::max)()) return n; + } + + Union_find facets; + { // fill the union find + std::vector non_filtered_facets; + if (tr_.is_parallel()) { + tr_.incident_facets_threadsafe(v, std::back_inserter(non_filtered_facets)); + } + else { + tr_.incident_facets(v, std::back_inserter(non_filtered_facets)); + } + + for (typename std::vector::iterator + fit = non_filtered_facets.begin(), + end = non_filtered_facets.end(); + fit != end; ++fit) + { + if (is_in_complex(*fit)) facets.push_back(*fit); + } + } + + typedef boost::unordered_map::handle, + Hash_fct> Vertex_set_map; + typedef typename Vertex_set_map::iterator Vertex_set_map_iterator; + + Vertex_set_map vsmap; + + for (typename Union_find::iterator + it = facets.begin(), end = facets.end(); + it != end; ++it) + { + const Cell_handle& ch = (*it).first; + const int& i = (*it).second; + for (int j = 0; j < 3; ++j) { + const Vertex_handle w = ch->vertex(tr_.vertex_triple_index(i, j)); + if (w != v) { + Vertex_set_map_iterator vsm_it = vsmap.find(w); + if (vsm_it != vsmap.end()) { + facets.unify_sets(vsm_it->second, it); + } + else { + vsmap.insert(std::make_pair(w, it)); + } + } + } + } + const std::size_t nb_components = facets.number_of_sets(); + + const std::size_t n = v->cached_number_of_incident_facets(); + v->set_c2t3_cache(n, nb_components); + return nb_components; + } + +public: + // ----------------------------------- + // Backward Compatibility + // ----------------------------------- +#ifndef DOXYGEN_RUNNING +#ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX + typedef Surface_patch_index Surface_index; + + void set_surface_index(const Facet& f, const Surface_index& index) + { + set_surface_patch_index(f, index); + } + + void set_surface_index(const Cell_handle& c, const int i, const Surface_index& index) + { + set_surface_patch_index(c, i, index); + } + + Surface_index surface_index(const Facet& f) const + { + return surface_patch_index(f); + } + + Surface_index surface_index(const Cell_handle& c, const int i) const + { + return surface_patch_index(c, i); + } +#endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX + +#ifndef CGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS + typedef Facets_in_complex_iterator Facet_iterator; + typedef Cells_in_complex_iterator Cell_iterator; + + Facet_iterator facets_begin() const + { + return facets_in_complex_begin(); + } + + Facet_iterator facets_end() const + { + return facets_in_complex_end(); + } + + Cell_iterator cells_begin() const + { + return cells_in_complex_begin(); + } + + Cell_iterator cells_end() const + { + return cells_in_complex_end(); + } +#endif // CGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS +#endif // DOXYGEN_RUNNING + // ----------------------------------- + // End backward Compatibility + // ----------------------------------- + + +private: + // Private data members + Triangulation tr_; + + typedef typename Base::Pair_of_vertices Pair_of_vertices; +#ifdef CGAL_LINKED_WITH_TBB + typedef tbb::concurrent_hash_map Edge_facet_counter; +#else // not CGAL_LINKED_WITH_TBB + typedef std::map Edge_facet_counter; +#endif // not CGAL_LINKED_WITH_TBB + + mutable Edge_facet_counter edge_facet_counter_; + + typename Number_of_elements::type number_of_facets_; + typename Number_of_elements::type number_of_cells_; + + mutable bool manifold_info_initialized_; + + Edge_map edges_; + Corner_map corners_; + Far_vertices_vec far_vertices_; +}; + +template +Mesh_complex_3_in_triangulation_3:: +Mesh_complex_3_in_triangulation_3() + : Base() + , tr_() + , edge_facet_counter_() //TODO: parallel! + , manifold_info_initialized_(false) //TODO: parallel! +{ + // We don't put it in the initialization list because + // std::atomic has no contructors + number_of_facets_ = 0; + number_of_cells_ = 0; +} + +template +Mesh_complex_3_in_triangulation_3:: +Mesh_complex_3_in_triangulation_3(const Self& rhs) + : Base(rhs) + , tr_(rhs.tr_) + , edge_facet_counter_(rhs.edge_facet_counter_) + , manifold_info_initialized_(rhs.manifold_info_initialized_) + , edges_() + , corners_() +{ + Init_number_of_elements init; + init(number_of_facets_, rhs.number_of_facets_); + init(number_of_cells_, rhs.number_of_cells_); + + // Copy edges + for ( typename Edge_map::const_iterator it = rhs.edges_.begin(), + end = rhs.edges_.end() ; it != end ; ++it ) + { + const Vertex_handle& va = it->right; + const Vertex_handle& vb = it->left; + + Vertex_handle new_va; + this->triangulation().is_vertex(rhs.triangulation().point(va), new_va); + + Vertex_handle new_vb; + this->triangulation().is_vertex(rhs.triangulation().point(vb), new_vb); + + this->add_to_complex(make_internal_edge(new_va,new_vb), it->info); + } + + // Copy corners + for ( typename Corner_map::const_iterator it = rhs.corners_.begin(), + end = rhs.corners_.end() ; it != end ; ++it ) + { + Vertex_handle new_v; + this->triangulation().is_vertex(rhs.triangulation().point(it->first), new_v); + this->add_to_complex(new_v, it->second); + } + + // Parse vertices to identify far vertices + if (rhs.far_vertices_.size() > 0) + { + Triangulation &tr = triangulation(); + typename Tr::Finite_vertices_iterator vit = tr.finite_vertices_begin(); + for(typename Tr::Finite_vertices_iterator end = tr.finite_vertices_end(); + vit != end ; ++vit) + { + if (vit->in_dimension() == -1) + far_vertices_.push_back(vit); + } + CGAL_assertion(far_vertices_.size() == rhs.far_vertices_.size()); + } +} + +template +Mesh_complex_3_in_triangulation_3:: +Mesh_complex_3_in_triangulation_3(Self&& rhs) + : Base() + , tr_(std::move(rhs.tr_)) + , edge_facet_counter_(std::move(rhs.edge_facet_counter_)) + , manifold_info_initialized_(std::exchange(rhs.manifold_info_initialized_, false)) + , edges_(std::move(rhs.edges_)) + , corners_(std::move(rhs.corners_)) + , far_vertices_(std::move(rhs.far_vertices_)) +{ + Init_number_of_elements init; + init(number_of_facets_, rhs.number_of_facets_); + init(number_of_cells_, rhs.number_of_cells_); + init(rhs.number_of_facets_); // set to 0 + init(rhs.number_of_cells_); // set to 0 +} + +template +template +OutputIterator +Mesh_complex_3_in_triangulation_3:: +adjacent_vertices_in_complex(const Vertex_handle& v, OutputIterator out) const +{ + CGAL_precondition(v->in_dimension() < 2); + + typedef typename Edge_map::right_const_iterator Rcit; + typedef typename Edge_map::left_const_iterator Lcit; + + // Add edges containing v is on the left + std::pair range_right = edges_.right.equal_range(v); + for ( Rcit rit = range_right.first ; rit != range_right.second ; ++rit ) + { + *out++ = std::make_pair(rit->second, rit->info); + } + + // Add edges containing v on the right + std::pair range_left = edges_.left.equal_range(v); + for ( Lcit lit = range_left.first ; lit != range_left.second ; ++lit ) + { + *out++ = std::make_pair(lit->second, lit->info); + } + + return out; +} + + +template +bool +Mesh_complex_3_in_triangulation_3:: +is_valid(bool verbose) const +{ + typedef typename Tr::Weighted_point Weighted_point; + typedef boost::unordered_map Vertex_map; + + Vertex_map vertex_map; + + // Fill map counting neighbor number for each vertex of an edge + for ( typename Edge_map::const_iterator it = edges_.begin(), + end = edges_.end() ; it != end ; ++it ) + { + const Vertex_handle& v1 = it->right; + if ( vertex_map.find(v1) == vertex_map.end() ) { vertex_map[v1] = 1; } + else { vertex_map[v1] += 1; } + + const Vertex_handle& v2 = it->left; + if ( vertex_map.find(v2) == vertex_map.end() ) { vertex_map[v2] = 1; } + else { vertex_map[v2] += 1; } + } + + // Verify that each vertex has 2 neighbors if it's not a corner + for ( typename Vertex_map::iterator vit = vertex_map.begin(), + vend = vertex_map.end() ; vit != vend ; ++vit ) + { + if ( vit->first->in_dimension() != 0 && vit->second != 2 ) + { + if(verbose) + std::cerr << "Validity error: vertex " << (void*)(&*vit->first) + << " (" << this->triangulation().point(vit->first) << ") " + << "is not a corner (dimension " << vit->first->in_dimension() + << ") but has " << vit->second << " neighbor(s)!\n"; + return false; + } + } + + // Verify that balls of each edge intersect + for ( typename Edge_map::const_iterator it = edges_.begin(), + end = edges_.end() ; it != end ; ++it ) + { + typename Tr::Geom_traits::Compute_weight_3 cw = + this->triangulation().geom_traits().compute_weight_3_object(); + typename Tr::Geom_traits::Construct_point_3 cp = + this->triangulation().geom_traits().construct_point_3_object(); + typename Tr::Geom_traits::Construct_sphere_3 sphere = + this->triangulation().geom_traits().construct_sphere_3_object(); + typename Tr::Geom_traits::Do_intersect_3 do_intersect = + this->triangulation().geom_traits().do_intersect_3_object(); + + const Weighted_point& itrwp = this->triangulation().point(it->right); + const Weighted_point& itlwp = this->triangulation().point(it->left); + + if ( ! do_intersect(sphere(cp(itrwp), cw(itrwp)), sphere(cp(itlwp), cw(itlwp))) ) + { + std::cerr << "Points p[" << disp_vert(it->right) << "], dim=" << it->right->in_dimension() + << " and q[" << disp_vert(it->left) << "], dim=" << it->left->in_dimension() + << " form an edge but do not intersect !\n"; + return false; + } + } + + return true; +} + +template +void +Mesh_complex_3_in_triangulation_3:: +add_to_complex(const Cell_handle& cell, + const int i, + const Surface_patch_index& index) +{ + CGAL_precondition(!(index == Surface_patch_index())); + + if (!is_in_complex(cell, i)) + { + Facet mirror = tr_.mirror_facet(std::make_pair(cell, i)); + set_surface_patch_index(cell, i, index); + set_surface_patch_index(mirror.first, mirror.second, index); + ++number_of_facets_; + if (manifold_info_initialized_) { + for (int j = 0; j < 3; ++j) + { + int edge_index_va = tr_.vertex_triple_index(i, j); + int edge_index_vb = tr_.vertex_triple_index(i, (j == 2) ? 0 : (j + 1)); + Vertex_handle edge_va = cell->vertex(edge_index_va); + Vertex_handle edge_vb = cell->vertex(edge_index_vb); +#ifdef CGAL_LINKED_WITH_TBB + { + typename Edge_facet_counter::accessor accessor; + edge_facet_counter_.insert(accessor, + this->make_ordered_pair(edge_va, edge_vb)); + ++accessor->second; + } +#else // not CGAL_LINKED_WITH_TBB + ++edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)]; +#endif // not CGAL_LINKED_WITH_TBB + + const std::size_t n = edge_va->cached_number_of_incident_facets(); + const std::size_t m = edge_va->cached_number_of_components(); + edge_va->set_c2t3_cache(n + 1, m); + } + const int dimension_plus_1 = tr_.dimension() + 1; + // update c2t3 for vertices of f + for (int j = 0; j < dimension_plus_1; j++) { + if (j != i) { +#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS + if (cell->vertex(j)->is_c2t3_cache_valid()) + std::cerr << "(" << tr_.point(cell, j) << ")->invalidate_c2t3_cache()\n"; +#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS + cell->vertex(j)->invalidate_c2t3_cache(); + } + } + } + } +} + +template +void +Mesh_complex_3_in_triangulation_3:: +remove_from_complex(const Facet& facet) +{ + if (is_in_complex(facet)) + { + Facet mirror = tr_.mirror_facet(facet); + set_surface_patch_index(facet.first, facet.second, Surface_patch_index()); + set_surface_patch_index(mirror.first, mirror.second, Surface_patch_index()); + --number_of_facets_; + if (manifold_info_initialized_) { + const Cell_handle cell = facet.first; + const int i = facet.second; + for (int j = 0; j < 3; ++j) + { + const int edge_index_va = tr_.vertex_triple_index(i, j); + const int edge_index_vb = tr_.vertex_triple_index(i, (j == 2) ? 0 : (j + 1)); + const Vertex_handle edge_va = cell->vertex(edge_index_va); + const Vertex_handle edge_vb = cell->vertex(edge_index_vb); +#ifdef CGAL_LINKED_WITH_TBB + { + typename Edge_facet_counter::accessor accessor; + edge_facet_counter_.insert(accessor, + this->make_ordered_pair(edge_va, edge_vb)); + --accessor->second; + } +#else // not CGAL_LINKED_WITH_TBB + --edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)]; +#endif // not CGAL_LINKED_WITH_TBB + + const std::size_t n = edge_va->cached_number_of_incident_facets(); + CGAL_assertion(n > 0); + const std::size_t m = edge_va->cached_number_of_components(); + edge_va->set_c2t3_cache(n - 1, m); + } + const int dimension_plus_1 = tr_.dimension() + 1; + // update c2t3 for vertices of f + for (int j = 0; j < dimension_plus_1; j++) { + if (j != facet.second) { +#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS + if (cell->vertex(j)->is_c2t3_cache_valid()) + std::cerr << "(" << tr_.point(cell, j) << ")->invalidate_c2t3_cache()\n"; +#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS + cell->vertex(j)->invalidate_c2t3_cache(); + } + } + } + } +} + +template +Bbox_3 +Mesh_complex_3_in_triangulation_3:: +bbox() const +{ + if (0 == triangulation().number_of_vertices()) + { + return Bbox_3(); + } + + typename Tr::Finite_vertices_iterator vit = tr_.finite_vertices_begin(); + Bbox_3 result = tr_.point(vit++).bbox(); + + for (typename Tr::Finite_vertices_iterator end = tr_.finite_vertices_end(); + vit != end; ++vit) + { + result = result + tr_.point(vit).bbox(); + } + + return result; +} + +template +void +Mesh_complex_3_in_triangulation_3:: +rescan_after_load_of_triangulation() +{ + corners_.clear(); + for(typename Tr::Finite_vertices_iterator + vit = this->triangulation().finite_vertices_begin(), + end = this->triangulation().finite_vertices_end(); + vit != end; ++vit) + { + if ( vit->in_dimension() == 0 ) { + add_to_complex(vit, Corner_index(1)); + } + } + + this->number_of_facets_ = 0; + for (typename Tr::Finite_facets_iterator + fit = this->triangulation().finite_facets_begin(), + end = this->triangulation().finite_facets_end(); + fit != end; ++fit) + { + if (this->is_in_complex(*fit)) { + ++this->number_of_facets_; + } + } + + this->number_of_cells_ = 0; + for (typename Tr::Finite_cells_iterator + cit = this->triangulation().finite_cells_begin(), + end = this->triangulation().finite_cells_end(); + cit != end; ++cit) + { + if (this->is_in_complex(cit)) { + ++this->number_of_cells_; + } + } +} + +template +std::ostream & +operator<< (std::ostream& os, + const Mesh_complex_3_in_triangulation_3 &c3t3) +{ + // TODO: implement edge saving + return os << c3t3.triangulation(); +} + + +template +std::istream & +operator>> (std::istream& is, + Mesh_complex_3_in_triangulation_3 &c3t3) +{ + // TODO: implement edge loading + c3t3.clear(); + is >> c3t3.triangulation(); + + if (!is) { + c3t3.clear(); + return is; + } + + c3t3.rescan_after_load_of_triangulation(); + return is; +} + +} //namespace CGAL + +#include + +#endif // CGAL_MESH_COMPLEX_3_IN_TRIANGULATION_3_H diff --git a/SMDS_3/include/CGAL/SMDS_3/Dump_c3t3.h b/SMDS_3/include/CGAL/SMDS_3/Dump_c3t3.h new file mode 100644 index 00000000000..ebb78341db1 --- /dev/null +++ b/SMDS_3/include/CGAL/SMDS_3/Dump_c3t3.h @@ -0,0 +1,137 @@ +// Copyright (c) 2012 GeometryFactory Sarl (France) +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Laurent Rineau + +#ifndef CGAL_SMDS_3_DUMP_C3T3_H +#define CGAL_SMDS_3_DUMP_C3T3_H + +#include + +#include + +#include +#include + +#include + +#include +#include + +namespace CGAL { + +template ::value && + is_streamable::value + && + (is_streamable::value || + Output_rep::is_specialized) + && + (is_streamable::value || + Output_rep::is_specialized) + > +struct Dump_c3t3 { + void dump_c3t3(const C3t3& c3t3, std::string prefix) const + { + std::clog<<"======dump c3t3===== to: " << prefix << std::endl; + std::ofstream medit_file((prefix+".mesh").c_str()); + medit_file.precision(17); + CGAL::IO::output_to_medit(medit_file, c3t3, false /*rebind*/, true /*show_patches*/); + medit_file.close(); + + std::string bin_filename = prefix; + bin_filename += ".binary.cgal"; + std::ofstream bin_file(bin_filename.c_str(), + std::ios_base::binary | std::ios_base::out); + std::string signature = CGAL::Get_io_signature()(); + CGAL_assertion(signature != std::string()); + bin_file << "binary CGAL c3t3 " << signature << "\n"; + CGAL::IO::set_binary_mode(bin_file); + bin_file << c3t3; + } +}; // end struct template Dump_c3t3 + +template +struct Dump_c3t3 +{ + void dump_c3t3(const C3t3&, std::string) { + std::cerr << "Warning " << __FILE__ << ":" << __LINE__ << "\n" + << " the c3t3 object of following type:\n" + << typeid(C3t3).name() << std::endl + << " cannot be dumped because some types are not streamable:\n"; + if(!is_streamable::value) { + std::cerr << " - C3t3::Triangulation::Vertex is not streamble\n"; + std::cerr << " " + << typeid(typename C3t3::Triangulation::Vertex).name() + << "\n"; + } + + if(!is_streamable::value) { + std::cerr << " - C3t3::Triangulation::Cell is not streamble\n"; + std::cerr << " " + << typeid(typename C3t3::Triangulation::Cell).name() + << "\n"; + } + + if(!is_streamable::value && + !CGAL::Output_rep::is_specialized) + { + std::cerr << " - C3t3::Surface_patch_index is not streamable\n"; + std::cerr << " " + << typeid(typename C3t3::Surface_patch_index).name() + << "\n"; + } + if(!is_streamable::value && + !CGAL::Output_rep::is_specialized) + { + std::cerr << " - C3t3::Subdomain_index is not streamable\n"; + std::cerr << " " + << typeid(typename C3t3::Subdomain_index).name() + << "\n"; + } + } +}; // end struct template specialization Dump_c3t3 + +template +void dump_c3t3_edges(const C3t3& c3t3, std::string prefix) +{ + typename C3t3::Triangulation::Geom_traits::Construct_point_3 cp = + c3t3.triangulation().geom_traits().construct_point_3_object(); + + std::ofstream file((prefix+".polylines.txt").c_str()); + file.precision(17); + for(typename C3t3::Edges_in_complex_iterator + edge_it = c3t3.edges_in_complex_begin(), + end = c3t3.edges_in_complex_end(); + edge_it != end; ++edge_it) + { + const typename C3t3::Triangulation::Cell_handle c = edge_it->first; + const int i = edge_it->second; + const int j = edge_it->third; + const typename C3t3::Triangulation::Weighted_point& ei = c3t3.triangulation().point(c, i); + const typename C3t3::Triangulation::Weighted_point& ej = c3t3.triangulation().point(c, j); + file << "2 " << cp(ei) << " " << cp(ej) << "\n"; + } +} +template +void dump_c3t3(const C3t3& c3t3, std::string prefix) +{ + if(!prefix.empty()) { + Dump_c3t3 dump; + dump.dump_c3t3(c3t3, prefix); + } +} + +} // end namespace CGAL + +#include + +#endif // CGAL_SMDS_3_DUMP_C3T3_H diff --git a/Mesh_3/include/CGAL/Mesh_3/Has_features.h b/SMDS_3/include/CGAL/SMDS_3/Has_features.h similarity index 96% rename from Mesh_3/include/CGAL/Mesh_3/Has_features.h rename to SMDS_3/include/CGAL/SMDS_3/Has_features.h index 94d9b02de4b..e2c322fc0f6 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Has_features.h +++ b/SMDS_3/include/CGAL/SMDS_3/Has_features.h @@ -13,7 +13,7 @@ #ifndef CGAL_MESH_3_HAS_FEATURES_H #define CGAL_MESH_3_HAS_FEATURES_H -#include +#include #include diff --git a/Mesh_3/include/CGAL/Mesh_3/internal/Boundary_of_subdomain_of_complex_3_in_triangulation_3_to_off.h b/SMDS_3/include/CGAL/SMDS_3/internal/Boundary_of_subdomain_of_complex_3_in_triangulation_3_to_off.h similarity index 81% rename from Mesh_3/include/CGAL/Mesh_3/internal/Boundary_of_subdomain_of_complex_3_in_triangulation_3_to_off.h rename to SMDS_3/include/CGAL/SMDS_3/internal/Boundary_of_subdomain_of_complex_3_in_triangulation_3_to_off.h index 93f5b70d430..77b0d8b0004 100644 --- a/Mesh_3/include/CGAL/Mesh_3/internal/Boundary_of_subdomain_of_complex_3_in_triangulation_3_to_off.h +++ b/SMDS_3/include/CGAL/SMDS_3/internal/Boundary_of_subdomain_of_complex_3_in_triangulation_3_to_off.h @@ -12,7 +12,7 @@ #ifndef CGAL_INTERNAL_MESH_3_BOUNDARY_OF_SUDDOMAIN_OF_COMPLEX_3_IN_TRIANGULATION_3_TO_OFF_H #define CGAL_INTERNAL_MESH_3_BOUNDARY_OF_SUDDOMAIN_OF_COMPLEX_3_IN_TRIANGULATION_3_TO_OFF_H -#include +#include #include @@ -58,11 +58,14 @@ output_boundary_of_c3t3_to_off(const C3T3& c3t3, { typedef typename C3T3::Triangulation::Geom_traits::Point_3 Point; typedef std::vector Face; + typedef typename C3T3::Surface_patch_index Surface_patch_index; std::vector points; std::vector faces; + std::vector patches; - CGAL::Mesh_3::internal::facets_in_complex_3_to_triangle_soup(c3t3, sd_index, points, faces, normals_point_outside_of_the_subdomain); + CGAL::SMDS_3::internal::facets_in_complex_3_to_triangle_soup(c3t3, sd_index, points, faces, + patches, normals_point_outside_of_the_subdomain); return output_polygon_soup_to_off(points, faces, out); } @@ -73,12 +76,14 @@ output_facets_in_complex_to_off(const C3T3& c3t3, std::ostream& out) { typedef typename C3T3::Triangulation::Geom_traits::Point_3 Point; + typedef typename C3T3::Surface_patch_index Surface_patch_index; typedef std::vector Face; std::vector points; std::vector faces; + std::vector patches; - CGAL::Mesh_3::internal::facets_in_complex_3_to_triangle_soup(c3t3, points, faces); + CGAL::SMDS_3::internal::facets_in_complex_3_to_triangle_soup(c3t3, points, faces, patches); return output_polygon_soup_to_off(points, faces, out); } diff --git a/Mesh_3/include/CGAL/Mesh_3/internal/Handle_IO_for_pair_of_int.h b/SMDS_3/include/CGAL/SMDS_3/internal/Handle_IO_for_pair_of_int.h similarity index 97% rename from Mesh_3/include/CGAL/Mesh_3/internal/Handle_IO_for_pair_of_int.h rename to SMDS_3/include/CGAL/SMDS_3/internal/Handle_IO_for_pair_of_int.h index b8b9c0c6182..cd3c8f135a9 100644 --- a/Mesh_3/include/CGAL/Mesh_3/internal/Handle_IO_for_pair_of_int.h +++ b/SMDS_3/include/CGAL/SMDS_3/internal/Handle_IO_for_pair_of_int.h @@ -13,12 +13,12 @@ #ifndef CGAL_INTERNAL_MESH_3_INTERNAL_HANDLE_IO_FOR_PAIR_OF_INT_H #define CGAL_INTERNAL_MESH_3_INTERNAL_HANDLE_IO_FOR_PAIR_OF_INT_H -#include +#include #include #include -#include +#include #include #include #include diff --git a/SMDS_3/include/CGAL/SMDS_3/internal/SMDS_3_helper.h b/SMDS_3/include/CGAL/SMDS_3/internal/SMDS_3_helper.h new file mode 100644 index 00000000000..86a631dd5cf --- /dev/null +++ b/SMDS_3/include/CGAL/SMDS_3/internal/SMDS_3_helper.h @@ -0,0 +1,68 @@ +// Copyright (c) 2021 GeometryFactory +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Jane Tournois + +#ifndef CGAL_INTERNAL_SMDS_3_HELPERS_H +#define CGAL_INTERNAL_SMDS_3_HELPERS_H + +#include + +#include + +#include +#include + +namespace CGAL { +namespace SMDS_3 { +namespace internal { + + template + bool is_convex(const Triangulation& tr) + { + typedef typename Triangulation::Vertex_handle Vertex_handle; + typedef typename Triangulation::Cell_handle Cell_handle; + typedef typename Triangulation::Geom_traits::Point_3 Point_3; + typename Triangulation::Geom_traits::Construct_point_3 cp + = tr.geom_traits().construct_point_3_object(); + typename Triangulation::Geom_traits::Orientation_3 orientation = + tr.geom_traits().orientation_3_object(); + + std::vector infcells; + tr.incident_cells(tr.infinite_vertex(), std::back_inserter(infcells)); + for (Cell_handle c : infcells) + { + const Cell_handle neigh = c->neighbor(c->index(tr.infinite_vertex())); + const int i = neigh->index(c); + + const std::array pfacet = { cp(neigh->vertex((i + 1) % 4)->point()), + cp(neigh->vertex((i + 2) % 4)->point()), + cp(neigh->vertex((i + 3) % 4)->point())}; + const CGAL::Orientation o = orientation( + pfacet[0], pfacet[1], pfacet[2], cp(neigh->vertex(i)->point())); + + for (Vertex_handle v : tr.finite_vertex_handles()) + { + if (c->has_vertex(v)) + continue; + if (o != orientation(pfacet[0], pfacet[1], pfacet[2], + cp(neigh->vertex(i)->point()))) + return false; + } + } + + return true; + } + +} // end namespace internal +} // end namespace SMDS_3 +} // end namespace CGAL + +#endif // CGAL_INTERNAL_SMDS_3_HELPERS_H diff --git a/Mesh_3/include/CGAL/Mesh_3/internal/indices_management.h b/SMDS_3/include/CGAL/SMDS_3/internal/indices_management.h similarity index 99% rename from Mesh_3/include/CGAL/Mesh_3/internal/indices_management.h rename to SMDS_3/include/CGAL/SMDS_3/internal/indices_management.h index a4b05a9cc61..b98528cace4 100644 --- a/Mesh_3/include/CGAL/Mesh_3/internal/indices_management.h +++ b/SMDS_3/include/CGAL/SMDS_3/internal/indices_management.h @@ -18,7 +18,7 @@ #ifndef CGAL_INTERNAL_MESH_3_INDICES_MANAGEMENT_H #define CGAL_INTERNAL_MESH_3_INDICES_MANAGEMENT_H -#include +#include #include @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/SMDS_3/include/CGAL/SMDS_3/io_signature.h b/SMDS_3/include/CGAL/SMDS_3/io_signature.h new file mode 100644 index 00000000000..ba50d850123 --- /dev/null +++ b/SMDS_3/include/CGAL/SMDS_3/io_signature.h @@ -0,0 +1,363 @@ +// Copyright (c) 2006 INRIA Sophia-Antipolis (France). +// Copyright (c) 2011 GeometryFactory Sarl (France) +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Laurent RINEAU + +#ifndef CGAL_SMDS_3_IO_SIGNATURE_H +#define CGAL_SMDS_3_IO_SIGNATURE_H + +#include + +#define CGAL_MESH_3_IO_H // the old include macro, tested by other files + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CGAL_PERIODIC_3_MESH_3_CONFIG_H +#include +#include +#endif + +#include +#include +#include + +namespace CGAL { + +// SFINAE test +template +class has_io_signature +{ +private: + template struct helper; + template static char check(helper<&V::io_signature> *); + template static char (&check(...))[2]; + +public: + enum { value = (sizeof(check(0)) == sizeof(char)) }; +}; + +template +struct Get_io_signature_aux +{ + std::string operator() () const + { + return T::io_signature(); + } +}; // end struct template Get_io_signature_aux + +template +struct Get_io_signature_aux +{ + std::string operator()() const + { + std::cerr << "Type without signature: " << typeid(T).name() << std::endl; + return std::string(); + } +}; // end template partial specialization Get_io_signature_aux + + +template +struct Get_io_signature + : public Get_io_signature_aux< + T, + (has_io_signature::value || + has_io_signature::value || + has_io_signature::value ) // signature for + // static mem func + > +{ +}; + +template <> +struct Get_io_signature +{ + std::string operator()() { + return "i"; + } +}; + +template <> +struct Get_io_signature +{ + std::string operator()() { + return "ui"; + } +}; + +template <> +struct Get_io_signature +{ + std::string operator()() { + return "c"; + } +}; + +template <> +struct Get_io_signature +{ + std::string operator()() { + return "uc"; + } +}; + +template <> +struct Get_io_signature +{ + std::string operator()() { + return "sc"; + } +}; + +template <> +struct Get_io_signature +{ + std::string operator()() { + return "s"; + } +}; + +template <> +struct Get_io_signature +{ + std::string operator()() { + return "us"; + } +}; + +template <> +struct Get_io_signature +{ + std::string operator()() { + return "d"; + } +}; + +template +struct Get_io_signature > +{ + std::string operator()() { + return std::string("boost::variant<") + + Get_io_signature()() + "," + + Get_io_signature()() + ">"; + } +}; + +template +struct Get_io_signature > +{ + std::string operator()() { + return std::string("std::pair<") + + Get_io_signature()() + "," + + Get_io_signature()() + ">"; + } +}; + +template +struct Get_io_signature > +{ + std::string operator()() { + return std::string("std::pair<") + + Get_io_signature()() + "," + + Get_io_signature()() + ">"; + } +}; + +template +struct Get_io_signature > +{ + std::string operator()() { + return std::string("boost::variant<") + + Get_io_signature()() + "," + + Get_io_signature()() + "," + + Get_io_signature()() + ">"; + } +}; + +template +struct Get_io_signature > +{ + std::string operator()() { + return std::string("boost::variant<") + + Get_io_signature()() + "," + + Get_io_signature()() + "," + + Get_io_signature()() + "," + + Get_io_signature()() + ">"; + } +}; + +template +struct Get_io_signature > +{ + std::string operator()() { + return "Point_3"; + } +}; + +template +struct Get_io_signature > +{ + std::string operator()() { + return std::string("Weighted_point<") + Get_io_signature >()() + ">"; + } +}; + +#ifdef CGAL_TRIANGULATION_3_H +template +struct +Get_io_signature > +{ + std::string operator()() { + return std::string("Triangulation_3(") + + Get_io_signature()() + + ",Vb(" + Get_io_signature()() + + "),Cb(" + Get_io_signature()() + + "))"; + } +}; +#endif + +#ifdef CGAL_DELAUNAY_TRIANGULATION_3_H +template +struct +Get_io_signature > +{ + std::string operator()() { + return Get_io_signature >()(); + } +}; +#endif + +#ifdef CGAL_REGULAR_TRIANGULATION_3_H +template +struct +Get_io_signature > +{ + std::string operator()() { + return Get_io_signature >()(); + } +}; +#endif + +#ifdef CGAL_PERIODIC_3_TRIANGULATION_3_H +template +struct +Get_io_signature > +{ + std::string operator()() { + return std::string("Periodic_3_triangulation_3(") + + Get_io_signature()() + + ",Vb(" + Get_io_signature()() + + "),Cb(" + Get_io_signature()() + + "))"; + } +}; +#endif + +#ifdef CGAL_PERIODIC_3_REGULAR_TRIANGULATION_3_H +template +struct +Get_io_signature > +{ + std::string operator()() { + return Get_io_signature >()(); + } +}; +#endif + +#ifdef CGAL_TRIANGULATION_VERTEX_BASE_3_H +template +struct Get_io_signature > +{ + std::string operator()() { + return "Tvb_3"; + } +}; +#endif + +#ifdef CGAL_REGULAR_TRIANGULATION_VERTEX_BASE_3_H +template +struct Get_io_signature > +{ + // identical to Triangulation_vertex_base_3 + std::string operator()() { + return "Tvb_3"; + } +}; +#endif + +#ifdef CGAL_TRIANGULATION_VERTEX_BASE_WITH_INFO_3_H +template +struct +Get_io_signature > +{ + std::string operator()() { + return Get_io_signature()(); + } +}; +#endif + +#ifdef CGAL_TRIANGULATION_CELL_BASE_3_H +template +struct +Get_io_signature > +{ + std::string operator()() { + return "Tcb_3"; + } +}; +#endif + +#ifdef CGAL_TRIANGULATION_CELL_BASE_WITH_INFO_3_H +template +struct +Get_io_signature > +{ + std::string operator()() { + return Get_io_signature()(); + } +}; +#endif + +#ifdef CGAL_REGULAR_TRIANGULATION_CELL_BASE_3_H +template +struct +Get_io_signature > +{ + std::string operator()() { + return "RTcb_3"; + } +}; +#endif + +#ifdef CGAL_REGULAR_TRIANGULATION_CELL_BASE_WITH_CIRCUMCENTER_3_H +template +struct +Get_io_signature > +{ + std::string operator()() { + return "RTWWCcb_3"; + } +}; +#endif + +} // end namespace CGAL + + +#endif // CGAL_SMDS_3_IO_SIGNATURE_H diff --git a/Mesh_3/include/CGAL/Mesh_3/tet_soup_to_c3t3.h b/SMDS_3/include/CGAL/SMDS_3/tet_soup_to_c3t3.h similarity index 57% rename from Mesh_3/include/CGAL/Mesh_3/tet_soup_to_c3t3.h rename to SMDS_3/include/CGAL/SMDS_3/tet_soup_to_c3t3.h index 5c2f6d69a08..812bc87214c 100644 --- a/Mesh_3/include/CGAL/Mesh_3/tet_soup_to_c3t3.h +++ b/SMDS_3/include/CGAL/SMDS_3/tet_soup_to_c3t3.h @@ -14,10 +14,10 @@ // //****************************************************************************** -#ifndef CGAL_MESH_3_TET_SOUP_TO_C3T3_H -#define CGAL_MESH_3_TET_SOUP_TO_C3T3_H +#ifndef CGAL_SMDS_3_TET_SOUP_TO_C3T3_H +#define CGAL_SMDS_3_TET_SOUP_TO_C3T3_H -#include +#include #include #include @@ -32,7 +32,8 @@ namespace CGAL { - +namespace SMDS_3 +{ template std::array make_ordered_vertex_array(const Vh vh0, const Vh vh1, const Vh vh2) { @@ -43,12 +44,13 @@ std::array make_ordered_vertex_array(const Vh vh0, const Vh vh1, const Vh return ft; } -template +template void build_vertices(Tr& tr, - const std::vector& points, + const PointRange& points, std::vector& vertex_handle_vector) { typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Point Point; vertex_handle_vector[0] = tr.tds().create_vertex(); // creates the infinite vertex tr.set_infinite_vertex(vertex_handle_vector[0]); @@ -58,7 +60,7 @@ void build_vertices(Tr& tr, { Vertex_handle vh = tr.tds().create_vertex(); vertex_handle_vector[i+1] = vh; - vh->set_point(points[i]); + vh->set_point(Point(points[i])); } } @@ -66,7 +68,8 @@ template bool add_facet_to_incident_cells_map(const typename Tr::Cell_handle c, int i, boost::unordered_map, std::vector > >& incident_cells_map, - const bool verbose) + const bool verbose, + const bool allow_non_manifold) { typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; @@ -74,8 +77,10 @@ bool add_facet_to_incident_cells_map(const typename Tr::Cell_handle c, int i, typedef std::pair Incident_cell; typedef boost::unordered_map > Incident_cells_map; + bool success = true; + // the opposite vertex of f in c is i - Facet_vvv f = make_ordered_vertex_array(c->vertex((i + 1) % 4), + Facet_vvv f = CGAL::SMDS_3::make_ordered_vertex_array(c->vertex((i + 1) % 4), c->vertex((i + 2) % 4), c->vertex((i + 3) % 4)); CGAL_precondition(f[0] != f[1] && f[1] != f[2]); @@ -92,47 +97,50 @@ bool add_facet_to_incident_cells_map(const typename Tr::Cell_handle c, int i, { if(verbose) std::cout << "Error in add_facet_to_incident_cells_map" << std::endl; - return false; + if(!allow_non_manifold) + success = false; } is_insert_successful.first->second.push_back(e); } - return true; + return success; } -template +template bool build_finite_cells(Tr& tr, - const std::vector >& finite_cells, + const CellRange& finite_cells, + const SubdomainsRange& subdomains, const std::vector& vertex_handle_vector, boost::unordered_map, std::vector > >& incident_cells_map, - const std::map, typename Tr::Cell::Surface_patch_index>& border_facets, + const FacetPatchMap& border_facets, const bool verbose, - bool replace_domain_0 = false) + const bool replace_domain_0) { - typedef std::array Tet_with_ref; // 4 ids + 1 reference - typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; typedef typename Tr::Cell::Surface_patch_index Surface_patch_index; + bool success = true; + CGAL_assertion_code( typename Tr::Geom_traits::Construct_point_3 cp = tr.geom_traits().construct_point_3_object(); + typename Tr::Geom_traits::Orientation_3 orientation = + tr.geom_traits().orientation_3_object(); ) - int max_domain = 0; + typename SubdomainsRange::value_type max_domain = 0; if(replace_domain_0) { for(std::size_t i=0; i max_domain) - max_domain=tet[4]; + if(subdomains[i] > max_domain) + max_domain = subdomains[i]; } } // build the finite cells for(std::size_t i=0; i vs; for(int j=0; j<4; ++j) @@ -145,16 +153,17 @@ bool build_finite_cells(Tr& tr, } // this assertion also tests for degeneracy - CGAL_assertion(CGAL::orientation(cp(tr.point(vs[0])), cp(tr.point(vs[1])), - cp(tr.point(vs[2])), cp(tr.point(vs[3]))) + CGAL_assertion(orientation(cp(tr.point(vs[0])), cp(tr.point(vs[1])), + cp(tr.point(vs[2])), cp(tr.point(vs[3]))) == POSITIVE); Cell_handle c = tr.tds().create_cell(vs[0], vs[1], vs[2], vs[3]); - c->set_subdomain_index(tet[4]); // the cell's info keeps the reference of the tetrahedron - if(replace_domain_0 && tet[4] == 0) + c->set_subdomain_index(subdomains[i]); // the cell's info keeps the reference of the tetrahedron + if(replace_domain_0 && subdomains[i] == 0) { c->set_subdomain_index(max_domain+1); // the cell's info keeps the reference of the tetrahedron } + // assign cells to vertices for(int j=0; j<4; ++j) { @@ -165,8 +174,9 @@ bool build_finite_cells(Tr& tr, // build the map used for adjacency later for(int j=0; j<4; ++j) { - if(!add_facet_to_incident_cells_map(c, j, incident_cells_map, verbose)) - return false; + if(!CGAL::SMDS_3::add_facet_to_incident_cells_map(c, j, incident_cells_map, verbose, false)) + //do not allow non-manifold in the finite cells case + success = false; if(border_facets.size() != 0) { std::array facet; @@ -185,8 +195,7 @@ bool build_finite_cells(Tr& tr, ++k; } while(f[0] != n0); - typename std::map, Surface_patch_index>::const_iterator - it = border_facets.find(f); + typename FacetPatchMap::const_iterator it = border_facets.find(f); if(it != border_facets.end()) { c->set_surface_patch_index(j, it->second); @@ -206,7 +215,7 @@ bool build_finite_cells(Tr& tr, } } } - return true; + return success; } template @@ -214,14 +223,15 @@ bool add_infinite_facets_to_incident_cells_map(typename Tr::Cell_handle c, int inf_vert_pos, boost::unordered_map, std::vector > >& incident_cells_map, - const bool verbose) + const bool verbose, + const bool allow_non_manifold) { int l = (inf_vert_pos + 1) % 4; - bool b1 = add_facet_to_incident_cells_map(c, l, incident_cells_map, verbose); + bool b1 = CGAL::SMDS_3::add_facet_to_incident_cells_map(c, l, incident_cells_map, verbose, allow_non_manifold); l = (inf_vert_pos + 2) % 4; - bool b2 = add_facet_to_incident_cells_map(c, l, incident_cells_map, verbose); + bool b2 = CGAL::SMDS_3::add_facet_to_incident_cells_map(c, l, incident_cells_map, verbose, allow_non_manifold); l = (inf_vert_pos + 3) % 4; - bool b3 = add_facet_to_incident_cells_map(c, l, incident_cells_map, verbose); + bool b3 = CGAL::SMDS_3::add_facet_to_incident_cells_map(c, l, incident_cells_map, verbose, allow_non_manifold); return b1 && b2 && b3; } @@ -229,7 +239,8 @@ template bool build_infinite_cells(Tr& tr, boost::unordered_map, std::vector > >& incident_cells_map, - const bool verbose) + const bool verbose, + const bool allow_non_manifold) { typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; @@ -237,6 +248,8 @@ bool build_infinite_cells(Tr& tr, typedef std::pair Incident_cell; typedef boost::unordered_map > Incident_cells_map; + bool success = true; + std::vector infinite_cells; // check the incident cells map for facets who only have one incident cell @@ -287,7 +300,7 @@ bool build_infinite_cells(Tr& tr, { for (int i = 1; i < 4; ++i) { - std::array vs = make_ordered_vertex_array(c->vertex((i + 1) % 4), + std::array vs = CGAL::SMDS_3::make_ordered_vertex_array(c->vertex((i + 1) % 4), c->vertex((i + 2) % 4), c->vertex((i + 3) % 4)); if (facets.find(vs) == facets.end()) @@ -297,52 +310,93 @@ bool build_infinite_cells(Tr& tr, } } for (auto fp : facets) - CGAL_assertion(fp.second == 2); + { + if (fp.second != 2) + { + std::cout << "Warning : non manifold edge" << std::endl; + std::cout << "fp.second = " << fp.second << std::endl; + std::cout << fp.first[0]->point() << " " + << fp.first[1]->point() << " " + << fp.first[2]->point() << std::endl; + success = false; + } +// CGAL_assertion(fp.second == 2); + } #endif // add the facets to the incident cells map for (const Cell_handle& c : infinite_cells) - if(!add_infinite_facets_to_incident_cells_map(c, 0, incident_cells_map, verbose)) - return false; + if(!CGAL::SMDS_3::add_infinite_facets_to_incident_cells_map(c, + 0, + incident_cells_map, + verbose, + allow_non_manifold)) + success = false; - return true; + return success; +} + +template +bool has_infinite_vertex(const std::array& v, + const Tr& tr) +{ + for (auto vh : v) + { + if (tr.infinite_vertex() == vh) + return true; + } + return false; } template bool assign_neighbors(Tr& tr, const boost::unordered_map, - std::vector > >& incident_cells_map) + std::vector > >& incident_cells_map, + const bool allow_non_manifold) { typedef typename Tr::Cell_handle Cell_handle; typedef std::pair Incident_cell; typedef boost::unordered_map, std::vector > Incident_cells_map; + bool success = true; + typename Incident_cells_map::const_iterator icit = incident_cells_map.begin(); for(; icit!=incident_cells_map.end(); ++icit) { const std::vector& adjacent_cells = icit->second; - if(adjacent_cells.size() != 2) - return false; + if (adjacent_cells.size() == 2) + { + Cell_handle c0 = adjacent_cells[0].first; + int i0 = adjacent_cells[0].second; + Cell_handle c1 = adjacent_cells[1].first; + int i1 = adjacent_cells[1].second; - Cell_handle c0 = adjacent_cells[0].first; - int i0 = adjacent_cells[0].second; - Cell_handle c1 = adjacent_cells[1].first; - int i1 = adjacent_cells[1].second; - - tr.tds().set_adjacency(c0, i0, c1, i1); + tr.tds().set_adjacency(c0, i0, c1, i1); + } + else if(allow_non_manifold)// if (adjacent_cells.size() == 4) + { + CGAL_assertion_code(const auto& v = icit->first); + CGAL_assertion(has_infinite_vertex(v, tr)); + success = false; + } } - return true; + return success; } -template -bool build_triangulation(Tr& tr, - const std::vector& points, - const std::vector >& finite_cells, - const std::map, typename Tr::Cell::Surface_patch_index>& border_facets, - std::vector& vertex_handle_vector, - const bool verbose = false, - bool replace_domain_0 = false) +template +bool build_triangulation_impl(Tr& tr, + const PointRange& points, + const CellRange& finite_cells, + const std::vector& subdomains, + const FacetPatchMap& border_facets, + std::vector& vertex_handle_vector, + const bool verbose,// = false, + const bool replace_domain_0,// = false, + const bool allow_non_manifold) // = false { typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; @@ -352,6 +406,8 @@ bool build_triangulation(Tr& tr, typedef std::pair Incident_cell; typedef boost::unordered_map > Incident_cells_map; + bool success = true; + Incident_cells_map incident_cells_map; vertex_handle_vector.resize(points.size() + 1); // id to vertex_handle //index 0 is for infinite vertex @@ -373,14 +429,23 @@ bool build_triangulation(Tr& tr, } if (!finite_cells.empty()) { - if(!build_finite_cells(tr, finite_cells, vertex_handle_vector, incident_cells_map, - border_facets, verbose, replace_domain_0)) - return false; - if(!build_infinite_cells(tr, incident_cells_map, verbose)) - return false; + if (!CGAL::SMDS_3::build_finite_cells(tr, finite_cells, subdomains, vertex_handle_vector, incident_cells_map, + border_facets, verbose, replace_domain_0)) + { + if(verbose) std::cout << "build_finite_cells went wrong" << std::endl; + success = false; + } + if (!CGAL::SMDS_3::build_infinite_cells(tr, incident_cells_map, verbose, allow_non_manifold)) + { + if(verbose) std::cout << "build_infinite_cells went wrong" << std::endl; + success = false; + } tr.tds().set_dimension(3); - if (!assign_neighbors(tr, incident_cells_map)) - return false; + if (!CGAL::SMDS_3::assign_neighbors(tr, incident_cells_map, allow_non_manifold)) + { + if(verbose) std::cout << "assign_neighbors went wrong" << std::endl; + success = false; + } if (verbose) { std::cout << "built triangulation : " << std::endl; @@ -390,25 +455,92 @@ bool build_triangulation(Tr& tr, if(verbose) std::cout << tr.number_of_vertices() << " vertices" << std::endl; - if(c3t3_loader_failed) - return true; - else - return tr.tds().is_valid(); + return success;// tr.tds().is_valid(); + //TDS not valid when cells do not cover the convex hull of vertices } -template +template +bool build_triangulation_one_subdomain(Tr& tr, + const PointRange& points, + const CellRange& finite_cells, + const typename Tr::Cell::Subdomain_index& subdomain, + const FacetPatchMap& border_facets, + std::vector& vertex_handle_vector, + const bool verbose,// = false, + const bool replace_domain_0,// = false + const bool allow_non_manifold)// = false +{ + std::vector subdomains(finite_cells.size(), subdomain); + return build_triangulation_impl(tr, points, finite_cells, subdomains, + border_facets, vertex_handle_vector, + verbose, replace_domain_0, + allow_non_manifold); +} + +template +bool build_triangulation_one_subdomain(Tr& tr, + const PointRange& points, + const CellRange& finite_cells, + const typename Tr::Cell::Subdomain_index& subdomain, + const FacetPatchMap& border_facets, + const bool verbose,// = false, + const bool replace_domain_0,// = false + const bool allow_non_manifold)//= false +{ + std::vector subdomains(finite_cells.size(), subdomain); + std::vector vertex_handle_vector; + return build_triangulation_impl(tr, points, finite_cells, subdomains, + border_facets, vertex_handle_vector, + verbose, replace_domain_0, + allow_non_manifold); +} + +template +bool build_triangulation_with_subdomains_range(Tr& tr, + const PointRange& points, + const CellRange& finite_cells, + const SubdomainsRange& subdomains, + const FacetPatchMap& border_facets, + const bool verbose,// = false + const bool replace_domain_0,// = false, + const bool allow_non_manifold) +{ + std::vector vertex_handle_vector; + std::vector subdomains_vector( + subdomains.begin(), subdomains.end()); + return build_triangulation_impl(tr, points, finite_cells, subdomains_vector, border_facets, + vertex_handle_vector, + verbose, replace_domain_0, + allow_non_manifold); +} + +template bool build_triangulation_from_file(std::istream& is, Tr& tr, - bool replace_domain_0) + const bool verbose, + const bool replace_domain_0, + const bool allow_non_manifold) { - typedef typename Tr::Point Point_3; + using Point_3 = typename Tr::Point; + using Subdomain_index = typename Tr::Cell::Subdomain_index; - typedef std::array Facet; // 3 = id - typedef std::array Tet_with_ref; // first 4 = id, fifth = reference + using Facet = std::array; // 3 = id + using Tet_with_ref = std::array; // 4 = id std::vector finite_cells; + std::vector subdomains; std::vector points; - std::map border_facets; + boost::unordered_map border_facets; // grab the vertices int dim; @@ -420,9 +552,25 @@ bool build_triangulation_from_file(std::istream& is, CGAL_assertion(dim == 3); - std::cout << "Reading .mesh file..." << std::endl; + if(verbose) + std::cout << "Reading .mesh file..." << std::endl; + + bool dont_replace_domain_0 = false; + while(is >> word && word != "End") { + if (word.at(0) == '#') + { + is >> word; + if (word == "End") + break; + else if (word == "CGAL::Mesh_complex_3_in_triangulation_3") + { + dont_replace_domain_0 = true;//with CGAL meshes, domain 0 should be kept + continue; + } + //else skip other comments + } if(word == "Vertices") { is >> nv; @@ -473,33 +621,33 @@ bool build_triangulation_from_file(std::istream& is, t[1] = n1 - 1; t[2] = n2 - 1; t[3] = n3 - 1; - t[4] = reference; finite_cells.push_back(t); + subdomains.push_back(reference); } } } - std::cout << points.size() << " points" << std::endl; - std::cout << border_facets.size() << " border facets" << std::endl; - std::cout << finite_cells.size() << " cells" << std::endl; + if (verbose) + { + std::cout << points.size() << " points" << std::endl; + std::cout << border_facets.size() << " border facets" << std::endl; + std::cout << finite_cells.size() << " cells" << std::endl; + } if(finite_cells.empty()) return false; + CGAL_assertion(finite_cells.size() == subdomains.size()); - std::vector vertices(points.size() + 1); - bool is_well_built = build_triangulation(tr, - points, finite_cells, border_facets, vertices, false, replace_domain_0); - return is_well_built; + return build_triangulation_with_subdomains_range(tr, + points, finite_cells, subdomains, border_facets, + verbose, + replace_domain_0 && !dont_replace_domain_0, + allow_non_manifold); } -template -bool build_triangulation_from_file(std::istream& is, - Tr& tr) -{ - return build_triangulation_from_file(is, tr, false); -} +} // namespace SMDS_3 } // namespace CGAL #include -#endif // CGAL_MESH_3_TET_SOUP_TO_C3T3_H +#endif // CGAL_SMDS_3_TET_SOUP_TO_C3T3_H diff --git a/Mesh_3/include/CGAL/Mesh_3/utilities.h b/SMDS_3/include/CGAL/SMDS_3/utilities.h similarity index 93% rename from Mesh_3/include/CGAL/Mesh_3/utilities.h rename to SMDS_3/include/CGAL/SMDS_3/utilities.h index 5e49f7a617e..369bfc9df03 100644 --- a/Mesh_3/include/CGAL/Mesh_3/utilities.h +++ b/SMDS_3/include/CGAL/SMDS_3/utilities.h @@ -14,10 +14,10 @@ // File Description : //****************************************************************************** -#ifndef CGAL_MESH_3_UTILITIES_H -#define CGAL_MESH_3_UTILITIES_H +#ifndef CGAL_SMDS_3_UTILITIES_H +#define CGAL_SMDS_3_UTILITIES_H -#include +#include #include #include @@ -25,7 +25,7 @@ #include namespace CGAL { -namespace Mesh_3 { +namespace SMDS_3 { namespace internal { struct Debug_messages_tools { @@ -115,7 +115,7 @@ public: } // end namespace internal -} // end namespace Mesh_3 +} // end namespace SMDS_3 } //namespace CGAL -#endif // CGAL_MESH_3_UTILITIES_H +#endif // CGAL_SMDS_3_UTILITIES_H diff --git a/SMDS_3/include/CGAL/Simplicial_mesh_cell_base_3.h b/SMDS_3/include/CGAL/Simplicial_mesh_cell_base_3.h new file mode 100644 index 00000000000..15a4b1fd3eb --- /dev/null +++ b/SMDS_3/include/CGAL/Simplicial_mesh_cell_base_3.h @@ -0,0 +1,391 @@ +// Copyright (c) 2006-2007 INRIA Sophia-Antipolis (France). +// Copyright (c) 2008,2011 GeometryFactory Sarl (France) +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Laurent Rineau, Stephane Tayeb, Andreas Fabri, Jane Tournois + + +#ifndef CGAL_SIMPLICIAL_MESH_CELL_BASE_3_H +#define CGAL_SIMPLICIAL_MESH_CELL_BASE_3_H + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CGAL_LINKED_WITH_TBB +# include +#endif + +namespace CGAL { + +// Class Simplicial_mesh_cell_3 +// Cell base class used for tetrahedral remeshing +// Adds information to Cb about the cell of the input complex containing it +template< class Subdomain_index_, + class Surface_patch_index_, + class TDS> +class Simplicial_mesh_cell_3 +{ +public: + using Triangulation_data_structure = TDS; + using Vertex_handle = typename TDS::Vertex_handle; + using Cell_handle = typename TDS::Cell_handle; + using Vertex = typename TDS::Vertex; + using Cell = typename TDS::Cell; + using TDS_data = typename TDS::Cell_data; + + // Index Type + using Subdomain_index = Subdomain_index_; + using Surface_patch_index = Surface_patch_index_; + +public: + // Constructors + Simplicial_mesh_cell_3() + : time_stamp_(std::size_t(-1)) + {} + + Simplicial_mesh_cell_3(const Simplicial_mesh_cell_3& rhs) + : N(rhs.N) + , V(rhs.V) + , time_stamp_(rhs.time_stamp_) + , subdomain_index_(rhs.subdomain_index_) + { + for(int i=0; i <4; i++){ + surface_index_table_[i] = rhs.surface_index_table_[i]; + } + } + + Simplicial_mesh_cell_3(Vertex_handle v0, + Vertex_handle v1, + Vertex_handle v2, + Vertex_handle v3) + : V(CGAL::make_array(v0, v1, v2, v3)) + { + } + + Simplicial_mesh_cell_3(Vertex_handle v0, + Vertex_handle v1, + Vertex_handle v2, + Vertex_handle v3, + Cell_handle n0, + Cell_handle n1, + Cell_handle n2, + Cell_handle n3) + : N(CGAL::make_array(n0, n1, n2, n3)) + , V(CGAL::make_array(v0, v1, v2, v3)) + { + } + + // ACCESS FUNCTIONS + Vertex_handle vertex(int i) const + { + CGAL_triangulation_precondition( i >= 0 && i <= 3 ); + return V[i]; + } + + bool has_vertex(Vertex_handle v) const + { + return (V[0] == v) || (V[1] == v) || (V[2]== v) || (V[3]== v); + } + + bool has_vertex(Vertex_handle v, int & i) const + { + if (v == V[0]) { i = 0; return true; } + if (v == V[1]) { i = 1; return true; } + if (v == V[2]) { i = 2; return true; } + if (v == V[3]) { i = 3; return true; } + return false; + } + + int index(Vertex_handle v) const + { + if (v == V[0]) { return 0; } + if (v == V[1]) { return 1; } + if (v == V[2]) { return 2; } + CGAL_triangulation_assertion( v == V[3] ); + return 3; + } + + Cell_handle neighbor(int i) const + { + CGAL_triangulation_precondition( i >= 0 && i <= 3); + return N[i]; + } + + bool has_neighbor(Cell_handle n) const + { + return (N[0] == n) || (N[1] == n) || (N[2] == n) || (N[3] == n); + } + + bool has_neighbor(Cell_handle n, int & i) const + { + if(n == N[0]){ i = 0; return true; } + if(n == N[1]){ i = 1; return true; } + if(n == N[2]){ i = 2; return true; } + if(n == N[3]){ i = 3; return true; } + return false; + } + + int index(Cell_handle n) const + { + if (n == N[0]) return 0; + if (n == N[1]) return 1; + if (n == N[2]) return 2; + CGAL_triangulation_assertion( n == N[3] ); + return 3; + } + + // SETTING + void set_neighbor(int i, Cell_handle n) + { + CGAL_triangulation_precondition( i >= 0 && i <= 3); + CGAL_triangulation_precondition( this != n.operator->() ); + N[i] = n; + } + + void set_neighbors() + { + N[0] = N[1] = N[2] = N[3] = Cell_handle(); + } + + void set_neighbors(Cell_handle n0, Cell_handle n1, + Cell_handle n2, Cell_handle n3) + { + CGAL_triangulation_precondition( this != n0.operator->() ); + CGAL_triangulation_precondition( this != n1.operator->() ); + CGAL_triangulation_precondition( this != n2.operator->() ); + CGAL_triangulation_precondition( this != n3.operator->() ); + N[0] = n0; + N[1] = n1; + N[2] = n2; + N[3] = n3; + } + + // CHECKING + + // the following trivial is_valid allows + // the user of derived cell base classes + // to add their own purpose checking + bool is_valid(bool = false, int = 0) const + { return true; } + + // For use by Compact_container. + void * for_compact_container() const { return N[0].for_compact_container(); } + void for_compact_container(void *p) { N[0].for_compact_container(p); } + + // TDS internal data access functions. + TDS_data& tds_data() { return _tds_data; } + const TDS_data& tds_data() const { return _tds_data; } + + // We must override the functions that modify the vertices. + // And if the point inside a vertex is modified, we fail, + // but there's not much we can do for this now. + void set_vertex(int i, Vertex_handle v) + { + CGAL_triangulation_precondition( i >= 0 && i <= 3); + V[i] = v; + } + + void set_vertices() + { + V[0] = V[1] = V[2] = V[3] = Vertex_handle(); + } + + void set_vertices(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3) + { + V[0] = v0; + V[1] = v1; + V[2] = v2; + V[3] = v3; + } + + // Returns the index of the cell of the input complex that contains the cell + Subdomain_index subdomain_index() const { return subdomain_index_; } + + // Sets the index of the cell of the input complex that contains the cell + void set_subdomain_index(const Subdomain_index& index) + { subdomain_index_ = index; } + + /// Set surface index of \c facet to \c index + void set_surface_patch_index(const int facet, const Surface_patch_index& index) + { + CGAL_precondition(facet>=0 && facet<4); + surface_index_table_[facet] = index; + } + + /// Returns surface index of facet \c facet + Surface_patch_index surface_patch_index(const int facet) const + { + CGAL_precondition(facet>=0 && facet<4); + return surface_index_table_[facet]; + } + + /// Returns true if facet lies on a surface patch + bool is_facet_on_surface(const int facet) const + { + CGAL_precondition(facet>=0 && facet<4); + return ( !( Surface_patch_index() == surface_index_table_[facet] )); + } + + // ----------------------------------- + // Backward Compatibility + // ----------------------------------- +#ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX + typedef Surface_patch_index Surface_index; + + void set_surface_index(const int facet, const Surface_index& index) + { set_surface_patch_index(facet,index); } + + /// Returns surface index of facet \c facet + Surface_index surface_index(const int facet) const + { return surface_patch_index(facet); } +#endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX + // ----------------------------------- + // End backward Compatibility + // ----------------------------------- + + static + std::string io_signature() + { + return + Get_io_signature()() + + "+(" + Get_io_signature()() + ")[4]"; + } + + /// For the determinism of Compact_container iterators + ///@{ + typedef Tag_true Has_timestamp; + + std::size_t time_stamp() const { + return time_stamp_; + } + void set_time_stamp(const std::size_t& ts) { + time_stamp_ = ts; + } + ///@} + +private: + + /// Stores surface_index for each facet of the cell + std::array surface_index_table_ = {}; + + std::array N; + std::array V; + + std::size_t time_stamp_; + + // The index of the cell of the input complex that contains me + Subdomain_index subdomain_index_ = {}; + + TDS_data _tds_data; + +public: + + friend std::istream& operator>>(std::istream &is, Simplicial_mesh_cell_3 &c) + { + Subdomain_index index; + if(IO::is_ascii(is)) + is >> index; + else + read(is, index); + if(is) { + c.set_subdomain_index(index); + for(int i = 0; i < 4; ++i) + { + Surface_patch_index i2; + if(IO::is_ascii(is)) + is >> IO::iformat(i2); + else + { + read(is, i2); + } + c.set_surface_patch_index(i, i2); + } + } + return is; + } + + friend + std::ostream& operator<<(std::ostream &os, const Simplicial_mesh_cell_3&c) + { + if(IO::is_ascii(os)) + os << c.subdomain_index(); + else + write(os, c.subdomain_index()); + for(int i = 0; i < 4; ++i) + { + if(IO::is_ascii(os)) + os << ' ' << IO::oformat(c.surface_patch_index(i)); + else + write(os, c.surface_patch_index(i)); + } + return os; + } + +}; // end class Simplicial_mesh_cell_3 + +/*! +\ingroup PkgSMDS3Classes + +The class `Simplicial_mesh_cell_base_3` +is a model of the concept `SimplicialMeshCellBase_3`. +It is designed to serve as cell base class for.3D simplicial mesh data structures. +It stores and gives access to data about the complex the cell belongs to, such as the +subdomain it belongs to or surface it takes part to. + +\tparam Subdomain_index Type of indices for subdomains of the discretized geometric domain. +Must be a model of `CopyConstructible`, `Assignable`, `DefaultConstructible` +and `EqualityComparable`. The default constructed value must match the label +of the exterior of the domain (which contains at least the unbounded component). + It must match the `Subdomain_index` of the model + of the `MeshDomain_3` concept when used for mesh generation. + +\tparam Surface_patch_index Type of indices for surface patches (boundaries and interfaces) +of the discretized geometric domain. +Must be a model of `CopyConstructible`, `Assignable`, `DefaultConstructible` +and `EqualityComparable`. The default constructed value must be the index value +assigned to a non surface facet. + It must match the `Surface_patch_index` of the model + of the `MeshDomain_3` concept when used for mesh generation. + +\cgalModels `SimplicialMeshCellBase_3` + +\sa `CGAL::Mesh_complex_3_in_triangulation_3` +\sa \link Mesh_cell_base_3 `CGAL::Mesh_cell_base_3`\endlink +\sa `MeshDomain_3` +\sa `MeshDomainWithFeatures_3` +*/ +template +class Simplicial_mesh_cell_base_3 +{ +public: + template + struct Rebind_TDS + { + typedef Simplicial_mesh_cell_3 Other; + }; +}; + +} // end namespace CGAL + + +#endif // CGAL_SIMPLICIAL_MESH_CELL_BASE_3_H diff --git a/SMDS_3/include/CGAL/Simplicial_mesh_vertex_base_3.h b/SMDS_3/include/CGAL/Simplicial_mesh_vertex_base_3.h new file mode 100644 index 00000000000..3f1a9c92d42 --- /dev/null +++ b/SMDS_3/include/CGAL/Simplicial_mesh_vertex_base_3.h @@ -0,0 +1,288 @@ +// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// Copyright (c) 2011 GeometryFactory Sarl (France) +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Stéphane Tayeb, Andreas Fabri, Jane Tournois +// +//****************************************************************************** +// File Description : +// +// +//****************************************************************************** + + +#ifndef CGAL_SIMPLICIAL_MESH_VERTEX_BASE_3_H +#define CGAL_SIMPLICIAL_MESH_VERTEX_BASE_3_H + +#include + +#include + +#include +#include +#include + +#include +#include + +namespace CGAL { + +//Class Simplicial_mesh_vertex_3 +//Adds information to Vb about the localization of the vertex in regards +//to the 3D input complex. +//\cgalModels `SimplicialMeshVertexBase_3` +template +class Simplicial_mesh_vertex_3 +: public Vb +{ +private : + using Cmvb3_base = Vb; + +public: + using Vertex_handle = typename Vb::Vertex_handle; + + // Types + using Index = boost::variant; + using FT = typename GT::FT; + + // Constructor + Simplicial_mesh_vertex_3() + : Vb() + , number_of_incident_facets_(0) + , number_of_components_(0) + , index_() + , dimension_(-1) + , cache_validity(false) + , time_stamp_(std::size_t(-1)) + {} + + // Default copy constructor and assignment operator are ok + + // Returns the dimension of the lowest dimensional face of the input 3D + // complex that contains the vertex + int in_dimension() const { + if(dimension_ < -1) return -2-dimension_; + else return dimension_; + } + + // Sets the dimension of the lowest dimensional face of the input 3D complex + // that contains the vertex + void set_dimension(const int dimension) { + CGAL_assertion(dimension < 4); + dimension_ = short(dimension); + } + + // Returns the index of the lowest dimensional face of the input 3D complex + // that contains the vertex + Index index() const { return index_; } + + // Sets the index of the lowest dimensional face of the input 3D complex + // that contains the vertex + void set_index(const Index& index) { index_ = index; } + + /// For the determinism of Compact_container iterators + ///@{ + typedef Tag_true Has_timestamp; + + std::size_t time_stamp() const { + return time_stamp_; + } + void set_time_stamp(const std::size_t& ts) { + time_stamp_ = ts; + } + ///@} + + bool is_c2t3_cache_valid() const { + return cache_validity; + } + + void invalidate_c2t3_cache() + { + cache_validity = false; + } + + void set_c2t3_cache(const std::size_t i, const std::size_t j) + { + number_of_incident_facets_ = i; + number_of_components_ = j; + cache_validity = true; + } + + std::size_t cached_number_of_incident_facets() const + { + return number_of_incident_facets_; + } + + std::size_t cached_number_of_components() const + { + return number_of_components_; + } + + static + std::string io_signature() + { + return + Get_io_signature()() + "+" + + Get_io_signature()() + "+" + + Get_io_signature()(); + } +private: + + std::size_t number_of_incident_facets_; + std::size_t number_of_components_; // number of components in the adjacency + // graph of incident facets (in complex) + + + // Index of the lowest dimensional face of the input 3D complex + // that contains me + Index index_; + + // Dimension of the lowest dimensional face of the input 3D complex + // that contains me. Negative values are a marker for special vertices. + short dimension_; + bool cache_validity; + std::size_t time_stamp_; + +public: + + friend std::istream& operator>>(std::istream &is, Simplicial_mesh_vertex_3& v) + { + is >> static_cast(v); + int dimension; + if(IO::is_ascii(is)) { + is >> dimension; + + } else { + CGAL::read(is, dimension); + } + v.set_dimension(dimension); + CGAL_assertion(v.in_dimension() >= -1); + CGAL_assertion(v.in_dimension() < 4); + + using Indices_tuple = std::tuple; + Index index = + Mesh_3::internal::Read_write_index()(is, v.in_dimension()); + v.set_index(index); + return is; + } + + friend std::ostream& operator<<(std::ostream &os, const Simplicial_mesh_vertex_3& v) + { + os << static_cast(v); + if(IO::is_ascii(os)) { + os << " " << v.in_dimension() + << " "; + } else { + CGAL::write(os, v.in_dimension()); + } + using Indices_tuple = std::tuple; + Mesh_3::internal::Read_write_index()(os, + v.in_dimension(), + v.index()); + return os; + } +}; // end class Simplicial_mesh_vertex_3 + + +/*! +\ingroup PkgSMDS3Classes + +The class `Simplicial_mesh_vertex_base_3` is a model of the concept +`SimplicialMeshVertexBase_3`. +It is designed to serve as vertex base class for 3D simplicial mesh data structures. +It stores and gives access to data about the complex the vertex belongs to, such as the +index of the subcomplex it belongs to. + +\tparam Gt is the geometric traits class. +It must be a model of the concept `TriangulationTraits_3` + +\tparam Subdomain_index Type of indices for subdomains of the discretized geometric domain. +Must be a model of `CopyConstructible`, `Assignable`, `DefaultConstructible` +and `EqualityComparable`. The default constructed value must match the label +of the exterior of the domain (which contains at least the unbounded component). + It must match the `Subdomain_index` of the model + of the `MeshDomain_3` concept when used for mesh generation. + +\tparam Surface_patch_index Type of indices for surface patches (boundaries and interfaces) +of the discretized geometric domain. +Must be a model of `CopyConstructible`, `Assignable`, `DefaultConstructible` +and `EqualityComparable`. The default constructed value must be the index value +assigned to a non surface facet. + It must match the `Surface_patch_index` of the model + of the `MeshDomain_3` concept when used for mesh generation. + +\tparam Curve_index Type of indices for curves (i.e. \f$ 1\f$-dimensional features) +of the discretized geometric domain. +Must be a model of `CopyConstructible`, `Assignable`, `DefaultConstructible` and +`LessThanComparable`. The default constructed value must be the value for an edge which +does not approximate a 1-dimensional feature of the geometric domain. + It must match the `Curve_index` types of the model + of the `MeshDomainWithFeatures_3` concept when used for mesh generation. + +\tparam Corner_index Type of indices for corners (i.e.\f$ 0\f$--dimensional features) +of the discretized geometric domain. +It must be a model of `CopyConstructible`, `Assignable`, `DefaultConstructible` and +`LessThanComparable`. + It must match the `Corner_index` of the model + of the `MeshDomainWithFeatures_3` concept when used for mesh generation. + +\tparam Vb is the vertex base class. It has to be a model +of the concept `TriangulationVertexBase_3` and defaults to +`Triangulation_vertex_base_3`. + +\cgalModels `SimplicialMeshVertexBase_3` + +\sa `CGAL::Mesh_complex_3_in_triangulation_3` +\sa \link Mesh_vertex_base_3 `CGAL::Mesh_vertex_base_3`\endlink +\sa `MeshDomain_3` +\sa `MeshDomainWithFeatures_3` +*/ +template > +struct Simplicial_mesh_vertex_base_3 +{ + using Triangulation_data_structure = internal::Dummy_tds_3; + using Vertex_handle = typename Triangulation_data_structure::Vertex_handle; + using Cell_handle = typename Triangulation_data_structure::Cell_handle; + + template < class TDS3 > + struct Rebind_TDS { + using Vb3 = typename Vb::template Rebind_TDS::Other; + using Other = Simplicial_mesh_vertex_3 ; + }; +}; + + +} // end namespace CGAL + + + +#endif // CGAL_SIMPLICIAL_MESH_VERTEX_BASE_3_H diff --git a/SMDS_3/include/CGAL/facets_in_complex_3_to_triangle_mesh.h b/SMDS_3/include/CGAL/facets_in_complex_3_to_triangle_mesh.h new file mode 100644 index 00000000000..24db08154f6 --- /dev/null +++ b/SMDS_3/include/CGAL/facets_in_complex_3_to_triangle_mesh.h @@ -0,0 +1,239 @@ +// Copyright (c) 2009-2017 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Maxime Gimeno, +// Mael Rouxel-Labbé + +#ifndef CGAL_FACETS_IN_COMPLEX_3_TO_TRIANGLE_MESH_H +#define CGAL_FACETS_IN_COMPLEX_3_TO_TRIANGLE_MESH_H + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +namespace CGAL { + +namespace SMDS_3 { + +namespace internal { + +template +void resize(Polygon& p, std::size_t size) +{ + p.resize(size); +} + +template +void resize(std::array&, std::size_t CGAL_assertion_code(size)) +{ + CGAL_assertion(size == N); +} + +template +void facets_in_complex_3_to_triangle_soup(const C3T3& c3t3, + const typename C3T3::Subdomain_index sd_index, + PointContainer& points, + FaceContainer& faces, + PatchIndexContainer& patches, + const bool normals_point_outside_of_the_subdomain = true, + const bool export_all_facets = false) +{ + typedef typename PointContainer::value_type Point_3; + typedef typename FaceContainer::value_type Face; + + typedef typename C3T3::Triangulation Tr; + typedef typename C3T3::Surface_patch_index Surface_patch_index; + + typedef typename Tr::Cell_handle Cell_handle; + typedef typename Tr::Weighted_point Weighted_point; + typedef typename Tr::Facet Facet; + + typedef std::unordered_map PIM; + + typedef typename C3T3::size_type size_type; + + // triangulation point to range point + CGAL::Cartesian_converter::type, + typename CGAL::Kernel_traits::type> t2r; + + size_type nf = c3t3.number_of_facets_in_complex(); + faces.reserve(faces.size() + nf); + patches.reserve(faces.size() + nf); + points.reserve(points.size() + nf/2); // approximating Euler + + PIM p_to_ids; + std::size_t inum = 0; + + for(Facet fit : c3t3.facets_in_complex()) + { + Cell_handle c = fit.first; + int s = fit.second; + const Surface_patch_index spi = c->surface_patch_index(s); + Face f; + resize(f, 3); + + typename C3T3::Subdomain_index cell_sdi = c3t3.subdomain_index(c); + typename C3T3::Subdomain_index opp_sdi = c3t3.subdomain_index(c->neighbor(s)); + + if(!export_all_facets && cell_sdi != sd_index && opp_sdi != sd_index) + continue; + + for(std::size_t i=1; i<4; ++i) + { + CGAL_assertion_code(typedef typename Tr::Vertex_handle Vertex_handle;) + CGAL_assertion_code(Vertex_handle v = c->vertex((s+i)&3);) + CGAL_assertion(v != Vertex_handle() && !c3t3.triangulation().is_infinite(v)); + + const Weighted_point& wp = c3t3.triangulation().point(c, (s+i)&3); + const Point_3& bp = t2r(c3t3.triangulation().geom_traits().construct_point_3_object()(wp)); + + auto insertion_res = p_to_ids.emplace(bp, inum); + if(insertion_res.second) // new point + { + points.push_back(bp); + ++inum; + } + + f[i-1] = insertion_res.first->second; + } + + if(export_all_facets) + { + if((cell_sdi > opp_sdi) == (s%2 == 1)) + std::swap(f[0], f[1]); + } + else + { + if(((cell_sdi == sd_index) == (s%2 == 1)) == normals_point_outside_of_the_subdomain) + std::swap(f[0], f[1]); + } + + faces.push_back(f); + patches.push_back(spi); + } +} + +template +void facets_in_complex_3_to_triangle_soup(const C3T3& c3t3, + PointContainer& points, + FaceContainer& faces, + SurfacePatchContainer& patches) +{ + typedef typename C3T3::Subdomain_index Subdomain_index; + Subdomain_index useless = Subdomain_index(); + facets_in_complex_3_to_triangle_soup(c3t3, useless, points, faces, patches, + true/*point outward*/, true /*extract all facets*/); +} + +template +void set_face_patches(const Index2FaceMap&, + const SurfacePatchRange&, + const internal_np::Param_not_found&) +{ + return; +} + +template +void set_face_patches(const Index2FaceMap& i2f, + const SurfacePatchRange& patches, + const FacePatchMap& fpmap) +{ + for (auto index_and_face : i2f) + { + put(fpmap, index_and_face.second, patches[index_and_face.first]); + } +} + +} // end namespace internal + +} // end namespace SMDS_3 + + /** + * @ingroup PkgSMDS3Functions + * + * @brief builds a `TriangleMesh` from the surface facets, with a consistent orientation + * at the interface of two subdomains. + * + * This function exports the surface as a `TriangleMesh` and appends it to `tmesh`, using + * `orient_polygon_soup()`. + * + * @tparam C3T3 a model of `MeshComplexWithFeatures_3InTriangulation_3`. + * @tparam TriangleMesh a model of `MutableFaceGraph` with an internal point property map. + * The point type must be compatible with the one used in `C3T3`. + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * @param c3t3 an instance of `C3T3` + * @param tmesh an instance of `TriangleMesh` + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{face_patch_map} + * \cgalParamDescription{a property map with the patch id's associated to the faces of `faces(tmesh)`} + * \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits::%face_descriptor` + * as key type and the desired property, model of `CopyConstructible` + * and `LessThanComparable`, + * and compatible with the `Surface_patch_index` type of `C3T3` as value type.} + * \cgalParamDefault{If not provided, faces patch ids are ignored.} + * \cgalParamNEnd + * \cgalNamedParamsEnd + */ + template + void facets_in_complex_3_to_triangle_mesh(const C3T3& c3t3, + TriangleMesh& tmesh, + const NamedParameters& np = parameters::default_values()) + { + namespace PMP = CGAL::Polygon_mesh_processing; + + typedef typename boost::property_map::type VertexPointMap; + typedef typename boost::property_traits::value_type Point_3; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename C3T3::Surface_patch_index Surface_patch_index; + + typedef std::array Face; + + std::vector faces; + std::vector patches; + std::vector points; + + SMDS_3::internal::facets_in_complex_3_to_triangle_soup(c3t3, points, faces, patches); + + if (!PMP::is_polygon_soup_a_polygon_mesh(faces)) + PMP::orient_polygon_soup(points, faces); + CGAL_postcondition(PMP::is_polygon_soup_a_polygon_mesh(faces)); + + std::unordered_map i2f; + PMP::polygon_soup_to_polygon_mesh(points, faces, tmesh, + CGAL::parameters::polygon_to_face_output_iterator(std::inserter(i2f, i2f.end()))); + + using parameters::get_parameter; + SMDS_3::internal::set_face_patches(i2f, + patches, + get_parameter(np, internal_np::face_patch)); + } + +} // namespace CGAL + +#endif // CGAL_FACETS_IN_COMPLEX_3_TO_TRIANGLE_MESH_H diff --git a/SMDS_3/include/CGAL/tetrahedron_soup_to_triangulation_3.h b/SMDS_3/include/CGAL/tetrahedron_soup_to_triangulation_3.h new file mode 100644 index 00000000000..5d481acd01e --- /dev/null +++ b/SMDS_3/include/CGAL/tetrahedron_soup_to_triangulation_3.h @@ -0,0 +1,221 @@ +// Copyright (c) 2009-2014 INRIA Sophia-Antipolis (France). +// Copyright (c) 2010-2013 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Mael Rouxel-Labbé, Maxime Gimeno, Jane Tournois +// +//****************************************************************************** +// File Description : +//****************************************************************************** + +#ifndef CGAL_SMDS_3_TETRAHEDRON_SOUP_TO_C3T3_H +#define CGAL_SMDS_3_TETRAHEDRON_SOUP_TO_C3T3_H + +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace CGAL { + + /** \ingroup PkgSMDS3Functions + * builds a 3D triangulation from a soup of tetrahedra. + * + * @tparam TetrahedronRange a model of `Range` whose value type is + * a `Tetrahedron_3`. The point type of the tetrahedra must be convertible + * to `Triangulation::Point` + * @tparam Triangulation a 3D triangulation class that has + * a vertex base model of `SimplicialMeshVertexBase_3` + * and a cell base model of `SimplicialMeshCellBase_3` + * + * @param tets the set of finite tetrahedra of a valid CGAL triangulation. + * Each element in the range is the geometric description of the + * corresponding cell in the triangulation. + * + * @returns the 3D triangulation built from \p tets + * + * @post the output triangulation must be a triangulation of the convex hull of `tets` + * + * @sa @ref SMDS_3/tetrahedron_soup_to_c3t3_example.cpp + * + */ + template + Triangulation tetrahedron_soup_to_triangulation_3(const TetrahedronRange& tets) + { + using Tr = Triangulation; + using Point = typename Tr::Point; + + Triangulation tr; + std::vector points; + std::vector > finite_cells; + boost::unordered_map, typename Tr::Cell::Surface_patch_index> border_facets; + boost::unordered_map p2i; + + CGAL_assertion_code( + typename Triangulation::Geom_traits::Orientation_3 orientation = + tr.geom_traits().orientation_3_object(); + ); + + for (typename TetrahedronRange::value_type tet : tets) + { + CGAL_assertion(tet.orientation() == CGAL::POSITIVE); + std::array cell; + + for (int i = 0; i < 4; ++i) + { + const Point& pi = tet[i]; + if (p2i.find(pi) == p2i.end()) + { + points.push_back(pi); + int index = static_cast(points.size() - 1); + p2i.insert(std::make_pair(pi, index)); + cell[i] = index; + } + else + cell[i] = p2i.at(pi); + } + + CGAL_assertion(orientation(points[cell[0]], + points[cell[1]], points[cell[2]], points[cell[3]]) == CGAL::POSITIVE); + + finite_cells.push_back(cell); + } + + typename Tr::Cell::Subdomain_index default_si(1); + CGAL::SMDS_3::build_triangulation_one_subdomain(tr, points, finite_cells, default_si, border_facets, + /*verbose = */false, /*replace_domain_0 = */false, /*allow_non_manifold =*/false); + + CGAL_assertion(CGAL::SMDS_3::internal::is_convex(tr)); + + return tr; + } + + /** \ingroup PkgSMDS3Functions + * builds a 3D triangulation from a soup of tetrahedra. + * + * @tparam PointRange a model of the concept `RandomAccessContainer` + * whose value type is the point type. + * The point type must be convertible to `Triangulation::Point`. + * @tparam TetrahedronRange a model of the concept `RandomAccessContainer` whose + * value type is a model of the concept `RandomAccessContainer` whose value type is `std::size_t` + * @tparam Triangulation a 3D triangulation class that has + * a vertex base model of `MeshVertexBase_3` + * and a cell base model of `MeshCellBase_3` + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * @param points points of the soup of tetrahedra + * @param tets the set of finite tetrahedra of a valid CGAL triangulation. + * Each element in the range describes a tetrahedron using the indices of the points + * in `points`. + * It must + * describe a non self-intersecting set of tetrahedra, that cover the convex hull of the + * corresponding point set. The tetrahedra must form a valid triangulation with each + * pair of neighboring cells sharing exactly one triangle. Combinatorial validity and + * validity of the geometric embedding are required. + * + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{surface_facets} + * \cgalParamDescription{each element in the range describes a surface facet using the indices of points + * in `points` (indices 0 to 2), and the associated `Surface_patch_index` (index 3)} + * \cgalParamType{a class model of `AssociativeContainer` + * whose key type is model of `RandomAccessContainer` containing `int` + * and mapped type is `Tr::Cell::Surface_patch_index`} + * \cgalParamDefault{an empty `boost::unordered_map, typename Tr::Cell::Surface_patch_index>`} + * \cgalParamExtra{to avoid copies of large data sets, this parameter can be passed using `std::cref`} + * \cgalParamNEnd + * \cgalParamNBegin{subdomain_indices} + * \cgalParamDescription{each element in the range gives the + * `Triangulation::Cell::Subdomain_index` corresponding to the tetrahedron (cell) + * of same index in `tets`} + * \cgalParamType{a class model of `RandomAccessContainer` whose value type + * is `Triangulation::Cell::Subdomain_index`} + * \cgalParamDefault{each finite cell of the output triangulation is + * set to have `1` as `Subdomain_index`} + * \cgalParamExtra{to avoid copies of large data sets, this parameter can be passed using `std::cref`} + * \cgalParamNEnd + *\cond SKIP_IN_MANUAL + * \cgalParamNBegin{allow_non_manifold} + * \cgalParamDescription{allows the construction of a triangulation with non-manifold edges + * and non manifold vertices. The triangulation is invalid if this situation is met, + * so it should be used only in advanced cases, and the triangulation will be hardly usable.} + * \cgalParamType{bool} + * \cgalParamDefault{false} + * \cgalParamNEnd + *\endcond + * \cgalNamedParamsEnd + * + * @returns the 3D triangulation built from parameters + * + * @pre `points` contains each point only once + * @post the output triangulation must be a triangulation of the convex hull of `points` + * @post `is_valid()` returns `true` for the returned triangulation + * + * @sa \link polygon_soup_to_polygon_mesh() `CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh()` \endlink + * @sa @ref SMDS_3/tetrahedron_soup_to_c3t3_example.cpp + * + */ + template + Triangulation tetrahedron_soup_to_triangulation_3(const PointRange& points, + const TetrahedronRange& tets, + const NamedParameters& np = parameters::default_values()) + { + using parameters::choose_parameter; + using parameters::get_parameter; + using parameters::get_parameter_reference; + + using Default_facet_map + = boost::unordered_map, + typename Triangulation::Cell::Surface_patch_index>; + using Facet_map_ref_type + = typename internal_np::Lookup_named_param_def< + internal_np::surface_facets_t, + NamedParameters, + Default_facet_map>::reference; + using Subdomains_ref_type + = typename internal_np::Lookup_named_param_def< + internal_np::subdomain_indices_t, + NamedParameters, + int>::reference; + + Triangulation tr; + Default_facet_map empty_map; + const Facet_map_ref_type& facets = choose_parameter( + get_parameter_reference(np, internal_np::surface_facets), + empty_map); + const Subdomains_ref_type& subdomains = choose_parameter( + get_parameter_reference(np, internal_np::subdomain_indices), + 1); + const bool non_manifold = choose_parameter( + get_parameter(np, internal_np::allow_non_manifold), + false); + + CGAL::SMDS_3::build_triangulation_with_subdomains_range(tr, points, tets, subdomains, facets, + /*verbose = */false, /*replace_domain_0 = */false, non_manifold); + + CGAL_assertion(CGAL::SMDS_3::internal::is_convex(tr)); + + return tr; + } + +} //namespace CGAL + + +#endif // CGAL_SMDS_3_TETRAHEDRON_SOUP_TO_C3T3_H diff --git a/SMDS_3/package_info/SMDS_3/copyright b/SMDS_3/package_info/SMDS_3/copyright new file mode 100644 index 00000000000..8932b3233d2 --- /dev/null +++ b/SMDS_3/package_info/SMDS_3/copyright @@ -0,0 +1,2 @@ +INRIA Sophia-Antipolis (France) + diff --git a/SMDS_3/package_info/SMDS_3/dependencies b/SMDS_3/package_info/SMDS_3/dependencies new file mode 100644 index 00000000000..41ea78306d3 --- /dev/null +++ b/SMDS_3/package_info/SMDS_3/dependencies @@ -0,0 +1,29 @@ +Algebraic_foundations +Arithmetic_kernel +BGL +Cartesian_kernel +Circulator +Distance_2 +Distance_3 +Filtered_kernel +Hash_map +Homogeneous_kernel +Installation +Intersections_2 +Intersections_3 +Interval_support +Kernel_23 +Kernel_d +Modular_arithmetic +Number_types +Polygon_mesh_processing +Profiling_tools +Property_map +Random_numbers +STL_Extension +Spatial_sorting +Stream_support +SMDS_3 +TDS_3 +Triangulation_3 +Union_find diff --git a/SMDS_3/package_info/SMDS_3/description.txt b/SMDS_3/package_info/SMDS_3/description.txt new file mode 100644 index 00000000000..75585704c22 --- /dev/null +++ b/SMDS_3/package_info/SMDS_3/description.txt @@ -0,0 +1,2 @@ +Package SMDS_3 : +Simplicial Mesh Data Structures \ No newline at end of file diff --git a/SMDS_3/package_info/SMDS_3/license.txt b/SMDS_3/package_info/SMDS_3/license.txt new file mode 100644 index 00000000000..8bb8efcb72b --- /dev/null +++ b/SMDS_3/package_info/SMDS_3/license.txt @@ -0,0 +1 @@ +GPL (v3 or later) diff --git a/SMDS_3/package_info/SMDS_3/maintainer b/SMDS_3/package_info/SMDS_3/maintainer new file mode 100644 index 00000000000..880cb264269 --- /dev/null +++ b/SMDS_3/package_info/SMDS_3/maintainer @@ -0,0 +1,2 @@ +Laurent Rineau +Jane Tournois diff --git a/SMDS_3/test/SMDS_3/CMakeLists.txt b/SMDS_3/test/SMDS_3/CMakeLists.txt new file mode 100644 index 00000000000..43cea5fc098 --- /dev/null +++ b/SMDS_3/test/SMDS_3/CMakeLists.txt @@ -0,0 +1,30 @@ +# Created by the script cgal_create_cmake_script +# This is the CMake script for compiling a CGAL application. + +cmake_minimum_required(VERSION 3.1...3.20) +project( SMDS_3_Tests ) + +find_package(CGAL REQUIRED) + +# Use Eigen +find_package(Eigen3 3.1.0 REQUIRED) #(requires 3.1.0 or greater) +include(CGAL_Eigen3_support) + +create_single_source_cgal_program( "test_c3t3.cpp" ) +create_single_source_cgal_program( "test_c3t3_io.cpp" ) +create_single_source_cgal_program( "test_c3t3_with_features.cpp" ) +create_single_source_cgal_program( "test_c3t3_into_facegraph.cpp" ) +create_single_source_cgal_program( "test_c3t3_extract_subdomains_boundaries.cpp" ) +create_single_source_cgal_program( "test_c3t3_io_MEDIT.cpp" ) +create_single_source_cgal_program( "test_simplicial_cb_vb.cpp") + +foreach(target + test_c3t3 + test_c3t3_io + test_c3t3_with_features + test_c3t3_into_facegraph + test_c3t3_extract_subdomains_boundaries) + if(TARGET ${target}) + target_link_libraries(${target} PUBLIC CGAL::Eigen3_support) + endif() +endforeach() diff --git a/Mesh_3/test/Mesh_3/data/c3t3_io-hetero.binary.cgal b/SMDS_3/test/SMDS_3/data/c3t3_io-hetero.binary.cgal similarity index 100% rename from Mesh_3/test/Mesh_3/data/c3t3_io-hetero.binary.cgal rename to SMDS_3/test/SMDS_3/data/c3t3_io-hetero.binary.cgal diff --git a/Mesh_3/test/Mesh_3/data/c3t3_io-hetero.cgal b/SMDS_3/test/SMDS_3/data/c3t3_io-hetero.cgal similarity index 100% rename from Mesh_3/test/Mesh_3/data/c3t3_io-hetero.cgal rename to SMDS_3/test/SMDS_3/data/c3t3_io-hetero.cgal diff --git a/Mesh_3/test/Mesh_3/data/c3t3_io-homo.binary.cgal b/SMDS_3/test/SMDS_3/data/c3t3_io-homo.binary.cgal similarity index 100% rename from Mesh_3/test/Mesh_3/data/c3t3_io-homo.binary.cgal rename to SMDS_3/test/SMDS_3/data/c3t3_io-homo.binary.cgal diff --git a/Mesh_3/test/Mesh_3/data/c3t3_io-homo.cgal b/SMDS_3/test/SMDS_3/data/c3t3_io-homo.cgal similarity index 100% rename from Mesh_3/test/Mesh_3/data/c3t3_io-homo.cgal rename to SMDS_3/test/SMDS_3/data/c3t3_io-homo.cgal diff --git a/Mesh_3/test/Mesh_3/test_c3t3.cpp b/SMDS_3/test/SMDS_3/test_c3t3.cpp similarity index 98% rename from Mesh_3/test/Mesh_3/test_c3t3.cpp rename to SMDS_3/test/SMDS_3/test_c3t3.cpp index ffbc80d090a..78835c78fda 100644 --- a/Mesh_3/test/Mesh_3/test_c3t3.cpp +++ b/SMDS_3/test/SMDS_3/test_c3t3.cpp @@ -37,10 +37,6 @@ struct Tester typedef typename CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - typedef CGAL::Mesh_3::Mesh_complex_3_in_triangulation_3_base C3t3_base_sequential; - typedef CGAL::Mesh_3::Mesh_complex_3_in_triangulation_3_base C3t3_base_parallel; typedef typename Tr::Bare_point Bare_point; typedef typename Tr::Weighted_point Weighted_point; @@ -254,7 +250,7 @@ struct Tester //------------------------------------------------------- std::cout << "Insert 6 points from domain in c3t3_bis, add 1 cell to c3t3_bis\n"; Polyhedron polyhedron; - std::ifstream input("data/sphere.off"); + std::ifstream input(CGAL::data_file_path("meshes/sphere.off")); input >> polyhedron; input.close(); Mesh_domain domain(polyhedron); @@ -393,7 +389,8 @@ struct Tester assert ( c3t3.surface_patch_index(*patch_fit_bis) == surface_patch_index_bis ); std::ofstream out_medit("test-medit.mesh"); - CGAL::IO::output_to_medit(out_medit, c3t3); + CGAL::IO::write_MEDIT(out_medit, c3t3); + out_medit.close(); CGAL::IO::output_to_tetgen("test-tetgen", c3t3); } }; diff --git a/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp b/SMDS_3/test/SMDS_3/test_c3t3_extract_subdomains_boundaries.cpp similarity index 100% rename from Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp rename to SMDS_3/test/SMDS_3/test_c3t3_extract_subdomains_boundaries.cpp diff --git a/Mesh_3/test/Mesh_3/test_c3t3_into_facegraph.cpp b/SMDS_3/test/SMDS_3/test_c3t3_into_facegraph.cpp similarity index 80% rename from Mesh_3/test/Mesh_3/test_c3t3_into_facegraph.cpp rename to SMDS_3/test/SMDS_3/test_c3t3_into_facegraph.cpp index 05ea8149ca6..b31fbe22f0a 100644 --- a/Mesh_3/test/Mesh_3/test_c3t3_into_facegraph.cpp +++ b/SMDS_3/test/SMDS_3/test_c3t3_into_facegraph.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include @@ -33,25 +33,23 @@ int main (int argc, char** argv){ Cell_base_with_info>::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - + typedef C3t3::Triangulation::Cell_handle Cell_handle; // Open file - std::ifstream in (argc > 1 ? argv[1] : "data/elephant.mesh", + std::ifstream in (argc > 1 ? argv[1] : CGAL::data_file_path("meshes/elephant.mesh"), std::ios_base::in); if(!in) { std::cerr << "Error! Cannot open file " << argv[1] << std::endl; return 1; } C3t3 c3t3; - if(CGAL::build_triangulation_from_file(in, c3t3.triangulation())) + if(CGAL::SMDS_3::build_triangulation_from_file(in, c3t3.triangulation())) { - for( C3t3::Triangulation::Finite_cells_iterator - cit = c3t3.triangulation().finite_cells_begin(); - cit != c3t3.triangulation().finite_cells_end(); - ++cit) + for( Cell_handle cit : c3t3.triangulation().finite_cell_handles()) { assert(cit->subdomain_index() >= 0); - c3t3.add_to_complex(cit, cit->subdomain_index()); + if(cit->subdomain_index() > 0) + c3t3.add_to_complex(cit, cit->subdomain_index()); for(int i=0; i < 4; ++i) { if(cit->surface_patch_index(i)>0) @@ -64,10 +62,7 @@ int main (int argc, char** argv){ //if there is no facet in the complex, we add the border facets. if(c3t3.number_of_facets_in_complex() == 0) { - for( C3t3::Triangulation::All_cells_iterator - cit = c3t3.triangulation().all_cells_begin(); - cit != c3t3.triangulation().all_cells_end(); - ++cit) + for( Cell_handle cit : c3t3.triangulation().all_cell_handles()) { if(c3t3.triangulation().is_infinite(cit)) { @@ -89,6 +84,7 @@ int main (int argc, char** argv){ std::ofstream out("graph.off"); out << poly; + out.close(); assert(is_valid(poly)); return EXIT_SUCCESS; diff --git a/Mesh_3/test/Mesh_3/test_c3t3_io.cpp b/SMDS_3/test/SMDS_3/test_c3t3_io.cpp similarity index 99% rename from Mesh_3/test/Mesh_3/test_c3t3_io.cpp rename to SMDS_3/test/SMDS_3/test_c3t3_io.cpp index a937d691868..ef8d9e16d7a 100644 --- a/Mesh_3/test/Mesh_3/test_c3t3_io.cpp +++ b/SMDS_3/test/SMDS_3/test_c3t3_io.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/SMDS_3/test/SMDS_3/test_c3t3_io_MEDIT.cpp b/SMDS_3/test/SMDS_3/test_c3t3_io_MEDIT.cpp new file mode 100644 index 00000000000..cb905e69edc --- /dev/null +++ b/SMDS_3/test/SMDS_3/test_c3t3_io_MEDIT.cpp @@ -0,0 +1,54 @@ +#include + +#include +#include +#include + +#include + +#include +#include +#include + +int main() +{ + using K = CGAL::Exact_predicates_inexact_constructions_kernel; + using Tr = CGAL::Tetrahedral_remeshing::Remeshing_triangulation_3; + + // Open file elephant + std::string filename = CGAL::data_file_path("meshes/elephant.mesh"); + std::ifstream in(filename, std::ios_base::in); + if(!in) { + std::cerr << "Error! Cannot open file " << filename << std::endl; + return 1; + } + Tr tr; + CGAL::IO::read_MEDIT(in, tr); + assert(tr.is_valid()); + + std::ofstream os("elephant_out.mesh"); + CGAL::IO::write_MEDIT(os, tr, + CGAL::parameters::all_vertices(false).all_cells(true)); + os.close(); + + CGAL::Bbox_3 bb(tr.finite_vertices_begin()->point().bbox()); + for (auto v : tr.finite_vertex_handles()) + bb = bb + v->point().bbox(); + + CGAL::Iso_cuboid_3 isocuboid(bb); + for (int i = 0; i < 8; ++i) + tr.insert(isocuboid.vertex(i)); + + std::ofstream os2("elephant_out_not_all_vertices.mesh"); + CGAL::IO::write_MEDIT(os2, tr, + CGAL::parameters::all_vertices(false)); + os2.close(); + + Tr tr2; + std::ifstream is2("elephant_out_not_all_vertices.mesh"); + CGAL::IO::read_MEDIT(is2, tr2);; + is2.close(); + assert(tr2.is_valid()); + + return EXIT_SUCCESS; +} diff --git a/Mesh_3/test/Mesh_3/test_c3t3_with_features.cpp b/SMDS_3/test/SMDS_3/test_c3t3_with_features.cpp similarity index 99% rename from Mesh_3/test/Mesh_3/test_c3t3_with_features.cpp rename to SMDS_3/test/SMDS_3/test_c3t3_with_features.cpp index 6280238c60b..737bfcacb33 100644 --- a/Mesh_3/test/Mesh_3/test_c3t3_with_features.cpp +++ b/SMDS_3/test/SMDS_3/test_c3t3_with_features.cpp @@ -18,6 +18,8 @@ #include "test_utilities.h" +#include +#include #include #include diff --git a/SMDS_3/test/SMDS_3/test_simplicial_cb_vb.cpp b/SMDS_3/test/SMDS_3/test_simplicial_cb_vb.cpp new file mode 100644 index 00000000000..4f3531c5fcb --- /dev/null +++ b/SMDS_3/test/SMDS_3/test_simplicial_cb_vb.cpp @@ -0,0 +1,45 @@ +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +using K = CGAL::Exact_predicates_inexact_constructions_kernel; + +using Subdomain_index = int; +using Surface_patch_index = std::pair; +using Curve_index = char; +using Corner_index = short; + +using Cb = CGAL::Simplicial_mesh_cell_base_3; +using Vb = CGAL::Simplicial_mesh_vertex_base_3; + +using Tds = CGAL::Triangulation_data_structure_3; +using Tr = CGAL::Triangulation_3; + +using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; + +int main () +{ + Tr triangulation; + auto rng = CGAL::Random_points_on_sphere_3(1.); + while (triangulation.number_of_vertices() < 100) + { + triangulation.insert(*rng++); + } + + C3t3 c3t3; + c3t3.triangulation() = std::move(triangulation); + + + return EXIT_SUCCESS; +} diff --git a/SMDS_3/test/SMDS_3/test_utilities.h b/SMDS_3/test/SMDS_3/test_utilities.h new file mode 100644 index 00000000000..16797ae26bc --- /dev/null +++ b/SMDS_3/test/SMDS_3/test_utilities.h @@ -0,0 +1,51 @@ +// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Stephane Tayeb +// +//****************************************************************************** +// File Description : +// +//****************************************************************************** + +#ifndef CGAL_MESH_3_TEST_TEST_UTILITIES_H +#define CGAL_MESH_3_TEST_TEST_UTILITIES_H + +#include +#include + +#include +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K_e_i; +typedef CGAL::Exact_predicates_exact_constructions_kernel K_e_e; + +namespace CGAL { +namespace details { + +template<> +struct Mesh_geom_traits_generator +{ +private: + typedef K_e_e Geom_traits; + +public: + typedef Geom_traits type; + typedef type Type; +}; // end struct Mesh_geom_traits_generator<...> + +} // end namespace details +} // end namespace CGAL + +#include + +#endif // CGAL_MESH_3_TEST_TEST_UTILITIES_H diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h index cfc54c6631c..184bb2ce429 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -32,6 +32,8 @@ CGAL_add_named_parameter(face_partition_id_t, face_partition_id, face_partition_ CGAL_add_named_parameter(vertex_to_vertex_output_iterator_t, vertex_to_vertex_output_iterator, vertex_to_vertex_output_iterator) CGAL_add_named_parameter(halfedge_to_halfedge_output_iterator_t, halfedge_to_halfedge_output_iterator, halfedge_to_halfedge_output_iterator) CGAL_add_named_parameter(face_to_face_output_iterator_t, face_to_face_output_iterator, face_to_face_output_iterator) +CGAL_add_named_parameter(point_to_vertex_output_iterator_t, point_to_vertex_output_iterator, point_to_vertex_output_iterator) +CGAL_add_named_parameter(polygon_to_face_output_iterator_t, polygon_to_face_output_iterator, polygon_to_face_output_iterator) CGAL_add_named_parameter(vertex_to_vertex_map_t, vertex_to_vertex_map, vertex_to_vertex_map) CGAL_add_named_parameter(halfedge_to_halfedge_map_t, halfedge_to_halfedge_map, halfedge_to_halfedge_map) @@ -214,6 +216,15 @@ CGAL_add_named_parameter(smooth_constrained_edges_t, smooth_constrained_edges, s CGAL_add_named_parameter(do_enforce_manifoldness_t, do_enforce_manifoldness, do_enforce_manifoldness) CGAL_add_named_parameter(seed_points_t, seed_points, seed_points) +// SMDS_3 parameters +CGAL_add_named_parameter(surface_facets_t, surface_facets, surface_facets) +CGAL_add_named_parameter(subdomain_indices_t, subdomain_indices, subdomain_indices) +CGAL_add_named_parameter(all_vertices_t, all_vertices, all_vertices) +CGAL_add_named_parameter(all_cells_t, all_cells, all_cells) +CGAL_add_named_parameter(rebind_labels_t, rebind_labels, rebind_labels) +CGAL_add_named_parameter(show_patches_t, show_patches, show_patches) +CGAL_add_named_parameter(allow_non_manifold_t, allow_non_manifold, allow_non_manifold) + // output parameters CGAL_add_named_parameter(face_proxy_map_t, face_proxy_map, face_proxy_map) CGAL_add_named_parameter(proxies_t, proxies, proxies) diff --git a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt index 2bc5e41c1a6..4834a83616b 100644 --- a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt +++ b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt @@ -432,8 +432,10 @@ A precise specification of the format is available VTK Libraries, - it is the format reserved to store `Unstructured Grids`, and in \cgal, + but also points, triangles, lines, etc. In the VTK Libraries. + It is the format reserved to store + `Unstructured Grids`, + and in \cgal, we use it to store triangulations (2D and 3D). - The `VTP` format can be used to store collections of points, lines, and triangles. @@ -473,8 +475,8 @@ A precise specification of those formats is available at The following \cgal data structures can be exported into the `.VTU` file format: -- `CGAL::Mesh_complex_3_in_triangulation_3`, using \link PkgMesh3IOFunctions `CGAL::IO::output_to_vtu()` \endlink -- `CGAL::Constrained_Delaunay_triangulation_2`, using the function \link PkgMesh2IO `CGAL::IO::write_VTU()` \endlink +- `CGAL::Mesh_complex_3_in_triangulation_3`, using \link CGAL::IO::output_to_vtu() `CGAL::IO::output_to_vtu()` \endlink +- `CGAL::Constrained_Delaunay_triangulation_2`, using the function \link CGAL::IO::write_VTU `CGAL::IO::write_VTU()` \endlink \section IOStreamAvizo Avizo File Format @@ -483,7 +485,7 @@ The AmiraMesh format, using file extension `.am`, is used by the Avizo software to read 3D geometry. A single \cgal data structure, `CGAL::Mesh_complex_3_in_triangulation_3`, can be exported into `.am` files. -This can be done using the function `CGAL::IO::output_to_avizo()`. +This can be done using the function \link CGAL::IO::output_to_avizo() `CGAL::IO::output_to_avizo()`\endlink. A precise specification of the format is available in this guide. @@ -497,7 +499,7 @@ A precise specification of the format is available vertex(0)->point(), c->vertex(1)->point(), - c->vertex(2)->point(), c->vertex(3)->point()))) + CGAL::centroid(P(c->vertex(0)->point()), + P(c->vertex(1)->point()), + P(c->vertex(2)->point()), + P(c->vertex(3)->point())))) c->set_subdomain_index(1); else c->set_subdomain_index(2); diff --git a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp index 9b39e266518..032cca7e1d3 100644 --- a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp +++ b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp @@ -62,11 +62,8 @@ public: void set_subdomain(Remeshing_triangulation& tr, const int index) { - for (Remeshing_triangulation::Finite_cells_iterator cit = tr.finite_cells_begin(); - cit != tr.finite_cells_end(); ++cit) - { + for (auto cit : tr.finite_cell_handles()) cit->set_subdomain_index(index); - } } int main(int argc, char* argv[]) diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/Remeshing_cell_base_3.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/Remeshing_cell_base_3.h index ca287666196..d8237882726 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/Remeshing_cell_base_3.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/Remeshing_cell_base_3.h @@ -15,49 +15,88 @@ #include -#include +#include namespace CGAL { namespace Tetrahedral_remeshing { -namespace internal + +template +class Remeshing_cell_3 + : public CGAL::Simplicial_mesh_cell_3 { -struct Fake_MD_C -{ - typedef int Subdomain_index; - typedef int Surface_patch_index; - typedef int Index; +private: + using Base = CGAL::Simplicial_mesh_cell_3; + +public: + using Base::Base; + + void set_sliver_value(double value) + { + sliver_cache_validity_ = true; + sliver_value_ = value; + } + + double sliver_value() const + { + CGAL_assertion(is_cache_valid()); + return sliver_value_; + } + + bool is_cache_valid() const { return sliver_cache_validity_; } + void reset_cache_validity() const { sliver_cache_validity_ = false; } + +private: + double sliver_value_ = 0.; + mutable bool sliver_cache_validity_ = false; }; -} /*! \ingroup PkgTetrahedralRemeshingClasses -The class `Remeshing_cell_base_3` is a model of the concept `MeshCellBase_3`. +The class `Remeshing_cell_base_3` is a model of the concept `SimplicialMeshCellBase_3`. It is designed to serve as cell base class for the 3D triangulation used in the tetrahedral remeshing process. -\tparam Gt is the geometric traits class. -It has to be a model of the concept `RemeshingTriangulationTraits_3`. +\tparam Subdomain_index Type of indices for subdomains of the discretized geometric domain. +Must be a model of `CopyConstructible`, `Assignable`, `DefaultConstructible` +and `EqualityComparable`. The default constructed value must match the label +of the exterior of the domain (which contains at least the unbounded component). + It must match the `Subdomain_index` of the model + of the `MeshDomain_3` concept when used for mesh generation. -\tparam Cb is a cell base class from which `Remeshing_cell_base_3` derives. -It must be a model of the `TriangulationCellBase_3` concept. -It has the default value `Triangulation_cell_base_3`. +\tparam Surface_patch_index Type of indices for surface patches (boundaries and interfaces) +of the discretized geometric domain. +Must be a model of `CopyConstructible`, `Assignable`, `DefaultConstructible` +and `EqualityComparable`. The default constructed value must be the index value +assigned to a non surface facet. + It must match the `Surface_patch_index` of the model + of the `MeshDomain_3` concept when used for mesh generation. -\cgalModels `MeshCellBase_3` +\cgalModels `RemeshingCellBase_3` +\cgalModels `SimplicialMeshCellBase_3` */ -#ifndef DOXYGEN_RUNNING -template > -using Remeshing_cell_base_3 - = CGAL::Mesh_cell_base_3; -#else -template > -class Remeshing_cell_base_3; -#endif +template +class Remeshing_cell_base_3 +{ +public: + template + struct Rebind_TDS + { + typedef Remeshing_cell_3 Other; + }; +}; }//end namespace Tetrahedral_remeshing }//end namespace CGAL diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/Remeshing_triangulation_3.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/Remeshing_triangulation_3.h index 3104978addb..7021252fd26 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/Remeshing_triangulation_3.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/Remeshing_triangulation_3.h @@ -21,8 +21,6 @@ #include #include -#include -#include #include #include @@ -55,7 +53,7 @@ and `Parallel_if_available_tag`. template, - typename Cb = Remeshing_cell_base_3 + typename Cb = Remeshing_cell_base_3<> > class Remeshing_triangulation_3 : public CGAL::Triangulation_3 > diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/Remeshing_vertex_base_3.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/Remeshing_vertex_base_3.h index 3d0f8b20170..b828ffb08d1 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/Remeshing_vertex_base_3.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/Remeshing_vertex_base_3.h @@ -15,23 +15,12 @@ #include -#include +#include namespace CGAL { namespace Tetrahedral_remeshing { -namespace internal -{ - -struct Fake_MD_V -{ - typedef int Subdomain_index; - typedef int Surface_patch_index; - typedef int Index; -}; - -} // internal /*! \ingroup PkgTetrahedralRemeshingClasses @@ -47,18 +36,22 @@ It has to be a model of the concept `RemeshingTriangulationTraits_3`. It must be a model of the `TriangulationVertexBase_3` concept. It has the default value `Triangulation_vertex_base_3`. -\cgalModels `MeshVertexBase_3` +\cgalModels `RemeshingVertexBase_3` +\cgalModels `SimplicialMeshVertexBase_3` */ -#ifndef DOXYGEN_RUNNING template > + typename Subdomain_index = int, + typename Surface_patch_index = int, + typename Curve_index = int, + typename Corner_index = int, + typename Vb = CGAL::Triangulation_vertex_base_3 > using Remeshing_vertex_base_3 - = CGAL::Mesh_vertex_base_3; -#else -template > -class Remeshing_vertex_base_3; -#endif + = CGAL::Simplicial_mesh_vertex_base_3; }//end namespace Tetrahedral_remeshing diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h index 4923e35923d..c107aec320a 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/collapse_short_edges.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include @@ -67,8 +67,8 @@ public: , v0_init(e.first->vertex(e.second)) , v1_init(e.first->vertex(e.third)) { - typedef std::array Facet; // 3 = id - typedef std::array Tet_with_ref; // first 4 = id, fifth = reference + typedef std::array Facet; + typedef std::array Tet; std::unordered_set vertices_to_insert; for (Cell_handle ch : cells_to_insert) @@ -96,23 +96,25 @@ public: } } - std::vector finite_cells; + std::vector finite_cells; + std::vector subdomains; for (Cell_handle ch : cells_to_insert) { - Tet_with_ref t = { { v2i.at(ch->vertex(0)), - v2i.at(ch->vertex(1)), - v2i.at(ch->vertex(2)), - v2i.at(ch->vertex(3)), - ch->subdomain_index() } }; - finite_cells.push_back(t); + finite_cells.push_back( { v2i.at(ch->vertex(0)), + v2i.at(ch->vertex(1)), + v2i.at(ch->vertex(2)), + v2i.at(ch->vertex(3)) } ); + subdomains.push_back(ch->subdomain_index()); } // finished std::vector new_vertices; std::map border_facets; - if (CGAL::build_triangulation(triangulation, - points, finite_cells, border_facets, - new_vertices, false/*verbose*/)) + if (CGAL::SMDS_3::build_triangulation_impl( + triangulation, points, finite_cells, subdomains, border_facets, + new_vertices, /*verbose*/ false, + /*replace_domain_0*/ false, + /*allow_non_manifold*/false)) { CGAL_assertion(triangulation.tds().is_valid()); CGAL_assertion(triangulation.infinite_vertex() == new_vertices[0]); diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/compute_c3t3_statistics.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/compute_c3t3_statistics.h index 1a6ecb15002..a2c8191fa8f 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/compute_c3t3_statistics.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/compute_c3t3_statistics.h @@ -39,7 +39,7 @@ void compute_statistics(const Triangulation& tr, typedef typename Tr::Cell_handle Cell_handle; typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Gt::Point_3 Point; - typedef typename Tr::Finite_facets_iterator Finite_facets_iterator; + typedef typename Tr::Facet Facet; typedef typename Tr::Finite_cells_iterator Finite_cells_iterator; typedef typename Tr::Cell::Subdomain_index Subdomain_index; @@ -55,11 +55,10 @@ void compute_statistics(const Triangulation& tr, double max_dihedral_angle = 0.; double min_dihedral_angle = 180.; - for (Finite_facets_iterator fit = tr.finite_facets_begin(); - fit != tr.finite_facets_end(); ++fit) + for (Facet fit : tr.finite_facets()) { - const Cell_handle cell = fit->first; - const int& index = fit->second; + const Cell_handle cell = fit.first; + const int& index = fit.second; if (!cell_selector(cell) || !cell_selector(cell->neighbor(index))) continue; diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/smooth_vertices.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/smooth_vertices.h index 0b371947a6e..745f89bb1d2 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/smooth_vertices.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/smooth_vertices.h @@ -381,15 +381,13 @@ private: std::unordered_map >& vertices_surface_indices) { - for (typename C3t3::Facets_in_complex_iterator - fit = c3t3.facets_in_complex_begin(); - fit != c3t3.facets_in_complex_end(); ++fit) + for (Facet fit : c3t3.facets_in_complex()) { - const Surface_patch_index& surface_index = c3t3.surface_patch_index(*fit); + const Surface_patch_index& surface_index = c3t3.surface_patch_index(fit); for (int i = 0; i < 3; i++) { - const Vertex_handle vi = fit->first->vertex(indices(fit->second, i)); + const Vertex_handle vi = fit.first->vertex(indices(fit.second, i)); std::vector& v_surface_indices = vertices_surface_indices[vi]; if (std::find(v_surface_indices.begin(), v_surface_indices.end(), surface_index) == v_surface_indices.end()) diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/split_long_edges.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/split_long_edges.h index 76851bc76e9..86e7aa27856 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/split_long_edges.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/split_long_edges.h @@ -239,7 +239,6 @@ void split_long_edges(C3T3& c3t3, typedef typename C3T3::Triangulation T3; typedef typename T3::Cell_handle Cell_handle; typedef typename T3::Edge Edge; - typedef typename T3::Finite_edges_iterator Finite_edges_iterator; typedef typename T3::Vertex_handle Vertex_handle; typedef typename std::pair Edge_vv; @@ -260,10 +259,8 @@ void split_long_edges(C3T3& c3t3, //collect long edges T3& tr = c3t3.triangulation(); Boost_bimap long_edges; - for (Finite_edges_iterator eit = tr.finite_edges_begin(); - eit != tr.finite_edges_end(); ++eit) + for (Edge e : tr.finite_edges()) { - Edge e = *eit; if (!can_be_split(e, c3t3, protect_boundaries, cell_selector)) continue; diff --git a/Tetrahedral_remeshing/package_info/Tetrahedral_remeshing/dependencies b/Tetrahedral_remeshing/package_info/Tetrahedral_remeshing/dependencies index 57bd26ce97b..d9c5098d64f 100644 --- a/Tetrahedral_remeshing/package_info/Tetrahedral_remeshing/dependencies +++ b/Tetrahedral_remeshing/package_info/Tetrahedral_remeshing/dependencies @@ -14,13 +14,13 @@ Intersections_3 Interval_support Kernel_23 Kernel_d -Mesh_3 Modular_arithmetic Number_types Polygon_mesh_processing Profiling_tools Property_map Random_numbers +SMDS_3 STL_Extension Spatial_sorting Stream_support diff --git a/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_tetrahedral_remeshing_from_mesh_file.cpp b/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_tetrahedral_remeshing_from_mesh_file.cpp index cb748e0e92b..30c83e1c533 100644 --- a/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_tetrahedral_remeshing_from_mesh_file.cpp +++ b/Tetrahedral_remeshing/test/Tetrahedral_remeshing/test_tetrahedral_remeshing_from_mesh_file.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; @@ -23,7 +23,7 @@ int main(int argc, char* argv[]) Remeshing_triangulation tr; std::ifstream in("data/sphere.mesh"); - if (CGAL::build_triangulation_from_file(in, tr)) + if (CGAL::SMDS_3::build_triangulation_from_file(in, tr)) std::cout << "build triangulation ok" << std::endl; CGAL::tetrahedral_isotropic_remeshing(tr, target_edge_length);