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();