/*
* This file is part of rasdaman community.
*
* Rasdaman community is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Rasdaman community is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rasdaman community. If not, see .
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
rasdaman GmbH.
*
* For more information please see
* or contact Peter Baumann via .
/
/**
* PURPOSE:
*
* A viewer for orthosections in 3D images (bias on medical images)
*
* COMENTS:
* None
*/
// Standard wxWindows preamble.
#ifdef __GNUG__
#pragma implementation
#endif
// changed in wxWindows 2.4.2:
//#include "wx_prec.h"
#include
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include
#endif
#include
#include
#include
#include
#ifdef EARLY_TEMPLATE
#define __EXECUTABLE__
#endif
#include "raslib/rmdebug.hh"
#include "rviewApp.hh"
#include "rviewOSection.hh"
#include "rviewTypes.hh"
#include "rviewPrefs.hh"
#include "cube_render.h"
const int rviewOSectionImage::osection_ctrly = 140;
const int rviewOSectionImage::osection_rcwidth = 60;
const int rviewOSectionImage::osection_sheight = 40;
const int rviewOSectionImage::osection_chkwidth = 60;
const int rviewOSectionImage::osection_chkheight = 20;
const int rviewOSectionImage::osection_twidth = 40;
const int rviewOSectionImage::osection_theight = 50;
const int rviewOSectionImage::osection_bwidth = 50;
const int rviewOSectionImage::osection_bheight = 30;
static void outputGeomData(const vertex_fp *v)
{
unsigned int j;
for (j=0; j<4; j++)
{
cout << '(' << v[j].x << ',' << v[j].y << ',' << v[j].z << ')';
}
cout << endl;
}
const unsigned int rviewOSectionImage::numSections = 3;
const char *rviewOSectionImage::sliderLabels[rviewOSectionImage::numSections] = {
"textSliceX",
"textSliceY",
"textSliceZ"
};
const char *rviewOSectionImage::view_Thickness = "thickness";
const char *rviewOSectionImage::view_MidPoint = "midPoint";
const char *rviewOSectionImage::view_UseBBox = "useBBox";
/*
* The actual viewer class
*/
// types for internal use defined here (to avoid including cube_render.h from headers)
// the dimensions a section is mapped to (z is the flat one)
struct rviewOSectionImage::section_map_s {
unsigned int x, y, z;
};
// a partition descriptor (each quadrant is described by one such partition;
// normally there are 12 in total)
struct rviewOSectionImage::section_part_s {
unsigned int section;
unsigned long offset;
tex_desc td;
vertex_fp gr[4]; // fully rotated and translated
vertex_fp grav; // center of gravity
real_t distance;
int quadrant;
};
rviewOSectionImage::rviewOSectionImage(mdd_frame *mf, unsigned int flags) :
rviewRenderImage(mf, osection_ctrly, flags)
{
secmap = NULL;
partition = NULL;
sliders = NULL;
sltexts = NULL;
thickness = prefs->imgOrthoThick;
unsigned int i, j;
secmap = new section_map_t[numSections];
memset(secmap, 0, numSections*sizeof(section_map_t));
currentSection = numSections + 1;
for (i=0; i= 2) ? i-2 : i+1;
secmap[i].z = (i >= 1) ? i-1 : i+2;
}
intersection = r_Point(dimMDD);
for (i=0; iimgOrthoBBox;
boundingBox->SetValue(doBoundingBox);
//sliders = new rviewSlider*[numSections];
sliders = new rviewSpecialSlider*[numSections];
sltexts = new rviewText*[numSections];
for (i=0; ilookup(sliderLabels[i]));
sliders[i] = new rviewSpecialSlider(this, ctrlPanel, intersection[j], interv[j].low(), interv[j].high(), 100, lman->lookup(sliderLabels[i]));
sltexts[i] = new rviewText(ctrlPanel, intersection[j]);
}
thickText = new rviewText(ctrlPanel, thickness);
thickText->SetValue(thickness);
}
int rviewOSectionImage::openViewer(void)
{
if (dimMDD != 3)
{
rviewErrorbox::reportError(lman->lookup("errorModeDim"), rviewOSectionImage::getFrameName(), "openViewer");
objectInitializedOK = FALSE;
return -1;
}
partition = new section_part_t[numSections * 4];
memset(partition, 0, numSections * 4 * sizeof(section_part_t));
numPartitions = 0;
if (rviewRenderImage::openViewer() == 0)
{
openViewerEpilogue(rviewOSectionImage::getFrameType());
return 0;
}
return -1;
}
rviewOSectionImage::~rviewOSectionImage(void)
{
if (secmap != NULL)
delete [] secmap;
if (partition != NULL)
delete [] partition;
if (sliders != NULL)
delete [] sliders;
if (sltexts != NULL)
delete [] sltexts;
}
const char *rviewOSectionImage::getFrameName(void) const
{
return "rviewOSectionImage";
}
rviewFrameType rviewOSectionImage::getFrameType(void) const
{
return rviewFrameTypeOSectionImage;
}
int rviewOSectionImage::getViewerType(void) const
{
return RVIEW_RESDISP_IMGOSECT;
}
void rviewOSectionImage::label(void)
{
unsigned int i;
setDisplayTitle(lman->lookup("titleImageOrtho"));
boundingBox->SetLabel(lman->lookup("textBBox"));
thickText->SetLabel(lman->lookup("textOrthoThickness"));
for (i=0; iSetLabel(lman->lookup(sliderLabels[i]));
}
rviewRenderImage::label();
}
void rviewOSectionImage::updateSlice(unsigned int num, long value, bool useDummy)
{
unsigned int map = secmap[num].z;
//cout << "update slice " << num << endl;
// make an update if the value has changed or we need a full update and the current
// section is a dummy.
if ((intersection[map] != value) || (!useDummy && (getSectionProjection(num) != value)))
{
if ((interv[map].low() <= value) && (value <= interv[map].high()))
{
intersection[map] = value;
sliders[num]->SetValue(value);
sltexts[num]->SetValue(value);
if (useDummy)
createDummySection(num);
else
ensureSections();
fillBuffer();
updatePixmap(imgData, imgData);
}
}
}
void rviewOSectionImage::refreshSlices(bool force)
{
if (force)
flushSlices();
ensureSections();
fillBuffer();
updatePixmap(imgData, imgData);
}
int rviewOSectionImage::process(wxObject &obj, wxEvent &evt)
{
int type = evt.GetEventType();
if (type == wxEVENT_TYPE_CHECKBOX_COMMAND)
{
if (&obj == (wxObject*)boundingBox)
{
doBoundingBox = boundingBox->GetValue();
fillBuffer();
pcanv->updateDisplay();
return 1;
}
}
else if (type == wxEVENT_TYPE_SLIDER_COMMAND)
{
unsigned int i;
for (i=0; iGetValue(), TRUE);
return 1;
}
}
}
else if (type == wxEVENT_TYPE_TEXT_ENTER_COMMAND)
{
unsigned int i;
for (i=0; iGetValue()), FALSE);
return 1;
}
}
if (&obj == (wxObject*)thickText)
{
int newThick = atoi(thickText->GetValue());
if ((newThick > 0) && (newThick != thickness))
{
thickness = newThick;
refreshSlices(TRUE);
return 1;
}
}
}
return rviewRenderImage::process(obj, evt);
}
void rviewOSectionImage::childMouseEvent(wxWindow *child, wxMouseEvent &mevt)
{
unsigned int i;
for (i=0; iPositionInWell(mx, my))
newSect = i;
else
newSect = numSections + 1;
if (newSect != currentSection)
{
currentSection = newSect;
fillBuffer();
updatePixmap(imgData, imgData);
}
break;
}
}
// pass on event
rviewRenderImage::childMouseEvent(child, mevt);
}
void rviewOSectionImage::OnSize(int w, int h)
{
rviewRenderImage::OnSize(w, h);
int x, y, width, orgy, posx, posy;
unsigned int i;
ctrlPanel->GetClientSize(&x, &y);
boundingBox->SetSize(w + 2*display_cnvborder - 3*display_border - 4*display_pbwidth, display_border, osection_chkwidth, osection_chkheight);
x -= 2*display_border;
orgy = totalCtrlHeight - osection_ctrly + display_border;
width = x - osection_rcwidth - osection_twidth;
if (width < 100)
width = 100;
posx = display_border;
posy = orgy;
for (i=0; iSetSize(posx, posy, width - display_border, osection_sheight);
sltexts[i]->SetSize(posx + width, posy + display_border, osection_twidth, osection_sheight);
posy += osection_sheight;
}
posx = x - osection_rcwidth + 3*display_border/2;
posy = orgy;
thickText->SetSize(posx, posy, osection_rcwidth, osection_theight);
}
bool rviewOSectionImage::doUpdate(int flags)
{
return FALSE;
}
char *rviewOSectionImage::initMode(void)
{
sprintf(projString, "*:*, *:*, *:*");
project->SetValue(projString);
setModeDimension(3);
ensureSections();
return rviewRenderImage::initMode();
}
char *rviewOSectionImage::setupEnvironment(int w, int h)
{
if (setupEnvBase(w, h, getCsmapArray(), &csmap, csInterv) != 0)
return NULL;
return imgData;
}
void rviewOSectionImage::fillBuffer(void)
{
bool cspaceOK;
unsigned int i, j;
performPartition();
// bounding boxes?
graphEnv->bbox_colour = (doBoundingBox) ? 0xffffff : 0xffffffff;
// z params
graphEnv->zpro = setup.zpro; graphEnv->clipz = setup.clipz;
fillBufferBackground(doValToCspace, cspaceOK, getCsmapArray(), &csmap, csInterv, baseType, doFullRangeCspace);
real_t ztranslate = graphEnv->zpro + zoff;
for (i=0; ix * v->x) + (v->y * v->y) + ((v->z + ztranslate) * (v->z + ztranslate)));
}
// finally sort it by the distance to the observer
// this is basically at most 12 entries, so there's no point in using complicated sorting techniques
for (i=0; i partition[i].distance)
{
section_part_t aux;
memcpy(&aux, partition+i, sizeof(section_part_t));
memcpy(partition+i, partition+j, sizeof(section_part_t));
memcpy(partition+j, &aux, sizeof(section_part_t));
}
}
}
//cout << "PARTITIONS " << numPartitions << endl;
for (i=0; ifloatType != 0) && (csmap != NULL))
{
td->minVal = csmap->getMinVal();
td->maxVal = csmap->getMaxVal();
}
td->data = getSectionArray(partition[i].section) + partition[i].offset;
memcpy(geomUse, &(partition[i].gr), 4 * sizeof(vertex_fp));
geomUse[0].z += ztranslate;
//outputGeomData(geomUse);
RenderCubeSurf(geomUse, graphEnv, td);
if (partition[i].section == currentSection)
{
render_desc renderDesc;
vertex_fp from, to;
vertex_fp *ax1, *ax2;
renderDesc.graphEnv = graphEnv;
renderDesc.texDesc = td;
ax1 = geomUse + (secmap[partition[i].section].x + 1);
ax2 = geomUse + (secmap[partition[i].section].y + 1);
from.x = geomUse[0].x + ax1->x;
from.y = geomUse[0].y + ax1->y;
from.z = geomUse[0].z + ax1->z;
to.x = geomUse[0].x + ax2->x;
to.y = geomUse[0].y + ax2->y;
to.z = geomUse[0].z + ax2->z;
Render3DLine(&from, &to, &renderDesc, graphEnv->bbox_colour);
from.x = geomUse[0].x;
from.y = geomUse[0].y;
from.z = geomUse[0].z;
to.x = geomUse[0].x + ax1->x + ax2->x;
to.y = geomUse[0].y + ax1->y + ax2->y;
to.z = geomUse[0].z + ax1->z + ax2->z;
Render3DLine(&from, &to, &renderDesc, graphEnv->bbox_colour);
}
}
}
if (doValToCspace && cspaceOK)
{
translateBufferToCspace(baseType);
}
}
int rviewOSectionImage::makeMinterval(unsigned int num, r_Minterval &dom)
{
r_Range low, high;
r_Sinterval aux[3];
dom = r_Minterval(dimMDD);
unsigned int map;
aux[secmap[num].x] = interv[secmap[num].x];
aux[secmap[num].y] = interv[secmap[num].y];
// projection dimension
map = secmap[num].z;
low = intersection[map] - thickness/2;
high = low + thickness - 1;
if (low < interv[map].low())
low = interv[map].low();
if (high > interv[map].high())
high = interv[map].high();
aux[map] = r_Sinterval(low, high);
dom << aux[0] << aux[1] << aux[2];
//cout << "INTERVAL " << dom << endl;
return 0;
}
int rviewOSectionImage::performPartition(void)
{
RMDBGONCE(3, RMDebug::module_applications, "rviewOSectionImage", "performPartition()");
unsigned int i, j;
section_part_t *part = partition;
r_Point midpoint(dimMDD);
for (i=0; i projection string)
if ((pt1[map] <= high) && (pt2[map] >= low))
{
// yes, now clip it
if (low < pt1[map])
low = pt1[map];
if (high > pt2[map])
high = pt2[map];
r_Sinterval ziv(low, high);
for (j=0; j<4; j++)
{
r_Sinterval auxdom[3];
auxdom[secmap[i].z] = ziv;
map = secmap[i].x;
if ((j & 1) == 0)
{
low = pt1[map]; high = intersection[map] - thickness/2;
}
else
{
low = intersection[map] + thickness/2; high = pt2[map];
}
// the current projection string might project some of these partitions away
if (low <= high)
{
// this can still happen if the intersection point is outside the current projection
// domain for the still visible quadrant.
if (low < pt1[map])
low = pt1[map];
if (high > pt2[map])
high = pt2[map];
auxdom[map] = r_Sinterval(low, high);
map = secmap[i].y;
if ((j & 2) == 0)
{
low = pt1[map]; high = intersection[map] - thickness/2;
}
else
{
low = intersection[map] + thickness/2; high = pt2[map];
}
// ditto
if (low <= high)
{
// see above
if (low < pt1[map])
low = pt1[map];
if (high > pt2[map])
high = pt2[map];
r_Minterval dom(dimMDD); // domain of quadrant in absolute coordinates
auxdom[map] = r_Sinterval(low, high);
dom << auxdom[0] << auxdom[1] << auxdom[2];
// now calculate the descriptor for this domain
tex_desc *td = &(part->td);
part->section = i;
const r_Minterval &pardom = getSectionParent(i);
td->dimx = pardom[0].high() - pardom[0].low() + 1;
td->dimy = pardom[1].high() - pardom[1].low() + 1;
td->dimz = pardom[2].high() - pardom[2].low() + 1;
td->widthx = dom[0].high() - dom[0].low() + 1;
td->widthy = dom[1].high() - dom[1].low() + 1;
td->widthz = dom[2].high() - dom[2].low() + 1;
part->offset = (((dom[0].low() - pardom[0].low()) * td->dimy + (dom[1].low() - pardom[1].low())) * td->dimz + (dom[2].low() - pardom[2].low())) * baseSize;
td->baseSize = baseSize;
td->floatType = ((baseType == rbt_float) || (baseType == rbt_double));
part->quadrant = j;
//cout << "DOM " << dom << ", PARENT " << pardom << ", OFFSET " << part->offset << ", size " << pardom.cell_count() << endl;
vertex_fp *v, *w;
// this rotates the subcube's origin. The total origin is 0 for now.
// use gr[1] as temporary workspace for the unrotated origin
w = &(part->gr[1]);
w->x = dom[0].low() - midpoint[0]; // or is it secmap?
w->y = dom[1].low() - midpoint[1];
w->z = dom[2].low() - midpoint[2];
v = &(part->gr[0]);
v->x = cubeScale * (w->x * rot[0].x + w->y * rot[0].y + w->z * rot[0].z);
v->y = cubeScale * (w->x * rot[1].x + w->y * rot[1].y + w->z * rot[1].z);
v->z = cubeScale * (w->x * rot[2].x + w->y * rot[2].y + w->z * rot[2].z);
// then rotate the whole thing and calculate the center of gravity (= origin + 0.5 * diagonal)
unsigned int k;
part->grav.x = part->gr[0].x;
part->grav.y = part->gr[0].y;
part->grav.z = part->gr[0].z;
for (k=1; k<4; k++)
{
geomUse[k].x = 0; geomUse[k].y = 0; geomUse[k].z = 0;
}
geomUse[1].x = td->widthx;
geomUse[2].y = td->widthy;
geomUse[3].z = td->widthz;
for (k=1; k<4; k++)
{
v = &(part->gr[k]); w = &(geomUse[k]);
// this rotates the cube's axes (edge lengths are width = dom.high() - dom.low() + 1);
v->x = cubeScale * (w->x * rot[0].x + w->y * rot[0].y + w->z * rot[0].z);
v->y = cubeScale * (w->x * rot[1].x + w->y * rot[1].y + w->z * rot[1].z);
v->z = cubeScale * (w->x * rot[2].x + w->y * rot[2].y + w->z * rot[2].z);
part->grav.x += 0.5 * (v->x);
part->grav.y += 0.5 * (v->y);
part->grav.z += 0.5 * (v->z);
}
// advance partition pointer
part++;
}
}
}
} // entire section clipped away by projection string
}
}
numPartitions = part - partition;
// sorting isn't done here because it depends on the exact current perspective view.
RMDBGIF(4, RMDebug::module_applications, "rviewOSection", \
for (i=0; iSetValue(thickness);
boundingBox->SetValue(doBoundingBox);
unsigned char modified[numSections];
unsigned int i;
for (i=0; iGetValue()));
//cout << i << ": IS " << sliders[i]->GetValue() << ", NEW " << value << ", MOD " << (int)(modified[i]) << endl;
if (modified[i])
{
sliders[i]->SetValue((int)value);
sltexts[i]->SetValue((int)value);
}
}
for (i=0; igetMinterval(dom, collname, loid) == 0)
{
cerr << "rviewOSectionImage::create(): unable to read spatial domain";
return NULL;
}
r_Minterval queryDom(dom.dimension());
for (di=0; diexecuteQuerySync(queryBuffer, NULL, FALSE)) != NULL)
{
if (desc->mddObjs != NULL)
{
unsigned int i;
r_GMarray *dummyMDD;
const r_GMarray *mdd;
mdd_frame dummyFrame;
mdd = desc->mddObjs[0].mdd.ptr();
// create a fake MDD with all the necessary meta data (spatial domain, base type, ...)
dummyMDD = new r_GMarray();
dummyMDD->set_spatial_domain(dom);
dummyMDD->set_type_length(mdd->get_type_length());
dummyMDD->set_type_structure(mdd->get_type_structure());
dummyMDD->set_type_by_name(mdd->get_type_name());
dummyMDD->initialize_oid(mdd->get_oid());
//dummyMDD->set_type_schema(mdd->get_type_schema());
dummyFrame.mdd = r_Ref(dummyMDD);
dummyFrame.flags = 0;
// the collection is useless now
rviewDeleteCollection(desc);
rviewOSectionPartImage *viewer = new rviewOSectionPartImage(&dummyFrame, collname, dummyFrame.mdd->get_oid(), display_flag_standalone);
// also open it automatically
if (viewer->openViewer() != 0)
{
delete viewer;
return NULL;
}
return viewer;
}
rviewDeleteCollection(desc);
}
return NULL;
}
#define INIT_DUMMY_MDD(type, min, max) \
csDummy = new r_Marray(dummyDom, dummySL); \
((type*)(csDummy->get_array()))[0] = min; \
((type*)(csDummy->get_array()))[1] = max;
rviewOSectionPartImage::rviewOSectionPartImage(mdd_frame *mf, const char *cname, const r_OId &oid, unsigned int flags) :
rviewOSectionImage(mf, flags),
objOId(oid),
collName(cname)
{
sections = NULL;
// create a dummy MDD for use with the colourspace mapper. This contains 2 cells, the first
// is min, the second is max. It must be kept up to date as new data is loaded.
r_Minterval dummyDom(1);
dummyDom << r_Sinterval((r_Range)0, (r_Range)1);
r_Storage_Layout *dummySL = NULL;
switch(baseType)
{
case rbt_bool:
INIT_DUMMY_MDD(r_Boolean, 0, 1);
break;
case rbt_char:
INIT_DUMMY_MDD(r_Char, 0, 255);
break;
case rbt_uchar:
INIT_DUMMY_MDD(r_Octet, -128, 127);
break;
// from here on the defaults are rather arbitrary...
case rbt_short:
INIT_DUMMY_MDD(r_Short, -4096, 4095);
break;
case rbt_ushort:
INIT_DUMMY_MDD(r_UShort, 0, 8191);
break;
case rbt_long:
INIT_DUMMY_MDD(r_Long, -65536, 65535);
break;
break;
case rbt_ulong:
INIT_DUMMY_MDD(r_ULong, 0, 131071);
break;
case rbt_float:
INIT_DUMMY_MDD(r_Float, -1000.0, 1000.0);
break;
case rbt_double:
INIT_DUMMY_MDD(r_Double, -1000.0, 1000.0);
break;
case rbt_rgb:
{
// basically no colourspace mapping is possible here, but I don't want a totally
// uninitialized marray around, it's asking for trouble...
RGBPixel *ptr;
csDummy = new r_Marray(dummyDom, dummySL);
ptr = (RGBPixel*)(csDummy->get_array());
ptr[0].red = 0; ptr[0].green = 0; ptr[0].blue = 0;
ptr[1].red = 255; ptr[1].green = 255; ptr[1].blue = 255;
}
break;
default:
// this shouldn't happen...
break;
}
csDummy->set_type_by_name(mddObj->get_type_name());
csDummy->set_type_structure(mddObj->get_type_structure());
unsigned int i;
sections = new section_desc_t[numSections];
memset(sections, 0, numSections*sizeof(section_desc_t));
for (i=0; iSetValue(prefs->imgOrthoDragRel);
fireButton = new rviewButton(ctrlPanel);
}
rviewOSectionPartImage::~rviewOSectionPartImage(void)
{
if (sections != NULL)
{
unsigned int i;
for (i=0; iSetLabel(lman->lookup("textOrthoDragRelease"));
fireButton->SetLabel(lman->lookup("textOrthoFireButton"));
}
int rviewOSectionPartImage::process(wxObject &obj, wxEvent &evt)
{
int type = evt.GetEventType();
if (type == wxEVENT_TYPE_BUTTON_COMMAND)
{
if (&obj == (wxObject*)fireButton)
{
// also read the thickness while we're at it
int newThick = atoi(thickText->GetValue());
if ((newThick > 0) && (newThick != thickness))
{
thickness = newThick;
refreshSlices(TRUE);
}
else
refreshSlices(FALSE);
return 1;
}
}
return rviewOSectionImage::process(obj, evt);
}
void rviewOSectionPartImage::childMouseEvent(wxWindow *child, wxMouseEvent &mevt)
{
int type = mevt.GetEventType();
//cout << "MOUSE EVENT " << type << endl;
if (((type == wxEVENT_TYPE_LEFT_UP) || (type == wxEVENT_TYPE_RIGHT_UP)) && fireDragRelease->GetValue())
refreshSlices(FALSE);
// pass event on to bottom layer
rviewOSectionImage::childMouseEvent(child, mevt);
}
void rviewOSectionPartImage::OnSize(int w, int h)
{
rviewOSectionImage::OnSize(w, h);
int x, y;
ctrlPanel->GetClientSize(&x, &y);
x -= osection_rcwidth;
y = totalCtrlHeight - osection_ctrly + display_border + osection_theight;
fireDragRelease->SetSize(x, y, osection_chkwidth, osection_chkheight);
y += osection_chkheight;
fireButton->SetSize(x, y, osection_bwidth, osection_bheight);
}
void rviewOSectionPartImage::flushSlices(void)
{
unsigned int i;
for (i=0; iexecuteQuerySync(buffer, NULL, FALSE)) != NULL)
{
if (desc->number != 0)
{
sections[i].mdd = desc->mddObjs[0].mdd.ptr();
desc->mddObjs[0].mdd = NULL;
rviewDeleteCollection(desc);
sections[i].proj = intersection[secmap[i].z];
}
}
if (sections[i].mdd == NULL)
{
createDummySection(i, &slicedom);
}
}
}
return 0;
}
#define MAKE_DUMMY_SECTION(type, init) \
{ \
sections[num].mdd = new r_Marray(*domp); \
type *ptr = (type*)(sections[num].mdd->get_array()); \
for (i=0; icell_count();
switch (baseType)
{
case rbt_bool:
MAKE_DUMMY_SECTION(r_Boolean, 1);
break;
case rbt_char:
MAKE_DUMMY_SECTION(r_Char, 80 + num*32);
break;
case rbt_uchar:
MAKE_DUMMY_SECTION(r_Octet, -48 + num*32);
break;
case rbt_short:
MAKE_DUMMY_SECTION(r_Short, (-48 + num*32)*256);
break;
case rbt_ushort:
MAKE_DUMMY_SECTION(r_UShort, (80 + num*32)*256);
break;
case rbt_long:
MAKE_DUMMY_SECTION(r_Long, (-48 + num*32)*0x1000000);
break;
case rbt_ulong:
MAKE_DUMMY_SECTION(r_ULong, (80 + num*32)*0x1000000);
break;
case rbt_float:
MAKE_DUMMY_SECTION(r_Float, 10.0);
break;
case rbt_double:
MAKE_DUMMY_SECTION(r_Double, 10.0);
break;
case rbt_rgb:
{
sections[num].mdd = new r_Marray(*domp);
RGBPixel *ptr = (RGBPixel*)(sections[num].mdd->get_array());
r_Char val = 80 + 32*num;
for (i=0; ispatial_domain();
}
const r_Minterval &rviewOSectionPartImage::getSectionParent(unsigned int num)
{
return sections[num].mdd->spatial_domain();
}
char *rviewOSectionPartImage::getSectionArray(unsigned int num)
{
return sections[num].mdd->get_array();
}
long rviewOSectionPartImage::getSectionProjection(unsigned int num)
{
return sections[num].proj;
}
r_Ref &rviewOSectionPartImage::getCsmapArray(void)
{
return csDummy;
}
/*
* Full orthosection: the entire object resides in main memory; this integrates
* seamlessly with the other viewer types.
*/
rviewOSectionFullImage::rviewOSectionFullImage(mdd_frame *mf, unsigned int flags) :
rviewOSectionImage(mf, flags)
{
sections = new r_Minterval[numSections];
};
rviewOSectionFullImage::~rviewOSectionFullImage(void)
{
closeViewer();
delete [] sections;
sections=0;
}
int rviewOSectionFullImage::ensureSections(void)
{
unsigned int i;
for (i=0; iget_array();
}
long rviewOSectionFullImage::getSectionProjection(unsigned int num)
{
return intersection[secmap[num].z];
}
r_Ref &rviewOSectionFullImage::getCsmapArray(void)
{
return mddObj;
}