Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solving mesh collision #263

Merged
merged 40 commits into from
Dec 27, 2023
Merged

Solving mesh collision #263

merged 40 commits into from
Dec 27, 2023

Conversation

sophietheis
Copy link
Collaborator

Solve mesh collision in 2D.
Fix issue #261 & #262.
Update readme.md

Copy link
Member

@glyg glyg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot @sophietheis

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
tyssue/collisions/solvers.py Outdated Show resolved Hide resolved
tyssue/topology/base_topology.py Outdated Show resolved Hide resolved
@sophietheis
Copy link
Collaborator Author

Is there a place in tyssue to check if a polygon does not "self-crossing" ? like this one :
image

@glyg
Copy link
Member

glyg commented Nov 14, 2022

Is there a place in tyssue to check if a polygon does not "self-crossing" ? like this one :

Nope .. That would also be a good addition!
An algo here: https://europepmc.org/article/PMC/3660981

README.md Show resolved Hide resolved
tyssue/collisions/solvers.py Show resolved Hide resolved
angle_e = pd.concat([angle_e.iloc[pos_s:], angle_e.iloc[:pos_s]])

angle_e = pd.concat([angle_e, angle_e.iloc[[0]]])
angle_e.iloc[-1]['angle'] += 360
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+= 2*np.pi

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can vectorize all that by sorting all the edges over the whole edge_df with reset_index(ordered=True) and then computing the angle everywhere?

Maybe I am not understanding something, but in your implementation, is there not a problem if a face is not convex?

rect2401

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, indeed it will cause problem if face is not convex. I hadn't thought about it...
But I try to implement the algorithm from the paper you send, but must have something that I don't get because it didn't work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well I think this only limits us to "star convex" cells, which is not so bad (the cell we see here is not very physiological).
Maybe we can live with that for the moment (with a warning in the doc)?
But in this case I think your alog boils down to:

angle = np.arctan2(
   sheet.edge_df["dy"],
   sheet.edge_df["dx"]
)
to_flip = sheet.edge_df[angle < 0, ["srce", "trgt"]]

(
   sheet.vert_df[to_flip["srce"].to_numpy(), ["x", "y"]], 
   sheet.vert_df[to_flip["trgt"].to_numpy(), ["x", "y"]] 
) = (
   sheet.vert_df[to_flip["trgt"].to_numpy(), ["x", "y"]], 
   sheet.vert_df[to_flip["srce"].to_numpy(), ["x", "y"]] 
)

As we just flip the negative angles (i.e. the red arrow on the drawing above)




Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, in fact I have a very strange behavior if I use reset_index(ordered=True): vertex stop moving.
They are supposed to move because when I plot forces, I see big arrow forces for a few vertex. And if I apply find_energy_min without collisions, vertex moves again...
I really don't know what append to "block" vertex movement...
So for now I will keep the code that work, and focus on why sometime tissue is out of control.... 😒
image

tyssue/collisions/solvers.py Outdated Show resolved Hide resolved
tyssue/collisions/solvers.py Outdated Show resolved Hide resolved
tyssue/core/objects.py Show resolved Hide resolved
@sophietheis
Copy link
Collaborator Author

Got an idea that I will test in the next commits, to not use CGAL to detect/fix collision. If it works it will be used as an effector.
Switch in french for the explanation...
L'idée est d'entourer la cellule d'un "champs de force" qui va repousser les vertex pour qu'ils ne pénétrent pas la cellule.
Ainsi, on définit un champ de force générique comme celui là par exemple
image
On crop ce champ pour qu'il s'adapte à chaque cellule, pour qu'il y ai une action seulement si un vertex se trouve à l'intérieur de la cellule
image

A ce stade, on a un champ de force par cellule (a voir plus tard, mais ca risque de poser problème pour des "gros tissus", et quand on passera en 3D...).
Ensuite, pour chaque vertex, on additionne les champs de force de toutes les cellules, sauf les cellules qui contiennent le vertex. On récupère la valeur du gradient à la position du vertex. Et on fait la descente de gradient avec les autres effecteurs du modèle.
C'est l'idée générale, à voir si ca fonctionne...

