diff --git a/src/fgt/filter_physics/MeshSubFilter.cpp b/src/fgt/filter_physics/MeshSubFilter.cpp index aeeff6f81..99267b7d4 100644 --- a/src/fgt/filter_physics/MeshSubFilter.cpp +++ b/src/fgt/filter_physics/MeshSubFilter.cpp @@ -14,6 +14,9 @@ void MeshSubFilter::initParameterSet(QAction* action,MeshDocument& md, RichParam } void MeshSubFilter::initialize(MeshDocument& md, RichParameterSet&, vcg::CallBackPos* cb){ + //TODO: Not working properly with meshlab for now; when the issue will be patched in meshlab, this code and the MM_TRANSFMATRIX + // postCondition in filter_physics.h can be uncommented */ + /*if(md.mm()->cm.Tr != vcg::Matrix44f::Identity()) throw MatrixNotFreezedException();*/ } diff --git a/src/fgt/filter_physics/ODEFacade.cpp b/src/fgt/filter_physics/ODEFacade.cpp index 5d277919f..a2ccc363f 100644 --- a/src/fgt/filter_physics/ODEFacade.cpp +++ b/src/fgt/filter_physics/ODEFacade.cpp @@ -100,7 +100,7 @@ bool ODEFacade::hasBorders(MeshModel& mesh){ } -void ODEFacade::setAsRigidBody(MeshModel& mesh, bool isRigidBody){ +void ODEFacade::setAsRigidBody(MeshModel& mesh, bool isRigidBody) throw(ODEInvalidMeshException) { MeshIterator entry = m_registeredMeshes.find(&mesh); if(entry == m_registeredMeshes.end()) return; diff --git a/src/fgt/filter_physics/ODEFacade.h b/src/fgt/filter_physics/ODEFacade.h index 34084efbb..047765497 100644 --- a/src/fgt/filter_physics/ODEFacade.h +++ b/src/fgt/filter_physics/ODEFacade.h @@ -24,19 +24,58 @@ class ODEFacade{ public: ODEFacade(); + /** + * Registers a mesh to the ODE physics engine. Once registered the mesh will be part of the physics + * simulation and will interact dynamically with other registered meshes. + * \param mesh The mesh to register + * \param scenery If true the mesh is part of the scenery and will act as static environment otherwise it will be set as a rigid body. + */ virtual void registerTriMesh(MeshModel& mesh, bool scenery = false); - virtual void setAsRigidBody(MeshModel& mesh, bool isRigidBody = true); + /** + * Sets an already registered mesh as a rigid body or as part of the static environment + * \param mesh A registered mesh + * \param isRigidBody If true the mesh will be set as rigid body otherwise it will be set as part of the static environment + * \throws ODEInvalidMeshException if a rigid body mesh has borders or has a negative mass (ODE can't handle it) + */ + virtual void setAsRigidBody(MeshModel& mesh, bool isRigidBody = true) throw(ODEInvalidMeshException); + /** + * This method updates meshlab's transformation matrices of all registered meshes. + */ virtual void updateTransform(); + /** + * Returns the transformation matrix of a registered mesh. + */ virtual vcg::Matrix44f getTransformationMatrix(MeshModel& mesh); + /** + * Sets a global force that will act on all registered meshes. + */ virtual void setGlobalForce(float force[3]); + /** + * Sets the number of iterations of the iterative stepping function. + */ virtual void setIterations(int iterations); + /** + * Sets the maximum number of contacts to be generated in a collision of a pair of objects + */ virtual void setMaxContacts(int contacts); + /** + * Sets the bounciness of a contact + */ virtual void setBounciness(float bounciness); + /** + * Sets the coloumb friction coefficient of contact + */ virtual void setFriction(float friction); + /** + * Performs an integration step of simulation + */ virtual void integrate(float step); + /** + * Unregisters all meshes + */ virtual void clear(MeshDocument& md); protected: diff --git a/src/fgt/filter_physics/RandomFillFilter.cpp b/src/fgt/filter_physics/RandomFillFilter.cpp index d294a760a..3b443e012 100644 --- a/src/fgt/filter_physics/RandomFillFilter.cpp +++ b/src/fgt/filter_physics/RandomFillFilter.cpp @@ -24,8 +24,8 @@ void RandomFillFilter::initParameterSet(QAction* action,MeshDocument& md, RichPa par.addParam(new RichMesh("container", 0, &md, "Container mesh", "This mesh will act as a container for the filling mesh")); par.addParam(new RichMesh("filler", 0, &md, "Filler mesh", "The container mesh will be filled with this mesh")); par.addParam(new RichFloat("factor", 0.5f, "Volume ratio factor", "The ratio between the container and the filler object will be multiplied by this factor. The volume ratio determines the number of filling objects to be spawn.")); - par.addParam(new RichFloat("seconds", 0.5f, "Simulation interval (sec)", "Physics simulation update interval in seconds")); - par.addParam(new RichFloat("updateFrequency", 1.f, "Update frequency", "The frequency with which the simulation gets updated")); + par.addParam(new RichFloat("seconds", 1.f, "Simulation interval (sec)", "Physics simulation update interval in seconds")); + par.addParam(new RichFloat("updateFrequency", 1.f, "Update frequency", "The frequency with which the simulation gets updated in case the objects spawn at the center of mass")); par.addParam(new RichBool("flipNormal", false, "Flip container normals", "If true the container normals will be flipped.")); par.addParam(new RichBool("useRandomVertices", true, "Random spawn points", "If true the filling objects will spawn at random positions in the container mesh instead of being spawn at the center of mass")); } @@ -46,7 +46,6 @@ bool RandomFillFilter::applyFilter(QAction* filter, MeshDocument &md, RichParame vcg::tri::Clean::FlipMesh(container->cm); tri::UpdateNormals::PerVertexNormalizedPerFace(container->cm); container->clearDataMask(MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEFLAGBORDER); - par.setValue("flipNormal", BoolValue(false)); // Why does it not work?? } m_engine.clear(md); @@ -84,13 +83,9 @@ bool RandomFillFilter::applyFilter(QAction* filter, MeshDocument &md, RichParame // To refactor when the right algorithm has be found if(par.getBool("useRandomVertices")){ for(int i = 0; i < objects; i++){ - if(cb != 0) (*cb)(98.f*i/objects, "Computing..."); + if(cb != 0) (*cb)(50.f*i/objects, "Computing..."); addRandomObject(md, filler, getRandomOrigin(par), restoredMeshes + i); m_engine.registerTriMesh(*md.getMesh(fillOffset++)); - - /*if(i % frequency == 0) - for(int j = 0; j < par.getFloat("seconds") * par.getInt("fps"); j++) - m_engine.integrate(1.0f/par.getInt("fps"));*/ } for(int j = 0; j < par.getFloat("seconds") * par.getInt("fps"); j++){ if(cb != 0) (*cb)(50 + 48.f*j/(par.getFloat("seconds") * par.getInt("fps")), "Computing..."); @@ -112,6 +107,12 @@ bool RandomFillFilter::applyFilter(QAction* filter, MeshDocument &md, RichParame filler->cm.Tr.SetIdentity(); m_currentFilterType = m_filterType; + if(par.getBool("flipNormal")){ + vcg::tri::Clean::FlipMesh(container->cm); + tri::UpdateNormals::PerVertexNormalizedPerFace(container->cm); + container->clearDataMask(MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEFLAGBORDER); + } + if(cb != 0) (*cb)(99, "Physics renderization of the scene completed..."); return true; } diff --git a/src/fgt/filter_physics/filter_physics.h b/src/fgt/filter_physics/filter_physics.h index 829c31196..9ecb5deff 100644 --- a/src/fgt/filter_physics/filter_physics.h +++ b/src/fgt/filter_physics/filter_physics.h @@ -32,7 +32,7 @@ class FilterPhysics : public QObject, public MeshFilterInterface virtual QString filterInfo(FilterIDType filter) const; virtual int getRequirements(QAction*){return MeshModel::MM_FACEVERT | MeshModel::MM_FACENORMAL | MeshModel::MM_VERTNORMAL | MeshModel::MM_FACEFACETOPO; } - virtual int postCondition( QAction* ) const{return MeshModel::MM_FACENORMAL | MeshModel::MM_TRANSFMATRIX;} + virtual int postCondition( QAction* ) const{return MeshModel::MM_FACENORMAL; /*| MeshModel::MM_TRANSFMATRIX;*/} virtual bool autoDialog(QAction*) {return true;} virtual void initParameterSet(QAction*, MeshDocument&, RichParameterSet&);