Skip to content

Commit 2ab9919

Browse files
committed
Merge pull request #662 from SCIInstitute/modules_L_good
Modules work
2 parents 21ce337 + a016a12 commit 2ab9919

File tree

12 files changed

+326
-275
lines changed

12 files changed

+326
-275
lines changed

src/Core/Algorithms/Base/AlgorithmVariableNames.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ INPUT(MatrixToWrite)
5757
INPUT(InputField)
5858
INPUT(ObjectField)
5959
INPUT(ListOfInputFields)
60+
INPUT(InputFields)
6061
INPUT(Source)
6162
INPUT(Destination)
6263

src/Core/Algorithms/Base/AlgorithmVariableNames.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class SCISHARE Variables
6262
static const AlgorithmInputName InputField;
6363
static const AlgorithmInputName ObjectField;
6464
static const AlgorithmInputName ListOfInputFields;
65+
static const AlgorithmInputName InputFields;
6566
static const AlgorithmInputName Source;
6667
static const AlgorithmInputName Destination;
6768

src/Core/Algorithms/Field/InterfaceWithCleaverAlgorithm.cc

Lines changed: 167 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -57,32 +57,55 @@ using namespace SCIRun;
5757
using namespace SCIRun::Core;
5858
using namespace SCIRun::Core::Logging;
5959

60-
AlgorithmInputName InterfaceWithCleaverAlgorithm::InputFields("InputFields");
61-
AlgorithmOutputName InterfaceWithCleaverAlgorithm::OutputField("OutputField");
62-
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VerboseCheckBox("VerboseCheckBox");
63-
AlgorithmParameterName InterfaceWithCleaverAlgorithm::PaddingCheckBox("PaddingCheckBox");
64-
AlgorithmParameterName InterfaceWithCleaverAlgorithm::AbsoluteVolumeScalingRadioButton("AbsoluteVolumeScalingRadioButton");
65-
AlgorithmParameterName InterfaceWithCleaverAlgorithm::RelativeVolumeScalingRadioButton("RelativeVolumeScalingRadioButton");
66-
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingSpinBox_X("VolumeScalingSpinBox_X");
67-
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingSpinBox_Y("VolumeScalingSpinBox_Y");
68-
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingSpinBox_Z("VolumeScalingSpinBox_Z");
60+
AlgorithmParameterName InterfaceWithCleaverAlgorithm::Verbose("VerboseCheckBox");
61+
AlgorithmParameterName InterfaceWithCleaverAlgorithm::Padding("PaddingCheckBox");
62+
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingOption("VolumeScalingOption");
63+
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingX("VolumeScalingSpinBox_X");
64+
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingY("VolumeScalingSpinBox_Y");
65+
AlgorithmParameterName InterfaceWithCleaverAlgorithm::VolumeScalingZ("VolumeScalingSpinBox_Z");
6966

7067
InterfaceWithCleaverAlgorithm::InterfaceWithCleaverAlgorithm()
7168
{
72-
addParameter(VerboseCheckBox,true);
73-
addParameter(PaddingCheckBox,true);
74-
addParameter(AbsoluteVolumeScalingRadioButton,false);
75-
addParameter(RelativeVolumeScalingRadioButton,true);
76-
addParameter(VolumeScalingSpinBox_X,1.0);
77-
addParameter(VolumeScalingSpinBox_Y,1.0);
78-
addParameter(VolumeScalingSpinBox_Z,1.0);
69+
addParameter(Verbose,true);
70+
addParameter(Padding,true);
71+
add_option(VolumeScalingOption, "Relative size", "Absolute size|Relative size|None");
72+
addParameter(VolumeScalingX,1.0);
73+
addParameter(VolumeScalingY,1.0);
74+
addParameter(VolumeScalingZ,1.0);
7975
}
8076

77+
boost::shared_ptr<Cleaver::ScalarField> InterfaceWithCleaverAlgorithm::makeCleaverFieldFromLatVol(FieldHandle field)
78+
{
79+
//TODO: this function assumes input is completely valid, may want to move various checks from run() function here.
80+
81+
VMesh* vmesh = field->vmesh();
82+
VField* vfield = field->vfield();
83+
VMesh::dimension_type dims;
84+
vmesh->get_dimensions( dims );
85+
float* ptr = static_cast<float*>(vfield->fdata_pointer());
86+
auto cleaverField = boost::make_shared<Cleaver::FloatField>(dims[0], dims[1], dims[2], ptr);
87+
88+
//0 = constant, 1 = linear
89+
if (0 == vfield->basis_order())
90+
cleaverField->setCenter(Cleaver::FloatField::CellCentered);
91+
else if (1 == vfield->basis_order())
92+
cleaverField->setCenter(Cleaver::FloatField::NodeCentered);
93+
//else: TODO? handle other bases, probably by throwing exception.
94+
95+
//TODO: Cleaver FloatField needs more setup (constructor is not sufficient)
96+
// 1.
97+
// setBounds(BoundingBox). Convert vmesh->get_bounding_box() to Cleaver BoundingBox.
98+
// 2.
99+
// setScale(vec3). Need to figure out which vmesh function to call, and convert to Cleaver::vec3.
100+
// 3. unit test heavily.
101+
102+
return cleaverField;
103+
}
81104

