Skip to content

Commit

Permalink
fix the bug: neuron tracing error caused by highdpi scaling problem
Browse files Browse the repository at this point in the history
  • Loading branch information
zackzhy committed Jan 20, 2025
1 parent 10e2584 commit dee45a6
Show file tree
Hide file tree
Showing 10 changed files with 1,167 additions and 682 deletions.
1,125 changes: 635 additions & 490 deletions v3d_main/3drenderer/nstroke_tracing.cpp

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion v3d_main/3drenderer/renderer_gl1.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ class Renderer_gl1 : public Renderer
friend class V3dr_colormapDialog;

public:
XYZ ImageCurRes;
XYZ ImageStartPoint;
XYZ ImageMaxRes;

//Coordinate transform
XYZ ConvertGlobaltoLocalBlockCroods(double x,double y,double z);
XYZ ConvertLocalBlocktoGlobalCroods(double x,double y,double z);
XYZ ConvertMaxRes2CurrResCoords(double x,double y,double z);
XYZ ConvertCurrRes2MaxResCoords(double x,double y,double z);

Renderer_gl1(void* widget);
virtual ~Renderer_gl1();
virtual const int class_version() {return 1;}
Expand Down Expand Up @@ -552,7 +562,7 @@ class Renderer_gl1 : public Renderer
bool hierarchyRelabel;

void simpleConnect();
void simpleConnectExecutor(My4DImage* curImg, vector<segInfoUnit>& segInfo);
bool simpleConnectExecutor(My4DImage* curImg, vector<segInfoUnit>& segInfo);
void showSubtree();
void showConnectedSegs();
void sort_tracedNeuron(My4DImage* curImg, size_t rootID); // Sort swc, Peng Xie, June 2019
Expand Down Expand Up @@ -618,6 +628,7 @@ class Renderer_gl1 : public Renderer

// @ADDED by Alessandro on 2015-05-23. Called when "Esc" key is pressed and tracedNeuron must be updated.
void deleteMultiNeuronsByStrokeCommit();
bool deleteMultiNeuronsByStrokeCommit(vector<XYZ> local_list, float mindist);
// @ADDED by Alessandro on 2015-09-30. Select multiple markers by one-mouse stroke.