@sophietheis
Copy link
Collaborator Author

Good news, it works ! ✌️ 💪
As you can see here, there is no self-intersection !
image

I don't think it requires a lot of execution time to be performed, compare to the previous method, which can take quite long time to solve intersection.
It still need some work on it (choose field profile, move gradient calculation into effectors...).
And I think, this method can be extend to 2.5D and 3D more easily than with the CGAL method... But this is for the future, stay focus on 2D for now 😉

@glyg
Copy link
Member

glyg commented Nov 29, 2022

Great, congrats,

I'll try to test/revise it soon, I have a PR to submit on my side also :)

Surface mesh create wasn't create all faces. Now it is fixed. 
Also : -add two methods to Mesh to list faces and vertices. 
           -generalised coordinates
           -add `write_polygon_mesh` to export mesh into .ply to visualised with blinder
Add class to solve collision in 2D or in 3D. 
3D collision solver need to be fixed
Add `How to cite` section
Add `Geometry` section
Add `Publications` section
Update bibliography link
Unable to make this algo works... https://europepmc.org/article/PMC/3660981
Use ordered vertices and their angle position.
     -> uncrossed face : angles are monotonically increasing
     -> crossed face : angles are not monotonically increasing
Need to recalculate angle_e for twisted face
One fix which is only suitable for 2D lateral sheet...
@glyg
Copy link
Member

glyg commented Jan 3, 2023

les test de topologie passent je pense avec mes derniers patchs
Pour les collisions, est-ce que tu as ajouté un test pour ton code?

@sophietheis
Copy link
Collaborator Author

Okay, je vais verifier que je n'ai pas écrasé certaines de tes modif en faisant le git rebase.
Non, je n'ai pas encore ajouté de test pour mon code. Je vais le faire en meme temps. Je vais vérifier aussi qu'il y a un warning sur l'ancienne méthode de résolution de collision pour dire qu'elle ne marche pas très bien...

Remove collisions tests
Fix method call in meshes test
Comment "update_repulstion" method in planar geometry
@sophietheis
Copy link
Collaborator Author

Les tests sont fixés.
Mais avant d'écrire les tests pour la résolution des collisions, peut-être qu'il faut qu'on voit ensemble si je modifie la façon dont c'est implémentée.
Notamment le fait que j'ajoute deux colonnes dans vert_df qui contient des matrices. Ce qui alourdit le dataframe, ralentit certaines executions et en plus peut casser quelques appels de fonction (np.isfinite(sheet.vert_df)) par exemple)...
Je pense qu'il vaudrait mieux que je modifie dès maintenant la façon dont c'est fait. Mais je pense que c'est mieux qu'on voit ensemble qu'elle pourrait être la meilleure implémentation.

@glyg
Copy link
Member

glyg commented Jan 3, 2023

ok, je regarde comment tu as écrit tout ça et je te fais un retour

@sophietheis sophietheis force-pushed the meshCollision branch 2 times, most recently from 5d51b61 to 181edcd Compare May 16, 2023 09:13
@sophietheis
Copy link
Collaborator Author

Salut,
Je viens de voir qu'il y a un message en haut de la pull request, je n'ai pas eu de notif, donc je ne sais pas depuis combien de temps il est là...
Il y a une instabilité que je n'arrive pas à régler. J'ai une oscillation d'utilisation de la mémoire, qui est de plus en plus grande. Le problème vient de update_repulsion et j'espère que j'ai réussi à trouver une façon de le fixer.
Screenshot from 2023-06-22 13-51-38
Screenshot from 2023-06-22 16-38-36

Maintenant, j'ai aussi un autre endroit qui à un certain moment, j'ai l'impression de manière aléatoire, utilise toute ma mémoire (encore un problème de mémoire) et le notebook plante. Je suis en train de chercher d'où ca vient, mais c'est compliqué à debugguer, parce que ca ne veut se produire que lorsque je ne suis pas devant l'ordinateur... --'

