diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bfad0a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/data/ +/scenes/ +.gitignore +*.vtk +*.obj +*.sxn +*.scn +*.csv \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 2dfdd3c..3b0951f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,11 +4,9 @@ project(MeshSkeletonizationPlugin VERSION 0.1) # Dependencies find_package(Sofa.Config REQUIRED) sofa_find_package(Sofa.Core REQUIRED) - sofa_find_package(CGAL REQUIRED) message(STATUS "CGAL VERSION = ${CGAL_VERSION}") - set(PLUGIN_SKELETONIZATION_SRC_DIR src/MeshSkeletonizationPlugin) set(HEADER_FILES @@ -16,11 +14,18 @@ set(HEADER_FILES ${PLUGIN_SKELETONIZATION_SRC_DIR}/init.h ${PLUGIN_SKELETONIZATION_SRC_DIR}/MeshSkeletonization.h ${PLUGIN_SKELETONIZATION_SRC_DIR}/MeshSkeletonization.inl + ${PLUGIN_SKELETONIZATION_SRC_DIR}/SkeletonGraph/SkeletonNode.h + ${PLUGIN_SKELETONIZATION_SRC_DIR}/SkeletonGraph/SkeletonGraph.h + ${PLUGIN_SKELETONIZATION_SRC_DIR}/SkeletonGraph/SkeletonReader.h + ${PLUGIN_SKELETONIZATION_SRC_DIR}/SkeletonGraph/SkeletonReader.inl ) - set(SOURCE_FILES ${PLUGIN_SKELETONIZATION_SRC_DIR}/init.cpp ${PLUGIN_SKELETONIZATION_SRC_DIR}/MeshSkeletonization.cpp + ${PLUGIN_SKELETONIZATION_SRC_DIR}/SkeletonGraph/SkeletonGraph.cpp + ${PLUGIN_SKELETONIZATION_SRC_DIR}/SkeletonGraph/SkeletonReader.cpp + + ) set(README_FILES README.md) @@ -36,7 +41,6 @@ endif() target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Core) target_link_libraries(${PROJECT_NAME} PUBLIC CGAL::CGAL) - # Install rules for the library and the headers; CMake package configurations files sofa_create_package_with_targets( PACKAGE_NAME ${PROJECT_NAME} @@ -45,6 +49,4 @@ sofa_create_package_with_targets( INCLUDE_SOURCE_DIR "src" INCLUDE_INSTALL_DIR "MeshSkeletonizationPlugin" RELOCATABLE "plugins" - ) - - + ) \ No newline at end of file diff --git a/data/skeletons/output_elephant_skeleton.txt b/data/skeletons/output_elephant_skeleton.txt deleted file mode 100644 index 6d4fbf2..0000000 --- a/data/skeletons/output_elephant_skeleton.txt +++ /dev/null @@ -1,343 +0,0 @@ -0.304274 -0.291248 -0.250424 -0.302647 -0.289881 -0.248977 -0.297276 -0.285308 -0.244199 -0.292146 -0.280944 -0.239594 -0.289038 -0.278274 -0.236786 -0.285683 -0.275382 -0.233752 -0.280481 -0.271073 -0.229049 -0.271949 -0.264133 -0.221328 -0.265036 -0.258818 -0.215034 -0.259161 -0.254284 -0.20969 -0.251482 -0.250092 -0.201727 -0.243137 -0.245727 -0.192981 -0.235305 -0.241678 -0.184764 -0.227833 -0.237815 -0.176925 -0.218513 -0.232993 -0.167147 -0.215076 -0.231247 -0.163537 -0.209485 -0.228445 -0.157663 -0.200105 -0.223886 -0.147793 -0.18795 -0.218424 -0.134971 -0.181561 -0.215587 -0.128228 -0.176092 -0.213158 -0.122457 -0.169519 -0.210248 -0.115534 -0.159239 -0.207395 -0.105205 -0.149172 -0.204691 -0.095105 -0.137947 -0.201638 -0.083807 -0.133318 -0.200401 -0.0793757 -0.128658 -0.199008 -0.0749297 -0.122033 -0.196586 -0.0685831 -0.117464 -0.194879 -0.0642338 -0.107746 -0.191164 -0.0550172 -0.102221 -0.188476 -0.0496764 -0.0942284 -0.186856 -0.04298 -0.091142 -0.186444 -0.0404987 -0.0815543 -0.186474 -0.0341091 -0.0649747 -0.182916 -0.0225711 - --0.284054 -0.285435 -0.108735 --0.281476 -0.277091 -0.095993 - --0.115199 -0.442307 -0.0357321 --0.114791 -0.436449 -0.0342161 --0.114423 -0.430905 -0.0328438 --0.113915 -0.423333 -0.0310235 --0.113528 -0.415917 -0.0293852 --0.11289 -0.402413 -0.027104 --0.112333 -0.389729 -0.0249702 --0.111962 -0.381237 -0.0235545 --0.111743 -0.376263 -0.0227249 --0.111171 -0.362224 -0.0204328 --0.110355 -0.347708 -0.0187175 --0.109494 -0.333289 -0.0173042 --0.108793 -0.32167 -0.0162264 --0.107909 -0.307919 -0.0151566 --0.107401 -0.300161 -0.0145633 --0.106697 -0.289765 -0.0137818 --0.106227 -0.275945 -0.0130616 --0.106965 -0.264422 -0.0138855 --0.113892 -0.246007 -0.0161702 - -0.189818 0.462774 0.104523 -0.187338 0.459598 0.110298 -0.185763 0.457199 0.114082 -0.183784 0.454051 0.118868 -0.181637 0.450624 0.124052 -0.179026 0.445831 0.130438 -0.175324 0.438192 0.139638 -0.172154 0.429906 0.147814 -0.171106 0.426589 0.150649 -0.171546 0.411705 0.153946 -0.17207 0.396065 0.157321 -0.172454 0.388647 0.158639 -0.172817 0.383912 0.159234 -0.173071 0.380255 0.159752 -0.17411 0.371378 0.160117 -0.175238 0.362374 0.160337 -0.177473 0.349151 0.159352 -0.179615 0.338348 0.157907 -0.181311 0.330518 0.156218 -0.183558 0.32084 0.153404 -0.185643 0.312285 0.15011 -0.187001 0.306874 0.147965 -0.188495 0.301558 0.146672 -0.189642 0.290314 0.137897 - -0.189642 0.290314 0.137897 -0.186593 0.29258 0.126974 -0.18463 0.294052 0.119816 -0.183383 0.293614 0.110937 -0.184658 0.289383 0.10346 -0.186221 0.284495 0.0957773 -0.188532 0.277531 0.0869771 -0.190133 0.27267 0.0829182 -0.193153 0.263486 0.0754929 -0.196653 0.252591 0.0682734 -0.198372 0.243271 0.0686715 -0.199083 0.239432 0.0688007 -0.199973 0.234519 0.0690452 -0.202457 0.220696 0.0698033 -0.203662 0.213583 0.070449 -0.205036 0.204719 0.0717006 -0.206578 0.193236 0.0738441 -0.207364 0.184075 0.0786544 -0.207658 0.176482 0.0837088 -0.208203 0.173454 0.0925648 - -0.189642 0.290314 0.137897 -0.192508 0.281122 0.139373 -0.193237 0.279028 0.14004 -0.193651 0.277709 0.140253 -0.197763 0.26265 0.139702 - -0.208203 0.173454 0.0925648 -0.2062 0.15505 0.0892159 -0.203246 0.141251 0.0870482 -0.201826 0.135234 0.0853339 -0.199995 0.128554 0.0837052 -0.198312 0.122646 0.0821924 -0.19643 0.116389 0.0805636 -0.194901 0.11217 0.0796708 -0.191994 0.103518 0.0775343 -0.187981 0.0928067 0.0750022 -0.181591 0.0804684 0.0723386 -0.174602 0.0687515 0.0688773 -0.162871 0.0495551 0.0626244 -0.144622 0.0174678 0.0534465 - -0.208203 0.173454 0.0925648 -0.209191 0.177211 0.0985635 -0.211253 0.182546 0.10795 - -0.211253 0.182546 0.10795 -0.208897 0.189732 0.111516 -0.208193 0.194213 0.113584 -0.20772 0.19761 0.115139 -0.206801 0.204195 0.118202 -0.204927 0.215401 0.123471 -0.203727 0.224035 0.127462 -0.202429 0.235278 0.132896 -0.201062 0.242067 0.134738 -0.200512 0.246961 0.136396 -0.199636 0.252468 0.137727 -0.197763 0.26265 0.139702 - -0.211253 0.182546 0.10795 -0.220839 0.171023 0.113297 -0.22612 0.169842 0.118266 -0.234097 0.171724 0.127764 -0.240874 0.173517 0.136012 -0.248823 0.179511 0.147931 -0.256144 0.185382 0.159181 -0.257236 0.192826 0.166081 -0.257077 0.19896 0.170855 -0.256702 0.202209 0.173118 -0.253842 0.212199 0.178484 -0.252163 0.218393 0.181896 -0.249172 0.225069 0.184376 -0.2455 0.23116 0.185565 -0.240919 0.237282 0.185685 -0.235621 0.241758 0.181658 -0.230661 0.245943 0.177868 -0.227254 0.24877 0.175195 -0.220279 0.254464 0.169614 -0.213848 0.259367 0.163787 -0.208629 0.264027 0.158413 -0.203251 0.268621 0.152097 -0.197763 0.26265 0.139702 - -0.0312592 0.0670683 -0.0667248 -0.0599315 0.0644702 -0.0583819 -0.0767565 0.0628558 -0.0526307 -0.094512 0.060636 -0.0395838 -0.101594 0.059674 -0.0340962 -0.115684 0.0576223 -0.0228566 -0.120129 0.0566495 -0.018746 -0.124017 0.0548582 -0.013903 -0.126879 0.0510702 -0.00718614 -0.128626 0.0486502 -0.00289694 -0.130794 0.0456114 0.00243446 -0.135053 0.0390826 0.0134841 -0.136091 0.0346357 0.0200582 -0.136111 0.0197165 0.03358 -0.137016 0.0152211 0.0395288 -0.144622 0.0174678 0.0534465 - --0.302048 -0.391632 -0.208798 --0.298106 -0.383453 -0.202898 --0.294633 -0.375787 -0.196851 --0.292141 -0.37073 -0.192817 --0.2887 -0.363805 -0.187321 --0.284203 -0.354741 -0.180133 --0.279856 -0.345941 -0.173173 --0.272361 -0.332393 -0.1606 --0.265696 -0.321131 -0.149258 --0.259286 -0.309931 -0.13794 --0.250073 -0.290803 -0.116339 --0.242137 -0.278431 -0.102246 - -0.127204 -0.425147 -0.0574258 -0.126583 -0.421892 -0.0566651 -0.125878 -0.418709 -0.0558792 -0.12384 -0.408693 -0.0537444 -0.122911 -0.404134 -0.0527634 -0.121436 -0.397035 -0.0512301 -0.117292 -0.382893 -0.0487983 -0.113957 -0.371877 -0.0470041 -0.112119 -0.365817 -0.0460208 -0.110834 -0.361593 -0.0453406 -0.10986 -0.358391 -0.044825 -0.109118 -0.355958 -0.044436 -0.10658 -0.347696 -0.0431359 -0.103896 -0.339469 -0.0419843 -0.100673 -0.32973 -0.0406093 -0.0985403 -0.323312 -0.0397009 -0.0969321 -0.318473 -0.0390159 -0.0952837 -0.313513 -0.0383138 -0.0923349 -0.30464 -0.0370578 -0.0897077 -0.296722 -0.0359384 -0.0839879 -0.279772 -0.0335958 -0.0740431 -0.256194 -0.0300035 -0.0704178 -0.247997 -0.0285047 -0.0680589 -0.242479 -0.0275265 -0.0565563 -0.218174 -0.0225435 - -0.14466 -0.0722011 0.21965 -0.146898 -0.0700648 0.214693 -0.158245 -0.0529903 0.18072 -0.162953 -0.0458087 0.166493 -0.165656 -0.0411544 0.1571 -0.166954 -0.0365764 0.147221 -0.162764 -0.0324547 0.133813 -0.158633 -0.029193 0.122858 -0.155613 -0.0246965 0.113317 -0.153739 -0.0218487 0.107345 -0.152173 -0.0206481 0.103215 -0.150459 -0.0196591 0.0987635 -0.143452 -0.0150868 0.080126 -0.14106 -0.0131892 0.0734365 -0.13915 -0.0111102 0.0675884 -0.135056 -0.0104941 0.0584959 - --0.281476 -0.277091 -0.095993 --0.288815 -0.274662 -0.0912037 --0.289421 -0.272079 -0.0870304 --0.287181 -0.26529 -0.0770248 --0.285581 -0.261127 -0.0709549 --0.283454 -0.255302 -0.0624267 --0.279494 -0.25109 -0.0569956 --0.276833 -0.248179 -0.0532184 --0.273477 -0.244643 -0.0486664 --0.267589 -0.240061 -0.0432158 --0.26187 -0.23669 -0.0395614 --0.253208 -0.232303 -0.0350579 --0.245789 -0.229232 -0.0323237 --0.23441 -0.227035 -0.0307117 --0.221078 -0.22701 -0.0298457 --0.20866 -0.228311 -0.0295397 --0.202411 -0.229404 -0.02953 --0.197181 -0.230531 -0.029858 --0.181657 -0.236222 -0.0345668 - --0.281476 -0.277091 -0.095993 --0.269182 -0.277241 -0.0979102 --0.265625 -0.277063 -0.0981271 --0.260115 -0.276907 -0.0986034 --0.252659 -0.277541 -0.100125 --0.251168 -0.277555 -0.100292 --0.242137 -0.278431 -0.102246 - --0.242137 -0.278431 -0.102246 --0.23035 -0.270563 -0.0939387 --0.225531 -0.267442 -0.0906574 --0.220725 -0.264524 -0.0876145 --0.211922 -0.260063 -0.0829855 --0.207367 -0.256369 -0.0759794 --0.201498 -0.252203 -0.0679393 --0.195537 -0.247527 -0.0588779 --0.190467 -0.244605 -0.0522582 --0.181657 -0.236222 -0.0345668 - -0.0630898 -0.22993 -0.0253825 -0.0565563 -0.218174 -0.0225435 - -0.144622 0.0174678 0.0534465 -0.138153 0.00188671 0.0538794 -0.136848 -0.00377154 0.0562223 -0.135056 -0.0104941 0.0584959 - -0.0565563 -0.218174 -0.0225435 -0.0607462 -0.205732 -0.0235656 -0.0643782 -0.199627 -0.0248542 -0.0649747 -0.182916 -0.0225711 - --0.113892 -0.246007 -0.0161702 --0.0841498 -0.233673 -0.0121917 --0.0629379 -0.223193 -0.0106843 --0.057161 -0.220163 -0.0102779 --0.0505946 -0.216749 -0.00982099 --0.0434099 -0.213028 -0.0093229 --0.039137 -0.210816 -0.0090266 --0.0253904 -0.204075 -0.00826876 --0.00717342 -0.196874 -0.00821703 -0.00417233 -0.193323 -0.00881139 -0.0174199 -0.189614 -0.0100062 -0.0295343 -0.186516 -0.0116949 -0.033754 -0.186149 -0.0127879 -0.0429554 -0.184416 -0.0149113 -0.0482991 -0.184203 -0.0167819 -0.0649747 -0.182916 -0.0225711 - --0.113892 -0.246007 -0.0161702 --0.13852 -0.240185 -0.0208952 --0.143669 -0.238493 -0.0219281 --0.144427 -0.238233 -0.0220802 --0.149802 -0.23646 -0.0231638 --0.156137 -0.234791 -0.0245356 --0.1614 -0.235246 -0.0269026 --0.164702 -0.235618 -0.0284928 --0.181657 -0.236222 -0.0345668 - -0.0649747 -0.182916 -0.0225711 -0.0681923 -0.166147 -0.0146381 -0.0693256 -0.156639 -0.00957911 -0.0705145 -0.149369 -0.00584912 -0.0713418 -0.141679 -0.00164125 -0.0723211 -0.131416 0.00405148 -0.0727596 -0.124475 0.00806783 -0.0735502 -0.118469 0.0113743 -0.0754863 -0.111152 0.0150937 -0.0782395 -0.104829 0.0177439 -0.0795523 -0.102023 0.0188735 -0.0822176 -0.0965385 0.0210292 -0.0860589 -0.0887214 0.0240766 -0.0885691 -0.0840944 0.0257345 -0.0923387 -0.0772477 0.0281619 -0.0991968 -0.0651448 0.0324166 -0.107639 -0.0515339 0.0379364 -0.111387 -0.0455082 0.0403816 -0.114694 -0.0402136 0.0425654 -0.120319 -0.0312058 0.0462764 -0.125489 -0.0238545 0.0504821 -0.130188 -0.0178832 0.0549454 -0.135056 -0.0104941 0.0584959 - diff --git a/data/skeletons/output_raptor_skeleton.txt b/data/skeletons/output_raptor_skeleton.txt deleted file mode 100644 index 2a440c5..0000000 --- a/data/skeletons/output_raptor_skeleton.txt +++ /dev/null @@ -1,488 +0,0 @@ -0.00261497 6.40846 6.39716 --0.00337782 6.41709 6.36901 --0.00174051 6.43132 6.32109 --0.00349442 6.44424 6.27716 --0.00503459 6.47727 6.14345 --0.0104874 6.49772 6.03833 --0.0145518 6.51146 5.9596 --0.0205835 6.52282 5.8861 --0.025315 6.54452 5.74731 --0.0265846 6.55027 5.65689 --0.0165136 6.5429 5.59899 --0.0119765 6.53285 5.54148 -0.00637587 6.50782 5.43913 -0.0238277 6.48386 5.3297 -0.0815777 6.42106 5.19377 -0.145395 6.38313 5.11974 - -1.01897 0.421997 0.0628335 -1.05207 0.483915 0.0207638 -1.04385 0.60381 -0.0266483 -1.04769 0.719494 -0.0447149 -1.04873 0.803692 -0.037129 -1.05688 0.948858 -0.0163011 -1.06908 1.11593 0.019074 -1.07806 1.22108 0.0469235 -1.08542 1.29973 0.0705155 -1.0943 1.38308 0.101553 -1.10325 1.46892 0.136485 -1.11265 1.56102 0.17715 -1.12134 1.65581 0.222554 -1.13074 1.76412 0.274958 -1.13349 1.91375 0.342186 -1.13688 2.07677 0.416111 -1.11001 2.16321 0.428953 -1.06589 2.27545 0.438655 -1.01605 2.39728 0.448417 -0.992935 2.45145 0.45238 -0.918632 2.6 0.459281 -0.890686 2.65577 0.461853 -0.853058 2.73086 0.465321 -0.822917 2.79103 0.468118 -0.740348 2.95714 0.476183 -0.673261 3.08145 0.481454 -0.595705 3.18157 0.485043 -0.465135 3.34433 0.506643 -0.420818 3.39915 0.515157 -0.373173 3.44317 0.519894 -0.337764 3.47263 0.523159 -0.286422 3.51514 0.527312 -0.201488 3.5808 0.536393 -0.112947 3.64388 0.544562 -0.00924497 3.71398 0.543265 - -1.01897 0.421997 0.0628335 -1.09058 0.370907 0.062301 -1.15937 0.255373 0.0967063 - -1.01897 0.421997 0.0628335 -0.955617 0.412398 0.102279 -0.918204 0.413237 0.142845 -0.893276 0.427925 0.186054 -0.861245 0.452373 0.261602 -0.82301 0.490443 0.361717 -0.812456 0.512409 0.40499 -0.818128 0.555863 0.457885 -0.820141 0.597832 0.517461 -0.82197 0.645579 0.586272 -0.821339 0.670468 0.631549 -0.821271 0.686509 0.684377 -0.821774 0.682353 0.744834 -0.821297 0.665787 0.804401 -0.821022 0.634865 0.862457 -0.820731 0.594921 0.913952 -0.820639 0.55976 0.947377 -0.820505 0.546759 0.956853 - -1.17023 2.82019 3.74835 -0.994379 2.73209 3.87521 -0.959659 2.62263 3.91314 -0.939374 2.52603 3.93137 -0.937979 2.51511 3.93289 -0.923 2.41308 3.93698 -0.912819 2.32148 3.93005 -0.905346 2.24363 3.91626 -0.90095 2.17632 3.89867 -0.890714 2.11473 3.8722 -0.890764 2.03546 3.82541 -0.871828 1.93974 3.71587 -0.86715 1.92094 3.6985 - -1.17023 2.82019 3.74835 -1.17509 2.93362 3.63576 -1.16331 2.9593 3.57418 -1.15197 2.977 3.53013 -1.14474 2.9895 3.49876 -1.13102 3.00907 3.44356 -1.11493 3.01434 3.38832 -1.09936 3.01604 3.33806 -1.05868 3.02036 3.17788 -1.02607 2.97854 3.04569 -0.98641 2.93453 2.8808 -0.970052 2.91572 2.81376 -0.957112 2.91331 2.76943 -0.931795 2.92371 2.69101 -0.90687 2.94497 2.63099 -0.861926 3.01242 2.57112 -0.808956 3.1126 2.53999 -0.760207 3.21046 2.52942 -0.739761 3.24954 2.52577 -0.654307 3.40896 2.51978 -0.563098 3.52488 2.51022 -0.419116 3.69709 2.48888 -0.398789 3.71773 2.47702 -0.287642 3.82297 2.39631 -0.23969 3.86245 2.36216 -0.225347 3.87368 2.35202 -0.138296 3.93495 2.29311 -0.043464 4.00201 2.25083 - -1.17023 2.82019 3.74835 -1.24253 2.75547 3.77854 - --0.0139116 6.07581 4.65773 --0.0130908 6.08357 4.79765 - --0.000111646 4.65926 -8.8909 --0.000167946 4.66852 -8.87191 --0.000285245 4.69151 -8.82333 --0.000372848 4.76282 -8.66742 --0.000463195 4.768 -8.65552 --0.000505209 4.91971 -8.30526 --0.00018484 5.0715 -7.91335 --0.000511521 5.17147 -7.57533 --0.000653166 5.17874 -7.55178 --0.000780947 5.2526 -7.21606 --0.000805166 5.31227 -6.82881 --0.00111204 5.33771 -6.49666 --0.0013606 5.33433 -6.10835 --0.00170417 5.30302 -5.74576 --0.002075 5.24318 -5.39706 --0.00259847 5.16285 -5.1098 --0.00334962 5.15331 -5.08037 --0.00319213 5.01459 -4.71194 --0.00285812 4.92224 -4.46713 --0.00263337 4.86815 -4.32203 --0.00183681 4.67531 -3.80244 --0.00162243 4.61988 -3.64812 --0.00140132 4.56219 -3.48685 --0.00127759 4.52627 -3.38076 --0.00118539 4.49924 -3.30059 --0.00103946 4.45631 -3.17364 --0.000952147 4.43223 -3.09014 --0.000849744 4.40381 -2.99011 --0.000749234 4.3759 -2.89178 --0.000676364 4.35569 -2.82055 --0.000603712 4.33564 -2.74987 --0.000333506 4.29926 -2.62131 --0.000560631 4.27333 -2.53078 --0.000762559 4.23751 -2.32785 --0.000764475 4.21507 -2.19787 --0.000776197 4.20526 -2.14049 --0.000769875 4.19382 -2.07098 -0.000436307 4.14688 -1.73285 -0.000921567 4.1283 -1.59837 -0.00126981 4.11505 -1.50244 -0.0015887 4.10308 -1.41585 -0.00187521 4.09233 -1.33802 -0.00210202 4.08417 -1.27908 -0.002386 4.07321 -1.19971 -0.00277998 4.05844 -1.0923 -0.00291705 4.0483 -1.01495 -0.00282244 4.03826 -0.937637 -0.00134058 4.02428 -0.816976 --0.00250201 4.0017 -0.612006 --0.00283235 3.99807 -0.580665 --0.00409215 3.98547 -0.501697 --0.00505377 3.97722 -0.451004 --0.00629344 3.96634 -0.385796 --0.00741305 3.9564 -0.327044 --0.00886432 3.93922 -0.227114 --0.0108551 3.92652 -0.155893 --0.0152359 3.90714 -0.0559182 --0.0169851 3.88096 0.0177719 --0.0177597 3.87127 0.0436049 --0.02093 3.82804 0.155477 --0.0169732 3.79467 0.238498 --0.0157682 3.76754 0.303001 --0.0149742 3.74263 0.362586 -0.00924497 3.71398 0.543265 - -0.043464 4.00201 2.25083 --0.0663285 3.98551 2.20978 - -0.043464 4.00201 2.25083 --0.00372098 4.10574 2.29997 --0.00377526 4.16519 2.37467 --0.00331632 4.23998 2.46185 -0.000324227 4.32196 2.55514 -0.00363728 4.37874 2.62279 -0.00476475 4.50916 2.76611 -0.00212634 4.61274 2.88122 -0.00127789 4.66954 2.93904 -0.000754877 4.7756 3.07298 --0.000244322 4.84597 3.16198 --0.000900852 4.89369 3.22253 --0.00159029 4.94037 3.28181 --0.00169167 5.01404 3.37698 --0.00183697 5.09564 3.48299 --0.00192279 5.15066 3.55451 --0.00205053 5.20628 3.62708 --0.00207498 5.27969 3.72289 --0.00286731 5.36623 3.83691 --0.000881729 5.45539 3.9547 --0.00592108 5.61662 4.17084 --0.0134564 5.68559 4.27069 --0.0139261 5.72882 4.32264 --0.0154722 5.78927 4.39772 --0.0160784 5.84443 4.45519 --0.0162719 5.86602 4.49471 --0.0169453 5.96829 4.62678 --0.0165677 6.01899 4.69984 --0.0130908 6.08357 4.79765 - --0.00155511 5.20719 5.63145 --0.000112239 5.23777 5.58707 --0.0013004 5.27058 5.53912 -0.00191911 5.32007 5.46784 --0.00462807 5.38123 5.39568 --0.00522766 5.41137 5.36147 --0.00488832 5.54771 5.20637 --0.00194912 5.61685 5.129 --0.00634078 5.71351 5.04538 --0.0112311 5.85823 4.92158 --0.0136633 5.97144 4.85749 --0.0130908 6.08357 4.79765 - --0.0130908 6.08357 4.79765 -0.000713041 6.16159 4.8372 -0.0213682 6.23167 4.89927 -0.0397861 6.28873 4.94993 -0.0571468 6.31584 4.99079 -0.0925364 6.3513 5.05926 -0.145395 6.38313 5.11974 - --1.01931 0.422806 0.075427 --0.919113 0.400184 0.125295 --0.891842 0.42179 0.173281 --0.865098 0.453473 0.247259 --0.848245 0.483677 0.312445 --0.839332 0.502072 0.350585 --0.821532 0.550689 0.443871 --0.819402 0.605129 0.522967 --0.819121 0.645219 0.576111 --0.821396 0.671778 0.629942 --0.822698 0.686302 0.687086 --0.822126 0.681939 0.744683 --0.821363 0.665754 0.8044 --0.821155 0.634592 0.861869 --0.820841 0.600134 0.909646 --0.82077 0.568335 0.940189 --0.820728 0.559211 0.947897 - --1.01931 0.422806 0.075427 --1.04366 0.482545 0.033539 --1.03915 0.574571 -0.0174808 --1.04134 0.650846 -0.0371799 --1.04143 0.736589 -0.0404554 --1.0565 0.925736 -0.00617953 --1.06001 0.978856 0.00333741 --1.06619 1.07198 0.0200443 --1.07402 1.18751 0.0411403 --1.08328 1.28338 0.0693308 --1.08867 1.33514 0.087121 --1.09773 1.41906 0.119035 --1.10259 1.46485 0.13857 --1.10812 1.53024 0.169576 --1.11274 1.58618 0.196325 --1.11559 1.62079 0.212878 --1.12226 1.70154 0.251494 --1.13815 1.89152 0.342425 --1.13961 2.05923 0.414907 --1.12014 2.24315 0.476025 --1.09233 2.38822 0.510812 --1.05031 2.53732 0.533809 --0.865754 2.84428 0.5318 --0.798021 2.94149 0.524323 --0.675642 3.11186 0.513378 --0.57643 3.23766 0.508371 --0.490161 3.34314 0.509535 --0.399438 3.44644 0.50794 --0.315633 3.54052 0.510762 --0.257664 3.58014 0.504731 --0.201317 3.61747 0.50296 --0.103018 3.6639 0.493547 -0.00924497 3.71398 0.543265 - --1.01931 0.422806 0.075427 --1.13663 0.327981 0.0943148 --1.26353 0.22476 0.101754 - --1.26353 0.22476 0.101754 --1.36027 0.184371 0.0873416 --1.40463 0.158929 0.0992558 --1.49838 0.109487 0.127903 --1.56407 0.076331 0.149128 --1.61577 0.0511591 0.166833 --1.71551 0.00407972 0.207825 --1.81566 -0.0324254 0.306125 --1.88191 -0.0639851 0.383817 --1.92842 -0.0745217 0.438116 --1.96344 -0.0828731 0.485337 --1.9983 -0.0950211 0.527875 --2.00815 -0.097902 0.539268 --2.03675 -0.111156 0.573474 --2.04709 -0.116388 0.585573 - --1.26353 0.22476 0.101754 --1.16722 0.213571 0.169484 --1.16376 0.177424 0.202799 --1.17248 0.146532 0.240166 --1.19056 0.111853 0.294862 --1.20859 0.0826745 0.347467 --1.24954 0.0203687 0.468659 --1.28219 -0.024772 0.568378 --1.31958 -0.0470282 0.655177 --1.34654 -0.0673524 0.731502 --1.36002 -0.0749547 0.773755 --1.37828 -0.0924546 0.840585 --1.38963 -0.104232 0.882057 --1.39493 -0.112241 0.904109 - --0.0663285 3.98551 2.20978 --0.129362 3.95112 2.25329 --0.180173 3.91724 2.30826 --0.305861 3.79916 2.39036 --0.392767 3.71271 2.44834 --0.570063 3.51905 2.51174 --0.652651 3.418 2.52467 --0.736124 3.26606 2.53992 --0.771399 3.19851 2.54701 --0.809993 3.1229 2.55772 --0.855696 3.03837 2.58808 --0.875775 3.00325 2.60698 --0.905334 2.96014 2.65164 --0.923948 2.9382 2.68926 --0.95696 2.90795 2.76831 --0.974652 2.93338 2.84662 --1.02338 2.9784 3.04675 --1.05071 3.01058 3.16613 --1.09323 3.01036 3.30952 --1.12562 3.00322 3.41787 --1.15248 2.99137 3.50681 --1.167 2.97166 3.56705 --1.18451 2.94087 3.62239 --1.20828 2.87816 3.6874 --1.19943 2.79677 3.75792 - --0.0663285 3.98551 2.20978 --0.0255949 4.00992 2.09743 --0.0148507 4.02366 1.97545 --0.01296 4.02121 1.91134 --0.0106726 4.02121 1.85884 --0.00841274 4.02102 1.74614 --0.00485643 4.00874 1.58741 --0.00239152 3.99758 1.47522 --0.001096 3.99116 1.41551 -9.17227e-05 3.98406 1.35923 -0.000866527 3.97758 1.32017 -0.00199231 3.9665 1.26094 -0.00472475 3.94671 1.15669 -0.00835773 3.91609 1.00506 -0.000265464 3.9029 0.952975 -0.00652361 3.83791 0.834585 -0.0111034 3.79914 0.761512 -0.0159731 3.77358 0.7148 -0.023216 3.73632 0.646847 -0.00924497 3.71398 0.543265 - --1.19943 2.79677 3.75792 --1.23713 2.73891 3.79696 --1.27427 2.69425 3.82301 --1.29531 2.65664 3.84895 --1.32613 2.54967 3.88623 --1.3468 2.44395 3.90395 --1.36109 2.35268 3.90831 --1.36991 2.26654 3.90344 --1.37532 2.17798 3.8878 --1.3762 2.10149 3.87261 --1.3698 2.03006 3.84114 --1.35855 1.94836 3.7856 --1.33641 1.88198 3.69193 - --1.19943 2.79677 3.75792 --1.01597 2.7195 3.87574 --0.96638 2.61722 3.91259 --0.941273 2.50915 3.93075 --0.923139 2.4165 3.93642 --0.913868 2.32762 3.93005 --0.91279 2.31942 3.92951 --0.904941 2.23996 3.91463 --0.89814 2.17471 3.89397 --0.893007 2.11978 3.87549 --0.890661 2.0953 3.86699 --0.88417 2.02466 3.8162 --0.869144 1.92855 3.70585 - --1.19943 2.79677 3.75792 --1.3809 2.7459 3.67964 --1.50156 2.66742 3.63605 --1.54291 2.56463 3.60231 --1.55574 2.47838 3.57033 --1.54926 2.39617 3.53038 --1.52832 2.32728 3.48821 --1.49782 2.27886 3.45595 --1.46023 2.23834 3.42026 --1.40086 2.19973 3.33452 --1.31818 2.18354 3.22772 - -1.31543 1.86601 3.64226 -1.36023 1.9521 3.77998 - -2.04778 -0.115785 0.587142 -2.03943 -0.112003 0.577252 -2.00184 -0.0974169 0.532404 -1.96484 -0.0843628 0.486345 -1.92989 -0.0769371 0.440746 -1.88128 -0.0707924 0.396185 -1.85317 -0.0583328 0.356398 -1.80429 -0.0339894 0.295681 -1.71758 -0.00408226 0.206552 -1.58534 0.056596 0.155286 -1.48788 0.107882 0.121585 -1.40853 0.151558 0.0955468 -1.33973 0.189062 0.0770308 -1.29481 0.218125 0.0639521 -1.23446 0.253485 0.0581332 -1.15937 0.255373 0.0967063 - -1.39792 -0.114262 0.914281 -1.39532 -0.112442 0.904249 -1.39112 -0.107227 0.888984 -1.38134 -0.0920801 0.847609 -1.37241 -0.088242 0.811562 -1.36471 -0.0818346 0.778999 -1.33614 -0.0697922 0.700069 -1.31296 -0.0469355 0.634475 -1.28429 -0.0272305 0.568022 -1.24217 0.0376124 0.418143 -1.2109 0.081772 0.329428 -1.19152 0.113041 0.269462 -1.17038 0.150212 0.211838 -1.15192 0.185315 0.167312 -1.15937 0.255373 0.0967063 - -0.517272 6.40976 5.26321 -0.331221 6.41377 5.19327 -0.288507 6.41535 5.18103 -0.240938 6.40515 5.16059 -0.145395 6.38313 5.11974 - -1.36023 1.9521 3.77998 -1.36135 1.93871 3.78143 - -1.36023 1.9521 3.77998 -1.36377 2.00475 3.82803 -1.37074 2.046 3.84818 -1.37823 2.10367 3.87008 -1.37812 2.17771 3.88825 -1.37386 2.26046 3.90187 -1.3607 2.35504 3.90806 -1.34362 2.46333 3.90143 -1.31158 2.58219 3.88205 -1.27741 2.67209 3.83482 -1.24253 2.75547 3.77854 - -1.24253 2.75547 3.77854 -1.29622 2.79519 3.70937 -1.38642 2.74501 3.6759 -1.50385 2.66613 3.63419 -1.53984 2.57964 3.60691 -1.54364 2.56817 3.60332 -1.55568 2.47859 3.57019 -1.54919 2.39621 3.53037 -1.52756 2.32745 3.48944 -1.49867 2.27892 3.45459 -1.45124 2.22993 3.40067 -1.35308 2.19445 3.27221 - diff --git a/data/skeletons/output_vessels_skeleton.txt b/data/skeletons/output_vessels_skeleton.txt deleted file mode 100644 index f444a87..0000000 --- a/data/skeletons/output_vessels_skeleton.txt +++ /dev/null @@ -1,235 +0,0 @@ -0.0469689 -0.0056659 0.977742 -0.0453733 -0.00326106 0.977921 -0.0444669 -0.00175594 0.978012 -0.0436379 -0.0011278 0.97811 -0.0430662 -0.000709462 0.978176 -0.0426091 -0.000413168 0.978227 -0.0412855 0.000415358 0.978373 -0.0407007 0.000764932 0.978436 -0.0401557 0.00108358 0.978493 -0.0399571 0.00119796 0.978514 -0.0384383 0.00206047 0.978661 -0.036929 0.00291855 0.978866 -0.035959 0.00331456 0.97897 -0.0350396 0.00366551 0.979008 -0.0338635 0.00411401 0.979053 -0.0317572 0.00497143 0.979171 -0.0301424 0.00558471 0.979242 -0.0283695 0.00618038 0.979326 -0.0274233 0.00651819 0.979372 -0.0262368 0.00688606 0.979407 -0.0246121 0.00736591 0.979453 -0.0234288 0.00768447 0.979489 -0.0224432 0.00792118 0.979535 -0.0210617 0.00812322 0.979633 -0.0202207 0.00824735 0.979685 -0.0194842 0.00835468 0.979731 -0.0176544 0.0086176 0.979832 -0.0171137 0.0086938 0.979856 -0.0163976 0.00879551 0.979889 -0.0158021 0.00887576 0.979917 -0.0149582 0.00898349 0.97996 -0.0144673 0.00900392 0.980002 -0.0136869 0.00902356 0.980073 -0.0125033 0.00905362 0.98018 -0.0116094 0.0090756 0.980261 -0.0106014 0.00909954 0.980351 -0.00931187 0.00912627 0.980466 -0.00632232 0.00917942 0.980743 -0.00449926 0.00891593 0.980864 -0.00312691 0.00872583 0.980968 -0.00242713 0.0086284 0.981021 -0.00144239 0.00849151 0.981097 -2.10942e-05 0.00829513 0.981197 --0.00159382 0.00800114 0.981291 --0.00334763 0.00764906 0.981341 --0.00433567 0.00746926 0.981317 --0.00557796 0.00727182 0.981392 --0.00765726 0.00692089 0.981424 --0.00967463 0.006641 0.981389 --0.0126216 0.00642837 0.981263 --0.0143405 0.00654632 0.981179 --0.0154121 0.00662211 0.981126 --0.0169374 0.00677974 0.981041 --0.0179808 0.00680759 0.98104 --0.0185493 0.0068245 0.981039 --0.0192053 0.00688972 0.98102 --0.0199304 0.00697514 0.980993 - -0.0469689 -0.0056659 0.977742 -0.0491851 -0.00608992 0.977239 -0.0495987 -0.00606291 0.977136 -0.0510828 -0.00558239 0.976732 -0.0519304 -0.00509899 0.976482 -0.053027 -0.00450125 0.976161 -0.0552678 -0.00483177 0.975553 -0.0572031 -0.0051304 0.974996 -0.058274 -0.00531052 0.974669 -0.059374 -0.00549882 0.974325 -0.059884 -0.00558844 0.974161 -0.0606351 -0.00572275 0.973916 -0.0614643 -0.00587599 0.973632 -0.0621898 -0.00601148 0.97338 -0.062863 -0.00613888 0.973141 -0.0638755 -0.0063314 0.972779 -0.0651174 -0.00657165 0.972332 -0.0668889 -0.00692016 0.97168 -0.0678343 -0.00703731 0.971259 -0.0690245 -0.00715766 0.970713 -0.0705755 -0.00729145 0.970052 -0.071647 -0.00730304 0.969539 -0.0725133 -0.00731158 0.969123 -0.0734875 -0.00737542 0.968705 -0.0744318 -0.00728708 0.968205 -0.0752835 -0.00720106 0.967795 -0.0768946 -0.00701639 0.96694 -0.0788049 -0.00665548 0.965886 -0.0796527 -0.00650188 0.965427 -0.0799408 -0.00644836 0.965272 -0.0805082 -0.0063418 0.964967 -0.0816004 -0.00612038 0.964414 -0.0822564 -0.00594323 0.964018 -0.0832025 -0.00564713 0.963511 -0.0843165 -0.00528742 0.962839 -0.0854876 -0.00491056 0.962217 -0.0862224 -0.00465064 0.961793 -0.0871678 -0.00432492 0.961237 - -0.0469689 -0.0056659 0.977742 -0.0474104 -0.0073906 0.977784 -0.0471867 -0.00964572 0.978034 -0.0466351 -0.0116049 0.978337 -0.0465087 -0.0120769 0.978408 -0.0464002 -0.0124773 0.978469 -0.0461282 -0.0133969 0.978614 -0.046003 -0.0138198 0.978681 -0.0458157 -0.0144608 0.978782 -0.0457139 -0.01494 0.978832 -0.0454789 -0.0159139 0.978914 -0.0452061 -0.0169073 0.978989 -0.0449379 -0.0178449 0.979057 -0.0445499 -0.0190518 0.979133 -0.0441777 -0.0201391 0.979195 -0.0438655 -0.0210161 0.979241 -0.0434672 -0.0220856 0.979291 -0.0431126 -0.0230152 0.979331 -0.0428579 -0.0236702 0.979359 -0.0425843 -0.0243568 0.979384 -0.0423474 -0.0250665 0.979448 -0.0419428 -0.0258103 0.979395 -0.0414905 -0.0266215 0.97933 -0.0409368 -0.0275835 0.979242 -0.0401568 -0.0289717 0.97913 -0.0392091 -0.0306304 0.978991 -0.0388309 -0.0312902 0.978935 -0.0379648 -0.0327893 0.978808 -0.0370654 -0.0343439 0.978675 -0.0365495 -0.0352323 0.978597 -0.0350815 -0.0377195 0.978364 -0.0342039 -0.0390422 0.978219 -0.0331458 -0.0405652 0.978026 -0.0324822 -0.0413444 0.977927 - --0.0538581 -0.0181914 0.988229 --0.0531305 -0.0174962 0.988183 --0.0527199 -0.0170608 0.987948 --0.0518517 -0.0161877 0.987708 --0.051147 -0.0154695 0.987589 --0.0502779 -0.0145734 0.987492 --0.0493777 -0.0136567 0.987404 --0.0485589 -0.0128133 0.987278 --0.0474374 -0.0116802 0.98709 --0.0463481 -0.0105776 0.986995 --0.0451136 -0.00938489 0.98689 --0.0443884 -0.00871443 0.986804 --0.0432676 -0.00764483 0.986719 --0.0417977 -0.00633713 0.986419 --0.0402577 -0.00543193 0.98609 --0.0387757 -0.00452052 0.985772 --0.0372883 -0.0036096 0.985459 --0.0358757 -0.00274808 0.985159 --0.0346556 -0.00200516 0.984901 --0.033988 -0.00160233 0.984758 --0.0333219 -0.0012045 0.984616 --0.0327273 -0.00085356 0.984486 --0.0315982 -0.000194698 0.984246 --0.0295469 0.0010164 0.98372 --0.0278505 0.0019718 0.983259 --0.0270032 0.00246915 0.982995 --0.026063 0.00305269 0.982705 --0.0251486 0.00364202 0.982419 --0.0247167 0.00393615 0.982281 --0.0236695 0.00468632 0.981937 --0.0211737 0.00618296 0.981318 --0.0199304 0.00697514 0.980993 - --0.0660678 0.0799506 0.964077 --0.0658798 0.0795537 0.964221 --0.0653773 0.07864 0.964587 --0.0648021 0.0776514 0.964978 --0.0640504 0.0762422 0.965584 --0.0632706 0.0746818 0.966201 --0.0627243 0.0737066 0.966673 --0.0622061 0.0727384 0.967127 --0.0619621 0.0722812 0.967342 --0.0615278 0.0714654 0.967726 --0.0610355 0.0705423 0.96816 --0.0603684 0.0692998 0.968747 --0.0597693 0.0681845 0.969256 --0.0594595 0.0676297 0.969523 --0.0591451 0.0670785 0.969794 --0.057952 0.065016 0.970825 --0.0573795 0.0640712 0.971315 --0.056563 0.0627234 0.972003 --0.0555271 0.0611072 0.972872 --0.0548764 0.0601064 0.973412 --0.0539908 0.0588041 0.974136 --0.053481 0.0580636 0.974514 --0.0526746 0.0569646 0.975096 --0.0519325 0.055968 0.97558 --0.0510737 0.0547354 0.976192 --0.0503021 0.0536787 0.976645 --0.0488239 0.0516112 0.977406 --0.04793 0.0502629 0.977808 --0.0467738 0.0486099 0.97813 --0.0460362 0.0475114 0.978264 --0.0454315 0.0466255 0.978345 --0.0445692 0.0453697 0.978447 --0.0435698 0.0437474 0.978347 --0.042717 0.0423882 0.978248 --0.0418023 0.0409206 0.978202 --0.0413294 0.0402016 0.9781 --0.0410171 0.0397114 0.978055 --0.0405197 0.038961 0.977975 --0.0397913 0.0378635 0.977856 --0.0391843 0.0369495 0.977757 --0.0386396 0.0361301 0.977668 --0.0380864 0.0352985 0.977578 --0.0375341 0.0344686 0.977489 --0.0362419 0.0325285 0.97728 --0.0354917 0.0314035 0.97716 --0.0349144 0.0305385 0.977067 --0.0342245 0.0295067 0.976958 --0.0336931 0.0287121 0.976874 --0.0330931 0.0278155 0.976777 --0.0325939 0.0270715 0.976829 --0.0316355 0.0256521 0.976735 --0.0307614 0.0243718 0.976716 --0.0301657 0.023507 0.976666 --0.0299206 0.0231408 0.976614 --0.0290781 0.0218958 0.976766 --0.0286142 0.0212087 0.976845 --0.0270717 0.0189947 0.977125 --0.0260201 0.0173428 0.977478 --0.0252485 0.0159936 0.977858 --0.0247092 0.0151112 0.978131 --0.0246319 0.0149807 0.978171 --0.0237678 0.0135157 0.978628 --0.0233234 0.0127479 0.978873 --0.0228252 0.0118465 0.979176 --0.0224331 0.0111191 0.979424 --0.0219868 0.0102781 0.979713 --0.0211447 0.00888227 0.980253 --0.0205194 0.00774802 0.980694 --0.0199304 0.00697514 0.980993 - diff --git a/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonGraph.cpp b/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonGraph.cpp new file mode 100644 index 0000000..6621ded --- /dev/null +++ b/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonGraph.cpp @@ -0,0 +1,397 @@ +#include "SkeletonGraph.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace meshskeletonizationplugin +{ + +void SkeletonGraph::clear() +{ + m_nodes.clear(); + m_adjacency.clear(); + m_loopEdges.clear(); + m_rootId = -1; +} + +int SkeletonGraph::findOrCreateNode(const std::array& p, double tol) +{ + const double tol2 = tol * tol; + for (const SkeletonNode& n : m_nodes) + { + const auto& q = n.position(); + double dx = q[0] - p[0]; + double dy = q[1] - p[1]; + double dz = q[2] - p[2]; + if (dx * dx + dy * dy + dz * dz <= tol2) + return n.id(); + } + + int newId = static_cast(m_nodes.size()); + m_nodes.emplace_back(newId, p[0], p[1], p[2]); + return newId; +} + +void SkeletonGraph::connect(int a, int b) +{ + if (a == b) + return; + + auto& neighborsA = m_adjacency[a]; + if (std::find(neighborsA.begin(), neighborsA.end(), b) == neighborsA.end()) + neighborsA.push_back(b); + + auto& neighborsB = m_adjacency[b]; + if (std::find(neighborsB.begin(), neighborsB.end(), a) == neighborsB.end()) + neighborsB.push_back(a); +} + +bool SkeletonGraph::loadFromFile(const std::string& filename, double mergeTolerance) +{ + std::ifstream in(filename); + if (!in.is_open()) + return false; + + clear(); + + std::string line; + int previousId = -1; + + while (std::getline(in, line)) + { + // Trim trailing whitespace/CR so blank-line detection works on + // files written or edited on Windows too. + while (!line.empty() && (line.back() == '\r' || line.back() == ' ' || line.back() == '\t')) + line.pop_back(); + + if (line.empty()) + { + previousId = -1; // end of current polyline + continue; + } + + std::istringstream iss(line); + std::array p{}; + if (!(iss >> p[0] >> p[1] >> p[2])) + continue; // skip malformed/comment lines + + int id = findOrCreateNode(p, mergeTolerance); + + if (previousId >= 0) + connect(previousId, id); + + previousId = id; + } + + return true; +} + +int SkeletonGraph::closestNodeId(const std::array& p) const +{ + int best = -1; + double bestDist = std::numeric_limits::max(); + for (const SkeletonNode& n : m_nodes) + { + const auto& q = n.position(); + double dx = q[0] - p[0]; + double dy = q[1] - p[1]; + double dz = q[2] - p[2]; + double d2 = dx * dx + dy * dy + dz * dz; + if (d2 < bestDist) + { + bestDist = d2; + best = n.id(); + } + } + return best; +} + +void SkeletonGraph::buildTree(const std::array& entryPoint) +{ + int root = closestNodeId(entryPoint); + if (root >= 0) + buildTree(root); +} + +void SkeletonGraph::buildTree(int rootId) +{ + m_loopEdges.clear(); + + for (SkeletonNode& n : m_nodes) + { + n = SkeletonNode(n.id(), n.position()[0], n.position()[1], n.position()[2]); + } + + if (rootId < 0 || rootId >= static_cast(m_nodes.size())) + { + m_rootId = -1; + return; + } + + m_rootId = rootId; + + std::vector visited(m_nodes.size(), false); + std::vector parentOf(m_nodes.size(), -1); + std::queue q; + + visited[rootId] = true; + q.push(rootId); + + std::set> seenEdges; // to dedupe loop-edge reporting + + while (!q.empty()) + { + int u = q.front(); + q.pop(); + + auto it = m_adjacency.find(u); + if (it == m_adjacency.end()) + continue; + + for (int v : it->second) + { + if (!visited[v]) + { + visited[v] = true; + parentOf[v] = u; + m_nodes[u].addChildId(v); + m_nodes[v].addParentId(u); + q.push(v); + } + else if (parentOf[u] != v) // don't re-report the edge we arrived from + { + std::pair key = (u < v) ? std::make_pair(u, v) : std::make_pair(v, u); + if (seenEdges.insert(key).second) + { + // Real loop/anastomosis: record extra parent/child links + // without duplicating the primary tree edge. + m_nodes[u].addChildId(v); + m_nodes[v].addParentId(u); + m_loopEdges.emplace_back(u, v); + } + } + } + } +} + +void SkeletonGraph::computeMeshCorrespondence(const std::vector>& meshVertices) +{ + if (meshVertices.empty()) + return; + + for (SkeletonNode& n : m_nodes) + { + const auto& p = n.position(); + int bestVid = -1; + double bestDist2 = std::numeric_limits::max(); + + for (int i = 0; i < static_cast(meshVertices.size()); ++i) + { + const auto& v = meshVertices[i]; + double dx = v[0] - p[0]; + double dy = v[1] - p[1]; + double dz = v[2] - p[2]; + double d2 = dx * dx + dy * dy + dz * dz; + if (d2 < bestDist2) + { + bestDist2 = d2; + bestVid = i; + } + } + + n.setMeshVertexId(bestVid); + n.setDistanceToMesh(std::sqrt(bestDist2)); + } +} + +void SkeletonGraph::exportToVTK(const std::string& filename) const +{ + if (!hasRoot()) + return; + + const int n = static_cast(m_nodes.size()); + + // Node ids are assigned sequentially at creation time (0..n-1), so id == + // vector index and no separate id-remapping table is needed here. + + // depth(v) = number of edges from root, via each node's primary parent + // (parentIds().front()), memoized as we go. + std::vector depth(n, -1); + depth[m_rootId] = 0; + for (int v = 0; v < n; ++v) + { + if (depth[v] >= 0) + continue; + + std::vector path; + int cur = v; + while (depth[cur] < 0) + { + path.push_back(cur); + const auto& parents = m_nodes[cur].parentIds(); + if (parents.empty()) + break; // only the root should have no parent + cur = parents.front(); + } + int d = depth[cur] >= 0 ? depth[cur] : 0; + for (auto it = path.rbegin(); it != path.rend(); ++it) + depth[*it] = ++d; + } + + // LINES: primary tree edge (parentIds()[0] -> id) for every non-root + // node, plus any extra parent entries (index > 0) recorded as loop edges. + std::vector> lines; + std::vector isLoop; + for (const SkeletonNode& node : m_nodes) + { + const auto& parents = node.parentIds(); + for (std::size_t j = 0; j < parents.size(); ++j) + { + lines.emplace_back(parents[j], node.id()); + isLoop.push_back(j == 0 ? 0 : 1); + } + } + + std::ofstream out(filename, std::ofstream::out | std::ofstream::trunc); + out << "# vtk DataFile Version 3.0\n"; + out << "Skeleton graph (SkeletonReader module)\n"; + out << "ASCII\n"; + out << "DATASET POLYDATA\n"; + + out << "POINTS " << n << " float\n"; + out << std::fixed << std::setprecision(6); + for (const SkeletonNode& node : m_nodes) + { + const auto& p = node.position(); + out << p[0] << " " << p[1] << " " << p[2] << "\n"; + } + + out << "LINES " << lines.size() << " " << (lines.size() * 3) << "\n"; + for (const auto& l : lines) + out << "2 " << l.first << " " << l.second << "\n"; + + out << "POINT_DATA " << n << "\n"; + out << "SCALARS type int 1\n"; + out << "LOOKUP_TABLE default\n"; + for (const SkeletonNode& node : m_nodes) + { + int type = (node.id() == m_rootId) ? 1 : (node.isLeaf() ? 6 : 5); // 1=root, 5=branch, 6=terminal + out << type << "\n"; + } + out << "SCALARS depth int 1\n"; + out << "LOOKUP_TABLE default\n"; + for (int d : depth) + out << d << "\n"; + + out << "CELL_DATA " << lines.size() << "\n"; + out << "SCALARS is_loop int 1\n"; + out << "LOOKUP_TABLE default\n"; + for (int flag : isLoop) + out << flag << "\n"; +} + +const SkeletonNode* SkeletonGraph::node(int nodeId) const +{ + if (nodeId < 0 || nodeId >= static_cast(m_nodes.size())) + return nullptr; + return &m_nodes[nodeId]; +} +const std::vector& SkeletonGraph::parentsOf(int nodeId) const +{ + static const std::vector empty; + const SkeletonNode* n = node(nodeId); + return n ? n->parentIds() : empty; +} + +const std::vector& SkeletonGraph::childrenOf(int nodeId) const +{ + static const std::vector empty; + const SkeletonNode* n = node(nodeId); + return n ? n->childrenIds() : empty; +} + + +std::vector SkeletonGraph::pathFromRoot(int nodeId) const +{ + std::vector path; + if (!hasRoot() || node(nodeId) == nullptr) return path; + + std::set seen; + int cur = nodeId; + while (true) + { + if (!seen.insert(cur).second) { path.clear(); return path; } + path.push_back(cur); + if (cur == m_rootId) break; + const auto& parents = parentsOf(cur); + if (parents.empty()) return {}; + cur = parents.front(); + } + std::reverse(path.begin(), path.end()); + return path; +} +std::vector SkeletonGraph::subtree(int nodeId) const +{ + std::vector result; + if (node(nodeId) == nullptr) return result; + + std::set visited; + std::queue q; + q.push(nodeId); visited.insert(nodeId); + + while (!q.empty()) + { + int cur = q.front(); q.pop(); + result.push_back(cur); + for (int child : childrenOf(cur)) + if (visited.insert(child).second) q.push(child); + } + return result; +} +static std::string joinIds(const std::vector& ids) +{ + std::string s; + for (size_t i = 0; i < ids.size(); ++i) + { + if (i > 0) s += ";"; + s += std::to_string(ids[i]); + } + return s; +} + +void SkeletonGraph::exportReportCSV(const std::string& filename) const +{ + if (!hasRoot()) + return; + + std::ofstream out(filename, std::ofstream::out | std::ofstream::trunc); + out << "id,x,y,z,parentId,childrenIds,pathFromRoot,loopParentIds\n"; + out << std::fixed << std::setprecision(6); + + for (const SkeletonNode& n : m_nodes) + { + const auto& p = n.position(); + const auto& parents = n.parentIds(); + + int primaryParent = parents.empty() ? -1 : parents.front(); + + std::vector loopParents; + if (parents.size() > 1) + loopParents.assign(parents.begin() + 1, parents.end()); + + std::vector path = pathFromRoot(n.id()); + + out << n.id() << "," + << p[0] << "," << p[1] << "," << p[2] << "," + << primaryParent << "," + << "\"" << joinIds(n.childrenIds()) << "\"," + << "\"" << joinIds(path) << "\"," + << "\"" << joinIds(loopParents) << "\"\n"; + } +} +} // namespace meshskeletonizationplugin diff --git a/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonGraph.h b/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonGraph.h new file mode 100644 index 0000000..f1d6ed0 --- /dev/null +++ b/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonGraph.h @@ -0,0 +1,67 @@ +#pragma once + +#include "SkeletonNode.h" + +#include +#include +#include +#include +#include + +namespace meshskeletonizationplugin +{ + +/// Loads a polyline skeleton file (the format written by +/// MeshSkeletonization/SkeletonizationLoader's Export_polylines: blocks of +/// "x y z" lines separated by a blank line) and stores it as a graph of +/// SkeletonNode, then turns it into a rooted parent/children tree. +class SkeletonGraph +{ +public: + /// Parses the file, merging points that are within `mergeTolerance` of an + /// already-seen point into a single node. Returns false if the file could + /// not be opened. Only fills raw connectivity; call buildTree() afterwards + /// to populate parent/children ids on the nodes. + bool loadFromFile(const std::string& filename, double mergeTolerance = 1e-6); + + /// Picks the node closest to entryPoint as root and (re)computes every + /// node's parentIds/childrenIds via BFS over the raw connectivity. + void buildTree(const std::array& entryPoint); + void buildTree(int rootId); + + /// Best-effort correspondence between each skeleton node and the closest + /// vertex of the input (vessel) mesh; fills meshVertexId/distanceToMesh. + void computeMeshCorrespondence(const std::vector>& meshVertices); + + const std::vector& nodes() const { return m_nodes; } + std::vector& nodes() { return m_nodes; } + + int rootId() const { return m_rootId; } + bool hasRoot() const { return m_rootId >= 0; } + + /// Ids of nodes connected by a loop/anastomosis (extra edge beyond the tree). + const std::vector>& loopEdges() const { return m_loopEdges; } + //newzest additions + const SkeletonNode* node(int nodeId) const; + const std::vector& parentsOf(int nodeId) const; + const std::vector& childrenOf(int nodeId) const; + std::vector pathFromRoot(int nodeId) const; + std::vector subtree(int nodeId) const; + void exportReportCSV(const std::string& filename) const; + + void exportToVTK(const std::string& filename) const; + + void clear(); + +private: + int findOrCreateNode(const std::array& p, double tol); + int closestNodeId(const std::array& p) const; + void connect(int a, int b); + + std::vector m_nodes; + std::map> m_adjacency; ///< raw undirected connectivity from the file + std::vector> m_loopEdges; + int m_rootId{ -1 }; +}; + +} // namespace meshskeletonizationplugin diff --git a/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonNode.h b/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonNode.h new file mode 100644 index 0000000..6deba3d --- /dev/null +++ b/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonNode.h @@ -0,0 +1,67 @@ +#pragma once + +#include +#include + +namespace meshskeletonizationplugin +{ + +/// A single node of a skeletonized structure (e.g. a vessel centerline point). +/// Deliberately has no SOFA/CGAL dependency so it can be reused, tested, +/// and serialized independently of the plugin's simulation types. +class SkeletonNode +{ +public: + SkeletonNode() = default; + SkeletonNode(int id, double x, double y, double z) + : m_id(id), m_position{ x, y, z } + { + } + + int id() const { return m_id; } + void setId(int id) { m_id = id; } + + const std::array& position() const { return m_position; } + void setPosition(double x, double y, double z) { m_position = { x, y, z }; } + + /// Ids of the node(s) this node is connected to towards the root. + /// Usually a single parent; more than one means this node closes a + /// loop/anastomosis in the raw skeleton graph. + const std::vector& parentIds() const { return m_parentIds; } + void addParentId(int id) { m_parentIds.push_back(id); } + + /// Ids of the node(s) reached by moving away from the root. + const std::vector& childrenIds() const { return m_childrenIds; } + void addChildId(int id) { m_childrenIds.push_back(id); } + + bool isRoot() const { return m_parentIds.empty(); } + bool isLeaf() const { return m_childrenIds.empty(); } + bool isBranchPoint() const { return m_childrenIds.size() > 1; } + + // --- Optional relation to the input (vessel) mesh this skeleton came from --- + + /// Index of the closest vertex in the input mesh, -1 if not computed. + int meshVertexId() const { return m_meshVertexId; } + void setMeshVertexId(int vId) { m_meshVertexId = vId; } + + /// Distance from this node to that mesh vertex, <0 if not computed. + double distanceToMesh() const { return m_distanceToMesh; } + void setDistanceToMesh(double d) { m_distanceToMesh = d; } + + /// Estimated local vessel radius at this node, <0 if not available. + double radius() const { return m_radius; } + void setRadius(double r) { m_radius = r; } + +private: + int m_id{ -1 }; + std::array m_position{ 0.0, 0.0, 0.0 }; + + std::vector m_parentIds; + std::vector m_childrenIds; + + int m_meshVertexId{ -1 }; + double m_distanceToMesh{ -1.0 }; + double m_radius{ -1.0 }; +}; + +} // namespace meshskeletonizationplugin \ No newline at end of file diff --git a/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonReader.cpp b/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonReader.cpp new file mode 100644 index 0000000..8187881 --- /dev/null +++ b/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonReader.cpp @@ -0,0 +1,21 @@ +#define SKELETONREADER_CPP +#include + +#include +#include + +namespace meshskeletonizationplugin +{ +using namespace sofa::defaulttype; + +void registerSkeletonReader(sofa::core::ObjectFactory* factory) +{ + factory->registerObjects(sofa::core::ObjectRegistrationData( + "Read a skeleton polyline file (skeleton.txt) and store it as a graph of " + "nodes, each with its id, parent ids, children ids, and (if an input mesh " + "is given) its correspondence to the closest mesh vertex") + .add< SkeletonReader >()); +} + +template class SOFA_MESHSKELETONIZATIONPLUGIN_API SkeletonReader; +} \ No newline at end of file diff --git a/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonReader.h b/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonReader.h new file mode 100644 index 0000000..ad90806 --- /dev/null +++ b/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonReader.h @@ -0,0 +1,69 @@ +#pragma once + +#include + +#include +#include +#include +#include +#include + +#include + +using namespace sofa; +using namespace sofa::defaulttype; + +namespace meshskeletonizationplugin +{ + +/// Reads a skeleton polyline file (the "skeleton.txt" format written by +/// MeshSkeletonization / SkeletonizationLoader's Export_polylines) and stores +/// it as a SkeletonGraph: a list of SkeletonNode, each with its id, parent +/// ids, children ids, and - if an input mesh is provided - its correspondence +/// to the closest mesh vertex. +/// +/// This component does not need CGAL: it only re-reads an already-exported +/// polyline file, so it can be used purely as a downstream consumer of +/// MeshSkeletonization/SkeletonizationLoader's output. +template +class SkeletonReader : public sofa::core::DataEngine +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(SkeletonReader, DataTypes), sofa::core::DataEngine); + + typedef typename DataTypes::Coord Coord; + typedef typename DataTypes::VecCoord VecCoord; + typedef typename Coord::value_type Real; + typedef type::Vec<3, Real> Vec3; + + // Inputs + sofa::core::objectmodel::DataFileName d_inSkeletonFilename; ///< Path to the skeleton polyline file to read (e.g. skeleton.txt) + sofa::core::objectmodel::Data d_inVertices; ///< Optional input mesh vertices, to link skeleton nodes to the mesh + sofa::core::objectmodel::Data d_inEntryPoint; ///< Approx. entry point; closest node becomes the tree root + sofa::core::objectmodel::DataFileName d_outReportFilename; /// CSV report that guves out the ide, 3D coordinates, parent vertice and child vertice + + // Outputs + sofa::core::objectmodel::DataFileName d_outVTKFilename; ///< File path to (re-)export the rooted tree as VTK + sofa::core::objectmodel::Data d_outNodeCount; ///< Number of skeleton nodes read + + /// Direct access to the loaded graph, e.g. for another component to query + /// via getContext()->get>()->graph(). + const SkeletonGraph& graph() const { return m_graph; } + +private: + SkeletonReader(); + virtual ~SkeletonReader() = default; + + void init() override; + void doUpdate() override; + + void draw(const sofa::core::visual::VisualParams* vparams) override; + + SkeletonGraph m_graph; +}; + +#if !defined(SKELETONREADER_CPP) +extern template class SOFA_MESHSKELETONIZATIONPLUGIN_API SkeletonReader; +#endif + +} // namespace meshskeletonizationplugin diff --git a/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonReader.inl b/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonReader.inl new file mode 100644 index 0000000..594fecc --- /dev/null +++ b/src/MeshSkeletonizationPlugin/SkeletonGraph/SkeletonReader.inl @@ -0,0 +1,105 @@ +#pragma once + +#include + +using namespace sofa::core::objectmodel; + +namespace meshskeletonizationplugin +{ + +template +SkeletonReader::SkeletonReader() + : d_inSkeletonFilename(initData(&d_inSkeletonFilename, "filename", "Skeleton polyline file to read (e.g. skeleton.txt)")) + , d_inVertices(initData(&d_inVertices, "inputVertices", "Optional input mesh vertices, to link skeleton nodes to the mesh")) + , d_inEntryPoint(initData(&d_inEntryPoint, Vec3(0, 0, 0), "entryPoint", "Approx. entry point; closest node becomes the tree root")) + , d_outVTKFilename(initData(&d_outVTKFilename, "outputVTK", "File path to export the rooted tree (.vtk)")) + , d_outReportFilename(initData(&d_outReportFilename, "outputReport", "File path to export a per-node CSV report (id, x, y, z, parentId, childrenIds, pathFromRoot)")) + , d_outNodeCount(initData(&d_outNodeCount, 0, "nodeCount", "Number of skeleton nodes read")) +{ + addInput(&d_inSkeletonFilename); + addInput(&d_inVertices); + addInput(&d_inEntryPoint); + + addOutput(&d_outVTKFilename); + addOutput(&d_outReportFilename); + addOutput(&d_outNodeCount); +} + + +template +void SkeletonReader::init() +{ + if (d_inSkeletonFilename.getValue().empty()) + { + msg_error() << "No input skeleton file set, please set the 'filename' data."; + return; + } + update(); +} + + +template +void SkeletonReader::doUpdate() +{ + if (d_inSkeletonFilename.getFullPath().empty()) + return; + + if (!m_graph.loadFromFile(d_inSkeletonFilename.getFullPath())) + { + + msg_error() << "Could not open skeleton file: " << d_inSkeletonFilename.getFullPath(); + return; + } + + msg_info() << "Skeleton loaded: " << m_graph.nodes().size() << " node(s)."; + d_outNodeCount.setValue(static_cast(m_graph.nodes().size())); + + const Vec3& entry = d_inEntryPoint.getValue(); + m_graph.buildTree({ double(entry[0]), double(entry[1]), double(entry[2]) }); + + if (m_graph.hasRoot()) + msg_info() << "Tree built, root id " << m_graph.rootId() + << ", " << m_graph.loopEdges().size() << " loop edge(s) detected."; + + if (!d_inVertices.getValue().empty()) + { + std::vector> meshVerts; + meshVerts.reserve(d_inVertices.getValue().size()); + for (const auto& v : d_inVertices.getValue()) + meshVerts.push_back({ double(v[0]), double(v[1]), double(v[2]) }); + m_graph.computeMeshCorrespondence(meshVerts); + } + + if (d_outVTKFilename.isSet()) + m_graph.exportToVTK(d_outVTKFilename.getFullPath()); + + if (d_outReportFilename.isSet()) + m_graph.exportReportCSV(d_outReportFilename.getFullPath()); +} + + +template +void SkeletonReader::draw(const sofa::core::visual::VisualParams* vparams) +{ + using Color = sofa::type::RGBAColor; + std::vector< type::Vec3 > dvec; + + + for (const SkeletonNode& node : m_graph.nodes()) + { + for (int childId : node.childrenIds()) + { + const SkeletonNode& child = m_graph.nodes()[childId]; + const auto& p0 = node.position(); + const auto& p1 = child.position(); + + dvec.emplace_back(Coord(p0[0], p0[1], p0[2])); + dvec.emplace_back(Coord(p1[0], p1[1], p1[2])); + + vparams->drawTool()->drawLines(dvec, 2, Color::blue()); + dvec.clear(); + } + } +} + +} // namespace meshskeletonizationplugin diff --git a/src/MeshSkeletonizationPlugin/init.cpp b/src/MeshSkeletonizationPlugin/init.cpp index 087590d..6527428 100644 --- a/src/MeshSkeletonizationPlugin/init.cpp +++ b/src/MeshSkeletonizationPlugin/init.cpp @@ -28,6 +28,8 @@ namespace meshskeletonizationplugin { extern void registerMeshSkeletonization(sofa::core::ObjectFactory* factory); +//extern void registerSkeletonizationLoader(sofa::core::ObjectFactory* factory); +extern void registerSkeletonReader(sofa::core::ObjectFactory* factory); //Here are just several convenient functions to help users know what the plugin contains extern "C" { @@ -79,6 +81,8 @@ void init() void registerObjects(sofa::core::ObjectFactory* factory) { registerMeshSkeletonization(factory); + // registerSkeletonizationLoader(factory); + registerSkeletonReader(factory); } }