void selectMultiMarkersByStroke();
Expand Down
434 changes: 283 additions & 151 deletions v3d_main/3drenderer/renderer_hit.cpp

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions v3d_main/3drenderer/renderer_obj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1827,17 +1827,89 @@ void Renderer_gl1::addCurveSWC(vector<XYZ> &loc_list, int chno, double creatmode
//// Vaa3d || Terafly
else
{
// qDebug()<<"11111111111111: currentTraceType: "<<currentTraceType;
if(selectMode == smCurveTiltedBB_fm_sbbox) //LMG 26/10/2018 Creation mode 1 for BBox
creatmode = 1;
if(selectMode == smCurveCreate_MarkerCreate1_fm)
curImg->proj_trace_add_curve_segment(loc_list, chno,currentTraceType,default_radius_gd,creatmode);
else
curImg->proj_trace_add_curve_segment(loc_list, chno,currentTraceType, 1,creatmode);

// qDebug()<<"22222222222222: currentTraceType: "<<currentTraceType;
QVector<XYZ> coords;
int firstSegID=-1;
int secondSegID=-1;
for(int i=0;i<curImg->colla_cur_seg.row.size();i++)
{
coords.push_back(XYZ(curImg->colla_cur_seg.row[i].x,curImg->colla_cur_seg.row[i].y,curImg->colla_cur_seg.row[i].z));
}
int index=w->findseg(curImg->tracedNeuron,coords);
if(index<0)
qDebug("addCurve: index<0");

// curImg->colla_cur_seg.printInfo();
for(size_t i=0; i<curImg->tracedNeuron.seg.size(); ++i){
V_NeuronSWC seg=curImg->tracedNeuron.seg[i];
for(size_t j=0; j<seg.row.size(); j++){
if(fabs(seg.row[j].x-curImg->colla_cur_seg.row[0].x)<1e-4&&fabs(seg.row[j].y-curImg->colla_cur_seg.row[0].y)<1e-4&&
fabs(seg.row[j].z-curImg->colla_cur_seg.row[0].z)<1e-4&&index!=i)
firstSegID=i;
if(fabs(seg.row[j].x-curImg->colla_cur_seg.row[curImg->colla_cur_seg.row.size()-1].x)<1e-4&&
fabs(seg.row[j].y-curImg->colla_cur_seg.row[curImg->colla_cur_seg.row.size()-1].y)<1e-4&&
fabs(seg.row[j].z-curImg->colla_cur_seg.row[curImg->colla_cur_seg.row.size()-1].z)<1e-4&&index!=i)
secondSegID=i;
}
}

qDebug()<<"firstSegID: "<<firstSegID<<" secondSegID: "<<secondSegID;
vector<V_NeuronSWC> connectedSegs;
bool isBegin = true;

if(firstSegID!=-1)
connectedSegs.push_back(curImg->tracedNeuron.seg[firstSegID]);
if(secondSegID!=-1)
connectedSegs.push_back(curImg->tracedNeuron.seg[secondSegID]);

if(firstSegID!=-1&&connectedSegs.size()==1)
isBegin=true;
if(secondSegID!=-1&&connectedSegs.size()==1)
isBegin=false;

if (!fromserver)
{
if (w->TeraflyCommunicator
&&w->TeraflyCommunicator->socket&&w->TeraflyCommunicator->socket->state()==QAbstractSocket::ConnectedState
&& curImg->colla_cur_seg.row.size() > 0)
{
// qDebug()<<"seg type="<<curImg->colla_cur_seg.row[0].type;
// cout << "Send msg success" << endl;
w->TeraflyCommunicator->cur_chno = curImg->cur_chno;
w->TeraflyCommunicator->cur_createmode = curImg->cur_createmode;
w->SetupCollaborateInfo();
w->TeraflyCommunicator->UpdateAddSegMsg(curImg->colla_cur_seg, connectedSegs, "TeraFly", isBegin);
// if(w->TeraflyCommunicator->timer_exit->isActive()){
// w->TeraflyCommunicator->timer_exit->stop();
// }
// w->TeraflyCommunicator->timer_exit->start(2*60*60*1000);
}/*else
{
QMessageBox::information(0,tr("Message "),
tr("Connection Lost!Data has been saved!"),
QMessageBox::Ok);
}*/
}
curImg->update_3drenderer_neuron_view(w, this);

// QFuture<void> future = QtConcurrent::run([=](){
// for(int i=0;i<curImg->tracedNeuron.seg.size();i++){
// curImg->tracedNeuron.seg[i].printInfo();
// }
// });
}
}



#else
v3d_msg("testmain addCurveSWC(vector<XYZ> &loc_list, int chno)");

Expand Down
8 changes: 4 additions & 4 deletions v3d_main/3drenderer/v3dr_glwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ void V3dR_GLWidget::mousePressEvent(QMouseEvent *event)

if (event->button()==Qt::LeftButton)
{
lastPos = event->pos();
lastPos = event->pos() * devicePixelRatio();
t_mouseclick_left = clock();
if(pluginLeftMouseFuncs.find(currentPluginState) != pluginLeftMouseFuncs.end())
{
Expand Down Expand Up @@ -772,9 +772,9 @@ void V3dR_GLWidget::mouseMoveEvent(QMouseEvent *event)

// setFocus(); // accept KeyPressEvent, by RZC 080831

int dx = event->x() - lastPos.x();
int dy = event->y() - lastPos.y();
lastPos = event->pos();
int dx = event->x() * devicePixelRatio() - lastPos.x();
int dy = event->y() * devicePixelRatio() - lastPos.y();
lastPos = event->pos() * devicePixelRatio();

if ((event->buttons() & Qt::RightButton) && renderer) //right-drag for 3d curve
if ( ABS(dx) + ABS(dy) >=2 )
Expand Down
1 change: 1 addition & 0 deletions v3d_main/basic_c_fun/v3d_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ class V3DPluginCallback

virtual NeuronTree getSWC(v3dhandle image_window) = 0;
virtual bool setSWC(v3dhandle image_window, NeuronTree & nt, bool collaborate=false) = 0;
virtual bool setSWC(v3dhandle image_window, V_NeuronSWC_list segments, bool collaborate=false) = 0;

virtual Image4DSimple * loadImage(char *filename) = 0; //2013-08-09. two more functions for simplied calls to use Vaa3D's image loading and saving functions without linking to additional libs
virtual Image4DSimple * loadImage(char *filename, V3DLONG zsliceno) = 0; //2013-11-02. load one single slice from an image, useful when the image is large
Expand Down
60 changes: 56 additions & 4 deletions v3d_main/plugin_loader/v3d_plugin_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1071,13 +1071,65 @@ NeuronTree V3d_PluginLoader::getSWC(v3dhandle image_window)
}
return NeuronTree();
}