Sophie

@glyg glyg mentioned this pull request Dec 27, 2023
7 tasks
@glyg glyg changed the base branch from master to main December 27, 2023 23:14
@glyg glyg changed the base branch from main to release December 27, 2023 23:39
@glyg
Copy link
Member

glyg commented Dec 27, 2023

Hi @sophietheis , I am finally working on releasing tyssue 1.0

I am merging everything this as is, feel free to push your latest updates!

Best
G

@glyg glyg merged commit b78f2d9 into DamCB:release Dec 27, 2023
glyg added a commit that referenced this pull request Jan 10, 2024
* dependency

* Update history.py

> Added the self.time_stamps() method code for HistoryHdf5 class into the __init__() method so that time_stamps are only calculated once as self._time_stamps
> Edited self.time_stamps() method to return self._time_stamps
> Greatly improves efficiency of retrieve() method as time_stamps is not computed each time a new time-point is loaded.

* Solving mesh collision (#263)

* Fix for Issues #261 - cell division failed at the border

* Fix Mesh creation

Surface mesh create wasn't create all faces. Now it is fixed. 
Also : -add two methods to Mesh to list faces and vertices. 
           -generalised coordinates
           -add `write_polygon_mesh` to export mesh into .ply to visualised with blinder

* Add 2D collision solver

Add class to solve collision in 2D or in 3D. 
3D collision solver need to be fixed

* Update README.md

Add `How to cite` section
Add `Geometry` section
Add `Publications` section
Update bibliography link

* Generalised wich vertex penetrate face

* Attempt to set out particular cases

* Detect and fix self-crossing face

Unable to make this algo works... https://europepmc.org/article/PMC/3660981
Use ordered vertices and their angle position.
     -> uncrossed face : angles are monotonically increasing
     -> crossed face : angles are not monotonically increasing

* Use `.apply()` 

Need to recalculate angle_e for twisted face
One fix which is only suitable for 2D lateral sheet...

* ENH: write `mean_XX` method in `Epithelium` class (Issue #224)

* Fix according to comments

* Fix Issue #258 ax argument not considered in `plt_draw.sheet_view`

* ENH: pass column name to `data_at_opposite` issue (#245)

* Add publication and remove bibtex reference

* Add check face convexity

* Use reset_index and code simplification

* yAdd to_mesh function (issue #221) and some test

* Remove the use of reset_index in face_self_intersect

* use ipv_draw with 2D data

* Fix solution after detection point inside polygon

* Remove solving collision for 2 same face...

* Abord vertex displacement if it creates twisted face

* New way to calculate the position of "penetrate" vertices

For now, it is the best way to fix collision (compare to what I tried before). So when a vertex is inside an other face. It is pullback by 10% of the length of the ([v-f1]+[v-f2]/2). with v, f1, f2 position of vertices and center of face 1 and face 2, which are the faces to which the vertex belongs.  It is not perfect and very arbitrary for now, but it avoids vertex displacement at strange place.

* WIP - use force field to fix collision

* Small fix

* Remove function duplication due to circular import

* Calculate "repulsion" gradient in the effector method. Remove loop

* Fix tests

Remove collisions tests
Fix method call in meshes test
Comment "update_repulstion" method in planar geometry

* Add lateralsheet shapes + test

* Update publication + add collapse texte

* Add test for Repulsion effector

* Add test update repulsion

* Remove unused import

* Add `drop_face` to allow hole (issues #220 and #141) (associate #221)

* Update readme.md

* Update publications in README.md

* Add `lineage` attribute to `Epithelium`

In order to keep track of cell lineage

* Remove memory oscillation

* dependency (#277)

* bug fixes

---------

Co-authored-by: Guillaume Gay <[email protected]>

* tests pass

* fixes unknown namz

---------

Co-authored-by: sniffo <[email protected]>
Co-authored-by: Sophie THEIS <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment