From 60709edf495c4265c5bfd5c592abc193565aefb8 Mon Sep 17 00:00:00 2001 From: Roy Turing Date: Tue, 16 Aug 2022 01:22:52 -0400 Subject: [PATCH] vtkpy folder added --- vtk_py/BiV.geo | 54 + vtk_py/CreateVertexFromPoint.py | 19 + vtk_py/CreateVertexFromPoint.pyc | Bin 0 -> 644 bytes vtk_py/LV.geo | 74 ++ vtk_py/LV_original.geo | 74 ++ vtk_py/Set4ChamberDirection.py | 62 + vtk_py/Set4ChamberDirection.pyc | Bin 0 -> 2071 bytes vtk_py/SetBiVFiber.py | 552 ++++++++ vtk_py/SetBiVFiber_J.py | 675 ++++++++++ vtk_py/SetBiVFiber_J.pyc | Bin 0 -> 17283 bytes vtk_py/SetBiVFiber_Quad.py | 561 ++++++++ vtk_py/SetBiVFiber_Quad_PyQ.py | 622 +++++++++ vtk_py/SetBiVFiber_Quad_PyQ.pyc | Bin 0 -> 20861 bytes vtk_py/SlerpTestJ.py | 170 +++ vtk_py/__init__.py | 90 ++ vtk_py/__init__.pyc | Bin 0 -> 3111 bytes vtk_py/_q! | 17 + vtk_py/addFieldPrincipalDirections.py | 99 ++ vtk_py/addFieldPrincipalDirections.pyc | Bin 0 -> 3129 bytes vtk_py/addLVfiber.py | 132 ++ vtk_py/addLVfiber.pyc | Bin 0 -> 4153 bytes vtk_py/addLVfiber_LDRB.py | 470 +++++++ vtk_py/addLVfiber_LDRB.pyc | Bin 0 -> 15746 bytes vtk_py/addLocalCylindricalDirections.py | 107 ++ vtk_py/addLocalCylindricalDirections.pyc | Bin 0 -> 2753 bytes vtk_py/addLocalFiberOrientation.py | 103 ++ vtk_py/addLocalFiberOrientation.pyc | Bin 0 -> 2986 bytes vtk_py/addLocalFiberOrientation2.py | 142 ++ vtk_py/addLocalFiberOrientation2.pyc | Bin 0 -> 3826 bytes vtk_py/addLocalFiberOrientation_infarct.py | 98 ++ vtk_py/addLocalFiberOrientation_infarct.pyc | Bin 0 -> 3245 bytes vtk_py/addLocalProlateSpheroidalDirections.py | 161 +++ .../addLocalProlateSpheroidalDirections.pyc | Bin 0 -> 4525 bytes vtk_py/addMappingFromPointsToCells.py | 43 + vtk_py/addMappingFromPointsToCells.pyc | Bin 0 -> 1337 bytes vtk_py/addSystolicStrains.py | 50 + vtk_py/addSystolicStrains.pyc | Bin 0 -> 1601 bytes vtk_py/clean_pdata.py | 22 + vtk_py/clean_pdata.pyc | Bin 0 -> 604 bytes vtk_py/clipDomainForCutLVMesh.py | 32 + vtk_py/clipDomainForCutLVMesh.pyc | Bin 0 -> 1012 bytes vtk_py/clipSurfacesForCutLVMesh.py | 59 + vtk_py/clipSurfacesForCutLVMesh.pyc | Bin 0 -> 1831 bytes vtk_py/clipSurfacesForCutLVMesh_PLY.py | 59 + vtk_py/clipSurfacesForCutLVMesh_PLY.pyc | Bin 0 -> 1821 bytes vtk_py/clipSurfacesForFullLVMesh.py | 71 + vtk_py/clipSurfacesForFullLVMesh.pyc | Bin 0 -> 2112 bytes vtk_py/clipheart.py | 29 + vtk_py/clipheart.pyc | Bin 0 -> 854 bytes vtk_py/clipheart_ugrid.py | 29 + vtk_py/clipheart_ugrid.pyc | Bin 0 -> 871 bytes vtk_py/computeLVthickness.py | 226 ++++ vtk_py/computeLVthickness.pyc | Bin 0 -> 2808 bytes vtk_py/computeRegionsForBiV.py | 169 +++ vtk_py/computeRegionsForBiV.pyc | Bin 0 -> 3163 bytes vtk_py/computeVolume.py | 66 + vtk_py/computeVolume.pyc | Bin 0 -> 1766 bytes vtk_py/convertAbaqusMeshToUGrid.py | 13 + vtk_py/convertCellDataToXML.py | 26 + vtk_py/convertCellDataToXML.pyc | Bin 0 -> 927 bytes vtk_py/convertPDataToXMLMesh.py | 48 + vtk_py/convertPDataToXMLMesh.pyc | Bin 0 -> 1268 bytes vtk_py/convertQuadDataToVTK.py | 106 ++ vtk_py/convertQuadDataToVTK.pyc | Bin 0 -> 3275 bytes vtk_py/convertQuadScalarDataToVTK.py | 101 ++ vtk_py/convertUGridToXMLMesh.py | 81 ++ vtk_py/convertUGridToXMLMesh.pyc | Bin 0 -> 1405 bytes vtk_py/convertUGridtoPdata.py | 19 + vtk_py/convertUGridtoPdata.pyc | Bin 0 -> 564 bytes vtk_py/convertXMLMeshToUGrid.py | 90 ++ vtk_py/convertXMLMeshToUGrid.pyc | Bin 0 -> 1035 bytes vtk_py/convertXMLMeshToUGrid2D.py | 34 + vtk_py/createFloatArray.py | 12 + vtk_py/createFloatArray.pyc | Bin 0 -> 553 bytes vtk_py/createIntArray.py | 12 + vtk_py/createIntArray.pyc | Bin 0 -> 529 bytes vtk_py/createLVmesh.py | 39 + vtk_py/createLVmesh.pyc | Bin 0 -> 1234 bytes vtk_py/create_BiVmesh.py | 50 + vtk_py/create_BiVmesh.pyc | Bin 0 -> 1622 bytes vtk_py/create_ellipsoidal_LV.py | 42 + vtk_py/create_ellipsoidal_LV.pyc | Bin 0 -> 1260 bytes vtk_py/ellipsoidal.geo | 112 ++ vtk_py/exportDynaDeformationGradients.py | 36 + vtk_py/exportDynaDeformationGradients.pyc | Bin 0 -> 1580 bytes vtk_py/extractCellFromPData.py | 29 + vtk_py/extractCellFromPData.pyc | Bin 0 -> 1067 bytes vtk_py/extractFeNiCsBiVFacet.py | 203 +++ vtk_py/extractFeNiCsBiVFacet.pyc | Bin 0 -> 4911 bytes vtk_py/extractUGridBasedOnThreshold.py | 37 + vtk_py/extractUGridBasedOnThreshold.pyc | Bin 0 -> 1190 bytes vtk_py/extract_slice_thickness.py | 101 ++ vtk_py/extract_slice_thickness.pyc | Bin 0 -> 2422 bytes vtk_py/extract_slice_thickness_LVonly.py | 85 ++ vtk_py/extract_slice_thickness_LVonly.pyc | Bin 0 -> 2293 bytes vtk_py/findPointsInCell.py | 40 + vtk_py/findPointsInCell.pyc | Bin 0 -> 1460 bytes vtk_py/getABPointsFromBoundsAndCenter.py | 25 + vtk_py/getABPointsFromBoundsAndCenter.pyc | Bin 0 -> 738 bytes vtk_py/getABPointsFromTTTSectors.py | 69 + vtk_py/getABPointsFromTTTSectors.pyc | Bin 0 -> 1901 bytes vtk_py/getCellCenters.py | 33 + vtk_py/getCellCenters.pyc | Bin 0 -> 666 bytes vtk_py/getCellLocator.py | 40 + vtk_py/getCellLocator.pyc | Bin 0 -> 753 bytes vtk_py/getPDataNormals.py | 24 + vtk_py/getPDataNormals.pyc | Bin 0 -> 804 bytes vtk_py/getcentroid.py | 16 + vtk_py/getcentroid.pyc | Bin 0 -> 536 bytes vtk_py/lspost.cfile | 3 + vtk_py/mapCellDataToCellData.py | 61 + vtk_py/mapCellDataToCellData.pyc | Bin 0 -> 1932 bytes vtk_py/mapPointDataToCellData.py | 53 + vtk_py/mapPointDataToCellData.pyc | Bin 0 -> 1688 bytes vtk_py/mat_vec_tools.py | 31 + vtk_py/mat_vec_tools.pyc | Bin 0 -> 1266 bytes vtk_py/myPrint.py | 25 + vtk_py/partitionmeshforEP.py | 66 + vtk_py/pyquaternion/__init__.py | 2 + vtk_py/pyquaternion/__init__.pyc | Bin 0 -> 218 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 235 bytes .../__pycache__/quaternion.cpython-37.pyc | Bin 0 -> 44060 bytes vtk_py/pyquaternion/quaternion.py | 1166 +++++++++++++++++ vtk_py/pyquaternion/quaternion.pyc | Bin 0 -> 50273 bytes vtk_py/readAbaqusDeformationGradients.py | 45 + vtk_py/readAbaqusDeformationGradients.pyc | Bin 0 -> 1445 bytes vtk_py/readAbaqusMesh.py | 72 + vtk_py/readAbaqusMesh.pyc | Bin 0 -> 2110 bytes vtk_py/readAbaqusStresses.py | 43 + vtk_py/readAbaqusStresses.pyc | Bin 0 -> 1241 bytes vtk_py/readDynaDeformationGradients.py | 38 + vtk_py/readDynaDeformationGradients.pyc | Bin 0 -> 1350 bytes vtk_py/readDynaDeformationGradients_vtk.py | 64 + vtk_py/readDynaDeformationGradients_vtk.pyc | Bin 0 -> 2167 bytes vtk_py/readDynaMesh.py | 101 ++ vtk_py/readDynaMesh.pyc | Bin 0 -> 2768 bytes vtk_py/readDynaMeshStructured.py | 90 ++ vtk_py/readDynaMeshStructured.pyc | Bin 0 -> 2494 bytes vtk_py/readFiberOrientation.py | 52 + vtk_py/readFiberOrientation.pyc | Bin 0 -> 1240 bytes vtk_py/readMSHGrid.py | 69 + vtk_py/readMSHGrid.pyc | Bin 0 -> 1593 bytes vtk_py/readPData.py | 22 + vtk_py/readPData.pyc | Bin 0 -> 855 bytes vtk_py/readPLY.py | 22 + vtk_py/readPLY.pyc | Bin 0 -> 678 bytes vtk_py/readSTL.py | 22 + vtk_py/readSTL.pyc | Bin 0 -> 678 bytes vtk_py/readUGrid.py | 22 + vtk_py/readUGrid.pyc | Bin 0 -> 699 bytes vtk_py/readVTI.py | 22 + vtk_py/readVTI.pyc | Bin 0 -> 670 bytes vtk_py/readXMLImage.py | 18 + vtk_py/readXMLImage.pyc | Bin 0 -> 629 bytes vtk_py/readXMLPData.py | 22 + vtk_py/readXMLPData.pyc | Bin 0 -> 870 bytes vtk_py/readXMLPUGrid.py | 22 + vtk_py/readXMLPUGrid.pyc | Bin 0 -> 719 bytes vtk_py/readXMLUGrid.py | 22 + vtk_py/readXMLUGrid.pyc | Bin 0 -> 714 bytes vtk_py/rotatePData.py | 31 + vtk_py/rotatePData_w_axis.py | 37 + vtk_py/rotatePData_w_axis.pyc | Bin 0 -> 1096 bytes vtk_py/rotateSymmetricMatrix.py | 78 ++ vtk_py/rotateSymmetricMatrix.pyc | Bin 0 -> 1249 bytes vtk_py/rotateUGrid.py | 30 + vtk_py/rotateUGrid.pyc | Bin 0 -> 864 bytes vtk_py/sliceheart.py | 28 + vtk_py/sliceheart.pyc | Bin 0 -> 801 bytes vtk_py/splitDomainBetweenEndoAndEpi.py | 80 ++ vtk_py/splitDomainBetweenEndoAndEpi.pyc | Bin 0 -> 1744 bytes vtk_py/transform_mesh_w_4x4mat.py | 54 + vtk_py/transform_mesh_w_4x4mat.pyc | Bin 0 -> 1547 bytes vtk_py/transform_pdata.py | 32 + vtk_py/transform_pdata.pyc | Bin 0 -> 919 bytes vtk_py/translate_mesh.py | 30 + vtk_py/translate_mesh.pyc | Bin 0 -> 796 bytes vtk_py/vtkmtvfiber_sheet_vector_translator.py | 263 ++++ ...mtvfiber_sheet_vector_translator_LVonly.py | 162 +++ vtk_py/vtkmtvtranslator_lintets_LVonly_v1.py | 462 +++++++ vtk_py/vtkmtvtranslator_lintets_v1.py | 554 ++++++++ vtk_py/vtkmtvtranslator_quadtets_LVonly_v1.py | 477 +++++++ vtk_py/vtkmtvtranslator_quadtets_v1.py | 561 ++++++++ vtk_py/writeFiberOrientationFileForAbaqus.py | 46 + vtk_py/writeFiberOrientationFileForAbaqus.pyc | Bin 0 -> 1598 bytes vtk_py/writeFiberOrientationFileForGNUPlot.py | 63 + .../writeFiberOrientationFileForGNUPlot.pyc | Bin 0 -> 2094 bytes vtk_py/writePData.py | 17 + vtk_py/writePData.pyc | Bin 0 -> 657 bytes vtk_py/writeSTL.py | 17 + vtk_py/writeSTL.pyc | Bin 0 -> 638 bytes vtk_py/writeUGrid.py | 17 + vtk_py/writeUGrid.pyc | Bin 0 -> 665 bytes vtk_py/writeXMLImage.py | 17 + vtk_py/writeXMLImage.pyc | Bin 0 -> 673 bytes vtk_py/writeXMLPData.pyc | Bin 0 -> 678 bytes vtk_py/writeXMLPdata.py | 17 + vtk_py/writeXMLUGrid.py | 18 + vtk_py/writeXMLUGrid.pyc | Bin 0 -> 680 bytes 199 files changed, 11926 insertions(+) create mode 100644 vtk_py/BiV.geo create mode 100644 vtk_py/CreateVertexFromPoint.py create mode 100644 vtk_py/CreateVertexFromPoint.pyc create mode 100644 vtk_py/LV.geo create mode 100644 vtk_py/LV_original.geo create mode 100644 vtk_py/Set4ChamberDirection.py create mode 100644 vtk_py/Set4ChamberDirection.pyc create mode 100644 vtk_py/SetBiVFiber.py create mode 100644 vtk_py/SetBiVFiber_J.py create mode 100644 vtk_py/SetBiVFiber_J.pyc create mode 100644 vtk_py/SetBiVFiber_Quad.py create mode 100644 vtk_py/SetBiVFiber_Quad_PyQ.py create mode 100644 vtk_py/SetBiVFiber_Quad_PyQ.pyc create mode 100644 vtk_py/SlerpTestJ.py create mode 100644 vtk_py/__init__.py create mode 100644 vtk_py/__init__.pyc create mode 100644 vtk_py/_q! create mode 100644 vtk_py/addFieldPrincipalDirections.py create mode 100644 vtk_py/addFieldPrincipalDirections.pyc create mode 100644 vtk_py/addLVfiber.py create mode 100644 vtk_py/addLVfiber.pyc create mode 100644 vtk_py/addLVfiber_LDRB.py create mode 100644 vtk_py/addLVfiber_LDRB.pyc create mode 100644 vtk_py/addLocalCylindricalDirections.py create mode 100644 vtk_py/addLocalCylindricalDirections.pyc create mode 100644 vtk_py/addLocalFiberOrientation.py create mode 100644 vtk_py/addLocalFiberOrientation.pyc create mode 100644 vtk_py/addLocalFiberOrientation2.py create mode 100644 vtk_py/addLocalFiberOrientation2.pyc create mode 100644 vtk_py/addLocalFiberOrientation_infarct.py create mode 100644 vtk_py/addLocalFiberOrientation_infarct.pyc create mode 100644 vtk_py/addLocalProlateSpheroidalDirections.py create mode 100644 vtk_py/addLocalProlateSpheroidalDirections.pyc create mode 100644 vtk_py/addMappingFromPointsToCells.py create mode 100644 vtk_py/addMappingFromPointsToCells.pyc create mode 100644 vtk_py/addSystolicStrains.py create mode 100644 vtk_py/addSystolicStrains.pyc create mode 100644 vtk_py/clean_pdata.py create mode 100644 vtk_py/clean_pdata.pyc create mode 100644 vtk_py/clipDomainForCutLVMesh.py create mode 100644 vtk_py/clipDomainForCutLVMesh.pyc create mode 100644 vtk_py/clipSurfacesForCutLVMesh.py create mode 100644 vtk_py/clipSurfacesForCutLVMesh.pyc create mode 100644 vtk_py/clipSurfacesForCutLVMesh_PLY.py create mode 100644 vtk_py/clipSurfacesForCutLVMesh_PLY.pyc create mode 100644 vtk_py/clipSurfacesForFullLVMesh.py create mode 100644 vtk_py/clipSurfacesForFullLVMesh.pyc create mode 100644 vtk_py/clipheart.py create mode 100644 vtk_py/clipheart.pyc create mode 100644 vtk_py/clipheart_ugrid.py create mode 100644 vtk_py/clipheart_ugrid.pyc create mode 100644 vtk_py/computeLVthickness.py create mode 100644 vtk_py/computeLVthickness.pyc create mode 100644 vtk_py/computeRegionsForBiV.py create mode 100644 vtk_py/computeRegionsForBiV.pyc create mode 100644 vtk_py/computeVolume.py create mode 100644 vtk_py/computeVolume.pyc create mode 100644 vtk_py/convertAbaqusMeshToUGrid.py create mode 100644 vtk_py/convertCellDataToXML.py create mode 100644 vtk_py/convertCellDataToXML.pyc create mode 100644 vtk_py/convertPDataToXMLMesh.py create mode 100644 vtk_py/convertPDataToXMLMesh.pyc create mode 100644 vtk_py/convertQuadDataToVTK.py create mode 100644 vtk_py/convertQuadDataToVTK.pyc create mode 100644 vtk_py/convertQuadScalarDataToVTK.py create mode 100644 vtk_py/convertUGridToXMLMesh.py create mode 100644 vtk_py/convertUGridToXMLMesh.pyc create mode 100644 vtk_py/convertUGridtoPdata.py create mode 100644 vtk_py/convertUGridtoPdata.pyc create mode 100644 vtk_py/convertXMLMeshToUGrid.py create mode 100644 vtk_py/convertXMLMeshToUGrid.pyc create mode 100644 vtk_py/convertXMLMeshToUGrid2D.py create mode 100644 vtk_py/createFloatArray.py create mode 100644 vtk_py/createFloatArray.pyc create mode 100644 vtk_py/createIntArray.py create mode 100644 vtk_py/createIntArray.pyc create mode 100644 vtk_py/createLVmesh.py create mode 100644 vtk_py/createLVmesh.pyc create mode 100644 vtk_py/create_BiVmesh.py create mode 100644 vtk_py/create_BiVmesh.pyc create mode 100644 vtk_py/create_ellipsoidal_LV.py create mode 100644 vtk_py/create_ellipsoidal_LV.pyc create mode 100644 vtk_py/ellipsoidal.geo create mode 100644 vtk_py/exportDynaDeformationGradients.py create mode 100644 vtk_py/exportDynaDeformationGradients.pyc create mode 100644 vtk_py/extractCellFromPData.py create mode 100644 vtk_py/extractCellFromPData.pyc create mode 100644 vtk_py/extractFeNiCsBiVFacet.py create mode 100644 vtk_py/extractFeNiCsBiVFacet.pyc create mode 100644 vtk_py/extractUGridBasedOnThreshold.py create mode 100644 vtk_py/extractUGridBasedOnThreshold.pyc create mode 100644 vtk_py/extract_slice_thickness.py create mode 100644 vtk_py/extract_slice_thickness.pyc create mode 100644 vtk_py/extract_slice_thickness_LVonly.py create mode 100644 vtk_py/extract_slice_thickness_LVonly.pyc create mode 100644 vtk_py/findPointsInCell.py create mode 100644 vtk_py/findPointsInCell.pyc create mode 100644 vtk_py/getABPointsFromBoundsAndCenter.py create mode 100644 vtk_py/getABPointsFromBoundsAndCenter.pyc create mode 100644 vtk_py/getABPointsFromTTTSectors.py create mode 100644 vtk_py/getABPointsFromTTTSectors.pyc create mode 100644 vtk_py/getCellCenters.py create mode 100644 vtk_py/getCellCenters.pyc create mode 100644 vtk_py/getCellLocator.py create mode 100644 vtk_py/getCellLocator.pyc create mode 100644 vtk_py/getPDataNormals.py create mode 100644 vtk_py/getPDataNormals.pyc create mode 100644 vtk_py/getcentroid.py create mode 100644 vtk_py/getcentroid.pyc create mode 100644 vtk_py/lspost.cfile create mode 100644 vtk_py/mapCellDataToCellData.py create mode 100644 vtk_py/mapCellDataToCellData.pyc create mode 100644 vtk_py/mapPointDataToCellData.py create mode 100644 vtk_py/mapPointDataToCellData.pyc create mode 100644 vtk_py/mat_vec_tools.py create mode 100644 vtk_py/mat_vec_tools.pyc create mode 100644 vtk_py/myPrint.py create mode 100644 vtk_py/partitionmeshforEP.py create mode 100644 vtk_py/pyquaternion/__init__.py create mode 100644 vtk_py/pyquaternion/__init__.pyc create mode 100644 vtk_py/pyquaternion/__pycache__/__init__.cpython-37.pyc create mode 100644 vtk_py/pyquaternion/__pycache__/quaternion.cpython-37.pyc create mode 100644 vtk_py/pyquaternion/quaternion.py create mode 100644 vtk_py/pyquaternion/quaternion.pyc create mode 100644 vtk_py/readAbaqusDeformationGradients.py create mode 100644 vtk_py/readAbaqusDeformationGradients.pyc create mode 100644 vtk_py/readAbaqusMesh.py create mode 100644 vtk_py/readAbaqusMesh.pyc create mode 100644 vtk_py/readAbaqusStresses.py create mode 100644 vtk_py/readAbaqusStresses.pyc create mode 100644 vtk_py/readDynaDeformationGradients.py create mode 100644 vtk_py/readDynaDeformationGradients.pyc create mode 100644 vtk_py/readDynaDeformationGradients_vtk.py create mode 100644 vtk_py/readDynaDeformationGradients_vtk.pyc create mode 100644 vtk_py/readDynaMesh.py create mode 100644 vtk_py/readDynaMesh.pyc create mode 100644 vtk_py/readDynaMeshStructured.py create mode 100644 vtk_py/readDynaMeshStructured.pyc create mode 100644 vtk_py/readFiberOrientation.py create mode 100644 vtk_py/readFiberOrientation.pyc create mode 100644 vtk_py/readMSHGrid.py create mode 100644 vtk_py/readMSHGrid.pyc create mode 100644 vtk_py/readPData.py create mode 100644 vtk_py/readPData.pyc create mode 100644 vtk_py/readPLY.py create mode 100644 vtk_py/readPLY.pyc create mode 100644 vtk_py/readSTL.py create mode 100644 vtk_py/readSTL.pyc create mode 100644 vtk_py/readUGrid.py create mode 100644 vtk_py/readUGrid.pyc create mode 100644 vtk_py/readVTI.py create mode 100644 vtk_py/readVTI.pyc create mode 100644 vtk_py/readXMLImage.py create mode 100644 vtk_py/readXMLImage.pyc create mode 100644 vtk_py/readXMLPData.py create mode 100644 vtk_py/readXMLPData.pyc create mode 100644 vtk_py/readXMLPUGrid.py create mode 100644 vtk_py/readXMLPUGrid.pyc create mode 100644 vtk_py/readXMLUGrid.py create mode 100644 vtk_py/readXMLUGrid.pyc create mode 100644 vtk_py/rotatePData.py create mode 100644 vtk_py/rotatePData_w_axis.py create mode 100644 vtk_py/rotatePData_w_axis.pyc create mode 100644 vtk_py/rotateSymmetricMatrix.py create mode 100644 vtk_py/rotateSymmetricMatrix.pyc create mode 100644 vtk_py/rotateUGrid.py create mode 100644 vtk_py/rotateUGrid.pyc create mode 100644 vtk_py/sliceheart.py create mode 100644 vtk_py/sliceheart.pyc create mode 100644 vtk_py/splitDomainBetweenEndoAndEpi.py create mode 100644 vtk_py/splitDomainBetweenEndoAndEpi.pyc create mode 100644 vtk_py/transform_mesh_w_4x4mat.py create mode 100644 vtk_py/transform_mesh_w_4x4mat.pyc create mode 100644 vtk_py/transform_pdata.py create mode 100644 vtk_py/transform_pdata.pyc create mode 100644 vtk_py/translate_mesh.py create mode 100644 vtk_py/translate_mesh.pyc create mode 100644 vtk_py/vtkmtvfiber_sheet_vector_translator.py create mode 100644 vtk_py/vtkmtvfiber_sheet_vector_translator_LVonly.py create mode 100644 vtk_py/vtkmtvtranslator_lintets_LVonly_v1.py create mode 100644 vtk_py/vtkmtvtranslator_lintets_v1.py create mode 100644 vtk_py/vtkmtvtranslator_quadtets_LVonly_v1.py create mode 100644 vtk_py/vtkmtvtranslator_quadtets_v1.py create mode 100644 vtk_py/writeFiberOrientationFileForAbaqus.py create mode 100644 vtk_py/writeFiberOrientationFileForAbaqus.pyc create mode 100644 vtk_py/writeFiberOrientationFileForGNUPlot.py create mode 100644 vtk_py/writeFiberOrientationFileForGNUPlot.pyc create mode 100644 vtk_py/writePData.py create mode 100644 vtk_py/writePData.pyc create mode 100644 vtk_py/writeSTL.py create mode 100644 vtk_py/writeSTL.pyc create mode 100644 vtk_py/writeUGrid.py create mode 100644 vtk_py/writeUGrid.pyc create mode 100644 vtk_py/writeXMLImage.py create mode 100644 vtk_py/writeXMLImage.pyc create mode 100644 vtk_py/writeXMLPData.pyc create mode 100644 vtk_py/writeXMLPdata.py create mode 100644 vtk_py/writeXMLUGrid.py create mode 100644 vtk_py/writeXMLUGrid.pyc diff --git a/vtk_py/BiV.geo b/vtk_py/BiV.geo new file mode 100644 index 0000000..cb80a16 --- /dev/null +++ b/vtk_py/BiV.geo @@ -0,0 +1,54 @@ +Geometry.HideCompounds = 1; + +Mesh.CharacteristicLengthFactor = <> ;// Fine + +Mesh.Algorithm = 6; // (1=MeshAdapt, 2=Automatic, 5=Delaunay, 6=Frontal, 7=bamg, 8=delquad) (Default=2) +Mesh.RecombineAll = 0; + +Mesh.RemeshAlgorithm = 1; // (0=no split, 1=automatic, 2=automatic only with metis) (Default=0) + +Mesh.RemeshParametrization = 7; // (0=harmonic_circle, 1=conformal_spectral, 2=rbf, 3=harmonic_plane, 4=convex_circle, 5=convex_plane, 6=harmonic square, 7=conformal_fe) (Default=4) + +Mesh.Algorithm3D = 4; // (1=Delaunay, 4=Frontal, 5=Frontal Delaunay, 6=Frontal Hex, 7=MMG3D, 9=R-tree) (Default=1) +Mesh.Recombine3DAll = 0; + +Mesh.Optimize = 1; +Mesh.OptimizeNetgen = 1; + +Mesh.Smoothing = 0; + +Merge <>; +Merge <>; +Merge <>; + +CreateTopology; + +ll[] = Line "*"; +L_LV_base = newl; Compound Line(L_LV_base) = ll[2]; +L_RV_base = newl; Compound Line(L_RV_base) = ll[0]; +L_epi_base = newl; Compound Line(L_epi_base) = ll[1]; +// Physical Line("EPI_BASE") = {L_epi_base}; +//Physical Line(0) = {L_epi_base}; + +ss[] = Surface "*"; +S_LV = news; Compound Surface(S_LV) = ss[0]; +S_RV = news; Compound Surface(S_RV) = ss[1]; +S_epi = news; Compound Surface(S_epi) = ss[2]; +// Physical Surface("LV") = {S_LV}; +// Physical Surface("RV") = {S_RV}; +// Physical Surface("epi") = {S_epi}; +//Physical Surface(3) = {S_epi}; +//Physical Surface(1) = {S_RV}; +//Physical Surface(2) = {S_LV}; + + +LL_base = newll; Line Loop(LL_base) = {L_LV_base, L_RV_base, L_epi_base}; +S_base = news; Plane Surface(S_base) = {LL_base}; +// Physical Surface("BASE") = {S_base}; +//Physical Surface(4) = {S_base}; + +SL_wall = newsl; Surface Loop(SL_wall) = {S_LV, S_RV, S_epi, S_base}; +V_wall = newv; Volume(V_wall) = {SL_wall}; +//Physical Volume("WALL") = {V_wall}; +Physical Volume(0) = {V_wall}; + diff --git a/vtk_py/CreateVertexFromPoint.py b/vtk_py/CreateVertexFromPoint.py new file mode 100644 index 0000000..720adcb --- /dev/null +++ b/vtk_py/CreateVertexFromPoint.py @@ -0,0 +1,19 @@ +######################################################################## + +import sys +import vtk + +######################################################################## + +def CreateVertexFromPoint(ugrid): + + vertices = vtk.vtkCellArray() + for p in range(ugrid.GetNumberOfPoints()): + vert = vtk.vtkVertex() + vert.GetPointIds().SetId(0, p) + vertices.InsertNextCell(vert) + + ugrid.SetCells(1, vertices) + + + diff --git a/vtk_py/CreateVertexFromPoint.pyc b/vtk_py/CreateVertexFromPoint.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eeac6d747f871c591dd97f8047f18d82c2b123e8 GIT binary patch literal 644 zcmb_Z!AiqG5S`t$S~V4VQ1IkQ$jKZ;@F1d8)EtabL7^bhCTp9Rv~_n{T1Zdz6Z}EH z!4J@xP0@=-m+Z_i@4cOuUFWmD{{C^$jbOPXbk3vkJfDEAhQwwMdh$XyHQ!;wz zImAr9XoZoWva;Mw%7(On0I7flz+AvI0F+Qr$KlRG!1?1L%%vq&EXjewfwanXy229* z2@46L5Rk4iMk4XL3lDrsjlB@U1ae!N2@{$M37hfO*nmS}f-mTnxv8@3OzX}JtJKh) zK~G_Ws!N68IPWTb^L#r@256AgB)nG|)f6{Mj>Ur5SoNL4AjVBXf`K7gNIX6tYt$l; zYvb{qSo*l9lh|StA}5hD$TmmF3~qUp!3J|gmERxc%Fm)qDZizR>gcHNUp23Na`iNt z`Aw}ls7ikqdYD^p`=c3dk@!!LeHp$8kgnJfuGkh0Y2VOZlbM+ogRMG+Uo-#UhzB3% R!+4yj6MhiGzw8RP@(ocxk2C-P literal 0 HcmV?d00001 diff --git a/vtk_py/LV.geo b/vtk_py/LV.geo new file mode 100644 index 0000000..1ed44fc --- /dev/null +++ b/vtk_py/LV.geo @@ -0,0 +1,74 @@ +Geometry.HideCompounds = 1; + +Mesh.CharacteristicLengthFactor = <>; // Coarse + +Mesh.Algorithm = 6; // (1=MeshAdapt, 2=Automatic, 5=Delaunay, 6=Frontal, 7=bamg, 8=delquad) (Default=2) +Mesh.RecombineAll = 0; + +Mesh.RemeshAlgorithm = 1; // (0=no split, 1=automatic, 2=automatic only with metis) (Default=0) + +Mesh.RemeshParametrization = 7; // (0=harmonic_circle, 1=conformal_spectral, 2=rbf, 3=harmonic_plane, 4=convex_circle, 5=convex_plane, 6=harmonic square, 7=conformal_fe) (Default=4) + +Mesh.Algorithm3D = 4; // (1=Delaunay, 4=Frontal, 5=Frontal Delaunay, 6=Frontal Hex, 7=MMG3D, 9=R-tree) (Default=1) +Mesh.Recombine3DAll = 0; + +Mesh.Optimize = 1; +Mesh.OptimizeNetgen = 1; + +Mesh.Smoothing = 0; + +Merge "<>"; +Merge "<>"; + +CreateTopology; + +ll[] = Line "*"; +L_LV_base = newl; Compound Line(L_LV_base) = ll[1]; +L_epi_base = newl; Compound Line(L_epi_base) = ll[0]; +//Physical Line("EPI_BASE") = {L_epi_base}; + +ss[] = Surface "*"; +S_LV = news; Compound Surface(S_LV) = ss[0]; +S_epi = news; Compound Surface(S_epi) = ss[1]; +Physical Surface("LV") = {S_LV}; +Physical Surface("epi") = {S_epi}; + +LL_base = newll; Line Loop(LL_base) = {L_LV_base, L_epi_base}; +S_base = news; Plane Surface(S_base) = {LL_base}; +Physical Surface("BASE") = {S_base}; + +SL_wall = newsl; Surface Loop(SL_wall) = {S_LV, S_epi, S_base}; +V_wall = newv; Volume(V_wall) = {SL_wall}; +Physical Volume("WALL") = {V_wall}; + + +// +//// P1 = newp; Point(P1) = {36., 74., 70.}; +//// Field[1] = Attractor; +//// Field[1].NodesList = {P1}; +//// Field[2] = Threshold; +//// Field[2].IField = 1; +//// Field[2].LcMin = 100.; +//// Field[2].LcMax = 100.; +//// Field[2].DistMin = 0.; +//// Field[2].DistMax = 10.; +//// Background Field = 2; +// +//// Field[1] = Box; +//// Field[1].VIn = 5.; +//// Field[1].VOut = 5.; +//// Field[1].XMin = 30.; +//// Field[1].XMax = 40.; +//// Field[1].YMin = 70.; +//// Field[1].YMax = 80.; +//// Field[1].ZMin = 69.; +//// Field[1].ZMax = 71.; +//// Background Field = 1; + + + + + + + + diff --git a/vtk_py/LV_original.geo b/vtk_py/LV_original.geo new file mode 100644 index 0000000..1ed44fc --- /dev/null +++ b/vtk_py/LV_original.geo @@ -0,0 +1,74 @@ +Geometry.HideCompounds = 1; + +Mesh.CharacteristicLengthFactor = <>; // Coarse + +Mesh.Algorithm = 6; // (1=MeshAdapt, 2=Automatic, 5=Delaunay, 6=Frontal, 7=bamg, 8=delquad) (Default=2) +Mesh.RecombineAll = 0; + +Mesh.RemeshAlgorithm = 1; // (0=no split, 1=automatic, 2=automatic only with metis) (Default=0) + +Mesh.RemeshParametrization = 7; // (0=harmonic_circle, 1=conformal_spectral, 2=rbf, 3=harmonic_plane, 4=convex_circle, 5=convex_plane, 6=harmonic square, 7=conformal_fe) (Default=4) + +Mesh.Algorithm3D = 4; // (1=Delaunay, 4=Frontal, 5=Frontal Delaunay, 6=Frontal Hex, 7=MMG3D, 9=R-tree) (Default=1) +Mesh.Recombine3DAll = 0; + +Mesh.Optimize = 1; +Mesh.OptimizeNetgen = 1; + +Mesh.Smoothing = 0; + +Merge "<>"; +Merge "<>"; + +CreateTopology; + +ll[] = Line "*"; +L_LV_base = newl; Compound Line(L_LV_base) = ll[1]; +L_epi_base = newl; Compound Line(L_epi_base) = ll[0]; +//Physical Line("EPI_BASE") = {L_epi_base}; + +ss[] = Surface "*"; +S_LV = news; Compound Surface(S_LV) = ss[0]; +S_epi = news; Compound Surface(S_epi) = ss[1]; +Physical Surface("LV") = {S_LV}; +Physical Surface("epi") = {S_epi}; + +LL_base = newll; Line Loop(LL_base) = {L_LV_base, L_epi_base}; +S_base = news; Plane Surface(S_base) = {LL_base}; +Physical Surface("BASE") = {S_base}; + +SL_wall = newsl; Surface Loop(SL_wall) = {S_LV, S_epi, S_base}; +V_wall = newv; Volume(V_wall) = {SL_wall}; +Physical Volume("WALL") = {V_wall}; + + +// +//// P1 = newp; Point(P1) = {36., 74., 70.}; +//// Field[1] = Attractor; +//// Field[1].NodesList = {P1}; +//// Field[2] = Threshold; +//// Field[2].IField = 1; +//// Field[2].LcMin = 100.; +//// Field[2].LcMax = 100.; +//// Field[2].DistMin = 0.; +//// Field[2].DistMax = 10.; +//// Background Field = 2; +// +//// Field[1] = Box; +//// Field[1].VIn = 5.; +//// Field[1].VOut = 5.; +//// Field[1].XMin = 30.; +//// Field[1].XMax = 40.; +//// Field[1].YMin = 70.; +//// Field[1].YMax = 80.; +//// Field[1].ZMin = 69.; +//// Field[1].ZMax = 71.; +//// Background Field = 1; + + + + + + + + diff --git a/vtk_py/Set4ChamberDirection.py b/vtk_py/Set4ChamberDirection.py new file mode 100644 index 0000000..1396b23 --- /dev/null +++ b/vtk_py/Set4ChamberDirection.py @@ -0,0 +1,62 @@ +######################################################################## +import argparse +import numpy as np +from dolfin import * +import math +######################################################################## + + +def Set4ChamberDirection(mesh, outfilename, apexC, apexR, basalC, basalN, outdirectory="./"): + + + def BCbase(x, on_boundary): + basalNorm = np.linalg.norm(basalN) + basalNN = 1.0/basalNorm*np.array(basalN) + + return (x[0] - basalC[0])*basalNN[0] + (x[1] - basalC[1])*basalNN[1] < DOLFIN_EPS and on_boundary + + def BCapex(x, on_boundary): + return (x[0] - apexC[0])**2 + (x[1] - apexC[1])**2 < apexR[0]**2 and on_boundary + + + V = FunctionSpace(mesh, 'Lagrange', 1) + u0 = Constant(1.0) + u1 = Constant(0.0) + + bc =[DirichletBC(V, u1, BCapex), DirichletBC(V, u0, BCbase)] + + # Define variational problem + u = TrialFunction(V) + v = TestFunction(V) + f = Constant(0) + a = inner(nabla_grad(u), nabla_grad(v))*dx + L = f*v*dx + + # Compute solution + u = Function(V) + solve(a == L, u, bc) + u_a = u.vector().array() + + # Compute gradient + V_g = VectorFunctionSpace(mesh, 'Lagrange', 1) + v = TestFunction(V_g) + w = TrialFunction(V_g) + + a = inner(w, v)*dx + L = inner(grad(u), v)*dx + grad_u = Function(V_g) + solve(a == L, grad_u) + #normalize_grad_u = project(grad_u/sqrt(dot(grad_u, grad_u)), V_g) + grad_u.rename('matdir', 'matdir') + + #plot(normalize_grad_u, interactive=True) + pvdoutfile = outdirectory+outfilename+"_matdir.pvd" + file15 = File(pvdoutfile) + file15 << grad_u + + #plot(normalize_grad_u, interactive=True) + pvdoutfile2 = outdirectory+outfilename+"_dirsoln.pvd" + file16 = File(pvdoutfile2) + file16 << u + + diff --git a/vtk_py/Set4ChamberDirection.pyc b/vtk_py/Set4ChamberDirection.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b713668b9ae17475aa99ae999d9a1fd93c6b4f90 GIT binary patch literal 2071 zcmb_c&2A$_5U!bV{v6xM+D@Es;ljb<5bpvDNUQ={FA+$=pmCH#E>_#qvBw$DSTk)C zOXE`z*$3c}coE(Ji3fnMs_lfJy)E`kb#+yB{e9Kr{Z%gh_Q$9F0j+*6)^G4;ryv0y zha#e@2i~D8SL7~59$l;~3UpPVz@wl*zrbRHk9C_Ha1s8EU#IDSHB3IvIKoM5u!ZFV zylmv*&3=da-lcnwt`WhZUx}7mbPu5;5?3VKWQcO4Bf;)GTJEspV1w=)S{8-h6n>YC zOZg7vyOeJeELYnid`0}g4DvlP8)P;qFY}g}3Nv>unJua> z_bK0FQC)V=$ZW5jz#*bT|BP;sNtyBz$92Gsi*!dc-etP1k|{kcsV1q^Bs@|_)xs3Pz4`I{?E6md+n=mQ8Q)vO)g^JSpUmPwr3*kz z)K{5`I_!a`+U`0{4kTej(0*h)O=u|l0;DxcCb|_3BCT7#&a_GgqtGzN2PRD7lj%Zyy>7#?F0m^vhMcO?aHa3--b>$KLB)M@Y&)?Wp_jG) zw30;)pu%R%b34EKS37MN*|BXU2b2nZj_q^ZwqWVuRNuC3H^KS;SGfw#st6>X5OQ$S zh|bk8Rq;?uRu7o37$gf53&KR1AWSocuV?v_={(4|eLYqr5gI!Wn)`g9401M$rQO}B z8fb~tPU6g{*vJe3j&LxFw0YeY^NTc8(fSN7G|`35%!7d262`GkWwc_|k5mtt2QrSq zt@wXpjD+S|aGnG9B=vbp4I_Ff`?ax6kCoz%(MWZyCR)b&ER1xMKeMu%=xk&McxJAl zVKbj=^(#zx=zVUGq@T>VVG?WMb3OhZtN0>aO4hUIc6lL7e;}%v(7DiSp-SjEzG6hP zo|5&lHx%j5QXnVZn@MAU0OE3PqG9I6OG)`r^U0&?a~UnU@b9YQy{=dt`M&G=@rBR6 z1R<}wSuIqZl2dX&@<8$b(5ZksbgG_}*PLTWYwo^R!MZK9$ruUXDjiN$nrXQz@oX|( v_}pHpFG!;6Ft)HMGxA?TVXFmWx%VoMFVCw<63ilf%GWw$0hds8N`-#_2H2Vx literal 0 HcmV?d00001 diff --git a/vtk_py/SetBiVFiber.py b/vtk_py/SetBiVFiber.py new file mode 100644 index 0000000..4d6a7f6 --- /dev/null +++ b/vtk_py/SetBiVFiber.py @@ -0,0 +1,552 @@ +######################################################################## +import argparse +import numpy as np +#from thLib import quat +import sys +import os +from dolfin import * +from sympy import Symbol, nsolve +import math +from scipy import linalg +from scipy import optimize +from cgkit.cgtypes import * +######################################################################## + + +def SetBiVFiber(mesh, boundaries, mtvfiberfilename, mtvsheetfilename, al_endo, al_epi, b_endo, b_epi, isrotatept, isreturn, outfilename, outdirectory="./", epiid=2, rvid=1, lvid=3): + + + # Set Input files + + #outdirectory = './' + #outfilename = "temp" + #filename = "/home/lclee/Research/fiber_orientation/Laplace_function_smaller_mesh/back_up/mesh/LKK_EDmesh.xml" + #facetfilename = "/home/lclee/Research/fiber_orientation/Laplace_function_smaller_mesh/back_up/mesh/LKK_EDmesh_facet_region.xml" + #print outfilename + #print mtvfiberfilename + #print isrotatept + + + # Set Fiber angle + #b_endo = -65; b_epi = 25; al_endo = 40; al_epi = -50; + al_endo = al_endo*math.pi/180; b_endo = b_endo*math.pi/180; + al_epi = al_epi*math.pi/180; b_epi = b_epi*math.pi/180; + + minz = np.amin(mesh.coordinates()[:,2]) + maxz = np.amax(mesh.coordinates()[:,2]) + + # Boundary condition for Laplace equation from the bottom to the top + + def right_boundary(x): + return x[2] < minz+1.0 + + # Function that solves the Laplace equation and and calculates the gradient of the solution + + def lap(Me, boud, par,op, filename): + epi=epiid; rv=rvid; lv=lvid; + # Create mesh and define function space + mesh = Me + V = FunctionSpace(mesh, 'Lagrange', 1) + y = mesh.coordinates() + sa = y.shape + ttt = y[:, 2].min() + cord = np.argwhere(y == ttt); + point = y[cord[0,0],:] + #print sa, cord, point + u0 = Constant(0.0) + if op == 1: + bc =[ DirichletBC(V, u0, right_boundary), DirichletBC(V, 1, boud, 4)] + # Define boundary conditions + else: + bc = [DirichletBC(V, par[0], boud, lv), DirichletBC(V, par[1], boud, epi ), DirichletBC(V, par[2], boud, rv)] + + # Define variational problem + u = TrialFunction(V) + v = TestFunction(V) + f = Constant(0) + a = inner(nabla_grad(u), nabla_grad(v))*dx + L = f*v*dx + + # Compute solution + u = Function(V) + solve(a == L, u, bc) + u_a = u.vector().array() + + # Compute gradient + V_g = VectorFunctionSpace(mesh, 'Lagrange', 1) + v = TestFunction(V_g) + w = TrialFunction(V_g) + + a = inner(w, v)*dx + L = inner(grad(u), v)*dx + grad_u = Function(V_g) + solve(a == L, grad_u) + grad_u.rename('grad_u', 'continuous gradient field') + grad_ua = grad_u.vector().array() + + #plot(u, interactive=True) + + # Dump solution to file in VTK format + #newfilename = filename + '.pvd' + #file1= File(newfilename) + #file1<< u + + #newfilename = filename + 'grad.pvd' + #file2 = File(newfilename) + #file2 << grad_u + + # Hold plot + #interactive() + return u_a, grad_ua + + # Function to calculate the lenght of the vector + + def len_vec(vec): + l = (vec[0]**2 + vec[1]**2 + vec[2]**2)**0.5 + return l + + + + ################################################################################################## + # Function to calculate the orthogonal axis using the gradients calculated in the previous step + ################################################################################################### + def L1(e0, v0): + + L1x = (v0[0] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[0])**2 + L1y = (v0[1] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[1])**2 + L1z = (v0[2] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[2])**2 + + return (L1x + L1y + L1z)**0.5; + + def P(e0, v0): + + P1x = v0[0] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[0] + P1y = v0[1] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[1] + P1z = v0[2] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[2] + + return [P1x, P1y, P1z]; + + def function_e0(e0, v0, e1): + + f = [L1(e0,v0)*e0[0] - (e1[1]*P(e0,v0)[2] - e1[2]*P(e0,v0)[1]), + L1(e0,v0)*e0[1] - (e1[2]*P(e0,v0)[0] - e1[0]*P(e0,v0)[2]), + L1(e0,v0)*e0[2] - (e1[0]*P(e0,v0)[1] - e1[1]*P(e0,v0)[0])] + + return f; + + + def axisf(vec1, vec2): + + len_vec2 = len_vec(vec2); len_vec1 = len_vec(vec1); + e1 = vec1/len_vec1; ini_e2 = vec2/len_vec2; + ini_e0 = np.cross(e1, ini_e2) + + # Solve using symbolic + #e0x = Symbol('e0x'); e0y = Symbol('e0y') ; e0z = Symbol('e0z'); e2x = Symbol('e2x'); e2y = Symbol('e2y') ; e2z = Symbol('e2z'); + + #aa = nsolve([ e0x - e1[1]*e2z + e1[2]*e2y, + # e0y - e1[2]*e2x + e1[0]*e2z, + # e0z - e1[0]*e2y + e1[1]*e2x, + # e2x*( ( vec2[0] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0x)**2 + ( vec2[1] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0y)**2 + ( vec2[2] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0z)**2 )**0.5 - vec2[0] + (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0x , + # e2y*( ( vec2[0] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0x)**2 + ( vec2[1] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0y)**2 + ( vec2[2] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0z)**2 )**0.5 - vec2[1] + (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0y, + # e2z*( ( vec2[0] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0x)**2 + ( vec2[1] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0y)**2 + ( vec2[2] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0z)**2 )**0.5 - vec2[2] + (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0z ], + # [ e0x, e0y, e0z, e2x, e2y, e2z ],[ini_e0[0], ini_e0[1], ini_e0[2], ini_e2[0], ini_e2[1],ini_e2[2] ], minimal=True) + + + e0 = np.zeros(3); e2 = np.zeros(3); + #e0[0] = aa[0]; e0[1] = aa[1]; e0[2] = aa[2]; + #e2[0] = aa[3]; e2[1] = aa[4]; e2[2] = aa[5]; + + # Solve using numerical + def function_wrap(e0): + return function_e0(e0, vec2, e1) + + sol = optimize.root(function_wrap, [ini_e0[0], ini_e0[1], ini_e0[2]], method='hybr') + e0[0] = sol.x[0]; e0[1] = sol.x[1]; e0[2] = sol.x[2]; + e2 = P(e0, vec2); + len_e2 = len_vec(e2) + e2[0] = e2[0]/len_e2; e2[1] = e2[1]/len_e2; e2[2] = e2[2]/len_e2; + + #print e0[0], e0[1], e0[2] + #print e2[0], e2[1], e2[2] + + Q = np.array([[e0[0], e1[0], e2[0] ],[ e0[1], e1[1], e2[1]],[ e0[2], e1[2], e2[2]]]) + + + return Q + + outfile = open("quat.txt", "w") + + ################################################################################################# + #Function to ensure the that the axis are orthogonal + ################################################################################################# + def orto(Q, cnt): + e0 = np.zeros(3); e1 = np.zeros(3); e2 = np.zeros(3); + e0[0] = Q[0][0]; e0[1] = Q[1][0]; e0[2] = Q[2][0]; + e1[0] = Q[0][1]; e1[1] = Q[1][1]; e1[2] = Q[2][1]; + e2[0] = Q[0][2]; e2[1] = Q[1][2]; e2[2] = Q[2][2]; + e0x = Symbol('e0x'); e0y = Symbol('e0y') ; e0z = Symbol('e0z'); e2x = Symbol('e2x'); e2y = Symbol('e2y') ; e2z = Symbol('e2z'); + + + try: + + aa = nsolve( [ e0x - e1[1]*e2z + e1[2]*e2y, e0y - e1[2]*e2x + e1[0]*e2z, e0z - e1[0]*e2y + e1[1]*e2x, e1[0] - e2y*e0z + e2z*e0y, e1[1] - e2z*e0x + e2x*e0z, e1[2] - e2x*e0y + e2y*e0x ], [ e0x, e0y, e0z, e2x, e2y, e2z ],[e0[0], e0[1], e0[2], e2[0], e2[1],e2[2] ]) + + + + e0[0] = aa[0]; e0[1] = aa[1]; e0[2] = aa[2]; + e2[0] = aa[3]; e2[1] = aa[4]; e2[2] = aa[5]; + Qa = np.array([[e0[0], e1[0], e2[0] ],[ e0[1], e1[1], e2[1]],[ e0[2], e1[2], e2[2]]]) + + except ZeroDivisionError as detail: + print 'Handling run-time error:', detail + Qa = Q + f = quat.rotmat2quat(Qa) + print >>outfile, cnt, " ", f + return Qa + + + def orto3(Q, cnt): + + Q2 = np.dot(np.transpose(Q),Q) + Q2inv = np.linalg.inv(Q2) + sqrtQ2 = linalg.sqrtm(Q2inv) + Qa = np.dot(Q,sqrtQ2) + + return Qa + + ################################################################################################# + #Function to ensure the that the axis are orthogonal but this one is not working prorperly + ################################################################################################# + + def orto2(Q): + e0 = np.zeros(3); e1 = np.zeros(3); e2 = np.zeros(3); + e0[0] = Q[0][0]; e0[1] = Q[1][0]; e0[2] = Q[2][0]; + e1[0] = Q[0][1]; e1[1] = Q[1][1]; e1[2] = Q[2][1]; + e2[0] = Q[0][2]; e2[1] = Q[1][2]; e2[2] = Q[2][2]; + + while np.dot(e0, e1) + np.dot(e0, e2) + np.dot(e1, e2) > 10e-30: + e2 = np.cross(e0, e1); + e0 = np.cross(e1, e2); + Qa = np.array([[e0[0], e1[0], e2[0] ],[ e0[1], e1[1], e2[1]],[ e0[2], e1[2], e2[2]]]) + return Qa + + ############################################################################################## + #Function 3 - This function rotates the axis calculated in the previous steps + ############################################################################################## + + def orient(Q, al, bt): + arr1 =np.array( [[np.cos(al), -np.sin(al), 0 ],[np.sin(al), np.cos(al), 0],[0, 0, 1]]); + arr2 = np.array([[1, 0, 0],[0, np.cos(bt), np.sin(bt) ],[0, -np.sin(bt), np.cos(bt) ]]); + out = np.dot(Q, arr1, arr2) + return out + + ################################################################################################## + #Function 4 - This function calculates quarternions and interpolates these quarternions + ################################################################################################# + + + def bislerp(Qa, Qb, t): + + Qa_M = mat3([Qa[0,0], Qa[0,1], Qa[0,2], Qa[1,0], Qa[1,1], Qa[1,2], Qa[2,0], Qa[2,1], Qa[2,2]]) + Qb_M = mat3([Qb[0,0], Qb[0,1], Qb[0,2], Qb[1,0], Qb[1,1], Qb[1,2], Qb[2,0], Qb[2,1], Qb[2,2]]) + qa = quat(Qa_M) + qb = quat(Qb_M) + + val = np.zeros(8) + quat_i = quat(0,1,0,0) + quat_j = quat(0,0,1,0) + quat_k = quat(0,0,0,1) + quat_array = [qa, -qa, qa*quat_i, -qa*quat_i, qa*quat_j, -qa*quat_j, qa*quat_k, -qa*quat_k] + cnt = 0 + for qt in quat_array: + val[cnt] = qt.dot(qb) + cnt = cnt + 1 + + qt = quat_array[val.argmax(axis=0)] + + if(t < 0): + t = 0.0 + + + qm = slerp(t, qt, qb) + qm = qm.normalize() + Qm_M = qm.toMat3() + Qm = [[Qm_M[0,0], Qm_M[0,1], Qm_M[0,2]], [Qm_M[1,0], Qm_M[1,1], Qm_M[1,2]], [Qm_M[2,0], Qm_M[2,1], Qm_M[2,2]]] + + return Qm + + + + ################################################################################################# + ######Generating results and using the functions ########## + ################################################################################################# + # DOF map + V = VectorFunctionSpace(mesh, "Lagrange", 1) + S = FunctionSpace(mesh, "Lagrange", 1) + + dof_coordinates = V.tabulate_dof_coordinates() + Sdof_coordinates = S.tabulate_dof_coordinates() + n = V.dim() + d = mesh.geometry().dim() + dof_coordinates.resize((n, d)) + Sdof_coordinates.resize((n,d)) + + x_dofs = V.sub(0).dofmap().dofs() + y_dofs = V.sub(1).dofmap().dofs() + z_dofs = V.sub(2).dofmap().dofs() + + jj = np.array([ 1, 1, 1] ); hh = np.array([1, 1, 1]); print np.dot(jj, hh) + + + ####### Solving the poisson equation ############ + + # case 1) epi -> u = 0 and rv/lv -> u = 1 + + print "Solve Poisson Eq. 1, epi -> u = 0 and rv/lv -> u = 1" + par1 = [0, 1, 0]; epi, dd = lap(mesh, boundaries, par1, 0, 'phi_epi') + + num_of_nodes = len(dd)/3 + scalar_array = np.zeros(num_of_nodes) + scalar_dof = S.dofmap().dofs() + + # case 2) lv -> u = 0 and rv/epi -> u = 1 + + print "Solve Poisson Eq. 2, lv -> u = 0 and rv/epi -> u = 1" + par2 = [1, 0, 0]; lv, dd2 = lap(mesh, boundaries, par2, 0, 'phi_lv'); #dd2 = -1*dd2 + + # case 3) rv -> u = 0 and epi/lv -> u = 1 + + print "Solve Poisson Eq. 3, rv -> u = 0 and epi/lv -> u = 1" + par3 = [0, 0, 1]; rv, dd3 = lap(mesh, boundaries, par3, 0, 'phi_rv') + + #case 4) from the top to the bottom + + print "Solve Poisson Eq. 4, from the top to the bottom" + par1 = [0, 1, 0]; b, dd4 = lap(mesh, boundaries, par1, 1, 'phi_ab') + + + # Start calculating the fiber orientation + cnt = 0; c = 0; + vector_array = np.zeros(V.dim()) + func_of_vector = Function(V); + func_of_scalar = Function(S); + func_of_e1 = Function(V); + func_of_e2 = Function(V); + func_of_e3 = Function(V); + + vec_dd = np.zeros(3); vec_dd2 = np.zeros(3); vec_dd3 = np.zeros(3); vec_dd4 = np.zeros(3); + + Qepi = np.zeros((len(dd),3)); Qrv = np.zeros((len(dd),3)); Qlv = np.zeros((len(dd),3)); + Qendo = np.zeros((len(dd),3)) + Qfiber = np.zeros((len(dd),3)) + + e0_epi = np.zeros(len(dd)); e1_epi = np.zeros(len(dd)); e2_epi = np.zeros(len(dd)); + e0_rv = np.zeros(len(dd)); e1_rv = np.zeros(len(dd)); e2_rv = np.zeros(len(dd)); + e0_lv = np.zeros(len(dd)); e1_lv = np.zeros(len(dd)); e2_lv = np.zeros(len(dd)); + check = np.zeros(len(dd)); check2 = np.zeros(len(dd)); + ds = np.zeros(len(dd)/3); al_s = np.zeros(len(dd)/3); b_s = np.zeros(len(dd)/3); + al_w = np.zeros(len(dd)/3); b_w = np.zeros(len(dd)/3); + + e0_endo = np.zeros(len(dd)); e1_endo = np.zeros(len(dd)); e2_endo = np.zeros(len(dd)); + e0_fiber = np.zeros(len(dd)); e1_fiber = np.zeros(len(dd)); e2_fiber = np.zeros(len(dd)); + + + # Open MTV fiber and sheet files + if(mtvfiberfilename): + mtvfiberfile = open(mtvfiberfilename, 'w') + print >>mtvfiberfile, len(dd)/3, 10 + + + if(mtvsheetfilename): + mtvsheetfile = open(mtvsheetfilename, 'w') + print >>mtvsheetfile, len(dd)/3 + + + num = 1 + #for x_dof, y_dof, z_dof, scl in zip(x_dofs[num:num+2], y_dofs[num:num+2], z_dofs[num:num+2], scalar_dof[num:num+2]): + for x_dof, y_dof, z_dof, scl in zip(x_dofs, y_dofs, z_dofs, scalar_dof): + + #print "cnt = ", cnt + + if(abs(rv[scl]) < 1e-9 and abs(rv[scl] + lv[scl]) < 1e-9): + ds[scl] = 0.0 + else: + ds[scl] = rv[scl]/(lv[scl]+rv[scl]) + + al_s[scl] = al_endo*(1 - ds[scl]) - al_endo*ds[scl]; b_s[scl] = b_endo*(1 - ds[scl]) - b_endo*ds[scl]; + al_w[scl] = al_endo*(1 - epi[scl]) + al_epi*epi[scl]; b_w[scl] = b_endo*(1 - epi[scl]) + b_epi*epi[scl]; + + vec_dd[0] = dd[x_dof]; vec_dd[1] = dd[y_dof]; vec_dd[2] = dd[z_dof]; + vec_dd2[0] = dd2[x_dof]; vec_dd2[1] = dd2[y_dof]; vec_dd2[2] = dd2[z_dof]; + vec_dd3[0] = dd3[x_dof]; vec_dd3[1] = dd3[y_dof]; vec_dd3[2] = dd3[z_dof]; + vec_dd4[0] = dd4[x_dof]; vec_dd4[1] = dd4[y_dof]; vec_dd4[2] = dd4[z_dof]; + + + Qlv[c:c+3][0:3]= axisf(vec_dd4, -1.0*vec_dd2); + Qlv[c:c+3][0:3] = orto3(Qlv[c:c+3][0:3], cnt); + Qlv[c:c+3][0:3]= orient(Qlv[c:c+3][0:3], al_s[scl], b_s[scl]) + + + e0_lv[x_dof] = Qlv[c][0]; e0_lv[y_dof] = Qlv[c+1][0]; e0_lv[z_dof] = Qlv[c+2][0]; + e1_lv[x_dof] = Qlv[c][1]; e1_lv[y_dof] = Qlv[c+1][1]; e1_lv[z_dof] = Qlv[c+2][1]; + e2_lv[x_dof] = Qlv[c][2]; e2_lv[y_dof] = Qlv[c+1][2]; e2_lv[z_dof] = Qlv[c+2][2]; + + Qrv[c:c+3][0:3] = axisf(vec_dd4, -1.0*vec_dd3); + Qrv[c:c+3][0:3] = orto3(Qrv[c:c+3][0:3], cnt); + Qrv[c:c+3][0:3]= orient(Qrv[c:c+3][0:3], -al_s[scl], -b_s[scl]); + + e0_rv[x_dof] = Qrv[c][0]; e0_rv[y_dof] = Qrv[c+1][0]; e0_rv[z_dof] = Qrv[c+2][0]; + e1_rv[x_dof] = Qrv[c][1]; e1_rv[y_dof] = Qrv[c+1][1]; e1_rv[z_dof] = Qrv[c+2][1]; + e2_rv[x_dof] = Qrv[c][2]; e2_rv[y_dof] = Qrv[c+1][2]; e2_rv[z_dof] = Qrv[c+2][2]; + + + Qendo[c:c+3][0:3] = bislerp(Qlv[c:c+3][0:3], Qrv[c:c+3][0:3], ds[scl]) + e0_endo[x_dof] = Qendo[c][0]; e0_endo[y_dof] = Qendo[c+1][0]; e0_endo[z_dof] = Qendo[c+2][0]; + e1_endo[x_dof] = Qendo[c][1]; e1_endo[y_dof] = Qendo[c+1][1]; e1_endo[z_dof] = Qendo[c+2][1]; + e2_endo[x_dof] = Qendo[c][2]; e2_endo[y_dof] = Qendo[c+1][2]; e2_endo[z_dof] = Qendo[c+2][2]; + + + Qepi[c:c+3][0:3] = axisf(vec_dd4, vec_dd); + Qepi[c:c+3][0:3] = orto3(Qepi[c:c+3][0:3], cnt); + Qepi[c:c+3][0:3] = orient(Qepi[c:c+3][0:3], al_w[scl], b_w[scl]); + + e0_epi[x_dof] = Qepi[c][0]; e0_epi[y_dof] = Qepi[c+1][0]; e0_epi[z_dof] = Qepi[c+2][0]; + e1_epi[x_dof] = Qepi[c][1]; e1_epi[y_dof] = Qepi[c+1][1]; e1_epi[z_dof] = Qepi[c+2][1]; + e2_epi[x_dof] = Qepi[c][2]; e2_epi[y_dof] = Qepi[c+1][2]; e2_epi[z_dof] = Qepi[c+2][2]; + + Qfiber[c:c+3][0:3] = bislerp(Qendo[c:c+3][0:3], Qepi[c:c+3][0:3], epi[scl]) + e0_fiber[x_dof] = Qfiber[c][0]; e0_fiber[y_dof] = Qfiber[c+1][0]; e0_fiber[z_dof] = Qfiber[c+2][0]; + e1_fiber[x_dof] = Qfiber[c][1]; e1_fiber[y_dof] = Qfiber[c+1][1]; e1_fiber[z_dof] = Qfiber[c+2][1]; + e2_fiber[x_dof] = Qfiber[c][2]; e2_fiber[y_dof] = Qfiber[c+1][2]; e2_fiber[z_dof] = Qfiber[c+2][2]; + + + cnt = cnt + 1; + c = c + 3; + + if(isrotatept): + points = [(-Sdof_coordinates[scl][2]+maxz)/10.0, Sdof_coordinates[scl][1]/10.0, Sdof_coordinates[scl][0]/10.0] + fvectors = [-1.0*e0_fiber[z_dof], e0_fiber[y_dof], e0_fiber[x_dof]] + svectors = [-1.0*e2_fiber[z_dof], e2_fiber[y_dof], e2_fiber[x_dof]] + + else: + points = [Sdof_coordinates[scl][0], Sdof_coordinates[scl][1], Sdof_coordinates[scl][2]] + fvectors = [e0_fiber[x_dof], e0_fiber[y_dof], e0_fiber[z_dof]] + svectors = [e2_fiber[x_dof], e2_fiber[y_dof], e2_fiber[z_dof]] + + + print >>mtvfiberfile, points[0], points[1], points[2], fvectors[0], fvectors[1], fvectors[2] + print >>mtvsheetfile, points[0], points[1], points[2], svectors[0], svectors[1], svectors[2] + + + + + + #func_of_vector.vector()[:] = e0_epi + #file1 = File("e0_epi.pvd") + #file1 << func_of_vector + # + #func_of_vector.vector()[:] = e1_epi + #file2 = File("e1_epi.pvd") + #file2 << func_of_vector + # + #func_of_vector.vector()[:] = e2_epi + #file3 = File("e2_epi.pvd") + #file3 << func_of_vector + # + #func_of_vector.vector()[:] = e0_rv + #file4 = File("e0_rv.pvd") + #file4 << func_of_vector + # + #func_of_vector.vector()[:] = e1_rv + #file5 = File("e1_rv.pvd") + #file5 << func_of_vector + # + #func_of_vector.vector()[:] = e2_rv + #file6 = File("e2_rv.pvd") + #file6 << func_of_vector + # + #func_of_vector.vector()[:] = e0_lv + #file7 = File("e0_lv.pvd") + #file7 << func_of_vector + # + #func_of_vector.vector()[:] = e1_lv + #file8 = File("e1_lv.pvd") + #file8 << func_of_vector + # + #func_of_vector.vector()[:] = e2_lv + #file9 = File("e2_lv.pvd") + #file9 << func_of_vector + # + #func_of_vector.vector()[:] = e0_endo + #file10 = File("e0_endo.pvd") + #file10 << func_of_vector + # + #func_of_vector.vector()[:] = e1_endo + #file11 = File("e1_endo.pvd") + #file11 << func_of_vector + # + #func_of_vector.vector()[:] = e2_endo + #file12 = File("e2_endo.pvd") + #file12 << func_of_vector + + pvdoutfile = outdirectory+outfilename+"_e0_fiber.pvd" + func_of_e1.vector()[:] = e0_fiber + func_of_e1.rename("fiber", "fiber") + file13 = File(pvdoutfile) + file13 << func_of_e1 + + pvdoutfile = outdirectory+outfilename+"_e1_fiber.pvd" + func_of_e2.vector()[:] = e1_fiber + func_of_e2.rename("sheet", "sheet") + file14 = File(pvdoutfile) + file14 << func_of_e2 + + pvdoutfile = outdirectory+outfilename+"_e2_fiber.pvd" + func_of_e3.rename("sheetnormal", "sheetnormal") + func_of_e3.vector()[:] = e2_fiber + file15 = File(pvdoutfile) + file15 << func_of_e3 + + print isrotatept + print outdirectory + outfilename + print "*******************************************************" + + if(isreturn): + + return func_of_e1, func_of_e2, func_of_e3 + +if (__name__ == "__main__"): + + parser = argparse.ArgumentParser() + parser.add_argument('--xml_folder', type=str, required=True) + parser.add_argument('--xml_meshfilename', type=str, required=True) + parser.add_argument('--xml_facetfilename', type=str, required=True) + parser.add_argument('--mtv_grid_directory', type=str, required=True) + parser.add_argument('--mtv_basename', type=str, required=True) + parser.add_argument('--isrotatept', type=bool, required=True) + parser.add_argument('--al_endo', type=float, required=True) + parser.add_argument('--al_epi', type=float, required=True) + parser.add_argument('--b_endo', type=float, required=True) + parser.add_argument('--b_epi', type=float, required=True) + args = parser.parse_args() + + print "************* Entering SetBiVFiber.py *****************" + + xmlmeshfilename = os.path.join(args.xml_folder, args.xml_meshfilename) + xmlfacetfilename = os.path.join(args.xml_folder, args.xml_facetfilename) + outdirectory = args.mtv_grid_directory + outfilename = args.mtv_basename + isrotatept = args.isrotatept + al_endo = args.al_endo + al_epi = args.al_epi + b_endo = args.b_endo + b_epi = args.b_epi + + mesh = Mesh(xmlmeshfilename) + boundaries = MeshFunction("size_t", mesh, xmlfacetfilename) + mtvfiberfilename = outdirectory+outfilename+"_fiber_rotated.axis" + mtvsheetfilename = outdirectory+outfilename+"_sheet_rotated.axis" + + SetBiVFiber(mesh, boundaries, mtvfiberfilename, mtvsheetfilename, al_endo, al_epi, b_endo, b_epi, isrotatept, outfilename, outdirectory) + diff --git a/vtk_py/SetBiVFiber_J.py b/vtk_py/SetBiVFiber_J.py new file mode 100644 index 0000000..fa82256 --- /dev/null +++ b/vtk_py/SetBiVFiber_J.py @@ -0,0 +1,675 @@ +######################################################################## +import argparse +import numpy as np +#from thLib import quat +import sys +import os +from dolfin import * +from sympy import Symbol, nsolve +import math +from scipy import linalg +from scipy import optimize + +import pdb + +#from cgkit.cgtypes import * # jaY change was this +#from cgkit import * # jaY change + +import pyquaternion as pyq +#import numpy as np + +######################################################################## + + +def SetBiVFiber_J(mesh, boundaries, mtvfiberfilename, mtvsheetfilename, al_endo, al_epi, b_endo, b_epi, isrotatept, isreturn, outfilename, outdirectory="./", epiid=2, rvid=1, lvid=3): + ''' + What: This function uses pyquaternion lib instead of cgkit for quarternion calculations + What more: pip install (http://kieranwynn.github.io/pyquaternion/) + + Where: my_bislerp() instead of bislerp() in SetBiVFiber + + How: vtk_py.SetBiVFiber_J( ... ) + + Plaussible issues: matrix to quaternion is not unique, topology is trickier + http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/tim.htm + http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ + + What else: comment out all other problematic lines + for eg., Sdof_coordinates + + + ''' + + # Set Input files + + #outdirectory = './' + #outfilename = "temp" + #filename = "/home/lclee/Research/fiber_orientation/Laplace_function_smaller_mesh/back_up/mesh/LKK_EDmesh.xml" + #facetfilename = "/home/lclee/Research/fiber_orientation/Laplace_function_smaller_mesh/back_up/mesh/LKK_EDmesh_facet_region.xml" + #print outfilename + #print mtvfiberfilename + #print isrotatept + + + # Set Fiber angle + #b_endo = -65; b_epi = 25; al_endo = 40; al_epi = -50; + al_endo = al_endo*math.pi/180; b_endo = b_endo*math.pi/180; + al_epi = al_epi*math.pi/180; b_epi = b_epi*math.pi/180; + + minz = np.amin(mesh.coordinates()[:,2]) + maxz = np.amax(mesh.coordinates()[:,2]) + + # Boundary condition for Laplace equation from the bottom to the top + + def right_boundary(x): + return x[2] < minz+1.0 + + # Function that solves the Laplace equation and and calculates the gradient of the solution + + def lap(Me, boud, par,op, filename): + epi=epiid; rv=rvid; lv=lvid; + # Create mesh and define function space + mesh = Me + V = FunctionSpace(mesh, 'Lagrange', 1) + y = mesh.coordinates() + sa = y.shape + ttt = y[:, 2].min() + cord = np.argwhere(y == ttt); + point = y[cord[0,0],:] + #print sa, cord, point + u0 = Constant(0.0) + if op == 1: + bc =[ DirichletBC(V, u0, right_boundary), DirichletBC(V, 1, boud, 4)] + # Define boundary conditions + else: + bc = [DirichletBC(V, par[0], boud, lv), DirichletBC(V, par[1], boud, epi ), DirichletBC(V, par[2], boud, rv)] + + # Define variational problem + u = TrialFunction(V) + v = TestFunction(V) + f = Constant(0) + a = inner(nabla_grad(u), nabla_grad(v))*dx + L = f*v*dx + + # Compute solution + u = Function(V) + solve(a == L, u, bc) + u_a = u.vector().array() + + # Compute gradient + V_g = VectorFunctionSpace(mesh, 'Lagrange', 1) + v = TestFunction(V_g) + w = TrialFunction(V_g) + + a = inner(w, v)*dx + L = inner(grad(u), v)*dx + grad_u = Function(V_g) + solve(a == L, grad_u) + grad_u.rename('grad_u', 'continuous gradient field') + grad_ua = grad_u.vector().array() + + #plot(u, interactive=True) + + # Dump solution to file in VTK format + #newfilename = filename + '.pvd' + #file1= File(newfilename) + #file1<< u + + #newfilename = filename + 'grad.pvd' + #file2 = File(newfilename) + #file2 << grad_u + + # Hold plot + #interactive() + return u_a, grad_ua + + # Function to calculate the lenght of the vector + + def len_vec(vec): + l = (vec[0]**2 + vec[1]**2 + vec[2]**2)**0.5 + return l + + + + ################################################################################################## + # Function to calculate the orthogonal axis using the gradients calculated in the previous step + ################################################################################################### + def L1(e0, v0): + + L1x = (v0[0] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[0])**2 + L1y = (v0[1] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[1])**2 + L1z = (v0[2] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[2])**2 + + return (L1x + L1y + L1z)**0.5; + + def P(e0, v0): + + P1x = v0[0] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[0] + P1y = v0[1] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[1] + P1z = v0[2] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[2] + + return [P1x, P1y, P1z]; + + def function_e0(e0, v0, e1): + + f = [L1(e0,v0)*e0[0] - (e1[1]*P(e0,v0)[2] - e1[2]*P(e0,v0)[1]), + L1(e0,v0)*e0[1] - (e1[2]*P(e0,v0)[0] - e1[0]*P(e0,v0)[2]), + L1(e0,v0)*e0[2] - (e1[0]*P(e0,v0)[1] - e1[1]*P(e0,v0)[0])] + + return f; + + + def axisf(vec1, vec2): + + len_vec2 = len_vec(vec2); len_vec1 = len_vec(vec1); + e1 = vec1/len_vec1; ini_e2 = vec2/len_vec2; + ini_e0 = np.cross(e1, ini_e2) + + # Solve using symbolic + #e0x = Symbol('e0x'); e0y = Symbol('e0y') ; e0z = Symbol('e0z'); e2x = Symbol('e2x'); e2y = Symbol('e2y') ; e2z = Symbol('e2z'); + + #aa = nsolve([ e0x - e1[1]*e2z + e1[2]*e2y, + # e0y - e1[2]*e2x + e1[0]*e2z, + # e0z - e1[0]*e2y + e1[1]*e2x, + # e2x*( ( vec2[0] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0x)**2 + ( vec2[1] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0y)**2 + ( vec2[2] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0z)**2 )**0.5 - vec2[0] + (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0x , + # e2y*( ( vec2[0] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0x)**2 + ( vec2[1] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0y)**2 + ( vec2[2] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0z)**2 )**0.5 - vec2[1] + (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0y, + # e2z*( ( vec2[0] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0x)**2 + ( vec2[1] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0y)**2 + ( vec2[2] - (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0z)**2 )**0.5 - vec2[2] + (e0x*vec2[0] + e0y*vec2[1] + e0z*vec2[2])*e0z ], + # [ e0x, e0y, e0z, e2x, e2y, e2z ],[ini_e0[0], ini_e0[1], ini_e0[2], ini_e2[0], ini_e2[1],ini_e2[2] ], minimal=True) + + + e0 = np.zeros(3); e2 = np.zeros(3); + #e0[0] = aa[0]; e0[1] = aa[1]; e0[2] = aa[2]; + #e2[0] = aa[3]; e2[1] = aa[4]; e2[2] = aa[5]; + + # Solve using numerical + def function_wrap(e0): + return function_e0(e0, vec2, e1) + + sol = optimize.root(function_wrap, [ini_e0[0], ini_e0[1], ini_e0[2]], method='hybr') + e0[0] = sol.x[0]; e0[1] = sol.x[1]; e0[2] = sol.x[2]; + e2 = P(e0, vec2); + len_e2 = len_vec(e2) + e2[0] = e2[0]/len_e2; e2[1] = e2[1]/len_e2; e2[2] = e2[2]/len_e2; + + #print e0[0], e0[1], e0[2] + #print e2[0], e2[1], e2[2] + + Q = np.array([[e0[0], e1[0], e2[0] ],[ e0[1], e1[1], e2[1]],[ e0[2], e1[2], e2[2]]]) + + + return Q + + outfile = open("quat.txt", "w") + + ################################################################################################# + #Function to ensure the that the axis are orthogonal + ################################################################################################# + def orto(Q, cnt): + e0 = np.zeros(3); e1 = np.zeros(3); e2 = np.zeros(3); + e0[0] = Q[0][0]; e0[1] = Q[1][0]; e0[2] = Q[2][0]; + e1[0] = Q[0][1]; e1[1] = Q[1][1]; e1[2] = Q[2][1]; + e2[0] = Q[0][2]; e2[1] = Q[1][2]; e2[2] = Q[2][2]; + e0x = Symbol('e0x'); e0y = Symbol('e0y') ; e0z = Symbol('e0z'); e2x = Symbol('e2x'); e2y = Symbol('e2y') ; e2z = Symbol('e2z'); + + + try: + + aa = nsolve( [ e0x - e1[1]*e2z + e1[2]*e2y, e0y - e1[2]*e2x + e1[0]*e2z, e0z - e1[0]*e2y + e1[1]*e2x, e1[0] - e2y*e0z + e2z*e0y, e1[1] - e2z*e0x + e2x*e0z, e1[2] - e2x*e0y + e2y*e0x ], [ e0x, e0y, e0z, e2x, e2y, e2z ],[e0[0], e0[1], e0[2], e2[0], e2[1],e2[2] ]) + + + + e0[0] = aa[0]; e0[1] = aa[1]; e0[2] = aa[2]; + e2[0] = aa[3]; e2[1] = aa[4]; e2[2] = aa[5]; + Qa = np.array([[e0[0], e1[0], e2[0] ],[ e0[1], e1[1], e2[1]],[ e0[2], e1[2], e2[2]]]) + + except ZeroDivisionError as detail: + print 'Handling run-time error:', detail + Qa = Q + f = quat.rotmat2quat(Qa) + print >>outfile, cnt, " ", f + return Qa + + + def orto3(Q, cnt): + + Q2 = np.dot(np.transpose(Q),Q) + Q2inv = np.linalg.inv(Q2) + sqrtQ2 = linalg.sqrtm(Q2inv) + Qa = np.dot(Q,sqrtQ2) + + return Qa + + ################################################################################################# + #Function to ensure the that the axis are orthogonal but this one is not working prorperly + ################################################################################################# + + def orto2(Q): + e0 = np.zeros(3); e1 = np.zeros(3); e2 = np.zeros(3); + e0[0] = Q[0][0]; e0[1] = Q[1][0]; e0[2] = Q[2][0]; + e1[0] = Q[0][1]; e1[1] = Q[1][1]; e1[2] = Q[2][1]; + e2[0] = Q[0][2]; e2[1] = Q[1][2]; e2[2] = Q[2][2]; + + while np.dot(e0, e1) + np.dot(e0, e2) + np.dot(e1, e2) > 10e-30: + e2 = np.cross(e0, e1); + e0 = np.cross(e1, e2); + Qa = np.array([[e0[0], e1[0], e2[0] ],[ e0[1], e1[1], e2[1]],[ e0[2], e1[2], e2[2]]]) + return Qa + + ############################################################################################## + #Function 3 - This function rotates the axis calculated in the previous steps + ############################################################################################## + + def orient(Q, al, bt): + arr1 =np.array( [[np.cos(al), -np.sin(al), 0 ],[np.sin(al), np.cos(al), 0],[0, 0, 1]]); + arr2 = np.array([[1, 0, 0],[0, np.cos(bt), np.sin(bt) ],[0, -np.sin(bt), np.cos(bt) ]]); + out = np.dot(Q, arr1, arr2) + return out + + ################################################################################################## + #Function 4 - This function calculates quarternions and interpolates these quarternions + ################################################################################################# + + + def bislerp(Qa, Qb, t): + + Qa_M = mat3([Qa[0,0], Qa[0,1], Qa[0,2], Qa[1,0], Qa[1,1], Qa[1,2], Qa[2,0], Qa[2,1], Qa[2,2]]) + Qb_M = mat3([Qb[0,0], Qb[0,1], Qb[0,2], Qb[1,0], Qb[1,1], Qb[1,2], Qb[2,0], Qb[2,1], Qb[2,2]]) + qa = quat(Qa_M) + qb = quat(Qb_M) + + val = np.zeros(8) + quat_i = quat(0,1,0,0) + quat_j = quat(0,0,1,0) + quat_k = quat(0,0,0,1) + quat_array = [qa, -qa, qa*quat_i, -qa*quat_i, qa*quat_j, -qa*quat_j, qa*quat_k, -qa*quat_k] + cnt = 0 + for qt in quat_array: + val[cnt] = qt.dot(qb) + cnt = cnt + 1 + + qt = quat_array[val.argmax(axis=0)] + + if(t < 0): + t = 0.0 + + + qm = slerp(t, qt, qb) + qm = qm.normalize() + Qm_M = qm.toMat3() + Qm = [[Qm_M[0,0], Qm_M[0,1], Qm_M[0,2]], [Qm_M[1,0], Qm_M[1,1], Qm_M[1,2]], [Qm_M[2,0], Qm_M[2,1], Qm_M[2,2]]] + + return Qm + + + def my_bislerp(Qa, Qb, t): + + #Qa_M = mat3([Qa[0,0], Qa[0,1], Qa[0,2], Qa[1,0], Qa[1,1], Qa[1,2], Qa[2,0], Qa[2,1], Qa[2,2]]) + #Qb_M = mat3([Qb[0,0], Qb[0,1], Qb[0,2], Qb[1,0], Qb[1,1], Qb[1,2], Qb[2,0], Qb[2,1], Qb[2,2]]) + #qa = quat(Qa_M) + #qb = quat(Qb_M) + + qa = pyq.Quaternion(matrix=Qa) + qb = pyq.Quaternion(matrix=Qb) + + + val = np.zeros(8) + #quat_i = quat(0,1,0,0) + #quat_j = quat(0,0,1,0) + #quat_k = quat(0,0,0,1) + + quat_i = pyq.Quaternion(0,1,0,0) + quat_j = pyq.Quaternion(0,0,1,0) + quat_k = pyq.Quaternion(0,0,0,1) + + quat_array = [qa, -qa, qa*quat_i, -qa*quat_i, qa*quat_j, -qa*quat_j, qa*quat_k, -qa*quat_k] + + + #print('My Quarternion NUMPY array {arr}'.format(arr=np.array(qa))) + #print('My Quarternion NUMPY array {arr}'.format(arr=np.array([qa[0], qa[1], qa[2], qa[3] ]) ) ) + + + cnt = 0 + qb_arr = np.array([qb[0], qb[1], qb[2], qb[3]]) + + for qt in quat_array: + #val[cnt] = qt.dot(qb) + qt_arr = np.array([qt[0], qt[1], qt[2], qt[3]]) + val[cnt] = np.dot(qt_arr, qb_arr) + cnt = cnt + 1 + + #print('calculated val array is :{arr}'.format(arr=val)) + qt = quat_array[val.argmax(axis=0)] + #print('calculated val array is :{arr}'.format(arr=qt)) + + + if(t < 0): + t = 0.0 + + #qm = slerp(t, qt, qb) + qm = pyq.Quaternion.slerp(qt, qb, t) + qm = qm.normalised + Qm_M = qm.rotation_matrix + + #Qm = [[Qm_M[0,0], Qm_M[0,1], Qm_M[0,2]], [Qm_M[1,0], Qm_M[1,1], Qm_M[1,2]], [Qm_M[2,0], Qm_M[2,1], Qm_M[2,2]]] + #print('calculated val matrix is :{mat}'.format(mat=Qm_M)) + + return Qm_M + + + + ################################################################################################# + ######Generating results and using the functions ########## + ################################################################################################# + # DOF map + V = VectorFunctionSpace(mesh, "Lagrange", 1) + S = FunctionSpace(mesh, "Lagrange", 1) + + dof_coordinates = V.tabulate_dof_coordinates() + Sdof_coordinates = S.tabulate_dof_coordinates() + n = V.dim() + d = mesh.geometry().dim() + + #pdb.set_trace() + + dof_coordinates.resize((n, d)) + #Sdof_coordinates.resize((n,d)) # Sdof_coordinates is of size n, so not able to resize + + x_dofs = V.sub(0).dofmap().dofs() + y_dofs = V.sub(1).dofmap().dofs() + z_dofs = V.sub(2).dofmap().dofs() + + jj = np.array([ 1, 1, 1] ); hh = np.array([1, 1, 1]); print np.dot(jj, hh) + + + ####### Solving the poisson equation ############ + + # case 1) epi -> u = 0 and rv/lv -> u = 1 + #pdb.set_trace() + + print "Solve Poisson Eq. 1, epi -> u = 0 and rv/lv -> u = 1" + par1 = [0, 1, 0]; epi, dd = lap(mesh, boundaries, par1, 0, 'phi_epi') + + print "length of dd is :", len(dd) + + num_of_nodes = len(dd)/3 + scalar_array = np.zeros(num_of_nodes) + scalar_dof = S.dofmap().dofs() + + # case 2) lv -> u = 0 and rv/epi -> u = 1 + + print "Solve Poisson Eq. 2, lv -> u = 0 and rv/epi -> u = 1" + par2 = [1, 0, 0]; lv, dd2 = lap(mesh, boundaries, par2, 0, 'phi_lv'); #dd2 = -1*dd2 + + # case 3) rv -> u = 0 and epi/lv -> u = 1 + + print "Solve Poisson Eq. 3, rv -> u = 0 and epi/lv -> u = 1" + par3 = [0, 0, 1]; rv, dd3 = lap(mesh, boundaries, par3, 0, 'phi_rv') + + #case 4) from the top to the bottom + + print "Solve Poisson Eq. 4, from the top to the bottom" + par1 = [0, 1, 0]; b, dd4 = lap(mesh, boundaries, par1, 1, 'phi_ab') + + + # Start calculating the fiber orientation + cnt = 0; c = 0; + vector_array = np.zeros(V.dim()) + func_of_vector = Function(V); + func_of_scalar = Function(S); + func_of_e1 = Function(V); + func_of_e2 = Function(V); + func_of_e3 = Function(V); + + vec_dd = np.zeros(3); vec_dd2 = np.zeros(3); vec_dd3 = np.zeros(3); vec_dd4 = np.zeros(3); + + Qepi = np.zeros((len(dd),3)); Qrv = np.zeros((len(dd),3)); Qlv = np.zeros((len(dd),3)); + Qendo = np.zeros((len(dd),3)) + Qfiber = np.zeros((len(dd),3)) + + e0_epi = np.zeros(len(dd)); e1_epi = np.zeros(len(dd)); e2_epi = np.zeros(len(dd)); + e0_rv = np.zeros(len(dd)); e1_rv = np.zeros(len(dd)); e2_rv = np.zeros(len(dd)); + e0_lv = np.zeros(len(dd)); e1_lv = np.zeros(len(dd)); e2_lv = np.zeros(len(dd)); + check = np.zeros(len(dd)); check2 = np.zeros(len(dd)); + ds = np.zeros(len(dd)/3); al_s = np.zeros(len(dd)/3); b_s = np.zeros(len(dd)/3); + al_w = np.zeros(len(dd)/3); b_w = np.zeros(len(dd)/3); + + e0_endo = np.zeros(len(dd)); e1_endo = np.zeros(len(dd)); e2_endo = np.zeros(len(dd)); + e0_fiber = np.zeros(len(dd)); e1_fiber = np.zeros(len(dd)); e2_fiber = np.zeros(len(dd)); + + #pdb.set_trace() + + ''' # mtv fiber_axis and sheet files not there error + # Open MTV fiber and sheet files + if(mtvfiberfilename): + mtvfiberfile = open(mtvfiberfilename, 'w') + print >>mtvfiberfile, len(dd)/3, 10 + + + if(mtvsheetfilename): + mtvsheetfile = open(mtvsheetfilename, 'w') + print >>mtvsheetfile, len(dd)/3 + ''' + + + + num = 1 + #for x_dof, y_dof, z_dof, scl in zip(x_dofs[num:num+2], y_dofs[num:num+2], z_dofs[num:num+2], scalar_dof[num:num+2]): + for x_dof, y_dof, z_dof, scl in zip(x_dofs, y_dofs, z_dofs, scalar_dof): + + #print "cnt = ", cnt + + if(abs(rv[scl]) < 1e-9 and abs(rv[scl] + lv[scl]) < 1e-9): + ds[scl] = 0.0 + else: + ds[scl] = rv[scl]/(lv[scl]+rv[scl]) + + al_s[scl] = al_endo*(1 - ds[scl]) - al_endo*ds[scl]; b_s[scl] = b_endo*(1 - ds[scl]) - b_endo*ds[scl]; + al_w[scl] = al_endo*(1 - epi[scl]) + al_epi*epi[scl]; b_w[scl] = b_endo*(1 - epi[scl]) + b_epi*epi[scl]; + + vec_dd[0] = dd[x_dof]; vec_dd[1] = dd[y_dof]; vec_dd[2] = dd[z_dof]; + vec_dd2[0] = dd2[x_dof]; vec_dd2[1] = dd2[y_dof]; vec_dd2[2] = dd2[z_dof]; + vec_dd3[0] = dd3[x_dof]; vec_dd3[1] = dd3[y_dof]; vec_dd3[2] = dd3[z_dof]; + vec_dd4[0] = dd4[x_dof]; vec_dd4[1] = dd4[y_dof]; vec_dd4[2] = dd4[z_dof]; + + + Qlv[c:c+3][0:3]= axisf(vec_dd4, -1.0*vec_dd2); + Qlv[c:c+3][0:3] = orto3(Qlv[c:c+3][0:3], cnt); + Qlv[c:c+3][0:3]= orient(Qlv[c:c+3][0:3], al_s[scl], b_s[scl]) + + + e0_lv[x_dof] = Qlv[c][0]; e0_lv[y_dof] = Qlv[c+1][0]; e0_lv[z_dof] = Qlv[c+2][0]; + e1_lv[x_dof] = Qlv[c][1]; e1_lv[y_dof] = Qlv[c+1][1]; e1_lv[z_dof] = Qlv[c+2][1]; + e2_lv[x_dof] = Qlv[c][2]; e2_lv[y_dof] = Qlv[c+1][2]; e2_lv[z_dof] = Qlv[c+2][2]; + + Qrv[c:c+3][0:3] = axisf(vec_dd4, -1.0*vec_dd3); + Qrv[c:c+3][0:3] = orto3(Qrv[c:c+3][0:3], cnt); + Qrv[c:c+3][0:3]= orient(Qrv[c:c+3][0:3], -al_s[scl], -b_s[scl]); + + e0_rv[x_dof] = Qrv[c][0]; e0_rv[y_dof] = Qrv[c+1][0]; e0_rv[z_dof] = Qrv[c+2][0]; + e1_rv[x_dof] = Qrv[c][1]; e1_rv[y_dof] = Qrv[c+1][1]; e1_rv[z_dof] = Qrv[c+2][1]; + e2_rv[x_dof] = Qrv[c][2]; e2_rv[y_dof] = Qrv[c+1][2]; e2_rv[z_dof] = Qrv[c+2][2]; + + ''' + #Qendo[c:c+3][0:3] = bislerp(Qlv[c:c+3][0:3], Qrv[c:c+3][0:3], ds[scl]) + print Qendo[c:c+3][0:3] + print my_bislerp(Qlv[c:c+3][0:3], Qrv[c:c+3][0:3], ds[scl]) + #Qendo[c:c+3][0:3] = my_bislerp(Qlv[c:c+3][0:3], Qrv[c:c+3][0:3], ds[scl]) + print Qendo[c:c+3][0:3] + + print Qendo[c][0] + print Qendo[c][1] + print Qendo[c][2] + + print Qendo[c+1][0] + print Qendo[c+1][1] + print Qendo[c+1][2] + + print Qendo[c+2][0] + print Qendo[c+2][1] + print Qendo[c+2][2] + + print e0_endo + ''' + + #pdb.set_trace() + print "c is :", c + print "x_dof is :", x_dof + print "y_dof is :", y_dof + print "z_dof is :", z_dof + + Qendo[c:c+3][0:3] = my_bislerp(Qlv[c:c+3][0:3], Qrv[c:c+3][0:3], ds[scl]) + + e0_endo[x_dof] = Qendo[c][0]; e0_endo[y_dof] = Qendo[c+1][0]; e0_endo[z_dof] = Qendo[c+2][0]; + e1_endo[x_dof] = Qendo[c][1]; e1_endo[y_dof] = Qendo[c+1][1]; e1_endo[z_dof] = Qendo[c+2][1]; + e2_endo[x_dof] = Qendo[c][2]; e2_endo[y_dof] = Qendo[c+1][2]; e2_endo[z_dof] = Qendo[c+2][2]; + + + Qepi[c:c+3][0:3] = axisf(vec_dd4, vec_dd); + Qepi[c:c+3][0:3] = orto3(Qepi[c:c+3][0:3], cnt); + Qepi[c:c+3][0:3] = orient(Qepi[c:c+3][0:3], al_w[scl], b_w[scl]); + + e0_epi[x_dof] = Qepi[c][0]; e0_epi[y_dof] = Qepi[c+1][0]; e0_epi[z_dof] = Qepi[c+2][0]; + e1_epi[x_dof] = Qepi[c][1]; e1_epi[y_dof] = Qepi[c+1][1]; e1_epi[z_dof] = Qepi[c+2][1]; + e2_epi[x_dof] = Qepi[c][2]; e2_epi[y_dof] = Qepi[c+1][2]; e2_epi[z_dof] = Qepi[c+2][2]; + + #Qfiber[c:c+3][0:3] = bislerp(Qendo[c:c+3][0:3], Qepi[c:c+3][0:3], epi[scl]) + Qfiber[c:c+3][0:3] = my_bislerp(Qendo[c:c+3][0:3], Qepi[c:c+3][0:3], epi[scl]) + e0_fiber[x_dof] = Qfiber[c][0]; e0_fiber[y_dof] = Qfiber[c+1][0]; e0_fiber[z_dof] = Qfiber[c+2][0]; + e1_fiber[x_dof] = Qfiber[c][1]; e1_fiber[y_dof] = Qfiber[c+1][1]; e1_fiber[z_dof] = Qfiber[c+2][1]; + e2_fiber[x_dof] = Qfiber[c][2]; e2_fiber[y_dof] = Qfiber[c+1][2]; e2_fiber[z_dof] = Qfiber[c+2][2]; + + + cnt = cnt + 1; + c = c + 3; + + ''' + if(isrotatept): + points = [(-Sdof_coordinates[scl][2]+maxz)/10.0, Sdof_coordinates[scl][1]/10.0, Sdof_coordinates[scl][0]/10.0] + fvectors = [-1.0*e0_fiber[z_dof], e0_fiber[y_dof], e0_fiber[x_dof]] + svectors = [-1.0*e2_fiber[z_dof], e2_fiber[y_dof], e2_fiber[x_dof]] + + else: + points = [Sdof_coordinates[scl][0], Sdof_coordinates[scl][1], Sdof_coordinates[scl][2]] + fvectors = [e0_fiber[x_dof], e0_fiber[y_dof], e0_fiber[z_dof]] + svectors = [e2_fiber[x_dof], e2_fiber[y_dof], e2_fiber[z_dof]] + + print >>mtvfiberfile, points[0], points[1], points[2], fvectors[0], fvectors[1], fvectors[2] + print >>mtvsheetfile, points[0], points[1], points[2], svectors[0], svectors[1], svectors[2] + + ''' + + #print >> points[0], points[1], points[2], fvectors[0], fvectors[1], fvectors[2] + #print >> points[0], points[1], points[2], svectors[0], svectors[1], svectors[2] + + + + + + #func_of_vector.vector()[:] = e0_epi + #file1 = File("e0_epi.pvd") + #file1 << func_of_vector + # + #func_of_vector.vector()[:] = e1_epi + #file2 = File("e1_epi.pvd") + #file2 << func_of_vector + # + #func_of_vector.vector()[:] = e2_epi + #file3 = File("e2_epi.pvd") + #file3 << func_of_vector + # + #func_of_vector.vector()[:] = e0_rv + #file4 = File("e0_rv.pvd") + #file4 << func_of_vector + # + #func_of_vector.vector()[:] = e1_rv + #file5 = File("e1_rv.pvd") + #file5 << func_of_vector + # + #func_of_vector.vector()[:] = e2_rv + #file6 = File("e2_rv.pvd") + #file6 << func_of_vector + # + #func_of_vector.vector()[:] = e0_lv + #file7 = File("e0_lv.pvd") + #file7 << func_of_vector + # + #func_of_vector.vector()[:] = e1_lv + #file8 = File("e1_lv.pvd") + #file8 << func_of_vector + # + #func_of_vector.vector()[:] = e2_lv + #file9 = File("e2_lv.pvd") + #file9 << func_of_vector + # + #func_of_vector.vector()[:] = e0_endo + #file10 = File("e0_endo.pvd") + #file10 << func_of_vector + # + #func_of_vector.vector()[:] = e1_endo + #file11 = File("e1_endo.pvd") + #file11 << func_of_vector + # + #func_of_vector.vector()[:] = e2_endo + #file12 = File("e2_endo.pvd") + #file12 << func_of_vector + + pvdoutfile = outdirectory+outfilename+"_e0_fiber.pvd" + func_of_e1.vector()[:] = e0_fiber + func_of_e1.rename("fiber", "fiber") + file13 = File(pvdoutfile) + file13 << func_of_e1 + + pvdoutfile = outdirectory+outfilename+"_e1_fiber.pvd" + func_of_e2.vector()[:] = e1_fiber + func_of_e2.rename("sheet", "sheet") + file14 = File(pvdoutfile) + file14 << func_of_e2 + + pvdoutfile = outdirectory+outfilename+"_e2_fiber.pvd" + func_of_e3.rename("sheetnormal", "sheetnormal") + func_of_e3.vector()[:] = e2_fiber + file15 = File(pvdoutfile) + file15 << func_of_e3 + + print isrotatept + print outdirectory + outfilename + print "*******************************************************" + + if(isreturn): + + return func_of_e1, func_of_e2, func_of_e3 + +if (__name__ == "__main__"): + + parser = argparse.ArgumentParser() + parser.add_argument('--xml_folder', type=str, required=True) + parser.add_argument('--xml_meshfilename', type=str, required=True) + parser.add_argument('--xml_facetfilename', type=str, required=True) + parser.add_argument('--mtv_grid_directory', type=str, required=True) + parser.add_argument('--mtv_basename', type=str, required=True) + parser.add_argument('--isrotatept', type=bool, required=True) + parser.add_argument('--al_endo', type=float, required=True) + parser.add_argument('--al_epi', type=float, required=True) + parser.add_argument('--b_endo', type=float, required=True) + parser.add_argument('--b_epi', type=float, required=True) + args = parser.parse_args() + + print "************* Entering SetBiVFiber.py *****************" + + xmlmeshfilename = os.path.join(args.xml_folder, args.xml_meshfilename) + xmlfacetfilename = os.path.join(args.xml_folder, args.xml_facetfilename) + outdirectory = args.mtv_grid_directory + outfilename = args.mtv_basename + isrotatept = args.isrotatept + al_endo = args.al_endo + al_epi = args.al_epi + b_endo = args.b_endo + b_epi = args.b_epi + + mesh = Mesh(xmlmeshfilename) + boundaries = MeshFunction("size_t", mesh, xmlfacetfilename) + mtvfiberfilename = outdirectory+outfilename+"_fiber_rotated.axis" + mtvsheetfilename = outdirectory+outfilename+"_sheet_rotated.axis" + + SetBiVFiber(mesh, boundaries, mtvfiberfilename, mtvsheetfilename, al_endo, al_epi, b_endo, b_epi, isrotatept, outfilename, outdirectory) + diff --git a/vtk_py/SetBiVFiber_J.pyc b/vtk_py/SetBiVFiber_J.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a4e677de71596d3a709d84cf053a76d75b0c996 GIT binary patch literal 17283 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, cnt, " ", f + return Qa + + + def orto3(Q, cnt): + + Q2 = np.dot(np.transpose(Q),Q) + Q2inv = np.linalg.inv(Q2) + sqrtQ2 = linalg.sqrtm(Q2inv) + Qa = np.dot(Q,sqrtQ2) + + return Qa + + ################################################################################################# + #Function to ensure the that the axis are orthogonal but this one is not working prorperly + ################################################################################################# + + def orto2(Q): + e0 = np.zeros(3); e1 = np.zeros(3); e2 = np.zeros(3); + e0[0] = Q[0][0]; e0[1] = Q[1][0]; e0[2] = Q[2][0]; + e1[0] = Q[0][1]; e1[1] = Q[1][1]; e1[2] = Q[2][1]; + e2[0] = Q[0][2]; e2[1] = Q[1][2]; e2[2] = Q[2][2]; + + while np.dot(e0, e1) + np.dot(e0, e2) + np.dot(e1, e2) > 10e-30: + e2 = np.cross(e0, e1); + e0 = np.cross(e1, e2); + Qa = np.array([[e0[0], e1[0], e2[0] ],[ e0[1], e1[1], e2[1]],[ e0[2], e1[2], e2[2]]]) + return Qa + + ############################################################################################## + #Function 3 - This function rotates the axis calculated in the previous steps + ############################################################################################## + + def orient(Q, al, bt): + arr1 =np.array( [[np.cos(al), -np.sin(al), 0 ],[np.sin(al), np.cos(al), 0],[0, 0, 1]]); + arr2 = np.array([[1, 0, 0],[0, np.cos(bt), np.sin(bt) ],[0, -np.sin(bt), np.cos(bt) ]]); + out = np.dot(Q, arr1, arr2) + return out + + ################################################################################################## + #Function 4 - This function calculates quarternions and interpolates these quarternions + ################################################################################################# + + + def bislerp(Qa, Qb, t): + + Qa_M = mat3([Qa[0,0], Qa[0,1], Qa[0,2], Qa[1,0], Qa[1,1], Qa[1,2], Qa[2,0], Qa[2,1], Qa[2,2]]) + Qb_M = mat3([Qb[0,0], Qb[0,1], Qb[0,2], Qb[1,0], Qb[1,1], Qb[1,2], Qb[2,0], Qb[2,1], Qb[2,2]]) + qa = quat(Qa_M) + qb = quat(Qb_M) + + val = np.zeros(8) + quat_i = quat(0,1,0,0) + quat_j = quat(0,0,1,0) + quat_k = quat(0,0,0,1) + quat_array = [qa, -qa, qa*quat_i, -qa*quat_i, qa*quat_j, -qa*quat_j, qa*quat_k, -qa*quat_k] + cnt = 0 + for qt in quat_array: + val[cnt] = qt.dot(qb) + cnt = cnt + 1 + + qt = quat_array[val.argmax(axis=0)] + + if(t < 0): + t = 0.0 + + + qm = slerp(t, qt, qb) + qm = qm.normalize() + Qm_M = qm.toMat3() + Qm = [[Qm_M[0,0], Qm_M[0,1], Qm_M[0,2]], [Qm_M[1,0], Qm_M[1,1], Qm_M[1,2]], [Qm_M[2,0], Qm_M[2,1], Qm_M[2,2]]] + + return Qm + + + + ################################################################################################# + ######Generating results and using the functions ########## + ################################################################################################# + # DOF map + parameters["form_compiler"]["quadrature_degree"] = degree + parameters["form_compiler"]["representation"] = 'quadrature' + + V = FunctionSpace(mesh, VectorElement("Quadrature", mesh.ufl_cell(), degree=degree, quad_scheme="default")) + S = FunctionSpace(mesh, FiniteElement("Quadrature", mesh.ufl_cell(), degree=degree, quad_scheme="default")) + + dof_coordinates = V.tabulate_dof_coordinates() + Sdof_coordinates = S.tabulate_dof_coordinates() + n = V.dim() + d = mesh.geometry().dim() + dof_coordinates.resize((n, d)) + Sdof_coordinates.resize((n,d)) + + x_my_first, x_my_last = V.sub(0).dofmap().ownership_range() + x_dofs = np.arange(0, x_my_last-x_my_first, d) + y_dofs = np.arange(1, x_my_last-x_my_first, d) + z_dofs = np.arange(2, x_my_last-x_my_first, d) + + + jj = np.array([ 1, 1, 1] ); hh = np.array([1, 1, 1]); + + + ####### Solving the poisson equation ############ + + # case 1) epi -> u = 0 and rv/lv -> u = 1 + + if(MPI.rank(mpi_comm_world()) == 0): + print "Solve Poisson Eq. 1, epi -> u = 0 and rv/lv -> u = 1" + par1 = [0, 1, 0]; epi, dd = lap(mesh, boundaries, par1, 0, 'phi_epi') + + #total_dd = comm.allreduce(len(dd), op=pyMPI.SUM) + #num_of_nodes = total_dd/3 + #scalar_array = np.zeros(num_of_nodes) + #scalar_dof = S.dofmap().dofs() + + total_dd = len(dd) + S_my_first, S_my_last = S.dofmap().ownership_range() + scalar_dof = filter(lambda dof: S.dofmap().local_to_global_index(dof) not in S.dofmap().local_to_global_unowned(), + xrange(S_my_last-S_my_first)) + + + # case 2) lv -> u = 0 and rv/epi -> u = 1 + + if(MPI.rank(mpi_comm_world()) == 0): + print "Solve Poisson Eq. 2, lv -> u = 0 and rv/epi -> u = 1" + par2 = [1, 0, 0]; lv, dd2 = lap(mesh, boundaries, par2, 0, 'phi_lv'); #dd2 = -1*dd2 + + # case 3) rv -> u = 0 and epi/lv -> u = 1 + + if(MPI.rank(mpi_comm_world()) == 0): + print "Solve Poisson Eq. 3, rv -> u = 0 and epi/lv -> u = 1" + par3 = [0, 0, 1]; rv, dd3 = lap(mesh, boundaries, par3, 0, 'phi_rv') + + #case 4) from the top to the bottom + + if(MPI.rank(mpi_comm_world()) == 0): + print "Solve Poisson Eq. 4, from the top to the bottom" + par1 = [0, 1, 0]; b, dd4 = lap(mesh, boundaries, par1, 1, 'phi_ab') + + + + # Start calculating the fiber orientation + cnt = 0; c = 0; + vector_array = np.zeros(V.dim()) + + func_of_vector = Function(V); + func_of_scalar = Function(S); + + func_of_e0 = Function(V); + func_of_e1 = Function(V); + func_of_e2 = Function(V); + + func_of_e0_vector = func_of_e0.vector() + func_of_e1_vector = func_of_e1.vector() + func_of_e2_vector = func_of_e2.vector() + + e0_fiber = func_of_e0_vector.get_local() + e1_fiber = func_of_e1_vector.get_local() + e2_fiber = func_of_e2_vector.get_local() + + vec_dd = np.zeros(3); vec_dd2 = np.zeros(3); vec_dd3 = np.zeros(3); vec_dd4 = np.zeros(3); + + Qepi = np.zeros((total_dd,3)); Qrv = np.zeros((total_dd,3)); Qlv = np.zeros((total_dd,3)); + Qendo = np.zeros((total_dd,3)) + Qfiber = np.zeros((total_dd,3)) + + e0_epi = np.zeros(total_dd); e1_epi = np.zeros(total_dd); e2_epi = np.zeros(total_dd); + e0_rv = np.zeros(total_dd); e1_rv = np.zeros(total_dd); e2_rv = np.zeros(total_dd); + e0_lv = np.zeros(total_dd); e1_lv = np.zeros(total_dd); e2_lv = np.zeros(total_dd); + check = np.zeros(total_dd); check2 = np.zeros(total_dd); + ds = np.zeros(total_dd/3); al_s = np.zeros(total_dd/3); b_s = np.zeros(total_dd/3); + al_w = np.zeros(total_dd/3); b_w = np.zeros(total_dd/3); + + e0_endo = np.zeros(total_dd); e1_endo = np.zeros(total_dd); e2_endo = np.zeros(total_dd); + + + # Open MTV fiber and sheet files + if( MPI.rank(mpi_comm_world()) == 0): + + if(mtvfiberfilename): + mtvfiberfile = open(mtvfiberfilename, 'w') + print >>mtvfiberfile, total_dd/3, 10 + + + if(mtvsheetfilename): + mtvsheetfile = open(mtvsheetfilename, 'w') + print >>mtvsheetfile, total_dd/3 + + + for x_dof, y_dof, z_dof, scl in zip(x_dofs, y_dofs, z_dofs, scalar_dof): + + + if(abs(rv[scl]) < 1e-9 and abs(rv[scl] + lv[scl]) < 1e-9): + ds[scl] = 0.0 + else: + ds[scl] = rv[scl]/(lv[scl]+rv[scl]) + + + pt = Point(np.array([Sdof_coordinates[scl][0], Sdof_coordinates[scl][1], Sdof_coordinates[scl][2]])) + meshid = mesh.bounding_box_tree().compute_first_collision(pt) + + al_endo = lv_fiber_angle[0]; b_endo = lv_sheet_angle[0]; + al_epi = lv_fiber_angle[1]; b_epi = lv_sheet_angle[1]; + + if matid is not None: + if(matid.array()[meshid] == septummatid): + al_endo = septum_fiber_angle[0]; b_endo = septum_sheet_angle[0]; + al_epi = septum_fiber_angle[1]; b_epi = septum_sheet_angle[1]; + elif(matid.array()[meshid] == rvmatid): + al_endo = rv_fiber_angle[0]; b_endo = rv_sheet_angle[0]; + al_epi = rv_fiber_angle[1]; b_epi = rv_sheet_angle[1]; + + + al_s[scl] = al_endo*(1 - ds[scl]) - al_endo*ds[scl]; b_s[scl] = b_endo*(1 - ds[scl]) - b_endo*ds[scl]; + al_w[scl] = al_endo*(1 - epi[scl]) + al_epi*epi[scl]; b_w[scl] = b_endo*(1 - epi[scl]) + b_epi*epi[scl]; + + vec_dd[0] = dd[x_dof]; vec_dd[1] = dd[y_dof]; vec_dd[2] = dd[z_dof]; + vec_dd2[0] = dd2[x_dof]; vec_dd2[1] = dd2[y_dof]; vec_dd2[2] = dd2[z_dof]; + vec_dd3[0] = dd3[x_dof]; vec_dd3[1] = dd3[y_dof]; vec_dd3[2] = dd3[z_dof]; + vec_dd4[0] = dd4[x_dof]; vec_dd4[1] = dd4[y_dof]; vec_dd4[2] = dd4[z_dof]; + + + Qlv[c:c+3][0:3]= axisf(vec_dd4, -1.0*vec_dd2); + Qlv[c:c+3][0:3] = orto3(Qlv[c:c+3][0:3], cnt); + Qlv[c:c+3][0:3]= orient(Qlv[c:c+3][0:3], al_s[scl], b_s[scl]) + + + e0_lv[x_dof] = Qlv[c][0]; e0_lv[y_dof] = Qlv[c+1][0]; e0_lv[z_dof] = Qlv[c+2][0]; + e1_lv[x_dof] = Qlv[c][1]; e1_lv[y_dof] = Qlv[c+1][1]; e1_lv[z_dof] = Qlv[c+2][1]; + e2_lv[x_dof] = Qlv[c][2]; e2_lv[y_dof] = Qlv[c+1][2]; e2_lv[z_dof] = Qlv[c+2][2]; + + Qrv[c:c+3][0:3] = axisf(vec_dd4, -1.0*vec_dd3); + Qrv[c:c+3][0:3] = orto3(Qrv[c:c+3][0:3], cnt); + Qrv[c:c+3][0:3]= orient(Qrv[c:c+3][0:3], -al_s[scl], -b_s[scl]); + + e0_rv[x_dof] = Qrv[c][0]; e0_rv[y_dof] = Qrv[c+1][0]; e0_rv[z_dof] = Qrv[c+2][0]; + e1_rv[x_dof] = Qrv[c][1]; e1_rv[y_dof] = Qrv[c+1][1]; e1_rv[z_dof] = Qrv[c+2][1]; + e2_rv[x_dof] = Qrv[c][2]; e2_rv[y_dof] = Qrv[c+1][2]; e2_rv[z_dof] = Qrv[c+2][2]; + + + Qendo[c:c+3][0:3] = bislerp(Qlv[c:c+3][0:3], Qrv[c:c+3][0:3], ds[scl]) + e0_endo[x_dof] = Qendo[c][0]; e0_endo[y_dof] = Qendo[c+1][0]; e0_endo[z_dof] = Qendo[c+2][0]; + e1_endo[x_dof] = Qendo[c][1]; e1_endo[y_dof] = Qendo[c+1][1]; e1_endo[z_dof] = Qendo[c+2][1]; + e2_endo[x_dof] = Qendo[c][2]; e2_endo[y_dof] = Qendo[c+1][2]; e2_endo[z_dof] = Qendo[c+2][2]; + + + Qepi[c:c+3][0:3] = axisf(vec_dd4, vec_dd); + Qepi[c:c+3][0:3] = orto3(Qepi[c:c+3][0:3], cnt); + Qepi[c:c+3][0:3] = orient(Qepi[c:c+3][0:3], al_w[scl], b_w[scl]); + + e0_epi[x_dof] = Qepi[c][0]; e0_epi[y_dof] = Qepi[c+1][0]; e0_epi[z_dof] = Qepi[c+2][0]; + e1_epi[x_dof] = Qepi[c][1]; e1_epi[y_dof] = Qepi[c+1][1]; e1_epi[z_dof] = Qepi[c+2][1]; + e2_epi[x_dof] = Qepi[c][2]; e2_epi[y_dof] = Qepi[c+1][2]; e2_epi[z_dof] = Qepi[c+2][2]; + + Qfiber[c:c+3][0:3] = bislerp(Qendo[c:c+3][0:3], Qepi[c:c+3][0:3], epi[scl]) + e0_fiber[x_dof] = Qfiber[c][0]; e0_fiber[y_dof] = Qfiber[c+1][0]; e0_fiber[z_dof] = Qfiber[c+2][0]; + e1_fiber[x_dof] = Qfiber[c][1]; e1_fiber[y_dof] = Qfiber[c+1][1]; e1_fiber[z_dof] = Qfiber[c+2][1]; + e2_fiber[x_dof] = Qfiber[c][2]; e2_fiber[y_dof] = Qfiber[c+1][2]; e2_fiber[z_dof] = Qfiber[c+2][2]; + + + cnt = cnt + 1; + c = c + 3; + + if(isrotatept): + points = [(-Sdof_coordinates[scl][2]+maxz)/10.0, Sdof_coordinates[scl][1]/10.0, Sdof_coordinates[scl][0]/10.0] + fvectors = [-1.0*e0_fiber[z_dof], e0_fiber[y_dof], e0_fiber[x_dof]] + svectors = [-1.0*e2_fiber[z_dof], e2_fiber[y_dof], e2_fiber[x_dof]] + + else: + points = [Sdof_coordinates[scl][0], Sdof_coordinates[scl][1], Sdof_coordinates[scl][2]] + fvectors = [e0_fiber[x_dof], e0_fiber[y_dof], e0_fiber[z_dof]] + svectors = [e2_fiber[x_dof], e2_fiber[y_dof], e2_fiber[z_dof]] + + + #print >>mtvfiberfile, points[0], points[1], points[2], fvectors[0], fvectors[1], fvectors[2] + #print >>mtvsheetfile, points[0], points[1], points[2], svectors[0], svectors[1], svectors[2] + + + vtkoutfile = outdirectory+outfilename+"_e0_fiber" + func_of_e0_vector.set_local(e0_fiber) + func_of_e0_vector.apply("insert") + vtk_py.convertQuadDataToVTK(mesh, V, func_of_e0, vtkoutfile) + + vtkoutfile = outdirectory+outfilename+"_e1_fiber" + func_of_e1_vector.set_local(e1_fiber) + func_of_e1_vector.apply("insert") + vtk_py.convertQuadDataToVTK(mesh, V, func_of_e1, vtkoutfile) + + vtkoutfile = outdirectory+outfilename+"_e2_fiber" + func_of_e2_vector.set_local(e2_fiber) + func_of_e2_vector.apply("insert") + vtk_py.convertQuadDataToVTK(mesh, V, func_of_e2, vtkoutfile) + + if(MPI.rank(mpi_comm_world()) == 0): + print isrotatept + print outdirectory + outfilename + print "*******************************************************" + + if(isreturn): + + return func_of_e0, func_of_e1, func_of_e2 + +if (__name__ == "__main__"): + + parser = argparse.ArgumentParser() + parser.add_argument('--xml_folder', type=str, required=True) + parser.add_argument('--xml_meshfilename', type=str, required=True) + parser.add_argument('--xml_facetfilename', type=str, required=True) + parser.add_argument('--mtv_grid_directory', type=str, required=True) + parser.add_argument('--mtv_basename', type=str, required=True) + parser.add_argument('--isrotatept', type=bool, required=True) + parser.add_argument('--al_endo', type=float, required=True) + parser.add_argument('--al_epi', type=float, required=True) + parser.add_argument('--b_endo', type=float, required=True) + parser.add_argument('--b_epi', type=float, required=True) + args = parser.parse_args() + + print "************* Entering SetBiVFiber.py *****************" + + xmlmeshfilename = os.path.join(args.xml_folder, args.xml_meshfilename) + xmlfacetfilename = os.path.join(args.xml_folder, args.xml_facetfilename) + outdirectory = args.mtv_grid_directory + outfilename = args.mtv_basename + isrotatept = args.isrotatept + al_endo = args.al_endo + al_epi = args.al_epi + b_endo = args.b_endo + b_epi = args.b_epi + + mesh = Mesh(xmlmeshfilename) + boundaries = MeshFunction("size_t", mesh, xmlfacetfilename) + mtvfiberfilename = outdirectory+outfilename+"_fiber_rotated.axis" + mtvsheetfilename = outdirectory+outfilename+"_sheet_rotated.axis" + + SetBiVFiber(mesh, boundaries, mtvfiberfilename, mtvsheetfilename, al_endo, al_epi, b_endo, b_epi, isrotatept, outfilename, outdirectory) + diff --git a/vtk_py/SetBiVFiber_Quad_PyQ.py b/vtk_py/SetBiVFiber_Quad_PyQ.py new file mode 100644 index 0000000..6b8c1cd --- /dev/null +++ b/vtk_py/SetBiVFiber_Quad_PyQ.py @@ -0,0 +1,622 @@ +######################################################################## +import argparse +from mpi4py import MPI as pyMPI +import numpy as np +#from thLib import quat +import sys +import os +from dolfin import * +from sympy import Symbol, nsolve +import math +from scipy import linalg +from scipy import optimize + +import vtk_py as vtk_py + +import pyquaternion as pyq +import pdb + + +######################################################################## + + +#def SetBiVFiber_Quad(mesh, boundaries, mtvfiberfilename, mtvsheetfilename, al_endo, al_epi, b_endo, b_epi, isrotatept, isreturn, outfilename, param, outdirectory="./", epiid=2, rvid=1, lvid=3, degree=2): +def SetBiVFiber_Quad_PyQ(param): + ''' + What: This function uses pyquaternion lib instead of cgkit for quarternion calculations + What more: pip install (http://kieranwynn.github.io/pyquaternion/) + + Where: my_bislerp() instead of bislerp() in SetBiVFiber_Quad + + How: vtk_py.SetBiVFiber_J( ... ) + + Plaussible issues: matrix to quaternion is not unique, topology is trickier + http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/tim.htm + http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ + + What else: comment out all other problematic lines + for eg., Sdof_coordinates + + ''' + + pdb.set_trace() + + assert "mesh" in param, "No mesh is found" + assert "facetboundaries" in param, "No facetboundaries are found" + + mesh = param["mesh"] + boundaries = param["facetboundaries"] + matid = param["matid"] if ("matid" in param) else None + + epiid = param["epiid"] if ("epiid" in param) else 2 + lvid = param["lvid"] if ("lvid" in param) else 3 + rvid = param["rvid"] if ("rvid" in param) else 1 + outdirectory = param["outdirectory"] if ("outdirectory" in param) else "./" + isrotatept = param["isrotatept"] if ("isrotatept" in param) else False + isreturn = param["isreturn"] if ("isreturn" in param) else True + isLV = param["isLV"] if ("isLV" in param) else False + isscaling = param["isscaling"] if ("isscaling" in param) else False + outfilename = param["outfilename"] if ("outfilename" in param) else "fiber" + degree = param["degree"] if ("degree" in param) else 2 + mtvfiberfilename = param["mtvfiberfilename"] if ("mtvfiberfilename" in param) else None + mtvsheetfilename = param["mtvsheetfilename"] if ("mtvsheetfilename" in param) else None + + lvmatid = param["LV_matid"] if ("LV_matid" in param) else 0 + rvmatid = param["RV_matid"] if ("RV_matid" in param) else 0 + septummatid = param["Septum_matid"] if ("Septum_matid" in param) else 0 + + lv_fiber_angle = np.array(param["LV_fiber_angle"])*math.pi/180 if ("LV_fiber_angle" in param) else np.array([60, -60])*math.pi/180 + rv_fiber_angle = np.array(param["RV_fiber_angle"])*math.pi/180 if ("RV_fiber_angle" in param) else np.array([60, -60])*math.pi/180 + septum_fiber_angle = np.array(param["Septum_fiber_angle"])*math.pi/180 if ("Septum_fiber_angle" in param) else np.array([60, -60])*math.pi/180 + + lv_sheet_angle = np.array(param["LV_sheet_angle"])*math.pi/180 if ("LV_sheet_angle" in param) else np.array([0.1, -0.1])*math.pi/180 + rv_sheet_angle = np.array(param["RV_sheet_angle"])*math.pi/180 if ("RV_sheet_angle" in param) else np.array([0.1, -0.1])*math.pi/180 + septum_sheet_angle = np.array(param["Septum_sheet_angle"])*math.pi/180 if ("Septum_sheet_angle" in param) else np.array([0.1, -0.1])*math.pi/180 + + + # Set Fiber angle + #al_endo = al_endo*math.pi/180; b_endo = b_endo*math.pi/180; + #al_epi = al_epi*math.pi/180; b_epi = b_epi*math.pi/180; + + comm = mesh.mpi_comm().tompi4py() + + minz = comm.allreduce(np.amin(mesh.coordinates()[:,2]), op=pyMPI.MIN) + maxz = comm.allreduce(np.amax(mesh.coordinates()[:,2]), op=pyMPI.MAX) + + + # Boundary condition for Laplace equation from the bottom to the top + + def right_boundary(x): + return x[2] < minz+1.0 + + # Function that solves the Laplace equation and and calculates the gradient of the solution + def lap(Me, boud, par,op, filename): + + set_log_level(40) + parameters["form_compiler"]["quadrature_degree"] = degree + parameters["form_compiler"]["representation"] = 'quadrature' + + epi=epiid; rv=rvid; lv=lvid; + # Create mesh and define function space + mesh = Me + V = FunctionSpace(mesh, FiniteElement("Lagrange", mesh.ufl_cell(), 2)) + SQuad = FunctionSpace(mesh, FiniteElement("Quadrature", mesh.ufl_cell(), degree=degree, quad_scheme="default")) + + y = mesh.coordinates() + sa = y.shape + ttt = y[:, 2].min() + cord = np.argwhere(y == ttt); + point = y[cord[0,0],:] + #print sa, cord, point + u0 = Constant(0.0) + if op == 1: + bc =[ DirichletBC(V, u0, right_boundary), DirichletBC(V, 1, boud, 4)] + # Define boundary conditions + else: + bc = [DirichletBC(V, par[0], boud, lv), DirichletBC(V, par[1], boud, epi ), DirichletBC(V, par[2], boud, rv)] + + # Define variational problem + u = TrialFunction(V) + v = TestFunction(V) + f = Constant(0) + a = inner(nabla_grad(u), nabla_grad(v))*dx + L = f*v*dx + + # Compute solution + u = Function(V) + solve(a == L, u, bc)#, solver_parameters={"linear_solver": "petsc"}) + u_a = u.vector().array() + u_a_quad = project(u, SQuad).vector().get_local()#, solver_type="petsc").vector().array() + + + # Compute gradient + V_g = FunctionSpace(mesh, VectorElement("Lagrange", mesh.ufl_cell(), 2)) + VQuad = FunctionSpace(mesh, VectorElement("Quadrature", mesh.ufl_cell(), degree=degree, quad_scheme="default")) + v = TestFunction(V_g) + w = TrialFunction(V_g) + + a = inner(w, v)*dx + L = inner(grad(u), v)*dx + grad_u = Function(V_g) + solve(a == L, grad_u)#, solver_parameters={"linear_solver": "petsc"}) + grad_u_quad = project(grad_u, VQuad)#, solver_type="petsc") + grad_u.rename('grad_u', 'continuous gradient field') + grad_ua_quad = grad_u_quad.vector().get_local()#.array() + + + #plot(u, interactive=True) + + # Dump solution to file in VTK format + #newfilename = filename + '.pvd' + #file1= File(newfilename) + #file1<< u + + #newfilename = filename + 'grad.pvd' + #file2 = File(newfilename) + #file2 << grad_u + + # Hold plot + #interactive() + return u_a_quad, grad_ua_quad + + # Function to calculate the lenght of the vector + + def len_vec(vec): + l = (vec[0]**2 + vec[1]**2 + vec[2]**2)**0.5 + return l + + + + ################################################################################################## + # Function to calculate the orthogonal axis using the gradients calculated in the previous step + ################################################################################################### + def L1(e0, v0): + + L1x = (v0[0] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[0])**2 + L1y = (v0[1] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[1])**2 + L1z = (v0[2] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[2])**2 + + return (L1x + L1y + L1z)**0.5; + + def P(e0, v0): + + P1x = v0[0] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[0] + P1y = v0[1] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[1] + P1z = v0[2] - (e0[0]*v0[0] + e0[1]*v0[1] + e0[2]*v0[2])*e0[2] + + return [P1x, P1y, P1z]; + + def function_e0(e0, v0, e1): + + f = [L1(e0,v0)*e0[0] - (e1[1]*P(e0,v0)[2] - e1[2]*P(e0,v0)[1]), + L1(e0,v0)*e0[1] - (e1[2]*P(e0,v0)[0] - e1[0]*P(e0,v0)[2]), + L1(e0,v0)*e0[2] - (e1[0]*P(e0,v0)[1] - e1[1]*P(e0,v0)[0])] + + return f; + + + def axisf(vec1, vec2): + + len_vec2 = len_vec(vec2); len_vec1 = len_vec(vec1); + e1 = vec1/len_vec1; ini_e2 = vec2/len_vec2; + ini_e0 = np.cross(e1, ini_e2) + + + e0 = np.zeros(3); e2 = np.zeros(3); + + # Solve using numerical + def function_wrap(e0): + return function_e0(e0, vec2, e1) + + sol = optimize.root(function_wrap, [ini_e0[0], ini_e0[1], ini_e0[2]], method='hybr') + e0[0] = sol.x[0]; e0[1] = sol.x[1]; e0[2] = sol.x[2]; + e2 = P(e0, vec2); + len_e2 = len_vec(e2) + e2[0] = e2[0]/len_e2; e2[1] = e2[1]/len_e2; e2[2] = e2[2]/len_e2; + + Q = np.array([[e0[0], e1[0], e2[0] ],[ e0[1], e1[1], e2[1]],[ e0[2], e1[2], e2[2]]]) + + + return Q + + + ################################################################################################# + #Function to ensure the that the axis are orthogonal + ################################################################################################# + def orto(Q, cnt): + e0 = np.zeros(3); e1 = np.zeros(3); e2 = np.zeros(3); + e0[0] = Q[0][0]; e0[1] = Q[1][0]; e0[2] = Q[2][0]; + e1[0] = Q[0][1]; e1[1] = Q[1][1]; e1[2] = Q[2][1]; + e2[0] = Q[0][2]; e2[1] = Q[1][2]; e2[2] = Q[2][2]; + e0x = Symbol('e0x'); e0y = Symbol('e0y') ; e0z = Symbol('e0z'); e2x = Symbol('e2x'); e2y = Symbol('e2y') ; e2z = Symbol('e2z'); + + + try: + + aa = nsolve( [ e0x - e1[1]*e2z + e1[2]*e2y, e0y - e1[2]*e2x + e1[0]*e2z, e0z - e1[0]*e2y + e1[1]*e2x, e1[0] - e2y*e0z + e2z*e0y, e1[1] - e2z*e0x + e2x*e0z, e1[2] - e2x*e0y + e2y*e0x ], [ e0x, e0y, e0z, e2x, e2y, e2z ],[e0[0], e0[1], e0[2], e2[0], e2[1],e2[2] ]) + + + + e0[0] = aa[0]; e0[1] = aa[1]; e0[2] = aa[2]; + e2[0] = aa[3]; e2[1] = aa[4]; e2[2] = aa[5]; + Qa = np.array([[e0[0], e1[0], e2[0] ],[ e0[1], e1[1], e2[1]],[ e0[2], e1[2], e2[2]]]) + + except ZeroDivisionError as detail: + print 'Handling run-time error:', detail + Qa = Q + f = quat.rotmat2quat(Qa) + outfile = open("quat.txt", "w") + print >>outfile, cnt, " ", f + return Qa + + + def orto3(Q, cnt): + + Q2 = np.dot(np.transpose(Q),Q) + Q2inv = np.linalg.inv(Q2) + sqrtQ2 = linalg.sqrtm(Q2inv) + Qa = np.dot(Q,sqrtQ2) + + return Qa + + ################################################################################################# + #Function to ensure the that the axis are orthogonal but this one is not working prorperly + ################################################################################################# + + def orto2(Q): + e0 = np.zeros(3); e1 = np.zeros(3); e2 = np.zeros(3); + e0[0] = Q[0][0]; e0[1] = Q[1][0]; e0[2] = Q[2][0]; + e1[0] = Q[0][1]; e1[1] = Q[1][1]; e1[2] = Q[2][1]; + e2[0] = Q[0][2]; e2[1] = Q[1][2]; e2[2] = Q[2][2]; + + while np.dot(e0, e1) + np.dot(e0, e2) + np.dot(e1, e2) > 10e-30: + e2 = np.cross(e0, e1); + e0 = np.cross(e1, e2); + Qa = np.array([[e0[0], e1[0], e2[0] ],[ e0[1], e1[1], e2[1]],[ e0[2], e1[2], e2[2]]]) + return Qa + + ############################################################################################## + #Function 3 - This function rotates the axis calculated in the previous steps + ############################################################################################## + + def orient(Q, al, bt): + arr1 =np.array( [[np.cos(al), -np.sin(al), 0 ],[np.sin(al), np.cos(al), 0],[0, 0, 1]]); + arr2 = np.array([[1, 0, 0],[0, np.cos(bt), np.sin(bt) ],[0, -np.sin(bt), np.cos(bt) ]]); + out = np.dot(Q, arr1, arr2) + return out + + ################################################################################################## + #Function 4 - This function calculates quarternions and interpolates these quarternions + ################################################################################################# + + def bislerp(Qa, Qb, t): + + Qa_M = mat3([Qa[0,0], Qa[0,1], Qa[0,2], Qa[1,0], Qa[1,1], Qa[1,2], Qa[2,0], Qa[2,1], Qa[2,2]]) + Qb_M = mat3([Qb[0,0], Qb[0,1], Qb[0,2], Qb[1,0], Qb[1,1], Qb[1,2], Qb[2,0], Qb[2,1], Qb[2,2]]) + qa = quat(Qa_M) + qb = quat(Qb_M) + + val = np.zeros(8) + quat_i = quat(0,1,0,0) + quat_j = quat(0,0,1,0) + quat_k = quat(0,0,0,1) + quat_array = [qa, -qa, qa*quat_i, -qa*quat_i, qa*quat_j, -qa*quat_j, qa*quat_k, -qa*quat_k] + cnt = 0 + for qt in quat_array: + val[cnt] = qt.dot(qb) + cnt = cnt + 1 + + qt = quat_array[val.argmax(axis=0)] + + if(t < 0): + t = 0.0 + + + qm = slerp(t, qt, qb) + qm = qm.normalize() + Qm_M = qm.toMat3() + Qm = [[Qm_M[0,0], Qm_M[0,1], Qm_M[0,2]], [Qm_M[1,0], Qm_M[1,1], Qm_M[1,2]], [Qm_M[2,0], Qm_M[2,1], Qm_M[2,2]]] + + return Qm + + def my_bislerp(Qa, Qb, t): + + qa = pyq.Quaternion(matrix=Qa) + qb = pyq.Quaternion(matrix=Qb) + + + val = np.zeros(8) + + quat_i = pyq.Quaternion(0,1,0,0) + quat_j = pyq.Quaternion(0,0,1,0) + quat_k = pyq.Quaternion(0,0,0,1) + + quat_array = [qa, -qa, qa*quat_i, -qa*quat_i, qa*quat_j, -qa*quat_j, qa*quat_k, -qa*quat_k] + + cnt = 0 + qb_arr = np.array([qb[0], qb[1], qb[2], qb[3]]) + + for qt in quat_array: + #val[cnt] = qt.dot(qb) + qt_arr = np.array([qt[0], qt[1], qt[2], qt[3]]) + val[cnt] = np.dot(qt_arr, qb_arr) + cnt = cnt + 1 + + qt = quat_array[val.argmax(axis=0)] + + if(t < 0): + t = 0.0 + + #qm = slerp(t, qt, qb) + qm = pyq.Quaternion.slerp(qt, qb, t) + qm = qm.normalised + Qm_M = qm.rotation_matrix + + return Qm_M + + + + ################################################################################################# + ######Generating results and using the functions ########## + ################################################################################################# + # DOF map + parameters["form_compiler"]["quadrature_degree"] = degree + parameters["form_compiler"]["representation"] = 'quadrature' + + V = FunctionSpace(mesh, VectorElement("Quadrature", mesh.ufl_cell(), degree=degree, quad_scheme="default")) + S = FunctionSpace(mesh, FiniteElement("Quadrature", mesh.ufl_cell(), degree=degree, quad_scheme="default")) + + dof_coordinates = V.tabulate_dof_coordinates() + Sdof_coordinates = S.tabulate_dof_coordinates() + n = V.dim() + d = mesh.geometry().dim() + dof_coordinates.resize((n, d)) + Sdof_coordinates.resize((n,d)) + + x_my_first, x_my_last = V.sub(0).dofmap().ownership_range() + x_dofs = np.arange(0, x_my_last-x_my_first, d) + y_dofs = np.arange(1, x_my_last-x_my_first, d) + z_dofs = np.arange(2, x_my_last-x_my_first, d) + + + jj = np.array([ 1, 1, 1] ); hh = np.array([1, 1, 1]); + + + ####### Solving the poisson equation ############ + + # case 1) epi -> u = 0 and rv/lv -> u = 1 + + if(MPI.rank(mpi_comm_world()) == 0): + print "Solve Poisson Eq. 1, epi -> u = 0 and rv/lv -> u = 1" + par1 = [0, 1, 0]; epi, dd = lap(mesh, boundaries, par1, 0, 'phi_epi') + + #total_dd = comm.allreduce(len(dd), op=pyMPI.SUM) + #num_of_nodes = total_dd/3 + #scalar_array = np.zeros(num_of_nodes) + #scalar_dof = S.dofmap().dofs() + + total_dd = len(dd) + S_my_first, S_my_last = S.dofmap().ownership_range() + scalar_dof = filter(lambda dof: S.dofmap().local_to_global_index(dof) not in S.dofmap().local_to_global_unowned(), + xrange(S_my_last-S_my_first)) + + + # case 2) lv -> u = 0 and rv/epi -> u = 1 + + if(MPI.rank(mpi_comm_world()) == 0): + print "Solve Poisson Eq. 2, lv -> u = 0 and rv/epi -> u = 1" + par2 = [1, 0, 0]; lv, dd2 = lap(mesh, boundaries, par2, 0, 'phi_lv'); #dd2 = -1*dd2 + + # case 3) rv -> u = 0 and epi/lv -> u = 1 + + if(MPI.rank(mpi_comm_world()) == 0): + print "Solve Poisson Eq. 3, rv -> u = 0 and epi/lv -> u = 1" + par3 = [0, 0, 1]; rv, dd3 = lap(mesh, boundaries, par3, 0, 'phi_rv') + + #case 4) from the top to the bottom + + if(MPI.rank(mpi_comm_world()) == 0): + print "Solve Poisson Eq. 4, from the top to the bottom" + par1 = [0, 1, 0]; b, dd4 = lap(mesh, boundaries, par1, 1, 'phi_ab') + + + + # Start calculating the fiber orientation + cnt = 0; c = 0; + vector_array = np.zeros(V.dim()) + + func_of_vector = Function(V); + func_of_scalar = Function(S); + + func_of_e0 = Function(V); + func_of_e1 = Function(V); + func_of_e2 = Function(V); + + func_of_e0_vector = func_of_e0.vector() + func_of_e1_vector = func_of_e1.vector() + func_of_e2_vector = func_of_e2.vector() + + e0_fiber = func_of_e0_vector.get_local() + e1_fiber = func_of_e1_vector.get_local() + e2_fiber = func_of_e2_vector.get_local() + + vec_dd = np.zeros(3); vec_dd2 = np.zeros(3); vec_dd3 = np.zeros(3); vec_dd4 = np.zeros(3); + + Qepi = np.zeros((total_dd,3)); Qrv = np.zeros((total_dd,3)); Qlv = np.zeros((total_dd,3)); + Qendo = np.zeros((total_dd,3)) + Qfiber = np.zeros((total_dd,3)) + + e0_epi = np.zeros(total_dd); e1_epi = np.zeros(total_dd); e2_epi = np.zeros(total_dd); + e0_rv = np.zeros(total_dd); e1_rv = np.zeros(total_dd); e2_rv = np.zeros(total_dd); + e0_lv = np.zeros(total_dd); e1_lv = np.zeros(total_dd); e2_lv = np.zeros(total_dd); + check = np.zeros(total_dd); check2 = np.zeros(total_dd); + ds = np.zeros(total_dd/3); al_s = np.zeros(total_dd/3); b_s = np.zeros(total_dd/3); + al_w = np.zeros(total_dd/3); b_w = np.zeros(total_dd/3); + + e0_endo = np.zeros(total_dd); e1_endo = np.zeros(total_dd); e2_endo = np.zeros(total_dd); + + + # Open MTV fiber and sheet files + if( MPI.rank(mpi_comm_world()) == 0): + + if(mtvfiberfilename): + mtvfiberfile = open(mtvfiberfilename, 'w') + print >>mtvfiberfile, total_dd/3, 10 + + + if(mtvsheetfilename): + mtvsheetfile = open(mtvsheetfilename, 'w') + print >>mtvsheetfile, total_dd/3 + + + for x_dof, y_dof, z_dof, scl in zip(x_dofs, y_dofs, z_dofs, scalar_dof): + + + if(abs(rv[scl]) < 1e-9 and abs(rv[scl] + lv[scl]) < 1e-9): + ds[scl] = 0.0 + else: + ds[scl] = rv[scl]/(lv[scl]+rv[scl]) + + + pt = Point(np.array([Sdof_coordinates[scl][0], Sdof_coordinates[scl][1], Sdof_coordinates[scl][2]])) + meshid = mesh.bounding_box_tree().compute_first_collision(pt) + + al_endo = lv_fiber_angle[0]; b_endo = lv_sheet_angle[0]; + al_epi = lv_fiber_angle[1]; b_epi = lv_sheet_angle[1]; + + if matid is not None: + if(matid.array()[meshid] == septummatid): + al_endo = septum_fiber_angle[0]; b_endo = septum_sheet_angle[0]; + al_epi = septum_fiber_angle[1]; b_epi = septum_sheet_angle[1]; + elif(matid.array()[meshid] == rvmatid): + al_endo = rv_fiber_angle[0]; b_endo = rv_sheet_angle[0]; + al_epi = rv_fiber_angle[1]; b_epi = rv_sheet_angle[1]; + + + al_s[scl] = al_endo*(1 - ds[scl]) - al_endo*ds[scl]; b_s[scl] = b_endo*(1 - ds[scl]) - b_endo*ds[scl]; + al_w[scl] = al_endo*(1 - epi[scl]) + al_epi*epi[scl]; b_w[scl] = b_endo*(1 - epi[scl]) + b_epi*epi[scl]; + + vec_dd[0] = dd[x_dof]; vec_dd[1] = dd[y_dof]; vec_dd[2] = dd[z_dof]; + vec_dd2[0] = dd2[x_dof]; vec_dd2[1] = dd2[y_dof]; vec_dd2[2] = dd2[z_dof]; + vec_dd3[0] = dd3[x_dof]; vec_dd3[1] = dd3[y_dof]; vec_dd3[2] = dd3[z_dof]; + vec_dd4[0] = dd4[x_dof]; vec_dd4[1] = dd4[y_dof]; vec_dd4[2] = dd4[z_dof]; + + + Qlv[c:c+3][0:3]= axisf(vec_dd4, -1.0*vec_dd2); + Qlv[c:c+3][0:3] = orto3(Qlv[c:c+3][0:3], cnt); + Qlv[c:c+3][0:3]= orient(Qlv[c:c+3][0:3], al_s[scl], b_s[scl]) + + + e0_lv[x_dof] = Qlv[c][0]; e0_lv[y_dof] = Qlv[c+1][0]; e0_lv[z_dof] = Qlv[c+2][0]; + e1_lv[x_dof] = Qlv[c][1]; e1_lv[y_dof] = Qlv[c+1][1]; e1_lv[z_dof] = Qlv[c+2][1]; + e2_lv[x_dof] = Qlv[c][2]; e2_lv[y_dof] = Qlv[c+1][2]; e2_lv[z_dof] = Qlv[c+2][2]; + + Qrv[c:c+3][0:3] = axisf(vec_dd4, -1.0*vec_dd3); + Qrv[c:c+3][0:3] = orto3(Qrv[c:c+3][0:3], cnt); + Qrv[c:c+3][0:3]= orient(Qrv[c:c+3][0:3], -al_s[scl], -b_s[scl]); + + e0_rv[x_dof] = Qrv[c][0]; e0_rv[y_dof] = Qrv[c+1][0]; e0_rv[z_dof] = Qrv[c+2][0]; + e1_rv[x_dof] = Qrv[c][1]; e1_rv[y_dof] = Qrv[c+1][1]; e1_rv[z_dof] = Qrv[c+2][1]; + e2_rv[x_dof] = Qrv[c][2]; e2_rv[y_dof] = Qrv[c+1][2]; e2_rv[z_dof] = Qrv[c+2][2]; + + + #Qendo[c:c+3][0:3] = bislerp(Qlv[c:c+3][0:3], Qrv[c:c+3][0:3], ds[scl]) + Qendo[c:c+3][0:3] = my_bislerp(Qlv[c:c+3][0:3], Qrv[c:c+3][0:3], ds[scl]) + + e0_endo[x_dof] = Qendo[c][0]; e0_endo[y_dof] = Qendo[c+1][0]; e0_endo[z_dof] = Qendo[c+2][0]; + e1_endo[x_dof] = Qendo[c][1]; e1_endo[y_dof] = Qendo[c+1][1]; e1_endo[z_dof] = Qendo[c+2][1]; + e2_endo[x_dof] = Qendo[c][2]; e2_endo[y_dof] = Qendo[c+1][2]; e2_endo[z_dof] = Qendo[c+2][2]; + + + Qepi[c:c+3][0:3] = axisf(vec_dd4, vec_dd); + Qepi[c:c+3][0:3] = orto3(Qepi[c:c+3][0:3], cnt); + Qepi[c:c+3][0:3] = orient(Qepi[c:c+3][0:3], al_w[scl], b_w[scl]); + + e0_epi[x_dof] = Qepi[c][0]; e0_epi[y_dof] = Qepi[c+1][0]; e0_epi[z_dof] = Qepi[c+2][0]; + e1_epi[x_dof] = Qepi[c][1]; e1_epi[y_dof] = Qepi[c+1][1]; e1_epi[z_dof] = Qepi[c+2][1]; + e2_epi[x_dof] = Qepi[c][2]; e2_epi[y_dof] = Qepi[c+1][2]; e2_epi[z_dof] = Qepi[c+2][2]; + + #Qfiber[c:c+3][0:3] = bislerp(Qendo[c:c+3][0:3], Qepi[c:c+3][0:3], epi[scl]) + Qfiber[c:c+3][0:3] = my_bislerp(Qendo[c:c+3][0:3], Qepi[c:c+3][0:3], epi[scl]) + + e0_fiber[x_dof] = Qfiber[c][0]; e0_fiber[y_dof] = Qfiber[c+1][0]; e0_fiber[z_dof] = Qfiber[c+2][0]; + e1_fiber[x_dof] = Qfiber[c][1]; e1_fiber[y_dof] = Qfiber[c+1][1]; e1_fiber[z_dof] = Qfiber[c+2][1]; + e2_fiber[x_dof] = Qfiber[c][2]; e2_fiber[y_dof] = Qfiber[c+1][2]; e2_fiber[z_dof] = Qfiber[c+2][2]; + + + cnt = cnt + 1; + c = c + 3; + + if(isrotatept): + points = [(-Sdof_coordinates[scl][2]+maxz)/10.0, Sdof_coordinates[scl][1]/10.0, Sdof_coordinates[scl][0]/10.0] + fvectors = [-1.0*e0_fiber[z_dof], e0_fiber[y_dof], e0_fiber[x_dof]] + svectors = [-1.0*e2_fiber[z_dof], e2_fiber[y_dof], e2_fiber[x_dof]] + + else: + points = [Sdof_coordinates[scl][0], Sdof_coordinates[scl][1], Sdof_coordinates[scl][2]] + fvectors = [e0_fiber[x_dof], e0_fiber[y_dof], e0_fiber[z_dof]] + svectors = [e2_fiber[x_dof], e2_fiber[y_dof], e2_fiber[z_dof]] + + + #print >>mtvfiberfile, points[0], points[1], points[2], fvectors[0], fvectors[1], fvectors[2] + #print >>mtvsheetfile, points[0], points[1], points[2], svectors[0], svectors[1], svectors[2] + + + vtkoutfile = outdirectory+outfilename+"_e0_fiber" + func_of_e0_vector.set_local(e0_fiber) + func_of_e0_vector.apply("insert") + vtk_py.convertQuadDataToVTK(mesh, V, func_of_e0, vtkoutfile) + + vtkoutfile = outdirectory+outfilename+"_e1_fiber" + func_of_e1_vector.set_local(e1_fiber) + func_of_e1_vector.apply("insert") + vtk_py.convertQuadDataToVTK(mesh, V, func_of_e1, vtkoutfile) + + vtkoutfile = outdirectory+outfilename+"_e2_fiber" + func_of_e2_vector.set_local(e2_fiber) + func_of_e2_vector.apply("insert") + vtk_py.convertQuadDataToVTK(mesh, V, func_of_e2, vtkoutfile) + + if(MPI.rank(mpi_comm_world()) == 0): + print isrotatept + print outdirectory + outfilename + print "*******************************************************" + + if(isreturn): + + return func_of_e0, func_of_e1, func_of_e2 + +if (__name__ == "__main__"): + + parser = argparse.ArgumentParser() + parser.add_argument('--xml_folder', type=str, required=True) + parser.add_argument('--xml_meshfilename', type=str, required=True) + parser.add_argument('--xml_facetfilename', type=str, required=True) + parser.add_argument('--mtv_grid_directory', type=str, required=True) + parser.add_argument('--mtv_basename', type=str, required=True) + parser.add_argument('--isrotatept', type=bool, required=True) + parser.add_argument('--al_endo', type=float, required=True) + parser.add_argument('--al_epi', type=float, required=True) + parser.add_argument('--b_endo', type=float, required=True) + parser.add_argument('--b_epi', type=float, required=True) + args = parser.parse_args() + + print "************* Entering SetBiVFiber.py *****************" + + xmlmeshfilename = os.path.join(args.xml_folder, args.xml_meshfilename) + xmlfacetfilename = os.path.join(args.xml_folder, args.xml_facetfilename) + outdirectory = args.mtv_grid_directory + outfilename = args.mtv_basename + isrotatept = args.isrotatept + al_endo = args.al_endo + al_epi = args.al_epi + b_endo = args.b_endo + b_epi = args.b_epi + + mesh = Mesh(xmlmeshfilename) + boundaries = MeshFunction("size_t", mesh, xmlfacetfilename) + mtvfiberfilename = outdirectory+outfilename+"_fiber_rotated.axis" + mtvsheetfilename = outdirectory+outfilename+"_sheet_rotated.axis" + + SetBiVFiber(mesh, boundaries, mtvfiberfilename, mtvsheetfilename, al_endo, al_epi, b_endo, b_epi, isrotatept, outfilename, outdirectory) + diff --git a/vtk_py/SetBiVFiber_Quad_PyQ.pyc b/vtk_py/SetBiVFiber_Quad_PyQ.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f6a2b9502bc78d425c129cdd4b3e6eec3c6594e GIT binary patch literal 20861 zcmds9YiwM{b)LJ+*Dfhi;zJ}QSz5`my?XE|#ZDB(mTcLQWr-0l70F@Zte1N)$xH2v z_ui#QVYg`GB(hPY4UhzAoBSz|rbQpCp`=tk#)eUB;_d{n{EqYBV{ zv~hTE;|HYR$ld}B5;Zy$V8opZMmrWfAzV1BoH2Fvn%k>3j;W1|a*wKw;}V`wZ((kq zR2_;=O3_n-_Ox1lMiN=Id`c3h)$(acoKeeXBymGu1jE(x zta9g+b5OZRJf+@Bs^xj*g6t_Z?u@JP<#Wy41ajw<`yN3B5=xLoGiU&$K@@GHAJ3?_ zAW~%!*`@3xWZ3%={w-uJB*P?vo3~!o8A48HA>b`2Emvc)sOXjR z#WkJpL%vcCy^{C9EeKHnQurh7;A3N;22r!fWDCotuGGCA6`W9ELOBTz`s0>zk`erZ zz`G0_$fz>ekZM4hY@kxN!Sx*`kew_imGiV}Anb|CepbqQbXl)@r;C!W+xEXGWqrCV zrQX4cOh;v3m$I}j>sRljl`{~P{jHP@=(2sP0h)tR+4rSvP|CtC)xhc>ipmBo_H#&= zb*l!n!TzW$D`oqe_0X3CQP~wKJJ2laQ_gTy_NJ5#OPMpG8d$rdQCVHeMs*p+4!(>< zWxph4W4a7H!}tzHWnY!DgUzyj1(`EE`;L^2>#_;efJ&H*%KlBtCYxo@3WuVyz68g9 zs96TZa5yS^Zvw)#(aS7=lMsclPi>^ssB=V(m7ky#qSSdpIY-r+h)S%y0Zno&qV(|? zrDH!aC8(ZEMCscxN|~RS5_Hw^h|D7TXlr8i@gPX5G{pbejj zDE(%P(o;V%B?y?MHquAiqmDsEXX$R5&rP?s7H4dtWeQFijBC9^7)H^BlFsUAPsfWGlA<}8JibZ#dMU8Rg zoTklt2TSdYB+#j|lCac6r5;-Bmop`Fx|w~5ut%+8sZ0w6n8O+3H((BDC2>eObCQ6K znwJDj&pAmzLeER$sCql8LU8;&YSMXDU38vn=H9C=hQh!QM)-X)XfeN7wy5J=P|o{d zOcF3PjbqASVi-Rb^PPmM!&ptoTx8VSi6{*r1bkB9C!{UdbIh8CJgMp#wSi@bq9@4+ ztURlJd@l$zFh-Ea42hN8I7%`fMITS9##1uw$B0megq>6qpazrGcseTR-&Ft^z>-D{ ztogPYSt-C;hsu%PwImyDoO%TOvVXf=+=Zi&P5n;T02Z2C`~9(YMfDZ zC^8rk@av2eeL%g{E#o+=8dE9+N2a8~X<_27vCgQ*tO`%6hY69s=P4i|`ai4cGim~@ zbJFG>(WTyA=LORx>5u8se5_0J(xppLm(Hoi`9~1D-RoR#jZcQi@x3QT>^(y4#faFm zssS17$gE%ObzW)_dla((zY-C9uWG!HMup@29K6a zUu)04+Md1Mo_)<^>(g|I_2OvU=mfmk3AoS+_`y!VTP+|vx!9hy+p|mU+1u^e54C6S zv}fJz zwDLcl4o@p2oR?)e!Z&nOm!8D2#H(G-D=P8obtr~9~z2qDyy_L88~(FhjaBy_bT`&-FgHK}zb`M4n} zf0}D#V@B0CWEI>~b+}BZ-6*O$+zX~k0t1;wSzt_6R2}x{X>~89{L2GK!v_PQ`aLu@ zC|dRh{dG7xh7$Hvh7w?g5@4Fr=57M}gaDxMxeNhVOG5xKLjbTQ0nS;GdCic?iBV)t zdUT@xhOn_-YRAC9guj!(_?X7fG%#6UB4}X1Iz2jG&&6ppF~Eo>#+w>rO4V1vhHLEd zMVO5Gn$Gp>+`7*7B6nV6zN#^iBPMdhM2?uq5%W2Xd0k^7M@;01i5xMJBPM(Sw*H#N zM2?uq5feFLB1cSEWTakIXk!${slK4<@8>Vp@c41`9r2kueDn_RyGsX09f7oc-(X-y08T@K}-j*5W9j z9F>MPISMF8B~Z=L5ACT<-T}I+wt>cKlS_B@)HcvvwGEWDq4qioUx#5HH%pmZ_+Tf- z3s7?*uX`ep78d|zPc*d21wh#oQ=21O*;Cs^-%~H9&XOHqcmY@@HvJZ3Ep^+dx?x5+zgFuI7$+=HFQ{1C*#+o!Blw%?0?F)Kmg# zaRE^FL_?cg0F*s3wK+0)rMqey=&srZ8mrBbUENdLKzG$PP}YWL4s{9#-LL^pdc9lu zKOBjC2H^JB58^oSx*CgMXg!{VIcAnSi>g==8Q0`!T}D002zH3Yn^KH!!uE`^yK7Oe zrPx=S-%dx3fNGTFXpIYl?&x+5)mR&#soT(e5Ox^)rby`Dt#_$9?3(i$#vRD+U{-+) z93hKag*oNikW4tQHsFg{+?`;bQ4i?QSyAnqx;FL`sQrqrjZEj-mv+})(6zAxLG7!$ zHZq-SUyf>b-j`h+!;D?MW;%BDn)5-uORM)Ne|d~ONAs6?RewoRw* zuIIxGncM4LkXfyj3!zsjXKH~PWU4!xwS4IMWkQPHO2#V(p__LymDNmP?VcBARx5r6 zIDUjw$QKK>VxA-dO*m7k`0j;F)vHSFe6g6xu7_du!pzJ)&-L@=`#a_G^qLp0*H)&z z%1pe?nNyi`I%EFbU3W>Sw3A!$f}-nJv!~+yi32lBZup{i=M`_o^>d50ypv9+u2t?| z$ZUo8a@C#bc=7dYW_o%$b1I!mr*0MVwIJ|Tif+aWf|?s#$Ye_S(D$}8VTI$2h6zrU zD`BQq_BLzoSrk?)#md?aYGr_3;K0(UREj+}W4(X>{w6g|hymxF4);7%7Rr5R9P z4`$ZfO34lVof*FpYTnHhD&;NL56DL%p$oSw7>Vh?3=Ynx*TYig|F#uyUxXv$76Y&z z9WJ@$FjJ|88O~!R#FS*JegzCeAH4!(qzth^r!a7ehPyU>HnZeZR&#|)#dmQ2A4+*T zh0|`ON^Y_=jul3|+sTdmZ}4i5d4S_PBB6=w6k=LW$MjkpV($@{LU)J>A;hZ8d8 zRz1)0FvIowjXCGaMu0S4

fjXOCRk%u(Txs|dFBxJ{z(6w4gqlAM10ADEQ^5wOn>wOg`InF=M!wCKYHqV26T-Usf zD51u&5njr&d_m@J4JrKl{tH<~`tFDnwslgZ$SXgP(%?B1%&cQA%@hko*PXH5z|H%G z^_gog-JH>DedQqZuK^{|2;g_YV>lzjXvI3)e&OX+{45MZm&QO zyJj3>0xcCoz{z(LA*IMDoLJy2T_61777C@^tlq$Ww_k1a@TLU`2bd~$qOSMkjeX|E z1Q>PMT66b5$O_o1Vw~Vo6N)P^LNSOq6lR{#9w7zC;edkFqeb>)ScUtd z^oaCuK;WYaQwjZn!wR4=F~S5`ilsNoyN6MNMkRMpg}6y*62v_j$`A6i0o8F_fk9bF zZGZ$0MMj0i;|gc-EXI`vj?Q(F9LhH)qB+A6e8)+hj3NB^Nj)UP!^t~_is50{I(?YK ztK$?N?KX$R5o1#zBaRj5(dl|e6xL>IbVpd*;y|!D$0Zs*gol z)@Dx>+>QJiyn;1Xt8UieGS!r9whF1ybaFvq-G!d*Mc#2&^R;3qdeZ0&Xgz8Qk2*p$ zFz7nDTEN?EnAgxN*DAFjL#Riyw(7Y>M=r93iUiq1tjqxhZkU6O&lTM*wi#ex;bt zarn}hvn}-7kmUkjc(*0iQTmzp{rrwF9j1Q+a4~~x!XH>d>Bt>HkA}_}kalPXeKC$% zYEx&rr!n}kxgiI}$*OQpb=P1SkypvlKl6RU--?z`O zSDYR#a2lEBTIY4`EGI+c*``skIV1K72CT_-r5?+kkzvJr^$pTlAhkr=8ngxzJqkaG z9_zSuIx%3StRvQ#bqJ{e>vZy3lJS6b%o;@MpfzkA?gAcRi4kiO@rX5K?YD;a7szxP zbvCnvzhD}HvE;CWBTVAu1(V}U(=;*-+c?sIPPd>!$bkjD)<{ZLt697MXzV@V!e`1K z+bjxa9-lqb8F15bp!+2x1ImZOPz!949pj%2?0ZO{yL3^^_)KopjEh+e4=2KU%*4T?ehDX5UVrh>BvP5!5#!cJ)_*!!Y8Ni~k`qD)EKWQf)zA9hU!St85D z)vIP}R;K30+_s5#Osw6p$Dbtj;l|wWAPo8tsKhH4eiD1<=xc5MwDzsWdC3IVpMpa4zgs2Am|}`z1qzoN5O9d@WP)i-1k)H7W+bV`-T?-tC!xk5g!<_n z=Kz}$xQ5*V5jL|@PkR;*Y4A2CDbHiDn@Pw^7}?oiPlK%qyn4BmCm{4B`v zLxGElf0P)R9d7=$@M1`ygH6X$mKY0J1bWXaq9xm6y9$`Si9mcB*spm(dn{)`JoreY z?)&-bcR=6leYJsRf3!zVp9^m9dc~0rtnaM&SxTCH9)b8m1-}vml6v4GX^Y+9aQ#Xp zv@^uLgdj^9jRrAi`^=F~#w^drGjrmE!k^B$^R48putl4sc{?Bh>Lhrrf-K5yE{lKRGw}ii-7emksP#-Q}y|!hs&xW9iv7>;=Ql@t0AC+4IvfXsP1j6M6 z2*ftRq5K2FS`>0wwar=v602n(v07XLU2Sa{NUWBDpcZBbi-Wy|CP5k-dZeL7kk)Iq zSJHg~m!lEfH4{fpL2%l^bXx6v*1`lsk+8??R9fMt9%(j(7og)0nm2CN%FivUBDp;)ll9iyR3c$LT#+bz!OB!&{m}(!$Y_g_EMII99?{ z1kR)MBTsNdAI{*M0?(0g$b{1&*cBYk4B-ilg-14BICemY11LVYvDE9Rv6SUGf>xWm zwGh|2JF6W}cUC(*?(73u|L(kj&l~vs133inxJZKu1lRIqhex&@5bLVDL!>pJD)Gt8ADF?TY8~qW%{1 zqVXIz%zH&~J7j}yPNTIQL6yhTanf%;tbC7zu8^Ds#ioX|GHVN=`l6p?GV#w{g9<;E z4nL9@!oITyYH-Lpq&Hl&DP*T8KpP3I;uwk-iRBMzqR41vi04Hj%v1}|hscUfU^enz zfDh5v-U}9HWKr3Ywp47-sp!Lt5GPJSwGy~C$0)PmmAAx%1)F|Y%1SlPl>G}t;QTMn zOZnnFFr%)KLUTB)lSHAqik1hY}`}8T$c}$^JET3a)i@_xX zx>Uq&m9Um#_&*S``84DQU)bQ^qn35z{Sdx`)?G`sew6v9@ckt+WTlolnJ_Sd5Md(H z{jgMEPaMQ_gsMvs@;51KTB~fFoh*$}?d@Q_`(cF>7o%j@qKD6@|D@m~ZL| z7+I&+H*uFb9OP4rK78fdk#DQ0~KZkrvMTmC5IVhFHiavS7k?EY+10?398Z`5} zq$D^E6mh#0XymF~Z{xLkg3j zmozjud_<%%A4rRj2oZwfVHR#8s^K@11zZ>LDoq0;IDv2+n?QjR2**w)xStU`KScc| zru!&a9n)o$EaJ63I%Q}T-puwH?&q$&@uY&Q122cFL%dmfeFJdF@P!k!5->MkvhD&E zaBghzi;b$XCRt57j{^b!^A=oTn6xq`MLb1NBsmBoE_nvc8(Ncwa}0+{Tqb-(HOXhW z_&|ygzJh{SGj&7*p3u?JCLCWku^68wF*+`ARN-~reuz64eN5bCpXX7Kw9H~#vxbcP zlRcAm#+Z*~A$;*HrC*n_Kx)LYEo3QeAu|<2mTU`IvMprb#*ro4LY8a`SsEhj|6w;$ z7?#Wxe9Uw9&m$LeR;iuDLBTyzDZj0~8a|+rdz&&Y?(lr!fh#Csck2XWbdYSK{r=Kv28)~Q6&gni}bqppB@`@xm%u;JXA9(IZ z4YFHYt}lQHt&6A{C`YVt<7jAzta-YmxF{B%f=W!ErU60J8bde@@;tzh5(qS&fkWx( zCNx}XX}w3gm4pgIgsrF~b5C)MohX6N^7B-GTy>mdr*`BA$x@i0@$6 zwBGGk+j#$+g5q10JspOFdeC)r@DR}zLd1HATJ`YK0H{#5&})3JAo@2AHHilWxOqSq zHve7S)mvzsy}>4N%v6)O@P?X9%6AbZ3s%agN#O*){saQL0F&QTmcY?kGiB7|l5E=+ zMDVaM@PMNAG%($jVyDVcFPU z15mH2Q1X97q^~1*m(~h-(0Xk5BA1I$P7L!vD=}f=CvgEciDwe~5@+BRM$2UaySr4v zev1plPct9^`xFDNyx=^7C4M8GxmCe4Dm*fLd2>25cQ%8Y-pthVnOf!pnb{2X z>KT7)rnnV>=Je(BIt~M?UV*BKf1Jw^`~__8ZO93iBbO%Er4@rfX7Dw6Z*xn?`4>jw zomweh#iIzEK~`{+oeL|uwPIxjDX;9f+u?YJl3KZPzwA14U@Ia6DmueXEeXpW>twMH zWG)u-r4=Xt{AV}|$Ulm8^JgVheUeWyI%y!^U7h1lk`y!{e` zSq7XgJQYHaU*S7lyv=EUoT)|F(>;mar3$O@PKRCssRy+c`&%S3gn;7j2kTxnC(m{S z7cXP*f`Pd)IKMv~jQx*WBA05t3u7`({f(fyZ(m|ZN&QC)LZWyK3y z^VMo`NBW_k4C1qDc`$_cxFPI-b0r_V?b*yNf`Kf-2rZIZXCbVRKcw;&vN!rBXfZ_>Q+3*@P%E+duVmX>e*I#WNUY6lHB zYwf{A<=FGgsB#<>s~iVY2t`n}6mLJUR{*g;&fv2QzQEv%48FwR8w~!8!A%4rFS`Yf zjM)7|Sp3bhgpQch?Ho*zOr1=aWQ+MA)Z#)R4kWqLNhaC$x3T1^SGO zF{gnj$SWWpGlwaHR z0hLhe8H4>7%+lY|&(}7Yav89$eVoAw2BN#3L+Yn}m`(NA>CrZ=Snz$Wq2V;WQM_+U zTSpQ{@S?55kA^3%Tlmpo?{MNd>$&csuESUHsYYL_Z#Xq}By~8oFSQ?^f*ehq;%m9n z@=A`|zhP_$M-s>J3JyQX2{q9>VfEpl^l0w@JmDd0q}$}XcE#OzZ)c71g`K>zYY*lA zL=7dz6n?n*Oz0bxU7j*lymBrVa8*rBZI_C<)k@KU ziRRi2ckq&yiph63YxuImkq-?t8rMwptTdnio7!~hns5r;)D%`L-p6`QuJv^Ym9s8b z$>ZHJ9srvjw7wMy=(kNxnFT2avN~7wOh&KIfQn*jN|xnbFE#UW8SW78C}YBp4;3_1`o zUolw1;x>~_M(1*32QT|;H9n}m#qMfRsC>y3iJW{o zvsd86cZ@7WE|NLzIEqL48kl6?WN?GQ0(r)6--MWJkCYr{?iKUE$Nnz>VqPaTbWFyw z$i7==2wZ{}OBJV9bf2d{1a}Y&;03YPf@x?b=JqEf-<$f8`jL8$Y0vr2j5P+QoXqz@|>AmzqXt{(IYG}i~l*V?Pq_q<#R(;@?&PLkAdn#$g?x?Zf zgGb=Scm^H-W_IPVVoLc*F3P8wo!On+Itza;E&le$qy4B>e$C_Gr}%3d3$ofebeic5(-PBJrgKc^ncii(z;u!664Pa-D@<3J zt}$I_dXMP_(@myZOt+cdXIf_Zfawm?U8WD2K4SWq=@X_ErcasfG2LhSjOlZx2TXOQ zFPOe$ddT#MX_e_Krmva4VfvQoJErfMeqegc^dr*~rk|LeGOaN+n3_y2rgf$^(+1Nf z(-zY+rsqr@rY_Sq(+*RQX_sjaX};E9!6~Y#zwm2i4hiUSZ+oRrd;=dMj@wEmanGnM zQn^T4%E$=-385M&S6-=KU5cPrYS(TM=r z&xg`z6(8H8JY-koxylaPMyEZkGO&Se$|SLH!TaftE$Bo=eK11d*{`5DN>tv`DZaP0 zX%^5Kbfp~v9hy}A!W@W5+G9#O^o+7yBuQy{uG9{tFc21pM#XTRWJcoo+ldyiW{eoa zSr%?(rRX+_Z3X@_#G{U%^W_Q(5G8qq5U(1e_?}`auUKnim^X=*eb3cRO3Dz>HP|-nJs}CQGF=H0gN>W!`8^wCs=5 zR02*^SKxExGGg;Yfp6J{gd-`l^(@v{==EH|9W*^M3j1tk(%LGK*u=grZm{08Y-9UH zFVO&t6LMoSUBxvxjhUrR4^ym0coeRVR-++f z8Wa1me68ECGtgNw1_~|GX<4NAAa>6&{PZSk|f-SxBm6{_q&m= 6): + ugrid_writer.SetInputData(ugrid) + else: + ugrid_writer.SetInput(ugrid) + ugrid_writer.Update() + ugrid_writer.Write() diff --git a/vtk_py/addFieldPrincipalDirections.py b/vtk_py/addFieldPrincipalDirections.py new file mode 100644 index 0000000..660c24b --- /dev/null +++ b/vtk_py/addFieldPrincipalDirections.py @@ -0,0 +1,99 @@ +######################################################################## + +import numpy +import vtk + +from mat_vec_tools import * +from createFloatArray import * + +######################################################################## + +def addFieldPrincipalDirections(ugrid_mesh, + field_name, + field_type="cell", + field_storage="vec", + verbose=True): + + if (verbose): print '*** addFieldPrincipalDirections ***' + + assert (field_type in ["point", "cell"]), "\"field_type\" must be \"point\" or \"cell\". Aborting." + assert (field_storage in ["vec", "Cmat", "Fmat"]), "\"field_storage\" must be \"vec\", \"Cmat\" or \"Fmat\". Aborting." + + if (field_type == "cell" ): nb_cells = ugrid_mesh.GetNumberOfCells() + elif (field_type == "point"): nb_cells = ugrid_mesh.GetNumberOfPoints() + + if (field_type == "cell" ): field = ugrid_mesh.GetCellData().GetArray(field_name) + elif (field_type == "point"): field = ugrid_mesh.GetPointData().GetArray(field_name) + + field_Lmin = createFloatArray(field_name+'_Lmin', 1, nb_cells) + field_Lmid = createFloatArray(field_name+'_Lmid', 1, nb_cells) + field_Lmax = createFloatArray(field_name+'_Lmax', 1, nb_cells) + + field_Vmin = createFloatArray(field_name+'_Vmin', 3, nb_cells) + field_Vmid = createFloatArray(field_name+'_Vmid', 3, nb_cells) + field_Vmax = createFloatArray(field_name+'_Vmax', 3, nb_cells) + + for num_cell in range(nb_cells): + if (field_storage == "vec" ): matrix = vec_col_to_mat_sym(field.GetTuple(num_cell)) + elif (field_storage == "Cmat"): matrix = numpy.reshape(field.GetTuple(num_cell), (3,3), order='C') + elif (field_storage == "Fmat"): matrix = numpy.reshape(field.GetTuple(num_cell), (3,3), order='F') + + if (numpy.linalg.norm(matrix) > 1e-6): + #if (verbose): print 'num_cell =', num_cell + + val, vec = numpy.linalg.eig(matrix) + #if (verbose): print 'val =', val + #if (verbose): print 'vec =', vec + idx = val.argsort() + val = val[idx] + vec = vec[:,idx] + #if (verbose): print 'val =', val + #if (verbose): print 'vec =', vec + + matrix_Lmin = [val[0]] + matrix_Lmid = [val[1]] + matrix_Lmax = [val[2]] + + matrix_Vmin = vec[:,0] + matrix_Vmid = vec[:,1] + matrix_Vmax = vec[:,2] + else: + matrix_Lmin = [0.] + matrix_Lmid = [0.] + matrix_Lmax = [0.] + matrix_Vmin = [0.]*3 + matrix_Vmid = [0.]*3 + matrix_Vmax = [0.]*3 + + field_Lmin.InsertTuple(num_cell, matrix_Lmin) + field_Lmid.InsertTuple(num_cell, matrix_Lmid) + field_Lmax.InsertTuple(num_cell, matrix_Lmax) + field_Vmin.InsertTuple(num_cell, matrix_Vmin) + field_Vmid.InsertTuple(num_cell, matrix_Vmid) + field_Vmax.InsertTuple(num_cell, matrix_Vmax) + + if (field_type == "cell"): + ugrid_mesh.GetCellData().AddArray(field_Lmin) + ugrid_mesh.GetCellData().AddArray(field_Lmid) + ugrid_mesh.GetCellData().AddArray(field_Lmax) + ugrid_mesh.GetCellData().AddArray(field_Vmin) + ugrid_mesh.GetCellData().AddArray(field_Vmid) + ugrid_mesh.GetCellData().AddArray(field_Vmax) + elif (field_type == "point"): + ugrid_mesh.GetPointData().AddArray(field_Lmin) + ugrid_mesh.GetPointData().AddArray(field_Lmid) + ugrid_mesh.GetPointData().AddArray(field_Lmax) + ugrid_mesh.GetPointData().AddArray(field_Vmin) + ugrid_mesh.GetPointData().AddArray(field_Vmid) + ugrid_mesh.GetPointData().AddArray(field_Vmax) + +if (__name__ == "__main__"): + assert (len(sys.argv) in [3,4,5]), "Number of arguments must be 2, 3 or 4. Aborting." + ugrid_mesh = readUGrid(sys.argv[1]) + if (len(sys.argv) == 2): + addFieldPrincipalDirections(ugrid_mesh, sys.argv[2]) + elif (len(sys.argv) == 3): + addFieldPrincipalDirections(ugrid_mesh, sys.argv[2], sys.argv[3]) + elif (len(sys.argv) == 4): + addFieldPrincipalDirections(ugrid_mesh, sys.argv[2], sys.argv[3], sys.argv[4]) + writeUGrid(ugrid_mesh, sys.argv[1]) diff --git a/vtk_py/addFieldPrincipalDirections.pyc b/vtk_py/addFieldPrincipalDirections.pyc new file mode 100644 index 0000000000000000000000000000000000000000..070216223736672b209d43049cd1a63e9b641c5d GIT binary patch literal 3129 zcmb_e&u<%55T3W|*p9u&AfT@X2vo9tX01G z{rW){l1~x8Z{QohDF9sj6W{~vPv-*m1>*+z2J8_7XC}@}a0?&{;LgC8ChX6EEP`8v zBLkw>ge-w9Lw^0^nh@M7tRb{-K~BeFLqCE}{fX4un83-=2DT9|3FB$2Q-bHJD%S$FL^$RdYbpewi z1eY`Fzc6R!DGnaANGk3utm55{kzvB5l%mxvT24_bi_WHK4bi#OLM27#vuHI%7qX}Y zCx)R)tSaEf06l1DIY_FHZAC*Gjp`5y9`Ho(cc*fj)!IZV*@7hFj;`{JoM-J zh8Af)UW7GV7%y=B0eoc;bZ8*TTz3W5dU%!#M8@E=u*5=L3(GlWb6^UcIWUFJ9GF6h1KhIjx1YzRayNbf$MyB~rsKLhp7h;& zkr#Bmq2u55BH2}57{pCnSJaM%p%SwL1&8>qlQeM!z+A&azJKgrcQ9RkfN&Lo{u~>zX)63e!Uf8|exN-9~a?3(@F zzzaO?r{pP#Zo1%{=-C6JnB)ReP)sNf1_>pMTp4jg-sW+q_w^q?fB*NBpEf;I1CRXg z(TqNAlHzGx;oTwM$!Pwn*13Ij>M(%F8E<4huUq0-90Ha>yx%L2Uv#3)pa0W6XQU}7FzN!I zWLzQy-^=tG4YOfdq9W>rn!txSYsRdgMr*u-=k4J6jjw1vHLrFotD*Q=S<#jS= 6): + cleanepipdata.SetInputData(epi) + else: + cleanepipdata.SetInput(epi) + cleanepipdata.Update() + pdata_epi = cleanepipdata.GetOutput() + + cleanendopdata = vtk.vtkCleanPolyData() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + cleanendopdata.SetInputData(endo) + else: + cleanendopdata.SetInput(endo) + cleanendopdata.Update() + pdata_endo = cleanendopdata.GetOutput() + + L_epi = pdata_epi.GetBounds()[5] - pdata_epi.GetBounds()[4] + L_endo = pdata_endo.GetBounds()[5] - pdata_endo.GetBounds()[4] + + if(L_endo > L_epi): + pdata_epi = temp + pdata_epi = pdata_endo + pdata_endo = temp + + + # Quad points + gdim = mesh.geometry().dim() + xdofmap = V.sub(0).dofmap().dofs() + ydofmap = V.sub(1).dofmap().dofs() + zdofmap = V.sub(2).dofmap().dofs() + + if(dolfin.dolfin_version() != '1.6.0'): + xq = V.tabulate_dof_coordinates().reshape((-1, gdim)) + xq0 = xq[xdofmap] + else: + xq = V.dofmap().tabulate_all_coordinates(mesh).reshape((-1, gdim)) + xq0 = xq[xdofmap] + + # Create an unstructured grid of Gauss Points + points = vtk.vtkPoints() + vertices = vtk.vtkCellArray() + ugrid = vtk.vtkUnstructuredGrid() + cnt = 0; + for pt in xq0: + points.InsertNextPoint([pt[0], pt[1], pt[2]]) + vertex = vtk.vtkVertex() + vertex.GetPointIds().SetId(0, cnt) + vertices.InsertNextCell(vertex) + cnt += 1 + + ugrid.SetPoints(points) + ugrid.SetCells(0, vertices) + + CreateVertexFromPoint(ugrid) + addLocalProlateSpheroidalDirections(ugrid, pdata_endo, pdata_epi, type_of_support="cell", epiflip=isepiflip, endoflip=isendoflip, apexflip=isapexflip) + addLocalFiberOrientation(ugrid, endo_angle, epi_angle) + + fiber_vector = ugrid.GetCellData().GetArray("fiber vectors") + sheet_vector = ugrid.GetCellData().GetArray("sheet vectors") + sheetnorm_vector = ugrid.GetCellData().GetArray("sheet normal vectors") + + eCC_vector = ugrid.GetCellData().GetArray("eCC") + eLL_vector = ugrid.GetCellData().GetArray("eLL") + eRR_vector = ugrid.GetCellData().GetArray("eRR") + + cnt = 0 + for pt in xq0: + + fvec = fiber_vector.GetTuple(cnt) + svec = sheet_vector.GetTuple(cnt) + nvec = sheetnorm_vector.GetTuple(cnt) + + cvec = eCC_vector.GetTuple(cnt) + lvec = eLL_vector.GetTuple(cnt) + rvec = eRR_vector.GetTuple(cnt) + + fvecnorm = sqrt(fvec[0]**2 + fvec[1]**2 + fvec[2]**2) + svecnorm = sqrt(svec[0]**2 + svec[1]**2 + svec[2]**2) + nvecnorm = sqrt(nvec[0]**2 + nvec[1]**2 + nvec[2]**2) + + if(abs(fvecnorm - 1.0) > 1e-7 or abs(svecnorm - 1.0) > 1e-6 or abs(nvecnorm - 1.0) > 1e-7): + print fvecnorm + print svecnorm + print nvecnorm + + #print xdofmap[cnt], ydofmap[cnt], zdofmap[cnt] + fiberV.vector()[xdofmap[cnt]] = fvec[0]; fiberV.vector()[ydofmap[cnt]] = fvec[1]; fiberV.vector()[zdofmap[cnt]] = fvec[2]; + sheetV.vector()[xdofmap[cnt]] = svec[0]; sheetV.vector()[ydofmap[cnt]] = svec[1]; sheetV.vector()[zdofmap[cnt]] = svec[2]; + sheetnormV.vector()[xdofmap[cnt]] = nvec[0]; sheetnormV.vector()[ydofmap[cnt]] = nvec[1]; sheetnormV.vector()[zdofmap[cnt]] = nvec[2]; + + cV.vector()[xdofmap[cnt]] = cvec[0]; cV.vector()[ydofmap[cnt]] = cvec[1]; cV.vector()[zdofmap[cnt]] = cvec[2]; + lV.vector()[xdofmap[cnt]] = lvec[0]; lV.vector()[ydofmap[cnt]] = lvec[1]; lV.vector()[zdofmap[cnt]] = lvec[2]; + rV.vector()[xdofmap[cnt]] = rvec[0]; rV.vector()[ydofmap[cnt]] = rvec[1]; rV.vector()[zdofmap[cnt]] = rvec[2]; + + + cnt += 1 + + + writeXMLUGrid(ugrid, "fiber.vtu") + + return fiberV, sheetV, sheetnormV, cV, lV, rV + + diff --git a/vtk_py/addLVfiber.pyc b/vtk_py/addLVfiber.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c08e4c1195bf5749c1cfa09ac6514414a48d89f2 GIT binary patch literal 4153 zcmbVO&2!tv6@LIJS)xUK+4`VkJN{4-+L0wWj?+uVNleEdQ`zyzveN0Kqk(`G1sDWq zVChIMcyh0~<&vDzV^7UYC%2w^$V|^Y=MTtCCOLGbm-hGG5+LX_J(M7K-+TM^x9@X_ z%1`y$=igo1b7}CgF~5&rx`DyN*P@VUn<<+@i+*e6Qk%9_g}e&=0n#cjKWbL7$^SP# zO$(If;qn7_64N{QP2tzVFa7)&7Kt*8URczhEYY_f zoTsamkI^&13Lhd%VB{cd;C&i^(o>dxgDE5j3HEB_9Vc&!vT^cIcE`v=i6FFHv zhhD6L$6-LcB=%e;&$Oo?4TYvjW!q3V$L91eG1gFsI)L!y zg!4z6!}$gU&_-N)mDqL4E|=I1%HAxoS1DU9v2T%HrR<7i3As7JBr?V1 z64OYR(0uGQ(Onzrf-H1Fmv!G3-Swd^$U+x%S@$|=cyx`t1zN^A-XeEa`o}SrzFkO{ zO493vRCJTSjA8qoyU@mP9Rs(ZaVkTVt#Kw%{|H~>-GPTgIl3&D!>XYi)hlx2a8`R6 z$9O-K=Qt)3LwSy4f|21q9JR+pW+=~bOq7Q59A`s48$Zkeq~$kwkIQal(8-R~WX{GV|u9nYXsu5aaX1d+ob_{_B@N{^R+L_GjOJ^VL89 z_VtaFUrgk@wP(85>~@dz0!TNGo~cCt=Kkh=l^$%zkMAVD zr%w!5j39pKIoi?3A#W?~sz@g>^!TtlO5cook(UbR!si3!4C1t%^prjgrL-IR`c~X= z{OG3ApDGo7h-iHfc^`It@d_sCStw#|h02K@#^KQ|KC)(nJ1R-p{CRWY&i1eGJ3*Y} zVtx&Kr1ZV0+tad*6Os$W=f_=mpmK{p>S<_7F16~I{IylwQ93yidpy4*bK2XJ?MQ9M z>B=|C3l`;nf;QC`gCEc9yv83BwUZ zjxOTyFvcONW*0d+D7_Do#5s~ALGU#8He=TbA0{!! z;SuVBi^d6W`3YJ9*-XX%T<40HxykSCvZaG8$P4|B^oZ-EDsoT*TyxybyH3;wI_Ck6KH#|R zS<~|qS@F~S65ws%@@v4b`9&ZVBaOKur1bla93>=o{*LDR$2C)EresIb(`$2Ia-z77 z9kIG4PCVCfSBisMud6)MeR6Z4xA?YVizEy#cNVNQ5bTyvyAVm{%{sJ=0y{8JU<5vV zQ*`+b0mVYbZ*#M7SPlnW!t_yzemLI-o>outfile, cnt, " ", f + return Qa + + + def orto3(Q, cnt): + + Q2 = np.dot(np.transpose(Q),Q) + Q2inv = np.linalg.inv(Q2) + sqrtQ2 = linalg.sqrtm(Q2inv) + Qa = np.dot(Q,sqrtQ2) + + return Qa + + ################################################################################################# + #Function to ensure the that the axis are orthogonal but this one is not working prorperly + ################################################################################################# + + def orto2(Q): + e0 = np.zeros(3); e1 = np.zeros(3); e2 = np.zeros(3); + e0[0] = Q[0][0]; e0[1] = Q[1][0]; e0[2] = Q[2][0]; + e1[0] = Q[0][1]; e1[1] = Q[1][1]; e1[2] = Q[2][1]; + e2[0] = Q[0][2]; e2[1] = Q[1][2]; e2[2] = Q[2][2]; + + while np.dot(e0, e1) + np.dot(e0, e2) + np.dot(e1, e2) > 10e-30: + e2 = np.cross(e0, e1); + e0 = np.cross(e1, e2); + Qa = np.array([[e0[0], e1[0], e2[0] ],[ e0[1], e1[1], e2[1]],[ e0[2], e1[2], e2[2]]]) + return Qa + + ############################################################################################## + #Function 3 - This function rotates the axis calculated in the previous steps + ############################################################################################## + + def orient(Q, al, bt): + arr1 =np.array( [[np.cos(al), -np.sin(al), 0 ],[np.sin(al), np.cos(al), 0],[0, 0, 1]]); + arr2 = np.array([[1, 0, 0],[0, np.cos(bt), np.sin(bt) ],[0, -np.sin(bt), np.cos(bt) ]]); + out = np.dot(Q, arr1, arr2) + return out + + ################################################################################################## + #Function 4 - This function calculates quarternions and interpolates these quarternions + ################################################################################################# + + def bislerp(Qa, Qb, t): + + Qa_M = mat3([Qa[0,0], Qa[0,1], Qa[0,2], Qa[1,0], Qa[1,1], Qa[1,2], Qa[2,0], Qa[2,1], Qa[2,2]]) + Qb_M = mat3([Qb[0,0], Qb[0,1], Qb[0,2], Qb[1,0], Qb[1,1], Qb[1,2], Qb[2,0], Qb[2,1], Qb[2,2]]) + qa = quat(Qa_M) + qb = quat(Qb_M) + + val = np.zeros(8) + quat_i = quat(0,1,0,0) + quat_j = quat(0,0,1,0) + quat_k = quat(0,0,0,1) + quat_array = [qa, -qa, qa*quat_i, -qa*quat_i, qa*quat_j, -qa*quat_j, qa*quat_k, -qa*quat_k] + cnt = 0 + for qt in quat_array: + val[cnt] = qt.dot(qb) + cnt = cnt + 1 + + qt = quat_array[val.argmax(axis=0)] + + if(t < 0): + t = 0.0 + + + qm = slerp(t, qt, qb) + qm = qm.normalize() + Qm_M = qm.toMat3() + Qm = [[Qm_M[0,0], Qm_M[0,1], Qm_M[0,2]], [Qm_M[1,0], Qm_M[1,1], Qm_M[1,2]], [Qm_M[2,0], Qm_M[2,1], Qm_M[2,2]]] + + return Qm + + def my_bislerp(Qa, Qb, t): + + qa = pyq.Quaternion(matrix=Qa) + qb = pyq.Quaternion(matrix=Qb) + + + val = np.zeros(8) + + quat_i = pyq.Quaternion(0,1,0,0) + quat_j = pyq.Quaternion(0,0,1,0) + quat_k = pyq.Quaternion(0,0,0,1) + + quat_array = [qa, -qa, qa*quat_i, -qa*quat_i, qa*quat_j, -qa*quat_j, qa*quat_k, -qa*quat_k] + + cnt = 0 + qb_arr = np.array([qb[0], qb[1], qb[2], qb[3]]) + + for qt in quat_array: + #val[cnt] = qt.dot(qb) + qt_arr = np.array([qt[0], qt[1], qt[2], qt[3]]) + val[cnt] = np.dot(qt_arr, qb_arr) + cnt = cnt + 1 + + qt = quat_array[val.argmax(axis=0)] + + if(t < 0): + t = 0.0 + + #qm = slerp(t, qt, qb) + qm = pyq.Quaternion.slerp(qt, qb, t) + qm = qm.normalised + Qm_M = qm.rotation_matrix + + return Qm_M + + + + ################################################################################################# + ######Generating results and using the functions ########## + ################################################################################################# + # DOF map + parameters["form_compiler"]["quadrature_degree"] = degree + parameters["form_compiler"]["representation"] = 'quadrature' + + V = FunctionSpace(mesh, VectorElement("Quadrature", mesh.ufl_cell(), degree=degree, quad_scheme="default")) + S = FunctionSpace(mesh, FiniteElement("Quadrature", mesh.ufl_cell(), degree=degree, quad_scheme="default")) + + dof_coordinates = V.tabulate_dof_coordinates() + Sdof_coordinates = S.tabulate_dof_coordinates() + n = V.dim() + d = mesh.geometry().dim() + dof_coordinates.resize((n, d)) + Sdof_coordinates.resize((n,d)) + + x_my_first, x_my_last = V.sub(0).dofmap().ownership_range() + x_dofs = np.arange(0, x_my_last-x_my_first, d) + y_dofs = np.arange(1, x_my_last-x_my_first, d) + z_dofs = np.arange(2, x_my_last-x_my_first, d) + + + jj = np.array([ 1, 1, 1] ); hh = np.array([1, 1, 1]); + + + ####### Solving the poisson equation ############ + + # case 1) epi -> u = 0 and rv/lv -> u = 1 + + if(MPI.rank(mpi_comm_world()) == 0): + print "Solve Poisson Eq. 1, epi -> u = 0 and rv/lv -> u = 1" + par1 = [0, 1, 0]; epi, dd = lap(mesh, boundaries, par1, 0, 'phi_epi') + + #total_dd = comm.allreduce(len(dd), op=pyMPI.SUM) + #num_of_nodes = total_dd/3 + #scalar_array = np.zeros(num_of_nodes) + #scalar_dof = S.dofmap().dofs() + + total_dd = len(dd) + S_my_first, S_my_last = S.dofmap().ownership_range() + scalar_dof = filter(lambda dof: S.dofmap().local_to_global_index(dof) not in S.dofmap().local_to_global_unowned(), + xrange(S_my_last-S_my_first)) + + #case 4) from the top to the bottom + + if(MPI.rank(mpi_comm_world()) == 0): + print "Solve Poisson Eq. 4, from the top to the bottom" + par1 = [0, 1, 0]; b, dd4 = lap(mesh, boundaries, par1, 1, 'phi_ab') + + + + # Start calculating the fiber orientation + cnt = 0; c = 0; + vector_array = np.zeros(V.dim()) + + func_of_vector = Function(V); + func_of_scalar = Function(S); + + func_of_e0 = Function(V); + func_of_e1 = Function(V); + func_of_e2 = Function(V); + + func_of_e0_vector = func_of_e0.vector() + func_of_e1_vector = func_of_e1.vector() + func_of_e2_vector = func_of_e2.vector() + + e0_fiber = func_of_e0_vector.get_local() + e1_fiber = func_of_e1_vector.get_local() + e2_fiber = func_of_e2_vector.get_local() + + vec_dd = np.zeros(3); vec_dd2 = np.zeros(3); vec_dd3 = np.zeros(3); vec_dd4 = np.zeros(3); + + Qepi = np.zeros((total_dd,3)); Qlv = np.zeros((total_dd,3)); + Qendo = np.zeros((total_dd,3)) + Qfiber = np.zeros((total_dd,3)) + + e0_epi = np.zeros(total_dd); e1_epi = np.zeros(total_dd); e2_epi = np.zeros(total_dd); + e0_lv = np.zeros(total_dd); e1_lv = np.zeros(total_dd); e2_lv = np.zeros(total_dd); + check = np.zeros(total_dd); check2 = np.zeros(total_dd); + ds = np.zeros(total_dd/3); al_s = np.zeros(total_dd/3); b_s = np.zeros(total_dd/3); + al_w = np.zeros(total_dd/3); b_w = np.zeros(total_dd/3); + + e0_endo = np.zeros(total_dd); e1_endo = np.zeros(total_dd); e2_endo = np.zeros(total_dd); + + + for x_dof, y_dof, z_dof, scl in zip(x_dofs, y_dofs, z_dofs, scalar_dof): + + pt = Point(np.array([Sdof_coordinates[scl][0], Sdof_coordinates[scl][1], Sdof_coordinates[scl][2]])) + meshid = mesh.bounding_box_tree().compute_first_collision(pt) + + al_endo = lv_fiber_angle[0]; b_endo = lv_sheet_angle[0]; + al_epi = lv_fiber_angle[1]; b_epi = lv_sheet_angle[1]; + + al_w[scl] = al_endo*(1 - epi[scl]) + al_epi*epi[scl]; b_w[scl] = b_endo*(1 - epi[scl]) + b_epi*epi[scl]; + + vec_dd[0] = dd[x_dof]; vec_dd[1] = dd[y_dof]; vec_dd[2] = dd[z_dof]; + vec_dd4[0] = dd4[x_dof]; vec_dd4[1] = dd4[y_dof]; vec_dd4[2] = dd4[z_dof]; + + Qepi[c:c+3][0:3] = axisf(vec_dd4, vec_dd); + Qepi[c:c+3][0:3] = orto3(Qepi[c:c+3][0:3], cnt); + Qepi[c:c+3][0:3] = orient(Qepi[c:c+3][0:3], al_w[scl], b_w[scl]); + + e0_epi[x_dof] = Qepi[c][0]; e0_epi[y_dof] = Qepi[c+1][0]; e0_epi[z_dof] = Qepi[c+2][0]; + e1_epi[x_dof] = Qepi[c][1]; e1_epi[y_dof] = Qepi[c+1][1]; e1_epi[z_dof] = Qepi[c+2][1]; + e2_epi[x_dof] = Qepi[c][2]; e2_epi[y_dof] = Qepi[c+1][2]; e2_epi[z_dof] = Qepi[c+2][2]; + + Qfiber[c:c+3][0:3] = Qepi[c:c+3][0:3] + + e0_fiber[x_dof] = Qfiber[c][0]; e0_fiber[y_dof] = Qfiber[c+1][0]; e0_fiber[z_dof] = Qfiber[c+2][0]; + e1_fiber[x_dof] = Qfiber[c][1]; e1_fiber[y_dof] = Qfiber[c+1][1]; e1_fiber[z_dof] = Qfiber[c+2][1]; + e2_fiber[x_dof] = Qfiber[c][2]; e2_fiber[y_dof] = Qfiber[c+1][2]; e2_fiber[z_dof] = Qfiber[c+2][2]; + + cnt = cnt + 1; + c = c + 3; + + if(isrotatept): + points = [(-Sdof_coordinates[scl][2]+maxz)/10.0, Sdof_coordinates[scl][1]/10.0, Sdof_coordinates[scl][0]/10.0] + fvectors = [-1.0*e0_fiber[z_dof], e0_fiber[y_dof], e0_fiber[x_dof]] + svectors = [-1.0*e2_fiber[z_dof], e2_fiber[y_dof], e2_fiber[x_dof]] + + else: + points = [Sdof_coordinates[scl][0], Sdof_coordinates[scl][1], Sdof_coordinates[scl][2]] + fvectors = [e0_fiber[x_dof], e0_fiber[y_dof], e0_fiber[z_dof]] + svectors = [e2_fiber[x_dof], e2_fiber[y_dof], e2_fiber[z_dof]] + + + vtkoutfile = outfilename+"_e0_fiber" + func_of_e0_vector.set_local(e0_fiber) + func_of_e0_vector.apply("insert") + vtk_py.convertQuadDataToVTK(mesh, V, func_of_e0, vtkoutfile, outdirectory) + + vtkoutfile = outfilename+"_e1_fiber" + func_of_e1_vector.set_local(e1_fiber) + func_of_e1_vector.apply("insert") + vtk_py.convertQuadDataToVTK(mesh, V, func_of_e1, vtkoutfile, outdirectory) + + vtkoutfile = outfilename+"_e2_fiber" + func_of_e2_vector.set_local(e2_fiber) + func_of_e2_vector.apply("insert") + vtk_py.convertQuadDataToVTK(mesh, V, func_of_e2, vtkoutfile, outdirectory) + + if(MPI.rank(mpi_comm_world()) == 0): + print isrotatept + print outdirectory + outfilename + print "*******************************************************" + + if(isreturn): + + return func_of_e0, func_of_e1, func_of_e2 + + + diff --git a/vtk_py/addLVfiber_LDRB.pyc b/vtk_py/addLVfiber_LDRB.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f3d0ae992aa2b49cca156986d96e4b274418a85 GIT binary patch literal 15746 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 P1ULkbme>JX@xK29-^Xo1 literal 0 HcmV?d00001 diff --git a/vtk_py/addLocalCylindricalDirections.py b/vtk_py/addLocalCylindricalDirections.py new file mode 100644 index 0000000..f398997 --- /dev/null +++ b/vtk_py/addLocalCylindricalDirections.py @@ -0,0 +1,107 @@ +######################################################################## + +import math +import numpy +import vtk + +from createFloatArray import * +from getABPointsFromBoundsAndCenter import * +from getCellCenters import * + +######################################################################## + +def addLocalCylindricalDirections(ugrid_wall, + type_of_support="cell", + points_AB=None, + verbose=True): + + if (verbose): print '*** addLocalCylindricalDirections ***' + + if (points_AB == None): + points_AB = getABPointsFromBoundsAndCenter(ugrid_wall, verbose) + #print points_AB + assert (points_AB.GetNumberOfPoints() >= 2), "points_AB must have at least two points. Aborting." + point_A = numpy.array([0.]*3) + point_B = numpy.array([0.]*3) + points_AB.GetPoint( 0, point_A) + points_AB.GetPoint(points_AB.GetNumberOfPoints()-1, point_B) + #if (verbose): print "point_A =", point_A + #if (verbose): print "point_B =", point_B + eL = point_B - point_A + eL /= numpy.linalg.norm(eL) + #if (verbose): print "eL =", eL + + if (type_of_support == "cell"): + pdata_cell_centers = getCellCenters(ugrid_wall) + + if (type_of_support == "cell"): + nb_cells = ugrid_wall.GetNumberOfCells() + elif (type_of_support == "point"): + nb_cells = ugrid_wall.GetNumberOfPoints() + + farray_eR = createFloatArray("eRR", 3, nb_cells) + farray_eC = createFloatArray("eCC", 3, nb_cells) + farray_eL = createFloatArray("eLL", 3, nb_cells) + + farray_r = createFloatArray("r", 1, nb_cells) + farray_t = createFloatArray("t", 1, nb_cells) + farray_z = createFloatArray("z", 1, nb_cells) + + for num_cell in range(nb_cells): + #if (verbose): print "num_cell =", num_cell + + if (type_of_support == "cell"): + cell_center = numpy.array(pdata_cell_centers.GetPoints().GetPoint(num_cell)) + elif (type_of_support == "point"): + cell_center = numpy.array(ugrid_wall.GetPoints().GetPoint(num_cell)) + + #if (verbose): print "cell_center =", cell_center + + #eR = cell_center - point_A + #eR -= numpy.dot(eR,eL) * eL + #eR /= numpy.linalg.norm(eR) + + #eC = numpy.cross(eL, eR) + + eR = cell_center - point_A + eC = numpy.cross(eL, eR) + eC /= numpy.linalg.norm(eC) + eR = numpy.cross(eC, eL) + + if (numpy.dot(eR,eC) > 1e-6) or (numpy.dot(eR,eL) > 1e-6) or (numpy.dot(eC,eL) > 1e-6): print "WTF?!" + + farray_eR.InsertTuple(num_cell, eR) + farray_eC.InsertTuple(num_cell, eC) + farray_eL.InsertTuple(num_cell, eL) + + r = numpy.dot(cell_center - point_A, eR) + farray_r.InsertTuple(num_cell, [r]) + + t = math.atan2(eR[1], eR[0]) + t += (t<0.)*(2*math.pi) + farray_t.InsertTuple(num_cell, [t]) + + z = numpy.dot(cell_center - point_A, eL) + farray_z.InsertTuple(num_cell, [z]) + + if (type_of_support == "cell"): + ugrid_wall.GetCellData().AddArray(farray_eR) + ugrid_wall.GetCellData().AddArray(farray_eC) + ugrid_wall.GetCellData().AddArray(farray_eL) + ugrid_wall.GetCellData().AddArray(farray_r) + ugrid_wall.GetCellData().AddArray(farray_t) + ugrid_wall.GetCellData().AddArray(farray_z) + elif (type_of_support == "point"): + ugrid_wall.GetPointData().AddArray(farray_eR) + ugrid_wall.GetPointData().AddArray(farray_eC) + ugrid_wall.GetPointData().AddArray(farray_eL) + ugrid_wall.GetPointData().AddArray(farray_r) + ugrid_wall.GetPointData().AddArray(farray_t) + ugrid_wall.GetPointData().AddArray(farray_z) + + return ugrid_wall + +if (__name__ == "__main__"): + assert (len(sys.argv) in [2]), "Number of arguments must be 1. Aborting." + writeUGrid(addLocalCylindricalDirections(readUGrid(sys.argv[1])), sys.argv[1]) + diff --git a/vtk_py/addLocalCylindricalDirections.pyc b/vtk_py/addLocalCylindricalDirections.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f091847fe7f4679a2094d2c9c865705ce6491689 GIT binary patch literal 2753 zcmb_eOK%%h6h1S4JC5xnuKN;|yFiK}Xhgd}La5YnX$uMgO@oReq0z*1kp^ z8~a_FesXx;!kvDH!N=F4kZ5l%TeN4*aGUmQk!=byw9DF%vU4d1DZ?IAf&46ek)gdJ zsS^1)INtH?7y$3gANr>6K!scUHKecIM zlUeQCbSilsY9<=gH60I7@JEnK_Tfe}OKH zb7lp~S-LQRYF?Zbs9$6m?%!Y(!HQDP-$<93F~=_ zy8ZD_)}*$O&ySX=-541!Gj&vKT;udO!#YK;E~N3tOc`p=RmM)%O(j>Pj8(4Tc!g^` zS*7vnLTy(~Z4CrHETi1eGnU}E!XOa8PDfcvk8NgZaM64kpLsBN@|o?gO#7`web5q9 z>4WlYF8-}CUJtV_ekDmLn@pzc*JxasX{~Ydu_L`geMDX1a$n>}99_erU6YE&e6C!Q#?0Q{NzjP!C5cE zr=g{1AvqeJG{o*cZCDj3dc4pNJ6R^se3rl*IwLTL&Irt*GXityjKCb45_lB#zCZ0x4qRGj8fe? z^o~`_)2&c>nCXXc%P3rHwfEyh2T|`@4_5LCGI#_m27Kx{a{lo_Cnh+ih?L`)XQyMH z+uL$NCNgRnAN9Wa^M`N#`T6^sDH}i7z4O-9_4AO>;7BTtl)eI?r*wPk17Uk7i3eNp zDDu;GR zI*$p;=7l{W5XH$r{D43QN4klZ>bkL+1>_|Ib`#}kbtjBH-4^d0G4UeUmloor62F_o zX)2}hV~t~w=$(k^?v93`lK2Bp9~!FKi>_#`>Lr2iKJ>y+*BCn)DmOlG)6sB<(g;7KyWP97QWqk*`Wf-J-~#2oYJ zIJ~D0=i~5Juj4jDdJEF#VLVWqVK-E2(^0ANlJ4Q=z0P}^$NI<}o@~DGZMud=dI?Tm zsI&})^cVx>@>H}d)~bEQYT~L}mojCmnW5xQ3OhK(Cg|K%2nt!M+Z= zy4|$a>`T^Vj7{r2tk>pO6BY|ITPo$c122eN*Sz{%0@J#!_@Lz_z0m-BmYPFgU$tIa zc;V&kmVY;5yUv~OT;hTAlIBIFoCYJ@WDa+O!@VvIyqk=abAxAGd)JM;fpT3j3lWo# ziS#5DRq!}=xO=5pA0~lTAKpdBN`K(B@@00meIorod&u109K`-8R5yhZzcUpSvSODl OT)B*uu__<&cKiqND>-=p literal 0 HcmV?d00001 diff --git a/vtk_py/addLocalFiberOrientation.py b/vtk_py/addLocalFiberOrientation.py new file mode 100644 index 0000000..2a7304d --- /dev/null +++ b/vtk_py/addLocalFiberOrientation.py @@ -0,0 +1,103 @@ +######################################################################## + +import sys +import math +import numpy +import vtk + +from addLocalFiberOrientation import * +from addLocalProlateSpheroidalDirections import * +from createFloatArray import * +from getABPointsFromBoundsAndCenter import * +from readSTL import * +from readUGrid import * +from writeUGrid import * + +######################################################################## + +def addLocalFiberOrientation(ugrid_wall, + fiber_angle_end, + fiber_angle_epi, + points_AB=None, + verbose=True): + + if (verbose): print '*** addLocalFiberOrientation ***' + + if (points_AB == None): + points_AB = getABPointsFromBoundsAndCenter(ugrid_wall, verbose) + assert (points_AB.GetNumberOfPoints() >= 2), "\"points_AB\" must have at least two points. Aborting." + point_A = numpy.array([0.]*3) + point_B = numpy.array([0.]*3) + points_AB.GetPoint( 0, point_A) + points_AB.GetPoint(points_AB.GetNumberOfPoints()-1, point_B) + eL = point_B - point_A + eL /= numpy.linalg.norm(eL) + + if (verbose): print "Computing local fiber orientation..." + + farray_norm_dist_end = ugrid_wall.GetCellData().GetArray("norm_dist_end") + farray_norm_dist_epi = ugrid_wall.GetCellData().GetArray("norm_dist_epi") + farray_eRR = ugrid_wall.GetCellData().GetArray("eRR") + farray_eCC = ugrid_wall.GetCellData().GetArray("eCC") + farray_eLL = ugrid_wall.GetCellData().GetArray("eLL") + + nb_cells = ugrid_wall.GetNumberOfCells() + + farray_fiber_angle = createFloatArray("fiber_angle", 1, nb_cells) + + farray_eF = createFloatArray("fiber vectors", 3, nb_cells) + farray_eS = createFloatArray("sheet vectors", 3, nb_cells) + farray_eN = createFloatArray("sheet normal vectors", 3, nb_cells) + + # LCL hack to have homogeneous fibers near apex + #bds = ugrid_wall.GetBounds() + #center = vtk.vtkCellCenters() + #center.SetInputData(ugrid_wall) + #center.Update() + ############################################### + + + for num_cell in range(nb_cells): + norm_dist_end = farray_norm_dist_end.GetTuple(num_cell)[0] + norm_dist_epi = farray_norm_dist_epi.GetTuple(num_cell)[0] + + fiber_angle_in_degrees = (1.-norm_dist_end) * fiber_angle_end + (1.-norm_dist_epi) * fiber_angle_epi + + # LCL hack to have homogeneous fibers near apex + #zloc = center.GetOutput().GetPoints().GetPoint(num_cell)[2] + #if(zloc < bds[4]+1): + # fiber_angle_in_degrees = 0 + ############################################### + + farray_fiber_angle.InsertTuple(num_cell, [fiber_angle_in_degrees]) + + eRR = numpy.array(farray_eRR.GetTuple(num_cell)) + eCC = numpy.array(farray_eCC.GetTuple(num_cell)) + eLL = numpy.array(farray_eLL.GetTuple(num_cell)) + + fiber_angle_in_radians = math.pi*fiber_angle_in_degrees/180 + eF = math.cos(fiber_angle_in_radians) * eCC + math.sin(fiber_angle_in_radians) * eLL + eS = eRR + eN = numpy.cross(eF, eS) + farray_eF.InsertTuple(num_cell, eF) + farray_eS.InsertTuple(num_cell, eS) + farray_eN.InsertTuple(num_cell, eN) + + if (verbose): print "Filling mesh..." + + ugrid_wall.GetCellData().AddArray(farray_fiber_angle) + ugrid_wall.GetCellData().AddArray(farray_eF) + ugrid_wall.GetCellData().AddArray(farray_eS) + ugrid_wall.GetCellData().AddArray(farray_eN) + +if (__name__ == "__main__"): + assert (len(sys.argv) in [4]), "Number of arguments must be 3. Aborting." + basename = sys.argv[1] + ugrid_wall = readUGrid(basename + "-Mesh.vtk") + pdata_end = readSTL(basename + "-End.stl") + pdata_epi = readSTL(basename + "-Epi.stl") + angle_end = float(sys.argv[2]) + angle_epi = float(sys.argv[3]) + addLocalProlateSpheroidalDirections(ugrid_wall, pdata_end, pdata_epi) + addLocalFiberOrientation(ugrid_wall, angle_end, angle_epi) + writeUGrid(ugrid_wall, basename + "-Mesh.vtk") diff --git a/vtk_py/addLocalFiberOrientation.pyc b/vtk_py/addLocalFiberOrientation.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a7cd49ae5c134e7c054a7215d048a4cb53e38ca GIT binary patch literal 2986 zcmbtW%}ygn5Uw8MAB+vy7!2%YHQDR|p_g84IPQ@6v;M5w+IXKO+Y(Y2&C*+Azej*hnQgI@cCer*wDx)Mo zR>04}Pq@Gw$SU}AaA`sMQpiP+0KFx+#U!e5SpfAb=wS)_EdYSdn z!WM{_Sv=laL|TJ?@OQL@+=8ZIyOYQ9J$#AyJ$%)A4j`L@bdk6}c!Ay-GfNCSCa;X= zZ!H++z|8h6xMjjG^Ps*2jrO?_A$ksac_OfjjOC$$+ZyKKZD@hk=@p2}EDso77@bBF zzXVpxZ)1ieMb>a;4dwJ}_QZ2k?X0X`b8AY%d=BsNgApwS$zLbgaHjQ-gw9Sad^ z4kRnzMIn~fMhBHG%;L>4UYW($sTX=Rires4V0E~`04}saxn@mhkO8J^^mWQ-6S6fJ z-s6xB$WXmUDGl#KwlvOj)0{f`n!MRUWVNw=pXa~-MSMdi|GVWk-aL8UHRd4h&K)6c zytRrQa-?h=x3{-#&-V|Lju-9+XEOaN4P>l69VD@hlYvFe^dSxp z`$-UM<+gVp+R;F1`@*}Dwx{h-dZ_8^#5NW!yM30VI*7ZiF8c8=z;1+q#DMx$J;Grx ziTVRFvqM_lKBwjF-nARWhi_x8;9@K7%x&Ou!- z?uJrPEVIa!?C2y_jHnAKwLL}}Xk!ps6|)*mjCS(Z=fQ7ev4q2Z5Qda}B-I6`y0wNF z79cX4#8N*%p(}NJ_chbDpC-|6GKhWEj{QAkSf;v$CI?a<4I<+G+!$)Q-`YyyJRZUG zG({@ua*GF1|Ar+mO}!gkGS2Lz3#ec&UfAUXD0SXFM&FZR_{_rt9XYhwd)au8mnI{H zH4V^7rKjb7n0VS)(%LEVC&vL!2K`WS^p`PZX>{6mPNMiM6xI!e>7>5A za&Gca(;1&Li|%Y`y?p|gq6|kKRA|#G*4wm-Wk*EEXKsf%t>1Z0?TK?A2i%|0j%TzZ z6KxQ2IEQ-2A%-;-+f+a|h+SWHQz?~0?cmUPI7Ir}EK|=9yjU4N_RZ(me2%uz2Y67Q zptN(5L~nI?hnh0lT%uPM9) zl(Rzav^#{3^4AC0J6wg=X`m&m4)p_H1}Evj^sej1UL;+YQwVYAL<+KS z= 2), "\"points_AB\" must have at least two points. Aborting." + point_A = numpy.array([0.]*3) + point_B = numpy.array([0.]*3) + points_AB.GetPoint( 0, point_A) + points_AB.GetPoint(points_AB.GetNumberOfPoints()-1, point_B) + #if (verbose): print "point_A =", point_A + #if (verbose): print "point_B =", point_B + + eL = point_B - point_A + eL /= numpy.linalg.norm(eL) + #if (verbose): print "eL =", eL + + if (verbose): print "Computing local fiber orientation..." + + farray_r = ugrid_wall.GetCellData().GetArray("r") + farray_t = ugrid_wall.GetCellData().GetArray("t") + farray_z = ugrid_wall.GetCellData().GetArray("z") + + farray_norm_dist_end = ugrid_wall.GetCellData().GetArray("norm_dist_end") + farray_norm_dist_epi = ugrid_wall.GetCellData().GetArray("norm_dist_epi") + + farray_norm_z_end = ugrid_wall.GetCellData().GetArray("norm_z_end") + farray_norm_z_epi = ugrid_wall.GetCellData().GetArray("norm_z_epi") + + farray_eRR = ugrid_wall.GetCellData().GetArray("eRR") + farray_eCC = ugrid_wall.GetCellData().GetArray("eCC") + farray_eLL = ugrid_wall.GetCellData().GetArray("eLL") + + nb_cells = ugrid_wall.GetNumberOfCells() + + farray_fiber_angle = createFloatArray("fiber_angle", 1, nb_cells) + + farray_eF = createFloatArray("eF", 3, nb_cells) + farray_eS = createFloatArray("eS", 3, nb_cells) + farray_eN = createFloatArray("eN", 3, nb_cells) + + for num_cell in range(nb_cells): + #print "num_cell = " + str(num_cell) + + t = farray_t.GetTuple(num_cell)[0] + i_t = int(t/dt/1.000001) + #print "i_t = " + str(i_t) + + zeta = (t - i_t*dt) / dt + #print "zeta = " + str(zeta) + + norm_z_end = farray_norm_z_end.GetTuple(num_cell)[0] + norm_z_epi = farray_norm_z_epi.GetTuple(num_cell)[0] + i_z_end = int(norm_z_end/dz/1.000001) + i_z_epi = int(norm_z_epi/dz/1.000001) + #print "i_z_end = " + str(i_z_end) + #print "i_z_epi = " + str(i_z_epi) + + eta_end = (norm_z_end - i_z_end*dz) / dz + eta_epi = (norm_z_epi - i_z_epi*dz) / dz + #print "eta_end = " + str(eta_end) + #print "eta_epi = " + str(eta_epi) + + t_ii_end = angles_end[i_z_end][i_t%nb_circ_nodes] + t_ji_end = angles_end[i_z_end][(i_t+1)%nb_circ_nodes] + t_ij_end = angles_end[(i_z_end+1)][i_t%nb_circ_nodes] + t_jj_end = angles_end[(i_z_end+1)][(i_t+1)%nb_circ_nodes] + t_ii_epi = angles_epi[i_z_epi][i_t%nb_circ_nodes] + t_ji_epi = angles_epi[i_z_epi][(i_t+1)%nb_circ_nodes] + t_ij_epi = angles_epi[(i_z_epi+1)][i_t%nb_circ_nodes] + t_jj_epi = angles_epi[(i_z_epi+1)][(i_t+1)%nb_circ_nodes] + #print "t_ii_end = " + str(t_ii_end) + #print "t_ji_end = " + str(t_ji_end) + #print "t_ij_end = " + str(t_ij_end) + #print "t_jj_end = " + str(t_jj_end) + #print "t_ii_epi = " + str(t_ii_epi) + #print "t_ji_epi = " + str(t_ji_epi) + #print "t_ij_epi = " + str(t_ij_epi) + #print "t_jj_epi = " + str(t_jj_epi) + + fiber_angle_end = t_ii_end * (1 - zeta - eta_end + zeta*eta_end) \ + + t_ji_end * (zeta - zeta*eta_end) \ + + t_ij_end * (eta_end - zeta*eta_end) \ + + t_jj_end * (zeta*eta_end) + fiber_angle_epi = t_ii_epi * (1 - zeta - eta_epi + zeta*eta_epi) \ + + t_ji_epi * (zeta - zeta*eta_epi) \ + + t_ij_epi * (eta_epi - zeta*eta_epi) \ + + t_jj_epi * (zeta*eta_epi) + + norm_dist_end = farray_norm_dist_end.GetTuple(num_cell)[0] + norm_dist_epi = farray_norm_dist_epi.GetTuple(num_cell)[0] + fiber_angle_in_degrees = (1.-norm_dist_end) * fiber_angle_end + (1.-norm_dist_epi) * fiber_angle_epi + if (sigma > 0.): fiber_angle_in_degrees *= random.normalvariate(1., sigma) + farray_fiber_angle.InsertTuple(num_cell, [fiber_angle_in_degrees]) + + eRR = numpy.array(farray_eRR.GetTuple(num_cell)) + eCC = numpy.array(farray_eCC.GetTuple(num_cell)) + eLL = numpy.array(farray_eLL.GetTuple(num_cell)) + + fiber_angle_in_radians = math.pi*fiber_angle_in_degrees/180 + eF = math.cos(fiber_angle_in_radians) * eCC + math.sin(fiber_angle_in_radians) * eLL + eS = eRR + eN = numpy.cross(eF, eS) + + farray_eF.InsertTuple(num_cell, eF) + farray_eS.InsertTuple(num_cell, eS) + farray_eN.InsertTuple(num_cell, eN) + + if (verbose): print "Filling mesh..." + + ugrid_wall.GetCellData().AddArray(farray_fiber_angle) + ugrid_wall.GetCellData().AddArray(farray_eF) + ugrid_wall.GetCellData().AddArray(farray_eS) + ugrid_wall.GetCellData().AddArray(farray_eN) diff --git a/vtk_py/addLocalFiberOrientation2.pyc b/vtk_py/addLocalFiberOrientation2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd8b2e00374ae7b8a67b6b92eccbbffa64a8b36b GIT binary patch literal 3826 zcmbtW+j1Mn5$#!kHxRsoBtTsZQYJK zozoWee?`3ih!#IX=i*P1PjoVr6`iO7ZqbP~kPCED7|2CBDT-{7KSfWO1=2JmxE4sy zl3S#2;W5YbPa0F0%KJZl#|;J1aJSn=C%@J-UcW=*_aR#R2Bc()qD6N9^s@ji02IAa zB3LXuw*-A2+nu5sEYn%~=3Qn>EZThZjG{Hi13KgDw!p6H+cV(D!nRDS`%cGv)xCw1gYkbD}vN= z$W{90Ucq3oAW`(_%iThHjglqmV5!#_;*v_Qlff#lQ&OUJcZ=3Jm2U`u9=luRfwWG^ z+JxhqlvF05ZQ;Ve%!uoTVB2HZ4ka+U!5H{qoZh4aCcuZtEh+LFR7()YEN#@%w{i$_ zvzeidKFY|*_U#FDWWUQN2Q!Uq-^n2(yWjNDao*ofpd3RrMKtW0dp zdz7qBK)2oRoZGIUiSd~cpKuHi#*9KVTvcXzk$xbEYy<@iV5sgC{}c{(tT z@xtJC9i#E*uyTU7uj8f;+`1zTYEz$k^=>aV^)u&%uE$PS*L@wd%~`z>oHqS1Xg7n< z)$!YV^@GzeGG5T$>wmZY`v;FdV;&mCzaLIe_r2J}zd+jZqSj?n&tjUp=(f*8FEDZQ z;Nf&RbMWvllHa2!>^=;8fg2wL?jg89vI3J&wK?u}xrm-+hWNH4CB5$XOOc!? za$cI*%u*~2|J#BX9ltHJar$JnpgPpP|Hwfp_8ktydwF~wHj43;A!xJ{1#!ihYvNC=+?oSczUD~!cChBtG!qA-qy`@nT& z$_D=)WcWKr210o}SmSHI;dME?uP)*bGWFS*IdByAGNAe2$3<=n0sIbpa z>0}C@_1yA>^b&UN*?gXDE?u)R;o${MSGOarW1Hi&Ie|7O{&kj-<9bdI+hsQ5OV8%J zq=A-o@kfyM&%&{tNTGdH!<$XFoc7xGZWQ_*nyvQ7x+#wXIgHvRbvSs|`HMYO7dM8wIvmS9rJ|G)QG@)ml|}thK_LsuWhy ziW=92Ji&9^X=Bs;M=rs_K1MC*PBovCTzq zZ*#|KmjXi)Y`#=&K0o#v!@N09qn@_^3SpE?k$!zfc~?K`hHlT-A4^<(a>_`ZJXT4S JW(umHegb2tMtJ}L literal 0 HcmV?d00001 diff --git a/vtk_py/addLocalFiberOrientation_infarct.py b/vtk_py/addLocalFiberOrientation_infarct.py new file mode 100644 index 0000000..1718f5b --- /dev/null +++ b/vtk_py/addLocalFiberOrientation_infarct.py @@ -0,0 +1,98 @@ +######################################################################## + +import sys +import math +import numpy +import vtk + +from addLocalFiberOrientation import * +from addLocalProlateSpheroidalDirections import * +from createFloatArray import * +from getABPointsFromBoundsAndCenter import * +from readSTL import * +from readUGrid import * +from writeUGrid import * + +######################################################################## + +def addLocalFiberOrientation_infarct(ugrid_wall, + fiber_angle_end, + fiber_angle_epi, + inf_fiber_angle_end, + inf_fiber_angle_epi, + matid, + points_AB=None, + verbose=True): + + if (verbose): print '*** addLocalFiberOrientation with infarct ***' + + if (points_AB == None): + points_AB = getABPointsFromBoundsAndCenter(ugrid_wall, verbose) + assert (points_AB.GetNumberOfPoints() >= 2), "\"points_AB\" must have at least two points. Aborting." + point_A = numpy.array([0.]*3) + point_B = numpy.array([0.]*3) + points_AB.GetPoint( 0, point_A) + points_AB.GetPoint(points_AB.GetNumberOfPoints()-1, point_B) + eL = point_B - point_A + eL /= numpy.linalg.norm(eL) + + if (verbose): print "Computing local fiber orientation..." + + farray_norm_dist_end = ugrid_wall.GetCellData().GetArray("norm_dist_end") + farray_norm_dist_epi = ugrid_wall.GetCellData().GetArray("norm_dist_epi") + farray_eRR = ugrid_wall.GetCellData().GetArray("eRR") + farray_eCC = ugrid_wall.GetCellData().GetArray("eCC") + farray_eLL = ugrid_wall.GetCellData().GetArray("eLL") + + nb_cells = ugrid_wall.GetNumberOfCells() + + farray_fiber_angle = createFloatArray("fiber_angle", 1, nb_cells) + + farray_eF = createFloatArray("fiber vectors", 3, nb_cells) + farray_eS = createFloatArray("sheet vectors", 3, nb_cells) + farray_eN = createFloatArray("sheet normal vectors", 3, nb_cells) + matid_data = createFloatArray("matid", 1, nb_cells) + + for num_cell in range(nb_cells): + norm_dist_end = farray_norm_dist_end.GetTuple(num_cell)[0] + norm_dist_epi = farray_norm_dist_epi.GetTuple(num_cell)[0] + + matid_data.InsertTuple(num_cell, [matid[num_cell]]) + if(matid[num_cell] == 1): + fiber_angle_in_degrees = (1.-norm_dist_end) * fiber_angle_end + (1.-norm_dist_epi) * fiber_angle_epi + else: + fiber_angle_in_degrees = (1.-norm_dist_end) * inf_fiber_angle_end + (1.-norm_dist_epi) * inf_fiber_angle_epi + + farray_fiber_angle.InsertTuple(num_cell, [fiber_angle_in_degrees]) + + eRR = numpy.array(farray_eRR.GetTuple(num_cell)) + eCC = numpy.array(farray_eCC.GetTuple(num_cell)) + eLL = numpy.array(farray_eLL.GetTuple(num_cell)) + + fiber_angle_in_radians = math.pi*fiber_angle_in_degrees/180 + eF = math.cos(fiber_angle_in_radians) * eCC + math.sin(fiber_angle_in_radians) * eLL + eS = eRR + eN = numpy.cross(eF, eS) + farray_eF.InsertTuple(num_cell, eF) + farray_eS.InsertTuple(num_cell, eS) + farray_eN.InsertTuple(num_cell, eN) + + if (verbose): print "Filling mesh..." + + ugrid_wall.GetCellData().AddArray(farray_fiber_angle) + ugrid_wall.GetCellData().AddArray(farray_eF) + ugrid_wall.GetCellData().AddArray(farray_eS) + ugrid_wall.GetCellData().AddArray(farray_eN) + ugrid_wall.GetCellData().AddArray(matid_data) + +if (__name__ == "__main__"): + assert (len(sys.argv) in [4]), "Number of arguments must be 3. Aborting." + basename = sys.argv[1] + ugrid_wall = readUGrid(basename + "-Mesh.vtk") + pdata_end = readSTL(basename + "-End.stl") + pdata_epi = readSTL(basename + "-Epi.stl") + angle_end = float(sys.argv[2]) + angle_epi = float(sys.argv[3]) + addLocalProlateSpheroidalDirections(ugrid_wall, pdata_end, pdata_epi) + addLocalFiberOrientation(ugrid_wall, angle_end, angle_epi) + writeUGrid(ugrid_wall, basename + "-Mesh.vtk") diff --git a/vtk_py/addLocalFiberOrientation_infarct.pyc b/vtk_py/addLocalFiberOrientation_infarct.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51b30e72d6de74a6487c9a5155d4195bb94ead84 GIT binary patch literal 3245 zcmb_e-A)@<5T0FwF~$Ti<~Ir1q`5#*0~hH{tEwp>AxTAOw4|zpRIS$DgIQSbx_geH zk=7S&`UriBURHgMzC+)jQXioGW{z!4e$<7D-ivpSFBs$X6}DL~41cKSOJ*vN8tMEVN2$k`!z~eTm+b$War*Lw42jRpAE* zyX2%2#ly{O2y6Tgeg~U~Eg4?!wJKO|)_?Wc{ z*?;3wzf5-b)TK8P@UuzMUy(s3N`ruy2|AtR0JagaNowF){R+Jgo#t~+aa5U#3cyR=_y{p+(f6Cxa3~2&bq(wUns8AjljCVSv;HnIA(I1wlEDWEz4X zmm@n%^h4J%@JfpC@pnz9zf8ppox-PO_5<-->#tBzdkb2nVu?=SB*bBVnbwdJ3A5#J z1gCi2jTWg`L8u*SFu4lSrN&BsjnZ`*Zk8@LC+udiFtonL$!5zo&Bg4cCmj3rLHdhp zSMlpZeC{fKgUmdgE>N+CGaIzjzbQbSikp1j;yN{00Ipj82K%!?#X9wGiOB{PU~jQY zeUFOz(9aEf{ly_K5>C+=@}BH}|Eu#Y*V9HRT6(*lmI$|o56)#Z0jj?XExrpi-i6T6 zu!UYb++0R09_ag6@7=rSg;BJhwZddCZmRt2JXWa*O`N6PMQl#II6V&Ymhm7NyWGN` zV7b%H;?(G1=g}Rn)6>Q~3D1=m8ZS{HICGJCR$|NBX=b^J)Am*ydh&}g11M%P<|(1? zV%g0)-5!g13A^GQvoBtD>CD#F7V45H&GJqV#o7cajowDOF{T5N@_qZ=-L>ESeKP}G zj0R!aPLyU__KU9$()}N>BrRDkF2-Jz;${A#*m1)U} zMg_5%R-S1sW_F@TtZ(w43{%C@Yv*wkT!cwtIJRR6l=Q!Y;fO`Zp=N`(W#5Z;V}FXz zn#N)a7A0*MI#+o!(@JRB33kTlM{*&xZ@5Iz9|(PLwKCto0sr_~0}ZazaTet|&Z25L zJ83g$Nh0c(nq!v}--ibGu5gD}xC1dRWgA4p)T4gHy3d{HbCwJbhcWv>oCc9<=Spdx zo6F~%`kc7;N#k$@a6|7u)CN zEa<-8{?J&0Lo$)JQ1~9~{FfYuO*gU7beSq{&8a&Z&N7~PXWgkf%Pyl!&fsxtZr!az z29LYw;Bi+VdDC5Y7u{6{kGtU9b;{VE$I}pPk%O${D+oFvViv?4D9!h^{p4lGUYNIg z9kjW&Q?seO2V)b`jzg}+`!9HUAP|}>;Qo^|+R`Q&Fx{9L8OAb7&(m5&nxR%KX2{qc_)i{iTZ+@L~miKIr6ww XRN3gMmYmwdnseKkmHL_I3KQyI52w?} literal 0 HcmV?d00001 diff --git a/vtk_py/addLocalProlateSpheroidalDirections.py b/vtk_py/addLocalProlateSpheroidalDirections.py new file mode 100644 index 0000000..4fe7121 --- /dev/null +++ b/vtk_py/addLocalProlateSpheroidalDirections.py @@ -0,0 +1,161 @@ +######################################################################## + +import sys +import math +import numpy +import vtk + +from createFloatArray import * +from getABPointsFromBoundsAndCenter import * +from getCellCenters import * +from getPDataNormals import * +from writePData import * + +######################################################################## + +def addLocalProlateSpheroidalDirections(ugrid_wall, + pdata_end, + pdata_epi, + type_of_support="cell", + epiflip=False, + endoflip=False, + apexflip=False, + points_AB=None, + eCCname="eCC", + eLLname="eLL", + eRRname="eRR", + verbose=True): + + if (verbose): print '*** addLocalProlateSpheroidalDirections ***' + + if (points_AB == None): + points_AB = getABPointsFromBoundsAndCenter(pdata_epi, verbose) + assert (points_AB.GetNumberOfPoints() == 2), "points_AB must have two points. Aborting." + point_A = numpy.array([0.]*3) + point_B = numpy.array([0.]*3) + points_AB.GetPoint(0, point_A) + points_AB.GetPoint(1, point_B) + if(apexflip): + eL = point_A - point_B + else: + eL = point_B - point_A + eL /= numpy.linalg.norm(eL) + + if (type_of_support == "cell"): + pdata_cell_centers = getCellCenters(ugrid_wall) + + if (verbose): print "Computing cell normals..." + + if(epiflip): + pdata_epi = getPDataNormals(pdata_epi, flip=1) + else: + pdata_epi = getPDataNormals(pdata_epi, flip=0) + + if(endoflip): + pdata_end = getPDataNormals(pdata_end, flip=1) + else: + pdata_end = getPDataNormals(pdata_end, flip=0) + + if (verbose): print "Computing surface bounds..." + + bounds_end = pdata_end.GetBounds() + bounds_epi = pdata_epi.GetBounds() + z_min_end = bounds_end[4] + z_min_epi = bounds_epi[4] + z_max_end = bounds_end[5] + z_max_epi = bounds_epi[5] + L_end = z_max_end-z_min_end + L_epi = z_max_epi-z_min_epi + + if (verbose): print "Initializing cell locators..." + + cell_locator_end = vtk.vtkCellLocator() + cell_locator_end.SetDataSet(pdata_end) + cell_locator_end.Update() + + cell_locator_epi = vtk.vtkCellLocator() + cell_locator_epi.SetDataSet(pdata_epi) + cell_locator_epi.Update() + + closest_point_end = [0.]*3 + closest_point_epi = [0.]*3 + generic_cell = vtk.vtkGenericCell() + cellId_end = vtk.mutable(0) + cellId_epi = vtk.mutable(0) + subId = vtk.mutable(0) + dist_end = vtk.mutable(0.) + dist_epi = vtk.mutable(0.) + + if (verbose): print "Computing local prolate spheroidal directions..." + + if (type_of_support == "cell"): + nb_cells = ugrid_wall.GetNumberOfCells() + elif (type_of_support == "point"): + nb_cells = ugrid_wall.GetNumberOfPoints() + + farray_norm_dist_end = createFloatArray("norm_dist_end", 1, nb_cells) + farray_norm_dist_epi = createFloatArray("norm_dist_epi", 1, nb_cells) + + farray_norm_z_end = createFloatArray("norm_z_end", 1, nb_cells) + farray_norm_z_epi = createFloatArray("norm_z_epi", 1, nb_cells) + + farray_eRR = createFloatArray(eRRname, 3, nb_cells) + farray_eCC = createFloatArray(eCCname, 3, nb_cells) + farray_eLL = createFloatArray(eLLname, 3, nb_cells) + + for num_cell in range(nb_cells): + if (type_of_support == "cell"): + cell_center = numpy.array(pdata_cell_centers.GetPoints().GetPoint(num_cell)) + elif (type_of_support == "point"): + cell_center = numpy.array(ugrid_wall.GetPoints().GetPoint(num_cell)) + cell_locator_end.FindClosestPoint(cell_center, closest_point_end, generic_cell, cellId_end, subId, dist_end) + cell_locator_epi.FindClosestPoint(cell_center, closest_point_epi, generic_cell, cellId_epi, subId, dist_epi) + + norm_dist_end = dist_end/(dist_end+dist_epi) + norm_dist_epi = dist_epi/(dist_end+dist_epi) + farray_norm_dist_end.InsertTuple(num_cell, [norm_dist_end]) + farray_norm_dist_epi.InsertTuple(num_cell, [norm_dist_epi]) + + norm_z_end = (closest_point_end[2]-z_min_end)/L_end + norm_z_epi = (closest_point_epi[2]-z_min_epi)/L_epi + farray_norm_z_end.InsertTuple(num_cell, [norm_z_end]) + farray_norm_z_epi.InsertTuple(num_cell, [norm_z_epi]) + + normal_end = numpy.reshape(pdata_end.GetCellData().GetNormals().GetTuple(cellId_end), (3)) + normal_epi = numpy.reshape(pdata_epi.GetCellData().GetNormals().GetTuple(cellId_epi), (3)) + eRR = -1*(1.-norm_dist_end) * normal_end + (1.-norm_dist_epi) * normal_epi + eRR /= numpy.linalg.norm(eRR) + eCC = numpy.cross(eL, eRR) + eCC /= numpy.linalg.norm(eCC) + eLL = numpy.cross(eRR, eCC) + farray_eRR.InsertTuple(num_cell, eRR) + farray_eCC.InsertTuple(num_cell, eCC) + farray_eLL.InsertTuple(num_cell, eLL) + + if (verbose): print "Filling mesh..." + + if (type_of_support == "cell"): + ugrid_wall.GetCellData().AddArray(farray_norm_dist_end) + ugrid_wall.GetCellData().AddArray(farray_norm_dist_epi) + ugrid_wall.GetCellData().AddArray(farray_norm_z_end) + ugrid_wall.GetCellData().AddArray(farray_norm_z_epi) + ugrid_wall.GetCellData().AddArray(farray_eRR) + ugrid_wall.GetCellData().AddArray(farray_eCC) + ugrid_wall.GetCellData().AddArray(farray_eLL) + elif (type_of_support == "point"): + ugrid_wall.GetPointData().AddArray(farray_norm_dist_end) + ugrid_wall.GetPointData().AddArray(farray_norm_dist_epi) + ugrid_wall.GetPointData().AddArray(farray_norm_z_end) + ugrid_wall.GetPointData().AddArray(farray_norm_z_epi) + ugrid_wall.GetPointData().AddArray(farray_eRR) + ugrid_wall.GetPointData().AddArray(farray_eCC) + ugrid_wall.GetPointData().AddArray(farray_eLL) + +if (__name__ == "__main__"): + assert (len(sys.argv) in [2]), "Number of arguments must be 1. Aborting." + basename = sys.argv[1] + ugrid_wall = readUGrid(basename + "-Mesh.vtk") + pdata_end = readSTL(basename + "-End.stl") + pdata_epi = readSTL(basename + "-Epi.stl") + addLocalProlateSpheroidalDirections(ugrid_wall, pdata_end, pdata_epi) + writeUGrid(ugrid_wall, basename + "-Mesh.vtk") diff --git a/vtk_py/addLocalProlateSpheroidalDirections.pyc b/vtk_py/addLocalProlateSpheroidalDirections.pyc new file mode 100644 index 0000000000000000000000000000000000000000..476a4b95c148285c37448ea7e71d7da7883b7d9d GIT binary patch literal 4525 zcmb_fNpIZ96@Fw(t;OAv+}gd!?eQX6*5YMyF@hwLJo0#;(HN8m2?PWUs#%gKv&jyN zZCeH#L82UU$YG8-<(6{}x#U;m9|V{m5G0q}lJC7D+1-{8bBHJw-}~OHs<+kBrGHn) zzx&72qb6m4bcqg2LfaG!(QEDrYPg`v1vOGo zqo7Kp#3d4X zC?ytjC&g~~_%HItG9QO1u38C3MEQ(!qAx6~Yg1UG9$3!6beQ62q70`BWh+-UpixG+ zFwdcd?3-9xbcWy&b*Ff$jJ`@K>ZL-9-5RBm+Qsg)U{zoq}qvI&tSI z8UKdRFqd7W?#)4VX^_2@vqPd>A7pQf6Th*seoUB(y#3Ke(#~o!;b#AM$|S zFWCvQgQ+cg{>v%5yV_TNosy~fbdt_y*%?%Ny2`2?x`!05_c`{bTp4PgRK}V_GEoB$ zDZNJN4N7lPdW+IJU6f50jSSI(Y)NFdjjYaE>1~>y?XK~+;9$TVIzu(V>@{AlvIOtu z(0T!(9&B3VDop2Sw!1;;b%UT9(|I79l-|p`Z4}+^=g?*jaYRs~SP_d7k!#Yz=9?T8 zgrE1AN3yJ;hQ;!c+ESm|WAbLngV$@cFq1x_8K&1^&|{jJ?>?dQN#FMHggZV1$`&9% zSR#Nh*;7iN_USz}dIo|Xh5-b<&naEb-I1PFx{~vvVWkgp{&NZBueM7+=bgYC_U1n> z@&62Si5usT$2&Z$H2~ec4Bfj7-MTRWO$F4msepPm z6;RKn0_xdRKs}oZD6>fp`Gb`OoJ{-rA==f|)w=6>dr{L3Ud2)1ChDMls^ZA^+~Bz% zt7hUyp{_&ExA{DKfTkV!VWJyb+x1pQC-qbJt*R&QqPoF1>RU%qocQ6%#tD?=&oANQ zGwJg|>TshM(d6Sf-AtLJXw?wf?+G9cp^+vGO%HhCkR z@#W53VaS4n=RhUg7ay7O+qQ?Y%avcKP{n?e`y?Y6wbe=7qd?&XIN&DBwSdi7q5EzS zxyhFJ#D2zZ2op1_vXJlyyFTI;L|W<0=PLkTh8(BYoi?W7DPyFzj}RWw zZ*%X)Rv*2c@Ft-4l3HPM6VYijr4+R|W>#iV{5cC>*rE@OmLC>=W?WC^zVDYY2N}n9 zPwteav*j(~%OEs)eKbwV8^$AExSv3w%jr5X1qh#z8eYCky!2#(el{~qcaC0q zl7?ba;KDErbeIW`WHgNn4K_7dd5yt+G-_9@nzdxj;hDly zwyO5HH3xLkW@*`)wQG4R+7)ZO_lQo#s#@dd!EF^S`sPn2pJdFgS+)EHH4W^xyf>^H z_JlQIO zP78}so1^(i)gSkr$8z{;PU-sBeB2=XnzOwAMd)qlB*>Vy&y4);l{w_TAe*{A*K#zp z+~m~Zt;w0^hEFMn*N($=?98H(a(Nf~iIQ_d*6=QlcI9xb$sn)ej&gp%9NW-n@E+7? z$UFgD;EIAfZyi3$MCHiUN;WF?0K2~T?F;Oo&MM2zzU_JkulJmX0Gu^Oxp2h@(d<>F sQ2)=;WDkDaio8yse!>etKS5JL_VA$IvS*}Z4L+4$bB$Cb|6HB_1MbY@IRF3v literal 0 HcmV?d00001 diff --git a/vtk_py/addMappingFromPointsToCells.py b/vtk_py/addMappingFromPointsToCells.py new file mode 100644 index 0000000..c1c336f --- /dev/null +++ b/vtk_py/addMappingFromPointsToCells.py @@ -0,0 +1,43 @@ +######################################################################## + +import sys +import math +import numpy +import vtk + +from createIntArray import * + +######################################################################## + +def addMappingFromPointsToCells(ugrid_points, ugrid_cells, verbose=True): + + if (verbose): print '*** addMappingFromPointsToCells ***' + + nb_points = ugrid_points.GetNumberOfPoints() + nb_cells = ugrid_cells.GetNumberOfCells() + print "nb_points = " + str(nb_points) + print "nb_cells = " + str(nb_cells) + + cell_locator = vtk.vtkCellLocator() + cell_locator.SetDataSet(ugrid_cells) + cell_locator.Update() + + closest_point = [0.]*3 + generic_cell = vtk.vtkGenericCell() + num_cell = vtk.mutable(0) + subId = vtk.mutable(0) + dist = vtk.mutable(0.) + + iarray_num_cell = createIntArray("num_cell", 1, nb_points) + + for num_point in range(nb_points): + point = ugrid_points.GetPoint(num_point) + + cell_locator.FindClosestPoint(point, closest_point, generic_cell, num_cell, subId, dist) + #num_cell = cell_locator.FindCell(point) + + iarray_num_cell.InsertTuple(num_point, [num_cell]) + #print "num_point = " + str(num_point) + #print "num_cell = " + str(num_cell) + + ugrid_points.GetPointData().AddArray(iarray_num_cell) diff --git a/vtk_py/addMappingFromPointsToCells.pyc b/vtk_py/addMappingFromPointsToCells.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c0c6be520d9730bee2609fef1ca0c8f0f62a659 GIT binary patch literal 1337 zcmb_b&2G~`5FXq4|7rM>dH{(?T%sV616Nv6rD|G43rd5KBB99fE~$fK2k)jLQgRB9 zz+>?eJOd8^-;5I|m!8;UXXk&vnOS>3>y>Xmo{t0CE*IxZZ1W04;qOpHH2lLmG<0@) zmxk_+_h{$|?^2YbfzFfi=qtPnoZ_;TL%Q%6)dnME-}1~OU~!-^q#x0$M~iVf(uuI;as-L zXxfE&0@`l3o4!)#{(K(Blan-=y-mW{nnBXlQDmC1n;QJ$@n|lF=0Vd`GesaC2h9mY zS)qp`WY+R%;>B#lJ|R!7b%)h=L3-L=EM{Y!zWJElW!ZE?D>tLH7_3d@ytbb#4;&{O zUnhZYlN9|zG1?yc*2iHB5Z}#}Z}rZ(r(>Ol0ms-Pth0sn$5CbuQVq|u*dC>+zqEOn zQ$L<)feti+O`x5GvFb*N(PpdU`p;scQ#)A9k&YX*i(oL4;z%jU++yJ3vY4cy+P2Yh zj!eNVG6L^fr(;}$$8n?KSu4lVNh5hUU=(e8P={}jfy+{h%OopYg8K61aD8SmK2w&z zDHR%P8(>18s~_z~m0gXw$*`pvKtvNNP;WTj8or+t}B*^#N`=F1!{alM@n?0DNk@{x7 wy%O{&Y`*Ms@qO;N7zgP>_a8(0Th)Int%S5MW{Fxv`cPglzfrCLKev+m4Moi|7XSbN literal 0 HcmV?d00001 diff --git a/vtk_py/addSystolicStrains.py b/vtk_py/addSystolicStrains.py new file mode 100644 index 0000000..32d6b48 --- /dev/null +++ b/vtk_py/addSystolicStrains.py @@ -0,0 +1,50 @@ +######################################################################## + +import numpy +import vtk + +from mat_vec_tools import * +from createFloatArray import * + +######################################################################## + +def addSystolicStrains(mesh, verbose=True): + + if (verbose): print '*** addSystolicStrains ***' + + nb_cells = mesh.GetNumberOfCells() + + farray_F_dia = mesh.GetCellData().GetArray('F_dia') + farray_F_sys = mesh.GetCellData().GetArray('F_sys') + + farray_E_dia = createFloatArray('E_dia', 6, nb_cells) + farray_E_sys = createFloatArray('E_sys', 6, nb_cells) + farray_F_num = createFloatArray('F_num', 9, nb_cells) + farray_E_num = createFloatArray('E_num', 6, nb_cells) + + for num_cell in range(nb_cells): + F_dia = numpy.reshape(farray_F_dia.GetTuple(num_cell), (3,3), order='C') + F_sys = numpy.reshape(farray_F_sys.GetTuple(num_cell), (3,3), order='C') + #print 'F_dia =', F_dia + #print 'F_sys =', F_sys + + C = numpy.dot(numpy.transpose(F_dia), F_dia) + E = (C - numpy.eye(3))/2 + farray_E_dia.InsertTuple(num_cell, mat_sym_to_vec_col(E)) + + C = numpy.dot(numpy.transpose(F_sys), F_sys) + E = (C - numpy.eye(3))/2 + farray_E_sys.InsertTuple(num_cell, mat_sym_to_vec_col(E)) + + F = numpy.dot(F_sys, numpy.linalg.inv(F_dia)) + farray_F_num.InsertTuple(num_cell, numpy.reshape(F, 9, order='C')) + #print 'F =', F + + C = numpy.dot(numpy.transpose(F), F) + E = (C - numpy.eye(3))/2 + farray_E_num.InsertTuple(num_cell, mat_sym_to_vec_col(E)) + + mesh.GetCellData().AddArray(farray_E_dia) + mesh.GetCellData().AddArray(farray_E_sys) + mesh.GetCellData().AddArray(farray_F_num) + mesh.GetCellData().AddArray(farray_E_num) diff --git a/vtk_py/addSystolicStrains.pyc b/vtk_py/addSystolicStrains.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd6442d8fdc5b4c814079d25df47eac7653bf26d GIT binary patch literal 1601 zcmbtU&2G~`5T3R32Xa7gst{G$v>aNbBob03WE}6db#Uz9-9$uk zPUR7}@OV4}4*)acq)i&p3voP|`F3{Zo0;9%ziZ_mzh3oyn13w%eTT2!MJZj8a~C}#Mi;Mg|9wEBo&Zs z(5~Z?2rYmCz%{_kVqK6vuqe^BfSJ7t+6?Bv*dUQY9#V9(VU}m4u!IyCDS~tsK1D`K zOFj;Ki-gIsgMhMCJ%!Gq&5tSkd`Q)M79->Rk*gqth{i@Ejes1IaJueVOfH- zOc6+0FsnjZWxNcM@h7qd+p`*^n6pCJ47${42f7PlaucV*aZuhHr||DMX-2FDgN->W z3Wa)cu_r4Wi*;_xS>v(6JW$@t!&$^!uIKAd_(1d= zyFjMBFyln3gpYVDpd(%0n@Tf31o5Tu0eP052E~~&D4<68}2R0*1IUaJ(4*dspXfz#S!t**} z*{-7vEc9#Cnpg2qHA6pCs@YLmd5M43JZYUaC+3Sgnl{%@)k|zU^=o~FMylVS0IL9w zRkgOowzVbru^x&&v6p))9*aj-CZCDtHfcM!Mo*pE-Pu6F-9`eYh6c@r24dnk)E(*+ lx4f5(Rp$j-w*~!gRSrhmAI5SVs<(80GyzpnwaTKL`wLQ>MhyS} literal 0 HcmV?d00001 diff --git a/vtk_py/clean_pdata.py b/vtk_py/clean_pdata.py new file mode 100644 index 0000000..34d34b6 --- /dev/null +++ b/vtk_py/clean_pdata.py @@ -0,0 +1,22 @@ +######################################################################## + +import sys +import vtk + +from mat_vec_tools import * + +######################################################################## + +def clean_pdata(pdata): + + cleanpdata = vtk.vtkCleanPolyData() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + cleanpdata.SetInputData(pdata) + else: + cleanpdata.SetInput(pdata) + cleanpdata.Update() + + return cleanpdata.GetOutput() + + + diff --git a/vtk_py/clean_pdata.pyc b/vtk_py/clean_pdata.pyc new file mode 100644 index 0000000000000000000000000000000000000000..48e993daaf8327ca39be958aae98430bf237d55e GIT binary patch literal 604 zcmbVJ%}T>S5T4z%wZ;UB;5!5l4dPWqsGuUPlGYx22{Bn{(=-X$X(3Qg^$~nQpTP&v znT=J?E<4}OeDk}z)`x4qy`MkF@Vz9RS0vgeNN5Yl0A@eBfSEA7giOLDvEY^57RQaf z7Ue8HX^lKVDl(kLj9ivwK%xTz1V{z!0A7UAC8QRcRAI}95(iUt1b^=818oRx> z+1cT6!P)_9V~^{P79B#b%N;C&4KA_QoP$h7`D2mQ*AYf&H{?`RdQs$fOy-Tk>EwPG zrA4);9iqny@A7huCXEa43FKB!WfGyn!zTY>jTC7n!8TFsY= 6): + clip.SetInputData(domain) + else: + clip.SetInput(domain) + clip.Update() + clipped0 = clip.GetOutput(0) + clipped1 = clip.GetOutput(1) + + if (clipped0.GetNumberOfPoints() > clipped1.GetNumberOfPoints()): + return clipped0 + else: + return clipped1 diff --git a/vtk_py/clipDomainForCutLVMesh.pyc b/vtk_py/clipDomainForCutLVMesh.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a94d0b632d56fdce6d0b4e2179b18a88d3543cb0 GIT binary patch literal 1012 zcmb_bOODe(5UqBc&zN`uNPJdk#LCJ7^I0Jwgp|=_5agpIWHFn_u^VE?v90cQq)5&R zj=;58asbZ20idcf0i@Ytxu5G*zpC!4Zr6Ug&etC=mLXg}7JlF0(9aPfdLw`r8YM@Rjs(+cG5+D)q z8DMWiWkX^?g;anbQiIB3LMoe8b*So)AR;9dk_Jr(k~AS{5s55V*FjaRJ%I{Xo4L%L zBd6F~97|T4D#Dce2CIlsr`e~R- z=})AVfeKgtWpChPUl+yBryMs==1H+L_pg__IZK_=j}gFXK+9?iSGbIhxF>E~u5d(0 zbgYNMw)h_KdFq{>@UP%v+$J!Ktqd0?&r@xvsF^C|gpTL${{Kf2EzJ08lSgGLU(>D9 LbV6;>wjBF6Ks4iR literal 0 HcmV?d00001 diff --git a/vtk_py/clipSurfacesForCutLVMesh.py b/vtk_py/clipSurfacesForCutLVMesh.py new file mode 100644 index 0000000..e207c7c --- /dev/null +++ b/vtk_py/clipSurfacesForCutLVMesh.py @@ -0,0 +1,59 @@ +######################################################################## + +import sys +import vtk + +from mat_vec_tools import * +from readSTL import * +from writeSTL import * + +######################################################################## + +def clipSurfacesForCutLVMesh(endo, epi, height, direction=-1, verbose=True): + + if (verbose): print '*** clipSurfacesForCutLVMesh ***' + + plane = vtk.vtkPlane() + plane.SetNormal(0,0,direction) + plane.SetOrigin(0,0,height) + + clip = vtk.vtkClipPolyData() + clip.SetClipFunction(plane) + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + clip.SetInputData(endo) + else: + clip.SetInput(endo) + clip.Update() + clipped_endo = clip.GetOutput(0) + + clip = vtk.vtkClipPolyData() + clip.SetClipFunction(plane) + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + clip.SetInputData(epi) + else: + clip.SetInput(epi) + clip.Update() + clipped_epi = clip.GetOutput(0) + + return clipped_endo, clipped_epi + +if (__name__ == "__main__"): + assert (len(sys.argv) in [3,4]), 'Number of arguments must be 2 or 3.' + if (len(sys.argv) == 3): + endo_filename = sys.argv[1] + '-EndoLV.stl' + epi_filename = sys.argv[1] + '-EpiLV.stl' + clipped_endo_filename = sys.argv[1] + '_CutLV-Endo.stl' + clipped_epi_filename = sys.argv[1] + '_CutLV-Epi.stl' + height = float(sys.argv[2]) + elif (len(sys.argv) == 4): + endo_filename = sys.argv[1] + epi_filename = sys.argv[2] + clipped_endo_filename = 'clipped_endo.stl' + clipped_epi_filename = 'clipped_epi.stl' + height = float(sys.argv[3]) + endo = readSTL(endo_filename) + epi = readSTL(epi_filename) + clipped_endo, clipped_epi = clipSurfacesForCutLVMesh(endo, epi, height) + writeSTL(clipped_endo, clipped_endo_filename) + writeSTL(clipped_epi, clipped_epi_filename) + diff --git a/vtk_py/clipSurfacesForCutLVMesh.pyc b/vtk_py/clipSurfacesForCutLVMesh.pyc new file mode 100644 index 0000000000000000000000000000000000000000..076e0d1bc944d1aeee8e9e4de67bde6ce0f52996 GIT binary patch literal 1831 zcmb_bTW=Fr5T3K^TWqiGBoILA!y;a+NW>L9wyIi%09BJf?T`nn(rV)!$0ymF&N-VZ zk^zbIC-e`}ztA5*XO1ti5lDT&m+{QE-`vOUzh3?Ck5A7=Fn^Wk_hg@VFj=XQ3);`Q11oS00AyGfTBkoxU7IyVCoQ6 z8TlY!jZn5;ALlMn4IV@raBtXH1?mJeSAhlr-YU=}pas}oU>-c6T*D5ezptmO*mO_C ztU^wAn~Iz$P1FL49kpRCV0jr30A0Wa_cGkHdeiD#fHVg}Na?_h3xCjLwqbY&umrdb z=)sKxf(?RN)=2H_2i;9thWtdY<1TFk42#`SndAn2d0qST)mwy5OQ2f3u@^7N+t8o| z+yJ~S!?X++4sVJ+QJivpx#+V4W_^y ziqy0A#=>UzI@1Mf4bDTfw^du!|IP8wA_ujxmSbjrB?r}1g=r1O4h*_HpJVNl+}+*v zN3qNYg&Kz=)Xy`uUzo$wBh(Y09!lbXtdQt7Nf?*JmAN#v+3)K(OwsVj2WXBnm4xxa zdZpyKOig=6+@~C`v-tX1XhMq-pRwmfIx;d#>Dq1JQ&gJGEizxAIX(I9D7?tj0_GaX z^Vc*lj19$gEC9o0zR9D|%t|8vSA`*FmkTu9G^SBzd%#>;`UK_q#Mqi6sc=?Hm6%tk z&N7XLPb#-vvOkZ?a1pHJ7zH+9V-?6{mrSri|3F%Ak|o%SM=@frj~YWYn)F`oAN6RC zL4MuiP+uDVUVd%v&m({7IhUbr8m9s^rzy6@Hc3z16&=SDbU0WzWw)mge0K}u5c8X zEQ___6)Fs)!O5X*`%fhevcVmnr~>;t9EHy(2+}aYAh020>YOPwg)75_|DrW2zR&}u zGG#au?>rbwqLQDz2D+wOfXiEUutvSJ`efCGk8B)gq3Lt`eNNKn3%`>U22uQv186cu0q|Ie+hv?$NtK?;Sxrai6UJ04H#UB>(^b literal 0 HcmV?d00001 diff --git a/vtk_py/clipSurfacesForCutLVMesh_PLY.py b/vtk_py/clipSurfacesForCutLVMesh_PLY.py new file mode 100644 index 0000000..c21bdfb --- /dev/null +++ b/vtk_py/clipSurfacesForCutLVMesh_PLY.py @@ -0,0 +1,59 @@ +######################################################################## + +import sys +import vtk + +from mat_vec_tools import * +from readPLY import * +from writeSTL import * + +######################################################################## + +def clipSurfacesForCutLVMesh_PLY(endo, epi, height, verbose=True): + + if (verbose): print '*** clipSurfacesForCutLVMesh ***' + + plane = vtk.vtkPlane() + plane.SetNormal(0,0,-1) + plane.SetOrigin(0,0,height) + + clip = vtk.vtkClipPolyData() + clip.SetClipFunction(plane) + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + clip.SetInputData(endo) + else: + clip.SetInput(endo) + clip.Update() + clipped_endo = clip.GetOutput(0) + + clip = vtk.vtkClipPolyData() + clip.SetClipFunction(plane) + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + clip.SetInputData(epi) + else: + clip.SetInput(epi) + clip.Update() + clipped_epi = clip.GetOutput(0) + + return clipped_endo, clipped_epi + +if (__name__ == "__main__"): + assert (len(sys.argv) in [3,4]), 'Number of arguments must be 2 or 3.' + if (len(sys.argv) == 3): + endo_filename = sys.argv[1] + epi_filename = sys.argv[1] + clipped_endo_filename = sys.argv[1] + '_CutLV-Endo.ply' + clipped_epi_filename = sys.argv[1] + '_CutLV-Epi.ply' + height = float(sys.argv[2]) + elif (len(sys.argv) == 4): + endo_filename = sys.argv[1] + epi_filename = sys.argv[2] + clipped_endo_filename = 'clipped_endo.stl' + clipped_epi_filename = 'clipped_epi.stl' + height = float(sys.argv[3]) + endo = readPLY(endo_filename) + epi = readPLY(epi_filename) + clipped_endo, clipped_epi = clipSurfacesForCutLVMesh(endo, epi, height) + writeSTL(clipped_endo, clipped_endo_filename) + writeSTL(clipped_epi, clipped_epi_filename) + diff --git a/vtk_py/clipSurfacesForCutLVMesh_PLY.pyc b/vtk_py/clipSurfacesForCutLVMesh_PLY.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a45e36b417e2b5e56342f8b0dfbe567b714b2fed GIT binary patch literal 1821 zcmb_bTW{l35T0WvPMX+hx0hvC+6N;Zh$_(__7!na*$blWmLybK3(0chN#oQvopW4> zl;wf)6Zmbs!(ZSBz|3iqCWuNrki_Ge?|gGPGZXtyul4Ki&o4)?_|)kA1wHCV0T9zq zKnf77bOC`dxCN;NLuQa>ue2Hru@12fzYx;_Y(QLtYYU_n*aQTaZow@@=)koDssP=B zxWUNJ0yYSByLN!w21Mnn3awea^Zx2GA@HM?9M*J^VhVN9__mw?TGzOs`&(x26UQxCMAu zgLw_67LSL2Hdi1RvKP?YG7x*zj7J^jb(oSQQ-I(D2c|R}DvD-U2lG+_>gk$cA8 zTH5U1V!B|h&3P!$JI7S@UvvDi%t66437R1=>L6XM)8I&nzrx+Jts;znOXs-ih(j^m&P@j|5n-m%L(ou@o>!ZR*jwZd=$EQ7NL|D#x z9O~b?9-g1PJt}AV*&_Nw94<$hbe026%N2WKkEACK#E#{Ome~G>WyTeTS(M~qnD7h} zzMJ}h#95VHqV$WgAIYmK!(1yrtCaRH(f`CRr2qUV;lG&TNrq-aK6*iIJSx+f>a1a9 z!cbx{cZbA!!;X|rO@I|hY{I(CzAvczm`pPtHB)`_@Ae4EA|2k~DAYxfDl;pIQB2J; z_xeF58VAD@GvJ}Duz$c&c;;c4M;V5p37OK>_||mI8_k7(sT4|Hz86v!QgbFAZa7Ye zN`7YSv?%ug2VUJ^gSx+dvhKp$G){|1_ql(4PSWS(`U#1L7NNh#G>&<{S^wX9ac4fw sinvPgGu{RDF$q_=R*P1rRdb)Y;(b~rkG_xS`*@){!Xce_;t8Gn4S1%CHUIzs literal 0 HcmV?d00001 diff --git a/vtk_py/clipSurfacesForFullLVMesh.py b/vtk_py/clipSurfacesForFullLVMesh.py new file mode 100644 index 0000000..aa6347a --- /dev/null +++ b/vtk_py/clipSurfacesForFullLVMesh.py @@ -0,0 +1,71 @@ +######################################################################## + +import sys +import vtk + +from mat_vec_tools import * +from readSTL import * +from writeSTL import * + +######################################################################## + +def clipSurfacesForFullLVMesh(endo, epi, verbose=True): + + if (verbose): print '*** clipSurfacesForFullLVMesh ***' + + endo_implicit_distance = vtk.vtkImplicitPolyDataDistance() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + endo_implicit_distance.SetInputData(endo) + else: + endo_implicit_distance.SetInput(endo) + + epi_implicit_distance = vtk.vtkImplicitPolyDataDistance() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + epi_implicit_distance.SetInputData(epi) + else: + epi_implicit_distance.SetInput(epi) + + epi_clip = vtk.vtkClipPolyData() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + epi_clip.SetInputData(epi) + else: + epi_clip.SetInput(epi) + epi_clip.SetClipFunction(endo_implicit_distance) + epi_clip.GenerateClippedOutputOn() + epi_clip.Update() + clipped_epi = epi_clip.GetOutput(0) + clipped_valve = epi_clip.GetOutput(1) + + endo_clip = vtk.vtkClipPolyData() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + endo_clip.SetInputData(endo) + else: + endo_clip.SetInput(endo) + endo_clip.SetClipFunction(epi_implicit_distance) + endo_clip.InsideOutOn() + endo_clip.Update() + clipped_endo = endo_clip.GetOutput(0) + + return clipped_endo, clipped_epi, clipped_valve + +if (__name__ == "__main__"): + assert (len(sys.argv) in [2,3]), 'Number of arguments must be 2 or 3.' + if (len(sys.argv) == 2): + endo_filename = sys.argv[1] + '-EndoLV.stl' + epi_filename = sys.argv[1] + '-EpiLV.stl' + clipped_endo_filename = sys.argv[1] + '_FullLV-Endo.stl' + clipped_epi_filename = sys.argv[1] + '_FullLV-Epi.stl' + clipped_valve_filename = sys.argv[1] + '_FullLV-Valve.stl' + elif (len(sys.argv) == 3): + endo_filename = sys.argv[1] + epi_filename = sys.argv[2] + clipped_endo_filename = 'clipped_endo.stl' + clipped_epi_filename = 'clipped_epi.stl' + clipped_valve_filename = 'clipped_valve.stl' + endo = readSTL(endo_filename) + epi = readSTL(epi_filename) + clipped_endo, clipped_epi, clipped_valve = clipSurfacesForFullLVMesh(endo, epi) + writeSTL(clipped_endo, clipped_endo_filename) + writeSTL(clipped_epi, clipped_epi_filename) + writeSTL(clipped_valve, clipped_valve_filename) + diff --git a/vtk_py/clipSurfacesForFullLVMesh.pyc b/vtk_py/clipSurfacesForFullLVMesh.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe9207be8540f00f2bbea34b9c3ae99ceed07dea GIT binary patch literal 2112 zcmb_b%Wm676um?0ZOXE2r)kiQf-Wi;hy^5@EP|$mABj;v3R%@c2td%{xTZ~!1ZSkc zh1^BmPw3zDSGwsp^aI*+MQ_PJ;}H}R zjS5=ONEqCr(4qlrfU*m!L<3nS-=^Q8Ss_^^zeG0{rN0PSBS~~!r+av4(@lj`Ou9jS zm66{BJyIwetG_Z6zeX?oIz1n)Edvbz&N8qDpt%e<0M?g*CV&=2`;UWFOt6kv3e&Oca}R$1TCykx8qA+rV#>jlr&6%)I> z%KA^5m!DXJFRWQu<#gCJGc|T)DC|u}VP%ZMUBx&9TVnmYstLFVURxFXt(e!I6b`;9 zoP`K(oEc5bmO}#0f`cl8*J+LiDOBmw#Xsz%=bzK4y@kdAge+(%Ms7S zhShxf6;08=-4d-_k|UNGr0Y(+AadQnf}?;pM}3XsbUL|^X(ztycm9?`1<)O|eMRXS8WqE`n=kg*$J-NnipEu+IbQ-Dceu=Wx*1xZd5)PWv1ZrQR20_b4KQ1yZdIRu7c<<6r`?$xyE=|TWtJ(Go_{_#HvRdW z23j)1Yd1)zvd^2GwJ!1|(shl?5G`UAv}>l2OnLPW(lky@B(pS^0aRh9d49Zg z1;FX$H9S_`UY0DI@Ve(FrtHF7pZB)UiS${izr_dpdDzeYX-R8v`fd{Y(@=hE_UAPK gM>rPmU8CfDyvbq_!w6H!nH^kx|Yl|AE7PD?5}2|Fg7n!yb#ASed5~H!C+u1ui9^O|nYlJ;TuoCuC zm!Hb!fEG&EnY8x@;Y^n8m6H3nnav!Bdg9)7O>Rro*l^HY3vCEKM0hUj_4>m_Rw;d; z=~|3@-?W{z(LccDJrbrY#3d@I?vHJe*`Y>Eh%AOCG$VIfs5--%X?inf7xoPO(v%G) zQJ93ZJE3ot5tioLx^E^n#}8n< zTWam|cJG>XB&Y}GDP`jUjCsUj7CZZdJ>clGkSA1un}XS!rTg<}E_G%%JCSd!QqoxZ iH`lro%g5;at?oZd9AlDKwJJI(Ueovubv0rU5B=Zwa=Ehr literal 0 HcmV?d00001 diff --git a/vtk_py/clipheart_ugrid.py b/vtk_py/clipheart_ugrid.py new file mode 100644 index 0000000..c693e19 --- /dev/null +++ b/vtk_py/clipheart_ugrid.py @@ -0,0 +1,29 @@ +######################################################################## + +import sys +import vtk + +from mat_vec_tools import * + +######################################################################## + +def clipheart_ugrid(domain, C, N, isinsideout, verbose=True): + + if (verbose): print '*** Slice Heart ***' + + plane = vtk.vtkPlane() + plane.SetOrigin(C) + plane.SetNormal(N) + + clipper = vtk.vtkClipDataSet() + clipper.SetClipFunction(plane) + if(vtk.vtkVersion().GetVTKMajorVersion() < 6): + clipper.SetInput(domain) + else: + clipper.SetInputData(domain) + clipper.SetInsideOut(isinsideout) + clipper.Update() + + return clipper.GetOutput(); + + diff --git a/vtk_py/clipheart_ugrid.pyc b/vtk_py/clipheart_ugrid.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4698b887257034ca599b7a463762cc47a3208891 GIT binary patch literal 871 zcmbtS!EVz)5S?8+Y3kYqfshcV9IYI%1XqMA1<@eX6eXdDULx0CHS0RIwL6X!$(-O5 z_yfL-Z{P!9W=$yKisgMfZ}!c2JhR@9DERvQZceWP$^Cmy%7rRY{qZN+kWFL=K;dhmvd&$e62f1F?I%aF>urv`ulnQ`s8p my0pmGbY)t#ctXZ~rT= 6): + cleanepipdata.SetInputData(epi) + else: + cleanepipdata.SetInput(epi) + cleanepipdata.Update() + cleanepi = cleanepipdata.GetOutput() + + cleanendopdata = vtk.vtkCleanPolyData() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + cleanendopdata.SetInputData(endo) + else: + cleanendopdata.SetInput(endo) + cleanendopdata.Update() + cleanendo = cleanendopdata.GetOutput() + + if(field_type == "point"): + + pointLocator = vtk.vtkPointLocator() + pointLocator.SetDataSet(cleanepi) + pointLocator.BuildLocator() + + thickness = vtk.vtkFloatArray() + thickness.SetName("Thickness") + thickness.SetNumberOfComponents(1) + + closest_epi_ptid = vtk.vtkIdList() + for ptid in range(0, cleanendo.GetNumberOfPoints()): + endopt = cleanendo.GetPoints().GetPoint(ptid) + closest_epi_ptid = pointLocator.FindClosestPoint(endopt) + closestepipt = cleanepi.GetPoints().GetPoint(closest_epi_ptid) + + distance = math.sqrt(vtk.vtkMath().Distance2BetweenPoints(endopt, closestepipt)) + thickness.InsertNextValue(distance) + + cleanendo.GetPointData().AddArray(thickness) + + if(field_type == "cell"): + pendo_cellcenter = vtk.vtkCellCenters() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + pendo_cellcenter.SetInputData(cleanendo) + else: + pendo_cellcenter.SetInput(cleanendo) + pendo_cellcenter.Update() + cleanendo_cellcenter = pendo_cellcenter.GetOutput() + + pepi_cellcenter = vtk.vtkCellCenters() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + pepi_cellcenter.SetInputData(cleanepi) + else: + pepi_cellcenter.SetInput(cleanepi) + pepi_cellcenter.Update() + cleanepi_cellcenter = pepi_cellcenter.GetOutput() + + pointLocator = vtk.vtkPointLocator() + pointLocator.SetDataSet(cleanepi_cellcenter) + pointLocator.BuildLocator() + + thickness = vtk.vtkFloatArray() + thickness.SetName("Thickness") + thickness.SetNumberOfComponents(1) + + closest_epi_ptid = vtk.vtkIdList() + for ptid in range(0, cleanendo.GetNumberOfCells()): + endopt = cleanendo_cellcenter.GetPoints().GetPoint(ptid) + closest_epi_ptid = pointLocator.FindClosestPoint(endopt) + closestepipt = cleanepi_cellcenter.GetPoints().GetPoint(closest_epi_ptid) + + distance = math.sqrt(vtk.vtkMath().Distance2BetweenPoints(endopt, closestepipt)) + thickness.InsertNextValue(distance) + + cleanendo.GetCellData().AddArray(thickness) + + #print "HERE" + + #myVTK.writePData(cleanendo, "/home/likchuan/Dropbox/UKentuckyData/endo.vtk") + + + + return cleanendo + +''' + +def computeLVthickness(ugrid, field_type="point"): + + + assert (field_type in ["point", "cell"]), "\"field_type\" must be \"point\" or \"cell\". Aborting." + + pdata = myVTK.convertUGridtoPdata(ugrid) + C = myVTK.getcentroid(pdata) + ztop = pdata.GetBounds()[5] + print ztop + C = [C[0], C[1], ztop-0.005] + #C = [C[0], C[1], ztop+0.05] + print C + + clippedheart = myVTK.clipheart(pdata, C, [0,0,1],isinsideout = 1) + + myVTK.writePData(clippedheart, "clippedheart.vtk") + + epi , endo= myVTK.splitDomainBetweenEndoAndEpi(clippedheart) + + myVTK.writePData(epi, "epi.vtk") + myVTK.writePData(endo, "endo.vtk") + + cleanepipdata = vtk.vtkCleanPolyData() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + cleanepipdata.SetInputData(epi) + else: + cleanepipdata.SetInput(epi) + cleanepipdata.Update() + cleanepi = cleanepipdata.GetOutput() + + cleanendopdata = vtk.vtkCleanPolyData() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + cleanendopdata.SetInputData(endo) + else: + cleanendopdata.SetInput(endo) + cleanendopdata.Update() + cleanendo = cleanendopdata.GetOutput() + + if(field_type == "point"): + + pointLocator = vtk.vtkPointLocator() + pointLocator.SetDataSet(cleanepi) + pointLocator.BuildLocator() + + thickness = vtk.vtkFloatArray() + thickness.SetName("Thickness") + thickness.SetNumberOfComponents(1) + + closest_epi_ptid = vtk.vtkIdList() + for ptid in range(0, cleanendo.GetNumberOfPoints()): + endopt = cleanendo.GetPoints().GetPoint(ptid) + closest_epi_ptid = pointLocator.FindClosestPoint(endopt) + closestepipt = cleanepi.GetPoints().GetPoint(closest_epi_ptid) + + distance = math.sqrt(vtk.vtkMath().Distance2BetweenPoints(endopt, closestepipt)) + thickness.InsertNextValue(distance) + + cleanendo.GetPointData().AddArray(thickness) + + if(field_type == "cell"): + pendo_cellcenter = vtk.vtkCellCenters() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + pendo_cellcenter.SetInputData(cleanendo) + else: + pendo_cellcenter.SetInput(cleanendo) + pendo_cellcenter.Update() + cleanendo_cellcenter = pendo_cellcenter.GetOutput() + + pepi_cellcenter = vtk.vtkCellCenters() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + pepi_cellcenter.SetInputData(cleanepi) + else: + pepi_cellcenter.SetInput(cleanepi) + pepi_cellcenter.Update() + cleanepi_cellcenter = pepi_cellcenter.GetOutput() + + pointLocator = vtk.vtkPointLocator() + pointLocator.SetDataSet(cleanepi_cellcenter) + pointLocator.BuildLocator() + + thickness = vtk.vtkFloatArray() + thickness.SetName("Thickness") + thickness.SetNumberOfComponents(1) + + closest_epi_ptid = vtk.vtkIdList() + for ptid in range(0, cleanendo.GetNumberOfCells()): + endopt = cleanendo_cellcenter.GetPoints().GetPoint(ptid) + closest_epi_ptid = pointLocator.FindClosestPoint(endopt) + closestepipt = cleanepi_cellcenter.GetPoints().GetPoint(closest_epi_ptid) + + distance = math.sqrt(vtk.vtkMath().Distance2BetweenPoints(endopt, closestepipt)) + thickness.InsertNextValue(distance) + + cleanendo.GetCellData().AddArray(thickness) + + #print "HERE" + + #myVTK.writePData(cleanendo, "cleanendo.vtk") + + + + return cleanendo + + + + + + + + + + + + + + + + + diff --git a/vtk_py/computeLVthickness.pyc b/vtk_py/computeLVthickness.pyc new file mode 100644 index 0000000000000000000000000000000000000000..025c1e265a037f7896563e2b5b5188a87db8680d GIT binary patch literal 2808 zcmb_eQB&JS5MD_(5U{}nOrW8yKJDt>Idzrmxw z$Kd17qLAotBwKW7m3EsB?NWB=&?)5#9ac)YN{18V1Ln{Rtes?s_tz?L9{h!$T~mda z#6e^{4t)jB1fC8aeI2k2(Prsvg7h*OuyE+yqF*dB7IkgPh}EGjszaGAstDZ*odaK? zm0^Xl3T@xcK(I2sTT zHY66D)Tld88Nz`cE0={1Lly)Azjf*^l3&juP?}Oh;2E_fs9AdUg3J|eN;X5?Wj3Ow zTR-(^I47nRHg(^l42;m`hD5$f8HhlgWeVL92K-^1C$mc3_oW6O$np;vpUtyt23!_y zEy_R|bRNI5zT@cE1l#6GHb?o+vnBghg-L(Jh~dJ!s{5y%El73IMqZ5kp<~Q-R*LFE z%B#C5esZ79cln%gvZnaV%gjEZV=T%JrSJ(U_qil~-slo)4NCu8m#%Xa#=5jP)`5$< zv^0kKmtFeZkuH7wc9&*woy_63*xkoKhHn;6g`xfwLi#fb>I5k0ZvL5hl6yTx2!f^8Q;vd^DpPR4E44ZTi>A+WU-{=N(FAS1I z`KQWF&H58_rYB)kNg(nR%aI?m67Y>?E@60Z8hB@s(t3?AJ3YGlbV+;d6Nb)W*wk8q zR2W&-CXHd{c-zX{i2ISRMPtIk z)=XpWX&M-{x5Z0Wq3R?I%vRiUgXo4bPnC*pg8pXY-%JAI0Dwdcr;T?fRBp5vhXYy7 z&R{%HsRmth87ks}>Rq=Rr=__D^L=IRL`mPsGOkc*FkGRB3Gz@S?|Xd%q~X@W`5u2E zc4E&ps09baO7?=6Vb3@ELFkwB^?c2(Fm}ymnz{qSodI;$?J3hN$4YmMsG#E9_*AzrK=p|AaRd*ZK7c%D>cTk&BNWzR;4#a}y^*X8bV7cELdq z1Rny!9r1Y6z{*{AaiPAp$bQeK0nX=n_l`^wAsOESJZ;LuB*}Sst&b4lC^2BqM@j_V zTg)QKw@LwICPrxZMcKto!pI}O7x*Bd=8NM*#wWNf2}c_P%h@dQ9J8+hN;2p#AZ?t+ zJ+%=cJ+-l~H0}@YbmMmC?gn~xlngdJY{|Y+I|ri-*OP&qtG8$H&l%}o*}t=F&slR; z!>U?W?W%p_4uUYf<67&n#UA$^)jr%G) zCF=K*!9Jf&!*^Y*Wmo8d-fyvuo06xy&sW?2CWhB#`meQO7GL&azaOfv`0moogENv} HyXO53#@cjM literal 0 HcmV?d00001 diff --git a/vtk_py/computeRegionsForBiV.py b/vtk_py/computeRegionsForBiV.py new file mode 100644 index 0000000..4b9d504 --- /dev/null +++ b/vtk_py/computeRegionsForBiV.py @@ -0,0 +1,169 @@ +#coding=utf8 + +######################################################################## +### ### +### Created by Martin Genet, 2012-2015 ### +### ### +### University of California at San Francisco (UCSF), USA ### +### Swiss Federal Institute of Technology (ETH), Zurich, Switzerland ### +### ### +######################################################################## + +import math +import numpy +import vtk +import os +import sys + +import vtk_py as myVTK + +######################################################################## + +def computeRegionsForBiV( + points, + pdata_endLV, + pdata_endRV, + pdata_epi, + verbose=0): + + #myVTK.myPrint(verbose, "*** computeRegionsForBiV ***") + #myVTK.myPrint(verbose, "Initializing cell locators...") + if (verbose): print "*** computeRegionsForBiV ***" + if (verbose): print "Initializing cell locators..." + + + (cell_locator_endLV, + closest_point_endLV, + generic_cell, + cellId_endLV, + subId, + dist_endLV) = myVTK.getCellLocator( + mesh=pdata_endLV, + verbose=verbose-1) + (cell_locator_endRV, + closest_point_endRV, + generic_cell, + cellId_endRV, + subId, + dist_endRV) = myVTK.getCellLocator( + mesh=pdata_endRV, + verbose=verbose-1) + (cell_locator_epi, + closest_point_epi, + generic_cell, + cellId_epi, + subId, + dist_epi) = myVTK.getCellLocator( + mesh=pdata_epi, + verbose=verbose-1) + + n_points = points.GetNumberOfPoints() + + iarray_region = myVTK.createIntArray("region_id", 1, n_points) + + for k_point in range(n_points): + point = numpy.array(points.GetPoint(k_point)) + cell_locator_endLV.FindClosestPoint( + point, + closest_point_endLV, + generic_cell, + cellId_endLV, + subId, + dist_endLV) + cell_locator_endRV.FindClosestPoint( + point, + closest_point_endRV, + generic_cell, + cellId_endRV, + subId, + dist_endRV) + cell_locator_epi.FindClosestPoint( + point, + closest_point_epi, + generic_cell, + cellId_epi, + subId, + dist_epi) + + if (dist_endRV == max(dist_endLV, dist_endRV, dist_epi)): + iarray_region.SetTuple(k_point, [0]) + elif (dist_epi == max(dist_endLV, dist_endRV, dist_epi)): + iarray_region.SetTuple(k_point, [1]) + elif (dist_endLV == max(dist_endLV, dist_endRV, dist_epi)): + iarray_region.SetTuple(k_point, [2]) + + return iarray_region + +######################################################################## + +def addRegionsToBiV( + ugrid_mesh, + pdata_endLV, + pdata_endRV, + pdata_epi, + verbose=0): + + #myVTK.myPrint(verbose, "*** addRegionsToBiV ***") + if (verbose): print "*** addRegionsToBiV ***" + + points = ugrid_mesh.GetPoints() + iarray_region = computeRegionsForBiV( + points=points, + pdata_endLV=pdata_endLV, + pdata_endRV=pdata_endRV, + pdata_epi=pdata_epi, + verbose=verbose-1) + ugrid_mesh.GetPointData().AddArray(iarray_region) + + cell_centers = myVTK.getCellCenters( + mesh=ugrid_mesh, + verbose=verbose-1) + iarray_region = computeRegionsForBiV( + points=cell_centers, + pdata_endLV=pdata_endLV, + pdata_endRV=pdata_endRV, + pdata_epi=pdata_epi, + verbose=verbose-1) + ugrid_mesh.GetCellData().AddArray(iarray_region) + +######################################################################## + +def addRegionsToBiV2D( + ugrid_mesh, + LVplane, + LVpoint, + RVplane, + RVpoint, + verbose=0): + + #myVTK.myPrint(verbose, "*** addRegionsToBiV2D ***") + if (verbose): print "*** addRegionsToBiV2D ***" + + tol = 1e-5 + + n_cells = ugrid_mesh.GetNumberOfCells() + + meshCellCenter = myVTK.getCellCenters(ugrid_mesh) + matid = myVTK.createIntArray("region_id", 1, n_cells) + + LVplanenorm = numpy.linalg.norm(LVplane) + LVPlane = 1.0/LVplanenorm*numpy.array(LVplane) + + RVplanenorm = numpy.linalg.norm(RVplane) + RVplane = 1.0/RVplanenorm*numpy.array(RVplane) + + + for ptid in range(n_cells): + x = meshCellCenter.GetPoints().GetPoint(ptid) + if((x[0] - LVpoint[0])*LVplane[0] + (x[1] - LVpoint[1])*LVplane[1] > tol): + matid.SetTuple(ptid,[0]) + elif((x[0] - RVpoint[0])*RVplane[0] + (x[1] - RVpoint[1])*RVplane[1] > tol): + matid.SetTuple(ptid,[1]) + else: + matid.SetTuple(ptid,[2]) + + ugrid_mesh.GetCellData().AddArray(matid) + + return ugrid_mesh + + diff --git a/vtk_py/computeRegionsForBiV.pyc b/vtk_py/computeRegionsForBiV.pyc new file mode 100644 index 0000000000000000000000000000000000000000..559e3f6641f8e96b8aba42c5d4737f30df4927b9 GIT binary patch literal 3163 zcmb_e&2HRO6h8L+PdrJRnfw$LkxKjw5lW=8fCUsvqP7ujsGKNBBhbhhn~A3$d$8|R z39?sV(FfoO=rh1Wux8OMf(HPxVSxnSIkqQm7^qekHuawhe>Xmc4LcJ>4P%F{5u&oJQ7P>BU zMd$`EbkMD0QTHEw_FYgks9;#bQ^&J|Cwit4#bpW?S^w@mKb>7?PclWUkjo5_wM4d<%9e836_H&P*>Wnwfy7C?NHJI?dZbgRw75f~Ca-SSXowBy zq<#G}Ys}I9zMx$xY9qA&^$jmG-}Qnv+wZca>{-?l-PK+!#2Xx8Vf?O9f%HwY7z?5{;ecMAbk%cEaNza$IB% z?}{iCkA2sc9CJD2y9+GjY#W~)9e%17K@A-WWZ z#y7wpI=&OSgFc%nW-zg5XBvFGXnMS7t0pMhjZ`L>w-WX=cO~$jcML|+9i|+m=Qloa zlVnB?tvnkw8_26mU~#z`4LsU?X5l@Qd-Z z#&}u*lFkrr1h}m-R5759Up~6$mtkbS&MXd4&e}y~N%q{fZK-OLtFj0S zJC3iMFp|Q9)eZ`Sjk+9aNyF(dbnQN)(7gSm8@-XQE9pH*UB0B8;~-p$&;YDR+}Dw6 zx`8Chzb&n;bJDeD9Hs}1IP8c^U6SVs_uopf{~}wmTu4($E*hN=8Nkh}&i9UM#HDl3 ztV#20P?{**?9v|BlpJf)3JcKTgxg6L3W_E1XNaOPQxt9|DbeXO!j16)+)jU@1dXsx zqlTmr8d^)t(d+Q)P^D`zau0v&{GNdS4ztTC8-K#ae`gJe{Rr!j znKvZ5c#|r*@CLSclfz$l>lM6}i{55yT=d?jXpSfZL(U=1oeK@D1Ie}h=o;>3PC4A% zQ!duK%dMK-Mzsyz=8NV@1*oa%@=}Rg>MxRS1 zcysq0%;-%Fg86zC_`amA=*!v~Kc%*|qP-97#-p$4ZN1BplrWDib&|%PBY}>i_)3FF z@iaP%iwvjeh|u CfRX0_ literal 0 HcmV?d00001 diff --git a/vtk_py/computeVolume.py b/vtk_py/computeVolume.py new file mode 100644 index 0000000..93019ff --- /dev/null +++ b/vtk_py/computeVolume.py @@ -0,0 +1,66 @@ +######################################################################## + +import sys +import numpy +import vtk + +from mat_vec_tools import * +from createFloatArray import * +from vtk_py import * + +######################################################################## + + +def computeVolume(pdata, orientation): + + bd = pdata.GetBounds() + + # Define the cutting plane + plane=vtk.vtkPlane() + if(orientation == 'z'): + plane.SetOrigin(0,0,bd[5]-0.1) + plane.SetNormal(0,0,-1) + elif(orientation == 'x'): + plane.SetOrigin(bd[0]+0.1,0,0) + plane.SetNormal(1,0,0) + elif(orientation == 'n'): + plane.SetOrigin(0,0,bd[5]+100) + plane.SetNormal(0,0,-1) + + + # Need a plane collection for clipping + planeCollection = vtk.vtkPlaneCollection() + planeCollection.AddItem(plane) + + # The clipper generates a clipped polygonial model + clipper = vtk.vtkClipClosedSurface() + clipper.SetClippingPlanes(planeCollection) + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + clipper.SetInput(pdata) + else: + clipper.SetInputData(pdata) + clipper.SetGenerateFaces(1) + clipper.SetScalarModeToLabels() + clipper.Update() + + # Get volume using mass property + massprop = vtk.vtkMassProperties() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + massprop.SetInput(clipper.GetOutput()) + else: + massprop.SetInputData(clipper.GetOutput()) + return massprop.GetVolume() + +if (__name__ == "__main__"): + assert (len(sys.argv) in [2,3]), "Number of arguments must be 1 or 2. Aborting." + pdata_mesh = readSTL(sys.argv[1]) + if (len(sys.argv) == 2): + vol = computeVolume(pdata_mesh, "z") + elif (len(sys.argv) == 3): + vol = computeVolume(pdata_mesh, sys.argv[2]) + + print "Cavity volume = ", vol + + + + diff --git a/vtk_py/computeVolume.pyc b/vtk_py/computeVolume.pyc new file mode 100644 index 0000000000000000000000000000000000000000..84783683cba418661699affb5c255a8c9c6aeee6 GIT binary patch literal 1766 zcmbtT&2Af26h3$Slf<#xG$Ab!2o0OcLLzQ~B?W?kw4zC?IL#uP(Rk)I8E0m$b?

3gvq0hj;5%pRkW}ojJZH{5|L6Pe)c)$UzW@FGVM6m?9q&)@ zxIZCM{1xRy$CtXIW3{jcbR38tP+p@$j)qph)Edxg^bOLRq?ahI(^)|F57Nt|iAF1Q zfl{k<)+G0We2da0wtTHfug(L~W!i%2xP3jRA%%V>jk;}0Q3#`SsNB9D)|9Z{=3!OK zw1J9MG{$YwuI|w8!%`L)cfpzLMtJA2-B>=tR-M|YR4VpD*w9M{>V}(X7 z_5sK_vT||SH@1j#zkVgKZ}MCxJ~O4~JGGOhkGwAY zYgI@;&&K`SIGqkA_IaFWe+v%OWyd%xPo$Z{$08#fY3sNWH^6*HhhOf+BV!k49uT>Y z%JIZ|zT1n#XR(j{T4mVPrM9uxU!a@wo0V~p#CdG@OsWsf<9MiZ=NXM>;}nrH69CwY zoqKA{SX-YVbq>;#iRX6n(~-$1h3@jIo`L5Av1d+<&2$N!=jShMm{tLT=1mS|?G?BZ zh5`L}vjXkMXy1iSBHTS_y;D=@UY_Jy_YSnvu}w~U5BqyPOdO4;y~GrlPgjF&kEgza zq-(|-Ft`sOC}`K(s;%Box39{2TXkUXs7 zyv1n@auk(up`%Dj=a{$-Bc?z1+;GP^Cf}5wTZ^%oWfV;ZhmYlk3fWPi-D&mBnEYR^ o{s&<^*N25kC%OJeuzeE-=BXWk3Ds(>bld7}wE;%f@oWYE0IWWK!T>xmlfile, "" + print >>xmlfile, "" + print >>xmlfile, "" + + cnt = 0 + for cellid in range(0,celldata.GetNumberOfTuples()): + data = celldata.GetTuple(cellid)[0] + print >>xmlfile, "" + cnt += 1 + + print >>xmlfile, "" + print >>xmlfile, "" + + + + + diff --git a/vtk_py/convertCellDataToXML.pyc b/vtk_py/convertCellDataToXML.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a968607ad1ed621794cdf858b470eb90c4e59355 GIT binary patch literal 927 zcmbtS+iKfD5FK6YIF6IH^kM>~=uLXcIo4>h`T_0CDv2rdt&;Za>|D;A-Ieoev-$n!^NSd69vkPEIMg;mf}aHf;3FC~ zd_%(`&q?55H2aOuAf}4?&FJH-ejsRoxk+8xu&`lngNp?Ao43Yt?kpFy1#^Ha8@31hDT}O?;o(b?d41(0XBQ*-a~; f%P{hg|CnxLrRV=eHIT16&XbAYp*dyh)^h&>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + + for p in range(0, MPI.size(mpi_comm_world())): + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + pvtufile.close() + + + + + + + diff --git a/vtk_py/convertQuadDataToVTK.pyc b/vtk_py/convertQuadDataToVTK.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d23b835c11d14dc5dcfc6a8f86fe1df69f74eb37 GIT binary patch literal 3275 zcmbtW-*XdH6h3zoS{hPHe?SsiBm~5W+Jbe)7g|Jqi9*4GARU;@HoK*pZg#hOZy;ed zGmiC7@X7Jb7vKGh^j~m>2Ve9%XR|5LIyhs}y*c-sbH8)$ch0@r+@IrxAAet5Z_?nC z!|!K!^dk%o{uKE{YpHCJuju|jYtfpOdE{sv=HJfnE7;L(47>W@*s zK&D8oadt=wl#Edsz&knWAIc2K@ijv+Ga#kc4C9$$2*tSojdMY?!<=Dqh${UFGMHFo zCI|*SXPG0^n&hndM~LMqktZpcq}DVO1PsNK8FFNos=GtxD5E7sO2#QUOgnkH`oyQl zdFoG5f13I;)Q1Pqj!}Y$NcSk?R5Gj*r_d@3B^4f%DXP4wn%=9L0Yr|}_L_RgxgM8X z5#t!OW;veVV=^bmCwLRAV&8Yf7lBLEI>{@<7n3R*RPd8{WlW&Q`eo`qCUc7G!zGrA zgR`qou2H{2Nts%;UB(2hOi6_*uh2G72zBN(Tj5t?-|ef`!|reU68ZCgB(fXro86;9 zc9Mz^Ez(}H_o!3C_oy?{|F9lz|6=_+@!e1M&F6&V^J-C2R)mE(CwOluPLiXdewk0u z-8m|ONOOi-?~*yor2`I=>Kvp}|2UcVs8yFDzt6_xI5}fv&Y{_rdSeypio+idah(DX zX32a&$t*cIsW>=ul+01yDUx;bOOeKh(&3>rF_exBrOBZ*HI$}@(hN)8D;Zzd&4;h- zhI{O+u*R`*kkU<~Fxf_(V^jjd_OJPel2vJlTpmcRkEE@)U*-e3ZtvAAxC2+b9N&b; zFx(0JUiF#VG-0eGyXjV+hw+w{Yt)08JibLe3j>ZX(ZG|h+WBWD!hv92ydG*-^G!P+ zv6k07*GDm4ywq*`z>l>T21~UI^XF@qmUW#i5AJ_;-Sge5=|%2R?e5*s?_ITxUEB3O zKYyXNtdFzv&|JN-8ESLOedhX0wev9Z-Ogq&Fuc6_Al=JSElm|3pNj_@FUPUn8w9-W zhqhV#xK>@U+lW8#uC8?2>u!8!<4V|$!oUrTUaBqDste0{oM9GrBQ5K(-OzejFTN$r zzQDjOyn+ju34!rkl;U34iJQnxGu@IyG4oBi$`%i(T&~Z4h>{P=%c-jlJv4f^- zc+bA4Q^03t%P`ycl}c;F)xb=uC}qXFi0Gbc_7+eQXA24~>AmpMoNflp$co!F0*coI z(XQ@(C-U9JRryzfw`X(nm_upYtXm~3U=On5`rH`IxZ#B5%Z`&~IFqh@fS_*ohTn@e zaR3ZvybNA9gQz1-EVO(RIiOvbO$p-jXGf76I4Q{{mfzcVZwgs(+LA)IBM)_Jw;MRh zzLOqXv(<=tLfZ4#Gw!#yZ{3yrm{cTur(+OWVqLd=ow6Sylpt&GMVd#`$2qU_i4%Pr z%^>jCrOiZ#oYP%z;A{uXIBzcO7{`m{WcGxz04*YmR`~{zz|v}hfxghfT)WrU@M81; zJ7MD6keP-qH>Vb{w=2F#MQ$VkOQ#$^oyM-yL1!^Q#P@|3{`ll`eFak_ffPv)CE+2U z=(#ku^ukjvBlgN=ln!;9jkHs^aU#)WR5XMO+>o72BfHELd@GU+`cp^?n>d^ce$#i| zg;iI(cHG=t_~Od#1++bixzG#)+^gp6j_q(M?}xYr=22wsvi)p);PrPH$SSI`HKk_N zoOLQ!QT(l11#1HOq8eA@R$Y~>8#$Jzp@Sx0v_{mNnpTtQq*&+FDOFOZ#b-{N%eCp>Nw}Q%J@g7WG#7P|9r)>ebtj dcUk)XRB<8~+o99(-DNJ9=3XfxMJ57Y>mNX(+F}3z literal 0 HcmV?d00001 diff --git a/vtk_py/convertQuadScalarDataToVTK.py b/vtk_py/convertQuadScalarDataToVTK.py new file mode 100644 index 0000000..eb11a05 --- /dev/null +++ b/vtk_py/convertQuadScalarDataToVTK.py @@ -0,0 +1,101 @@ +import vtk as vtk +from dolfin import * +import vtk_py as vtk_py +import math as math +import numpy as np +import os as os + +def convertQuadScalarDataToVTK(mesh, Fspace, data, filename=[]): + + nsubspace = Fspace.num_sub_spaces() + assert (nsubspace == 0), 'Only scalar space works' + + dim = mesh.geometry().dim() + coord = Fspace.tabulate_dof_coordinates().reshape((-1, dim)) + npts = int(len(coord)) + + my_first, my_last = Fspace.dofmap().ownership_range() + + x_dofs = np.arange(0, my_last-my_first) + coord_dofs = np.arange(0, (my_last-my_first)) + + coord_reduce = coord[x_dofs] + + if(not isinstance(data, list)): + + points = vtk.vtkPoints() + scalar = vtk.vtkFloatArray() + scalar.SetNumberOfComponents(1) + scalar.SetName("scalar") + + for x_dof, coord_dof in zip(x_dofs, coord_dofs): + points.InsertNextPoint(coord_reduce[int(coord_dof)]) + scalar.InsertNextValue(data.vector().array()[x_dof]) + + + pdata = vtk.vtkPolyData() + pdata.SetPoints(points) + pdata.GetPointData().AddArray(scalar) + + glyphfilter = vtk.vtkVertexGlyphFilter() + glyphfilter.AddInputData(pdata) + glyphfilter.Update() + + else: + + points = vtk.vtkPoints() + + scalar_array = [] + for p in range(0, len(data)): + scalar_array.append(vtk.vtkFloatArray()) + scalar_array[p].SetNumberOfComponents(3) + scalar_array[p].SetName("scalar"+str(p)) + + for x_dof, coord_dof in zip(x_dofs, coord_dofs): + points.InsertNextPoint(coord_reduce[int(coord_dof)]) + for p in range(0, len(data)): + scalar_array[p].InsertNextValue(data[p].vector().array()[x_dof]) + + + pdata = vtk.vtkPolyData() + pdata.SetPoints(points) + for p in range(0, len(data)): + pdata.GetPointData().AddArray(scalar_array[p]) + + glyphfilter = vtk.vtkVertexGlyphFilter() + glyphfilter.AddInputData(pdata) + glyphfilter.Update() + + + + if(not (not filename)): + filename_ = filename + str(MPI.rank(mpi_comm_world())) + '.vtp' + #vtk_py.writeXMLPData(glyphfilter.GetOutput(), filename_, verbose=False) + vtk_py.writeXMLPData(pdata, filename_, verbose=False) + + if(MPI.rank(mpi_comm_world()) == 0): + pvtufilename = filename + '.pvtp' + pvtufile = open(pvtufilename, 'w') + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + + for p in range(0, MPI.size(mpi_comm_world())): + print >>pvtufile, "" + print >>pvtufile, "" + print >>pvtufile, "" + pvtufile.close() + + + + + return pdata + + + diff --git a/vtk_py/convertUGridToXMLMesh.py b/vtk_py/convertUGridToXMLMesh.py new file mode 100644 index 0000000..941c969 --- /dev/null +++ b/vtk_py/convertUGridToXMLMesh.py @@ -0,0 +1,81 @@ +######################################################################## + +import vtk +import dolfin +import numpy as np +from vtk.util import numpy_support + +######################################################################## + +def convertUGridToXMLMesh(ugrid): + + + num_pts = ugrid.GetNumberOfPoints() + num_cells = ugrid.GetNumberOfCells() + + celltypes = numpy_support.vtk_to_numpy(ugrid.GetCellTypesArray()) + + + num_tetra = np.count_nonzero(celltypes == 10) + + print "Number of points = ", num_pts + print "Number of tetra = ", num_tetra + + mesh = dolfin.Mesh() + editor = dolfin.MeshEditor() + editor.open(mesh, 3, 3) # top. and geom. dimension are both 2 + editor.init_vertices(num_pts) # number of vertices + editor.init_cells(num_tetra) # number of cells + + for p in range(0, num_pts): + pt = ugrid.GetPoints().GetPoint(p) + editor.add_vertex(p, pt[0], pt[1], pt[2]) + + + + cnt = 0 + for p in range(0, num_cells): + pts = vtk.vtkIdList() + ugrid.GetCellPoints(p, pts) + if(pts.GetNumberOfIds() == 4): + editor.add_cell(cnt, pts.GetId(0), pts.GetId(1), pts.GetId(2), pts.GetId(3)) + cnt = cnt + 1 + + editor.close() + + return mesh + +''' +def convertUGridToXMLMesh(ugrid): + + + num_pts = ugrid.GetNumberOfPoints() + num_cells = ugrid.GetNumberOfCells() + + print num_pts + print num_cells + + mesh = dolfin.Mesh() + editor = dolfin.MeshEditor() + editor.open(mesh, 3, 3) # top. and geom. dimension are both 2 + editor.init_vertices(num_pts) # number of vertices + editor.init_cells(num_cells) # number of cells + + for p in range(0, num_pts): + pt = ugrid.GetPoints().GetPoint(p) + editor.add_vertex(p, pt[0], pt[1], pt[2]) + + + + for p in range(0, num_cells): + pts = vtk.vtkIdList() + ugrid.GetCellPoints(p, pts) + editor.add_cell(p, pts.GetId(0), pts.GetId(1), pts.GetId(2), pts.GetId(3)) + + editor.close() + + return mesh + +''' + + diff --git a/vtk_py/convertUGridToXMLMesh.pyc b/vtk_py/convertUGridToXMLMesh.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a61a60f05a0f691bcf5e44a0e608352e625a62fd GIT binary patch literal 1405 zcmb_b%Wl&^6uo2T-K6xDmhK`Up{$w(8x|B%l`5^&7L*nhMM6<(Pg}c=?b?&7K@OX+ zhXp^uXYmbu0GxZ16e_VKif7K;>wD(hhwY!W%C{fS&K;WlEbOoFq&rw#{1pX6-FvL4 ztLAo#y0&18f*cL<)XkG}ZTgIW0!N-Sb71j);dk6rfTo5e91h}9FCE5llo*H23wTO+ zcJZWNVabSmq6yJh308tFG8Xx^SaNKcC>q;j^5hpNgA_&AmKby7TGY-IwfCW?o#g;b zk^GYII*E(Mb!82U=3yZ#)U6PuhYY2n54M@3xE>dS)f(_)7;Tb1+dUh04-a|VYmX<)bJ`eN!Br$#06%u`CxEx48BCsF0hhA#rDnxJ=Gmgb6$Gk8HZfcm8nfP+K z8xaStASZ}Y-Q*8Rj>F5ub1~)ewe@0?%5^B1#7gs8(pw?koQY&g(En5|<$?11^ zzB-JgE;2G5ZkrSnlD3A%3uLr9PhkF&%zwzJ1i}}C$Q=gyCAU50OjtH#=E{4&0hR1A A5&!@I literal 0 HcmV?d00001 diff --git a/vtk_py/convertUGridtoPdata.py b/vtk_py/convertUGridtoPdata.py new file mode 100644 index 0000000..535ab09 --- /dev/null +++ b/vtk_py/convertUGridtoPdata.py @@ -0,0 +1,19 @@ +######################################################################## + +import vtk + +######################################################################## + + +def convertUGridtoPdata(ugrid): + + geometry = vtk.vtkGeometryFilter() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + geometry.SetInputData(ugrid) + else: + geometry.SetInput(ugrid) + + geometry.Update() + + return geometry.GetOutput() + diff --git a/vtk_py/convertUGridtoPdata.pyc b/vtk_py/convertUGridtoPdata.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25545d5e2c6ba08d3783a94109d289ec025983e7 GIT binary patch literal 564 zcmbtR%}T>S5T4zbswDw`@ZcNdWDvoVh)^+#v`TAx@FFo;+N5a`b|-~EJ=I6>1$_n| zKxfhxFWy`-v)_EPGxKHF`f}SJpJ%TTte2$yip(67i|G@P0X!3s@J>K5Gw>|RCf~Gr zks!!bY#lPwCx-y3fF;12Xt0FT;*g4`Ht17W2uQbJ0k9Mxa<_@?P0Yy_9~X?a84Wz{ z-%DELy&axlk(=Wb_g8zMikU)P-y|6-jqMdXQraX%jt3M53P(@(-7qcmhIWV^D7?$d z3a>*9kvne)*QIXF{?J(dz#UsrMPs$n(sq~K&t23+_q$7^Ro^)kfHfs3Jq0c}4 XE8yQMc-+OTh^tIp@@*S_0>}OV6~=&R literal 0 HcmV?d00001 diff --git a/vtk_py/convertXMLMeshToUGrid.py b/vtk_py/convertXMLMeshToUGrid.py new file mode 100644 index 0000000..e06986b --- /dev/null +++ b/vtk_py/convertXMLMeshToUGrid.py @@ -0,0 +1,90 @@ +######################################################################## + +import vtk +import dolfin + +######################################################################## + +def convertXMLMeshToUGrid(mesh, p_region=None): + + connectivity = mesh.cells() + coords = mesh.coordinates() + + points = vtk.vtkPoints() + for coord in coords: + points.InsertNextPoint(coord[0], coord[1], coord[2]) + + + + '''part_id = vtk.vtkIntArray() + part_id.SetName("part_id") + if(p_region): + V = dolfin.FunctionSpace(mesh, "DG", 0) + dm = V.dofmap() + + for cell in dolfin.cells(mesh): + matid = p_region[cell] + part_id.InsertNextValue(matid)''' + + + + cellarray = vtk.vtkCellArray() + for cell in connectivity: + tetra = vtk.vtkTetra() + tetra.GetPointIds().SetId(0, cell[0]) + tetra.GetPointIds().SetId(1, cell[1]) + tetra.GetPointIds().SetId(2, cell[2]) + tetra.GetPointIds().SetId(3, cell[3]) + + cellarray.InsertNextCell(tetra) + + ugrid = vtk.vtkUnstructuredGrid() + ugrid.SetPoints(points) + ugrid.SetCells(tetra.GetCellType(), cellarray) + #ugrid.GetCellData().AddArray(part_id) + + return ugrid +''' + +def convertXMLMeshToUGrid(mesh, p_region=None): + + connectivity = mesh.cells() + coords = mesh.coordinates() + + points = vtk.vtkPoints() + for coord in coords: + points.InsertNextPoint(coord[0], coord[1], coord[2]) + + + part_id = vtk.vtkIntArray() + part_id.SetName("part_id") + if(p_region): + V = dolfin.FunctionSpace(mesh, "DG", 0) + dm = V.dofmap() + + for cell in dolfin.cells(mesh): + matid = p_region[cell] + part_id.InsertNextValue(matid) + + + + cellarray = vtk.vtkCellArray() + for cell in connectivity: + tetra = vtk.vtkTetra() + tetra.GetPointIds().SetId(0, cell[0]) + tetra.GetPointIds().SetId(1, cell[1]) + tetra.GetPointIds().SetId(2, cell[2]) + tetra.GetPointIds().SetId(3, cell[3]) + + cellarray.InsertNextCell(tetra) + + ugrid = vtk.vtkUnstructuredGrid() + ugrid.SetPoints(points) + ugrid.SetCells(tetra.GetCellType(), cellarray) + #ugrid.GetCellData().AddArray(part_id) + + return ugrid + +''' + + diff --git a/vtk_py/convertXMLMeshToUGrid.pyc b/vtk_py/convertXMLMeshToUGrid.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d01b76dbcb85a80bd99593e38bb195f34fc216dd GIT binary patch literal 1035 zcmb_aON$dh5U!q{Ja^&)QCyG8LO^s5UOb2>5!QeSOE!zLAWNKSlO88Cak>%`n4BVb z^x_}%H~0gzswTMjI65<3{dHB>*I(7N{@!VS{r2cx1pCLM`56t@B@@%9AO$%8g%zAD zcE%ojBCHvob~SCbKj;}oOwguLr_rO~jub!%kO1reww_=mSOa>HXu&?LA3&+$#oHs; z)}Ztu@u93S{UJ|YHEB59X;2^U!)wm1Np2n1U!e3T_cLr8LRyzV6Urte4aP~6smg{B z?mSSxMMxDz=#0N2S|WVxpE)Fta{PUy4oQno+bL2vt<<$e1i4#~9B@e-gNH33oz{jfi+6WictQqy&`Wc1+z20^4 x-qKwbI^rKKRmFMwp8g#>hk0g3w+URz{STU1+LL)6FH`fBZ;j)&l1M)|`3WEa;k*C< literal 0 HcmV?d00001 diff --git a/vtk_py/convertXMLMeshToUGrid2D.py b/vtk_py/convertXMLMeshToUGrid2D.py new file mode 100644 index 0000000..1b7c322 --- /dev/null +++ b/vtk_py/convertXMLMeshToUGrid2D.py @@ -0,0 +1,34 @@ +######################################################################## + +import vtk +import dolfin + +######################################################################## + +def convertXMLMeshToUGrid2D(mesh): + + connectivity = mesh.cells() + coords = mesh.coordinates() + + points = vtk.vtkPoints() + for coord in coords: + points.InsertNextPoint(coord[0], coord[1], coord[2]) + + cellarray = vtk.vtkCellArray() + for cell in connectivity: + triangle = vtk.vtkTriangle() + triangle.GetPointIds().SetId(0, cell[0]) + triangle.GetPointIds().SetId(1, cell[1]) + triangle.GetPointIds().SetId(2, cell[2]) + + cellarray.InsertNextCell(triangle) + + ugrid = vtk.vtkUnstructuredGrid() + ugrid.SetPoints(points) + ugrid.SetCells(triangle.GetCellType(), cellarray) + + return ugrid + + + + diff --git a/vtk_py/createFloatArray.py b/vtk_py/createFloatArray.py new file mode 100644 index 0000000..588691c --- /dev/null +++ b/vtk_py/createFloatArray.py @@ -0,0 +1,12 @@ +######################################################################## + +import vtk + +######################################################################## + +def createFloatArray(name, nb_components=1, nb_tuples=0, verbose=True): + farray = vtk.vtkFloatArray() + farray.SetName(name) + farray.SetNumberOfComponents(nb_components) + farray.SetNumberOfTuples(nb_tuples) + return farray \ No newline at end of file diff --git a/vtk_py/createFloatArray.pyc b/vtk_py/createFloatArray.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b7f0fce5960dab2566855a9b21789c4aa0acd620 GIT binary patch literal 553 zcmbtRJ5Iwu5S_KnFG?gRxB!(aT%@2u2xJM-V5B5fn#iAtlHi|q$B`_VDjb0e<_sJF zX6zsfT6TA4-~8X&_UCBuu^&e<9G1iPJ&UK<|0 z`iobvRsvZdmL?LgSbP?9!-@bl3U&Z*4m1vIENB3B3X~W&G#on^9JhXqsVi-Rb`IGL zxAaP*?tV;*kRG%SYdT@i6e$QZq{{=YvIzCd(l4^I$T25F7r!I3s!Y*zt%Y(f)zUkU z7I9y7)_JJSZYOO~M}0xlzHl^HYgRz-$h8mEZf1Pz8dUU^Ucv&ZZgW$ncp zL&Bc_by?Fn*ZuX&v&?`MsG%CQ+m(+n5f=&PnXYgm89jsl(KzK^w^@-?Dc;E_BR_HI Fd;>gaea!#> literal 0 HcmV?d00001 diff --git a/vtk_py/createIntArray.py b/vtk_py/createIntArray.py new file mode 100644 index 0000000..78488d6 --- /dev/null +++ b/vtk_py/createIntArray.py @@ -0,0 +1,12 @@ +######################################################################## + +import vtk + +######################################################################## + +def createIntArray(name, nb_components, nb_tuples, verbose=True): + iarray = vtk.vtkIntArray() + iarray.SetName(name) + iarray.SetNumberOfComponents(nb_components) + iarray.SetNumberOfTuples(nb_tuples) + return iarray diff --git a/vtk_py/createIntArray.pyc b/vtk_py/createIntArray.pyc new file mode 100644 index 0000000000000000000000000000000000000000..18a554b4d817754dda50ceca7f3b64944f0b8002 GIT binary patch literal 529 zcmbtRJ5Iwu5S_KnFC<75bR57H7NVd*2;>F|jAW-u6ZtbJ3I1t!94S($!V$P2XW#%Z zV>^mcv%51pzc=%|wtq&0ukV{Ag??FlKd_ifRv8}!Ilu$}6=W8CDwtRjj9i-w=D)mx z)M4|0MZi9bxn)HF3k4g14+qu`EG$?9Y!oPQY*=%ycQ|itoyb*;4P0qQGGa;ZblTm| zB|T~#ujq*V2q}mQq>J8eiUjrRn_m@mRboko&i6Cprq0oHjfHS2=#d!7G~J<2x(Kz^ z?W85@q%uf{oSDZ$z-0?sWvtY+p5};Nhz4Vw&b%l8#bfT%dgY}WW5O-_t9nIe wjM|UNCz$~&P(w9pcl*Mjgh=>~b%UW)?56*R!ZCNcE2^x?@m}89$j=)(f2Wjq?f?J) literal 0 HcmV?d00001 diff --git a/vtk_py/createLVmesh.py b/vtk_py/createLVmesh.py new file mode 100644 index 0000000..041180b --- /dev/null +++ b/vtk_py/createLVmesh.py @@ -0,0 +1,39 @@ +######################################################################## + +import sys +import vtk +import os +import inspect +import vtk_py + +######################################################################## + +def createLVmesh(casename, meshsize, epifilename, endofilename, verbose=True): + + if (verbose): print '*** createLVmesh ***' + + cur_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) + + LVgeofile = cur_dir + "/LV.geo" + LVtempgeofile = "LVtemp.geo" + mshfilename = casename + ".msh" + vtkfilename = casename + ".vtk" + + cmd = "cp " + LVgeofile + " " + LVtempgeofile + os.system(cmd) + cmd = "sed -i.bak s/'<>'/'" + str(meshsize) + "'/g " + LVtempgeofile + os.system(cmd) + cmd = "sed -i.bak s/'<>'/'" + endofilename + "'/g " + LVtempgeofile + os.system(cmd) + cmd = "sed -i.bak s/'<>'/'" + epifilename + "'/g " + LVtempgeofile + os.system(cmd) + cmd = "gmsh -3 LVtemp.geo -o " + mshfilename + os.system(cmd) + cmd = "gmsh -3 LVtemp.geo -o " + vtkfilename + os.system(cmd) + cmd = "rm LVtemp.geo" + os.system(cmd) + + + + diff --git a/vtk_py/createLVmesh.pyc b/vtk_py/createLVmesh.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fab74de4ffe2cce930ca8e7104ebc9a3f7b7040e GIT binary patch literal 1234 zcmbVL&2HL25T3P-L!6L9)s{-VxR-*Ez=vF;s8Uol2bu$|IB7mB6o}K-6e!dypUyb0$&%<#->&L*z@Qo~Osht*B+MwW3ML@16jDT%`HMY_1n^rdROrDO5508}u5W333X% zhv7r2VK)!Cful0pvbJ|&F*2YzV;G2v*i4NSoX$##YxQ`{_x9O>3!NBipJ*eY%|7tS zby@0#xhUn54+GyaXfnbFo3bsliD>{ZW?PZn2p2s2ri~oyhf1tVy;Z-BccaU3&a0dd z?;JTADWE?@YiuS`;Hu`0MI3{S4MjE(`gFgy{mRldU}P7LpheR>)6qPcYaI$ps& z(do(O2v^UG+h}`6dd2OEfvvfbsN4~sj!$)`>jcVIfeM@#s-fOMu}M^sSg0(kf~cTfv|R+~B0`EBdzv_nW6LvXRphM7 zC-4z`7JLIA0Ow8~G;Jy&;bg{l?%aFk+{ZZct5W>-bGPf!?6L5EgCTuP7`{P6qV_^I zsBO;m8ER+da+ccJxtybRZZ2EYw#bJIEVCr?Bnsr`=qqg282m$>PYizJIaL{mZ-cWQ zUU+`IR$07yq3nAF2L%TdUX^H2 zCK!X;1YEc7S)>(|cpDWvm5(v+?CjWHB3vapD0C=f--b$Zc^xR4JrT(=7LYqigt1m| z(VLg*LUMn2v8_;hvgK3EQuuZwXm;HTTROG9y%QkH;EUMbuQ@fzjy0!e%V#T0kI&A7 zp%}U0%$Px+YiLKBkUu*s-CB3t>=n@O;$Rv35sd7{u6;W!yAj!P6B|jmtd|>8C1+<2 zQ?Ed$m{uh9t%zOKS9z@cAmJFa>~`fsABG~Q;-^*Nf)7F5S)V&q46 zwXJ(vF2CnWT@1ww4xP(5WzQdg&_}P~Lm{t{035Ne_bx@!jpWo0k#&%bS;Uc!n0>g9 z&{vBL+|H|xmBDi`9QQaN2&5NZ}@4-#I!sai+;|mYcbW^l&bg zwM;_3!bBO13TDGB8kUhWN@mgAHY(;5qhh?cHP#_p&~NCuUWA{fi4!%=(Ky60+zX?) z#l12u*tKkN>RR0N+U~tOL}qyTF&T>%-+{lu{ZE8^%w8Dzi;rPVLz8Oj;E= ztMUo_8DGGbEgt~qPLohUmN=Q~EKpq?%1aT=NEl2lSHhT9dfJHroM|e-) zo5)-}hVq_nq-9nZ19!7`r7x8O5Ep^A@D9v1N{XPH^v2O;pu*1K;h9uZm3)>*N1d>v zIIt5=0`;5&y8U1qebCJV)rLcvZME<3!lrGAT$xE1k)G;0zC}{bqf8ncjnzh<%vB*{ zZS)hVFOpPhCW#kiDd+m4Jd literal 0 HcmV?d00001 diff --git a/vtk_py/ellipsoidal.geo b/vtk_py/ellipsoidal.geo new file mode 100644 index 0000000..5bc50ba --- /dev/null +++ b/vtk_py/ellipsoidal.geo @@ -0,0 +1,112 @@ +//Thick-Walled Prolate Spheroid Script + +scale = 11; +//lc = 0.05*scale; //this value changes the resolution of the mesh // medium +//lc = 0.025*scale; // Medium 2 mesh +//lc = 0.030*scale; // Medium mesh +lc = <>*scale; //Coarse +//lz_o = 1*scale; // outer long axis +//lx_o = 0.5*scale; // outer radius +wt=0.15*scale; + +lz_o=0.7*0.95*scale; +lx_o=0.35*0.95*scale; +wt=0.112*scale; + +lx_i=lx_o-wt; //inner radius +lz_i=lz_o-wt; //inner long axis + +Point(1) = {0,0,0,lc}; +Point(2) = {lx_o,0,0,lc}; +Point(3) = {0,0,-lz_o,lc}; +Point(4) = {lx_i,0,0,lc}; +Point(5) = {0,0,-lz_i,lc}; +Ellipse(1) = {2,1,3,3}; +Ellipse(2) = {4,1,5,5}; + +//OUTER ELLIPSOID + +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{1}; +} +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{3}; +} +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{6}; +} +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{9}; +} +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{12}; +} +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{15}; +} +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{18}; +} +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{21}; +} + +//INNER ELLIPSOID + +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{2}; +} + +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{27}; +} +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{30}; +} +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{33}; +} +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{36}; +} +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{39}; +} +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{42}; +} +Extrude {{0,0,1}, {0,0,0}, Pi/4} { + Line{45}; +} + +//Upper lines connecting inner and outer half spheroid and the related surfaces + + +Line(51) = {16, 9}; +Line(52) = {15, 8}; +Line(53) = {14, 7}; +Line(54) = {13, 6}; +Line(55) = {4, 2}; +Line(56) = {19, 12}; +Line(57) = {18, 11}; +Line(58) = {17, 10}; +Line Loop(59) = {40, 58, -16, -51}; +Plane Surface(60) = {59}; +Line Loop(61) = {51, -13, -52, 37}; +Plane Surface(62) = {61}; +Line Loop(63) = {52, -10, -53, 34}; +Plane Surface(64) = {63}; +Line Loop(65) = {53, -7, -54, 31}; +Plane Surface(66) = {65}; +Line Loop(67) = {54, -4, -55, 28}; +Plane Surface(68) = {67}; +Line Loop(69) = {55, -25, -56, 49}; +Plane Surface(70) = {69}; +Line Loop(71) = {56, -22, -57, 46}; +Plane Surface(72) = {71}; +Line Loop(73) = {57, -19, -58, 43}; +Plane Surface(74) = {73}; +Plane Surface(75) = {59}; +Surface Loop(76) = {14, 17, 20, 23, 26, 5, 8, 11, 64, 62, 38, 41, 44, 47, 50, 29, 32, 35, 66, 68, 70, 72, 74, 60}; +Volume(77) = {76}; +Physical Volume(1) = {77}; diff --git a/vtk_py/exportDynaDeformationGradients.py b/vtk_py/exportDynaDeformationGradients.py new file mode 100644 index 0000000..cd3a1b9 --- /dev/null +++ b/vtk_py/exportDynaDeformationGradients.py @@ -0,0 +1,36 @@ +######################################################################## + +import os + +######################################################################## +#open d3plot "''' + d3plot_file_basename + '''.d3plot" + +def exportDynaDeformationGradients(d3plot_file_basename, stateno): + lspp_file_name = d3plot_file_basename+'.lspp' + lspp_file = open(lspp_file_name, 'w') + lspp_file.write('''\ +open d3plot "d3plot" +selectpart shell off +fringe 91 +output "''' + d3plot_file_basename + '''.history#11"''' + str(stateno) + ''' 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1.000000 +fringe 92 +output "''' + d3plot_file_basename + '''.history#12"''' + str(stateno) + ''' 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1.000000 +fringe 93 +output "''' + d3plot_file_basename + '''.history#13"''' + str(stateno) + ''' 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1.000000 +fringe 94 +output "''' + d3plot_file_basename + '''.history#14"''' + str(stateno) + ''' 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1.000000 +fringe 95 +output "''' + d3plot_file_basename + '''.history#15"''' + str(stateno) + ''' 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1.000000 +fringe 96 +output "''' + d3plot_file_basename + '''.history#16"''' + str(stateno) + ''' 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1.000000 +fringe 97 +output "''' + d3plot_file_basename + '''.history#17"''' + str(stateno) + ''' 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1.000000 +fringe 98 +output "''' + d3plot_file_basename + '''.history#18"''' + str(stateno) + ''' 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1.000000 +fringe 99 +output "''' + d3plot_file_basename + '''.history#19"''' + str(stateno) + ''' 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1.000000 +exit +''') + lspp_file.close() +# os.system('Xvfb :2 -screen 0 1074x800x24 &') + os.system('/opt/lsprepost4.1_centos6/lspp41 -nographics c='+lspp_file_name) diff --git a/vtk_py/exportDynaDeformationGradients.pyc b/vtk_py/exportDynaDeformationGradients.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b3fbb73b8e970d8ce23af26a17459b027f4c37b9 GIT binary patch literal 1580 zcmb`H&2HL25XZ*`5@JZw4_eeqWzh>#6%2t8kkYDEBDI(1KyJMt$1K6A@vb~W6C`q? zkI+}@gY+5t0PU=?+W6qAvbthtXMa2M-`x@G!jE0+>-X-Z2T3z|e8U}|v6=ACfB@hl zJ0^T#$I#@WS>RRwC%1D?XB3lu$|F_`fK{AXzcYb&V(RR*33mlp72ujR*a4_diclvL zRtBsMo|T{;)2$TUPG~trcM@u)XeFW56x~heUW)D~^g)U~Oz5K&eVou*iavolpWDz^ zD!>}RpdwtCVDePoI9}ocUNq}mlyfYxZ3UOxZP>t<|NMUw zw?0|uaJ(ZGIs6JDp(IkT)fsytB#C_uRj*?ogz_qK)y((M_Fgr&IEP===Bbc=LpPC6 zg7o(XDT;{~NEG}T;UFZPfJ-DXZ|XFvvDv(=@zf8*_|ioYx^qF>I*?ovp`<)ZE7h)JNA?5}$vu@% z;Lf-44SWE+StpKCj@aJu%$s>LZ`X*ZxYtINXsEmrXqCd8vCA-br2MHh-f zi@pQ2Bs=ZfsEq#L8VADO!4k;BDxNDMCW;l^65Uu-S`=F=B(~{RkrJq}hMG0BLnWC& z=(~n)Q)yG&k|siw#GXl1^tSl%zF6qGCdz+O*`U}Fy(JV_7*@rmlf>y0Q_{Ipg19ab z%7HXB1Mi7<(=>Yj9cZhvDFcPml}gc>_DImqHY!lnRysZMmjQI?LgP_qMYs`)t5NqDxLYnDFVU^L=`D&u7->y%Ay7tnBgH1q~j z(+$MB+bAm7bi=3`WMRAuLo=!eAIZTt&i!CR%4#}et_^q^ZD6_Q$Nn~HQWM> zdBb$RsOGGLBcFYieSe;ZK5LdeW6X)pW}5Tmag?ymd9UjFalzpCrQFO7bdp42BHEk4 zq=U~Lc*WK!3A;wj*7e<8?4x7_UiyXZBP3&rSMb~`sBx1Z(b}EpLi>4e<-Ye$T`2uB zU%D%%2RX-iHv1%-dNE(}!%f$%oP4F?84OvD>f!Dv$E-uuRXwW<+Xix|9$7urw#*-G jBIV|!s-cs|h&MX_Uu+BgUeB^{k?1$_^D9K9qa5omw+!x7 literal 0 HcmV?d00001 diff --git a/vtk_py/extractFeNiCsBiVFacet.py b/vtk_py/extractFeNiCsBiVFacet.py new file mode 100644 index 0000000..61eced8 --- /dev/null +++ b/vtk_py/extractFeNiCsBiVFacet.py @@ -0,0 +1,203 @@ +import vtk +import vtk_py as vtk_py +import dolfin as dolfin +import numpy as np + +def extractFeNiCsBiVFacet(ugrid, geometry="BiV"): + + tol = 1e-2 + + #ugrid = vtk_py.readUGrid(meshfilename) + + # Extract surface + geom = vtk.vtkGeometryFilter() + if(vtk.vtkVersion().GetVTKMajorVersion() < 6): + geom.SetInput(ugrid) + else: + geom.SetInputData(ugrid) + geom.Update() + surf = geom.GetOutput() + + bc_pts_locator = [] + bc_pts = [] + bc_pts_range = [] + bc_pts_map = [] + + # Extract Surface Normal + normal = vtk.vtkPolyDataNormals() + if(vtk.vtkVersion().GetVTKMajorVersion() < 6): + normal.SetInput(surf) + else: + normal.SetInputData(surf) + normal.ComputeCellNormalsOn() + normal.Update() + surf_w_norm = normal.GetOutput() + + #vtk_py.writePData(normal.GetOutput(), "normal.vtk") + + zmax = surf_w_norm.GetBounds()[5] + + surf_w_norm.BuildLinks() + idlist = vtk.vtkIdList() + basecellidlist = vtk.vtkIdTypeArray() + basesurf = vtk.vtkPolyData() + for p in range(0, surf_w_norm.GetNumberOfCells()): + zvec = surf_w_norm.GetCellData().GetNormals().GetTuple3(p)[2] + + surf_w_norm.GetCellPoints(p, idlist) + zpos = surf_w_norm.GetPoints().GetPoint(idlist.GetId(0))[2] + + if((abs(zvec - 1.0) < tol or abs(zvec + 1.0) < tol) and (abs(zmax - zpos) < tol)): + surf_w_norm.DeleteCell(p) + basecellidlist.InsertNextValue(p) + + basesurf = vtk_py.extractCellFromPData(basecellidlist, surf) + baseptlocator = vtk.vtkPointLocator() + baseptlocator.SetDataSet(basesurf) + baseptlocator.BuildLocator() + + ####################################################################### + + surf_w_norm.RemoveDeletedCells() + + + cleanpdata = vtk.vtkCleanPolyData() + if(vtk.vtkVersion().GetVTKMajorVersion() < 6): + cleanpdata.SetInput(surf_w_norm) + else: + cleanpdata.SetInputData(surf_w_norm) + cleanpdata.Update() + + connfilter = vtk.vtkPolyDataConnectivityFilter() + if(vtk.vtkVersion().GetVTKMajorVersion() < 6): + connfilter.SetInput(cleanpdata.GetOutput()) + else: + connfilter.SetInputData(cleanpdata.GetOutput()) + connfilter.Update() + + print "Total_num_points = ", cleanpdata.GetOutput().GetNumberOfPoints() + tpt = 0 + + if(geometry=="BiV"): + nsurf = 3 + else: + nsurf = 2 + + + for p in range(0,nsurf): + + pts = vtk.vtkPolyData() + + connfilter.SetExtractionModeToSpecifiedRegions() + [connfilter.DeleteSpecifiedRegion(k) for k in range(0,nsurf)] + connfilter.AddSpecifiedRegion(p) + connfilter.ScalarConnectivityOff() + connfilter.FullScalarConnectivityOff() + connfilter.Update() + + cleanpdata2 = vtk.vtkCleanPolyData() + if(vtk.vtkVersion().GetVTKMajorVersion() < 6): + cleanpdata2.SetInput(connfilter.GetOutput()) + else: + cleanpdata2.SetInputData(connfilter.GetOutput()) + cleanpdata2.Update() + + pts.DeepCopy(cleanpdata2.GetOutput()) + + tpt = tpt + cleanpdata2.GetOutput().GetNumberOfPoints() + + ptlocator = vtk.vtkPointLocator() + ptlocator.SetDataSet(pts) + ptlocator.BuildLocator() + + bc_pts_locator.append(ptlocator) + bc_pts.append(pts) + bc_pts_range.append([abs(pts.GetBounds()[k+1] - pts.GetBounds()[k]) for k in range(0, 6, 2)]) + + + #vtk_py.writePData(connfilter.GetOutput(), "/home/likchuan/Research/fenicsheartmesh/ellipsoidal/Geometry/test.vtk") + + print "Total_num_points = ", tpt + + Epiid = np.argmax(np.array([max(pts) for pts in bc_pts_range])) + maxzrank = np.array([pts[2] for pts in bc_pts_range]).argsort() + + + if(geometry=="BiV"): + LVid = maxzrank[1] + RVid = 3 - (LVid + Epiid) + bc_pts_map = [4, 4, 4, 4] + bc_pts_map[Epiid] = 1; bc_pts_map[LVid] = 2; bc_pts_map[RVid] = 3 + baseid = 3; + else: + LVid = maxzrank[0] + bc_pts_map = [4, 4, 4] + bc_pts_map[Epiid] = 1; bc_pts_map[LVid] = 2 + baseid = 2; + + + bc_pts_locator.append(baseptlocator) + bc_pts.append(basesurf) + + + dolfin_mesh = vtk_py.convertUGridToXMLMesh(ugrid) + dolfin_facets = dolfin.FacetFunction('size_t', dolfin_mesh) + dolfin_facets.set_all(0) + + for facet in dolfin.SubsetIterator(dolfin_facets, 0): + for locator in range(0,nsurf+1): + cnt = 0 + for p in range(0,3): + v0 = dolfin.Vertex(dolfin_mesh, facet.entities(0)[p]).x(0) + v1 = dolfin.Vertex(dolfin_mesh, facet.entities(0)[p]).x(1) + v2 = dolfin.Vertex(dolfin_mesh, facet.entities(0)[p]).x(2) + ptid = bc_pts_locator[locator].FindClosestPoint(v0, v1, v2) + x0 = bc_pts[locator].GetPoints().GetPoint(ptid) + dist = vtk.vtkMath.Distance2BetweenPoints([v0,v1,v2], x0) + if(dist < 1e-5): + cnt = cnt + 1 + + if(cnt == 3): + dolfin_facets[facet] = bc_pts_map[locator] + + + dolfin_edges = dolfin.EdgeFunction('size_t', dolfin_mesh) + dolfin_edges.set_all(0) + + epilocator = Epiid + lvendolocator = LVid + + for edge in dolfin.SubsetIterator(dolfin_edges, 0): + cnt_epi = 0; cnt_lvendo = 0; + for p in range(0,2): + v0 = dolfin.Vertex(dolfin_mesh, edge.entities(0)[p]).x(0) + v1 = dolfin.Vertex(dolfin_mesh, edge.entities(0)[p]).x(1) + v2 = dolfin.Vertex(dolfin_mesh, edge.entities(0)[p]).x(2) + + epiptid = bc_pts_locator[epilocator].FindClosestPoint(v0, v1, v2) + epix0 = bc_pts[epilocator].GetPoints().GetPoint(epiptid) + epidist = vtk.vtkMath.Distance2BetweenPoints([v0,v1,v2], epix0) + + topptid = bc_pts_locator[baseid].FindClosestPoint(v0, v1, v2) + topx0 = bc_pts[baseid].GetPoints().GetPoint(topptid) + topdist = vtk.vtkMath.Distance2BetweenPoints([v0,v1,v2], topx0) + + lvendoptid = bc_pts_locator[lvendolocator].FindClosestPoint(v0, v1, v2) + lvendox0 = bc_pts[lvendolocator].GetPoints().GetPoint(lvendoptid) + lvendodist = vtk.vtkMath.Distance2BetweenPoints([v0,v1,v2], lvendox0) + + if(topdist < 1e-5 and epidist < 1e-5): + cnt_epi = cnt_epi + 1 + + if(topdist < 1e-5 and lvendodist < 1e-5): + cnt_lvendo = cnt_lvendo + 1 + + if(cnt_epi == 2): + dolfin_edges[edge] = 1 + + if(cnt_lvendo == 2): + dolfin_edges[edge] = 2 + + + + return dolfin_mesh, dolfin_facets, dolfin_edges diff --git a/vtk_py/extractFeNiCsBiVFacet.pyc b/vtk_py/extractFeNiCsBiVFacet.pyc new file mode 100644 index 0000000000000000000000000000000000000000..53e15b7c36a81f4824529f2c13a437330406c955 GIT binary patch literal 4911 zcmb_g&2Jmm5uaU(lt_!Rz9ri6x0A?Uk}Suuow`XQ*;0&JvP&ycVW1^e+$VaeM^4^iijq>qz}!@|ul3t!lD z?`MCY7q)nK{D>@p@J$hU}aej~!91O*-N)1PgTFb0aiW%(8&bFD9r%v*wp&gcJq`>Qjp_f zf$03oO3OTH3jDc+0&|L{5vC;QMZo}_{Icx?B`6#+c$?yBKK0LS+P#&rSoBU8e`em5 z{Y=gDr~@zzuB9Wu_&O7p1Pttc2@FU9#$hQNrgJbw^-IKjZ%Yguy1apB3efOLO%tGD zPDm3>nI-^}HbIu^msu&jkrO7h>1U<~3*SFkdXd4H%rY|EzsN&o5cs$SnkpR@l(^d& zvY+&^>)m6SO)2683a777{VMT#jRVB}a5_rK6zN%Znr{3xZ^Sz}`HJZ;ZLJ zsN@UkYY?FhWH%C z=cs-oy-%#phQ$`|v6QbEzOWXpEpn9Q(S- zq2lvYe?JX^Ypn#6`mK~t-u_-Yxd4)PzSj=DgHpcBaKsm=RKHCz1`C6P@d1J}1ZYIj zyG$`n*l|g^_zu?w_-pjKmKP;eLf;bY>5C^h9!%`yshTor`u_gDbrn4BN@9AU!ARJazt^ z)`RDTtMqrdb$WQu{*QRS+3t0`-)wgn@2juleO>ToMGx=mg7?A^crOUvm;lu8%qdj8%Me>actcT@bmFaEB*?(dfPV@1#3E%A5z2!FT5-yMq4%cdX3^D&Cpqfs6V zM>0nNZk(RcoqT+!YXo}U7|n|jc4Vb_%6YyX&=<3Gmv_U;D8A_D+rlVzzv#z%bGOpJ z$y0?kyF%L;{7@UhFR``S=i|R$`R4hTA9*>jUX~X;b9m*K_Yg@5~Lb`*KfRYlkS`Rp&h{QA4UemHZN6>PVscl3z)Tv1^| z>DK5cUtuR8Ux)fMwk$R|oa2%2rJ2M;m#9PLQxPn)iz zmBuej-v6kr*^<2>^yARqXT!Cy)o}bsk3+l^HejKal<%kFM?rV@V%QGcNK#vDd%pY7 z3w9z=!r23`k=6{OaO?X`^>M4^?CWDMN7IaI%L!^q4}(HhYwgCCYCYQKpplqE$c&tV zkzk`V$@C=a?WV78=%P`w@nb1NH`kP7fUsFO2@K|eE7&_*<|y}+ugrn*%Yx`Z5CQ%* z)zKS{-&O)54peFG3qFvyoT_BE+zK0yB}LvRc%l&=hE+$0rhq67>+vDQF`%V-u0dHf z!aZdYaLwr%61ZCOl@oO9qfd4Hn|dvUL7=MI+w*j{UAT!Dq!h{Y^cNsS@cSlb^wDbQ zs`cw|)Q3S}w;u zrJ742;N;10noSkBn#U_>8cD0xa5_>eN7{$ygeCoK-l|2wRuZm;!5%90=}OCU*TbK# zK3rANGjZXD{x&MXy|L_6m0oTKKnqjEE+VBXj_*sOK51`(eSmqBl5s+qER7m-qAJjy z_Ee;Km^;#}%U<9v`C$a1X({%Ia;-Z0nVtlF4>RBdRkg6F^k+(;gnTzh_3yhi)y-sv z|NSRtY}b&!gsY_&fHbELea+Vg3x$ZG9t6FL5sN$z>#5o(01WC1Kym)d_LBlcV z1~Nr5W9+f=S%oDM;W>lM?mXA;PV$x$sVZhG6)`F-l4KZ_rrEiNZscsAH^WF^XQQU> z=E!+exuN+ka^(I%@q%r0({X)uQwth_cxDOCD7f!Pt_QmpWWW!6^JQ|s>7^Lr2+wi$ z9m(e52Be%;nF#?3X@TSm$@EC2!9Bx`lJeW!FOlRTq_j-;9Gq7*(9*4Y^XB8a`B;!Z zO%3nd%bj`QUB;2G<Q&B-I5g7x} z2+HjUO5!rD!)DI{bZP-gEVwSlofvU-4GX&i9h=TTMY2So; zKAZbwX?4zAlym7NxvbW_r3nA!AyYVuk>`8kjY_UgG{h}s=dy#=v^8uOt%5aZ=PY?; z4rGw_4cl1d^_F$U9=6Wgi&oJZw?`qvzP`eNz0Er(?J=uhPgpr{c{`Vxv2g^Zy Z{trbOfWy0u&~5wbL#{}~0)zIT{a@e`EIj}K literal 0 HcmV?d00001 diff --git a/vtk_py/extractUGridBasedOnThreshold.py b/vtk_py/extractUGridBasedOnThreshold.py new file mode 100644 index 0000000..206d291 --- /dev/null +++ b/vtk_py/extractUGridBasedOnThreshold.py @@ -0,0 +1,37 @@ +import vtk as vtk +from vtk_py import * + +def extractUGridBasedOnThreshold(ugrid, arrayname, thresholdval): + + selectionNode = vtk.vtkSelectionNode(); + selectionNode.SetFieldType(vtk.vtkSelectionNode.CELL); + + idArray = vtk.vtkIdTypeArray() + if(type(thresholdval) == list): + selectionNode.SetContentType(vtk.vtkSelectionNode.THRESHOLDS); + idArray.SetNumberOfTuples(len(thresholdval)*2) + cnt = 0 + for tval in thresholdval: + idArray.SetValue(cnt, tval) + idArray.SetValue(cnt+1, tval) + cnt += 2 + else: + selectionNode.SetContentType(vtk.vtkSelectionNode.THRESHOLDS); + idArray.SetNumberOfTuples(2) + idArray.SetValue(0, thresholdval) + idArray.SetValue(1, thresholdval) + + selectionNode.SetSelectionList(idArray) + + selection = vtk.vtkSelection(); + selection.AddNode(selectionNode); + + extract = vtk.vtkExtractSelectedThresholds(); + extract.SetInputData(0, ugrid); + extract.SetInputData(1, selection); + extract.Update(); + + + return extract.GetOutput() + + diff --git a/vtk_py/extractUGridBasedOnThreshold.pyc b/vtk_py/extractUGridBasedOnThreshold.pyc new file mode 100644 index 0000000000000000000000000000000000000000..28e130b3f87ba04bf6422557b79ec7e859fa7930 GIT binary patch literal 1190 zcmb_b&5ja55U!r#ZxL2lHrb1wybuq|K@%@VcLiKFK}h(~#Kf4{=~jkq2ArwcED6K| zK7#MzGx-cYfL3)gV?5|dpliCTzWVB`>cRa{Er0#~=*oxv$D!vLt@r^MNk0J^;H}*| zpao2%3t!0PaBSSn5ia;ipFva57TG-XU9tzXINGKaPsxt}a{)VmtqU6$=FZ+TcVQ<$ za5!heIlw$@9QI-Xt{sTJnS^4RP%;Ud9Lx^@%X=uvIc6T|z%~!JpV{4c_ZYSXVB{Ux z5NQE+4v6eby_}@JJU8@&Qa>TQ3D5pskzicMl2A2PnvoJ?dZrdDTsm#8YMLv;rU>&x zrcVQRO`rsu63lDBj9?k@GU$@I!E3D9=U8dw zW3UVdOR2Cz&auLmfzooaUMVzJ)$RB3(84c``#g%gwTWR0(m{*{MCt8ih$=)wP^P>| zZ`2+4hW*YM>$bokSzM`T_+gT)w2F-;O&KK{eeLN)8G%HW3G8zP7D(zdCl<+ZE~Qa_ z&j!1<7uhV zTB+7Z#mbBPS*zE6)uIW!U#(mFtmy?weBs4P4#TY3)72Vz9{SC_XT^-})AqOi|JOu`c%LqoGSTW8*Nj

rUfF6h5{?fRF%77Ff2sY};+6s6QI1RsU2~+vV0>3BoF&R6?pEV^6?Y$M)J2 zN+k1(K0;rmZ_$_NGxP!4@0@Wi6#B0*o;lZV&TWkISFQ5fpI@GPRQzo0-{Z|*WAX84 zQAl()p)ESI#&Vm^Y@uxm9XeraP$fE1bL2bpD{RXQ&}oza7W|E0t6_oEynN=Bu|B~& zhj$lm_LT!2QQx9lqMI`1W$N3M6Wv;5G2>7UUBQ&t%3}LDv7e`WUQA$EW{DU=G%tp% zT$oUc6RI+yrhrQ*=71%#+-TtH1-YT~je@f*4_LoW%`^2Be2@)DP3i#OYB z4sG2!$a4alFH(P194DviM+7MnyIB+ka2$h!jd8Hu$60z12T20QLn9OlhfeJJzfTP8 zj_%2yn`7U`;b_m*?rt1K%F{?kkBVeo!UD^; z083ZF?hJ#_AM0x-yn`@y^{X^>M|$3PwA_Kx-2T*!E)>2GM5y_=cXGz069vaTgpF`g z?t>um?}X3a>w&8;H51wURLf}?m?IW$K)4rV+KoK*#g5XyC>0gZ+~hY=h9PRHYklg5 zLnSjeK)E=l@v)qz9F1gOal=%{b3-@H#)T-@1`n!uM%i>uW$^rX-~yFXKRoqxDpXr2 zp3D6tU?ErON~P!Mn)D%6y&zKlKxLN#+nXI&F0yAvsAsMM-xrkxa^T^qiu_o}wjnuN zXcHcWuxR8OWXAHI*m&I$^V9*sFRCg37!%F6H_ zbt5n~4e%sO_BE*HWjs*L5aX$uZIvlE^)8#QcaNHAb~hO{(M7&D-7E||)z#y#$>$hr z{!ILbnh(uFEM!-$8lDRFx>XrJV-7o>a>aT9P2H-_6?>`J9rkA5JFD}|TDMnLu%OjNW^_E<1)S&ba{rD~c literal 0 HcmV?d00001 diff --git a/vtk_py/extract_slice_thickness_LVonly.py b/vtk_py/extract_slice_thickness_LVonly.py new file mode 100644 index 0000000..0628b98 --- /dev/null +++ b/vtk_py/extract_slice_thickness_LVonly.py @@ -0,0 +1,85 @@ +######################################################################## + +import sys +import vtk +import math + +from mat_vec_tools import * +from clean_pdata import * + +######################################################################## + +def extract_slice_thickness_LVonly(nsubdivision, domain, verbose=True): + + refinedmesh = vtk.vtkLoopSubdivisionFilter() + refinedmesh.SetNumberOfSubdivisions(nsubdivision); + refinedmesh.SetInput(domain) + refinedmesh.Update() + + bds = domain.GetBounds() + ctr = [0,0,0] + ctr[0] = 0.5*(bds[0] + bds[1]) + ctr[1] = 0.5*(bds[2] + bds[3]) + ctr[2] = 0.5*(bds[4] + bds[5]) + + featureEdges = vtk.vtkFeatureEdges(); + featureEdges.SetInput(refinedmesh.GetOutput()); + featureEdges.BoundaryEdgesOn(); + featureEdges.FeatureEdgesOff(); + featureEdges.ManifoldEdgesOff(); + featureEdges.NonManifoldEdgesOff(); + featureEdges.Update(); + + connectfilter = vtk.vtkPolyDataConnectivityFilter() + connectfilter.SetInput(featureEdges.GetOutput()) + connectfilter.SetExtractionModeToSpecifiedRegions() + connectfilter.Update() + + epi = vtk.vtkPolyData() + LVendo = vtk.vtkPolyData() + + connectfilter.SetExtractionModeToClosestPointRegion() + connectfilter.SetClosestPoint(ctr[0], ctr[1]+1000, ctr[2]+1000) + connectfilter.Update() + epi.DeepCopy(connectfilter.GetOutput()) + epi = clean_pdata(epi) + + + connectfilter.SetClosestPoint(ctr[0], ctr[1], ctr[2]) + connectfilter.Update() + LVendo.DeepCopy(connectfilter.GetOutput()) + LVendo = clean_pdata(LVendo) + + + epipointlocator = vtk.vtkPointLocator() + epipointlocator.SetDataSet(epi) + epipointlocator.BuildLocator() + + LVendopointlocator = vtk.vtkPointLocator() + LVendopointlocator.SetDataSet(LVendo) + LVendopointlocator.BuildLocator() + + epidistance = vtk.vtkFloatArray() + epidistance.SetName("Thickness") + + + for p in range(0, epi.GetNumberOfPoints()): + pt = epi.GetPoints().GetPoint(p) + + LVendoid = LVendopointlocator.FindClosestPoint(pt) + LVendopt = LVendo.GetPoints().GetPoint(LVendoid) + + disttoLVendo = math.sqrt(vtk.vtkMath.Distance2BetweenPoints(pt, LVendopt)) + + epidistance.InsertNextValue(disttoLVendo) + + + epi.GetPointData().SetActiveScalars("Thickness") + epi.GetPointData().SetScalars(epidistance) + + return epi + + + + + diff --git a/vtk_py/extract_slice_thickness_LVonly.pyc b/vtk_py/extract_slice_thickness_LVonly.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a10f576cecc713e34b4948a2cbcc52fabe4b84e3 GIT binary patch literal 2293 zcmb_d-A^M`6hG4`P)b=~%Pz9+!s=>le6Wc=nGlta#oYwTrbSFhOdV!!VY<_~-MP0& zli|VOpWq*;i4VT}2k7sdnQ39&_+;C;b3T6O`&@AUTCD#1`xj?E<)0GX-{3JXa0K`{ z6cL?HXopUnLSCZNlF%iJTsmens4^X^846tb1=v}3&}o$6Ec_dvR>J{l`S{d#ao)!> zgJ&0y`2*1{QQx5(qHC8@m-;12iEbQnn1KkooGCNPfuKJl_%g@Je&;S-BL~=uaGhT+ zt*@=7kUF%LYsw^=nL^`EG_#pzuF#ZeixZobK(mz2N-oG~jwO;2L=|QnR?bhT>V#UD zP+8{eu*S0MIZEfmAuOj3AzI8#Kut~ViAhBomC^HJzBIuuQWzfg8ip*1E^E|WJd za-6tKE7V^R2b0M5K0%72t}CK=+h6YMEkE<`^n*sg&%9(?m&~h_R;j<5hj5sAAgOad zGROj@3jz^qhnXqlp?IlLTBH6N1sUY(XR`0{Xt|tqM%p5^*1E*P3k{oaJtNXS&Nn-{s)wqlo0~?<9O_dM(E>Nr-uMR9hVm-Y+@l=l3}CLT2Kp#ycSJ45A%y-)>h zbq=Ai3wJ$PZr(fWb|Y<2+AAH#HZzqXfV{1drtK*;+||Rexb`FE#a-^4SM*AJ9BALO zI7jvNfKb6#36Jw0up6R(2t?34>b^$i8&vZ`4^%V4>ZoR08RaGZ zMf1h(VH1Ps4#!P&n0LBsqR>}eTipBZ!HJHe@n_h)4S4x)6sKT*#6hK+vxsjM?NylbVZ^9kg2r{-?vZ?= 6): + geometry_filter.SetInputData(ugrid_cell) + else: + geometry_filter.SetInput(ugrid_cell) + geometry_filter.Update() + cell_boundary = geometry_filter.GetOutput() + + pdata_points = vtk.vtkPolyData() + pdata_points.SetPoints(points) + + enclosed_points_filter = vtk.vtkSelectEnclosedPoints() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + enclosed_points_filter.SetSurfaceData(cell_boundary) + enclosed_points_filter.SetInputData(pdata_points) + else: + enclosed_points_filter.SetSurface(cell_boundary) + enclosed_points_filter.SetInput(pdata_points) + enclosed_points_filter.Update() + + points_in_cell = [num_point for num_point in range(points.GetNumberOfPoints()) if enclosed_points_filter.GetOutput().GetPointData().GetArray('SelectedPoints').GetTuple(num_point)[0]] + return points_in_cell diff --git a/vtk_py/findPointsInCell.pyc b/vtk_py/findPointsInCell.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7ce4398168969a60d4ba90568028554f7feb9d3 GIT binary patch literal 1460 zcmbtU+iuf95S?}IX+kfdEiL_khzBB39(X{Asx3`~npWurR0%A{-lTRNJ6*4zvH|ye9;B8{qIr z9@ec>oKu7iH4yucGEL(Coal@{eiw8h%{dh8z>S&b7OVo1F z?x~?8)rmww<20W7vQ42(cFHHJ>2GS2bQRp(NHs({EJ!@YV>IufE0YuSVis>&bOtF- zzHuh0IZ8F9Gp1y77{-BPsTrRi31p>}BE5zoG7}*4<=J$5f_Rekq>Gr+HQj()w$TH; zMBBLQT;h3leA}0@Gmw$AlzrLh?jCkfcyl`IjNBl*!M%X)#`Eb+FJa!_e$pU%feREH zq9yQwOVPFZRk0ip!3U=QN4JW#UQa?N P_T?M;??v=-Zj^rmps`q8 literal 0 HcmV?d00001 diff --git a/vtk_py/getABPointsFromBoundsAndCenter.py b/vtk_py/getABPointsFromBoundsAndCenter.py new file mode 100644 index 0000000..d93aa69 --- /dev/null +++ b/vtk_py/getABPointsFromBoundsAndCenter.py @@ -0,0 +1,25 @@ +######################################################################## + +import vtk + +######################################################################## + +def getABPointsFromBoundsAndCenter(ugrid_wall, + verbose=True): + + if (verbose): print '*** getABPointsFromBoundsAndCenter ***' + + # Note that it is assumed here that the ventricle is vertical in the global coordinates system + bounds = ugrid_wall.GetBounds() + center = ugrid_wall.GetCenter() + #print "bounds =", bounds + #print "center =", center + point_A = [center[0], center[1], bounds[4]] + point_B = [center[0], center[1], bounds[5]] + #print "point_A =", point_A + #print "point_B =", point_B + points_AB = vtk.vtkPoints() + points_AB.InsertNextPoint(point_A) + points_AB.InsertNextPoint(point_B) + #print points_AB + return points_AB diff --git a/vtk_py/getABPointsFromBoundsAndCenter.pyc b/vtk_py/getABPointsFromBoundsAndCenter.pyc new file mode 100644 index 0000000000000000000000000000000000000000..31f26e05ef5c71ea9c8b4dbbb6e8861c0ecc4770 GIT binary patch literal 738 zcmb_a%}&BV5T5O}h@|Mn3&9vprr}@@UX8Jk2p%K`JaK8D-9WLlq`O5);DqrBd_kYV z2hf=Xq6fptP3N1RotgbQyZp0UdjGf_2C!WQ>Khb!iV)(*AO`3I2nL}6uMGMI1$z$1 zgy;)bC!nGO6ceS1BHs{}46-9iZM75h044xyfR&+brfm*OPHiisI4bOILS@8ZW&W{c zZMG~>228l_P=I9tCYWr(ngQE7*3RiU1*FoE=ZN)sy*3icYdoY;qU3FsP8(^SgwjjG zrbv{?YM2sXCPa*YekZaJ90GNS&=P7>v-38EiiR;)PdbWvbAmd?=v^X3raIz9>7YY% zQYD0ZltrQcJcwgOvAM{GsT7L%4mB-p2AY`8m=SH?`(-!uc{(nAui;=RXpkOS?l_$a zHx6PU+^&#fkOgD6-Mn{^pg&u<`)6@6Tc|VavOkNM%M%3P1t@Zx*}TfCsLQNu=qJ*p i$DwGHk6A9dHX1)X|C4MHJ6}!HFptGGU5BKDZR;EB!l&H; literal 0 HcmV?d00001 diff --git a/vtk_py/getABPointsFromTTTSectors.py b/vtk_py/getABPointsFromTTTSectors.py new file mode 100644 index 0000000..a4262fa --- /dev/null +++ b/vtk_py/getABPointsFromTTTSectors.py @@ -0,0 +1,69 @@ +#coding=utf8 + +######################################################################## + +import numpy +import vtk + +######################################################################## + +def getABPointsFromTTTSectors(ugrid_sectors, + verbose=True): + + if (verbose): print '*** getABPointsFromTTTSectors ***' + + nb_points = ugrid_sectors.GetNumberOfPoints() + nb_cells = ugrid_sectors.GetNumberOfCells() + + nb_csects = 12 + nb_rsects = 3 + nb_slices = nb_points / (nb_rsects+1) / (nb_csects+1) + if (verbose): print "nb_slices =", nb_slices + + zmin = ugrid_sectors.GetPoint(0)[2] + zmax = ugrid_sectors.GetPoint(ugrid_sectors.GetNumberOfPoints()-1)[2] + + dist_btw_slices = abs(zmin-zmax)/(nb_slices-1) + if (verbose): print "dist_btw_slices =", dist_btw_slices + + A = ugrid_sectors.GetPoints().GetPoint(0) + B = ugrid_sectors.GetPoints().GetPoint(6) + C = ugrid_sectors.GetPoints().GetPoint(3) + D = ugrid_sectors.GetPoints().GetPoint(9) + + #print A + #print B + #print C + #print D + + Px = ((A[0]*B[1]-A[1]*B[0])*(C[0]-D[0])-(A[0]-B[0])*(C[0]*D[1]-C[1]*D[0]))/((A[0]-B[0])*(C[1]-D[1])-(A[1]-B[1])*(C[0]-D[0])) + Py = ((A[0]*B[1]-A[1]*B[0])*(C[1]-D[1])-(A[1]-B[1])*(C[0]*D[1]-C[1]*D[0]))/((A[0]-B[0])*(C[1]-D[1])-(A[1]-B[1])*(C[0]-D[0])) + + #print Px + #print Py + + A = [Px, Py, zmin] + B = [Px, Py, zmax] + + if (verbose): print "A =", A + if (verbose): print "B =", B + + points_AB = vtk.vtkPoints() + points_AB.InsertNextPoint(A) + points_AB.InsertNextPoint(B) + + cells_AB = vtk.vtkCellArray() + cell_AB = vtk.vtkVertex() + cell_AB.GetPointIds().SetId(0, 0) + cells_AB.InsertNextCell(cell_AB) + cell_AB.GetPointIds().SetId(0, 1) + cells_AB.InsertNextCell(cell_AB) + + AB_ugrid = vtk.vtkUnstructuredGrid() + AB_ugrid.SetPoints(points_AB) + AB_ugrid.SetCells(vtk.VTK_VERTEX, cells_AB) + + return points_AB + + + diff --git a/vtk_py/getABPointsFromTTTSectors.pyc b/vtk_py/getABPointsFromTTTSectors.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d56871001061868fd45337abdc693c54e2b013bb GIT binary patch literal 1901 zcmb_d&2Ab=5Uw7~kAX4R;4D5wB8N!Ghvl%>I0`t4W384%HfybXL5AtIhvmnbZnE}j zI3?$t@&tK?yilGY50L$;dN9UPBp(b+byw9_UsqSv*s1S+{`0rr`U6Tn9@ZClOamgo zPtl0z^k%Q5@aQA^` zLNGCRA1CiXO3oPRm^YJcq%oE7n-QD`RwypNNX*jXwbu=A! zyWL|wu+zxY;SGyGg((&a!W1AT{hk?x18wSiAyf+aJvEyUL1=8RZ~tBT`PB{A+0PuU z`kt)q`d)+amc@a#o!Pjrqql#%ENpqzy01qgV{^_Z5WIOrXMJOt8SzORTi@G%#ELbs zmS8=c7#-P;zH(5@w*rEhTTyg&y$Cr03Lw7ag7z>lC@|5nwugb;SRvzhTX9@}PK=Fa z13Qa!a1e!oP$DSFg42iQ?vjUc(*3=6^6IGj>aPa>jkDa8**OAx#+Bb@VR^5k{?uq8 zL)|Z>O;QVJ11SvGfE5mN6@eD5Xs%s$4aon-Xtdj$U0JTpou*mtb4z4f|?4KA8*_Wx+2 zF}=&{=1=GH*UM|W1A?CdxV)wVL8%PoyrL?48I@6wRECOPMLqUvvfEbj&3;i|(j`^$ z;1zpO`O4=gMELw*@2iT};IhdqOlITD>m!~DDP=dB>7%F6mN$H$Yvw@uY&;ESBmJC@ KGn@i4OaBks%7MoK literal 0 HcmV?d00001 diff --git a/vtk_py/getCellCenters.py b/vtk_py/getCellCenters.py new file mode 100644 index 0000000..4088c23 --- /dev/null +++ b/vtk_py/getCellCenters.py @@ -0,0 +1,33 @@ +#coding=utf8 + +######################################################################## +### ### +### Created by Martin Genet, 2012-2015 ### +### ### +### University of California at San Francisco (UCSF), USA ### +### Swiss Federal Institute of Technology (ETH), Zurich, Switzerland ### +### ### +######################################################################## + +import vtk + +import vtk_py as myVTK + +######################################################################## + +def getCellCenters( + mesh, + verbose=1): + + #myVTK.myPrint(verbose, "*** getCellCenters ***") + print "*** getCellCenters ***" + if (verbose): print "*** getCellCenters ***" + + filter_cell_centers = vtk.vtkCellCenters() + if(vtk.vtkVersion().GetVTKMajorVersion() > 5): + filter_cell_centers.SetInputData(mesh) + else: + filter_cell_centers.SetInput(mesh) + filter_cell_centers.Update() + + return filter_cell_centers.GetOutput() diff --git a/vtk_py/getCellCenters.pyc b/vtk_py/getCellCenters.pyc new file mode 100644 index 0000000000000000000000000000000000000000..307b0c59dde9a82d32f87bcbeb086bac14e8af5d GIT binary patch literal 666 zcmbtRO;5r=5S`ruB7!lR7>^tY2OHzn7!yp;7&QU)z=f1{mDbXd?m$9}#%6i{d4_c|-6%W@F{BF_em9FlR2y(lO;w&m{06J! zP3IVnv}*ILkcXHmGqIk9%14<|=#w!b_)wRnVS^2tTn2};ESaK(jLX17hT6Q(rN~{H z`RF3H(c{D*e^;=~9Fi1FvQz~+(n= 6): + poly_data_normals.SetInputData(pdata) + else: + poly_data_normals.SetInput(pdata) + if (flip): poly_data_normals.FlipNormalsOn() + else: poly_data_normals.FlipNormalsOff() + poly_data_normals.Update() + + return poly_data_normals.GetOutput() diff --git a/vtk_py/getPDataNormals.pyc b/vtk_py/getPDataNormals.pyc new file mode 100644 index 0000000000000000000000000000000000000000..548c724b06dd0efff1652e9c39c3717735d3d702 GIT binary patch literal 804 zcmbtR&2G~`5T0EpX=>t9ssa)hdW>?w5?m2N3hIwg(4B=N7`AFhV*@I<_RX7g{^jrdbw04@Pg0csd& zxYuwQ3Eyu@asHQ|&QM^5O|!Mx{7-fZ4Q@wDkB$of0+=Yc1NafaB7%t)tOP{?NxlM; zss!BUrV6ef3TvR>5 zl2O*NZkic?z+7JAT(iNBB6hcQLwn1$Yt8&gF}-5CZKvgouxs;z9z@Q@W7=P*+Gxxw zQ&7B=xJ;fr`g216)oNSNGAnrOGm0dAt>SC(B$P>b!UU&31k=F%27s0 z+YGtM*^F4ODR)Fwc9P6U!ZC}{7K2-KSJorFkTmahASHuhc{oibAvph@QF?8sn3|zM zOnc}tbHnTOxP6-Pi4Dqmx^cAc$~isf-!^FJ>ff+~N)76|p<;ets$HF^8YB|wFmX>x o!q|s=PZ-8NcQfqmGQXbezs9Sx)W@kE%?y5$tM_s?jcTO+0T9%>5C8xG literal 0 HcmV?d00001 diff --git a/vtk_py/getcentroid.py b/vtk_py/getcentroid.py new file mode 100644 index 0000000..6ae2671 --- /dev/null +++ b/vtk_py/getcentroid.py @@ -0,0 +1,16 @@ +######################################################################## + +import sys +import vtk + +######################################################################## + +def getcentroid(domain, verbose=True): + + if (verbose): print '*** Get Centroid ***' + + bds = domain.GetBounds() + + return [0.5*(bds[0]+bds[1]), 0.5*(bds[2]+bds[3]), 0.5*(bds[4]+bds[5]) ] + + diff --git a/vtk_py/getcentroid.pyc b/vtk_py/getcentroid.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ede7f4f399cf504eb19bb1a14998ee71b46c5cf6 GIT binary patch literal 536 zcmbVHO;5r=5S@MiRnZfP;nrirfjxLNYUBVHIiQIN7X#f1R7*>`3rQ0^;ZN`f>TmD| z=$k^6vy<+dx39BrX1uS{tX-xZYk#BHJ1km^#N{Pn5+@Y~U?2>lr4cwE0`^ZCa z@{JhAVj$N#P7lXC0yYj6XHwc9WVjJM6K#oJE1wO}qqZcU+UG4;3$N{@`hnEgNr6Z+ z4}Fi|Jv1#~r_%}hY{MRBw#XA5LYP5Ed|W4z5=TJBOR8~wVKqP`Kde~6;5J`n+Efc! zSwZKENs`$H=$eaZZrIA}DQb|Y0@DRk^L)W7jZlC<6H threshold_min)] + if (threshold_max != None): + values = [value for value in values if (numpy.linalg.norm(value) < threshold_max)] + avg = numpy.mean(values, 0) + std = numpy.std(values, 0) + else: + avg = [0]*nb_components + std = [0]*nb_components + farray_field_avg.InsertTuple(num_cell, avg) + farray_field_std.InsertTuple(num_cell, std) + + ugrid_mesh.GetCellData().AddArray(farray_field_avg) + ugrid_mesh.GetCellData().AddArray(farray_field_std) diff --git a/vtk_py/mapCellDataToCellData.pyc b/vtk_py/mapCellDataToCellData.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43de8737d9bf8b55b3dc1c5f914431cd72556862 GIT binary patch literal 1932 zcmbtU&2HO95S}GvNtPw~M^c=h7RaFo!G{WHf}n?@X&~2$0oN&H7Xb{U1SPH|()>}# zl^dhf$-VT{OP?U`(C6qYq|Z>G*Y=yC6g#QWO9^s!X7-!^S=xU#YQO&RU^t@1vx5CA zeA(AnJiLlRqLX*Dq7x-@i$aTz83D=$WiuA9ULmhUKb7dD%z|cb z69q-PFMm|?bun9~d|iAs7>9DS<{J`ilX4I?wewX9fE85UWPb`=&bMIh6PmZg+${>WDQ~e3 zaAze-hYBn!4_O%v$kEe6|M&maU!gO^|7NNGW}(kf-)6TSdSTJLEspP8lXNJ)%co-m zQKL2x*O(6Fbqelsx$-s}P4i|PWU)x;cs32Sh@rFZ zNqG;Ej#MM`V>c{H9w%uehmm$;sVaIPb=r?JotnZ98-3z=l4F+xmLz85)b|_|*1g6? zI-3Z4>g&*RVmH!;n>a$zoKSLhQrGy2bDE@}B+&+&oTN}qpcA2&A4uHSQo?hc4wFoq zZQ!}1u6TFE_GmE~tU2XzaKgnrT%kF*f1~4}GrDRv=gN|IO+J;vIz>J_syq(w3AtqL zrQ6K;L3+5%P3+AgF(`lLP^V>KYH0QDUEL;1E;2hxVxP;DT(Jn93k#(?kkpw0{5*1>HoGHS=^Ob;G{yUI= 6): + filter_cell_centers.SetInputData(ugrid_mesh) + else: + filter_cell_centers.SetInput(ugrid_mesh) + filter_cell_centers.Update() + pdata_mesh_cell_centers = filter_cell_centers.GetOutput() + + point_locator = vtk.vtkPointLocator() + point_locator.SetDataSet(ugrid_data) + point_locator.Update() + + nb_components = ugrid_data.GetPointData().GetArray(field_name).GetNumberOfComponents() + farray_tensors = createFloatArray(field_name, + nb_components, + nb_cells) + + points_within_radius = vtk.vtkIdList() + + for num_cell in range(nb_cells): + l = (ugrid_mesh.GetCell(num_cell).GetLength2())**(0.5) + + point_locator.FindPointsWithinRadius(l*cell_length_ratio_for_radius, + pdata_mesh_cell_centers.GetPoint(num_cell), + points_within_radius) + #points_in_cell = findPointsInCell(ugrid_data.GetPoints(), ugrid_mesh.GetCell(num_cell)) + + if (points_within_radius.GetNumberOfIds()): + tensor = sum([numpy.array(ugrid_data.GetPointData().GetArray(field_name).GetTuple(points_within_radius.GetId(num_id))) for num_id in range(points_within_radius.GetNumberOfIds())])/points_within_radius.GetNumberOfIds() + else: + tensor = [0]*nb_components + farray_tensors.InsertTuple(num_cell, tensor) + + ugrid_mesh.GetCellData().AddArray(farray_tensors) diff --git a/vtk_py/mapPointDataToCellData.pyc b/vtk_py/mapPointDataToCellData.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f8fe4ee420fd5e4a9f7953f29d1d820a97ef22be GIT binary patch literal 1688 zcmb_c-HzKt6h33;f0Ny9H%nVuP%opsAW{((NQhGHs%_Nm7Nwz;Rw|YgPZGP1oqEPC zD>+x&N8oXI0$uX0_r7JJU-_;|34G=&ra*7KRzE%X#KeOev8+9fg`|A zQA~8cr4^kk!5xYn8U-$Cmx2ntbLhOn+Ru7bScZS$IqNBqmXD(u4m`i#o3MBvZv*c! zUh^{)iV9`BZ2s_30!~pxbV;jHdZU!mLbW$;)hR%gbxO6WQ0 zFiq^$(){`8@e@Bvvklw^{7lp9ZlP)Sz#*>GaGFkh zn`ROamRtxvmOUfiZJFX3!2K-qFYI9{-Byz>mT7{_jnp~GG-5u8Q-7__(GhPDoQB3) zz8#sL%(ShSZn$oV5C5k+nc4XrtOC)4FbO09^CGnKFd6zmn43)|B9Yd?Y?H|#D7$L% zg~Unn#qvTZUlQm3Kz)=iV=XY4L11?P4-%uZwS;*{Hj|Z*_k%!+@9`)l-F%jXfrtM3 z|6mu|%!QqXIu5+VUub&^784Zd#ZsM@`8G_wX_|qOlDH9XbT&?nmRQNyV|`-}Aee?R zRzd(A<$7EL&Xe^$j`wd_hh@B;Uc88Ovz=gp)e4#bkTzz$zi?%)t{#e-H#`+*8QP2+RrBQ{-fh3eQbiayy$=U5`Bho z@$5e=E4R zPobfw;WPLKJ^7JM$*|xwZNE$Mds{nkT^e3TF1;a=d~HqIU=a z`h-AG9=aglt<$K7-_$QWCz(LVwgEeYnQw5G=)Itij_4L=0=fvOK5}@_;JdsX((c>? zh#2TO0N5?^bZPpI=F2)w;13UQICS(405&GwSmOAj0sdqU2}d|tKBS{#ix~Bw1*g#n zg`6ljQXxBTlHyX;fSv0>ACWnLdt2*jKDm~e)%7G-rL2t7)kIZ{rI{{LtJ893Q?n?i zlhT_-KGR9EHY!ZN8*AEbk3bv^Ttyiqpd)VLoJ7$Yp?oY_YdpX*Y_MOH`| zC(_7Sot?+Whi~F*dy!r)VouEWuv!;piabv|P3K~)q2VnOJ7OEQBc8&Z4ff}@{H{XOpGzAMDg33Q+2Jtz6sHO5ukGmgBpn|^uVm$6^A{PGZK243ub zN9;$arV+clA~Vh?r@_C>_W{e^h+6P~*^{XdNL V5JWFZonIC5r4x@UANNL&e*>*8>5~8e literal 0 HcmV?d00001 diff --git a/vtk_py/myPrint.py b/vtk_py/myPrint.py new file mode 100644 index 0000000..d05d59e --- /dev/null +++ b/vtk_py/myPrint.py @@ -0,0 +1,25 @@ +#coding=utf8 + +######################################################################## +### ### +### Created by Martin Genet, 2012-2015 ### +### ### +### University of California at San Francisco (UCSF), USA ### +### Swiss Federal Institute of Technology (ETH), Zurich, Switzerland ### +### ### +######################################################################## + +import numpy + +import myVTKPythonLibrary as myVTK + +######################################################################## + +def myPrint( + verbose, + string): + + if not hasattr(myPrint, "initialized"): + myPrint.initialized = True + myPrint.verbose_ini = verbose + if (verbose > 0): print (myPrint.verbose_ini - verbose) * 4 * " " + string diff --git a/vtk_py/partitionmeshforEP.py b/vtk_py/partitionmeshforEP.py new file mode 100644 index 0000000..0ad12b5 --- /dev/null +++ b/vtk_py/partitionmeshforEP.py @@ -0,0 +1,66 @@ +# Partitioning Biventricular mesh for visualizing EP measurements +# This script partition the mesh into polar segments: +# Input: ugrid = vtk file containing BiVMesh +# : center = origin of the polar coordinate system (if none, mesh centroid will be used) +# : xaxis = direction corresponding to 0 degree in the polar coord system +# : nsectors = number of circular partition +# : nz = number of longitudinal partition +# : meas = measurements of size nz*nsectors + + +import vtk_py as vtk_py +import vtk +import numpy as np +import math as math + +def partitionmeshforEP(ugrid, nsector=6, nz=2, meas=None, center=None, xaxis=[1,0]): + + if(center == None): + midx = 0.5*(ugrid.GetBounds()[0] + ugrid.GetBounds()[1]) + midy = 0.5*(ugrid.GetBounds()[2] + ugrid.GetBounds()[3]) + center = [midx, midy] + + + cellcenter = vtk.vtkCellCenters() + cellcenter.SetInputData(ugrid) + cellcenter.Update() + + zpartition = np.linspace(ugrid.GetBounds()[4], ugrid.GetBounds()[5], nz+1) + apartition = np.linspace(-math.pi, math.pi, nsector+1) + + regid = vtk.vtkIntArray() + data = vtk.vtkFloatArray() + + for cellid in range(0, ugrid.GetNumberOfCells()): + x = cellcenter.GetOutput().GetPoints().GetPoint(cellid)[0] + y = cellcenter.GetOutput().GetPoints().GetPoint(cellid)[1] + z = cellcenter.GetOutput().GetPoints().GetPoint(cellid)[2] + + # Determine position in z direction + zloc = np.argmax(zpartition>z) + + # Determine position in theta direction + norm = np.linalg.norm([(x - midx), (y - midy)]) + angle = np.arctan2((y - midy)/norm, (x - midx)/norm) + sloc = np.argmax(apartition>angle) + + regloc = (zloc-1)*nsector + sloc + + regid.InsertNextValue(regloc) + data.InsertNextValue(meas[regloc-1]) + + regid.SetName("Regionid") + data.SetName("EP measurements") + + ugrid.GetCellData().AddArray(regid) + ugrid.GetCellData().AddArray(data) + + vtk_py.writeXMLUGrid(ugrid, "/home/lclee/Downloads/test.vtu") + + + + + + + + diff --git a/vtk_py/pyquaternion/__init__.py b/vtk_py/pyquaternion/__init__.py new file mode 100644 index 0000000..11d8282 --- /dev/null +++ b/vtk_py/pyquaternion/__init__.py @@ -0,0 +1,2 @@ +from quaternion import Quaternion +import quaternion diff --git a/vtk_py/pyquaternion/__init__.pyc b/vtk_py/pyquaternion/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..11f3b4b7b9281b94f406c630a432b658d891934d GIT binary patch literal 218 zcmZSn%*!?9p>a|&0~9a;X$K%KRsa$yK*Y$9!@!Ws$PmTIzzE_qf%s8iMz97mP*LW8 zAkbh0vP!ssL||!RNorAEW`3TZ2FNh5U?E&E2q?s$fl3rx0QveE`MIh3ImtPxsro^w z#i@x!$r<_{&c6C(CE4)>mHGvh2t)Ma<1_OzOXB183MxxDfSPS`^HWN5Qtd#lCg`kf)!uNV)TLZV-N=hn1BoiATAaF5-AKRj5!Rsj8Tk?3@J>(44TX@fuanW zjJLP~OA|{{i}Et_^ZYcKqQna-3*iEK2xbw;xRne=%s>iE{EBk6iU}=FEh>%)F3pQ^ zEGTeEEJ=*<$xlwqi3v%~Er=<|EYQu&D=taQ$F4FjFm&V literal 0 HcmV?d00001 diff --git a/vtk_py/pyquaternion/__pycache__/quaternion.cpython-37.pyc b/vtk_py/pyquaternion/__pycache__/quaternion.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8116ea7c089a8294e3d436238ea1a59c230f0f6 GIT binary patch literal 44060 zcmeHwdvGMjdEdSOEEc%;k-Q@*YIq`f0EyQ<_|S5Os-~0Qz`?SEdm^y@#LNc=}$1b=BH zp2p8#!a*hG5-O=umE=llF13=LORr?+GD+S`S9(@@=XzKA=K5B$bJ>;tx&D>hTyAAx zZeV3_Zg6GC+>Vu(n<^*9r~StCnk3Tr?JOTB)hEikr(#uHn)<;RJur zmtC(=bza)2R&y`8m;G|XwGS5?jk%u`nsv+r zX9yR=x!lQGeZwo478}k`ao9OJapYkq`c1j>uD4S5Sp&Oi(e>QR8%_z|+;G*1v*5Wd zyREob@JjB8)2KOx>V{KCoA5&Ia-&eLma8SF;1p3$PC6LH__c+`dckv%SvdvYuNBMa zaOJ3IH^|ud&Jc&>&;|3xp<$^+xrIuuT$SMp9y#mi=h|As@m#;*m5c1k5vN=&R@M~T z5InAwSIWAh<#qXZKZlmD`S=31bA-cPUf|i4&#JFou9W@75l59-^yRe%a{9a}ojk(t z7_WJb?^Y@~lu&m40GNW-NgnnO`UdrzF7kP2eX+I@|B|wwTUZ19`HScjwYNQa?bbT4k%&%xKNUG^Io_;R7*)N7v9*ZG-asQFZJO%hgp|j^4R%nWvI*s?vI4_)@Ir$t) zo_uEN?9}WlBe^qEv(qf|%()q7(m6jlGdp$i;@Qa==lsQ)^XD#{M)jvq?DW+1nHkh_ z`i0Zevty_g_ngx&;=;M`+~nD_tSUEo5v`wL`<#>K&c8A<_3U%A&U5F^o;r=2&zwff zCZ9QbT33aSI(c?->V*;K)Z`13&$4wh&N-AalVdjBI_IV5PV*M)o5cTH<6D%*?qLMsn;g9IY zFIU^?V$E-73QT4SO!pK3gh$(H_iDYJuGC7yNfhV0bz<&xku?T?86=*@&;J})jhmQD zg2|**axSe>D*bw5E~7H42j?EmBIbJCK9yDduP3f2=dwuW)PSV>ksee#B%M<`)h@g< zpmwW0I1j45Y9G!!)P8jv&O6oZ>JFTDsRQaD&b!r}>Mor3sJqoWaNeu#QSZcgAE@2E zIPX`7)VpxLP2H#N$N6^kfI5ux9coAo<9t9ps2;-kpc+x5INzzp)Hu#}sR?xi=eyNW zbqwcssN?EkobOSOs7G;rr+Q4i8)rwIQ18L{UiG+o0_Q{ON%a)Y?@~{zNu2Lf) z->*)o(>On%&ZuW`KCGToQ#cQ)_p0Y{9(Es8XVnYR2M-}VtdQrWE^8}u~tX`34N06RVuS)tT(wEe0l0Js?`&C}j$B~{_1xY`wen%CR zdObP!h;r2eN_$k5)FRH0sj^za`Q2(+Rd7Cmky=qzdFwq$*Hm57k0ZURJV`%+w67YH zeiG?5bw$!oA-%4yO8RM}H&j#7lSqF+wIuxv($~}nC4Ca<-&G${AAUUvcsYfu-&5Ds z>vDBkeN=r6?Kz{qU%i3zv-p~is~?c}oXVY5Li$tc2POSp^+W1Sfd*cQ5 z>6^)gr235dEWUagxjv_USaO|1`t#}wl0J|07uA;}{XV3BM15J(Gf4la`Y}mgK>91{ z$0a?B^bK`W(if5b3H6hbei7-fs-KedOGy8;`WZ>TjP%#k&r13gq<>ERyrk!l{<``F zNx!OoQT-BHeM$YY`W2jCQ@^Ty4d?f(f1-XJ=e#?wenb7H`5jPCrLTT;XJnvMh=+>!o%@VRfc#(f&tzGL8@MHuR7JWmCLT@fbT|#R4zv` zC@d602zjRO6d|TvcFE+GQ*x^=Bm}Ux4TvAk@l&QOe?;C!iMYE~1)B~_?r4-((=vol zK6&hv~Pd1E@0Cvo4{;i&fHtP836*LO<*snyZP-nrJURwd3EqGpGLl;&= zr^w$99JBcC!q5McR3gzxv;cY6(yg>gE@$6Nd50Q_H$b~^mBH1ZO1+U-?)4{BnrH8W zZzOI&z*d=?scV@QDBp6{d#}n|%T%+CR4ap$GLj=*N+3s1D{&*;0%c^nk-5>+%CveG zQa6*WM85aU)T*QUr1T$DStjXrGE{j_e$x#D7{y5WTo^zDZNih?~~Gd zTYa(8`=#{1Q8{xSFy}#@-%NVm#(tLZMnd%;gouw;W?xEF@5v+@eaksKpGYS7uaQ+d zt|vc|d?is$y^P*L59Dqp-%QrukGD|=t_N-=^&Pny)M>Q5zmdB!(8{*@Z>E-d`PJ1g zs-33xH%;9;QTMK!DS6sdyUo*I#G7cR+I=u_Gilzv)YyUYcizPKT+4lb0=T_L?R`Dl z%AMk!0gUAUMs6R*G3os^#$!Mw5Aw+%dS_Q_5S$ACN*Ue%)t%CR1Get{%moe<&-KfI z43?PkzS-E_0$dzSG;-HdxIU||bla#D>1&P}o_dWv>bAz-#y)-bI-u+hwB;kojr-6t zDQByeu`GO3 zOe1DpfC_R>kleBFi5^9D0*McgeTP3AK_0sP< zjz<)2_xd0x1+U$!QM-hD@;Ci0NFRxI#)Hn%?k}$tO66+7+kiB4wd}Y1yn-qhsz@le z1Z|4)O|?{Un-?dYE9e5{1eC@(%oh$*RV}Qz&`+I}HNQccR`+UG%HWKmD!6_T8VWmZ z#Vt_zT3D;tGR9CkNz1n=8nt^@3LsQhErkJ1!Qdql`|$Jk<4{Vp60Z$jOTGd4IGFf! zYBh5q@v{ly0BKgG+D2og1~m^ zYz@70Y1Un-U#geuqva}8iArU(Q1h--o0oAjqIAbELJ|xK^sjP{11uUG&?ni$KHJ=z zXdVtJ{#ZWGk;>=C9GYwo1?|>-nRu%wg9GiFYrKIoe#@XA$1Bcn;FnhQ0aDayi9NJm8;?f%7 zw?SuRu#@t-=g8Bbe;>w`*lrTpY%-VHncAHkOlFh4scdR6Ihfj??7TjdOeJ|Yg{Nc5 zy~!M|@I&ss$(?xj_SEjo?I?-wWpL*Jb0SX$@ARhjCNr7lzAocz;g@4eTsz5z?Zlyx zXn*i!xi0n$oJT(W{@y``J4Zjoucz z0%i5z;xq!wBtCyf>L8qj0lj$);!n>8iy&f z00#n@g>MLs_z?;{QvfB8$U>x>AvT-<*%ovPDgeQ*)~cf@l|mY+;F@b`?X(^3fLdKZ zPsga0mWwpC3c&Y%WExI+@4%^@bUVh{yBD`V%VG>Qc`OQL(zY(B-i^F~pj6RoAk9>W z12m$DXgl`t=FpQAMlHPoC5NO-^Op#KWD`al6~5A(xLAd%3vm%SG__$TcPo3$dA8O# z;WP(fL@{riaN5bS;Xdy$KfI^udNtpB7t-ECyaAq6_vZQvzAy#v814;c1RJ1xyQ}SF zwVkYVcGd&P^>O_C+i^(r0`-BUDM8^oiTFU^=6$!)fkpN<|6q+3#7X1q|1l05xmI#1 zaV-UuxEm;u1WG($P$H#(4uL$^N~zRx%6p`h{CJ`|hO0ELE&=Tz-F`F$*$nc~M`lnMxYMutZYFQ0{2xTltjU>cWR?af)7?xe z$bqHBZG^Dv*pCW?oZvI;U7pN0IdqrR%W71_DY!8f)4Z zsb4TfWDwxyUJSe(kiL^?9;UzbfAH5l(@_bmmETP*Qhf8|3sR+R9a!sPtwhxl=HfAT z3}g+;9(%H0g9I9WJ@1#RS0LKBp$O4gnv4=qI4m_RR8eeOf%pflHt3s&V6V3{tskE} zh~GZ^{QnAmrjnP^*OJ##*U}{Il*3v{LNZdRmcaA@rlAA!uB5?YOb##_rtZ)=!n=}J z?xys6Qi3V11lUE{VeYUDQzM?6R&1&}t!tDL!df8V+ZLI2N-dl2o0dwAo63+kJL-=1 zf%#f_PwG36Fy9iqX!i2zvjH)0vr{r?RA2mqKV>i z#nrMs;EHYx;g1mj6Vxlh7CTBK_UM_5(_;OdJbSOjee&FA3N(IzE{G2RIt1!D5$Hb! zuQ*mH7YbuFuQaY|<#E_-$B#^m9ew!7@$sW$#~*q4c&xDDw6G`d5J2@?q~r!AvQIY$ zPnTg~5x(u8XztKgV(;)z4EG8z(lTss1-MWt&86LPsof)%;JIE%t1E@8!~Nb}D72lt z+D>k?lg)PWdDv$ucl&a7i$2_dg{zSDm3wt=A73t(>xD|5x8^knHnnWfCL32U=RUpFd24Ca9Y_j=qNQcLwVtFV5bSv2+HRZxy{6tWB z6G#nJI01%}yqUNLM50;_HkRFqI&e5JIuWUJR|o3utubMB`<&n z_j#R_YnVeMe@?CjcvZ?=OIObZrAaBML2`wq+5GZ6T2`zsQ`#@;mf?t!1`^8&m@OXY ztRZOc9lE`?Ou29ClXlo|!Br~WUU?pAuap*RQ@p%*`$+^qJc*Eym&I5HlM3bFyAtnC z@ET~hqwq@@mKb=8pQBh)VlkwUD=tCU427|ZBNOs+rBw5Pk1LKcYB$|xq0x^>7kGiy zvEuqMrH-y2J9_mfyup>)nu0J;ZH!gj#`t=D6i&PbpmrRJNv)v#ar$D%CytD3zB<~d zjgmW$)zw0*p_+NaDFf~VZO^$JBDo6_fY6e#b#&lvZXaCD>+9=d?phIw0IUYum=_cRZrb@H{S z{{^NU9>#F^3VuGX64?~U>(1oP6l?|{v-hO3=|ed0Pr`n%Kl_g69b0^;Rk-_5NH2aT z@$;)Vi24hX3TrSB8_IXeySo7$L8SOJxN!Oatiiw0If910Elo(^$6#Nl^d2# zkX@+CNbOHtgXOo?1A8_J6aq=)2tsxpmayUe!gBzRPT`(L939v|JKo<`$hVFH<8N?m z@c}Mcq!7cAGX!PR*p}V~@%}uGjUB2xTW|stQ50jN{2w#zw2dL!OM{qGbXt)IpyW!g zgpIUs7|co}n)jU#44T0=>aT{q1(J_36PWDZeyX(Rzl?tPOJ7)hA}HYLP%shVVANml zB|u1f&m45%Q^xzOt#N5cI)bnstv4Q_3a`Avv^9(&{HRdM`>QYA zD5B{`WAPXBJdkSciHxwW(vB-x32T;d9YR7S zZ$K7Yf>RD;g=b2CJVV-%a}OLyBs9Iv7bnRRMYD&NT17AqdQ}8wQ4ScD1hatkCdQ#zYF|E&cIET?*-i#u#gW3vJ#RcJI&!u8lb1Z@B9?ro96C z*_-5Hds{d`E1y4ThqAZB7OtOLlU^DnT3BDiMGLTg6A%xUyj!KN0oGfzL}&0zQ^MC4 zZkz6n-0#y8KWykwtVPS=8G4RfQ;*;^G#wfH!2$tl3bBtK%r&rH!%0>{2qW?2Z;d&j zjgIi;Zy;jxs(2XZH9F*J{h4=G%5?dV#$o)8u5fv+TxkG@nH^HKvF0JbQ@bd|Xigli z*ANfo(252VI=LwSPA%N|^k;~GnZroKy;$?t&}0n;61y+XMXX;VAV%#dg_Qy)0dOkH!D zX^;;bmKJxu zP9&SRg>VnD66A|f7DD7n{ETBr=qt2eaSWvj2o*?7F|0)VUef(Q+(5;l@dcw2VQsS> z0@i?snvaFG2Z#)FZLJCtjWT?wR6?CObd-ebs9H+}kehzqHAHdJxU0iEVf81xG~5zg zy&^o}3H+?ecWB2Cfn&PHpkopgmJqxyaytCOri2kjzVKp5at#T*4Xq9jht$I;PVF>u zZAT42*O4QiKWd3VUk6>6$Fbfg`Ip{jI5_$ql;9u?BEzZX$F}cwY3KK>V#c!<9;M zkurbD-pyq@x= z6S-Whcs;~Fc|bPk7T_u~&ezb8HXj5y4;5g8zdYB|q@{MeUY?|ou8HJ9Nla~Zzh zd{uN*5N;vl9^)TZt&^@(;Ag}S4S^B=GT|CCEtFF!FS|g{i1%#_iq8>rufVRhUA@Rl z@@4NL4(;B2-d)Y-+n{_B(Vfo^_h|QUPYsyu&GmSBHnpc9Cs>D0qj8%&#&wkS631V( zVzIMl;4!|F#vj<+V>*+ru{$6#bcMWwlyd;6DDKtNbYS92d8=&sHgYUDSJf?nN=JY( zu93)N3yI`fmU@ri!b0LbXamCj0E5XT$gjFB(3TT7pnKnhG%IKlv@8?p=dg__9e3if z(TuXu2M4J(8d^{)pI>4_si-DkD%+pzV6&1X)>zACDIK9Xx*^GFDH^6u33TaJA);N% zQd}+4H66h=Z*O(5QQ-qg&9!dWNfPz*?q8>ch!%iAI{FsA4;_l>EBXADNPY2xA&bC{bJ7`tz%K?ZeQhxeXLzlvdWjC_luH2*Cc%POz6OvG3Rf z_R_jr>$b8K_t7o8O+SxS*C7?$Ko>DC*Hj9mCyu`bws}(R8(UVZpU0}Tqje%WS`We* z52{1!AarX7wmmU-6Zw~57ZiTSU~ZvH!tc@{`)RBzOoeg*)6+SKkr_pW;em;F2T5}D>i)QgKu5CC$)cm%i8tx?zMk69}IDif{N7o zrAV!DanEMC^@>0A7T-FEp0>sQXr$(t4=0l6)~o*TTUYJbs(*aTs>3|C>X@8)71fXe z!u>-#6XZ-dg)ouAt8XCKekp}ej^j)~DcW#mgx$t5_9_Q8iwdE{l0PI%qOz=@P> z0S6KBnQlPd)am`Oczp`idPIZbU9mr8LW~4h6Yc=kJV~G~#I*a7ZfB~n9JTk=Ylt$> z$080qBBU1Ma!JDBF?>MVs2H6@8LM4y@}(V6VIx1bT86#8ph zR;r)JL{jo5cB1d#AYMnBAhl8t1x2M9eK?Tdj26(0%yg)m$SXM{fv;qC3@)jfIb z8HWN}U0N%_-t?Q1R^A=b?y*f7W6iZPETJQ4E}{A+Z4V5K*6pE(Y`gaCf)KTmuPwk4 zwg#ob|LsU?BBtlDj%?lA!pL*9LE{VBA`(5@lWP8(@XKgH)1N*9n|HBL_tz@u2R%Jm z=7t1O@DaPn8E~;er(+5e$2oVE${dUmVqk|qk!i!oA_W+IFjVkpd6?`z6~%$24MD#W zm&FJ{6U-nh3P7D;W39RuL+iBGS3*4R9*Ev=d*JtMclXE4PBw$>XyTwnj0x#zn%{M} z5r`T^JP{ix-rZ$L7u|wXl@(o1J%vY6+mvSUfejm@jzA7s7eP;e;I9+r4m9*$`2(hC5ZX~d6w5(Q`|`2HXc#yx0Yst0W($3N*RdujsVcP$i14}}l$RQ+g zS4bhp_}O+ukqcHY!=1>cNMbdSPf9u9iQT5VAeOR(SyOAu{ZFijK#@qrsEo~E>tZGg zJr77-gdYD8sf(pGyn^y^7g~}BZ$w+t%}XYA_~iXZOYFvs~eUIIpph5EC~~hkZ6Q5dxhcD`y75e3fU_T1FBx zlF?|$>N~~+{wND>|Cv1|IG53(OmTmd&1XA~q}lRhBDF?4|HVcUdK#@t_#uc1NGKlD z``B#~Ml3NO2w+Nh&lnFX1D8^m)&Ln4va5a@VaVugXoBeM-a;15n+{MT+CgHm@9b=i zPz8q=r9IA9;Rz6nzKJG;eKg{Ujv)TFgBs!iF+~cHf*HslZP3$;?8t5&^tW%Yjo}`# zL%-qu$-%GOcv0pOVjL1rL)rZ_&K>fQ_bTrRx@w1|_d~dWHHr$QPPo|BL5u!7frF%# zQ)PC8By%Vg$@WN({v)F=_dhkiq!jB-l5RyZP^)bvaSKb1(x63wnte zT0)V46(JrNREdn?O@#I^72*1G zJB&i0k)`wd_h{XaP+$~-UF-%SO{tv>MoTuMTEnL7wm$&0p#VwfCEQVDTmo&elPNtK zDYT;cQKYtDEd#n53H-aA?IBQuxkRlJku0$`FsqD-Xm>_iSRh?X7T$?QS`e`w9MFHk z0wadA=XJ;-sSf(TI%-&cgdjoOsKFK!`rbp|PfX7a;eOS50&6-5>xHoKpflt;58}8w zwy8_;Ft{u2fWzH3+Q&@vB7FBjY=&DMTQ4t{>#*SHc^JGJKfhVwkC^T9y2f}rHFI;IIq^~gs3gMi>;ICZVP3R-r^nR%%8zz9h5Du!gYw{p#W?dFaT6oE5%_$ z*%445bbSYX6V5zrL8m{i+Gyb|2A?EP0-s+&BCvaeW*VAkNYNNkXi_qpr9_(^L{$@6 z7MOM9S&-l4(Gi=NV%m{c%s(bi@GPt)QnH>r2Jr1^PQ9S#C0hN%MsY^Kmp*8?4jSb; z7N64@z-Bm8EE1X(F*lvTm+P2KW8Lir;CREAe-(O<9{YZC#byVy;-5kIVLGz(H- zO3{Q$UgZ*zAghs@7@FsZ`Qs|h9~(4(EH@)8u`7|9+$^$&p$~yg#?%-zqoZCzUFZpC(g`Mr zL>LD33M>{1$x9}O*%cDNZ!ohxTm}Jachx*t_29t>WVEXz4p!%+Y}eF0HA4J?A-#Y( zYdVe=O-H~j*BkXP0~BTsPJ_keiD)#8KY|b$pCQAHq2%fyUCNAn2U#}wo0u#t#YVa4 zz{2K!;v%1zQg1|0u?<5InUKm%&j&Z9`)RmfzX#nGvd-Z1W*65a)Q5To=2Mi-9AR2X zocVB^#xx8f(sN#$P76>$C>DhP9I$#B4~#Ts?!T4PFdKjfnrNEuNeC4?Hez6B7&GIM z)^RhG6fhW@YU#2>$Shu#=%*7DPXttSWR|JXTG}uaW;G3nN3bczJNXa5;4a>ulNB3_U6GceB%zr1hb4G2-Vi1?rDfh9!w7pg^A9fD9=K}LoJxgM)}-LXg?m?Q zmjy1%5OzIRS`p7GrkO-w;0&gv3&ji^uUs@&G|&j%6;=?i9mTb7B$O)$k|YSmM6h-o z^Wec@l7 zIrEo0OOFFRiND$_-`~|(Lpz1eBo-^0UbH8^SI;OU26$h>0qewx1-YFD@$uf|?Knbs zEUHdyVDNEb7gxmMJXwjG*%^-a7<#um3VZ~w#lRnO#S-EefEGjnT9F?|ltK?}S_6!f z1=u4;8o-_*up_RPdFCXN0nbzq|CO*Rl{`hx78kt0GCDvTJZFr<5>SQ~qE=5(3S^CT z9A(bdN(GrV9~n4{Fj&!7Km3P=E@(JV#W{hZdOJjW^iML)Tpf>j+NucaQt07=s7^Ls@0~6Ko&hXb7Y~N z#_~2%MA6RB?${zYazDV->{pYF!}aw{II56vKhq~e6F2DPR?wNOA_Xf7!ti+o6(y72Bn7R=0u1YC{n!}40mMF zORl)iOc~S*Q&~ZUaK_wNEUILeX0SxdNZ=tMg5(sgElZNN9h>0t4`vP-*bTt}LE*C;*B9D1e(__D!`ED=Y#^@v(v_v}!&$ zk|%)8kO2an1yjk95G!O+6N|8;=i`Xj?n76=o>Bh^A|rl@#QvC}&OEjVNaV8!cqcCC z^xP*)vxJD)0#gzjZzYb5{>BPdCMh=|@^=hDWXLRY*(Q5{q>+vY@zr)`*f;jpEn*|J ztIc|$EhUO`@j-&7Y6QLRC>Sk*Aisq?7PXsm7@$Sd0RXeGOa#;@ z6&apblcTRt^b3kEQm+N1!&xR<4Pa{(2MgpNV8nM~qNrKDrcf*>cLk0UE)VeNBM(3F z=p#qQ&sFn4=lmqJLaw`8V({7p12e_^c~ikC4Ch=k*3HlA3c~0BW2we^FHs!GggD^+ zBtUkqmzx&kS37ZG03VY#0RIi*0|7m;4|bxc^DC0cVnvKCX$Ksb62!L_LPsU4Fj-)n zk(MxvoAiBEEIber_>_MjpF&DS z-jNXUC_PQqJ0YkKT}W#BFDy0P6{Du+v4xv0sj1LX2<*^nK}!XKQiW?vAe)ii$ekw=fb`^fRf-klG5WBzQu9wo5V z{MoXbe-^5Foz!;P%s&kY6(kpn4gq=ngMhpeFA(@>MGWt!NnWwn(-j0AZ%JYe7W{il zV)t|*v7M;Whm!GvHWy7Gfe8H+*49I0M=OOjC!ix^5n5QzafDf@)eBvCsKv$ddtpUq z+)b)*K8`@v(aQyI=sb=LniWEVX9#v{thJgpEhe;g7Et1P->qaamL#}L$*_({>Y;O^} zq{-@S(s*28sRT&!FyO#$Rm3M18nzlV22H3!K=+;135pA=M z%A(Y)(RQ)Hg~+7y5eAq>>xOx{QCLQ74&-tejdkBkr!N$^*%o~Vnv9RGG6bD#0?Jo$ ziI%`m5<)b-W(xLgD(*1Q7o1WJi+REtNN+6$lLH#OdFsQBtjff1gMUF6+rG!Cti!T5Y z^5Ynk{2k(fv7L6s1EX7ZDy+bPCL4sv{lkoqhN4Ea-x z9|t9F535}{c<|~!e7KE#UUZZ#hH6>mJA`6Q#^d^;7#Oicf!&=615U@LOaVctH{}>$ zNwg8r+GtCGtOT2iqBTWqYCId_ABrjwz>R1)YSSxak{8ldc5w!WO3G@uR_#kkP_qXH8Rz=OXq@;>IGlO-q6{xCQl^ z9+l|12v3a&bOCOE?K{KmL4cTLPWM~RK*U|mE! zn6beGB4%V%Lpp3%UeaEBYl^0ka{G|f3kdbAhZZH_-oY|>VO1euLxd_s0st)<&9 zb~CVW3G@bTP(}m{LwW*?V>y$uR|Hhou{9j=rLhR*0_=|=0hFCxEJ!NSa#*!3FR&T= zPDOT3h(a*w1!S}cAV;WtU|Yosa@vkg2`WFq7Wo0X6<5d`%7<)MCpX;XnI9p8uwIM(n zKxya?@DOkkQ25Yf|JKugp!7|2RE;l`~8dcT)4(ncCe$kA81Div^LWgCXh#lkRiyT4u4NEbJJ&Lku62BF+@a z<@nc!AERF0g`Z!+0det|_H{?%F6?#F%6Mb4KMfrAuV)(w{KGRWta&{pL4iHhyX7hN zY?P zp|NApw;I3Jxf7-AKqAZQK(U7=}UzKSU5qg`0lRM=2GmxA-{ z15gi0WUyg-$Mg^VLIeh1DZ3Tbv6TBHFjdy`2KH*51vqTg zZW_yY_F$qFR=NEZJPB6bw@g?TtC`!g38Uw*l(1XJ*6=(@@i3c8Rjj4GBlex^tdHtp z;vlz{ya!=H2nmW#t%zl};dJajj?GE@WN!{mtzditCud`seT8C%XSBJ_Jrr?w1 zTwG0>Xs^P5w+1yMLeYX?M;I+)a${^#hGv0Uy2S=+r=Y@vE}Gcqd0xzi8dx{YfmwnO z_hX~7#h)`I$`y8i9p!qE!$J5FsZ+pmr5-32mxJY|OO@JXka@=3i-g_8ZVa$NFe0Bp zHHb)wIwZD`nmZ)DXvOTRSmltHkC4hk2~ckTIKf(C2Xx&ZnUuqz9h@5mb8YEVRUx@)%r9Ljl8zFEO@~ zagi--e+^Zh+lOGqCzt`C=t*t*uv%vi96BA(hfm|X{UQ~0roC$)h$WVi4UZ>0=?`omsiJ*n^ zi0s6YCeRx+>%}|T_$SuAV3icn_hQ|l$pgG_q^m*20FubCbYsvE)N7TsAb3Ys5XUaa zu(=w~0NV~547PifJR%mGs%R5I$T#U-tRqU(U$S7IELO4~{N{HJjU@E?Xiu#p>SEX0(!k-@HT zJ^1xvQaCQxumtmx%#z14a|aJD8vBkPF6! zooTTVXoLIDGA1e2eEm7Mf;a->syN}iI^|HWP-olW%YPv#QXJs}!N9?2*}XnTy*nZ0%rKmRxmoEjTa=q2uti`_Ip zDX~c=CdVec2e`5r?{PjK;vLz4>B5IlNI>NT$ze}0CJAjY2xGsy2%AO`3On-*%@Of6 zI?;2oa2DJHvIam{45rfwdE%sB&M(kIMjh7Tc%ib+X*W=5=c$KrDarUN+?x~su}=~s z{$1>39{|7BZehm76E32o6&*dGEbmoBRPq07(Is^P-8LwMXIpm6=B#JG>%|qM<4muK z4rLb0)NShQkg$nCErB-y@i#L0h0f>=#*;AQ9P9<8oKR~wo-5!@7t2vQ^_HV$h zZiGK#dm*TTJ;&Ly`0{YxKEz}8X3#-Hkv`!9rig9PJ?qQT1(#ih(PPSRM0)PZt0s*A zCvv`>W^Y``RIgcSNED3m0;?%#0OStA8X_VUeJ@CJtdsr@bdX?d?0n1VC~=M`#GHX2 zQ00CLj(X~(Xv`fNNEYt8JUcT5GNH|+`!IJB^Nq79#Dqqd;0|(Hu@5Rj7(`9Fq=^cM z1(uagdcV)6bX{>&)b4v&A&sn94lcT+DH~&};B)FjLc2zg=t{S^AXpDL0M}ekEcIQ7 zb2faLpAXsF!q6Iozk%=V+WzrK+5Jg<7MrwYE%O%GmP3)^-SVqA)^4J708Sym{ zKtXfXC!`A^vnmd8U2EA`TJ;38o^fvI+C6?#^VJZhi z=ik$?>RAc2gUETmhYa2T51b-r3@+L#7^iXG0X#oMY9p4F{UmO&zzP{IOL9onKs7YU zq2Guk2V_NW7zWCgYUdg?Y{EeN@ul!BsN5ZR`9y@uMK>KXug7X-%|htdPSnU*uR=-r z0bA6;)l#0^q7I|n#p)nIl{)kuBazJ*Kj>%lPky~A`vW1ngVQD*j|JGBi}_MS{PzZU)6 zaKFP)rsb5yzwI~UbFubr;D7@`kZ<<6mQMy+^3;WBF3Sx$JaA(AvcpI@=wuEQB?*_0& zyaQdUYbVz)MJgK%<;=15TdjnHvu!1^p40pm)m**RYRxZvS=(jZrt489hPlBhTM_7V!ygCCKd-D zVD)W+qyd$ zG0QO@X0qOFQb0=uxx7Nq5(F+_-5;kZl`jPRM5I{R;YM)i%bg$N#&$5ohq+?2C(>=kwRXCUndW z3Ub&{V%^p&M=WOj=ojge>*69o*kiH*+sJkFk=T&Hj5B&m4zd*KqjsvSj2)+)S#jZ; z?bbl-k)>R>t{eGbHc~{9`D|AalPo~-(_0v_<$mt~h7*lza2J;(*T|58 z40dS!(8ALYiexZZ*>G~MUj&^z#Db0v^!@-DK4$w4?#)=7L@4dtYLgV2)c6jXL}@5K zrXH2OPi)sDBi&Hb{GxoH_X~15Gh8G*IrxD6i zV?)+4mHl9}F#IO-i4-kf^w06~hk5us4-ll*WLb+$uhH~XUj7sh zKf}Y_q;9{vc2_8^>Lm~ml-k}xh%6@fH?IfoAz zNbn$jKHHh?&!n>N%cirp4Nec 0: + # Keyword arguments provided + if ("scalar" in kwargs) or ("vector" in kwargs): + scalar = kwargs.get("scalar", 0.0) + if scalar is None: + scalar = 0.0 + else: + scalar = float(scalar) + + vector = kwargs.get("vector", []) + vector = self._validate_number_sequence(vector, 3) + + self.q = np.hstack((scalar, vector)) + elif ("real" in kwargs) or ("imaginary" in kwargs): + real = kwargs.get("real", 0.0) + if real is None: + real = 0.0 + else: + real = float(real) + + imaginary = kwargs.get("imaginary", []) + imaginary = self._validate_number_sequence(imaginary, 3) + + self.q = np.hstack((real, imaginary)) + elif ("axis" in kwargs) or ("radians" in kwargs) or ("degrees" in kwargs) or ("angle" in kwargs): + try: + axis = self._validate_number_sequence(kwargs["axis"], 3) + except KeyError: + raise ValueError( + "A valid rotation 'axis' parameter must be provided to describe a meaningful rotation." + ) + angle = kwargs.get('radians') or self.to_radians(kwargs.get('degrees')) or kwargs.get('angle') or 0.0 + self.q = Quaternion._from_axis_angle(axis, angle).q + elif "array" in kwargs: + self.q = self._validate_number_sequence(kwargs["array"], 4) + elif "matrix" in kwargs: + self.q = Quaternion._from_matrix(kwargs["matrix"]).q + else: + keys = sorted(kwargs.keys()) + elements = [kwargs[kw] for kw in keys] + if len(elements) is 1: + r = float(elements[0]) + self.q = np.array([r, 0.0, 0.0, 0.0]) + else: + self.q = self._validate_number_sequence(elements, 4) + + else: + # Default initialisation + self.q = np.array([1.0, 0.0, 0.0, 0.0]) + elif s is 1: + # Single positional argument supplied + if isinstance(args[0], Quaternion): + self.q = args[0].q + return + if args[0] is None: + raise TypeError("Object cannot be initialised from " + str(type(args[0]))) + try: + r = float(args[0]) + self.q = np.array([r, 0.0, 0.0, 0.0]) + return + except TypeError: + pass # If the single argument is not scalar, it should be a sequence + + self.q = self._validate_number_sequence(args[0], 4) + return + + else: + # More than one positional argument supplied + self.q = self._validate_number_sequence(args, 4) + + def __hash__(self): + return hash(tuple(self.q)) + + def _validate_number_sequence(self, seq, n): + """Validate a sequence to be of a certain length and ensure it's a numpy array of floats. + + Raises: + ValueError: Invalid length or non-numeric value + """ + if seq is None: + return np.zeros(n) + if len(seq) is n: + try: + l = [float(e) for e in seq] + except ValueError: + raise ValueError("One or more elements in sequence <" + repr(seq) + "> cannot be interpreted as a real number") + else: + return np.asarray(l) + elif len(seq) is 0: + return np.zeros(n) + else: + raise ValueError("Unexpected number of elements in sequence. Got: " + str(len(seq)) + ", Expected: " + str(n) + ".") + + # Initialise from matrix + @classmethod + def _from_matrix(cls, matrix): + """Initialise from matrix representation + + Create a Quaternion by specifying the 3x3 rotation or 4x4 transformation matrix + (as a numpy array) from which the quaternion's rotation should be created. + + """ + try: + shape = matrix.shape + except AttributeError: + raise TypeError("Invalid matrix type: Input must be a 3x3 or 4x4 numpy array or matrix") + + if shape == (3, 3): + R = matrix + elif shape == (4,4): + R = matrix[:-1][:,:-1] # Upper left 3x3 sub-matrix + else: + raise ValueError("Invalid matrix shape: Input must be a 3x3 or 4x4 numpy array or matrix") + + # Check matrix properties + if not np.allclose(np.dot(R, R.conj().transpose()), np.eye(3)): + raise ValueError("Matrix must be orthogonal, i.e. its transpose should be its inverse") + if not np.isclose(np.linalg.det(R), 1.0): + raise ValueError("Matrix must be special orthogonal i.e. its determinant must be +1.0") + + def decomposition_method(matrix): + """ Method supposedly able to deal with non-orthogonal matrices - NON-FUNCTIONAL! + Based on this method: http://arc.aiaa.org/doi/abs/10.2514/2.4654 + """ + x, y, z = 0, 1, 2 # indices + K = np.array([ + [R[x, x]-R[y, y]-R[z, z], R[y, x]+R[x, y], R[z, x]+R[x, z], R[y, z]-R[z, y]], + [R[y, x]+R[x, y], R[y, y]-R[x, x]-R[z, z], R[z, y]+R[y, z], R[z, x]-R[x, z]], + [R[z, x]+R[x, z], R[z, y]+R[y, z], R[z, z]-R[x, x]-R[y, y], R[x, y]-R[y, x]], + [R[y, z]-R[z, y], R[z, x]-R[x, z], R[x, y]-R[y, x], R[x, x]+R[y, y]+R[z, z]] + ]) + K = K / 3.0 + + e_vals, e_vecs = np.linalg.eig(K) + print('Eigenvalues:', e_vals) + print('Eigenvectors:', e_vecs) + max_index = np.argmax(e_vals) + principal_component = e_vecs[max_index] + return principal_component + + def trace_method(matrix): + """ + This code uses a modification of the algorithm described in: + https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf + which is itself based on the method described here: + http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ + + Altered to work with the column vector convention instead of row vectors + """ + m = matrix.conj().transpose() # This method assumes row-vector and postmultiplication of that vector + if m[2, 2] < 0: + if m[0, 0] > m[1, 1]: + t = 1 + m[0, 0] - m[1, 1] - m[2, 2] + q = [m[1, 2]-m[2, 1], t, m[0, 1]+m[1, 0], m[2, 0]+m[0, 2]] + else: + t = 1 - m[0, 0] + m[1, 1] - m[2, 2] + q = [m[2, 0]-m[0, 2], m[0, 1]+m[1, 0], t, m[1, 2]+m[2, 1]] + else: + if m[0, 0] < -m[1, 1]: + t = 1 - m[0, 0] - m[1, 1] + m[2, 2] + q = [m[0, 1]-m[1, 0], m[2, 0]+m[0, 2], m[1, 2]+m[2, 1], t] + else: + t = 1 + m[0, 0] + m[1, 1] + m[2, 2] + q = [t, m[1, 2]-m[2, 1], m[2, 0]-m[0, 2], m[0, 1]-m[1, 0]] + + q = np.array(q) + q *= 0.5 / sqrt(t); + return q + + return cls(array=trace_method(R)) + + # Initialise from axis-angle + @classmethod + def _from_axis_angle(cls, axis, angle): + """Initialise from axis and angle representation + + Create a Quaternion by specifying the 3-vector rotation axis and rotation + angle (in radians) from which the quaternion's rotation should be created. + + Params: + axis: a valid numpy 3-vector + angle: a real valued angle in radians + """ + mag_sq = np.dot(axis, axis) + if mag_sq == 0.0: + raise ZeroDivisionError("Provided rotation axis has no length") + # Ensure axis is in unit vector form + if (abs(1.0 - mag_sq) > 1e-12): + axis = axis / sqrt(mag_sq) + theta = angle / 2.0 + r = cos(theta) + i = axis * sin(theta) + + return cls(r, i[0], i[1], i[2]) + + @classmethod + def random(cls): + """Generate a random unit quaternion. + + Uniformly distributed across the rotation space + As per: http://planning.cs.uiuc.edu/node198.html + """ + r1, r2, r3 = np.random.random(3) + + q1 = sqrt(1.0 - r1) * (sin(2 * pi * r2)) + q2 = sqrt(1.0 - r1) * (cos(2 * pi * r2)) + q3 = sqrt(r1) * (sin(2 * pi * r3)) + q4 = sqrt(r1) * (cos(2 * pi * r3)) + + return cls(q1, q2, q3, q4) + + # Representation + def __str__(self): + """An informal, nicely printable string representation of the Quaternion object. + """ + return "{:.3f} {:+.3f}i {:+.3f}j {:+.3f}k".format(self.q[0], self.q[1], self.q[2], self.q[3]) + + def __repr__(self): + """The 'official' string representation of the Quaternion object. + + This is a string representation of a valid Python expression that could be used + to recreate an object with the same value (given an appropriate environment) + """ + return "Quaternion({}, {}, {}, {})".format(repr(self.q[0]), repr(self.q[1]), repr(self.q[2]), repr(self.q[3])) + + def __format__(self, formatstr): + """Inserts a customisable, nicely printable string representation of the Quaternion object + + The syntax for `format_spec` mirrors that of the built in format specifiers for floating point types. + Check out the official Python [format specification mini-language](https://docs.python.org/3.4/library/string.html#formatspec) for details. + """ + if formatstr.strip() == '': # Defualt behaviour mirrors self.__str__() + formatstr = '+.3f' + + string = \ + "{:" + formatstr +"} " + \ + "{:" + formatstr +"}i " + \ + "{:" + formatstr +"}j " + \ + "{:" + formatstr +"}k" + return string.format(self.q[0], self.q[1], self.q[2], self.q[3]) + + # Type Conversion + def __int__(self): + """Implements type conversion to int. + + Truncates the Quaternion object by only considering the real + component and rounding to the next integer value towards zero. + Note: to round to the closest integer, use int(round(float(q))) + """ + return int(self.q[0]) + + def __float__(self): + """Implements type conversion to float. + + Truncates the Quaternion object by only considering the real + component. + """ + return self.q[0] + + def __complex__(self): + """Implements type conversion to complex. + + Truncates the Quaternion object by only considering the real + component and the first imaginary component. + This is equivalent to a projection from the 4-dimensional hypersphere + to the 2-dimensional complex plane. + """ + return complex(self.q[0], self.q[1]) + + def __bool__(self): + return not (self == Quaternion(0.0)) + + def __nonzero__(self): + return not (self == Quaternion(0.0)) + + def __invert__(self): + return (self == Quaternion(0.0)) + + # Comparison + def __eq__(self, other): + """Returns true if the following is true for each element: + `absolute(a - b) <= (atol + rtol * absolute(b))` + """ + if isinstance(other, Quaternion): + r_tol = 1.0e-13 + a_tol = 1.0e-14 + try: + isEqual = np.allclose(self.q, other.q, rtol=r_tol, atol=a_tol) + except AttributeError: + raise AttributeError("Error in internal quaternion representation means it cannot be compared like a numpy array.") + return isEqual + return self.__eq__(self.__class__(other)) + + # Negation + def __neg__(self): + return self.__class__(array= -self.q) + + # Addition + def __add__(self, other): + if isinstance(other, Quaternion): + return self.__class__(array=self.q + other.q) + return self + self.__class__(other) + + def __iadd__(self, other): + return self + other + + def __radd__(self, other): + return self + other + + # Subtraction + def __sub__(self, other): + return self + (-other) + + def __isub__(self, other): + return self + (-other) + + def __rsub__(self, other): + return -(self - other) + + # Multiplication + def __mul__(self, other): + if isinstance(other, Quaternion): + return self.__class__(array=np.dot(self._q_matrix(), other.q)) + return self * self.__class__(other) + + def __imul__(self, other): + return self * other + + def __rmul__(self, other): + return self.__class__(other) * self + + # Division + def __div__(self, other): + if isinstance(other, Quaternion): + if other == self.__class__(0.0): + raise ZeroDivisionError("Quaternion divisor must be non-zero") + return self * other.inverse + return self.__div__(self.__class__(other)) + + def __idiv__(self, other): + return self.__div__(other) + + def __rdiv__(self, other): + return self.__class__(other) * self.inverse + + def __truediv__(self, other): + return self.__div__(other) + + def __itruediv__(self, other): + return self.__idiv__(other) + + def __rtruediv__(self, other): + return self.__rdiv__(other) + + # Exponentiation + def __pow__(self, exponent): + # source: https://en.wikipedia.org/wiki/Quaternion#Exponential.2C_logarithm.2C_and_power + exponent = float(exponent) # Explicitly reject non-real exponents + norm = self.norm + if norm > 0.0: + try: + n, theta = self.polar_decomposition + except ZeroDivisionError: + # quaternion is a real number (no vector or imaginary part) + return Quaternion(scalar=self.scalar ** exponent) + return (self.norm ** exponent) * Quaternion(scalar=cos(exponent * theta), vector=(n * sin(exponent * theta))) + return Quaternion(self) + + def __ipow__(self, other): + return self ** other + + def __rpow__(self, other): + return other ** float(self) + + # Quaternion Features + def _vector_conjugate(self): + return np.hstack((self.q[0], -self.q[1:4])) + + def _sum_of_squares(self): + return np.dot(self.q, self.q) + + @property + def conjugate(self): + """Quaternion conjugate, encapsulated in a new instance. + + For a unit quaternion, this is the same as the inverse. + + Returns: + A new Quaternion object clone with its vector part negated + """ + return self.__class__(scalar=self.scalar, vector= -self.vector) + + @property + def inverse(self): + """Inverse of the quaternion object, encapsulated in a new instance. + + For a unit quaternion, this is the inverse rotation, i.e. when combined with the original rotation, will result in the null rotation. + + Returns: + A new Quaternion object representing the inverse of this object + """ + ss = self._sum_of_squares() + if ss > 0: + return self.__class__(array=(self._vector_conjugate() / ss)) + else: + raise ZeroDivisionError("a zero quaternion (0 + 0i + 0j + 0k) cannot be inverted") + + @property + def norm(self): + """L2 norm of the quaternion 4-vector. + + This should be 1.0 for a unit quaternion (versor) + Slow but accurate. If speed is a concern, consider using _fast_normalise() instead + + Returns: + A scalar real number representing the square root of the sum of the squares of the elements of the quaternion. + """ + mag_squared = self._sum_of_squares() + return sqrt(mag_squared) + + @property + def magnitude(self): + return self.norm + + def _normalise(self): + """Object is guaranteed to be a unit quaternion after calling this + operation UNLESS the object is equivalent to Quaternion(0) + """ + if not self.is_unit(): + n = self.norm + if n > 0: + self.q = self.q / n + + def _fast_normalise(self): + """Normalise the object to a unit quaternion using a fast approximation method if appropriate. + + Object is guaranteed to be a quaternion of approximately unit length + after calling this operation UNLESS the object is equivalent to Quaternion(0) + """ + if not self.is_unit(): + mag_squared = np.dot(self.q, self.q) + if (mag_squared == 0): + return + if (abs(1.0 - mag_squared) < 2.107342e-08): + mag = ((1.0 + mag_squared) / 2.0) # More efficient. Pade approximation valid if error is small + else: + mag = sqrt(mag_squared) # Error is too big, take the performance hit to calculate the square root properly + + self.q = self.q / mag + + @property + def normalised(self): + """Get a unit quaternion (versor) copy of this Quaternion object. + + A unit quaternion has a `norm` of 1.0 + + Returns: + A new Quaternion object clone that is guaranteed to be a unit quaternion + """ + q = Quaternion(self) + q._normalise() + return q + + @property + def polar_unit_vector(self): + vector_length = np.linalg.norm(self.vector) + if vector_length <= 0.0: + raise ZeroDivisionError('Quaternion is pure real and does not have a unique unit vector') + return self.vector / vector_length + + @property + def polar_angle(self): + return acos(self.scalar / self.norm) + + @property + def polar_decomposition(self): + """ + Returns the unit vector and angle of a non-scalar quaternion according to the following decomposition + + q = q.norm() * (e ** (q.polar_unit_vector * q.polar_angle)) + + source: https://en.wikipedia.org/wiki/Polar_decomposition#Quaternion_polar_decomposition + """ + return self.polar_unit_vector, self.polar_angle + + @property + def unit(self): + return self.normalised + + def is_unit(self, tolerance=1e-14): + """Determine whether the quaternion is of unit length to within a specified tolerance value. + + Params: + tolerance: [optional] maximum absolute value by which the norm can differ from 1.0 for the object to be considered a unit quaternion. Defaults to `1e-14`. + + Returns: + `True` if the Quaternion object is of unit length to within the specified tolerance value. `False` otherwise. + """ + return abs(1.0 - self._sum_of_squares()) < tolerance # if _sum_of_squares is 1, norm is 1. This saves a call to sqrt() + + def _q_matrix(self): + """Matrix representation of quaternion for multiplication purposes. + """ + return np.array([ + [self.q[0], -self.q[1], -self.q[2], -self.q[3]], + [self.q[1], self.q[0], -self.q[3], self.q[2]], + [self.q[2], self.q[3], self.q[0], -self.q[1]], + [self.q[3], -self.q[2], self.q[1], self.q[0]]]) + + def _q_bar_matrix(self): + """Matrix representation of quaternion for multiplication purposes. + """ + return np.array([ + [self.q[0], -self.q[1], -self.q[2], -self.q[3]], + [self.q[1], self.q[0], self.q[3], -self.q[2]], + [self.q[2], -self.q[3], self.q[0], self.q[1]], + [self.q[3], self.q[2], -self.q[1], self.q[0]]]) + + def _rotate_quaternion(self, q): + """Rotate a quaternion vector using the stored rotation. + + Params: + q: The vector to be rotated, in quaternion form (0 + xi + yj + kz) + + Returns: + A Quaternion object representing the rotated vector in quaternion from (0 + xi + yj + kz) + """ + self._normalise() + return self * q * self.conjugate + + def rotate(self, vector): + """Rotate a 3D vector by the rotation stored in the Quaternion object. + + Params: + vector: A 3-vector specified as any ordered sequence of 3 real numbers corresponding to x, y, and z values. + Some types that are recognised are: numpy arrays, lists and tuples. + A 3-vector can also be represented by a Quaternion object who's scalar part is 0 and vector part is the required 3-vector. + Thus it is possible to call `Quaternion.rotate(q)` with another quaternion object as an input. + + Returns: + The rotated vector returned as the same type it was specified at input. + + Raises: + TypeError: if any of the vector elements cannot be converted to a real number. + ValueError: if `vector` cannot be interpreted as a 3-vector or a Quaternion object. + + """ + if isinstance(vector, Quaternion): + return self._rotate_quaternion(vector) + q = Quaternion(vector=vector) + a = self._rotate_quaternion(q).vector + if isinstance(vector, list): + l = [x for x in a] + return l + elif isinstance(vector, tuple): + l = [x for x in a] + return tuple(l) + else: + return a + + @classmethod + def exp(cls, q): + """Quaternion Exponential. + + Find the exponential of a quaternion amount. + + Params: + q: the input quaternion/argument as a Quaternion object. + + Returns: + A quaternion amount representing the exp(q). See [Source](https://math.stackexchange.com/questions/1030737/exponential-function-of-quaternion-derivation for more information and mathematical background). + + Note: + The method can compute the exponential of any quaternion. + """ + tolerance = 1e-17 + v_norm = np.linalg.norm(q.vector) + vec = q.vector + if v_norm > tolerance: + vec = vec / v_norm + magnitude = exp(q.scalar) + return Quaternion(scalar = magnitude * cos(v_norm), vector = magnitude * sin(v_norm) * vec) + + @classmethod + def log(cls, q): + """Quaternion Logarithm. + + Find the logarithm of a quaternion amount. + + Params: + q: the input quaternion/argument as a Quaternion object. + + Returns: + A quaternion amount representing log(q) := (log(|q|), v/|v|acos(w/|q|)). + + Note: + The method computes the logarithm of general quaternions. See [Source](https://math.stackexchange.com/questions/2552/the-logarithm-of-quaternion/2554#2554) for more details. + """ + v_norm = np.linalg.norm(q.vector) + q_norm = q.norm + tolerance = 1e-17 + if q_norm < tolerance: + # 0 quaternion - undefined + return Quaternion(scalar=-float('inf'), vector=float('nan')*q.vector) + if v_norm < tolerance: + # real quaternions - no imaginary part + return Quaternion(scalar=log(q_norm), vector=[0,0,0]) + vec = q.vector / v_norm + return Quaternion(scalar=log(q_norm), vector=acos(q.scalar/q_norm)*vec) + + @classmethod + def exp_map(cls, q, eta): + """Quaternion exponential map. + + Find the exponential map on the Riemannian manifold described + by the quaternion space. + + Params: + q: the base point of the exponential map, i.e. a Quaternion object + eta: the argument of the exponential map, a tangent vector, i.e. a Quaternion object + + Returns: + A quaternion p such that p is the endpoint of the geodesic starting at q + in the direction of eta, having the length equal to the magnitude of eta. + + Note: + The exponential map plays an important role in integrating orientation + variations (e.g. angular velocities). This is done by projecting + quaternion tangent vectors onto the quaternion manifold. + """ + return q * Quaternion.exp(eta) + + @classmethod + def sym_exp_map(cls, q, eta): + """Quaternion symmetrized exponential map. + + Find the symmetrized exponential map on the quaternion Riemannian + manifold. + + Params: + q: the base point as a Quaternion object + eta: the tangent vector argument of the exponential map + as a Quaternion object + + Returns: + A quaternion p. + + Note: + The symmetrized exponential formulation is akin to the exponential + formulation for symmetric positive definite tensors [Source](http://www.academia.edu/7656761/On_the_Averaging_of_Symmetric_Positive-Definite_Tensors) + """ + sqrt_q = q ** 0.5 + return sqrt_q * Quaternion.exp(eta) * sqrt_q + + @classmethod + def log_map(cls, q, p): + """Quaternion logarithm map. + + Find the logarithm map on the quaternion Riemannian manifold. + + Params: + q: the base point at which the logarithm is computed, i.e. + a Quaternion object + p: the argument of the quaternion map, a Quaternion object + + Returns: + A tangent vector having the length and direction given by the + geodesic joining q and p. + """ + return Quaternion.log(q.inverse * p) + + @classmethod + def sym_log_map(cls, q, p): + """Quaternion symmetrized logarithm map. + + Find the symmetrized logarithm map on the quaternion Riemannian manifold. + + Params: + q: the base point at which the logarithm is computed, i.e. + a Quaternion object + p: the argument of the quaternion map, a Quaternion object + + Returns: + A tangent vector corresponding to the symmetrized geodesic curve formulation. + + Note: + Information on the symmetrized formulations given in [Source](https://www.researchgate.net/publication/267191489_Riemannian_L_p_Averaging_on_Lie_Group_of_Nonzero_Quaternions). + """ + inv_sqrt_q = (q ** (-0.5)) + return Quaternion.log(inv_sqrt_q * p * inv_sqrt_q) + + @classmethod + def absolute_distance(cls, q0, q1): + """Quaternion absolute distance. + + Find the distance between two quaternions accounting for the sign ambiguity. + + Params: + q0: the first quaternion + q1: the second quaternion + + Returns: + A positive scalar corresponding to the chord of the shortest path/arc that + connects q0 to q1. + + Note: + This function does not measure the distance on the hypersphere, but + it takes into account the fact that q and -q encode the same rotation. + It is thus a good indicator for rotation similarities. + """ + q0_minus_q1 = q0 - q1 + q0_plus_q1 = q0 + q1 + d_minus = q0_minus_q1.norm + d_plus = q0_plus_q1.norm + if (d_minus < d_plus): + return d_minus + else: + return d_plus + + @classmethod + def distance(cls, q0, q1): + """Quaternion intrinsic distance. + + Find the intrinsic geodesic distance between q0 and q1. + + Params: + q0: the first quaternion + q1: the second quaternion + + Returns: + A positive amount corresponding to the length of the geodesic arc + connecting q0 to q1. + + Note: + Although the q0^(-1)*q1 != q1^(-1)*q0, the length of the path joining + them is given by the logarithm of those product quaternions, the norm + of which is the same. + """ + q = Quaternion.log_map(q0, q1) + return q.norm + + @classmethod + def sym_distance(cls, q0, q1): + """Quaternion symmetrized distance. + + Find the intrinsic symmetrized geodesic distance between q0 and q1. + + Params: + q0: the first quaternion + q1: the second quaternion + + Returns: + A positive amount corresponding to the length of the symmetrized + geodesic curve connecting q0 to q1. + + Note: + This formulation is more numerically stable when performing + iterative gradient descent on the Riemannian quaternion manifold. + However, the distance between q and -q is equal to pi, rendering this + formulation not useful for measuring rotation similarities when the + samples are spread over a "solid" angle of more than pi/2 radians + (the spread refers to quaternions as point samples on the unit hypersphere). + """ + q = Quaternion.sym_log_map(q0, q1) + return q.norm + + @classmethod + def slerp(cls, q0, q1, amount=0.5): + """Spherical Linear Interpolation between quaternions. + Implemented as described in https://en.wikipedia.org/wiki/Slerp + + Find a valid quaternion rotation at a specified distance along the + minor arc of a great circle passing through any two existing quaternion + endpoints lying on the unit radius hypersphere. + + This is a class method and is called as a method of the class itself rather than on a particular instance. + + Params: + q0: first endpoint rotation as a Quaternion object + q1: second endpoint rotation as a Quaternion object + amount: interpolation parameter between 0 and 1. This describes the linear placement position of + the result along the arc between endpoints; 0 being at `q0` and 1 being at `q1`. + Defaults to the midpoint (0.5). + + Returns: + A new Quaternion object representing the interpolated rotation. This is guaranteed to be a unit quaternion. + + Note: + This feature only makes sense when interpolating between unit quaternions (those lying on the unit radius hypersphere). + Calling this method will implicitly normalise the endpoints to unit quaternions if they are not already unit length. + """ + # Ensure quaternion inputs are unit quaternions and 0 <= amount <=1 + q0._fast_normalise() + q1._fast_normalise() + amount = np.clip(amount, 0, 1) + + dot = np.dot(q0.q, q1.q) + + # If the dot product is negative, slerp won't take the shorter path. + # Note that v1 and -v1 are equivalent when the negation is applied to all four components. + # Fix by reversing one quaternion + if (dot < 0.0): + q0.q = -q0.q + dot = -dot + + # sin_theta_0 can not be zero + if (dot > 0.9995): + qr = Quaternion(q0.q + amount*(q1.q - q0.q)) + qr._fast_normalise() + return qr + + theta_0 = np.arccos(dot) # Since dot is in range [0, 0.9995], np.arccos() is safe + sin_theta_0 = np.sin(theta_0) + + theta = theta_0*amount + sin_theta = np.sin(theta) + + s0 = np.cos(theta) - dot * sin_theta / sin_theta_0 + s1 = sin_theta / sin_theta_0 + qr = Quaternion((s0 * q0.q) + (s1 * q1.q)) + qr._fast_normalise() + return qr + + @classmethod + def intermediates(cls, q0, q1, n, include_endpoints=False): + """Generator method to get an iterable sequence of `n` evenly spaced quaternion + rotations between any two existing quaternion endpoints lying on the unit + radius hypersphere. + + This is a convenience function that is based on `Quaternion.slerp()` as defined above. + + This is a class method and is called as a method of the class itself rather than on a particular instance. + + Params: + q_start: initial endpoint rotation as a Quaternion object + q_end: final endpoint rotation as a Quaternion object + n: number of intermediate quaternion objects to include within the interval + include_endpoints: [optional] if set to `True`, the sequence of intermediates + will be 'bookended' by `q_start` and `q_end`, resulting in a sequence length of `n + 2`. + If set to `False`, endpoints are not included. Defaults to `False`. + + Yields: + A generator object iterating over a sequence of intermediate quaternion objects. + + Note: + This feature only makes sense when interpolating between unit quaternions (those lying on the unit radius hypersphere). + Calling this method will implicitly normalise the endpoints to unit quaternions if they are not already unit length. + """ + step_size = 1.0 / (n + 1) + if include_endpoints: + steps = [i * step_size for i in range(0, n + 2)] + else: + steps = [i * step_size for i in range(1, n + 1)] + for step in steps: + yield cls.slerp(q0, q1, step) + + def derivative(self, rate): + """Get the instantaneous quaternion derivative representing a quaternion rotating at a 3D rate vector `rate` + + Params: + rate: numpy 3-array (or array-like) describing rotation rates about the global x, y and z axes respectively. + + Returns: + A unit quaternion describing the rotation rate + """ + rate = self._validate_number_sequence(rate, 3) + return 0.5 * self * Quaternion(vector=rate) + + def integrate(self, rate, timestep): + """Advance a time varying quaternion to its value at a time `timestep` in the future. + + The Quaternion object will be modified to its future value. + It is guaranteed to remain a unit quaternion. + + Params: + + rate: numpy 3-array (or array-like) describing rotation rates about the + global x, y and z axes respectively. + timestep: interval over which to integrate into the future. + Assuming *now* is `T=0`, the integration occurs over the interval + `T=0` to `T=timestep`. Smaller intervals are more accurate when + `rate` changes over time. + + Note: + The solution is closed form given the assumption that `rate` is constant + over the interval of length `timestep`. + """ + self._fast_normalise() + rate = self._validate_number_sequence(rate, 3) + + rotation_vector = rate * timestep + rotation_norm = np.linalg.norm(rotation_vector) + if rotation_norm > 0: + axis = rotation_vector / rotation_norm + angle = rotation_norm + q2 = Quaternion(axis=axis, angle=angle) + self.q = (self * q2).q + self._fast_normalise() + + + @property + def rotation_matrix(self): + """Get the 3x3 rotation matrix equivalent of the quaternion rotation. + + Returns: + A 3x3 orthogonal rotation matrix as a 3x3 Numpy array + + Note: + This feature only makes sense when referring to a unit quaternion. Calling this method will implicitly normalise the Quaternion object to a unit quaternion if it is not already one. + + """ + self._normalise() + product_matrix = np.dot(self._q_matrix(), self._q_bar_matrix().conj().transpose()) + return product_matrix[1:][:,1:] + + @property + def transformation_matrix(self): + """Get the 4x4 homogeneous transformation matrix equivalent of the quaternion rotation. + + Returns: + A 4x4 homogeneous transformation matrix as a 4x4 Numpy array + + Note: + This feature only makes sense when referring to a unit quaternion. Calling this method will implicitly normalise the Quaternion object to a unit quaternion if it is not already one. + """ + t = np.array([[0.0], [0.0], [0.0]]) + Rt = np.hstack([self.rotation_matrix, t]) + return np.vstack([Rt, np.array([0.0, 0.0, 0.0, 1.0])]) + + @property + def yaw_pitch_roll(self): + """Get the equivalent yaw-pitch-roll angles aka. intrinsic Tait-Bryan angles following the z-y'-x'' convention + + Returns: + yaw: rotation angle around the z-axis in radians, in the range `[-pi, pi]` + pitch: rotation angle around the y'-axis in radians, in the range `[-pi/2, -pi/2]` + roll: rotation angle around the x''-axis in radians, in the range `[-pi, pi]` + + The resulting rotation_matrix would be R = R_x(roll) R_y(pitch) R_z(yaw) + + Note: + This feature only makes sense when referring to a unit quaternion. Calling this method will implicitly normalise the Quaternion object to a unit quaternion if it is not already one. + """ + + self._normalise() + yaw = np.arctan2(2*(self.q[0]*self.q[3] - self.q[1]*self.q[2]), + 1 - 2*(self.q[2]**2 + self.q[3]**2)) + pitch = np.arcsin(2*(self.q[0]*self.q[2] + self.q[3]*self.q[1])) + roll = np.arctan2(2*(self.q[0]*self.q[1] - self.q[2]*self.q[3]), + 1 - 2*(self.q[1]**2 + self.q[2]**2)) + + return yaw, pitch, roll + + def _wrap_angle(self, theta): + """Helper method: Wrap any angle to lie between -pi and pi + + Odd multiples of pi are wrapped to +pi (as opposed to -pi) + """ + result = ((theta + pi) % (2*pi)) - pi + if result == -pi: result = pi + return result + + def get_axis(self, undefined=np.zeros(3)): + """Get the axis or vector about which the quaternion rotation occurs + + For a null rotation (a purely real quaternion), the rotation angle will + always be `0`, but the rotation axis is undefined. + It is by default assumed to be `[0, 0, 0]`. + + Params: + undefined: [optional] specify the axis vector that should define a null rotation. + This is geometrically meaningless, and could be any of an infinite set of vectors, + but can be specified if the default (`[0, 0, 0]`) causes undesired behaviour. + + Returns: + A Numpy unit 3-vector describing the Quaternion object's axis of rotation. + + Note: + This feature only makes sense when referring to a unit quaternion. + Calling this method will implicitly normalise the Quaternion object to a unit quaternion if it is not already one. + """ + tolerance = 1e-17 + self._normalise() + norm = np.linalg.norm(self.vector) + if norm < tolerance: + # Here there are an infinite set of possible axes, use what has been specified as an undefined axis. + return undefined + else: + return self.vector / norm + + @property + def axis(self): + return self.get_axis() + + @property + def angle(self): + """Get the angle (in radians) describing the magnitude of the quaternion rotation about its rotation axis. + + This is guaranteed to be within the range (-pi:pi) with the direction of + rotation indicated by the sign. + + When a particular rotation describes a 180 degree rotation about an arbitrary + axis vector `v`, the conversion to axis / angle representation may jump + discontinuously between all permutations of `(-pi, pi)` and `(-v, v)`, + each being geometrically equivalent (see Note in documentation). + + Returns: + A real number in the range (-pi:pi) describing the angle of rotation + in radians about a Quaternion object's axis of rotation. + + Note: + This feature only makes sense when referring to a unit quaternion. + Calling this method will implicitly normalise the Quaternion object to a unit quaternion if it is not already one. + """ + self._normalise() + norm = np.linalg.norm(self.vector) + return self._wrap_angle(2.0 * atan2(norm,self.scalar)) + + @property + def degrees(self): + return self.to_degrees(self.angle) + + @property + def radians(self): + return self.angle + + @property + def scalar(self): + """ Return the real or scalar component of the quaternion object. + + Returns: + A real number i.e. float + """ + return self.q[0] + + @property + def vector(self): + """ Return the imaginary or vector component of the quaternion object. + + Returns: + A numpy 3-array of floats. NOT guaranteed to be a unit vector + """ + return self.q[1:4] + + @property + def real(self): + return self.scalar + + @property + def imaginary(self): + return self.vector + + @property + def w(self): + return self.q[0] + + @property + def x(self): + return self.q[1] + + @property + def y(self): + return self.q[2] + + @property + def z(self): + return self.q[3] + + @property + def elements(self): + """ Return all the elements of the quaternion object. + + Returns: + A numpy 4-array of floats. NOT guaranteed to be a unit vector + """ + return self.q + + def __getitem__(self, index): + index = int(index) + return self.q[index] + + def __setitem__(self, index, value): + index = int(index) + self.q[index] = float(value) + + def __copy__(self): + result = self.__class__(self.q) + return result + + def __deepcopy__(self, memo): + result = self.__class__(deepcopy(self.q, memo)) + memo[id(self)] = result + return result + + @staticmethod + def to_degrees(angle_rad): + if angle_rad is not None: + return float(angle_rad) / pi * 180.0 + + @staticmethod + def to_radians(angle_deg): + if angle_deg is not None: + return float(angle_deg) / 180.0 * pi diff --git a/vtk_py/pyquaternion/quaternion.pyc b/vtk_py/pyquaternion/quaternion.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac2528d3fd8976a56b1faad7a496b527698cd03f GIT binary patch literal 50273 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 F{{eV+&r$#Y literal 0 HcmV?d00001 diff --git a/vtk_py/readAbaqusDeformationGradients.py b/vtk_py/readAbaqusDeformationGradients.py new file mode 100644 index 0000000..2b4d6ac --- /dev/null +++ b/vtk_py/readAbaqusDeformationGradients.py @@ -0,0 +1,45 @@ +######################################################################## + +import numpy +import vtk + +######################################################################## + +def readAbaqusDeformationGradients(data_file_name, + verbose=True): + + if (verbose): print '*** readAbaqusDeformationGradients ***' + + F_array = createFloatArray("F", 9) + + data_file = open(data_file_name, 'r') + context = "" + num_cell = 0 + for line in data_file: + if (context == "reading deformation gradients"): + #print line + if ("MAXIMUM" in line): + context = "" + continue + if ("OR" in line): + splitted_line = line.split() + assert (int(splitted_line[0]) == num_cell+1), "Wrong element number. Aborting." + F_list = [float(splitted_line[ 3]), float(splitted_line[ 6]), float(splitted_line[7]), + float(splitted_line[ 9]), float(splitted_line[ 4]), float(splitted_line[8]), + float(splitted_line[10]), float(splitted_line[11]), float(splitted_line[5])] + F_array.InsertNextTuple(F_list) + num_cell += 1 + + if (line == " ELEMENT PT FOOT- DG11 DG22 DG33 DG12 DG13 DG23 DG21 DG31 DG32 \n"): + context = "reading deformation gradients" + + data_file.close() + + if (verbose): print "nb_tuples = " + str(F_array.GetNumberOfTuples()) + + return F_array + + + + + diff --git a/vtk_py/readAbaqusDeformationGradients.pyc b/vtk_py/readAbaqusDeformationGradients.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f3669b8b31ac95c4c21dfe50581f7ad56d14d84 GIT binary patch literal 1445 zcmb_c%}(1u5T3P30wE#LmO>A-KD7}NM8Kh!wlo3)NKL396%|qyIq?Dp#}2z21X3bZ zrG10GL!Yb9&+fkJ~NN??qC3Z@n^CY9?ViXp@n( zDDh2IDgP4ZjVS3sxRub0LW9EzMX@mxcvrQSXhRZjD20A7=#Uqi61?r0KQ`orY4T3? zYbQ#yv=rJXGX>P9G!5I+okI)LWjjM=4}9ad4#P;cV!tcxkj|xQGXuA}*79wQjK720 zFP$Vd*cPV?Li^oTM@EsA5{0oeMP#*=B7>IA@bqeMwc$S!vPM_oRgROctVEqi%F3?P z(pR11%GO%Fa&Asrz01nO=W?-kX`X}SVH6jsmtn}w(x_8%N+OH9C<;!&dIeDsFU2d| z3&>6)TXgbHmS&wYkH_{EDzO=l29;TNnja=tuG$Z>zZ!RGRq* D<108B literal 0 HcmV?d00001 diff --git a/vtk_py/readAbaqusMesh.py b/vtk_py/readAbaqusMesh.py new file mode 100644 index 0000000..83da9c6 --- /dev/null +++ b/vtk_py/readAbaqusMesh.py @@ -0,0 +1,72 @@ +######################################################################## + +import vtk + +######################################################################## + +def readAbaqusMesh(mesh_filename, + elem_types="all", + verbose=True): + + if (verbose): print "*** readAbaqusMesh ***" + + points = vtk.vtkPoints() + cell_array = vtk.vtkCellArray() + + mesh_file = open(mesh_filename, "r") + + context = "" + for line in mesh_file: + if (line[-1:] == "\n"): line = line[:-1] + #if (verbose): print "line =", line + + if line.startswith("**"): continue + + if (context == "reading nodes"): + if line.startswith("*"): + context = "" + else: + splitted_line = line.split(",") + points.InsertNextPoint([float(coord) for coord in splitted_line[1:4]]) + + if (context == "reading elems"): + if line.startswith("*"): + context = "" + else: + splitted_line = line.split(",") + assert (len(splitted_line) == 1+cell_nb_points), "Wrong number of elements in line. Aborting." + for num_point in range(cell_nb_points): cell.GetPointIds().SetId(num_point, int(splitted_line[1+num_point])-1) + cell_array.InsertNextCell(cell) + + if line.startswith("*NODE"): + context = "reading nodes" + if line.startswith("*ELEMENT"): + if ("TYPE=F3D4" in line) and (("quad" in elem_types) or ("all" in elem_types)): + context = "reading elems" + cell_vtk_type = vtk.VTK_QUAD + cell_nb_points = 4 + cell = vtk.vtkQuad() + elif ("TYPE=C3D4" in line) and (("tet" in elem_types) or ("all" in elem_types)): + context = "reading elems" + cell_vtk_type = vtk.VTK_TETRA + cell_nb_points = 4 + cell = vtk.vtkTetra() + elif ("TYPE=C3D8" in line) and (("hex" in elem_types) or ("all" in elem_types)): + context = "reading elems" + cell_vtk_type = vtk.VTK_HEXAHEDRON + cell_nb_points = 8 + cell = vtk.vtkHexahedron() + else: + print "Warning: element type not taken into account." + + mesh_file.close() + + if (verbose): print "Creating UGrid..." + + ugrid = vtk.vtkUnstructuredGrid() + ugrid.SetPoints(points) + ugrid.SetCells(cell_vtk_type, cell_array) + + if (verbose): print "nb_cells = " + str(ugrid.GetNumberOfCells()) + + return ugrid diff --git a/vtk_py/readAbaqusMesh.pyc b/vtk_py/readAbaqusMesh.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a310328e55c2a4b2e894535b2b31f9462c4efb7 GIT binary patch literal 2110 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 literal 0 HcmV?d00001 diff --git a/vtk_py/readDynaMeshStructured.py b/vtk_py/readDynaMeshStructured.py new file mode 100644 index 0000000..df67644 --- /dev/null +++ b/vtk_py/readDynaMeshStructured.py @@ -0,0 +1,90 @@ +######################################################################## + +import vtk +import math + +######################################################################## + +def readDynaMeshStructured(lsdyna_mesh_file_name, cell_type='hexahedron', verbose=True): + + if (verbose): print '*** readDynaMesh ***' + + points = vtk.vtkPoints() + + if (cell_type == 'vertex'): + cell_vtk_type = vtk.VTK_VERTEX + cell = vtk.vtkVertex() + cell_array = vtk.vtkCellArray() + elif (cell_type == 'hexahedron'): + cell_vtk_type = vtk.VTK_HEXAHEDRON + cell = vtk.vtkHexahedron() + cell_array = vtk.vtkCellArray() + else: + print 'Wrong cell type. Aborting.' + exit() + + if (verbose): print 'Reading Dyna mesh file...' + + cnt = 1; + + mesh_file = open(lsdyna_mesh_file_name, 'r') + + context = '' + for line in mesh_file: + if (line[-1:] == '\n'): line = line[:-1] + #if (verbose): print 'line =', line + + if line.startswith('$'): continue + + if (context == 'reading nodes'): + if line.startswith('*'): + context = '' + else: + #splitted_line = line.split(',') + splitted_line = [] + splitted_line.append(line[0:8].replace(" ","")) + splitted_line.append(line[8:24].replace(" ","")) + splitted_line.append(line[25:25+16].replace(" ","")) + splitted_line.append(line[25+17:50+17].replace(" ","")) + print splitted_line + + points.InsertNextPoint([float(coord) for coord in splitted_line[1:4]]) + if (cell_type == 'vertex'): + cell.GetPointIds().SetId(0, points.GetNumberOfPoints()-1) + cell_array.InsertNextCell(cell) + + if (context == 'reading elems'): + if line.startswith('*'): + context = '' + else: + if(cnt%2 == 0): + + splitted_line = [] + splitted_line.append(line[0:8].replace(" ","")) + splitted_line.append(line[9:16].replace(" ","")) + splitted_line.append(line[17:24].replace(" ","")) + splitted_line.append(line[25:32].replace(" ","")) + splitted_line.append(line[33:40].replace(" ","")) + splitted_line.append(line[41:48].replace(" ","")) + splitted_line.append(line[49:56].replace(" ","")) + splitted_line.append(line[57:64].replace(" ","")) + if (len(splitted_line) == 3): continue + if (cell_type == 'hexahedron'): + for num_node in range(8): + cell.GetPointIds().SetId(num_node, int(splitted_line[num_node])-1) + cell_array.InsertNextCell(cell) + + cnt = cnt + 1; + + if line.startswith('*NODE'): context = 'reading nodes' + if line.startswith('*ELEMENT_SOLID'): context = 'reading elems' + + mesh_file.close() + + if (verbose): print 'Creating VTK mesh...' + + ugrid = vtk.vtkUnstructuredGrid() + ugrid.SetPoints(points) + ugrid.SetCells(cell_vtk_type, cell_array) + + return ugrid diff --git a/vtk_py/readDynaMeshStructured.pyc b/vtk_py/readDynaMeshStructured.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e90962e7b04cedd4a4762ba891da1b062a6cf489 GIT binary patch literal 2494 zcmb_e+j1L45bfEOWJ}h?m&9?xC2I)aC>4v#3sh26QkKegNMuSjNy?N_tu+&SmDNh# z9R-_`o7J3@KMT1RzkjmZ zqVdPY`wpJu286~}QAo6XGFG&$NIPU4(k^}P(6-Aqn@cI!2Y=yHw>b>=&7r?l4oMoRUox+}Wf^w<&l7?A2th$3qs_xu& zhdCPLNN4G)&dIL7j^`c_qyn&=B|SyY6~%wh!Ans>lNal(Gd3uQ!K@njKgc?J$bO0j zQ`8>q0Cq~W*q$Oi%|Rd}3=>?jHM=tZv?ti7~GU>T9Qyo)%;oqsea^CtkNWXa={ub%C&%>{h z_Rhl>Nx$B}-#90y`u9Ztl8XyHBE$C)&QSZ}$;m6G z^!umhf1dS2G){H8u;QeJch-@MkJXSUz)*4&2$H(A9;oRm& zrYqq3ZXEkZmSbS+wc6vmYqe@)qmEld+^wDbNLXgU90pbf-JXeLlf?S5O}-86zEsuk z0noU+netxfw~XZcLv}Z&E8bs3yyNSUGlXSj{5*znhwjUe48V6d4!FFTk+zgnp z*JO#~wihA7M5F1N+;mNDx@P2ejI88tZF09t!szH--iy1tH!1_OC`PEv$dFlNjgTjh zFD2kIwh%Ix@nk1)+v-L*C?nd#ATm;#q!*$RMmI&nnYX&#SmT$GDC&2b+~<;he-CML zSCWW?`>?X#?U+i~3XQ2WOk(`FwO?6Vc~IdfdqhNvjD#GET|KsDhfNf?J{t>`E%@W|TMnOFK8Q##3`6#F>WmF?Rf( zr3`H5)D1Q56r2)eRf!5tZnQJ|cI2O(2DhQKYsW`_GWA<=-!v*1oKo_C@WR>O?sRoO OG@r})=DqSNpZXh-h5Y3J literal 0 HcmV?d00001 diff --git a/vtk_py/readFiberOrientation.py b/vtk_py/readFiberOrientation.py new file mode 100644 index 0000000..a3675f9 --- /dev/null +++ b/vtk_py/readFiberOrientation.py @@ -0,0 +1,52 @@ +######################################################################## + +import numpy +import vtk + +from createFloatArray import * + +######################################################################## + +def readFiberOrientation(mesh, + filename, + verbose=True): + + if (verbose): print '*** readFiberOrientation ***' + + nb_cells = mesh.GetNumberOfCells() + + if verbose: print 'Reading fiber orientations...' + + eF_array = createFloatArray('eF', 3, nb_cells) + eS_array = createFloatArray('eS', 3, nb_cells) + eN_array = createFloatArray('eN', 3, nb_cells) + + file = open(filename, 'r') + file.readline() + + num_cell = 0 + for line in file: + line = line.split(', ') + #print line + + eF = [float(item) for item in line[1:4]] + eS = [float(item) for item in line[4:7]] + eN = numpy.cross(eF,eS) + #print "eF =", eF + #print "eS =", eS + #print "eN =", eN + + eF_array.InsertTuple(num_cell, eF) + eS_array.InsertTuple(num_cell, eS) + eN_array.InsertTuple(num_cell, eN) + + num_cell += 1 + #print "num_cell =", num_cell + + file.close() + + mesh.GetCellData().AddArray(eF_array) + mesh.GetCellData().AddArray(eS_array) + mesh.GetCellData().AddArray(eN_array) + + return mesh diff --git a/vtk_py/readFiberOrientation.pyc b/vtk_py/readFiberOrientation.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b4fb446981854a418c566e0d2bfa8fea7cbd2e94 GIT binary patch literal 1240 zcmbtT&2G~`5T0HCByp0qDjY!ym&%GzBEg{-gs57j{9CYMWS%0M76=bS8=mbQZ$jmPcA)gg|B=JR7pU5|QEd>N zhoinj)dB6o9ILmX>=-6pC~cTGp~PRC5LP<3wuxXRX4L*}?Qas5ZRC7$4IiivpD2+}tK=e?!i{kb4VF{4SotSUo}6@ArF!483f^ zy%`1c^1BE%7z}XC0CE&t_^I_t{TZ91FJi<&QPA^VOqU@xH>81@-$9`_Q0z-RUZzxj zwkwlF88AXpT8@%D)H_8HUTI3q7f7#(3NcRNOyarV{);5mMw?N%(XwT_xH4K)eH1d@KT?jEUtzRo$LSy^B8j<@_C4x|326*G?xG zb=kVL#kSa{v%&D?YnI0!F?_jCM-kARH4#MuflCH8a#$>7K)3CVzR~`x2O90GG#AT6 OzNU(b%5_+Wd+u+U&%gt~%sMHpNH4_om)Y6*`R3bAonOuR*PoBx4`A`(`27rDy@??3k3kG@ za&9v?VIVksK_{o(!;XWI;cxu(2Mo3X`0DRi&j1v*(451JLBSwmFb9}nK6)IB zuEjMl93sc=R;=w>y9(3$yx{QS?IxdjARH(>7*;?eByXL86Q=kc|sN4ywoUAsAaWst}c^N{G96<_u=FReN5!S6{VPEB6{uR3Y-9 zs6kPOq5*RU*wMJhTvLN#9n@2XA0&gWV;rnNkxD{)kbBHvjt8p<`B3;E>X!Q(PGVwh zl)4E;6C&SE(4<*clxSFP*ylDL6uT7fu8Q}sj`vo@H?NLI9seDvbveEQQH!QP-5E-9 zG#>M%S_xmMHRi`8+8!Ly=xsYXCbb}1C&ek17S}+up}_N`Ia_#z*YU3Q4c%T9B7m+T zY;46ck*U!kZD`-RQnB=Ey5t-Ek&t>3o(j7P={FQQ1TMiE0R@Lu0*|1M(7BFaC}fmj z8)~U!AmT8U+EDsOGc?o{zk4!{pDPvQHVhpvMgI+IVx>6TI>W&2^>QoiIQSlg~AfWqyL<$jAa@mvK&POCa_ki0%@X6pp3+$uodkp zMbRzu0WznU!MQx7b5?3Y%2FA7u2YM-#ZQI~LdJ>7v$C(TW0RPZ56HcP23XJ!(CVIz z64{Lhv6S5dsb!!BXWgCNeisFMm*rhLwf(~#n)*SO+rcilXmWi_6?vQatU?d>(Q1|} zv`f!Lbl6>b_$}UKb;oD4rksb1=O$*iFtf?lUHcE%ik422EI**Db8rvg?->6*3z2`E QjKn0CPpGaYQIUxI2g{N=E&u=k literal 0 HcmV?d00001 diff --git a/vtk_py/readPData.py b/vtk_py/readPData.py new file mode 100644 index 0000000..6ec0cc8 --- /dev/null +++ b/vtk_py/readPData.py @@ -0,0 +1,22 @@ +######################################################################## + +import vtk + +######################################################################## + +def readPData(pdata_file_name, verbose=True): + if (verbose): print '*** readPData ***' + + pdata_reader = vtk.vtkPolyDataReader() + pdata_reader.SetFileName(pdata_file_name) + pdata_reader.Update() + pdata = pdata_reader.GetOutput() + + if (verbose): + print "nb_points = " + str(pdata.GetNumberOfPoints()) + print "nb_verts = " + str(pdata.GetNumberOfVerts()) + print "nb_lines = " + str(pdata.GetNumberOfLines()) + print "nb_polys = " + str(pdata.GetNumberOfPolys()) + print "nb_strips = " + str(pdata.GetNumberOfStrips()) + + return pdata diff --git a/vtk_py/readPData.pyc b/vtk_py/readPData.pyc new file mode 100644 index 0000000000000000000000000000000000000000..876265f0ab2504b7041cd3a5b73171573f7f074e GIT binary patch literal 855 zcmbW0&u-H|5XNWiBuzugp92CR4mny8!UwK^kcvnSkVXk`=p}OEsp{a^mUmn!QaF`I z;5|6-L_7lz0N-rlHspxy9q;^hcIMk%+y8yi`Tpz0d_lX*!}|@IeF_ufF_aRW6S1M# zqi=@JJ%!W2M?mri*Jz=W8fc16(dC-%b9Z1*J(FpO!7<2!Avf#(oWt_F$ui?LFA6;qe}9)v$95ArMuj!4Y(i>;u?- zzuzl4ipOswiF)vC7c`sCiag20_Fnbuoh`WH@*h7>j*QYZ*Cf%q_2 z@MI|l`GP^XOqiQwh^6X;l z)XM#BY)wC_ndg>87rhW^i`6IFhz;Xj46k>uqnkE@hl>q%Pu6}pYT(NV(W literal 0 HcmV?d00001 diff --git a/vtk_py/readPLY.py b/vtk_py/readPLY.py new file mode 100644 index 0000000..3d41962 --- /dev/null +++ b/vtk_py/readPLY.py @@ -0,0 +1,22 @@ +######################################################################## + +import vtk + +######################################################################## + +def readPLY(mesh_file_name, verbose=True): + if (verbose): print '*** readSTL ***' + + mesh_reader = vtk.vtkPLYReader() + mesh_reader.SetFileName(mesh_file_name) + mesh_reader.Update() + mesh = mesh_reader.GetOutput() + + if (verbose): + nb_points = mesh.GetNumberOfPoints() + print 'nb_points =', nb_points + + nb_cells = mesh.GetNumberOfCells() + print 'nb_cells =', nb_cells + + return mesh diff --git a/vtk_py/readPLY.pyc b/vtk_py/readPLY.pyc new file mode 100644 index 0000000000000000000000000000000000000000..deb24b5ed6cb79e41eb2fd038a1e86fe825a64fd GIT binary patch literal 678 zcmbVK!EV|>5S_IRA=ISFEr%XBS{&*_u1Qr1DR4+h1oTiY2<(Y~*kF0bNJ#WVJ|REY zZ|Da!ZuR3R+wib{#k8LgQhbIoq6rZjN>am`MKCR<2R@^*h^J1b!vE_ wX_=-8y}Aj_DNyLS*B|NuSJSwxc-R7ZcmJ;v8j!foH))me7kvz?e^eN}0)Ls5y#N3J literal 0 HcmV?d00001 diff --git a/vtk_py/readSTL.py b/vtk_py/readSTL.py new file mode 100644 index 0000000..cb2c8a9 --- /dev/null +++ b/vtk_py/readSTL.py @@ -0,0 +1,22 @@ +######################################################################## + +import vtk + +######################################################################## + +def readSTL(mesh_file_name, verbose=True): + if (verbose): print '*** readSTL ***' + + mesh_reader = vtk.vtkSTLReader() + mesh_reader.SetFileName(mesh_file_name) + mesh_reader.Update() + mesh = mesh_reader.GetOutput() + + if (verbose): + nb_points = mesh.GetNumberOfPoints() + print 'nb_points =', nb_points + + nb_cells = mesh.GetNumberOfCells() + print 'nb_cells =', nb_cells + + return mesh diff --git a/vtk_py/readSTL.pyc b/vtk_py/readSTL.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3b4114d89edccc3ba7b7e350ae71122e0deb7fc0 GIT binary patch literal 678 zcmbVKu}q6p);f(9lGQJtzrwVtL0%NV$sp1b&cj z-~+ffo9Iroth}@Ho@eIGcL;31$JVopZ3Sjys65or-pz^#%+k;+(Ql779xY*sUJV%qzP@l?;6i+tT+qg+ zWz8{xiuX1FiYZxlWQ|fEWNoVeeiQ`|?%N~SPN&l@d76&Kw{7_L0NiReDb|aX*!G2O zZgIj{1{m!DijMRwPZDlVqz+MmOVQ*J%k?7T{xoONVegA{DlGeOdn|)Wib~|i7WJ!q z#^vDgms6ADuWVN}BdsBaFge@#{1062FNN()_LdG6fjId|^Z{*Tr6*Y6L92`!%*_UBmkCBz7?qLk?HLRWOC zoZq9=qXWr+=0k&9k*?For!PJo24e1a1#kQl&!DTIvWQ+H-VRm+Ya7dchQIR3+>olB z-5eIt3DKNrR+B2Q0Jy5r+^1Qc&i531&Q$d3{WCQSh!I9jjjDj=O5Rz6D%b3(N5&8b zbkd*^AP{O&zUw?qCtEJFPPZ@Wr84--Zd|gD{NF51s?Z#fuzb79()x!5nO9g~UtxiL zJxj|Wx0gLvO<}KEH1}w>a9);ZsqGRPk{~+LR;a4e2_$CKp=!nT?~(fWnBF0>-)-V1 z2KFvwuh+Y03XWOtPqR$387F%&+8gUV2F-LZqv9tv&hr#mY42oR4 zvb@YDQ`|d|o@#DkXCT>0VHfe(5lDPgFt1>LlUr?;P(rul5V|FESH4S!RivY6fgqph zIF}6Tx+zLt7!o+sW+;TxWJ9|#&>cvCL-&t_ zE>9p9d0kYI6ZR3b{&A7%eww6O_d{)UY?9;t?)F~)j8CJVJpgsX6sndOi|{o zwojSc8cdJw`ZNPnG>NwG`TP&o@dYBc?t@>iQ@JF->EZ0-*dH)Vv`}^9x{T{0pfCH4BQ-q6(^NW2(|g~BT$b4Trv76G;7s+A*$ zcUD+lh9bp@0O;xpJ(4Pu$b;1MDjm#o)`n$xxad?HJFiNYb*TAt`r#;9RAxoXm?xUwmvzHV z(+a#zAVoxicn~=Rfhr#xMt&q$I8DuknP)7mny;N(cJ9VG+mW^-?Tzc{TAQ=VY8C}7 zQz#O4*?b;>B4_L#qWH2ZbeyNT*6~y;R=BqRA$4WKSwp3Mcjx z5dX(F@BuL6QudA&KhGP#natP@e#O!EpReyS_&X%6?`XPL1UY>IDuCO6wt!pV{Sqn( zYaKuyzyo~p zgr2AX!6blQdcvyEs|L^ypd=(pD&83KMtQ=ROSlKHofnOu2QO-3&rgq>Gej&GY&~IX zl>}7U!aXOPPN$PqRb+ZH*UI9Ac)?vHV*+H|4)1YvSU**&(RfN^rSaMpUyA0)7RJ`9 z@{9sz9ip~)c2E-g&@~wrrorft=|)?}^cm3$jW_F$SE@Aj=;r^?FD{#w5^*I*@?N1r zuJ3c3D?HRf@z))aGT{xso10ouZG15^j|)5@d#CN4aT*6?x4svS$b7L0S>VCFAS>OP zTBlW3X`L>$qqE7j>3nvTQg@qnpE^FXEg#v-cJI4-^l*>vob$;cjO19vBKCMLp2}E6 zGT{RJ;kvzB`ZpAlr&hSx>1>0>R1Wz)t!<~5d`*wl{cnjQ%JQZ*c~|MTe65aKAB(Y! F!avWCt7-rM literal 0 HcmV?d00001 diff --git a/vtk_py/splitDomainBetweenEndoAndEpi.py b/vtk_py/splitDomainBetweenEndoAndEpi.py new file mode 100644 index 0000000..69316bb --- /dev/null +++ b/vtk_py/splitDomainBetweenEndoAndEpi.py @@ -0,0 +1,80 @@ +######################################################################## + +import sys +import vtk + +from mat_vec_tools import * + +######################################################################## + +def splitDomainBetweenEndoAndEpi(domain, verbose=True): + + if (verbose): print '*** splitDomainBetweenEndoAndEpi ***' + + connectivity0 = vtk.vtkConnectivityFilter() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + connectivity0.SetInputData(domain) + else: + connectivity0.SetInput(domain) + connectivity0.SetExtractionModeToSpecifiedRegions() + connectivity0.AddSpecifiedRegion(0) + connectivity0.Update() + ugrid0_temp = connectivity0.GetOutput() + + geom0 = vtk.vtkGeometryFilter() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + geom0.SetInputData(ugrid0_temp) + else: + geom0.SetInput(ugrid0_temp) + geom0.Update() + pdata0_temp = geom0.GetOutput() + + tfilter0 = vtk.vtkTriangleFilter() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + tfilter0.SetInputData(pdata0_temp) + else: + tfilter0.SetInput(pdata0_temp) + tfilter0.Update() + + connectivity1 = vtk.vtkConnectivityFilter() + connectivity1.SetExtractionModeToSpecifiedRegions() + connectivity1.AddSpecifiedRegion(1) + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + connectivity1.SetInputData(domain) + else: + connectivity1.SetInput(domain) + connectivity1.Update() + ugrid1_temp = connectivity1.GetOutput() + geom1 = vtk.vtkGeometryFilter() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + geom1.SetInputData(ugrid1_temp) + else: + geom1.SetInput(ugrid1_temp) + geom1.Update() + pdata1_temp = geom1.GetOutput() + + + tfilter1 = vtk.vtkTriangleFilter() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + tfilter1.SetInputData(pdata1_temp) + else: + tfilter1.SetInput(pdata1_temp) + tfilter1.Update() + + pdata1 = tfilter1.GetOutput() + pdata0 = tfilter0.GetOutput() + + p0bd = pdata0.GetBounds() + p1bd = pdata1.GetBounds() + + if (abs(p1bd[0] - p1bd[1]) < abs(p0bd[0] - p0bd[1])): + pdata_epi = pdata0 + pdata_endo = pdata1 + else: + pdata_epi = pdata1 + pdata_endo = pdata0 + + return pdata_epi, pdata_endo + + + diff --git a/vtk_py/splitDomainBetweenEndoAndEpi.pyc b/vtk_py/splitDomainBetweenEndoAndEpi.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b9dc98664d05137a1ad435c20ea46219179f012 GIT binary patch literal 1744 zcmb_cOK;Oa5T11&O;Yy}q)JrcPy~ml2a>`S@n|V6LM>7oI3S_Ojkm2^$F}TAA(DH7 z8(01SS8n_yegk*ln_cGtRGf&i>+hSH{dRVC?9%sz#;0%hj`~#m96TRkWOp(7_$vyD zUQe*1*UH!(3LWa|68R!@XDBrvnt_A(3~VCVM1yXb6wD7 z$;dYhE?>3P7s|_KE2|+}fn%#e6Qs}tvYHj6GjBAjS84vBylONnlk~x%X}LJ9=CllR zl+R5L1%yMD&0-0`xsc7II&YN3{#G6EX>~w~l!0u@wV5*1uS)r=%IiiGD~pPQL(_6` z7Meg-voTYK`KvT5PCjomQT{>`9GaGkv(N;xny#sw#kh$DI&)2#7b$ngc!?OUCGtzO zDvvU)UWdLI(O_c4qcENmr5_#WTrP{kWs@Ro0RRePlX8G29Xn`dY1jSiHsu!9Q=zeei~);Wb8mTy|pIr1&o0FbkqxSmb| zbAts#L$u%{Gi48f+NY>pJM4#Aw-0oty|jPY-rd@3qprPV)c#jj-AP7#0~-H|k@m^( zp(b*wRC8RlqL!Tn)lf3r89swy75_NWRnt{&X@U_YYh0(Js;cf(Rn;+Xgt^;nlpUB4 xyjREhoOET?^h=MD~UGBzW@;^a)$r_ literal 0 HcmV?d00001 diff --git a/vtk_py/transform_mesh_w_4x4mat.py b/vtk_py/transform_mesh_w_4x4mat.py new file mode 100644 index 0000000..ba093cf --- /dev/null +++ b/vtk_py/transform_mesh_w_4x4mat.py @@ -0,0 +1,54 @@ +######################################################################## + +import sys +import numpy +import vtk +from vtk_py import * + +######################################################################## + +def transform_mesh_w_4x4mat(infilename, outfilename, matrix): + + ugrid = vtk.vtkUnstructuredGrid() + + if(infilename[len(infilename)-4:len(infilename)] == ".vtu"): + ugrid = readXMLUGrid(infilename) + elif(infilename[len(infilename)-4:len(infilename)] == ".vtk"): + ugrid = readUGrid(infilename) + + rot_mat = vtk.vtkMatrix4x4() + rot_mat.DeepCopy(matrix) + + transform = vtk.vtkTransform() + transform.SetMatrix(rot_mat) + transform.Update() + + transformfilter = vtk.vtkTransformFilter() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + transformfilter.SetInputData(ugrid) + else: + transformfilter.SetInput(ugrid) + transformfilter.SetTransform(transform) + transformfilter.Update() + + if(outfilename[len(outfilename)-4:len(outfilename)] == ".vtu"): + writeXMLUGrid(transformfilter.GetOutput(), outfilename) + elif(outfilename[len(outfilename)-4:len(outfilename)] == ".vtk"): + writeUGrid(transformfilter.GetOutput(), outfilename) + + + + +if (__name__ == "__main__"): + + print len(sys.argv) + assert (len(sys.argv) == 19), 'Number of arguments must be 3.' + infilename = sys.argv[1] + outfilename = sys.argv[2] + matrix = map(float,sys.argv[3:19]) + + print matrix + + transform_mesh_w_4x4mat(infilename, outfilename, matrix) + + diff --git a/vtk_py/transform_mesh_w_4x4mat.pyc b/vtk_py/transform_mesh_w_4x4mat.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc4f2d61ddf92329eddd0bf441c712f3d63856e6 GIT binary patch literal 1547 zcmb_c&2AG{6h3$Sli2Yj(DIY05^}`GVi8Ngrl>+xp$(`_kemdeY(^8$H5tb zK88j_C(FB`6SL3B~>~P$h{+5CrdP3p_!q*XP=^^CNAC) zuToMM`=92@H(8;rlg0w90yN34k!>wh4MOzx3=M>2LrILP2!LBivkIA9J3s6+F-7_w zuY-=kl||g^S0Gn#syMqi{t|jdn}%jYe^h7+7>GnyU|@3zwv#{ydrYieu){sS|FwvU zMvRH8R~aQ@UazM0ps&)fPSZf@8EFK3p^+L*YcyOHvls+4#Go!sb*XFLYcy;L6xwU# z{-J4|h9ONW8kge+yuQE!HYBws1(+wD8XX!Od>mTAV(3SPuW6?1QVZ^Q04D!YZbHzP z0_U@P!{7ZsP>Coiw9cnRu3meVUmpFo9}f$+P)ifY`aB<({50lR zn^-8c34mp44&i?3QnsJXguE|GMg}dab{(-Jo2|MuAEclp&MdD%SCqWOGD)T!u<&2L z778WM6&%5!gY%Mx4Oo^4Nib>$DpKJe;nqDXGTR;XN7i&>iw>{1*&Vv+<;- ze;`8Ke5BqF;wI}8MZ$3u^&}d= 6): + transformfilter.SetInputData(pdata) + else: + transformfilter.SetInput(pdata) + transformfilter.SetTransform(transform) + transformfilter.Update() + + return transformfilter.GetOutput() + + + + + diff --git a/vtk_py/transform_pdata.pyc b/vtk_py/transform_pdata.pyc new file mode 100644 index 0000000000000000000000000000000000000000..47a9da272ad27ccfe906ce26959463ca8a73d37f GIT binary patch literal 919 zcmbtS&2G~`5T5lqZE9jD2oB}K)#899ID!yTD}IDpP!cN0r84$bwd>fHcT&kxIE6>x z!V~cvJOd8^GqZ6>x#FMMnQwl-vGuPo`1bS3=M>hLN9PNA?NbsNJqk*I*+y3|Q$6m% z%oE*%Qo}UU@RdS+&Y46$<>$ZYI*Ami$l_tDNeUs^C7Kok=RP&9&Fc#9 zkon5s>GbV!Qq*k^^GFkeZ>na2oQ%UQKn5o7^?|9%y9H9b&_?FY1G!XWZdWE1YORpz zEpZ9$Ta>b~&Sl()AP`|6lNMjpa}$?oX-qse)+B9u5x+h>j%kf&O&4#n&!qLEro(GR z9n34Rye9BQ>Vdi~cR>0*weN*0RDtI>@CUM;6)x3c-gIO6b9vdW;rK48e`ox!L5Ec8 S*}TpcrFkxm85k+P1OE@C-N}#u literal 0 HcmV?d00001 diff --git a/vtk_py/translate_mesh.py b/vtk_py/translate_mesh.py new file mode 100644 index 0000000..8751db0 --- /dev/null +++ b/vtk_py/translate_mesh.py @@ -0,0 +1,30 @@ +######################################################################## + +import sys +import numpy +import vtk +from vtk_py import * + +######################################################################## + +def translate_mesh(ugrid, vec): + + transform = vtk.vtkTransform() + transform.Translate(vec[0],vec[1],vec[2]) + transform.Update() + + transformfilter = vtk.vtkTransformFilter() + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + transformfilter.SetInputData(ugrid) + else: + transformfilter.SetInput(ugrid) + transformfilter.SetTransform(transform) + transformfilter.Update() + + return transformfilter.GetOutput() + + + + + + diff --git a/vtk_py/translate_mesh.pyc b/vtk_py/translate_mesh.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83b398936fd1e8857ebe66b065b48c838861d9e1 GIT binary patch literal 796 zcmbtS%}(Pm5FXnplx)i)#2z?tjW`gkID!xoD;9(RsVy9OK_PKzLjDv_kSdi^_YrtO zo`DBoXB=97t|aj{|1+QMsF$w$^t^i;!rLQB9?~*<1QC4#Qh?z?7cdlazl5Q*x`b50 zAX4y;QXQ`8dk)pduk>7af>dPK4!J!?TC|R6nI{4SNCeCP9wkgAB!o0Wz$OdX2nCxn z1%kthQw0|}wn*6qEl8Hwj2yUcK{bM@f@B${05bt1?^?S(w>h}N!#K!B)08!ryYxL~ zco7po%+zCM9xoAiKL}6}Jm5Wc8ab$f+>DAU!xeH^D-BR17hIJQtLtAfkK+_|g>K`% z)|H8i+-CjNcs)2f50avqyLn7s<7r;j_$R;s+aDa31VulSpe~m+Qog+k#_dWZH~( z$_cK{doH}ZTeCp`vLm*HOZZEy$*$;a?E~QJv}ozEQ)Dj^NjI{sWoCtl0nn literal 0 HcmV?d00001 diff --git a/vtk_py/vtkmtvfiber_sheet_vector_translator.py b/vtk_py/vtkmtvfiber_sheet_vector_translator.py new file mode 100644 index 0000000..e0415d8 --- /dev/null +++ b/vtk_py/vtkmtvfiber_sheet_vector_translator.py @@ -0,0 +1,263 @@ +######################################################################## + +import argparse +import glob +from numpy import * +from sets import Set +from vtk import * +import os + +import vtk_py as vtk_py + +######################################################################## + + + +parser = argparse.ArgumentParser() +parser.add_argument('--vtk_folder', type=str, required=True) +parser.add_argument('--vtk_filename', type=str, required=True) +parser.add_argument('--fiberdata_directory', type=str, required=True) +parser.add_argument('--mtv_grid_directory', type=str, required=True) +parser.add_argument('--mtv_basename', type=str, required=True) +args = parser.parse_args() + +print "************* Entering vtkmtvfiber_sheet_vector_translator.py *****************" + + +points = [] +fvectors = [] +svectors = [] + +srcfilename = os.path.join(args.vtk_folder, args.vtk_filename) +directory = args.fiberdata_directory +outdirectory = args.mtv_grid_directory +outfilename = args.mtv_basename + +reader = vtkUnstructuredGridReader(); +reader.SetFileName(srcfilename); +reader.Update(); + +mesh = vtkUnstructuredGrid(); +mesh.DeepCopy(reader.GetOutput()) + +rotate = 1; +bds = mesh.GetBounds() +zoffset = bds[5]; + + +rotate = 1; +# Import vtk file +# Read in LV fiber data +LVfiberreader = vtkXMLPolyDataReader(); +LVfiberreader.SetFileName(directory+"LVfiberdata.vtp"); +LVfiberreader.Update(); + +LVfiberdata = vtkPolyData(); +LVfiberdata.DeepCopy(LVfiberreader.GetOutput()) + +fvec = [0,0,0] +svec = [0,0,0] +pts = [0,0,0] +rotatedpt = [0,0,0] + +for p in range(0, LVfiberdata.GetPoints().GetNumberOfPoints()): + pt= LVfiberdata.GetPoints().GetPoint(p) + if(rotate == 0): + points.append(pt) + else: + rotatedpt[0] = float(-pt[2]+zoffset)/10.0; + rotatedpt[1] = float(pt[1])/10.0; + rotatedpt[2] = float(pt[0])/10.0; + points.append([rotatedpt[0], rotatedpt[1], rotatedpt[2]]) + + + LVfiberdata.GetPointData().SetActiveVectors("f vectors") + temp = LVfiberdata.GetPointData().GetVectors().GetTuple3(p); + fvec[0] = temp[0] + fvec[1] = temp[1] + fvec[2] = temp[2] + vtkMath.Normalize(fvec) + if(rotate == 0): + fvectors.append([fvec[0], fvec[1], fvec[2]]) + else: + fvectors.append([-1.0*fvec[2], fvec[1], fvec[0]]) + + + LVfiberdata.GetPointData().SetActiveVectors("n vectors") + temp = LVfiberdata.GetPointData().GetVectors().GetTuple3(p); + svec[0] = temp[0] + svec[1] = temp[1] + svec[2] = temp[2] + vtkMath.Normalize(svec) + if(rotate == 0): + svectors.append([svec[0], svec[1], svec[2]]) + else: + svectors.append([-1.0*svec[2], svec[1], svec[0]]) + + +# Read in RV fiber data +RVfiberreader = vtkXMLPolyDataReader(); +RVfiberreader.SetFileName(directory+"RVfiberdata.vtp"); +RVfiberreader.Update(); + +RVfiberdata = vtkPolyData(); +RVfiberdata.DeepCopy(RVfiberreader.GetOutput()) + +fvec = [0,0,0] +svec = [0,0,0] +pts = [0,0,0] + +rotatedpt = [0,0,0] + +for p in range(0, RVfiberdata.GetPoints().GetNumberOfPoints()): + pt= RVfiberdata.GetPoints().GetPoint(p) + if(rotate == 0): + points.append(pt) + else: + rotatedpt[0] = float(-pt[2]+zoffset)/10.0; + rotatedpt[1] = float(pt[1])/10.0; + rotatedpt[2] = float(pt[0])/10.0; + points.append([rotatedpt[0], rotatedpt[1], rotatedpt[2]]) + + + + RVfiberdata.GetPointData().SetActiveVectors("f vectors") + temp = RVfiberdata.GetPointData().GetVectors().GetTuple3(p); + fvec[0] = temp[0] + fvec[1] = temp[1] + fvec[2] = temp[2] + vtkMath.Normalize(fvec) + if(rotate == 0): + fvectors.append([fvec[0], fvec[1], fvec[2]]) + else: + fvectors.append([-1.0*fvec[2], fvec[1], fvec[0]]) + + RVfiberdata.GetPointData().SetActiveVectors("n vectors") + temp = RVfiberdata.GetPointData().GetVectors().GetTuple3(p); + svec[0] = temp[0] + svec[1] = temp[1] + svec[2] = temp[2] + vtkMath.Normalize(svec) + if(rotate == 0): + svectors.append([svec[0], svec[1], svec[2]]) + else: + svectors.append([-1.0*svec[2], svec[1], svec[0]]) + + + +# Read in Septum fiber data +Septumfiberreader = vtkXMLPolyDataReader(); +Septumfiberreader.SetFileName(directory+"Septumfiberdata.vtp"); +Septumfiberreader.Update(); + +Septumfiberdata = vtkPolyData(); +Septumfiberdata.DeepCopy(Septumfiberreader.GetOutput()) + +fvec = [0,0,0] +svec = [0,0,0] +pts = [0,0,0] +rotatedpt = [0,0,0] + + +for p in range(0, Septumfiberdata.GetPoints().GetNumberOfPoints()): + pt= Septumfiberdata.GetPoints().GetPoint(p) + if(rotate == 0): + points.append(pt) + else: + rotatedpt[0] = float(-pt[2]+zoffset)/10.0; + rotatedpt[1] = float(pt[1])/10.0; + rotatedpt[2] = float(pt[0])/10.0; + points.append([rotatedpt[0], rotatedpt[1], rotatedpt[2]]) + + + Septumfiberdata.GetPointData().SetActiveVectors("f vectors") + temp = Septumfiberdata.GetPointData().GetVectors().GetTuple3(p); + fvec[0] = temp[0] + fvec[1] = temp[1] + fvec[2] = temp[2] + vtkMath.Normalize(fvec) + if(rotate == 0): + fvectors.append([fvec[0], fvec[1], fvec[2]]) + else: + fvectors.append([-1.0*fvec[2], fvec[1], fvec[0]]) + + + Septumfiberdata.GetPointData().SetActiveVectors("n vectors") + temp = Septumfiberdata.GetPointData().GetVectors().GetTuple3(p); + svec[0] = temp[0] + svec[1] = temp[1] + svec[2] = temp[2] + vtkMath.Normalize(svec) + if(rotate == 0): + svectors.append([svec[0], svec[1], svec[2]]) + else: + svectors.append([-1.0*svec[2], svec[1], svec[0]]) + + +mtvfiberfilename = outdirectory+outfilename+"_fiber_rotated.axis" +mtvfiberfile = open(mtvfiberfilename, 'w') +print >>mtvfiberfile, len(fvectors), 10 + +mtvsheetfilename = outdirectory+outfilename+"_sheet_rotated.axis" +mtvsheetfile = open(mtvsheetfilename, 'w') +print >>mtvsheetfile, len(svectors) + +pdata = vtk.vtkPolyData() +ppoints = vtk.vtkPoints() +cellarray = vtk.vtkCellArray() + +fvector = vtk.vtkFloatArray() +fvector.SetNumberOfComponents(3) +fvector.SetName("f vectors") +svector = vtk.vtkFloatArray() +svector.SetNumberOfComponents(3) +svector.SetName("s vectors") +nvector = vtk.vtkFloatArray() +nvector.SetNumberOfComponents(3) +nvector.SetName("n vectors") + +for p in range(0,len(fvectors)): + + print >>mtvfiberfile, points[p][0], points[p][1], points[p][2], fvectors[p][0], fvectors[p][1], fvectors[p][2] + print >>mtvsheetfile, points[p][0], points[p][1], points[p][2], svectors[p][0], svectors[p][1], svectors[p][2] + + ppoints.InsertNextPoint(points[p][0],points[p][1], points[p][2]) + + vert = vtk.vtkVertex() + vert.GetPointIds().SetId(0,p) + cellarray.InsertNextCell(vert) + + fvector.InsertNextTuple3(fvectors[p][0], fvectors[p][1], fvectors[p][2]) + svector.InsertNextTuple3(svectors[p][0], svectors[p][1], svectors[p][2]) + + f = array([fvectors[p][0], fvectors[p][1], fvectors[p][2]]) + s = array([svectors[p][0], svectors[p][1], svectors[p][2]]) + n = cross(f,s) + + nvector.InsertNextTuple3(n[0], n[1], n[2]) + +pdata.SetPoints(ppoints) +pdata.SetVerts(cellarray) +pdata.GetPointData().SetActiveVectors("f vectors") +pdata.GetPointData().SetVectors(fvector) +pdata.GetPointData().SetActiveVectors("s vectors") +pdata.GetPointData().SetVectors(svector) +pdata.GetPointData().SetActiveVectors("n vectors") +pdata.GetPointData().SetVectors(nvector) + + +newfilename = outdirectory + outfilename + "_scaled_rotated.vtp" + +writer = vtk.vtkXMLPolyDataWriter() +writer.SetFileName(newfilename) +if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + writer.SetInput(pdata) +else: + writer.SetInputData(pdata) +writer.Write() + +mtvfiberfile.close() +mtvsheetfile.close() + + +print "************* Leaving vtkmtvfiber_sheet_vector_translator.py *****************" diff --git a/vtk_py/vtkmtvfiber_sheet_vector_translator_LVonly.py b/vtk_py/vtkmtvfiber_sheet_vector_translator_LVonly.py new file mode 100644 index 0000000..a4ca733 --- /dev/null +++ b/vtk_py/vtkmtvfiber_sheet_vector_translator_LVonly.py @@ -0,0 +1,162 @@ +######################################################################## + +import argparse +import glob +from numpy import * +from sets import Set +from vtk import * +import os + +import vtk_py as vtk_py + +######################################################################## + +def transform_scale_n_write(mesh, outdirectory): + + newfilename = outdirectory + "fiberdata" +"_scaled_rotated.vtp" + + bds = mesh.GetBounds() + + trans = vtk.vtkTransform() + trans.Translate(bds[5]/10,0,0) + trans.RotateY(-90) + trans.Scale(0.1, 0.1, 0.1) + + transfilter = vtk.vtkTransformPolyDataFilter() + transfilter.SetTransform(trans) + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + transfilter.SetInput(mesh) + else: + transfilter.SetInputData(mesh) + transfilter.Update() + + writer = vtk.vtkXMLPolyDataWriter() + writer.SetFileName(newfilename) + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + writer.SetInput(transfilter.GetOutput()) + else: + writer.SetInputData(transfilter.GetOutput()) + writer.Write() + +parser = argparse.ArgumentParser() +parser.add_argument('--vtk_folder', type=str, required=True) +parser.add_argument('--vtk_filename', type=str, required=True) +parser.add_argument('--fiberdata_directory', type=str, required=True) +parser.add_argument('--mtv_grid_directory', type=str, required=True) +parser.add_argument('--mtv_basename', type=str, required=True) +parser.add_argument('--scale', type=float, required=True) +args = parser.parse_args() + +print "************* Entering vtkmtvfiber_sheet_vector_translator_LVonly.py *****************" + + +points = [] +fvectors = [] +svectors = [] + +srcfilename = os.path.join(args.vtk_folder, args.vtk_filename) +directory = args.fiberdata_directory +outdirectory = args.mtv_grid_directory +outfilename = args.mtv_basename +scale = args.scale + +#srcfilename = "/home/likchuan/Research/C++/heartmech_bitbucket/pulse_cmake/pulse-cmake-growth/cases/singleLV/mesh/LV_fine.vtu" +#directory = "/home/likchuan/Research/C++/heartmech_bitbucket/pulse_cmake/pulse-cmake-growth/cases/singleLV/mesh/" +#outdirectory = "/home/likchuan/Research/C++/heartmech_bitbucket/pulse_cmake/pulse-cmake-growth/cases/singleLV/mesh/" +#outfilename = "LV_fiber_fine" + +reader = vtkXMLUnstructuredGridReader(); +reader.SetFileName(srcfilename); +reader.Update(); + + +mesh = vtkUnstructuredGrid(); +mesh.DeepCopy(reader.GetOutput()) + +rotate = 1; +bds = mesh.GetBounds() +zoffset = bds[5]; + + +rotate = 1; +# Import vtk file +# Read in LV fiber data +LVfiberreader = vtkXMLPolyDataReader(); +LVfiberreader.SetFileName(directory+"fiberdirections.vtp"); +LVfiberreader.Update(); + +LVfiberdata = vtkPolyData(); +LVfiberdata.DeepCopy(LVfiberreader.GetOutput()) + +fvec = [0,0,0] +svec = [0,0,0] +pts = [0,0,0] +rotatedpt = [0,0,0] + +for p in range(0, LVfiberdata.GetPoints().GetNumberOfPoints()): + pt= LVfiberdata.GetPoints().GetPoint(p) + if(rotate == 0): + points.append(pt) + else: + rotatedpt[0] = float(-pt[2]+zoffset)/scale; + rotatedpt[1] = float(pt[1])/scale; + rotatedpt[2] = float(pt[0])/scale; + #print rotatedpt + points.append([rotatedpt[0], rotatedpt[1], rotatedpt[2]]) + + + LVfiberdata.GetPointData().SetActiveVectors("fiber vectors") + temp = LVfiberdata.GetPointData().GetVectors().GetTuple3(p); + fvec[0] = temp[0] + fvec[1] = temp[1] + fvec[2] = temp[2] + vtkMath.Normalize(fvec) + if(rotate == 0): + fvectors.append([fvec[0], fvec[1], fvec[2]]) + else: + fvectors.append([-1.0*fvec[2], fvec[1], fvec[0]]) + + + LVfiberdata.GetPointData().SetActiveVectors("sheet vectors") + temp = LVfiberdata.GetPointData().GetVectors().GetTuple3(p); + svec[0] = temp[0] + svec[1] = temp[1] + svec[2] = temp[2] + vtkMath.Normalize(svec) + if(rotate == 0): + svectors.append([svec[0], svec[1], svec[2]]) + else: + svectors.append([-1.0*svec[2], svec[1], svec[0]]) + + +# Appending PolyData +appendeddata = vtk.vtkAppendPolyData() +if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + appendeddata.AddInput(LVfiberreader.GetOutput()) +else: + appendeddata.AddInputData(LVfiberreader.GetOutput()) +appendeddata.Update() + +#print appendeddata.GetOutput() + +#transform_scale_n_write(appendeddata.GetOutput(), outdirectory) + + +mtvfiberfilename = outdirectory+outfilename+"_fiber_rotated.axis" +mtvfiberfile = open(mtvfiberfilename, 'w') +print >>mtvfiberfile, len(fvectors), 10 + +mtvsheetfilename = outdirectory+outfilename+"_sheet_rotated.axis" +mtvsheetfile = open(mtvsheetfilename, 'w') +print >>mtvsheetfile, len(svectors) + +for p in range(0,len(fvectors)): + print >>mtvfiberfile, points[p][0], points[p][1], points[p][2], fvectors[p][0], fvectors[p][1], fvectors[p][2] + print >>mtvsheetfile, points[p][0], points[p][1], points[p][2], svectors[p][0], svectors[p][1], svectors[p][2] + + +mtvfiberfile.close() +mtvsheetfile.close() + + +print "************* Leaving vtkmtvfiber_sheet_vector_translator.py *****************" diff --git a/vtk_py/vtkmtvtranslator_lintets_LVonly_v1.py b/vtk_py/vtkmtvtranslator_lintets_LVonly_v1.py new file mode 100644 index 0000000..1d22c86 --- /dev/null +++ b/vtk_py/vtkmtvtranslator_lintets_LVonly_v1.py @@ -0,0 +1,462 @@ +######################################################################## + +import argparse +import glob +from numpy import * +from sets import Set +from vtk import * +import os + +import vtk_py as vtk_py + +######################################################################## + + + +def extract_tetra(mesh): + + idlist = vtk.vtkIdList() + celltype = mesh.GetCellTypesArray() + for p in range(0, celltype.GetNumberOfTuples()): + if(float(celltype.GetTuple(p)[0]) == 10): + idlist.InsertNextId(p) + + extracted = vtk.vtkExtractCells() + extracted.SetCellList(idlist) + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + extracted.SetInput(mesh) + else: + extracted.SetInputData(mesh) + extracted.Update() + + return extracted.GetOutput() + + + +def writepdata(filename, pdata): + + pdatawriter = vtk.vtkXMLPolyDataWriter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + pdatawriter.SetInput(pdata) + else: + pdatawriter.SetInputData(pdata) + pdatawriter.SetFileName(filename) + pdatawriter.Write() + + + +def savepoints(ugrid, nodeids, ptfilename): + + # View points + viewpts = vtk.vtkPoints() + viewptspdata =vtk.vtkPolyData() + for p in range(0, nodeids.GetNumberOfIds()): + pt = [0,0,0] + pt = ugrid.GetPoints().GetPoint(nodeids.GetId(p)) + viewpts.InsertNextPoint(pt) + + viewptspdata.SetPoints(viewpts) + + maskPoints = vtk.vtkMaskPoints() + maskPoints.SetOnRatio(1); + maskPoints.SetInput(viewptspdata); + maskPoints.GenerateVerticesOn(); + maskPoints.Update(); + + writepdata(ptfilename, maskPoints.GetOutput()) + + +def extract_LV_surf_nodes(ugrid): + + Basalsurfnodes = vtk.vtkIdList() + Episurfnodes = vtk.vtkIdList() + LVEndosurfnodes = vtk.vtkIdList() + Basalepisurfnodes = vtk.vtkIdList() + + Episurf = vtk.vtkPolyData() + LVEndosurf = vtk.vtkPolyData() + + Idfilter = vtk.vtkIdFilter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + Idfilter.SetInput(ugrid) + else: + Idfilter.SetInputData(ugrid) + Idfilter.Update() + + geomfilter = vtk.vtkGeometryFilter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + geomfilter.SetInput(Idfilter.GetOutput()) + else: + geomfilter.SetInputData(Idfilter.GetOutput()) + geomfilter.Update() + + cleanpdata = vtk.vtkCleanPolyData() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + cleanpdata.SetInput(geomfilter.GetOutput()) + else: + cleanpdata.SetInputData(geomfilter.GetOutput()) + cleanpdata.Update() + + pdatanormal = vtk.vtkPolyDataNormals() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + pdatanormal.SetInput(cleanpdata.GetOutput()) + else: + pdatanormal.SetInputData(cleanpdata.GetOutput()) + pdatanormal.ComputeCellNormalsOn() + pdatanormal.Update() + + reducedsurfacemesh = vtk.vtkPolyData() + reducedsurfacemesh.DeepCopy(pdatanormal.GetOutput()) + reducedsurfacemesh.BuildLinks() + + bds = reducedsurfacemesh.GetBounds() + numcells = reducedsurfacemesh.GetNumberOfCells() + tol = 1e-1; + for p in range(0, numcells): + + ptlist = vtk.vtkIdList() + normvec = reducedsurfacemesh.GetCellData().GetArray("Normals").GetTuple3(p) + + # If cell normal is in 0,0,1 direction + if(abs(vtkMath.Dot(normvec, [1,0,0])) < tol and abs(vtkMath.Dot(normvec, [0,1,0])) < tol): + reducedsurfacemesh.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = reducedsurfacemesh.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + + pt = [0,0,0] + pt = ugrid.GetPoints().GetPoint(ptid) + + if(pt[2] > 0.5*(bds[5] + bds[4])): + Basalsurfnodes.InsertUniqueId(ptid) + + reducedsurfacemesh.DeleteCell(p) + + reducedsurfacemesh.RemoveDeletedCells(); + #reducedsurfacemesh.Update() + + + # Split the surfaces to LVendo, RVendo, Epi + connectivityfilter = vtk.vtkPolyDataConnectivityFilter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + connectivityfilter.SetInput(reducedsurfacemesh) + else: + connectivityfilter.SetInputData(reducedsurfacemesh) + connectivityfilter.Update() + + # Extracting Epi surface + connectivityfilter.SetExtractionModeToLargestRegion(); + connectivityfilter.ColorRegionsOn(); + connectivityfilter.Update(); + Episurf.DeepCopy(connectivityfilter.GetOutput()); + + zrange = [] + for p in range(0, 3): + + connectivityfilter.AddSpecifiedRegion(p); + connectivityfilter.SetExtractionModeToSpecifiedRegions(); + connectivityfilter.Update(); + connectivityfilter.DeleteSpecifiedRegion(p); + + bds = connectivityfilter.GetOutput().GetBounds() + zrange.append(abs(bds[5] - bds[4])) + + epiids = zrange.index(max(zrange)) + RVendoids = zrange.index(min(zrange)) + idlist = set([0,1]) + #LVendoids = list(idlist.difference(set([epiids, RVendoids])))[0] + LVendoids = list(idlist.difference(set([epiids])))[0] + + # Extracting LV surface + connectivityfilter.AddSpecifiedRegion(LVendoids); + connectivityfilter.SetExtractionModeToSpecifiedRegions(); + connectivityfilter.Update(); + LVEndosurf.DeepCopy(connectivityfilter.GetOutput()); + connectivityfilter.DeleteSpecifiedRegion(LVendoids); + + # Get Epi surface points + for p in range(0, Episurf.GetNumberOfCells()): + ptlist = vtk.vtkIdList() + Episurf.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = Episurf.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + Episurfnodes.InsertUniqueId(ptid) + + + # Get LV surface points + for p in range(0, LVEndosurf.GetNumberOfCells()): + ptlist = vtk.vtkIdList() + LVEndosurf.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = LVEndosurf.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + LVEndosurfnodes.InsertUniqueId(ptid) + + # Get Epi basal edge points + Basalepisurfnodes.DeepCopy(Basalsurfnodes) + Basalepisurfnodes.IntersectWith(Episurfnodes) + + + return Basalsurfnodes, Basalepisurfnodes, Episurfnodes, LVEndosurfnodes + + + +def set_pix_intensity(mesh, vtuoutputdir, vtufilename, txtoutputdir, txtfilename): + + + outvtufilename = vtuoutputdir + vtufilename + outtxtfilename = txtoutputdir + txtfilename + + txtfile = open(outtxtfilename, "w"); + + cellpixintensity = mesh.GetCellData().GetScalars("closest_pix_intensity") + print cellpixintensity.GetNumberOfTuples() + + rangeofpixintensity = cellpixintensity.GetValueRange() + + + matid = vtk.vtkIntArray() + matid.SetNumberOfComponents(1) + matid.SetName("Material Id") + + normalized_pix = vtk.vtkFloatArray() + normalized_pix.SetNumberOfComponents(1) + normalized_pix.SetName("Normalized Pixel Intensity") + + for p in range(0, mesh.GetNumberOfCells()): + + pix_intensity = cellpixintensity.GetTuple(p) + normalized_pix_intensity = (pix_intensity[0] - rangeofpixintensity[0])/(rangeofpixintensity[1] - rangeofpixintensity[0]) + + normalized_pix.InsertNextValue(normalized_pix_intensity) + + print >>txtfile, p+1, normalized_pix_intensity + + txtfile.close() + + #mesh.GetCellData().SetActiveScalars("Material Id") + #mesh.GetCellData().SetScalars(matid) + + mesh.GetCellData().SetActiveScalars("Normalized_Pixel_Intensity") + mesh.GetCellData().SetScalars(normalized_pix) + + writer = vtk.vtkXMLUnstructuredGridWriter() + writer.SetFileName(outvtufilename) + writer.SetInput(mesh) + writer.Write(); + +def transform_scale_n_write(mesh, outdirectory, vtufilename): + + newfilename = outdirectory + vtufilename[0:len(vtufilename)-4]+"_scaled_rotated.vtu" + + + bds = mesh.GetBounds() + + trans = vtk.vtkTransform() + trans.Translate(bds[5]/10,0,0) + trans.RotateY(-90) + trans.Scale(0.1, 0.1, 0.1) + + + transfilter = vtk.vtkTransformFilter() + transfilter.SetTransform(trans) + transfilter.SetInput(mesh) + + writer = vtk.vtkXMLUnstructuredGridWriter() + writer.SetFileName(newfilename) + writer.SetInput(transfilter.GetOutput()) + writer.Write() + +def convert_lintets_2_mtv(mesh, outdirectory, name, issavepts, isrotate, basalnormal, tol, epispringcond, scale): + + + rotate = isrotate; + bds = mesh.GetBounds() + if(basalnormal == 'z'): + zoffset = bds[5]; + print "z offset = ", zoffset + elif(basalnormal == 'x'): + zoffset = bds[1]; + print "x offset = ", zoffset + + filename = outdirectory + name + ".grid" + mtvfile = open(filename, 'w') + + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, "Finite element mesh (MLGridFEAdB)" + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, "Finite element mesh (GridFE):" + print >>mtvfile, " " + print >>mtvfile, " Number of space dim. = 3 embedded in physical space with dimension 3" + print >>mtvfile, " Number of elements = %5d" %mesh.GetNumberOfCells() + print >>mtvfile, " Number of nodes = %5d" %mesh.GetNumberOfPoints() + print >>mtvfile, " " + print >>mtvfile, " All elements are of the same type : true" + print >>mtvfile, " Max number of nodes in an element: 4" + print >>mtvfile, " Only one material : false" + print >>mtvfile, " Lattice data ? 0" + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " 12 boundary indicators: " + print >>mtvfile, " P1" + print >>mtvfile, " P2" + print >>mtvfile, " P3" + print >>mtvfile, " T1" + print >>mtvfile, " T2" + print >>mtvfile, " u1=0" + print >>mtvfile, " u2=0" + print >>mtvfile, " u3=0" + print >>mtvfile, " u1=u1_0" + print >>mtvfile, " u2=u2_0" + print >>mtvfile, " u3=u3_0" + print >>mtvfile, " free" + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " Nodal coordinates and nodal boundary indicators," + print >>mtvfile, " the columns contain:" + print >>mtvfile, " - node number" + print >>mtvfile, " - coordinates" + print >>mtvfile, " - no of boundary indicators that are set (ON)" + print >>mtvfile, " - the boundary indicators that are set (ON) if any." + print >>mtvfile, "#" + + + # Get Surface nodes for pressure constraint + Basalsurfnodes, Basalepisurfnodes, Episurfnodes, LVEndosurfnodes = extract_LV_surf_nodes(mesh) + + if(issavepts == 1): + ptfilename = outdirectory + name + '_Basalsurfnodes.vtp' + savepoints(mesh, Basalsurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_Basalepisurfnodes.vtp' + savepoints(mesh, Basalepisurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_Episurfnodes.vtp' + savepoints(mesh, Episurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_LVEndosurfnodes.vtp' + savepoints(mesh, LVEndosurfnodes, ptfilename) + + + + num_bindicator = zeros(mesh.GetNumberOfPoints()); + bindicator = ['']*mesh.GetNumberOfPoints(); + + for k in range(0,Episurfnodes.GetNumberOfIds()): + nodeid = Episurfnodes.GetId(k) + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + if(epispringcond): + bindicator[nodeid] = bindicator[nodeid] + ' 4' + else: + bindicator[nodeid] = bindicator[nodeid] + ' 3' + + for k in range(0,LVEndosurfnodes.GetNumberOfIds()): + nodeid = LVEndosurfnodes.GetId(k) + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 1' + + for k in range(0,Basalepisurfnodes.GetNumberOfIds()): + nodeid = Basalepisurfnodes.GetId(k) + if(epispringcond): + num_bindicator[nodeid] = num_bindicator[nodeid] + 0 + else: + num_bindicator[nodeid] = num_bindicator[nodeid] + 3 + bindicator[nodeid] = bindicator[nodeid] + ' 6 7 8' + + for k in range(0,Basalsurfnodes.GetNumberOfIds()): + nodeid = Basalsurfnodes.GetId(k) + if(rotate == 0): + if(Basalepisurfnodes.IsId(nodeid) == -1): + if(epispringcond): + num_bindicator[nodeid] = num_bindicator[nodeid] + 0 + else: + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 8' + else: + if(Basalepisurfnodes.IsId(nodeid) == -1): + if(epispringcond): + num_bindicator[nodeid] = num_bindicator[nodeid] + 0 + else: + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 6' + + + #print bindicator + pt = [0,0,0]; + rotatedpt = [0,0,0]; + #num_bindicator = 0; + #bindicator = " "; + for p in range(0, mesh.GetNumberOfPoints()): + if(rotate == 0): + mesh.GetPoints().GetPoint(p,pt); + print >>mtvfile, "%6d ( %11.5e, %11.5e, %11.5e) [%d] %s " %((p+1), pt[0], pt[1], pt[2], num_bindicator[p], bindicator[p] ) + else: + mesh.GetPoints().GetPoint(p,pt); + rotatedpt[0] = (-pt[2]+zoffset)/1.0; + rotatedpt[1] = (pt[1])/1.0; + rotatedpt[2] = (pt[0])/1.0; + + print >>mtvfile, "%6d ( %11.5e, %11.5e, %11.5e) [%d] %s " %((p+1), rotatedpt[0], rotatedpt[1], rotatedpt[2], num_bindicator[p], bindicator[p] ) + + print >>mtvfile, " " + print >>mtvfile, " Element types and connectivity" + print >>mtvfile, " the columns contain:" + print >>mtvfile, " - element number" + print >>mtvfile, " - element type" + print >>mtvfile, " - material number" + print >>mtvfile, " - the global node numbers of the nodes in the element." + print >>mtvfile, "#" + + + materialid = mesh.GetCellData().GetArray('Material Id') + ptid = vtkIdList() + ids = [0,0,0,0,0,0,0,0,0,0]; + + for p in range(0, mesh.GetNumberOfCells()): + mesh.GetCellPoints(p, ptid); + for j in range(0, 4): + ids[j] = int(ptid.GetId(j)); + try: + matid = materialid.GetValue(p) + + except AttributeError: + matid = 1 + + print >>mtvfile, "%5d ElmT4n3D %1d %5d %5d %5d %5d " %((p+1), matid, ids[0]+1, ids[1]+1, ids[2]+1, ids[3]+1) + + + mtvfile.close() + + +tol = 1e-1 +parser = argparse.ArgumentParser() +parser.add_argument('--vtk_folder', type=str, required=True) +parser.add_argument('--vtk_filename', type=str, required=True) +parser.add_argument('--mtv_grid_directory', type=str, required=True) +parser.add_argument('--mtv_basename', type=str, required=True) +parser.add_argument('--isepispring', type=int, required=True) +parser.add_argument('--scale', type=float, required=True) +args = parser.parse_args() + + +print "************* Entering vtkmtvtranslator_lintets_v1.py *****************" + +if(args.isepispring): + print "Enforce spring B.C on epi" + + +if (args.vtk_filename[len(args.vtk_filename)-3:len(args.vtk_filename)] == 'vtu'): + print os.path.join(args.vtk_folder, args.vtk_filename) + mesh = vtk_py.readXMLUGrid(os.path.join(args.vtk_folder, args.vtk_filename)) +else: + mesh = vtk_py.readUGrid(os.path.join(args.vtk_folder, args.vtk_filename)) + +mesh = extract_tetra(mesh) + +convert_lintets_2_mtv(mesh, args.mtv_grid_directory, args.mtv_basename, 1, 1, "z", tol, args.isepispring, args.scale) + +print "************* Leaving vtkmtvtranslator_lintets_v1.py *****************" + + diff --git a/vtk_py/vtkmtvtranslator_lintets_v1.py b/vtk_py/vtkmtvtranslator_lintets_v1.py new file mode 100644 index 0000000..c3ca94d --- /dev/null +++ b/vtk_py/vtkmtvtranslator_lintets_v1.py @@ -0,0 +1,554 @@ +######################################################################## + +import argparse +import glob +from numpy import * +from sets import Set +from vtk import * +import os + +import vtk_py as vtk_py + +######################################################################## + + + + +def extract_tetra(mesh): + + idlist = vtk.vtkIdList() + celltype = mesh.GetCellTypesArray() + for p in range(0, celltype.GetNumberOfTuples()): + if(float(celltype.GetTuple(p)[0]) == 10): + idlist.InsertNextId(p) + + extracted = vtk.vtkExtractCells() + extracted.SetCellList(idlist) + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + extracted.SetInput(mesh) + else: + extracted.SetInputData(mesh) + extracted.Update() + + return extracted.GetOutput() + + + +def writepdata(filename, pdata): + + pdatawriter = vtk.vtkXMLPolyDataWriter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + pdatawriter.SetInput(pdata) + else: + pdatawriter.SetInputData(pdata) + pdatawriter.SetFileName(filename) + pdatawriter.Write() + + + +def savepoints(ugrid, nodeids, ptfilename): + + # View points + viewpts = vtk.vtkPoints() + viewptspdata =vtk.vtkPolyData() + for p in range(0, nodeids.GetNumberOfIds()): + pt = [0,0,0] + pt = ugrid.GetPoints().GetPoint(nodeids.GetId(p)) + viewpts.InsertNextPoint(pt) + + viewptspdata.SetPoints(viewpts) + + maskPoints = vtk.vtkMaskPoints() + maskPoints.SetOnRatio(1); + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + maskPoints.SetInput(viewptspdata); + else: + maskPoints.SetInputData(viewptspdata); + maskPoints.GenerateVerticesOn(); + maskPoints.Update(); + + writepdata(ptfilename, maskPoints.GetOutput()) + + +def extract_biven_surf_nodes(ugrid, basalnormal, tol): + + Basalsurfnodes = vtk.vtkIdList() + Episurfnodes = vtk.vtkIdList() + RVEndosurfnodes = vtk.vtkIdList() + LVEndosurfnodes = vtk.vtkIdList() + Basalepisurfnodes = vtk.vtkIdList() + + Episurf = vtk.vtkPolyData() + LVEndosurf = vtk.vtkPolyData() + RVEndosurf = vtk.vtkPolyData() + + Idfilter = vtk.vtkIdFilter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + Idfilter.SetInput(ugrid) + else: + Idfilter.SetInputData(ugrid) + Idfilter.Update() + + geomfilter = vtk.vtkGeometryFilter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + geomfilter.SetInput(Idfilter.GetOutput()) + else: + geomfilter.SetInputData(Idfilter.GetOutput()) + geomfilter.Update() + + cleanpdata = vtk.vtkCleanPolyData() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + cleanpdata.SetInput(geomfilter.GetOutput()) + else: + cleanpdata.SetInputData(geomfilter.GetOutput()) + cleanpdata.Update() + + pdatanormal = vtk.vtkPolyDataNormals() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + pdatanormal.SetInput(cleanpdata.GetOutput()) + else: + pdatanormal.SetInputData(cleanpdata.GetOutput()) + pdatanormal.ComputeCellNormalsOn() + pdatanormal.Update() + + #vtk_py.writeXMLPData(pdatanormal.GetOutput(), "test.vtp") + + reducedsurfacemesh = vtk.vtkPolyData() + reducedsurfacemesh.DeepCopy(pdatanormal.GetOutput()) + reducedsurfacemesh.BuildLinks() + + bds = reducedsurfacemesh.GetBounds() + numcells = reducedsurfacemesh.GetNumberOfCells() + for p in range(0, numcells): + + ptlist = vtk.vtkIdList() + normvec = reducedsurfacemesh.GetCellData().GetArray("Normals").GetTuple3(p) + + # If cell normal is in 0,0,1 direction + if(basalnormal == 'z'): + if(abs(vtkMath.Dot(normvec, [1,0,0])) < tol and abs(vtkMath.Dot(normvec, [0,1,0])) < tol): + reducedsurfacemesh.GetCellPoints(p, ptlist) + count_nodes_at_base = 0; + for j in range(0, ptlist.GetNumberOfIds()): + ptid = reducedsurfacemesh.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + + pt = [0,0,0] + pt = ugrid.GetPoints().GetPoint(ptid) + + if(pt[2] > 0.5*(bds[5] + bds[4])): + Basalsurfnodes.InsertUniqueId(ptid) + + if(pt[2] > bds[5] - tol): + count_nodes_at_base = count_nodes_at_base + 1 + + if(count_nodes_at_base == 3): + reducedsurfacemesh.DeleteCell(p) + + elif(basalnormal =='x'): + + if(abs(vtkMath.Dot(normvec, [0,0,1])) < tol and abs(vtkMath.Dot(normvec, [0,1,0])) < tol): + reducedsurfacemesh.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = reducedsurfacemesh.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + + pt = [0,0,0] + pt = ugrid.GetPoints().GetPoint(ptid) + + + if(pt[0] < bds[0] + tol): + Basalsurfnodes.InsertUniqueId(ptid) + + if(pt[0] < bds[0] + tol): + reducedsurfacemesh.DeleteCell(p) + + + + reducedsurfacemesh.RemoveDeletedCells(); + #reducedsurfacemesh.Update() + + + # Split the surfaces to LVendo, RVendo, Epi + connectivityfilter = vtk.vtkPolyDataConnectivityFilter() + connectivityfilter.SetScalarConnectivity(0); + connectivityfilter.ColorRegionsOn(); + connectivityfilter.SetExtractionModeToAllRegions() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + connectivityfilter.SetInput(reducedsurfacemesh) + else: + connectivityfilter.SetInputData(reducedsurfacemesh) + connectivityfilter.Update() + + print "Number of connected regions = ", connectivityfilter.GetNumberOfExtractedRegions() + vtk_py.writeXMLPData(connectivityfilter.GetOutput(), "connectedregion.vtp") + + + # Extracting Epi surface + connectivityfilter.SetExtractionModeToLargestRegion(); + connectivityfilter.ColorRegionsOn(); + connectivityfilter.Update(); + Episurf.DeepCopy(connectivityfilter.GetOutput()); + + + zrange = [] + for p in range(0, 3): + + connectivityfilter.AddSpecifiedRegion(p); + connectivityfilter.SetExtractionModeToSpecifiedRegions(); + connectivityfilter.Update(); + connectivityfilter.DeleteSpecifiedRegion(p); + + bds = connectivityfilter.GetOutput().GetBounds() + + if(basalnormal == 'z'): + zrange.append(abs(bds[5] - bds[4])) + elif(basalnormal == 'x'): + zrange.append(abs(bds[1] - bds[0])) + + epiids = zrange.index(max(zrange)) + #RVendoids = zrange.index(min(zrange)) + LVendoids = zrange.index(min(zrange)) + #idlist = set([0,1,2]) + #LVendoids = list(idlist.difference(set([epiids, RVendoids])))[0] + + epiids = 0 + LVendoids = 2 + + # Extracting RV surface + [connectivityfilter.AddSpecifiedRegion(p) for p in range(0,connectivityfilter.GetNumberOfExtractedRegions())] + connectivityfilter.DeleteSpecifiedRegion(epiids); + connectivityfilter.DeleteSpecifiedRegion(LVendoids); + connectivityfilter.SetExtractionModeToSpecifiedRegions(); + #connectivityfilter.SetExtractionModeToSpecifiedRegions(); + connectivityfilter.Update(); + RVEndosurf.DeepCopy(connectivityfilter.GetOutput()); + [connectivityfilter.DeleteSpecifiedRegion(p) for p in range(0,connectivityfilter.GetNumberOfExtractedRegions())] + #connectivityfilter.DeleteSpecifiedRegion(RVendoids); + + + outfilename = 'RV_surf.vtp' + vtk_py.writeXMLPData(RVEndosurf, outfilename) + + # Extracting LV surface + connectivityfilter.AddSpecifiedRegion(LVendoids); + connectivityfilter.SetExtractionModeToSpecifiedRegions(); + connectivityfilter.Update(); + LVEndosurf.DeepCopy(connectivityfilter.GetOutput()); + connectivityfilter.DeleteSpecifiedRegion(LVendoids); + + outfilename = 'LV_surf.vtp' + vtk_py.writeXMLPData(LVEndosurf, outfilename) + + + # Get Epi surface points + for p in range(0, Episurf.GetNumberOfCells()): + ptlist = vtk.vtkIdList() + Episurf.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = Episurf.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + Episurfnodes.InsertUniqueId(ptid) + + + # Get RV surface points + for p in range(0, RVEndosurf.GetNumberOfCells()): + ptlist = vtk.vtkIdList() + RVEndosurf.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = RVEndosurf.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + RVEndosurfnodes.InsertUniqueId(ptid) + + # Get LV surface points + for p in range(0, LVEndosurf.GetNumberOfCells()): + ptlist = vtk.vtkIdList() + LVEndosurf.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = LVEndosurf.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + LVEndosurfnodes.InsertUniqueId(ptid) + + # Get Epi basal edge points + Basalepisurfnodes.DeepCopy(Basalsurfnodes) + Basalepisurfnodes.IntersectWith(Episurfnodes) + + + return Basalsurfnodes, Basalepisurfnodes, Episurfnodes, RVEndosurfnodes, LVEndosurfnodes + + + +def set_pix_intensity(mesh, vtuoutputdir, vtufilename, txtoutputdir, txtfilename): + + + outvtufilename = vtuoutputdir + vtufilename + outtxtfilename = txtoutputdir + txtfilename + + txtfile = open(outtxtfilename, "w"); + + cellpixintensity = mesh.GetCellData().GetScalars("closest_pix_intensity") + print cellpixintensity.GetNumberOfTuples() + + rangeofpixintensity = cellpixintensity.GetValueRange() + + + matid = vtk.vtkIntArray() + matid.SetNumberOfComponents(1) + matid.SetName("Material Id") + + normalized_pix = vtk.vtkFloatArray() + normalized_pix.SetNumberOfComponents(1) + normalized_pix.SetName("Normalized Pixel Intensity") + + for p in range(0, mesh.GetNumberOfCells()): + + pix_intensity = cellpixintensity.GetTuple(p) + normalized_pix_intensity = (pix_intensity[0] - rangeofpixintensity[0])/(rangeofpixintensity[1] - rangeofpixintensity[0]) + + normalized_pix.InsertNextValue(normalized_pix_intensity) + + print >>txtfile, p+1, normalized_pix_intensity + + txtfile.close() + + #mesh.GetCellData().SetActiveScalars("Material Id") + #mesh.GetCellData().SetScalars(matid) + + mesh.GetCellData().SetActiveScalars("Normalized_Pixel_Intensity") + mesh.GetCellData().SetScalars(normalized_pix) + + writer = vtk.vtkXMLUnstructuredGridWriter() + writer.SetFileName(outvtufilename) + writer.SetInput(mesh) + writer.Write(); + +def transform_scale_n_write(mesh, outdirectory, vtufilename): + + newfilename = outdirectory + vtufilename[0:len(vtufilename)-4]+"_scaled_rotated.vtu" + + + bds = mesh.GetBounds() + + trans = vtk.vtkTransform() + trans.Translate(bds[5]/10,0,0) + trans.RotateY(-90) + trans.Scale(0.1, 0.1, 0.1) + + + transfilter = vtk.vtkTransformFilter() + transfilter.SetTransform(trans) + transfilter.SetInput(mesh) + + writer = vtk.vtkXMLUnstructuredGridWriter() + writer.SetFileName(newfilename) + writer.SetInput(transfilter.GetOutput()) + writer.Write() + +def convert_lintets_2_mtv(mesh, outdirectory, name, issavepts, isrotate, basalnormal, tol, epispringcond): + + + rotate = isrotate; + bds = mesh.GetBounds() + if(basalnormal == 'z'): + zoffset = bds[5]; + print "z offset = ", zoffset + elif(basalnormal == 'x'): + zoffset = bds[1]; + print "x offset = ", zoffset + + filename = outdirectory + name + ".grid" + mtvfile = open(filename, 'w') + + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, "Finite element mesh (MLGridFEAdB)" + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, "Finite element mesh (GridFE):" + print >>mtvfile, " " + print >>mtvfile, " Number of space dim. = 3 embedded in physical space with dimension 3" + print >>mtvfile, " Number of elements = %5d" %mesh.GetNumberOfCells() + print >>mtvfile, " Number of nodes = %5d" %mesh.GetNumberOfPoints() + print >>mtvfile, " " + print >>mtvfile, " All elements are of the same type : true" + print >>mtvfile, " Max number of nodes in an element: 4" + print >>mtvfile, " Only one material : false" + print >>mtvfile, " Lattice data ? 0" + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " 12 boundary indicators: " + print >>mtvfile, " P1" + print >>mtvfile, " P2" + print >>mtvfile, " P3" + print >>mtvfile, " T1" + print >>mtvfile, " T2" + print >>mtvfile, " u1=0" + print >>mtvfile, " u2=0" + print >>mtvfile, " u3=0" + print >>mtvfile, " u1=u1_0" + print >>mtvfile, " u2=u2_0" + print >>mtvfile, " u3=u3_0" + print >>mtvfile, " free" + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " Nodal coordinates and nodal boundary indicators," + print >>mtvfile, " the columns contain:" + print >>mtvfile, " - node number" + print >>mtvfile, " - coordinates" + print >>mtvfile, " - no of boundary indicators that are set (ON)" + print >>mtvfile, " - the boundary indicators that are set (ON) if any." + print >>mtvfile, "#" + + + # Get Surface nodes for pressure constraint + Basalsurfnodes, Basalepisurfnodes, Episurfnodes, RVEndosurfnodes, LVEndosurfnodes = extract_biven_surf_nodes(mesh, basalnormal, tol) + + if(issavepts == 1): + ptfilename = outdirectory + name + '_Basalsurfnodes.vtp' + savepoints(mesh, Basalsurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_Basalepisurfnodes.vtp' + savepoints(mesh, Basalepisurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_Episurfnodes.vtp' + savepoints(mesh, Episurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_RVEndosurfnodes.vtp' + savepoints(mesh, RVEndosurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_LVEndosurfnodes.vtp' + savepoints(mesh, LVEndosurfnodes, ptfilename) + + + + + num_bindicator = zeros(mesh.GetNumberOfPoints()); + bindicator = ['']*mesh.GetNumberOfPoints(); + for k in range(0,Episurfnodes.GetNumberOfIds()): + nodeid = Episurfnodes.GetId(k) + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + if(epispringcond==1): + bindicator[nodeid] = bindicator[nodeid] + ' 4' + elif(epispringcond==2): + bindicator[nodeid] = bindicator[nodeid] + ' 4' + else: + bindicator[nodeid] = bindicator[nodeid] + ' 3' + + for k in range(0,LVEndosurfnodes.GetNumberOfIds()): + nodeid = LVEndosurfnodes.GetId(k) + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 1' + + for k in range(0,RVEndosurfnodes.GetNumberOfIds()): + nodeid = RVEndosurfnodes.GetId(k) + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 2' + + for k in range(0,Basalepisurfnodes.GetNumberOfIds()): + nodeid = Basalepisurfnodes.GetId(k) + if(epispringcond==1): + num_bindicator[nodeid] = num_bindicator[nodeid] + 0 + elif(epispringcond==2): + num_bindicator[nodeid] = num_bindicator[nodeid] + 2 + if(rotate == 0): + bindicator[nodeid] = bindicator[nodeid] + ' 4 8' + else: + bindicator[nodeid] = bindicator[nodeid] + ' 4 6' + else: + num_bindicator[nodeid] = num_bindicator[nodeid] + 3 + bindicator[nodeid] = bindicator[nodeid] + ' 6 7 8' + + for k in range(0,Basalsurfnodes.GetNumberOfIds()): + nodeid = Basalsurfnodes.GetId(k) + if(rotate == 0): + if(Basalepisurfnodes.IsId(nodeid) == -1): + if(epispringcond==1): + num_bindicator[nodeid] = num_bindicator[nodeid] + 0 + elif(epispringcond==2): + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 8' + else: + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 8' + else: + if(Basalepisurfnodes.IsId(nodeid) == -1): + if(epispringcond==1): + num_bindicator[nodeid] = num_bindicator[nodeid] + 0 + elif(epispringcond==2): + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 6' + else: + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 6' + + #print bindicator + pt = [0,0,0]; + rotatedpt = [0,0,0]; + #num_bindicator = 0; + #bindicator = " "; + for p in range(0, mesh.GetNumberOfPoints()): + if(rotate == 0): + mesh.GetPoints().GetPoint(p,pt); + print >>mtvfile, "%6d ( %11.5e, %11.5e, %11.5e) [%d] %s " %((p+1), pt[0], pt[1], pt[2], num_bindicator[p], bindicator[p] ) + else: + mesh.GetPoints().GetPoint(p,pt); + rotatedpt[0] = (-pt[2]+zoffset)/10.0; + rotatedpt[1] = (pt[1])/10.0; + rotatedpt[2] = (pt[0])/10.0; + + print >>mtvfile, "%6d ( %11.5e, %11.5e, %11.5e) [%d] %s " %((p+1), rotatedpt[0], rotatedpt[1], rotatedpt[2], num_bindicator[p], bindicator[p] ) + + print >>mtvfile, " " + print >>mtvfile, " Element types and connectivity" + print >>mtvfile, " the columns contain:" + print >>mtvfile, " - element number" + print >>mtvfile, " - element type" + print >>mtvfile, " - material number" + print >>mtvfile, " - the global node numbers of the nodes in the element." + print >>mtvfile, "#" + + + materialid = mesh.GetCellData().GetArray('Material Id') + ptid = vtkIdList() + ids = [0,0,0,0,0,0,0,0,0,0]; + + for p in range(0, mesh.GetNumberOfCells()): + mesh.GetCellPoints(p, ptid); + for j in range(0, 4): + ids[j] = int(ptid.GetId(j)); + try: + matid = materialid.GetValue(p) + + except AttributeError: + matid = 1 + + print >>mtvfile, "%5d ElmT4n3D %1d %5d %5d %5d %5d " %((p+1), matid, ids[0]+1, ids[1]+1, ids[2]+1, ids[3]+1) + + + mtvfile.close() + + + +tol = 1e-1 +parser = argparse.ArgumentParser() +parser.add_argument('--vtk_folder', type=str, required=True) +parser.add_argument('--vtk_filename', type=str, required=True) +parser.add_argument('--mtv_grid_directory', type=str, required=True) +parser.add_argument('--mtv_basename', type=str, required=True) +parser.add_argument('--isepispring', type=int, required=True) +args = parser.parse_args() + + +print "************* Entering vtkmtvtranslator_lintets_v1.py *****************" + +if(args.isepispring): + print "Enforce spring B.C on epi" + + +if (args.vtk_filename[len(args.vtk_filename)-3:len(args.vtk_filename)] == 'vtu'): + mesh = vtk_py.readXMLUGrid(os.path.join(args.vtk_folder, args.vtk_filename)) +else: + mesh = vtk_py.readUGrid(os.path.join(args.vtk_folder, args.vtk_filename)) + +mesh = extract_tetra(mesh) + +convert_lintets_2_mtv(mesh, args.mtv_grid_directory, args.mtv_basename, 1, 1, "z", tol, args.isepispring) + +print "************* Leaving vtkmtvtranslator_lintets_v1.py *****************" diff --git a/vtk_py/vtkmtvtranslator_quadtets_LVonly_v1.py b/vtk_py/vtkmtvtranslator_quadtets_LVonly_v1.py new file mode 100644 index 0000000..5ea740e --- /dev/null +++ b/vtk_py/vtkmtvtranslator_quadtets_LVonly_v1.py @@ -0,0 +1,477 @@ +######################################################################## + +import argparse +import glob +from numpy import * +from sets import Set +from vtk import * +import os + +import vtk_py as vtk_py + +######################################################################## + + + +def extract_tetra(mesh): + + idlist = vtk.vtkIdList() + celltype = mesh.GetCellTypesArray() + for p in range(0, celltype.GetNumberOfTuples()): + if(float(celltype.GetTuple(p)[0]) == 24): + idlist.InsertNextId(p) + + extracted = vtk.vtkExtractCells() + extracted.SetCellList(idlist) + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + extracted.SetInput(mesh) + else: + extracted.SetInputData(mesh) + extracted.Update() + + return extracted.GetOutput() + + + +def writepdata(filename, pdata): + + pdatawriter = vtk.vtkXMLPolyDataWriter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + pdatawriter.SetInput(pdata) + else: + pdatawriter.SetInputData(pdata) + pdatawriter.SetFileName(filename) + pdatawriter.Write() + + + +def savepoints(ugrid, nodeids, ptfilename): + + # View points + viewpts = vtk.vtkPoints() + viewptspdata =vtk.vtkPolyData() + for p in range(0, nodeids.GetNumberOfIds()): + pt = [0,0,0] + pt = ugrid.GetPoints().GetPoint(nodeids.GetId(p)) + viewpts.InsertNextPoint(pt) + + viewptspdata.SetPoints(viewpts) + + maskPoints = vtk.vtkMaskPoints() + maskPoints.SetOnRatio(1); + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + maskPoints.SetInput(viewptspdata); + else: + maskPoints.SetInputData(viewptspdata); + maskPoints.GenerateVerticesOn(); + maskPoints.Update(); + + writepdata(ptfilename, maskPoints.GetOutput()) + + +def extract_LV_surf_nodes(ugrid): + + Basalsurfnodes = vtk.vtkIdList() + Episurfnodes = vtk.vtkIdList() + LVEndosurfnodes = vtk.vtkIdList() + Basalepisurfnodes = vtk.vtkIdList() + + + Episurf = vtk.vtkPolyData() + LVEndosurf = vtk.vtkPolyData() + + Idfilter = vtk.vtkIdFilter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + Idfilter.SetInput(ugrid) + else: + Idfilter.SetInputData(ugrid) + Idfilter.Update() + + geomfilter = vtk.vtkGeometryFilter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + geomfilter.SetInput(Idfilter.GetOutput()) + else: + geomfilter.SetInputData(Idfilter.GetOutput()) + geomfilter.Update() + + cleanpdata = vtk.vtkCleanPolyData() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + cleanpdata.SetInput(geomfilter.GetOutput()) + else: + cleanpdata.SetInputData(geomfilter.GetOutput()) + cleanpdata.Update() + + pdatanormal = vtk.vtkPolyDataNormals() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + pdatanormal.SetInput(cleanpdata.GetOutput()) + else: + pdatanormal.SetInputData(cleanpdata.GetOutput()) + pdatanormal.ComputeCellNormalsOn() + pdatanormal.Update() + + reducedsurfacemesh = vtk.vtkPolyData() + reducedsurfacemesh.DeepCopy(pdatanormal.GetOutput()) + reducedsurfacemesh.BuildLinks() + + + + bds = reducedsurfacemesh.GetBounds() + numcells = reducedsurfacemesh.GetNumberOfCells() + tol = 1e-1; + for p in range(0, numcells): + + ptlist = vtk.vtkIdList() + normvec = reducedsurfacemesh.GetCellData().GetArray("Normals").GetTuple3(p) + + # If cell normal is in 0,0,1 direction + if(abs(vtkMath.Dot(normvec, [1,0,0])) < tol and abs(vtkMath.Dot(normvec, [0,1,0])) < tol): + reducedsurfacemesh.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = reducedsurfacemesh.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + + pt = [0,0,0] + pt = ugrid.GetPoints().GetPoint(ptid) + + if(pt[2] > 0.5*(bds[5] + bds[4])): + Basalsurfnodes.InsertUniqueId(ptid) + + reducedsurfacemesh.DeleteCell(p) + + reducedsurfacemesh.RemoveDeletedCells(); + #reducedsurfacemesh.Update() + + + # Split the surfaces to LVendo, RVendo, Epi + connectivityfilter = vtk.vtkPolyDataConnectivityFilter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + connectivityfilter.SetInput(reducedsurfacemesh) + else: + connectivityfilter.SetInputData(reducedsurfacemesh) + connectivityfilter.Update() + + # Extracting Epi surface + connectivityfilter.SetExtractionModeToLargestRegion(); + connectivityfilter.ColorRegionsOn(); + connectivityfilter.Update(); + Episurf.DeepCopy(connectivityfilter.GetOutput()); + + zrange = [] + for p in range(0, 3): + + connectivityfilter.AddSpecifiedRegion(p); + connectivityfilter.SetExtractionModeToSpecifiedRegions(); + connectivityfilter.Update(); + connectivityfilter.DeleteSpecifiedRegion(p); + + bds = connectivityfilter.GetOutput().GetBounds() + zrange.append(abs(bds[5] - bds[4])) + + epiids = zrange.index(max(zrange)) + RVendoids = zrange.index(min(zrange)) + idlist = set([0,1]) + #LVendoids = list(idlist.difference(set([epiids, RVendoids])))[0] + LVendoids = list(idlist.difference(set([epiids])))[0] + + # Extracting LV surface + connectivityfilter.AddSpecifiedRegion(LVendoids); + connectivityfilter.SetExtractionModeToSpecifiedRegions(); + connectivityfilter.Update(); + LVEndosurf.DeepCopy(connectivityfilter.GetOutput()); + connectivityfilter.DeleteSpecifiedRegion(LVendoids); + + # Get Epi surface points + for p in range(0, Episurf.GetNumberOfCells()): + ptlist = vtk.vtkIdList() + Episurf.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = Episurf.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + Episurfnodes.InsertUniqueId(ptid) + + + # Get LV surface points + for p in range(0, LVEndosurf.GetNumberOfCells()): + ptlist = vtk.vtkIdList() + LVEndosurf.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = LVEndosurf.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + LVEndosurfnodes.InsertUniqueId(ptid) + + # Get Epi basal edge points + Basalepisurfnodes.DeepCopy(Basalsurfnodes) + Basalepisurfnodes.IntersectWith(Episurfnodes) + + + return Basalsurfnodes, Basalepisurfnodes, Episurfnodes, LVEndosurfnodes + + + +def set_pix_intensity(mesh, vtuoutputdir, vtufilename, txtoutputdir, txtfilename): + + + outvtufilename = vtuoutputdir + vtufilename + outtxtfilename = txtoutputdir + txtfilename + + txtfile = open(outtxtfilename, "w"); + + cellpixintensity = mesh.GetCellData().GetScalars("closest_pix_intensity") + print cellpixintensity.GetNumberOfTuples() + + rangeofpixintensity = cellpixintensity.GetValueRange() + + + matid = vtk.vtkIntArray() + matid.SetNumberOfComponents(1) + matid.SetName("Material Id") + + normalized_pix = vtk.vtkFloatArray() + normalized_pix.SetNumberOfComponents(1) + normalized_pix.SetName("Normalized Pixel Intensity") + + for p in range(0, mesh.GetNumberOfCells()): + + pix_intensity = cellpixintensity.GetTuple(p) + normalized_pix_intensity = (pix_intensity[0] - rangeofpixintensity[0])/(rangeofpixintensity[1] - rangeofpixintensity[0]) + + normalized_pix.InsertNextValue(normalized_pix_intensity) + + print >>txtfile, p+1, normalized_pix_intensity + + txtfile.close() + + #mesh.GetCellData().SetActiveScalars("Material Id") + #mesh.GetCellData().SetScalars(matid) + + mesh.GetCellData().SetActiveScalars("Normalized_Pixel_Intensity") + mesh.GetCellData().SetScalars(normalized_pix) + + writer = vtk.vtkXMLUnstructuredGridWriter() + writer.SetFileName(outvtufilename) + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + writer.SetInput(mesh) + else: + writer.SetInputData(mesh) + writer.Write(); + +def transform_scale_n_write(mesh, outdirectory, vtufilename): + + newfilename = outdirectory + vtufilename[0:len(vtufilename)-4]+"_scaled_rotated.vtu" + + + bds = mesh.GetBounds() + + trans = vtk.vtkTransform() + trans.Translate(bds[5]/10,0,0) + trans.RotateY(-90) + trans.Scale(0.1, 0.1, 0.1) + + + transfilter = vtk.vtkTransformFilter() + transfilter.SetTransform(trans) + transfilter.SetInput(mesh) + + writer = vtk.vtkXMLUnstructuredGridWriter() + writer.SetFileName(newfilename) + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + writer.SetInput(transfilter.GetOutput()) + else: + writer.SetInputData(transfilter.GetOutput()) + writer.Write() + +def convert_quadtets_2_mtv(mesh, outdirectory, name, issavepts, isrotate, basalnormal, tol, epispringcond, scale): + + + rotate = isrotate; + bds = mesh.GetBounds() + if(basalnormal == 'z'): + zoffset = bds[5]; + print "z offset = ", zoffset + elif(basalnormal == 'x'): + zoffset = bds[1]; + print "x offset = ", zoffset + + filename = outdirectory + name + ".grid" + mtvfile = open(filename, 'w') + + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, "Finite element mesh (MLGridFEAdB)" + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, "Finite element mesh (GridFE):" + print >>mtvfile, " " + print >>mtvfile, " Number of space dim. = 3 embedded in physical space with dimension 3" + print >>mtvfile, " Number of elements = %5d" %mesh.GetNumberOfCells() + print >>mtvfile, " Number of nodes = %5d" %mesh.GetNumberOfPoints() + print >>mtvfile, " " + print >>mtvfile, " All elements are of the same type : true" + print >>mtvfile, " Max number of nodes in an element: 10" + print >>mtvfile, " Only one material : false" + print >>mtvfile, " Lattice data ? 0" + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " 12 boundary indicators: " + print >>mtvfile, " P1" + print >>mtvfile, " P2" + print >>mtvfile, " P3" + print >>mtvfile, " T1" + print >>mtvfile, " T2" + print >>mtvfile, " u1=0" + print >>mtvfile, " u2=0" + print >>mtvfile, " u3=0" + print >>mtvfile, " u1=u1_0" + print >>mtvfile, " u2=u2_0" + print >>mtvfile, " u3=u3_0" + print >>mtvfile, " free" + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " Nodal coordinates and nodal boundary indicators," + print >>mtvfile, " the columns contain:" + print >>mtvfile, " - node number" + print >>mtvfile, " - coordinates" + print >>mtvfile, " - no of boundary indicators that are set (ON)" + print >>mtvfile, " - the boundary indicators that are set (ON) if any." + print >>mtvfile, "#" + + + # Get Surface nodes for pressure constraint + Basalsurfnodes, Basalepisurfnodes, Episurfnodes, LVEndosurfnodes = extract_LV_surf_nodes(mesh) + + + if(issavepts == 1): + ptfilename = outdirectory + name + '_Basalsurfnodes.vtp' + savepoints(mesh, Basalsurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_Basalepisurfnodes.vtp' + savepoints(mesh, Basalepisurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_Episurfnodes.vtp' + savepoints(mesh, Episurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_LVEndosurfnodes.vtp' + savepoints(mesh, LVEndosurfnodes, ptfilename) + + + + num_bindicator = zeros(mesh.GetNumberOfPoints()); + bindicator = ['']*mesh.GetNumberOfPoints(); + + for k in range(0,Episurfnodes.GetNumberOfIds()): + nodeid = Episurfnodes.GetId(k) + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + if(epispringcond): + bindicator[nodeid] = bindicator[nodeid] + ' 4' + else: + bindicator[nodeid] = bindicator[nodeid] + ' 3' + + for k in range(0,LVEndosurfnodes.GetNumberOfIds()): + nodeid = LVEndosurfnodes.GetId(k) + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 1' + + for k in range(0,Basalepisurfnodes.GetNumberOfIds()): + nodeid = Basalepisurfnodes.GetId(k) + if(epispringcond): + num_bindicator[nodeid] = num_bindicator[nodeid] + 0 + else: + num_bindicator[nodeid] = num_bindicator[nodeid] + 3 + bindicator[nodeid] = bindicator[nodeid] + ' 6 7 8' + + for k in range(0,Basalsurfnodes.GetNumberOfIds()): + nodeid = Basalsurfnodes.GetId(k) + if(rotate == 0): + if(Basalepisurfnodes.IsId(nodeid) == -1): + if(epispringcond): + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 13' + else: + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 8' + else: + if(Basalepisurfnodes.IsId(nodeid) == -1): + if(epispringcond): + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 13' + else: + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 6' + + + #print bindicator + pt = [0,0,0]; + rotatedpt = [0,0,0]; + #num_bindicator = 0; + #bindicator = " "; + for p in range(0, mesh.GetNumberOfPoints()): + if(rotate == 0): + mesh.GetPoints().GetPoint(p,pt); + print >>mtvfile, "%6d ( %11.5e, %11.5e, %11.5e) [%d] %s " %((p+1), pt[0], pt[1], pt[2], num_bindicator[p], bindicator[p] ) + else: + mesh.GetPoints().GetPoint(p,pt); + rotatedpt[0] = (-pt[2]+zoffset)/1.0; + rotatedpt[1] = (pt[1])/1.0; + rotatedpt[2] = (pt[0])/1.0; + + print >>mtvfile, "%6d ( %11.5e, %11.5e, %11.5e) [%d] %s " %((p+1), rotatedpt[0], rotatedpt[1], rotatedpt[2], num_bindicator[p], bindicator[p] ) + + print >>mtvfile, " " + print >>mtvfile, " Element types and connectivity" + print >>mtvfile, " the columns contain:" + print >>mtvfile, " - element number" + print >>mtvfile, " - element type" + print >>mtvfile, " - material number" + print >>mtvfile, " - the global node numbers of the nodes in the element." + print >>mtvfile, "#" + + + materialid = mesh.GetCellData().GetArray('Material Id') + ptid = vtkIdList() + ids = [0,0,0,0,0,0,0,0,0,0]; + + for p in range(0, mesh.GetNumberOfCells()): + mesh.GetCellPoints(p, ptid); + for j in range(0, 10): + ids[j] = int(ptid.GetId(j)); + try: + matid = materialid.GetValue(p) + + except AttributeError: + matid = 1 + + print >>mtvfile, "%5d ElmT10n3D %1d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d " %((p+1), matid, ids[0]+1, ids[1]+1, ids[2]+1, ids[3]+1, ids[4]+1, ids[5]+1, ids[6]+1, ids[7]+1, ids[8]+1, ids[9]+1) + + + mtvfile.close() + + +tol = 1e-1 +parser = argparse.ArgumentParser() +parser.add_argument('--vtk_folder', type=str, required=True) +parser.add_argument('--vtk_filename', type=str, required=True) +parser.add_argument('--mtv_grid_directory', type=str, required=True) +parser.add_argument('--mtv_basename', type=str, required=True) +parser.add_argument('--isepispring', type=int, required=True) +parser.add_argument('--scale', type=float, required=True) +args = parser.parse_args() + + +print "************* Entering vtkmtvtranslator_quadtets_v1.py *****************" + +if(args.isepispring): + print "Enforce spring B.C on epi" + + +if (args.vtk_filename[len(args.vtk_filename)-3:len(args.vtk_filename)] == 'vtu'): + print os.path.join(args.vtk_folder, args.vtk_filename) + mesh = vtk_py.readXMLUGrid(os.path.join(args.vtk_folder, args.vtk_filename)) +else: + mesh = vtk_py.readUGrid(os.path.join(args.vtk_folder, args.vtk_filename)) + +#mesh = extract_tetra(mesh) + +convert_quadtets_2_mtv(mesh, args.mtv_grid_directory, args.mtv_basename, 1, 1, "z", tol, args.isepispring, args.scale) + +print "************* Leaving vtkmtvtranslator_quadtets_v1.py *****************" + + diff --git a/vtk_py/vtkmtvtranslator_quadtets_v1.py b/vtk_py/vtkmtvtranslator_quadtets_v1.py new file mode 100644 index 0000000..692df9d --- /dev/null +++ b/vtk_py/vtkmtvtranslator_quadtets_v1.py @@ -0,0 +1,561 @@ +######################################################################## + +import argparse +import glob +from numpy import * +from sets import Set +from vtk import * +import os + +import vtk_py as vtk_py + +######################################################################## + + + + +def extract_tetra(mesh): + + idlist = vtk.vtkIdList() + celltype = mesh.GetCellTypesArray() + for p in range(0, celltype.GetNumberOfTuples()): + if(float(celltype.GetTuple(p)[0]) == 24): + idlist.InsertNextId(p) + + extracted = vtk.vtkExtractCells() + extracted.SetCellList(idlist) + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + extracted.SetInput(mesh) + else: + extracted.SetInputData(mesh) + extracted.Update() + + return extracted.GetOutput() + + + +def writepdata(filename, pdata): + + pdatawriter = vtk.vtkXMLPolyDataWriter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + pdatawriter.SetInput(pdata) + else: + pdatawriter.SetInputData(pdata) + pdatawriter.SetFileName(filename) + pdatawriter.Write() + + + +def savepoints(ugrid, nodeids, ptfilename): + + # View points + viewpts = vtk.vtkPoints() + viewptspdata =vtk.vtkPolyData() + for p in range(0, nodeids.GetNumberOfIds()): + pt = [0,0,0] + pt = ugrid.GetPoints().GetPoint(nodeids.GetId(p)) + viewpts.InsertNextPoint(pt) + + viewptspdata.SetPoints(viewpts) + + maskPoints = vtk.vtkMaskPoints() + maskPoints.SetOnRatio(1); + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + maskPoints.SetInput(viewptspdata); + else: + maskPoints.SetInputData(viewptspdata); + maskPoints.GenerateVerticesOn(); + maskPoints.Update(); + + writepdata(ptfilename, maskPoints.GetOutput()) + + +def extract_biven_surf_nodes(ugrid, basalnormal, tol): + + Basalsurfnodes = vtk.vtkIdList() + Episurfnodes = vtk.vtkIdList() + RVEndosurfnodes = vtk.vtkIdList() + LVEndosurfnodes = vtk.vtkIdList() + Basalepisurfnodes = vtk.vtkIdList() + + Episurf = vtk.vtkPolyData() + LVEndosurf = vtk.vtkPolyData() + RVEndosurf = vtk.vtkPolyData() + + Idfilter = vtk.vtkIdFilter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + Idfilter.SetInput(ugrid) + else: + Idfilter.SetInputData(ugrid) + Idfilter.Update() + + geomfilter = vtk.vtkGeometryFilter() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + geomfilter.SetInput(Idfilter.GetOutput()) + else: + geomfilter.SetInputData(Idfilter.GetOutput()) + geomfilter.Update() + + cleanpdata = vtk.vtkCleanPolyData() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + cleanpdata.SetInput(geomfilter.GetOutput()) + else: + cleanpdata.SetInputData(geomfilter.GetOutput()) + cleanpdata.Update() + + pdatanormal = vtk.vtkPolyDataNormals() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + pdatanormal.SetInput(cleanpdata.GetOutput()) + else: + pdatanormal.SetInputData(cleanpdata.GetOutput()) + pdatanormal.ComputeCellNormalsOn() + pdatanormal.Update() + + #vtk_py.writeXMLPData(pdatanormal.GetOutput(), "test.vtp") + + reducedsurfacemesh = vtk.vtkPolyData() + reducedsurfacemesh.DeepCopy(pdatanormal.GetOutput()) + reducedsurfacemesh.BuildLinks() + + bds = reducedsurfacemesh.GetBounds() + numcells = reducedsurfacemesh.GetNumberOfCells() + for p in range(0, numcells): + + ptlist = vtk.vtkIdList() + normvec = reducedsurfacemesh.GetCellData().GetArray("Normals").GetTuple3(p) + + # If cell normal is in 0,0,1 direction + if(basalnormal == 'z'): + if(abs(vtkMath.Dot(normvec, [1,0,0])) < tol and abs(vtkMath.Dot(normvec, [0,1,0])) < tol): + reducedsurfacemesh.GetCellPoints(p, ptlist) + count_nodes_at_base = 0; + for j in range(0, ptlist.GetNumberOfIds()): + ptid = reducedsurfacemesh.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + + pt = [0,0,0] + pt = ugrid.GetPoints().GetPoint(ptid) + + if(pt[2] > 0.5*(bds[5] + bds[4])): + Basalsurfnodes.InsertUniqueId(ptid) + + if(pt[2] > bds[5] - tol): + count_nodes_at_base = count_nodes_at_base + 1 + + if(count_nodes_at_base == 3): + reducedsurfacemesh.DeleteCell(p) + + elif(basalnormal =='x'): + + if(abs(vtkMath.Dot(normvec, [0,0,1])) < tol and abs(vtkMath.Dot(normvec, [0,1,0])) < tol): + reducedsurfacemesh.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = reducedsurfacemesh.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + + pt = [0,0,0] + pt = ugrid.GetPoints().GetPoint(ptid) + + + if(pt[0] < bds[0] + tol): + Basalsurfnodes.InsertUniqueId(ptid) + + if(pt[0] < bds[0] + tol): + reducedsurfacemesh.DeleteCell(p) + + + + reducedsurfacemesh.RemoveDeletedCells(); + #reducedsurfacemesh.Update() + + + # Split the surfaces to LVendo, RVendo, Epi + connectivityfilter = vtk.vtkPolyDataConnectivityFilter() + connectivityfilter.SetScalarConnectivity(0); + connectivityfilter.ColorRegionsOn(); + connectivityfilter.SetExtractionModeToAllRegions() + if(vtk.vtkVersion.GetVTKMajorVersion() < 6): + connectivityfilter.SetInput(reducedsurfacemesh) + else: + connectivityfilter.SetInputData(reducedsurfacemesh) + connectivityfilter.Update() + + print "Number of connected regions = ", connectivityfilter.GetNumberOfExtractedRegions() + vtk_py.writeXMLPData(connectivityfilter.GetOutput(), "connectedregion.vtp") + + + # Extracting Epi surface + connectivityfilter.SetExtractionModeToLargestRegion(); + connectivityfilter.ColorRegionsOn(); + connectivityfilter.Update(); + Episurf.DeepCopy(connectivityfilter.GetOutput()); + + + zrange = [] + for p in range(0, 3): + + connectivityfilter.AddSpecifiedRegion(p); + connectivityfilter.SetExtractionModeToSpecifiedRegions(); + connectivityfilter.Update(); + connectivityfilter.DeleteSpecifiedRegion(p); + + bds = connectivityfilter.GetOutput().GetBounds() + + if(basalnormal == 'z'): + zrange.append(abs(bds[5] - bds[4])) + elif(basalnormal == 'x'): + zrange.append(abs(bds[1] - bds[0])) + + epiids = zrange.index(max(zrange)) + #RVendoids = zrange.index(min(zrange)) + LVendoids = zrange.index(min(zrange)) + #idlist = set([0,1,2]) + #LVendoids = list(idlist.difference(set([epiids, RVendoids])))[0] + + # LKK + epiids = [0,4] #[1, 8] + LVendoids = [1,3] #[2, 13] + # CRT02 + epiids = [0] #[1, 8] + LVendoids = [1] #[2, 13] + # LKK COARSE + epiids = [1] #[1, 8] + LVendoids = [0] #[2, 13] + + # Extracting RV surface + [connectivityfilter.AddSpecifiedRegion(p) for p in range(0,connectivityfilter.GetNumberOfExtractedRegions())] + [connectivityfilter.DeleteSpecifiedRegion(p) for p in epiids]; + [connectivityfilter.DeleteSpecifiedRegion(p) for p in LVendoids]; + connectivityfilter.SetExtractionModeToSpecifiedRegions(); + #connectivityfilter.SetExtractionModeToSpecifiedRegions(); + connectivityfilter.Update(); + RVEndosurf.DeepCopy(connectivityfilter.GetOutput()); + [connectivityfilter.DeleteSpecifiedRegion(p) for p in range(0,connectivityfilter.GetNumberOfExtractedRegions())] + #connectivityfilter.DeleteSpecifiedRegion(RVendoids); + + + outfilename = 'RV_surf.vtp' + vtk_py.writeXMLPData(RVEndosurf, outfilename) + + # Extracting LV surface + [connectivityfilter.AddSpecifiedRegion(p) for p in LVendoids]; + connectivityfilter.SetExtractionModeToSpecifiedRegions(); + connectivityfilter.Update(); + LVEndosurf.DeepCopy(connectivityfilter.GetOutput()); + [connectivityfilter.DeleteSpecifiedRegion(p) for p in LVendoids]; + + outfilename = 'LV_surf.vtp' + vtk_py.writeXMLPData(LVEndosurf, outfilename) + + + # Get Epi surface points + for p in range(0, Episurf.GetNumberOfCells()): + ptlist = vtk.vtkIdList() + Episurf.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = Episurf.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + Episurfnodes.InsertUniqueId(ptid) + + + # Get RV surface points + for p in range(0, RVEndosurf.GetNumberOfCells()): + ptlist = vtk.vtkIdList() + RVEndosurf.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = RVEndosurf.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + RVEndosurfnodes.InsertUniqueId(ptid) + + # Get LV surface points + for p in range(0, LVEndosurf.GetNumberOfCells()): + ptlist = vtk.vtkIdList() + LVEndosurf.GetCellPoints(p, ptlist) + for j in range(0, ptlist.GetNumberOfIds()): + ptid = LVEndosurf.GetPointData().GetArray("vtkIdFilter_Ids").GetValue(ptlist.GetId(j)) + LVEndosurfnodes.InsertUniqueId(ptid) + + # Get Epi basal edge points + Basalepisurfnodes.DeepCopy(Basalsurfnodes) + Basalepisurfnodes.IntersectWith(Episurfnodes) + + + return Basalsurfnodes, Basalepisurfnodes, Episurfnodes, RVEndosurfnodes, LVEndosurfnodes + + + +def set_pix_intensity(mesh, vtuoutputdir, vtufilename, txtoutputdir, txtfilename): + + + outvtufilename = vtuoutputdir + vtufilename + outtxtfilename = txtoutputdir + txtfilename + + txtfile = open(outtxtfilename, "w"); + + cellpixintensity = mesh.GetCellData().GetScalars("closest_pix_intensity") + print cellpixintensity.GetNumberOfTuples() + + rangeofpixintensity = cellpixintensity.GetValueRange() + + + matid = vtk.vtkIntArray() + matid.SetNumberOfComponents(1) + matid.SetName("Material Id") + + normalized_pix = vtk.vtkFloatArray() + normalized_pix.SetNumberOfComponents(1) + normalized_pix.SetName("Normalized Pixel Intensity") + + for p in range(0, mesh.GetNumberOfCells()): + + pix_intensity = cellpixintensity.GetTuple(p) + normalized_pix_intensity = (pix_intensity[0] - rangeofpixintensity[0])/(rangeofpixintensity[1] - rangeofpixintensity[0]) + + normalized_pix.InsertNextValue(normalized_pix_intensity) + + print >>txtfile, p+1, normalized_pix_intensity + + txtfile.close() + + #mesh.GetCellData().SetActiveScalars("Material Id") + #mesh.GetCellData().SetScalars(matid) + + mesh.GetCellData().SetActiveScalars("Normalized_Pixel_Intensity") + mesh.GetCellData().SetScalars(normalized_pix) + + writer = vtk.vtkXMLUnstructuredGridWriter() + writer.SetFileName(outvtufilename) + writer.SetInput(mesh) + writer.Write(); + +def transform_scale_n_write(mesh, outdirectory, vtufilename): + + newfilename = outdirectory + vtufilename[0:len(vtufilename)-4]+"_scaled_rotated.vtu" + + + bds = mesh.GetBounds() + + trans = vtk.vtkTransform() + trans.Translate(bds[5]/10,0,0) + trans.RotateY(-90) + trans.Scale(0.1, 0.1, 0.1) + + + transfilter = vtk.vtkTransformFilter() + transfilter.SetTransform(trans) + transfilter.SetInput(mesh) + + writer = vtk.vtkXMLUnstructuredGridWriter() + writer.SetFileName(newfilename) + writer.SetInput(transfilter.GetOutput()) + writer.Write() + +def convert_quadtets_2_mtv(mesh, outdirectory, name, issavepts, isrotate, basalnormal, tol, epispringcond): + + + rotate = isrotate; + bds = mesh.GetBounds() + if(basalnormal == 'z'): + zoffset = bds[5]; + print "z offset = ", zoffset + elif(basalnormal == 'x'): + zoffset = bds[1]; + print "x offset = ", zoffset + + filename = outdirectory + name + ".grid" + mtvfile = open(filename, 'w') + + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, "Finite element mesh (MLGridFEAdB)" + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, "Finite element mesh (GridFE):" + print >>mtvfile, " " + print >>mtvfile, " Number of space dim. = 3 embedded in physical space with dimension 3" + print >>mtvfile, " Number of elements = %5d" %mesh.GetNumberOfCells() + print >>mtvfile, " Number of nodes = %5d" %mesh.GetNumberOfPoints() + print >>mtvfile, " " + print >>mtvfile, " All elements are of the same type : true" + print >>mtvfile, " Max number of nodes in an element: 10" + print >>mtvfile, " Only one material : false" + print >>mtvfile, " Lattice data ? 0" + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " 12 boundary indicators: " + print >>mtvfile, " P1" + print >>mtvfile, " P2" + print >>mtvfile, " P3" + print >>mtvfile, " T1" + print >>mtvfile, " T2" + print >>mtvfile, " u1=0" + print >>mtvfile, " u2=0" + print >>mtvfile, " u3=0" + print >>mtvfile, " u1=u1_0" + print >>mtvfile, " u2=u2_0" + print >>mtvfile, " u3=u3_0" + print >>mtvfile, " free" + print >>mtvfile, " " + print >>mtvfile, " " + print >>mtvfile, " Nodal coordinates and nodal boundary indicators," + print >>mtvfile, " the columns contain:" + print >>mtvfile, " - node number" + print >>mtvfile, " - coordinates" + print >>mtvfile, " - no of boundary indicators that are set (ON)" + print >>mtvfile, " - the boundary indicators that are set (ON) if any." + print >>mtvfile, "#" + + + # Get Surface nodes for pressure constraint + Basalsurfnodes, Basalepisurfnodes, Episurfnodes, RVEndosurfnodes, LVEndosurfnodes = extract_biven_surf_nodes(mesh, basalnormal, tol) + + if(issavepts == 1): + ptfilename = outdirectory + name + '_Basalsurfnodes.vtp' + savepoints(mesh, Basalsurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_Basalepisurfnodes.vtp' + savepoints(mesh, Basalepisurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_Episurfnodes.vtp' + savepoints(mesh, Episurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_RVEndosurfnodes.vtp' + savepoints(mesh, RVEndosurfnodes, ptfilename) + + ptfilename = outdirectory + name + '_LVEndosurfnodes.vtp' + savepoints(mesh, LVEndosurfnodes, ptfilename) + + + + + num_bindicator = zeros(mesh.GetNumberOfPoints()); + bindicator = ['']*mesh.GetNumberOfPoints(); + for k in range(0,Episurfnodes.GetNumberOfIds()): + nodeid = Episurfnodes.GetId(k) + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + if(epispringcond==1): + bindicator[nodeid] = bindicator[nodeid] + ' 4' + elif(epispringcond==2): + bindicator[nodeid] = bindicator[nodeid] + ' 4' + else: + bindicator[nodeid] = bindicator[nodeid] + ' 3' + + for k in range(0,LVEndosurfnodes.GetNumberOfIds()): + nodeid = LVEndosurfnodes.GetId(k) + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 1' + + for k in range(0,RVEndosurfnodes.GetNumberOfIds()): + nodeid = RVEndosurfnodes.GetId(k) + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 2' + + for k in range(0,Basalepisurfnodes.GetNumberOfIds()): + nodeid = Basalepisurfnodes.GetId(k) + if(epispringcond==1): + num_bindicator[nodeid] = num_bindicator[nodeid] + 0 + elif(epispringcond==2): + num_bindicator[nodeid] = num_bindicator[nodeid] + 2 + if(rotate == 0): + bindicator[nodeid] = bindicator[nodeid] + ' 4 8' + else: + bindicator[nodeid] = bindicator[nodeid] + ' 4 6' + else: + num_bindicator[nodeid] = num_bindicator[nodeid] + 3 + bindicator[nodeid] = bindicator[nodeid] + ' 6 7 8' + + for k in range(0,Basalsurfnodes.GetNumberOfIds()): + nodeid = Basalsurfnodes.GetId(k) + if(rotate == 0): + if(Basalepisurfnodes.IsId(nodeid) == -1): + if(epispringcond==1): + num_bindicator[nodeid] = num_bindicator[nodeid] + 0 + elif(epispringcond==2): + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 8' + else: + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 8' + else: + if(Basalepisurfnodes.IsId(nodeid) == -1): + if(epispringcond==1): + num_bindicator[nodeid] = num_bindicator[nodeid] + 0 + elif(epispringcond==2): + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 6' + else: + num_bindicator[nodeid] = num_bindicator[nodeid] + 1 + bindicator[nodeid] = bindicator[nodeid] + ' 6' + + #print bindicator + pt = [0,0,0]; + rotatedpt = [0,0,0]; + #num_bindicator = 0; + #bindicator = " "; + for p in range(0, mesh.GetNumberOfPoints()): + if(rotate == 0): + mesh.GetPoints().GetPoint(p,pt); + print >>mtvfile, "%6d ( %11.5e, %11.5e, %11.5e) [%d] %s " %((p+1), pt[0], pt[1], pt[2], num_bindicator[p], bindicator[p] ) + else: + mesh.GetPoints().GetPoint(p,pt); + rotatedpt[0] = (-pt[2]+zoffset)/10.0; + rotatedpt[1] = (pt[1])/10.0; + rotatedpt[2] = (pt[0])/10.0; + + print >>mtvfile, "%6d ( %11.5e, %11.5e, %11.5e) [%d] %s " %((p+1), rotatedpt[0], rotatedpt[1], rotatedpt[2], num_bindicator[p], bindicator[p] ) + + print >>mtvfile, " " + print >>mtvfile, " Element types and connectivity" + print >>mtvfile, " the columns contain:" + print >>mtvfile, " - element number" + print >>mtvfile, " - element type" + print >>mtvfile, " - material number" + print >>mtvfile, " - the global node numbers of the nodes in the element." + print >>mtvfile, "#" + + + materialid = mesh.GetCellData().GetArray('Material Id') + ptid = vtkIdList() + ids = [0,0,0,0,0,0,0,0,0,0]; + + for p in range(0, mesh.GetNumberOfCells()): + mesh.GetCellPoints(p, ptid); + for j in range(0, 10): + ids[j] = int(ptid.GetId(j)); + try: + matid = materialid.GetValue(p) + + except AttributeError: + matid = 1 + + print >>mtvfile, "%5d ElmT10n3D %1d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d " %((p+1), matid, ids[0]+1, ids[1]+1, ids[2]+1, ids[3]+1, ids[4]+1, ids[5]+1, ids[6]+1, ids[7]+1, ids[8]+1, ids[9]+1) + + + mtvfile.close() + + + +tol = 1e-1 +parser = argparse.ArgumentParser() +parser.add_argument('--vtk_folder', type=str, required=True) +parser.add_argument('--vtk_filename', type=str, required=True) +parser.add_argument('--mtv_grid_directory', type=str, required=True) +parser.add_argument('--mtv_basename', type=str, required=True) +parser.add_argument('--isepispring', type=int, required=True) +args = parser.parse_args() + + +print "************* Entering vtkmtvtranslator_quadtets_v1.py *****************" + +if(args.isepispring): + print "Enforce spring B.C on epi" + + +if (args.vtk_filename[len(args.vtk_filename)-3:len(args.vtk_filename)] == 'vtu'): + mesh = vtk_py.readXMLUGrid(os.path.join(args.vtk_folder, args.vtk_filename)) +else: + mesh = vtk_py.readUGrid(os.path.join(args.vtk_folder, args.vtk_filename)) + +mesh = extract_tetra(mesh) + +convert_quadtets_2_mtv(mesh, args.mtv_grid_directory, args.mtv_basename, 1, 1, "z", tol, args.isepispring) + +print "************* Leaving vtkmtvtranslator_quadtets_v1.py *****************" diff --git a/vtk_py/writeFiberOrientationFileForAbaqus.py b/vtk_py/writeFiberOrientationFileForAbaqus.py new file mode 100644 index 0000000..72f3565 --- /dev/null +++ b/vtk_py/writeFiberOrientationFileForAbaqus.py @@ -0,0 +1,46 @@ +######################################################################## + +import sys + +from readUGrid import * + +######################################################################## + +def writeFiberOrientationFileForAbaqus(mesh, + fiber_orientation_file_name, + eF_field_name="eF", + eS_field_name="eS", + sep=", ", + verbose=True): + if (verbose): print "*** writeFiberOrientationFileForAbaqus ***" + + orientation_file = open(fiber_orientation_file_name, "w") + orientation_file.write(", 1., 0., 0., 0., 1., 0." + "\n") + + nb_cells = mesh.GetNumberOfCells() + + eF_array = mesh.GetCellData().GetArray(eF_field_name) + eS_array = mesh.GetCellData().GetArray(eS_field_name) + + for num_cell in range(nb_cells): + eF = eF_array.GetTuple(num_cell) + eS = eS_array.GetTuple(num_cell) + + line = str(num_cell+1) + for k in range(3): line += sep + str(eF[k]) + for k in range(3): line += sep + str(eS[k]) + line += "\n" + orientation_file.write(line) + + orientation_file.close() + +if (__name__ == "__main__"): + assert (len(sys.argv) in [2,3]), "Number of arguments must be 1 or 2. Aborting." + if (len(sys.argv) == 2): + mesh_file_name = sys.argv[1] + "-Mesh.vtk" + fiber_orientation_file_name = sys.argv[1] + "-Orientation.inp" + elif (len(sys.argv) == 3): + mesh_file_name = sys.argv[1] + fiber_orientation_file_name = sys.argv[2] + mesh = readUGrid(mesh_file_name) + writeFiberOrientationFileForAbaqus(mesh, fiber_orientation_file_name) diff --git a/vtk_py/writeFiberOrientationFileForAbaqus.pyc b/vtk_py/writeFiberOrientationFileForAbaqus.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8cea83d56d9112761ca57648c1ba8c536a1334fb GIT binary patch literal 1598 zcmb_a%We}%6us4U+K<>y5JVw>P=jV+S&q$P!3H6sfWw9$*+HO4qgLBpNjm9=Q&kQ` zYHxrqK>P$-Hv9k|0@D1!e89}PWgrfVVKYwZ_Pyu6ABDf`)eqn94oCF;w}9_MJpC6) zh<`yb(e8|QC>FF67AP!IxIogO(4}`p+AWX-QlcY=)K`*F5goepR#4cWBbW3`G9?PD zjJy%&4a(N*{dbpek=DW*t?riRfjWQ+rFYJIR;=fjIm0urGOe)(kwm&O=iRN6M4g}& zdh3vY4$TdkOK3Fu2fyv60Be}Ei~}lrv(G@Y)b>U$K5SmX+r-mt80QP58XRit2|^kG z=-S~FQO-salf%(HClFwa{z412Dnbs2IY0ii`Ed{4O)X{^&U)*KhcZ- zG_RdE|3)tm3Kzl7vwk5Xnm9g&3Io9Si3E;m(B#Q&>lSFM)$(4c$jDwalQ5svzB$Kj59oIF^R9Xrrup6lYr6JF+Pg zsSnIm==ZoYKRav9-$QSH8YI%xp_e@XG7jgE!8~Gf$T4{(Fejvw#M{Q7mP*FSQKR=%D*# z^J(|Q9QotZ?(bLF8K0V)i1d3)UYh;`gj|=(&XTy`)SMNu;#?FiZElVmGhX!Ohm|WqV$r_9qE0KzqqV8*eDR+g_%;I~{Lhm?;yb`yG2Vnscu| z#pXI_O!Jwn&)sAvO2uwuG6h5=Q#&o!DuiU6KAUL5jKj<#lc`ok^Nl zyAq;20`G#v8zAu#ya5uw5qxLX&N`)_{=n;*J?G3f-?`0B=8yH#kH39zG@`}N!uuYE z`W%ykzaWpOe2M7zO|Gy)XyyCEcLS_bL3d`1Mqn!`Kprvq5BtphodaSI~Z#i z`xxp^xQ#LtRvG%>p--e?AbKH;AXs>2k$Rsryj!e(pDYJEIA)TkFLQxTh3T<+9>&Ae& zNX<4c#HhkL#WlM4MKEnGrTt07bwgV>v^9VmhO$9XE~VU{2nNhKro=*g!{om~+Yub) zX=^)fu2?wi#Jah#vL(fCy<|=CEiNiNrP%h0CBKFsxB*;cr@xHH=MEHUKX&538zFC43tmPn>DjF$-J87h2FBocV?jm0s z_%v{RV^BIYkdYTC+2Q+1v%9pu*VGeN-@@uKH)#;0T^bytO#>el*9EMf%kT(vdL8n$ z%HvkSr8-|Oq}9U>v2>bXwC19{+L6fsyxK(WpUog~r4}hdHhs9pnF2234bqFkPe z)?HB%RZ$lW@s=oAHL-5xMN2gCY#6C-qz$o!=cZV^bG>ZO+P4~3hmS>a;4YQv%5117 zrt3JSPB2?G2=Q@CkdZ-s9iGX@d_kn8_}}YM1pSAzz&Z2e$Lw422T(z}<|+IQ$q~^G literal 0 HcmV?d00001 diff --git a/vtk_py/writePData.py b/vtk_py/writePData.py new file mode 100644 index 0000000..da1d2db --- /dev/null +++ b/vtk_py/writePData.py @@ -0,0 +1,17 @@ +######################################################################## + +import vtk + +######################################################################## + +def writePData(pdata, pdata_file_name, verbose=True): + if (verbose): print '*** writePData ***' + + pdata_writer = vtk.vtkPolyDataWriter() + pdata_writer.SetFileName(pdata_file_name) + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + pdata_writer.SetInputData(pdata) + else: + pdata_writer.SetInput(pdata) + pdata_writer.Update() + pdata_writer.Write() diff --git a/vtk_py/writePData.pyc b/vtk_py/writePData.pyc new file mode 100644 index 0000000000000000000000000000000000000000..44600452c0956a2f2eb109499d2538c3e7cd30c4 GIT binary patch literal 657 zcmbVK%}&BV5T0%M6RCfRHxC>MiT2>t7!!G2} zEsW9A!?9bd)Lp)5f4*|J-8h@C%%!#wkuhxpm4Td9P>woQ2bQDq%Di$*q)6)R=moYM acDCyOEg{FJT+E`;BEU;|kyw77Lh1+Jn2`to literal 0 HcmV?d00001 diff --git a/vtk_py/writeSTL.py b/vtk_py/writeSTL.py new file mode 100644 index 0000000..29d5bfa --- /dev/null +++ b/vtk_py/writeSTL.py @@ -0,0 +1,17 @@ +######################################################################## + +import vtk + +######################################################################## + +def writeSTL(stl, stl_file_name, verbose=True): + if (verbose): print '*** writeSTL ***' + + stl_writer = vtk.vtkSTLWriter() + stl_writer.SetFileName(stl_file_name) + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + stl_writer.SetInputData(stl) + else: + stl_writer.SetInput(stl) + stl_writer.Update() + stl_writer.Write() diff --git a/vtk_py/writeSTL.pyc b/vtk_py/writeSTL.pyc new file mode 100644 index 0000000000000000000000000000000000000000..152db520ac7d9e113ef0e14a16d697aa829d39a8 GIT binary patch literal 638 zcmbVKO;5r=5S?xL5~(33-aK$@FtG=(#+YaXBX9u3gbOKU4TaLy-2p>_C;bWjL4Sik zKxei#dba7#&YOAL_jb4Tr&E3ZIGYCW^H?-r($L2gX7mb(0LB1Pz|4X-0b`4c1J@=( z_(e}I;Iu%47hloPPZV|*r~{_9+A#nEECjp)yx6d_VPV0Jpa8)Q!UgV;z_JLcV;Du) zfnmgs!KEDY@-ou}XBCr?)67v%*GaqCY&M=%h;lIOGzf$xD!O|V(5A4#CDyW;2oFqD zxKD+F#G5dZJ%1&!nh{1)=`e}$kYG#VXn5E47m3Qt{25wx8>ef$_R+`6p8~S%eLC|| zVv$m#= 6): + ugrid_writer.SetInputData(ugrid) + else: + ugrid_writer.SetInput(ugrid) + ugrid_writer.Update() + ugrid_writer.Write() diff --git a/vtk_py/writeUGrid.pyc b/vtk_py/writeUGrid.pyc new file mode 100644 index 0000000000000000000000000000000000000000..05d78cde3257bd7578beba1297a49506e9ddb11d GIT binary patch literal 665 zcmbVK%}T>S5S~r?XKhpj4}u4erJy-@6%i^{QG2LXp_h^-qo$@w-JMi~deTSm1$_n| zKxZ~eJ-cLQ=bQN^-|Ub3>DAvq_C_K642Rc4o@R?p#Gir$U;uy$A_v|S3>*nwHeDvf zUp%^@xFw!a+~#Q>*~}f#D?;s@qyPjkR`3e&;=*643X~)mmn6pm4`tBjmQjW| zSVrnuT=~UPUKP3$uVy{&wCJd7)>*sNYHdI1n6Tf`akR}au5h@y#D-ipGkT!SV(q7f zbRJT!F%tHT)M;Ag>?P81oM1PYAk_=@HEI)QDTzu4>H6yIA{b}-H{2+yPSa^lM*#&? z`x7APp+AiRLMpRsm6~#J7Up-XPOA*9H@s!(VJg~Hj?GYyGJ_-vMc!^uHyML9W`{lh zKAWJQgbAYGLxX`1@BNeZh0i-4PM`h7sq9Xl?WPtHk+H`Issc5qp**#r)*MgOmA&nr iNRjk=rE~0g>@3v(+d_^1vOme9Ji!CG86%IVQThfaN0kQv literal 0 HcmV?d00001 diff --git a/vtk_py/writeXMLImage.py b/vtk_py/writeXMLImage.py new file mode 100644 index 0000000..75f3583 --- /dev/null +++ b/vtk_py/writeXMLImage.py @@ -0,0 +1,17 @@ +######################################################################## + +import vtk + +######################################################################## + +def writeXMLImage(image, image_file_name, verbose=True): + if (verbose): print '*** writeXMLImage ***' + + image_writer = vtk.vtkXMLImageDataWriter() + image_writer.SetFileName(image_file_name) + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + image_writer.SetInputData(image) + else: + image_writer.SetInput(image) + image_writer.Update() + image_writer.Write() diff --git a/vtk_py/writeXMLImage.pyc b/vtk_py/writeXMLImage.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f19dc39d3527989a750c7f6f1b0ab5fec7c20718 GIT binary patch literal 673 zcmbtS%}&BV5T0%M6R8>#Zyr1n4%Wo0F(w*;C>&7Hcp(KwDU=p>2aHKQ=_B}pK7$XS zGh2yzcGI1mZ|0l*W_Rm;c;&bE{r&*Hhr{a;PqWQt$e)4;;1&QC3>|n?aO+6$qUtgs z{N&Ldh@0an#m79&1Dn(Vy(ZLpBL*OVv4R(XXBScz#tx(m6(~tC&Pk31CV9~3mXU`P zEF<7lp3GD_M^_%{pqEE!M8pYCDfQB)n;zH>bfp?rA$*_*py*z6L<3umRm8_~6&*mhXQR!EJ zME`0w3U#9W)r|!N_kMw|qWjZ}#N>xs=`66M0`47j5C3SS#2Xz_HxC>M2Yc{pjEP1x0x^JSI7lk2q5QPCJ4Hz9Nngm9@P&K; zo!Ls1vzzYhd^6wdH@jQ=)5$MB-tYVHGb~z9XzG131NsC^0J;EDz`%kx0bPrOt+Gu7 z|BFVW&u)q)7oXD9Ph?^X)D}~#7XbhQj0C&_yx0)iFtQ*fC_r$6aEfyzFiwN28Acjn zFpR)4IJ3fBo@KgVFK0aJH0h|Ji=?h>p@?6j}y-Y8V7a3QI>3}zAXW|;dE zK$gFm4Lp>XCf6vH`PvNRgooP%jn{i5>0ZFvS&Gf2dI+^dR!H*Zc&bbojM0bWxzhmM zVK|kpj)G+*7rxt+T6(HKbm_dk+0tFRmV?<69jaRkvYzG>g2+J5DhNju#g65OyfBa6 j

t_Z57ET*Z;Qhzg}{**U>Z_L=$<;Z>0H;Dx|&v9I~1X literal 0 HcmV?d00001 diff --git a/vtk_py/writeXMLPdata.py b/vtk_py/writeXMLPdata.py new file mode 100644 index 0000000..8354f8e --- /dev/null +++ b/vtk_py/writeXMLPdata.py @@ -0,0 +1,17 @@ +######################################################################## + +import vtk + +######################################################################## + +def writeXMLPData(pdata, pdata_file_name, verbose=True): + if (verbose): print '*** writeXMLPData ***' + + pdata_writer = vtk.vtkXMLPolyDataWriter() + pdata_writer.SetFileName(pdata_file_name) + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + pdata_writer.SetInputData(pdata) + else: + pdata_writer.SetInput(pdata) + pdata_writer.Update() + pdata_writer.Write() diff --git a/vtk_py/writeXMLUGrid.py b/vtk_py/writeXMLUGrid.py new file mode 100644 index 0000000..70cb8d1 --- /dev/null +++ b/vtk_py/writeXMLUGrid.py @@ -0,0 +1,18 @@ +######################################################################## + +import vtk + +######################################################################## + +def writeXMLUGrid(ugrid, ugrid_file_name, verbose=True): + + if (verbose): print '*** writeXMLUGrid ***' + + ugrid_writer = vtk.vtkXMLUnstructuredGridWriter() + ugrid_writer.SetFileName(ugrid_file_name) + if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): + ugrid_writer.SetInputData(ugrid) + else: + ugrid_writer.SetInput(ugrid) + ugrid_writer.Update() + ugrid_writer.Write() diff --git a/vtk_py/writeXMLUGrid.pyc b/vtk_py/writeXMLUGrid.pyc new file mode 100644 index 0000000000000000000000000000000000000000..11c39c8f400a92db6a559c0464e19916d6191678 GIT binary patch literal 680 zcmbtSy-veG4E81cqcnh!x-l?T9S9ODLP#K51ntm5K`d2B3{6Rsa_1Bwl?fh!7vvdu z0I;thU?$4>{Mr8U*>`c@z3S`R&UFZ1kHh;uFSEfW;#WZea0P%0A_ra+Tsac#H(V}= zKltf};ud%b`GA+XXES#|uSjXDodOWRSiv*ElM8bf#tzIGDo~POT#y_K+!aBe+KM8~ z!B(W6#ieg7^su&E^ zoDKsDsPZd7(#H8T3J9slu2pKt@mZMPvO29YwBGQBrH83#mpL{=eVrL3QCQ^dn7Y9j ztTEf{`J-%tei9~#eh&=>Ivn}!gO1O`4yTX)pR?JTK9a|zKS2>QG9EZ3s5mv{sk&No oJXKZp=6jMN>H19P*c1Lw5C3SS!XMh5WKo{rp4^g=f2vma1RDRD%m4rY literal 0 HcmV?d00001