82105
FieldHandle InterfaceWithCleaverAlgorithm::run(const std::vector<FieldHandle>& input) const
83106
{
84107
FieldHandle output;
85-
108+
86109
std::vector<FieldHandle> inputs;
87110
std::copy_if(input.begin(), input.end(), std::back_inserter(inputs), [](FieldHandle f) { return f; });
88111

@@ -93,144 +116,165 @@ FieldHandle InterfaceWithCleaverAlgorithm::run(const std::vector<FieldHandle>& i
93116
}
94117
if (inputs.size()<2)
95118
{
96-
THROW_ALGORITHM_INPUT_ERROR(" At least 2 indicator functions stored as float values are needed to run cleaver! " );
97-
return FieldHandle();
119+
THROW_ALGORITHM_INPUT_ERROR(" At least 2 indicator functions stored as float values are needed to run cleaver! " );
120+
return FieldHandle();
98121
}
99-
122+
100123
std::vector<boost::shared_ptr<Cleaver::ScalarField>> fields;
101124
VMesh::dimension_type dims; int x=0,y=0,z=0;
102125
for (size_t p=1; p<inputs.size(); p++)
103126
{
104-
VMesh* imesh1 = inputs[p]->vmesh();
105-
127+
FieldHandle input = inputs[p];
128+
VMesh* imesh1 = input->vmesh();
129+
106130
if( !imesh1->is_structuredmesh() )
107131
{
108-
THROW_ALGORITHM_INPUT_ERROR("needs to be structured mesh!");
109-
} else
132+
THROW_ALGORITHM_INPUT_ERROR("needs to be structured mesh!");
133+
}
134+
else
110135
{
111-
VField* vfield1 = inputs[p]->vfield();
112-
if (!vfield1->is_scalar())
113-
{
114-
THROW_ALGORITHM_INPUT_ERROR("values at the node needs to be scalar!");
115-
return FieldHandle();
116-
}
117-
118-
imesh1->get_dimensions( dims );
119-
if (p==1)
120-
{
121-
x=dims[0]; y=dims[1]; z=dims[2];
122-
if (x<1 || y<1 || z<1)
123-
{
124-
THROW_ALGORITHM_INPUT_ERROR(" Size of input fields should be non-zero !");
125-
}
126-
} else
127-
{
128-
if ( dims[0]!=x || dims[1]!=y || dims[2]!=z)
129-
{
130-
THROW_ALGORITHM_INPUT_ERROR(" Size of input fields is inconsistent !");
131-
}
132-
}
133-
134-
if (dims.size()!=3)
135-
{
136-
THROW_ALGORITHM_INPUT_ERROR("need a three dimensional indicator function");
137-
return FieldHandle();
138-
}
139-
140-
if (vfield1->is_float())
141-
{
142-
float* ptr = static_cast<float*>(vfield1->fdata_pointer());
143-
if (ptr)
136+
VField* vfield1 = input->vfield();
137+
if (!vfield1->is_scalar())
138+
{
139+
THROW_ALGORITHM_INPUT_ERROR("values at the node needs to be scalar!");
140+
return FieldHandle();
141+
}
142+
143+
imesh1->get_dimensions( dims );
144+
if (p==1)
145+
{
146+
x=dims[0]; y=dims[1]; z=dims[2];
147+
if (x<1 || y<1 || z<1)
148+
{
149+
THROW_ALGORITHM_INPUT_ERROR(" Size of input fields should be non-zero !");
150+
}
151+
}
152+
else
144153
{
145-
fields.push_back(boost::make_shared<Cleaver::FloatField>(dims[0], dims[1], dims[2], ptr));
146-
} else
154+
if ( dims[0]!=x || dims[1]!=y || dims[2]!=z)
155+
{
156+
THROW_ALGORITHM_INPUT_ERROR(" Size of input fields is inconsistent !");
157+
}
158+
}
159+
160+
if (dims.size()!=3)
147161
{
148-
THROW_ALGORITHM_INPUT_ERROR(" float field is NULL pointer");
162+
THROW_ALGORITHM_INPUT_ERROR("need a three dimensional indicator function");
149163
return FieldHandle();
164+
}
165+
166+
if (vfield1->is_float())
167+
{
168+
float* ptr = static_cast<float*>(vfield1->fdata_pointer());
169+
if (ptr)
170+
{
171+
fields.push_back(makeCleaverFieldFromLatVol(input));
172+
}
173+
else
174+
{
175+
THROW_ALGORITHM_INPUT_ERROR(" float field is NULL pointer");
176+
return FieldHandle();
177+
}
150178
}
151-
}
152179

153180
}
154-
181+
155182
}
156-
183+
157184
boost::shared_ptr<Cleaver::Volume> volume(new Cleaver::Volume(toVectorOfRawPointers(fields)));
158185

