22 October 2020 at 0 h 53 min #17438
Can anyone help me with the meaning of variable CollisionElement and CollisionModel? From what I am understanding, the CollisionElement refers to the unit like point, edge, triangle and CollisionModel refers to bounding volume? The explanation either in the documentation or code comments is vague. Can anyone give me more details about these two variables?
The problem I have currently is that I don’t know how to extract the indices position. For example, if an edge intersects with a triangle, how to know the position of points and vertices on the edge and triangle? I found in BruteForceDetection it uses CollisionElementIterator to switch the element. But the CollisionELementIterator only indicates the address not exact value.
Do you have any suggestion to help me understand when go through the code? Really appreciate for your help.
Ben30 October 2020 at 15 h 24 min #17498
Good question, it’s nice to see you digging in the code.
CollisionElement in SOFA is implementing : CollisionElementIterator. From the API documentation, you can read that : you can think of a CollisionElementIterator as a glorified pointer to a collision element. It is only there to create a reference to it, not to actual contain its data. Classes derived from TCollisionElementIterator does not store any data, but just provide methods allowing to access the additionnal data stored inside the derived CollisionModel. For instance, the Cube class adds the minVect() / maxVect() methods to retrieve the corners of the cube, however this data is not stored inside Cube, instead it is stored inside the CubeData class within CubeModel.
CollisionModel is the model describing the kind of primitives which will be used for the collision: line (edge), triangle, quad, tet, capsule, cylinder etc.
To see how collision information is stored, you can have a look to the ContactListener for instance. You will notice how maps are created, storing information relate to object1 and object2 involved in the collision.
Hugo20 November 2020 at 3 h 21 min #17771
Sorry for late reply and thanks for the explanation.
I have sort of figuring out the usage of CollisionElemenIterator. But there is another problem appears. My collision algorithm requires to compare the node positions in previous frame and current frame. Does SOFA store all nodes’ old positions? From what I have seen in Intersection either BaseProximityIntersection or other intersection methods, none of then applied the node position from previous. All of them are using current position to detect the collision. Could you give me some advice on this one?
Ben4 December 2020 at 23 h 32 min #17942
Great to read that you are heading towards more and more complicated stuff! Congrats.
in EulerImplicit or EulerExplicit, dofs of previous time steps (i.e. “old positions”) are not stored in the MechanicalObject.
However, you can create your own integration scheme (ODESolver), add a vector and store at each time steps the previous position in this vector.
How to do it would you ask? You can see an example in the RungeKutta4Solver.
The C++ code looks like this:
// Allocate auxiliary vectors MultiVecDeriv oldPos(&vop); .. oldPos.eq(pos); .. //then the usual time integration
I hope this helps.
Hugo23 January 2021 at 22 h 19 min #18380
Sorry for the late update. I have tried your method, but it seems if I need to use the old position in the collision detection, calling the position from solver is hard to make for me. From what I found, the solver updated every time before the collision detection is triggered.
So I am trying to add additional function in BruteForceDetection (my version) to store the old position. I want to store the position along with point index, so that I can compare old position and current position based on the index. The code I am using to get the position is
core::behavior::MechanicalState<defaulttype::Vec3Types>* mstate = mstate = dynamic_cast< behavior::MechanicalState< defaulttype::Vec3Types >* >(getContext()->getMechanicalState());Then call the position by using
mstate->read(core::ConstVecCoordId::position())->getValue(). However, the mstate in BruteForceDetection return null (0x0). Can I ask if I am using the right statement?
Also, I have noticed in TriangleModel.h or other collision model head files. The statement for returning a point position is
model->mstate->read(core::ConstVecCoordId::position())->getValue()[(*(model->tetra))[index]];Can I ask if I want to return all the points position in the object, how I should do?
Really appreciate your support.
Ben5 February 2021 at 9 h 06 min #18512
My earlier suggestion (in the solver) will have as a consequence to add a “state” vector in the MechanicalObject. Thus you could access the previous pos when accessing the Mechanical object.
Your solution could work as well, to save it locally in the Collision pipeline. Using the getContext, you are looking into the node of your BruteForceDetection if you can find a MechanicalState< defaulttype::Vec3Types >. You might instead, define SingleLink so that you could simply indicates which MechanicalObject you would like to access. You can find plenty examples of Link in SOFA, e.g. in TetrahedronHyperelasticityFEMForceField.h.
I hope this helps.
Hugo7 February 2021 at 0 h 49 min #18548
Very appreciate your help. It solves my problem.
- You must be logged in to reply to this topic.