bool V3d_PluginLoader::setSWC(v3dhandle image_window, NeuronTree & nt, bool collaborate)
{
if (v3d_mainwindow)
{
if (v3d_mainwindow)
{
// if(TeraflyCommunicator&&TeraflyCommunicator->socket!=nullptr&&TeraflyCommunicator->socket->state()==QAbstractSocket::ConnectedState){
// auto segments = NeuronTree__2__V_NeuronSWC_list(nt);
// for(auto it = segments.seg.begin(); it != segments.seg.end();){
// bool flag = true;
// for(auto row_it = it->row.begin(); row_it != it->row.end(); row_it++){
// if(row_it->x < 0 || row_it->x >= TeraflyCommunicator->ImageMaxRes.x ||
// row_it->y < 0 || row_it->y >= TeraflyCommunicator->ImageMaxRes.y ||
// row_it->z < 0 || row_it->z >= TeraflyCommunicator->ImageMaxRes.z){
// it = segments.seg.erase(it);
// flag = false;
// break;
// }
// }
// if(flag)
// it++;
// }
// NeuronTree newNt = V_NeuronSWC_list__2__NeuronTree(segments);
// return v3d_mainwindow->setSWC(image_window, newNt, collaborate);
// }
// else{
return v3d_mainwindow->setSWC(image_window, nt, collaborate);
}
return false;

}
return false;
}

bool V3d_PluginLoader::setSWC(v3dhandle image_window, V_NeuronSWC_list segments, bool collaborate)
{
if (v3d_mainwindow)
{
if(TeraflyCommunicator&&TeraflyCommunicator->socket!=nullptr&&TeraflyCommunicator->socket->state()==QAbstractSocket::ConnectedState){
for(auto it = segments.seg.begin(); it != segments.seg.end();){
bool flag = true;
for(auto row_it = it->row.begin(); row_it != it->row.end(); row_it++){
if(row_it->x < 0 || row_it->x >= TeraflyCommunicator->ImageMaxRes.x ||
row_it->y < 0 || row_it->y >= TeraflyCommunicator->ImageMaxRes.y ||
row_it->z < 0 || row_it->z >= TeraflyCommunicator->ImageMaxRes.z){
it = segments.seg.erase(it);
flag = false;
break;
}
}
if(flag)
it++;
}
NeuronTree newNt = V_NeuronSWC_list__2__NeuronTree(segments);
return v3d_mainwindow->setSWC(image_window, newNt, collaborate);
}
else{
auto nt = V_NeuronSWC_list__2__NeuronTree(segments);
return v3d_mainwindow->setSWC(image_window, nt, collaborate);
}
}
return false;
}

int V3d_PluginLoader::setSWC_noDecompose(V3dR_MainWindow* window, const char* fileName)
Expand Down
1 change: 1 addition & 0 deletions v3d_main/plugin_loader/v3d_plugin_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ public slots:

virtual NeuronTree getSWC(v3dhandle image_window);
virtual bool setSWC(v3dhandle image_window, NeuronTree & nt, bool collaborate=false);
virtual bool setSWC(v3dhandle image_window, V_NeuronSWC_list segments, bool collaborate=false);

