diff --git a/src/meshlabplugins/filter_camera/filter_camera.cpp b/src/meshlabplugins/filter_camera/filter_camera.cpp
index 94afccaa5..25df40725 100644
--- a/src/meshlabplugins/filter_camera/filter_camera.cpp
+++ b/src/meshlabplugins/filter_camera/filter_camera.cpp
@@ -36,8 +36,9 @@ FilterCameraPlugin::FilterCameraPlugin()
FP_SET_MESH_CAMERA <<
FP_SET_RASTER_CAMERA <<
FP_QUALITY_FROM_CAMERA <<
- FP_MESHCAMERA_SCALE<<
- FP_RASTERCAMERA_SCALE<<
+ FP_CAMERA_ROTATE<<
+ FP_CAMERA_SCALE<<
+ FP_CAMERA_TRANSLATE<<
FP_CAMERA_EDIT;
foreach(FilterIDType tt , types())
@@ -51,8 +52,9 @@ QString FilterCameraPlugin::filterName(FilterIDType filterId) const
case FP_SET_MESH_CAMERA : return QString("Set Mesh Camera");
case FP_SET_RASTER_CAMERA : return QString("Set Raster Camera");
case FP_QUALITY_FROM_CAMERA : return QString("Vertex Quality from Camera");
- case FP_MESHCAMERA_SCALE : return QString("Scale Mesh Camera");
- case FP_RASTERCAMERA_SCALE : return QString("Scale Raster Camera");
+ case FP_CAMERA_ROTATE : return QString("Transform: Rotate Camera or set of cameras");
+ case FP_CAMERA_SCALE : return QString("Transform: Scale Camera or set of cameras");
+ case FP_CAMERA_TRANSLATE : return QString("Transform: Translate Camera or set of cameras");
case FP_CAMERA_EDIT : return QString("Edit Raster Camera");
default : assert(0);
}
@@ -65,8 +67,9 @@ QString FilterCameraPlugin::filterInfo(FilterIDType filterId) const
case FP_SET_MESH_CAMERA : return QString("This filter allow to set a shot for the current mesh");
case FP_SET_RASTER_CAMERA : return QString("This filter allow to set a shot for the current mesh");
case FP_QUALITY_FROM_CAMERA : return QString("Compute vertex quality using the camera definition, according to viewing angle or distance");
- case FP_MESHCAMERA_SCALE : return QString("Scale the mesh camera");
- case FP_RASTERCAMERA_SCALE : return QString("Scale the raster camera, or all the raster cameras of the project");
+ case FP_CAMERA_ROTATE : return QString("Rotate the camera, or all the cameras of the project. The selected raster is the reference if viewpoint rotation is selected.");
+ case FP_CAMERA_SCALE : return QString("Scale the camera, or all the cameras of the project. The selected raster is the reference if viewpoint scaling is selected.");
+ case FP_CAMERA_TRANSLATE : return QString("Translate the camera, or all the cameras of the project.");
case FP_CAMERA_EDIT : return QString("Allow to edit the current raster camera allowing to tweak intrinsics.");
default : assert(0);
}
@@ -81,12 +84,60 @@ void FilterCameraPlugin::initParameterSet(QAction *action, MeshDocument &/*m*/,
case FP_CAMERA_EDIT :
parlst.addParam(new RichDynamicFloat("fov_scale", 0, -3,3,"Scaling exp", "Exponent of the scaling factor. 0 means no scaling, 1 means 10 times larger, -1 means 1/10."));
break;
- case FP_MESHCAMERA_SCALE :
- parlst.addParam(new RichFloat("scale", 1.0, "Scale factor", "The scale factor that has to be applied to the camera"));
+ case FP_CAMERA_ROTATE :
+ {
+ QStringList shotType;
+ shotType.push_back("Raster Camera");
+ shotType.push_back("Mesh Camera");
+ parlst.addParam(new RichEnum("camera", 0, shotType, tr("Camera type"), tr("Choose the camera to scale")));
+ QStringList rotMethod;
+ rotMethod.push_back("X axis");
+ rotMethod.push_back("Y axis");
+ rotMethod.push_back("Z axis");
+ rotMethod.push_back("custom axis");
+ parlst.addParam(new RichEnum("rotAxis", 0, rotMethod, tr("Rotation on:"), tr("Choose a method")));
+ QStringList rotCenter;
+ rotCenter.push_back("origin");
+ rotCenter.push_back("camera viewpoint");
+ rotCenter.push_back("custom point");
+ parlst.addParam(new RichEnum("rotCenter", 0, rotCenter, tr("Center of rotation:"), tr("Choose a method")));
+ parlst.addParam(new RichDynamicFloat("angle",0,-360,360,"Rotation Angle","Angle of rotation (in degree). If snapping is enable this vaule is rounded according to the snap value"));
+ parlst.addParam(new RichPoint3f("customAxis",Point3f(0,0,0),"Custom axis","This rotation axis is used only if the 'custom axis' option is chosen."));
+ parlst.addParam(new RichPoint3f("customCenter",Point3f(0,0,0),"Custom center","This rotation center is used only if the 'custom point' option is chosen."));
+ parlst.addParam(new RichBool ("toallRaster", false, "Apply to all Raster layers", "Apply the same scaling to all the Raster layers: it is taken into account only if 'Raster Camera' is selected"));
+ parlst.addParam(new RichBool ("toall", false, "Apply to all Raster and Mesh layers", "Apply the same scaling to all the layers, including any 3D layer"));
+ }
break;
- case FP_RASTERCAMERA_SCALE :
+ case FP_CAMERA_SCALE :
+ {
+ QStringList shotType;
+ shotType.push_back("Raster Camera");
+ shotType.push_back("Mesh Camera");
+ parlst.addParam(new RichEnum("camera", 0, shotType, tr("Camera type"), tr("Choose the camera to scale")));
+ QStringList scaleCenter;
+ scaleCenter.push_back("origin");
+ scaleCenter.push_back("camera viewpoint");
+ scaleCenter.push_back("custom point");
+ parlst.addParam(new RichEnum("scaleCenter", 0, scaleCenter, tr("Center of scaling:"), tr("Choose a method")));
+ parlst.addParam(new RichPoint3f("customCenter",Point3f(0,0,0),"Custom center","This scaling center is used only if the 'custom point' option is chosen."));
parlst.addParam(new RichFloat("scale", 1.0, "Scale factor", "The scale factor that has to be applied to the camera"));
- parlst.addParam(new RichBool ("toall", false, "Apply to all Raster layers", "Apply the same scaling to all the Raster layers"));
+ parlst.addParam(new RichBool ("toallRaster", false, "Apply to all Raster layers", "Apply the same scaling to all the Raster layers: it is taken into account only if 'Raster Camera' is selected"));
+ parlst.addParam(new RichBool ("toall", false, "Apply to all Raster and Mesh layers", "Apply the same scaling to all the layers, including any 3D layer"));
+ }
+ break;
+ case FP_CAMERA_TRANSLATE :
+ {
+ QStringList shotType;
+ shotType.push_back("Raster Camera");
+ shotType.push_back("Mesh Camera");
+ parlst.addParam(new RichEnum("camera", 0, shotType, tr("Camera type"), tr("Choose the camera to scale")));
+ parlst.addParam(new RichDynamicFloat("axisX",0,-1000,1000,"X Axis","Absolute translation amount along the X axis"));
+ parlst.addParam(new RichDynamicFloat("axisY",0,-1000,1000,"Y Axis","Absolute translation amount along the Y axis"));
+ parlst.addParam(new RichDynamicFloat("axisZ",0,-1000,1000,"Z Axis","Absolute translation amount along the Z axis"));
+ parlst.addParam(new RichBool("centerFlag",false,"translate viewpoint position to the origin","If selected, the camera viewpoint is translated to the origin"));
+ parlst.addParam(new RichBool ("toallRaster", false, "Apply to all Raster layers", "Apply the same scaling to all the Raster layers: it is taken into account only if 'Raster Camera' is selected"));
+ parlst.addParam(new RichBool ("toall", false, "Apply to all Raster and Mesh layers", "Apply the same scaling to all the layers, including any 3D layer"));
+ }
break;
case FP_SET_RASTER_CAMERA :
parlst.addParam(new RichShotf ("Shot", defShot, "New shot", "This filter allow to set a shot for the current raster."));
@@ -112,20 +163,210 @@ bool FilterCameraPlugin::applyFilter(QAction *filter, MeshDocument &md, RichPara
RasterModel *rm = md.rm();
switch(ID(filter))
{
- case FP_MESHCAMERA_SCALE :
+ case FP_CAMERA_ROTATE :
{
- float scale = par.getFloat("scale");
- cm.shot.RescalingWorld(scale);
- }
- case FP_RASTERCAMERA_SCALE :
- {
- float scale = par.getFloat("scale");
- if (!par.getBool("toall"))
- rm->shot.RescalingWorld(scale);
- else
+ Matrix44f trRot; trRot.SetIdentity();
+ Point3f axis, tranVec;
+ Matrix44f trTran,trTranInv;
+
+ switch(par.getEnum("rotAxis"))
+ {
+ case 0: axis=Point3f(1,0,0); break;
+ case 1: axis=Point3f(0,1,0);break;
+ case 2: axis=Point3f(0,0,1);break;
+ case 3: axis=par.getPoint3f("customAxis");break;
+ }
+ switch(par.getEnum("rotCenter"))
+ {
+ case 0: tranVec=Point3f(0,0,0); break;
+ case 1: {
+ switch(par.getEnum("camera"))
+ {
+ case 0: tranVec=rm->shot.Extrinsics.Tra();
+ break;
+ case 1: tranVec=cm.shot.Extrinsics.Tra();
+ }
+ }
+ break;
+ case 2: tranVec=par.getPoint3f("customCenter");break;
+ }
+
+ float angleDeg= par.getDynamicFloat("angle");
+
+ trRot.SetRotateDeg(angleDeg,axis);
+ trTran.SetTranslate(tranVec);
+ trTranInv.SetTranslate(-tranVec);
+ //cm.Tr=trTran*trRot*trTranInv;
+ Matrix44f transf=trTran*trRot*trTranInv;
+ if (par.getBool("toall"))
+ {
+ for (int i=0; icm.Tr=transf;
+ tri::UpdatePosition::Matrix(md.meshList[i]->cm, md.meshList[i]->cm.Tr);
+ tri::UpdateNormals::PerVertexMatrix(md.meshList[i]->cm,md.meshList[i]->cm.Tr);
+ tri::UpdateNormals::PerFaceMatrix(md.meshList[i]->cm,md.meshList[i]->cm.Tr);
+ tri::UpdateBounding::Box(md.meshList[i]->cm);
+ md.meshList[i]->cm.Tr.SetIdentity();
+ md.meshList[i]->cm.shot.ApplyRigidTransformation(transf);
+
+ }
+ for (int i=0; ishot.ApplyRigidTransformation(transf);
+
+ }
+ }
+ else if (par.getBool("toallRaster") && (par.getEnum("camera")==0))
{
for (int i=0; ishot.RescalingWorld(scale);
+ {
+ md.rasterList[i]->shot.ApplyRigidTransformation(transf);
+
+ }
+ }
+ else switch(par.getEnum("camera"))
+ {
+ case 0:
+ {
+ rm->shot.ApplyRigidTransformation(transf);
+ }
+ case 1:
+ {
+ cm.shot.ApplyRigidTransformation(transf);
+ }
+ }
+ }
+ break;
+ case FP_CAMERA_SCALE :
+ {
+ Matrix44f trScale; trScale.SetIdentity();
+ Point3f tranVec;
+ Matrix44f trTran,trTranInv;
+
+ float Scale= par.getFloat("scale");
+ trScale.SetScale(Scale,Scale,Scale);
+
+ switch(par.getEnum("scaleCenter"))
+ {
+ case 0: tranVec=Point3f(0,0,0); break;
+ case 1:
+ {
+ switch(par.getEnum("camera"))
+ {
+ case 0: tranVec=rm->shot.Extrinsics.Tra();
+ break;
+ case 1: tranVec=cm.shot.Extrinsics.Tra();
+ }
+ }
+ break;
+ case 2: tranVec=par.getPoint3f("customCenter");break;
+ }
+
+ trTran.SetTranslate(tranVec);
+ trTranInv.SetTranslate(-tranVec);
+ if (par.getBool("toall"))
+ {
+ for (int i=0; icm.Tr=trTran*trScale*trTranInv;
+ tri::UpdatePosition::Matrix(md.meshList[i]->cm, md.meshList[i]->cm.Tr);
+ tri::UpdateNormals::PerVertexMatrix(md.meshList[i]->cm,md.meshList[i]->cm.Tr);
+ tri::UpdateNormals::PerFaceMatrix(md.meshList[i]->cm,md.meshList[i]->cm.Tr);
+ tri::UpdateBounding::Box(md.meshList[i]->cm);
+ md.meshList[i]->cm.Tr.SetIdentity();
+ md.meshList[i]->cm.shot.ApplyRigidTransformation(trTran);
+ md.meshList[i]->cm.shot.RescalingWorld(trScale[0][0]);
+ md.meshList[i]->cm.shot.ApplyRigidTransformation(trTranInv);
+
+ }
+ for (int i=0; ishot.ApplyRigidTransformation(trTran);
+ md.rasterList[i]->shot.RescalingWorld(trScale[0][0]);
+ md.rasterList[i]->shot.ApplyRigidTransformation(trTranInv);
+ }
+ }
+ else if (par.getBool("toallRaster") && (par.getEnum("camera")==0))
+ {
+ for (int i=0; ishot.ApplyRigidTransformation(trTran);
+ md.rasterList[i]->shot.RescalingWorld(trScale[0][0]);
+ md.rasterList[i]->shot.ApplyRigidTransformation(trTranInv);
+ }
+ }
+ else switch(par.getEnum("camera"))
+ {
+ case 0:
+ {
+ rm->shot.ApplyRigidTransformation(trTran);
+ rm->shot.RescalingWorld(Scale);
+ rm->shot.ApplyRigidTransformation(trTranInv);
+ }
+ case 1:
+ {
+ cm.shot.ApplyRigidTransformation(trTran);
+ cm.shot.RescalingWorld(Scale);
+ cm.shot.ApplyRigidTransformation(trTranInv);
+ }
+ }
+ }
+ break;
+ case FP_CAMERA_TRANSLATE :
+ {
+ Matrix44f trTran; trTran.SetIdentity();
+
+ float xScale= par.getDynamicFloat("axisX");
+ float yScale= par.getDynamicFloat("axisY");
+ float zScale= par.getDynamicFloat("axisZ");
+
+ trTran.SetTranslate(xScale,yScale,zScale);
+ if(par.getBool("centerFlag"))
+ switch(par.getEnum("camera"))
+ {
+ case 0: trTran.SetTranslate(-rm->shot.Extrinsics.Tra());
+ break;
+ case 1: trTran.SetTranslate(-cm.shot.Extrinsics.Tra());
+ }
+
+ if (par.getBool("toall"))
+ {
+ for (int i=0; icm.Tr=trTran;
+ tri::UpdatePosition::Matrix(md.meshList[i]->cm, md.meshList[i]->cm.Tr);
+ tri::UpdateNormals::PerVertexMatrix(md.meshList[i]->cm,md.meshList[i]->cm.Tr);
+ tri::UpdateNormals::PerFaceMatrix(md.meshList[i]->cm,md.meshList[i]->cm.Tr);
+ tri::UpdateBounding::Box(md.meshList[i]->cm);
+ md.meshList[i]->cm.Tr.SetIdentity();
+ md.meshList[i]->cm.shot.ApplyRigidTransformation(trTran);
+
+ }
+ for (int i=0; ishot.ApplyRigidTransformation(trTran);
+
+ }
+ }
+ else if (par.getBool("toallRaster") && (par.getEnum("camera")==0))
+ {
+ for (int i=0; ishot.ApplyRigidTransformation(trTran);
+
+ }
+ }
+ else switch(par.getEnum("camera"))
+ {
+ case 0:
+ {
+ rm->shot.ApplyRigidTransformation(trTran);
+ }
+ case 1:
+ {
+ cm.shot.ApplyRigidTransformation(trTran);
+ }
}
}
break;
@@ -191,8 +432,9 @@ int FilterCameraPlugin::postCondition(QAction * filter) const
switch (ID(filter))
{
case FP_SET_MESH_CAMERA :
- case FP_MESHCAMERA_SCALE : return MeshModel::MM_CAMERA;
- case FP_RASTERCAMERA_SCALE : return MeshModel::MM_CAMERA;
+ case FP_CAMERA_ROTATE :
+ case FP_CAMERA_TRANSLATE :
+ case FP_CAMERA_SCALE : return MeshModel::MM_CAMERA;
case FP_QUALITY_FROM_CAMERA : return MeshModel::MM_VERTQUALITY + MeshModel::MM_VERTCOLOR;
default : return MeshModel::MM_UNKNOWN;
}
@@ -202,8 +444,9 @@ int FilterCameraPlugin::postCondition(QAction * filter) const
{
switch(ID(a))
{
- case FP_MESHCAMERA_SCALE :
- case FP_RASTERCAMERA_SCALE :
+ case FP_CAMERA_ROTATE :
+ case FP_CAMERA_SCALE :
+ case FP_CAMERA_TRANSLATE :
case FP_CAMERA_EDIT :
case FP_SET_MESH_CAMERA :
case FP_SET_RASTER_CAMERA :
diff --git a/src/meshlabplugins/filter_camera/filter_camera.h b/src/meshlabplugins/filter_camera/filter_camera.h
index d85975400..8d142e601 100644
--- a/src/meshlabplugins/filter_camera/filter_camera.h
+++ b/src/meshlabplugins/filter_camera/filter_camera.h
@@ -37,8 +37,9 @@ public:
enum { FP_SET_MESH_CAMERA,
FP_SET_RASTER_CAMERA,
FP_QUALITY_FROM_CAMERA,
- FP_MESHCAMERA_SCALE,
- FP_RASTERCAMERA_SCALE,
+ FP_CAMERA_ROTATE,
+ FP_CAMERA_SCALE,
+ FP_CAMERA_TRANSLATE,
FP_CAMERA_EDIT};
FilterCameraPlugin();