159-
if ( get(VolumeScalingSpinBox_X).toDouble()>0 && get(VolumeScalingSpinBox_Y).toDouble()>0 && get(VolumeScalingSpinBox_Z).toDouble()>0 )
186+
const double xScale = get(VolumeScalingX).toDouble();
187+
const double yScale = get(VolumeScalingY).toDouble();
188+
const double zScale = get(VolumeScalingZ).toDouble();
189+
190+
if (xScale > 0 && yScale > 0 && zScale > 0)
160191
{
161-
if (get(AbsoluteVolumeScalingRadioButton).toBool())
162-
volume->setSize(get(VolumeScalingSpinBox_X).toDouble(),get(VolumeScalingSpinBox_Y).toDouble(),get(VolumeScalingSpinBox_Z).toDouble());
163-
else
164-
if (get(RelativeVolumeScalingRadioButton).toBool())
165-
volume->setSize(get(VolumeScalingSpinBox_X).toDouble()*volume->size().x, get(VolumeScalingSpinBox_Y).toDouble()*volume->size().y, get(VolumeScalingSpinBox_Z).toDouble()*volume->size().z);
166-
else
167-
volume->setSize(dims[0],dims[1],dims[2]);
168-
}
169-
else
192+
const std::string scaling = get_option(VolumeScalingOption);
193+
if ("Absolute size" == scaling)
170194
{
171-
volume->setSize(dims[0],dims[1],dims[2]);
172-
THROW_ALGORITHM_INPUT_ERROR(" Invalid Scaling. Use Input sizes.");
195+
volume->setSize(xScale, yScale,zScale);
173196
}
174-
175-
/// Padding is now optional!
176-
boost::scoped_ptr<Cleaver::TetMesh> mesh(Cleaver::createMeshFromVolume(get(PaddingCheckBox).toBool() ? ((boost::shared_ptr<Cleaver::AbstractVolume>) new Cleaver::PaddedVolume(volume.get())).get() : volume.get(), get(VerboseCheckBox).toBool()));
177-
178-
FieldInformation fi("TetVolMesh",0,"double"); ///create output field
197+
else if ("Relative size" == scaling)
198+
{
199+
double newX = xScale*volume->size().x;
200+
double newY = yScale*volume->size().y;
201+
double newZ = zScale*volume->size().z;
202+
std::cout << "Cleaver setting volume size to " << newX << "," << newY << "," << newZ << std::endl;
203+
volume->setSize(newX, newY, newZ);
204+
}
205+
else // None
206+
volume->setSize(dims[0],dims[1],dims[2]);
207+
}
208+
else
209+
{
210+
THROW_ALGORITHM_INPUT_ERROR(" Invalid Scaling. Use Input sizes.");
211+
}
179212

180-
output = CreateField(fi);
181-
auto omesh = output->vmesh();
182-
auto ofield = output->vfield();
213+
/// Padding is now optional!
214+
boost::shared_ptr<Cleaver::AbstractVolume> paddedVolume(volume);
183215

184-
auto nr_of_tets = mesh->tets.size();
185-
auto nr_of_verts = mesh->verts.size();
216+
const bool verbose = get(Verbose).toBool();
217+
const bool pad = get(Padding).toBool();
218+
if (pad)
219+
paddedVolume.reset(new Cleaver::PaddedVolume(volume.get()));
220+
boost::scoped_ptr<Cleaver::TetMesh> mesh(Cleaver::createMeshFromVolume(paddedVolume.get(), verbose));
186221

187-
omesh->node_reserve(nr_of_verts);
188-
omesh->elem_reserve(nr_of_tets);
222+
FieldInformation fi("TetVolMesh",0,"double"); ///create output field
189223