virtual Image4DSimple * loadImage(char *filename); //2013-08-09. two more functions for simplied calls to use Vaa3D's image loading and saving functions without linking to additional libs
virtual Image4DSimple * loadImage(char *filename, V3DLONG zsliceno); //2013-11-02
Expand Down
79 changes: 59 additions & 20 deletions v3d_main/terafly/src/control/CViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1967,53 +1967,92 @@ void CViewer::clearAnnotations()
void CViewer::deleteSelectedMarkers()
{
/**/tf::debug(tf::LEV1, strprintf("title = %s", titleShort.c_str()).c_str(), __itm__current__function__);
qDebug()<<"delete mul selected markers huanglei";

if(PAnoToolBar::instance()->buttonMarkerRoiDelete->isChecked())
{
// associate selected image markers to vaa3d markers and delete
QList<LocationSimple> vaa3dMarkers = V3D_env->getLandmark(window);
QList<LocationSimple> deletedMarkers;
QList<ImageMarker> &listMarker = static_cast<Renderer_gl1*>(view3DWidget->getRenderer())->listMarker;
for (QList<ImageMarker>::iterator it = listMarker.begin(); it!= listMarker.end(); it++)
{
if (it->selected && !CAnnotations::isMarkerOutOfRendererBounds(*it, *this))
// associate selected image markers to vaa3d markers and delete
QList<LocationSimple> vaa3dMarkers = V3D_env->getLandmark(window);
QList<LocationSimple> deletedMarkers;
QList<ImageMarker> &listMarker = static_cast<Renderer_gl1*>(view3DWidget->getRenderer())->listMarker;

vector<CellAPO> tobeSendMarkers;
bool flag = false;
for (QList<ImageMarker>::iterator it = listMarker.begin(); it!= listMarker.end(); it++)
{
if (it->selected && !CAnnotations::isMarkerOutOfRendererBounds(*it, *this))
{
for(QList<LocationSimple>::iterator jt = vaa3dMarkers.begin(); jt != vaa3dMarkers.end();)
{
if(jt->x == it->x && jt->y == it->y && jt->z == it->z)
{
deletedMarkers.push_back(*jt);
RGBA8 color = jt->color;
jt = vaa3dMarkers.erase(jt);

if(view3DWidget->TeraflyCommunicator!=nullptr
&&view3DWidget->TeraflyCommunicator->socket!=nullptr&&view3DWidget->TeraflyCommunicator->socket->state() == QAbstractSocket::ConnectedState)
{
view3DWidget->SetupCollaborateInfo();
CellAPO marker;
marker.x = it->x;
marker.y = it->y;
marker.z = it->z;
marker.color = it->color;
marker.comment = it->comment;
tobeSendMarkers.push_back(marker);
// if(view3DWidget->TeraflyCommunicator->timer_exit->isActive()){
// view3DWidget->TeraflyCommunicator->timer_exit->stop();
// }
// view3DWidget->TeraflyCommunicator->timer_exit->start(2*60*60*1000);
if(std::find(view3DWidget->quality_control_types.begin(), view3DWidget->quality_control_types.end(), it->comment) != view3DWidget->quality_control_types.end()){
flag = true;
view3DWidget->TeraflyCommunicator->checkedQcMarkers.push_back(marker);
}
}

break;
}
else
++jt;
}

it->selected = false;
}

}
}

// set new markers
V3D_env->setLandmark(window, vaa3dMarkers);
V3D_env->pushObjectIn3DWindow(window);
terafly::CViewer::getCurrent()->storeAnnotations();
if(view3DWidget->TeraflyCommunicator!=nullptr
&&view3DWidget->TeraflyCommunicator->socket!=nullptr&&view3DWidget->TeraflyCommunicator->socket->state() == QAbstractSocket::ConnectedState){
view3DWidget->TeraflyCommunicator->UpdateDelMarkersMsg(tobeSendMarkers, "TeraFly");
if(flag){
view3DWidget->TeraflyCommunicator->emitUpdateQcInfo();
view3DWidget->TeraflyCommunicator->emitUpdateQcMarkersCounts();
}
}

// set new markers
V3D_env->setLandmark(window, vaa3dMarkers);
V3D_env->pushObjectIn3DWindow(window);

// update visible markers
PAnoToolBar::instance()->buttonMarkerRoiViewChecked(PAnoToolBar::instance()->buttonMarkerRoiView->isChecked());
// update visible markers
PAnoToolBar::instance()->buttonMarkerRoiViewChecked(PAnoToolBar::instance()->buttonMarkerRoiView->isChecked());


// add Undo action
undoStack.beginMacro("delete markers");
undoStack.push(new QUndoMarkerDeleteROI(this, deletedMarkers));
undoStack.endMacro();
PAnoToolBar::instance()->buttonUndo->setEnabled(true);
// add Undo action
undoStack.beginMacro("delete markers");
undoStack.push(new QUndoMarkerDeleteROI(this, deletedMarkers));
undoStack.endMacro();
PAnoToolBar::instance()->buttonUndo->setEnabled(true);


// need to refresh annotation tools as this Vaa3D's action resets the Vaa3D annotation mode
PAnoToolBar::instance()->refreshTools();
// need to refresh annotation tools as this Vaa3D's action resets the Vaa3D annotation mode
PAnoToolBar::instance()->refreshTools();
}
}


void CViewer::createMarkerAt(int logicX, int logicY)
{
int deviceCoordX = logicX * devicePixelRatio();
Expand Down
Loading

0 comments on commit dee45a6

Please sign in to comment.