[#7698] Bug in 3D object adjustment function

Please log in

State: more information
Open
Date:
2014-10-07 00:12
Priority: more information
3
Submitted By:
Hanbo Chen (cojoc)
Assigned To: more information
Nobody (None)
Hardware: 
None
Product: 
None
Operating System: 
None
Component: 
None
Version: 
None
Severity: 
None
Resolution: 
None
Summary: more information
Bug in 3D object adjustment function

Detailed description

Bug description:
Right click on 3D object in the 3D view => lock scene and adjust the object

1.
The rotation function does not function properly on windows 7. The object rotates too "fast". See attachment 1 and 2. Checked the code, it is likely to be caused by the large single step of QDial. The single step is 16 by default (min 0, max 5760).

Add following in surfaceobj_geometry_dialog.cpp can solve the problem:
dial_x->setRange(0, 360);
dial_y->setRange(0, 360);
dial_z->setRange(0, 360);

dial_x->setSingleStep(1);
dial_y->setSingleStep(1);
dial_z->setSingleStep(1);

2.
Reset button only reset the parameters. However, the adjusted object will not be reset (should also be reset, right?).

reset() function may need to be adjusted to correct this.

3.
After rotation in pop up window, if click Cancel directly, the 3D view will show improperly - the object is rotated while the boundary of the 3D object is not refreshed (see attachment 3). After clicking Cancel, should reset the adjustment first, then quite dialog.

The code looks good. I am still looking at the reason that causes this problem.

Hanbo

Response

Message

Date: 2014-10-13 18:54
Sender: Hanbo Chen

Just found a new potential bug that is not very obvious in this function.

When perform global scale, the center of the object in the scale direction will be moved. However, this value is not updated in the code:

void SurfaceObjGeometryDialog::gscale_x(double s)
{
if (p_tree)
{
last_val = cur_gscale_x*1000; cur_op = SOG_GSCALE_X;
// if (pushButton_undo_last->text()=="Redo one step") pushButton_undo_last->setText("Undo one step");

#ifdef B_USE_NEGATIVE_SCALING
if (s<0.0001 && s>=0) {s=0.0001; QMessageBox::warning(0, "invalid value input", "You have entered a very small value which is not allowed. V3D will just use 0.0001 to replace it.");}
else if (s<0 && s>-0.0001) {s=-0.0001; QMessageBox::warning(0, "invalid value input", "You have entered a very small value which is not allowed. V3D will just use -0.0001 to replace it.");}
#endif
proc_neuron_gmultiply_factor(p_tree, s/(cur_gscale_x*1000), 1, 1);
cur_gscale_x = s/1000.0;
}
if (p_apo)
{
last_val = cur_gscale_x*1000; cur_op = SOG_GSCALE_X;
// if (pushButton_undo_last->text()=="Redo one step") pushButton_undo_last->setText("Undo one step");
#ifdef B_USE_NEGATIVE_SCALING
if (s<0.0001 && s>=0) {s=0.0001; QMessageBox::warning(0, "invalid value input", "You have entered a very small value which is not allowed. V3D will just use 0.0001 to replace it.");}
else if (s<0 && s>-0.0001) {s=-0.0001; QMessageBox::warning(0, "invalid value input", "You have entered a very small value which is not allowed. V3D will just use -0.0001 to replace it.");}
#endif
proc_apo_gmultiply_factor(p_apo, s/(cur_gscale_x*1000), 1, 1);
cur_gscale_x = s/1000.0;
}
POST_3DVIEWER_updateGL
}

Need to add following:
cur_cx*=s/(cur_gscale_x*1000);


Date: 2014-10-09 21:44
Sender: Hanbo Chen

New finding on bug 2 and 3, it seems to be caused by the copy() function of neuron tree:

void copy(const NeuronTree & p)
{
n=p.n; color=p.color; on=p.on; selected=p.selected; name=p.name; comment=p.comment;
listNeuron = p.listNeuron;
hashNeuron = p.hashNeuron;
file = p.file;
editable = p.editable;
linemode = p.linemode;
}

Though we have made a copy of neuron before operation. In the copy() function, it seems did not create a new instant for the items in listNueron. That is, the items in listNeuron in backup neuron and the original neuron that is under operation points to the same memory. Thus, when we change the geometry of one neuron, we are also changing the backup neuron.


Date: 2014-10-08 22:51
Sender: Hanbo Chen

For the first bug, I found that the problem is not there.

The problem is the usage of MY_ANGLE_TICK

My guess is that, the usage of MY_ANGLE_TICK is to increase the accuracy of qtdial since it only allows int format.

However, the previous code works in the opposite direction - instead of increase the accuracy, it increased the step of each movement. E.g. if the value returned by qtdial increased 1, then the angle will increase 1*MY_ANGLE_TICK, and MY_ANGLE_TICK is set to be 16 here
surfaceobj_geometry_dialog.cpp:
d->setSingleStep(1 * MY_ANGLE_TICK);
d->setPageStep(10 * MY_ANGLE_TICK);

Actually, the rotation dial for 3D view in 3Dmainwindow also have similar issue:
v3dr_control_signal.cpp:
slider->setSingleStep(1 * ANGLE_TICK);
slider->setPageStep(10 * ANGLE_TICK); 
But since "#define ANGLE_TICK 1 //divided" here, the problem is not that obvious. 

Attached Files:

Name Download
c1.PNG Download
c2.PNG Download
c3.PNG Download

Changes:

Field Old Value Date By
New Message2014-10-13 18:54cojoc
New Message2014-10-09 21:44cojoc
New Message2014-10-08 22:51cojoc
File Added723: c3.PNG2014-10-07 00:12cojoc
File Added722: c2.PNG2014-10-07 00:12cojoc
File Added721: c1.PNG2014-10-07 00:12cojoc