190-
for (auto i=0; i<nr_of_verts; i++)
191-
{
192-
omesh->add_point(Point(mesh->verts[i]->pos().x,mesh->verts[i]->pos().y,mesh->verts[i]->pos().z));
193-
}
224+
output = CreateField(fi);
225+
auto omesh = output->vmesh();
226+
auto ofield = output->vfield();
194227

195-
VMesh::Node::array_type vdata;
196-
vdata.resize(4);
197-
std::vector<double> values(nr_of_tets);
198-
199-
for (auto i=0; i<nr_of_tets; i++)
200-
{
201-
vdata[0]=mesh->tets[i]->verts[0]->tm_v_index;
202-
vdata[1]=mesh->tets[i]->verts[1]->tm_v_index;
203-
vdata[2]=mesh->tets[i]->verts[2]->tm_v_index;
204-
vdata[3]=mesh->tets[i]->verts[3]->tm_v_index;
205-
omesh->add_elem(vdata);
206-
auto mat_label = mesh->tets[i]->mat_label+1;
207-
values[i]=mat_label;
208-
}
209-
ofield->resize_values();
210-
ofield->set_values(values);
211-
mesh->computeAngles();
212-
std::ostringstream ostr1;
213-
ostr1 << "Number of tetrahedral elements:" << ofield->vmesh()->num_elems() << std::endl;
214-
ostr1 << "Number of tetrahedral nodes:" << ofield->vmesh()->num_nodes() << std::endl;
215-
ostr1 << "Number of tetrahedral nodes:" << ofield->vmesh()->num_nodes() << std::endl;
216-
ostr1 << "Worst Angle (min):" << mesh->min_angle << std::endl;
217-
ostr1 << "Worst Angle (max):" << mesh->max_angle << std::endl;
218-
ostr1 << "Volume:" << volume->size().toString() << std::endl;
219-
220-
remark(ostr1.str());
228+
auto nr_of_tets = mesh->tets.size();
229+
auto nr_of_verts = mesh->verts.size();
230+
231+
omesh->node_reserve(nr_of_verts);
232+
omesh->elem_reserve(nr_of_tets);
233+
234+
for (auto i=0; i<nr_of_verts; i++)
235+
{
236+
omesh->add_point(Point(mesh->verts[i]->pos().x,mesh->verts[i]->pos().y,mesh->verts[i]->pos().z));
237+
}
238+
239+
VMesh::Node::array_type vdata;
240+
vdata.resize(4);
241+
std::vector<double> values(nr_of_tets);
242+
243+
for (auto i=0; i<nr_of_tets; i++)
244+
{
245+
vdata[0]=mesh->tets[i]->verts[0]->tm_v_index;
246+
vdata[1]=mesh->tets[i]->verts[1]->tm_v_index;
247+
vdata[2]=mesh->tets[i]->verts[2]->tm_v_index;
248+
vdata[3]=mesh->tets[i]->verts[3]->tm_v_index;
249+
omesh->add_elem(vdata);
250+
auto mat_label = mesh->tets[i]->mat_label+1;
251+
values[i]=mat_label;
252+
}
253+
ofield->resize_values();
254+
ofield->set_values(values);
255+
mesh->computeAngles();
256+
std::ostringstream ostr1;
257+
ostr1 << "Number of tetrahedral elements:" << ofield->vmesh()->num_elems() << std::endl;
258+
ostr1 << "Number of tetrahedral nodes:" << ofield->vmesh()->num_nodes() << std::endl;
259+
ostr1 << "Number of tetrahedral nodes:" << ofield->vmesh()->num_nodes() << std::endl;
260+
ostr1 << "Worst Angle (min):" << mesh->min_angle << std::endl;
261+
ostr1 << "Worst Angle (max):" << mesh->max_angle << std::endl;
262+
ostr1 << "Volume:" << volume->size().toString() << std::endl;
263+
264+
remark(ostr1.str());
221265

222266
return output;
223267
}
224268

225269
AlgorithmOutput InterfaceWithCleaverAlgorithm::run_generic(const AlgorithmInput& input) const
226270
{
227-
auto inputfields = input.getList<Field>(InputFields);
228-
229-
FieldHandle output_fld;
230-
output_fld=run(inputfields);
231-
if ( !output_fld ) THROW_ALGORITHM_PROCESSING_ERROR("False returned on legacy run call.");
271+
auto inputfields = input.getList<Field>(Variables::InputFields);
272+
273+
FieldHandle output_fld = run(inputfields);
274+
if ( !output_fld )
275+
THROW_ALGORITHM_PROCESSING_ERROR("Null returned on legacy run call.");
232276

233277
AlgorithmOutput output;
234-
output[OutputField] = output_fld;
278+
output[Variables::OutputField] = output_fld;
235279
return output;
236280
}

0 commit comments

Comments
 (0)