forked from DIDSR/breastPhantom
-
Notifications
You must be signed in to change notification settings - Fork 1
/
createArtery.cxx
147 lines (119 loc) · 4.36 KB
/
createArtery.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*! \file createArtery.cxx
* \brief breastPhantom createArtery
* \author Christian G. Graff
* \version 1.0
* \date 2018
*
* \copyright To the extent possible under law, the author(s) have
* dedicated all copyright and related and neighboring rights to this
* software to the public domain worldwide. This software is
* distributed without any warranty. You should have received a copy
* of the CC0 Public Domain Dedication along with this software.
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
// function to generate an arterial tree
#include "createArtery.hxx"
using namespace std;
namespace po = boost::program_options;
/* This function creates arterial network, inserts it into the segmented
* breast and saves the tree */
void generate_artery(vtkImageData* breast, po::variables_map vm, int* boundBox,
tissueStruct* tissue, double* sposPtr, double* sdirPtr, double* nipplePos, int seed, int mainSeed, bool firstTree){
char arteryFilename[256];
std::string outputDir = vm["base.outputDir"].as<std::string>();
sprintf(arteryFilename,"%s/p_%d_arteryFill.vti", outputDir.c_str(), mainSeed);
double spos[3];
double sdir[3];
for(int i=0; i<3; i++){
spos[i] = sposPtr[i];
sdir[i] = sdirPtr[i];
}
// declare arteryTreeInit struct and fill information
arteryTreeInit treeInit;
treeInit.seed = seed;
// bounds of artery simulation derived from breast structure
int startInd[3] = {boundBox[0], boundBox[2], boundBox[4]};
int endInd[3] = {boundBox[1], boundBox[3], boundBox[5]};
//startPos
breast->GetPoint(breast->ComputePointId(startInd), treeInit.startPos);
//endPos
breast->GetPoint(breast->ComputePointId(endInd), treeInit.endPos);
// size of voxels
treeInit.nVox[0] = boundBox[1]-boundBox[0];
treeInit.nVox[1] = boundBox[3]-boundBox[2];
treeInit.nVox[2] = boundBox[5]-boundBox[4];
treeInit.nFill[0] = vm["vesselTree.nFillX"].as<uint>();
treeInit.nFill[1] = vm["vesselTree.nFillY"].as<uint>();
treeInit.nFill[2] = vm["vesselTree.nFillZ"].as<uint>();
for(int i=0; i<3; i++){
treeInit.nipplePos[i] = nipplePos[i];
}
treeInit.boundBox = boundBox;
treeInit.tissue = tissue;
treeInit.breast = breast;
// create arterial tree
arteryTree myTree(vm, &treeInit);
// root of tree
double srad = vm["vesselTree.initRad"].as<double>();
// initialize fill map based on distance to start position if first tree, else load current fill
if(firstTree){
// initialize fill map based on distance to start position
int fillExtent[6];
myTree.fill->GetExtent(fillExtent);
for(int a=fillExtent[0]; a<=fillExtent[1]; a++){
for(int b=fillExtent[2]; b<=fillExtent[3]; b++){
for(int c=fillExtent[4]; c<=fillExtent[5]; c++){
double* v = static_cast<double*>(myTree.fill->GetScalarPointer(a,b,c));
// set distance to 0 if fill voxel is not in breast, otherwise
// initialize with squared distance to tree base
// fill voxel location
vtkIdType id;
int coord[3];
coord[0] = a;
coord[1] = b;
coord[2] = c;
id = myTree.fill->ComputePointId(coord);
// get spatial coordinates of fill voxel
double pos[3];
myTree.fill->GetPoint(id,pos);
// compare to nearest breast voxel id
unsigned char* breastVal = static_cast<unsigned char *>(breast->GetScalarPointer());
bool inBreast = true;
unsigned char voxelVal = breastVal[breast->FindPoint(pos)];
if(voxelVal == tissue->skin || voxelVal == tissue->bg){
inBreast = false;
}
if(inBreast){
// inside breast
v[0] = vtkMath::Distance2BetweenPoints(spos,pos);
} else {
// outside breast, set distance to zero
v[0] = 0.0;
}
}
}
}
} else {
vtkSmartPointer<vtkXMLImageDataReader> fillReader =
vtkSmartPointer<vtkXMLImageDataReader>::New();
fillReader->SetFileName(arteryFilename);
fillReader->Update();
vtkSmartPointer<vtkImageData> holder =
vtkSmartPointer<vtkImageData>::New();
holder = fillReader->GetOutput();
myTree.fill->DeepCopy(holder);
}
myTree.head = new arteryBr(spos, sdir, srad, &myTree);
// save density map
vtkSmartPointer<vtkXMLImageDataWriter> fillWriter =
vtkSmartPointer<vtkXMLImageDataWriter>::New();
fillWriter->SetFileName(arteryFilename);
#if VTK_MAJOR_VERSION <= 5
fillWriter->SetInput(myTree.fill);
#else
fillWriter->SetInputData(myTree.fill);
#endif
fillWriter->Write();
return;
}