11.3.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Various fixes in PredicateVolumeExplorer, PointPredicateRenderArea and ManualTissueSegmenter.

parent 109f93d8
......@@ -51,7 +51,6 @@ namespace campvis {
, p_pbProperties("PredicateBitsetProperties", "Predicate Bitset Properties", VALID)
, _predicateEvaluation(_viewportSizeProperty)
, _bitmaskHandle(nullptr)
, _mousePressedPointer(nullptr)
{
p_inputVolume.addSharedProperty(&_predicateEvaluation.p_inputImage);
......@@ -77,10 +76,6 @@ namespace campvis {
p_histogram.addSharedProperty(&(static_cast<PointPredicateRaycaster*>(_raycaster.getRaycastingProcessor())->p_predicateHistogram));
p_histogram.addSharedProperty(&_predicateEvaluation.p_histogram);
//_raycaster.p_camera.addSharedProperty(&_predicateEvaluation.p_camera);
_sliceExtractor.p_geometryID.setValue("scribbles");
}
PredicateVolumeExplorer::~PredicateVolumeExplorer() {
......@@ -90,6 +85,8 @@ namespace campvis {
VolumeExplorer::init();
_predicateEvaluation.init();
_predicateEvaluation.s_invalidated.connect<PredicateVolumeExplorer>(this, &PredicateVolumeExplorer::onProcessorInvalidated);
p_enableScribbling.setValue(true);
}
void PredicateVolumeExplorer::deinit() {
......@@ -109,14 +106,7 @@ namespace campvis {
validate(BITSET_INVALID);
}
if (getInvalidationLevel() & SCRIBBLE_INVALID) {
FaceGeometry* g = createScribbleGeometry();
data.addData("scribbles", g);
validate(SCRIBBLE_INVALID);
}
VolumeExplorer::updateResult(data);
validate(INVALID_RESULT);
}
......@@ -143,74 +133,20 @@ namespace campvis {
}
void PredicateVolumeExplorer::onEvent(tgt::Event* e) {
// forward the event to the correspsonding event listeners depending on the mouse position
if (_bitmaskHandle.getData() != nullptr) {
const ImageData* id = static_cast<const ImageData*>(_bitmaskHandle.getData());
if (const GenericImageRepresentationLocal<BitmaskType, 1>* repLocal = id->getRepresentation< GenericImageRepresentationLocal<BitmaskType, 1> >()) {
const tgt::svec3& imageSize = repLocal->getSize();
if (typeid(*e) == typeid(tgt::MouseEvent)) {
tgt::MouseEvent* me = static_cast<tgt::MouseEvent*>(e);
if (me->x() <= p_sliceRenderSize.getValue().x) {
float renderTargetRatio = static_cast<float>(p_sliceRenderSize.getValue().x) / static_cast<float>(p_sliceRenderSize.getValue().y);
tgt::vec2 ratio = tgt::vec2(static_cast<float>(me->x()), static_cast<float>(me->y() % p_sliceRenderSize.getValue().y)) / tgt::vec2(p_sliceRenderSize.getValue());
// TODO: these transformation could probably be integrated into the SliceExtractor much more beautiful, as they are performed there anyway.
tgt::vec3 imgSize(repLocal->getSize());
tgt::svec3 voxel;
if (me->y() <= p_sliceRenderSize.getValue().y) {
float sliceRatio = (imgSize.x * repLocal->getParent()->getMappingInformation().getVoxelSize().x) / (imgSize.y * repLocal->getParent()->getMappingInformation().getVoxelSize().y);
float ratioRatio = sliceRatio / renderTargetRatio;
ratio -= (ratioRatio > 1) ? tgt::vec2(0.f, (1.f - (1.f / ratioRatio)) / 2.f) : tgt::vec2((1.f - ratioRatio) / 2.f, 0.f);
ratio *= (ratioRatio > 1) ? tgt::vec2(1.f, ratioRatio) : tgt::vec2(1.f / ratioRatio, 1.f);
ratio = tgt::clamp(ratio, 0.f, 1.f);
voxel = tgt::clamp(tgt::svec3(static_cast<size_t>(ratio.x * imageSize.x), static_cast<size_t>(ratio.y * imageSize.y), _sliceExtractor.p_zSliceNumber.getValue()), tgt::svec3(0, 0, 0), imageSize);
}
else if (me->y() <= 2*p_sliceRenderSize.getValue().y) {
float sliceRatio = (imgSize.x * repLocal->getParent()->getMappingInformation().getVoxelSize().x) / (imgSize.z * repLocal->getParent()->getMappingInformation().getVoxelSize().z);
float ratioRatio = sliceRatio / renderTargetRatio;
ratio -= (ratioRatio > 1) ? tgt::vec2(0.f, (1.f - (1.f / ratioRatio)) / 2.f) : tgt::vec2((1.f - ratioRatio) / 2.f, 0.f);
ratio *= (ratioRatio > 1) ? tgt::vec2(1.f, ratioRatio) : tgt::vec2(1.f / ratioRatio, 1.f);
ratio = tgt::clamp(ratio, 0.f, 1.f);
voxel = tgt::clamp(tgt::svec3(static_cast<size_t>(ratio.x * imageSize.x), _sliceExtractor.p_ySliceNumber.getValue(), static_cast<size_t>(ratio.y * imageSize.z)), tgt::svec3(0, 0, 0), imageSize);
}
else {
float sliceRatio = (imgSize.y * repLocal->getParent()->getMappingInformation().getVoxelSize().y) / (imgSize.z * repLocal->getParent()->getMappingInformation().getVoxelSize().z);
float ratioRatio = sliceRatio / renderTargetRatio;
ratio -= (ratioRatio > 1) ? tgt::vec2(0.f, (1.f - (1.f / ratioRatio)) / 2.f) : tgt::vec2((1.f - ratioRatio) / 2.f, 0.f);
ratio *= (ratioRatio > 1) ? tgt::vec2(1.f, ratioRatio) : tgt::vec2(1.f / ratioRatio, 1.f);
ratio = tgt::clamp(ratio, 0.f, 1.f);
voxel = tgt::clamp(tgt::svec3(_sliceExtractor.p_xSliceNumber.getValue(), static_cast<size_t>(ratio.x * imageSize.y), static_cast<size_t>(ratio.y * imageSize.z)), tgt::svec3(0, 0, 0), imageSize);
}
if (me->action() == tgt::MouseEvent::PRESSED) {
_mousePressedPointer = (me->button() == tgt::MouseEvent::MOUSE_BUTTON_LEFT) ? &_yesScribbles : &_noScribbles;
if (! me->modifiers() & tgt::Event::SHIFT)
_mousePressedPointer->clear();
_mousePressedPointer->push_back(voxel);
invalidate(INVALID_RESULT | SCRIBBLE_INVALID | SLICES_INVALID);
return;
}
else if (_mousePressedPointer != nullptr && me->action() == tgt::MouseEvent::MOTION) {
_mousePressedPointer->push_back(voxel);
invalidate(INVALID_RESULT | SCRIBBLE_INVALID | SLICES_INVALID);
return;
}
else if (_mousePressedPointer != nullptr && me->action() == tgt::MouseEvent::RELEASED) {
updatePredicateHistogramFromScribbles();
_mousePressedPointer = nullptr;
return;
}
}
}
bool doHistogramUpdateFromScribbles = false;
// intercept the finishing of a scribble paint, so that we can trigger the predicate histogram update.
if (typeid(*e) == typeid(tgt::MouseEvent)) {
tgt::MouseEvent* me = static_cast<tgt::MouseEvent*>(e);
if (_scribblePointer != nullptr && me->action() == tgt::MouseEvent::RELEASED) {
doHistogramUpdateFromScribbles = true;
}
}
VolumeExplorer::onEvent(e);
if (doHistogramUpdateFromScribbles)
updatePredicateHistogramFromScribbles();
}
void PredicateVolumeExplorer::updatePredicateHistogramFromScribbles() {
......@@ -235,7 +171,7 @@ namespace campvis {
invalidate(INVALID_RESULT);
}
std::vector<int> PredicateVolumeExplorer::computeBitHistogram(const std::vector<tgt::svec3>& voxels) {
std::vector<int> PredicateVolumeExplorer::computeBitHistogram(const std::vector<tgt::vec3>& voxels) {
std::vector<int> toReturn = std::vector<int>(p_histogram.getPredicateHistogram()->getPredicates().size(), 0);
if (_bitmaskHandle.getData() != nullptr) {
......@@ -257,49 +193,5 @@ namespace campvis {
return toReturn;
}
std::vector<tgt::vec3> PredicateVolumeExplorer::createScribbleGeometryVertices(const std::vector<tgt::svec3>& scribble) const {
const tgt::ivec2& sliceSize = p_sliceRenderSize.getValue();
std::vector<tgt::vec3> vertices;
if (_bitmaskHandle.getData() != nullptr) {
const ImageData* id = static_cast<const ImageData*>(_bitmaskHandle.getData());
if (const GenericImageRepresentationLocal<BitmaskType, 1>* repLocal = id->getRepresentation< GenericImageRepresentationLocal<BitmaskType, 1> >()) {
// TODO: these transformation could probably be integrated into the SliceExtractor much more beautiful, as they are performed there anyway.
tgt::vec3 imgSize(repLocal->getSize());
float sliceRatioX = (imgSize.y * repLocal->getParent()->getMappingInformation().getVoxelSize().y)
/ (imgSize.z * repLocal->getParent()->getMappingInformation().getVoxelSize().z);
float sliceRatioY = (imgSize.x * repLocal->getParent()->getMappingInformation().getVoxelSize().x)
/ (imgSize.z * repLocal->getParent()->getMappingInformation().getVoxelSize().z);
float sliceRatioZ = (imgSize.x * repLocal->getParent()->getMappingInformation().getVoxelSize().x)
/ (imgSize.y * repLocal->getParent()->getMappingInformation().getVoxelSize().y);
// transform scribbles into viewport coordinates
for (size_t i = 0; i < scribble.size(); ++i) {
const tgt::svec3& v = scribble[i];
if (v.x == _sliceExtractor.p_xSliceNumber.getValue()) {
//vertices.push_back(tgt::vec3(x.y, v.z, 0.f) * )
}
}
}
}
return vertices;
}
FaceGeometry* PredicateVolumeExplorer::createScribbleGeometry() const {
std::vector<tgt::vec3> vertices;
std::vector<tgt::vec4> colors;
for (size_t i = 0; i < _yesScribbles.size(); ++i) {
vertices.push_back(tgt::vec3(_yesScribbles[i]));
colors.push_back(tgt::vec4(.2f, .8f, 0.f, 1.f));
}
for (size_t i = 0; i < _noScribbles.size(); ++i) {
vertices.push_back(tgt::vec3(_noScribbles[i]));
colors.push_back(tgt::vec4(.85f, .2f, 0.f, 1.f));
}
return new FaceGeometry(vertices, std::vector<tgt::vec3>(), colors);
}
}
......@@ -81,8 +81,7 @@ namespace campvis {
/// Additional invalidation levels for this processor.
/// Not the most beautiful design though.
enum ProcessorInvalidationLevel {
BITSET_INVALID = SLICES_INVALID << 1,
SCRIBBLE_INVALID = SLICES_INVALID << 2,
BITSET_INVALID = SCRIBBLE_INVALID << 1
};
/// \see AbstractProcessor::updateResult
......@@ -95,27 +94,25 @@ namespace campvis {
*/
virtual void onProcessorInvalidated(AbstractProcessor* processor);
/**
* \see VisualizationProcessor::onPropertyChanged
*/
/// \see VisualizationProcessor::onPropertyChanged
virtual void onPropertyChanged(const AbstractProperty* prop);
/**
* Updates the point predicate histogram from the current scribble geometry.
*/
void updatePredicateHistogramFromScribbles();
std::vector<int> computeBitHistogram(const std::vector<tgt::svec3>& bitmasks);
std::vector<tgt::vec3> createScribbleGeometryVertices(const std::vector<tgt::svec3>& scribble) const;
FaceGeometry* createScribbleGeometry() const;
PointPredicateEvaluator _predicateEvaluation;
/**
* Returns the predicate bit histogram of the given vector of voxels.
* \param voxels List of voxels to compute the bit histogram for.
* \return A histogram where each bit corresponds to the number of voxels in \a voxels where the corresponding predicate yields true.
*/
std::vector<int> computeBitHistogram(const std::vector<tgt::vec3>& voxels);
PointPredicateEvaluator _predicateEvaluation; ///< Processor to perform the point predicate evaluation on.
DataHandle _bitmaskHandle; ///< DataHandle storing the predicate bitmask
std::vector<tgt::svec3>* _mousePressedPointer; ///< Pointer encoding whether the mouse was pressed (!= nullptr) and whether we have yes-scribbles or no-scribbles.
std::vector<tgt::svec3> _yesScribbles; ///< All voxels of the current yes-scribbles
std::vector<tgt::svec3> _noScribbles; ///< All voxels of the current no-scribbles
private:
static const std::string loggerCat_;
};
......
......@@ -128,8 +128,6 @@ namespace campvis {
void PointPredicateRenderArea::mouseMoveEvent(QMouseEvent* e) {
if (_movingPredicate >= 0) {
AbstractPointPredicate* daPredicate = getPredicate(_movingPredicate);
int hh = height() - MARGIN_TOP - MARGIN_BOTTOM;
double y = height() - e->y() - MARGIN_BOTTOM;
float newValue = tgt::clamp(y/hh, 0.0, 1.0);
......@@ -209,8 +207,6 @@ namespace campvis {
}
QPoint PointPredicateRenderArea::transformToGraphSpace(int x, int y) {
int hw = width() - MARGIN_LEFT - MARGIN_RIGHT;
int hh = height() - MARGIN_TOP - MARGIN_BOTTOM;
return QPoint(x - MARGIN_LEFT, height() - y - MARGIN_BOTTOM);
}
......@@ -219,8 +215,6 @@ namespace campvis {
int hh = height() - MARGIN_TOP - MARGIN_BOTTOM;
std::vector<AbstractPointPredicate*> preds = _prop->getPredicateHistogram()->getPredicates();
double w = static_cast<double>(hw) / preds.size();
if (preds.empty())
return -1;
......@@ -246,8 +240,6 @@ namespace campvis {
int hh = height() - MARGIN_TOP - MARGIN_BOTTOM;
std::vector<AbstractPointPredicate*> preds = _prop->getPredicateHistogram()->getPredicates();
double w = static_cast<double>(hw) / preds.size();
if (preds.empty())
return -1;
......@@ -276,8 +268,6 @@ namespace campvis {
int hh = height() - MARGIN_TOP - MARGIN_BOTTOM;
std::vector<AbstractPointPredicate*> preds = _prop->getPredicateHistogram()->getPredicates();
double w = static_cast<double>(hw) / preds.size();
if (preds.empty())
return -1;
......
......@@ -539,7 +539,7 @@ namespace campvis {
_splines[p_frameNumber.getValue()] = tmp;
}
catch (itk::ExceptionObject e) {
catch (itk::ExceptionObject& e) {
LERROR(e.what());
}
......@@ -654,7 +654,7 @@ namespace campvis {
}
_segmentation.setLayer(layer, l);
}
catch (itk::ExceptionObject e) {
catch (itk::ExceptionObject& e) {
LERROR(e.what());
}
}
......
......@@ -178,6 +178,7 @@ namespace campvis {
}
if (prop == &p_outputImage) {
_raycaster.p_outputImage.setValue(p_outputImage.getValue() + ".raycaster");
_sliceExtractor.p_geometryID.setValue(p_outputImage.getValue() + ".scribbles");
}
if (prop == &p_inputVolume) {
invalidate(VR_INVALID | SLICES_INVALID);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment