14#include "arcane/utils/Array.h"
15#include "arcane/utils/Real3.h"
16#include "arcane/utils/StringBuilder.h"
17#include "arcane/utils/TraceAccessor.h"
18#include "arcane/utils/NotImplementedException.h"
20#include "arcane/core/ISubDomain.h"
21#include "arcane/core/IMesh.h"
22#include "arcane/core/IItemFamily.h"
23#include "arcane/core/Item.h"
24#include "arcane/core/BasicService.h"
25#include "arcane/core/FactoryService.h"
26#include "arcane/core/ItemPrinter.h"
27#include "arcane/core/ItemGroup.h"
28#include "arcane/core/VariableTypes.h"
29#include "arcane/core/IRayMeshIntersection.h"
30#include "arcane/core/IParallelMng.h"
31#include "arcane/core/IParticleFamily.h"
33#include "arcane_packages.h"
55class RayTriangle3DIntersection
69 m_rays_origin = origins;
70 m_rays_direction = directions;
81 m_triangles_coordinates = coordinates;
82 m_triangles_indexes = indexes;
113 return m_intersected_triangle_indexes;
141 Integer nb_ray = m_rays_origin.size();
142 m_distances.resize(nb_ray);
143 m_distances.fill(1.0e100);
144 m_intersected_triangle_indexes.resize(nb_ray);
145 m_intersected_triangle_indexes.fill(-1);
146 Integer nb_index = m_triangles_indexes.size();
149 Integer nb_triangle = nb_index / 3;
150 info() <<
"COMPUTE RAY INTERSECTION nb_ray=" << nb_ray
151 <<
" nb_triangle=" << nb_triangle;
153 for(
Integer i=0; i<nb_triangle; ++i ){
154 Real3 p0 = m_triangles_coordinates[m_triangles_indexes[(i*3)]];
155 Real3 p1 = m_triangles_coordinates[m_triangles_indexes[(i*3)+1]];
156 Real3 p2 = m_triangles_coordinates[m_triangles_indexes[(i*3)+2]];
157 _compute2(i,p0,p1,p2);
160 for(
Integer i=0; i<nb_ray; ++i ){
161 Int32 tid = m_intersected_triangle_indexes[i];
163 m_distances[i] = -1.0;
170void RayTriangle3DIntersection::
174 for(
Integer i=0; i<nb_ray; ++i ){
177 info() <<
"Segment " << i <<
" intersect triangle " << triangle_id <<
" T=" << t;
178 if (t<m_distances[i]){
180 m_intersected_triangle_indexes[i] = triangle_id;
181 info() <<
"Get this triangle";
222 Real ZERO_TOLERANCE = 1.0e-14;
224 Real3 kDiff = origin - p0;
225 Real3 kEdge1 = p1 - p0;
226 Real3 kEdge2 = p2 - p0;
231 if (fDdN > ZERO_TOLERANCE)
235 else if (fDdN < -ZERO_TOLERANCE)
248 if (fDdQxE2 >= (
Real)0.0)
251 if (fDdE1xQ >= (
Real)0.0)
253 Real diff = fDdN-(fDdQxE2 + fDdE1xQ);
259 if (diff>=0.0 || diff>-ZERO_TOLERANCE)
267 Real fExtDdN = m_pkSegment->Extent*fDdN;
268 if (-fExtDdN <= fQdN && fQdN <= fExtDdN)
298bool RayTriangle3DIntersection::
301 Real3 box_center = (box_max+box_min) * 0.5;
302 Real afWdU[3], afAWdU[3], afDdU[3], afADdU[3], afAWxDdU[3], fRhs;
304 Real3 kDiff = origin - box_center;
309 Axis[0] =
Real3(1.0,0.0,0.0);
310 Axis[1] =
Real3(0.0,1.0,0.0);
311 Axis[2] =
Real3(0.0,0.0,1.0);
313 Extent[0] = box_max.
x - box_min.
x;
314 Extent[1] = box_max.
y - box_min.
y;
315 Extent[2] = box_max.
z - box_min.
z;
318 afAWdU[0] = math::abs(afWdU[0]);
320 afADdU[0] = math::abs(afDdU[0]);
321 if (afADdU[0] > Extent[0] && afDdU[0]*afWdU[0] >= (
Real)0.0)
327 afAWdU[1] = math::abs(afWdU[1]);
329 afADdU[1] = math::abs(afDdU[1]);
330 if (afADdU[1] > Extent[1] && afDdU[1]*afWdU[1] >= (Real)0.0)
336 afAWdU[2] = math::abs(afWdU[2]);
338 afADdU[2] = math::abs(afDdU[2]);
339 if (afADdU[2] > Extent[2] && afDdU[2]*afWdU[2] >= (
Real)0.0)
346 afAWxDdU[0] = math::abs(
math::dot(kWxD,Axis[0]));
347 fRhs = Extent[1]*afAWdU[2] + Extent[2]*afAWdU[1];
348 if (afAWxDdU[0] > fRhs)
353 afAWxDdU[1] = math::abs(
math::dot(kWxD,Axis[1]));
354 fRhs = Extent[0]*afAWdU[2] + Extent[2]*afAWdU[0];
355 if (afAWxDdU[1] > fRhs)
360 afAWxDdU[2] = math::abs(
math::dot(kWxD,Axis[2]));
361 fRhs = Extent[0]*afAWdU[1] + Extent[1]*afAWdU[0];
362 if (afAWxDdU[2] > fRhs)
373class BasicRayFaceIntersector
378 : m_triangle_intersector(tm)
383 Int32 orig_face_local_id,
389 ARCANE_UNUSED(orig_face_local_id);
390 ARCANE_UNUSED(face_local_id);
396 Real3 center = (face_nodes[0] + face_nodes[1] + face_nodes[2] + face_nodes[3]) / 4.0;
397 Real d0 = m_triangle_intersector.checkIntersection(origin,direction,center,face_nodes[0],face_nodes[1]);
398 Real d1 = m_triangle_intersector.checkIntersection(origin,direction,center,face_nodes[1],face_nodes[2]);
399 Real d2 = m_triangle_intersector.checkIntersection(origin,direction,center,face_nodes[2],face_nodes[3]);
400 Real d3 = m_triangle_intersector.checkIntersection(origin,direction,center,face_nodes[3],face_nodes[0]);
403 if (d0>=0.0 && d0<d){
407 if (d1>=0.0 && d1<d){
411 if (d2>=0.0 && d2<d){
415 if (d3>=0.0 && d3<d){
422 *position = origin + d * direction;
440class BasicRayMeshIntersection
447 virtual ~BasicRayMeshIntersection() {}
471 m_face_intersector = intersector;
475 return m_face_intersector;
480 inline void _checkBoundingBox(
Real3 p,
Real3* ARCANE_RESTRICT min_bounding_box,
481 Real3* ARCANE_RESTRICT max_bounding_box)
483 if (p.
x<min_bounding_box->x)
484 min_bounding_box->x = p.
x;
485 if (p.
y<min_bounding_box->y)
486 min_bounding_box->y = p.
y;
487 if (p.
z<min_bounding_box->z)
488 min_bounding_box->z = p.
z;
490 if (p.
x>max_bounding_box->x)
491 max_bounding_box->x = p.
x;
492 if (p.
y>max_bounding_box->y)
493 max_bounding_box->y = p.
y;
494 if (p.
z>max_bounding_box->z)
495 max_bounding_box->z = p.
z;
499 IRayFaceIntersector* m_face_intersector;
505BasicRayMeshIntersection::
508, m_face_intersector(0)
526 bool is_3d =
mesh->dimension()==3;
527 info() <<
"COMPUTE INTERSECTION!!";
531 info() <<
"NB OUTER FACE=" << nb_face <<
" NB_SEGMENT=" << nb_segment;
533 const Real max_value = 1.0e100;
534 const Real3 max_bb(max_value,max_value,max_value);
535 const Real3 min_bb(-max_value,-max_value,-max_value);
537 Real3 mesh_min_bounding_box(max_bb);
538 Real3 mesh_max_bounding_box(min_bb);
539 Integer max_face_local_id =
mesh->faceFamily()->maxLocalId();
546 Int32 lid = iface.localId();
547 Real3 face_max_bb(max_bb);
548 Real3 face_min_bb(min_bb);
549 for(
NodeEnumerator inode((*iface).nodes()); inode.hasNext(); ++inode )
550 _checkBoundingBox(nodes_coordinates[inode],&face_min_bb,&face_max_bb);
551 _checkBoundingBox(face_min_bb,&mesh_min_bounding_box,&mesh_max_bounding_box);
552 _checkBoundingBox(face_max_bb,&mesh_min_bounding_box,&mesh_max_bounding_box);
555 faces_min_bb[lid] = face_min_bb;
556 faces_max_bb[lid] = face_max_bb;
561 segments_distance.
fill(max_value);
562 faces_local_id.
fill(NULL_ITEM_LOCAL_ID);
564 if (!m_face_intersector)
568 for(
Integer i=0; i<nb_segment; ++i ){
569 Real3 position = segments_position[i];
570 Real3 direction = segments_direction[i];
571 Int32 orig_face_local_id = segments_orig_face[i];
573 Real distance = 1.0e100;
574 Int32 min_face_local_id = NULL_ITEM_LOCAL_ID;
575 Int32 user_value = 0;
577 const Face& face = *iface;
586 is_bb = RayTriangle3DIntersection::checkBoundingBox(position,direction,faces_min_bb[lid],faces_max_bb[lid]);
590 face_nodes.
resize(nb_node);
592 face_nodes[inode.index()] = nodes_coordinates[inode];
594 Real3 local_intersection;
596 bool is_found = m_face_intersector->computeIntersection(position,direction,orig_face_local_id,lid,
597 face_nodes,&uv,&d,&local_intersection);
604 if (is_found && !is_bb)
605 fatal() <<
"Intersection found but no bounding box intersection";
606 if (is_found && d<distance){
608 min_face_local_id = lid;
609 intersection = local_intersection;
613 if (min_face_local_id==NULL_ITEM_LOCAL_ID)
615 segments_distance[i] = distance;
616 segments_intersection[i] = intersection;
617 faces_local_id[i] = min_face_local_id;
618 user_values[i] = user_value;
628 Int32 orig_face_local_id;
660 if (global_nb_ray==0)
662 info() <<
"LOCAL_NB_RAY=" << nb_local_ray <<
" GLOBAL=" << global_nb_ray;
674 local_positions[index] = rays_position[iitem];
675 local_directions[index] = rays_direction[iitem];
684 local_ids[index] = iitem.localId();
685 unique_ids[index] = (*iitem).uniqueId();
696 local_owners.
fill(my_rank);
711 for(
Integer z=0, zn=all_orig_faces.
size(); z<zn; ++z ){
712 if (all_owners[z]!=my_rank)
713 all_orig_faces[z] = NULL_ITEM_LOCAL_ID;
715 compute(all_positions,all_directions,all_orig_faces,all_user_values,all_intersections,all_distances,all_faces);
725 for(
Integer i=0; i<global_nb_ray; ++i ){
726 Int32 face_lid = all_faces[i];
727 if (face_lid==NULL_ITEM_LOCAL_ID)
730 fi.contrib_owner = my_rank;
731 fi.owner = all_owners[i];
732 fi.local_id = all_local_ids[i];
733 fi.face_local_id = all_faces[i];
734 fi.orig_face_local_id = all_orig_faces[i];
735 fi.user_value = all_user_values[i];
736 fi.intersection = all_intersections[i];
737 fi.distance = all_distances[i];
740 info() <<
"NB_FOUND=" << founds_info.
size();
748 Integer nb_total_found = global_founds_info.
size();
750 rays_face.fill(NULL_ITEM_LOCAL_ID);
753 rays_new_owner.fill(my_rank);
754 for(
Integer i=0; i<nb_total_found; ++i ){
755 const FoundInfo& fi = global_founds_info[i];
756 Int32 owner = fi.owner;
760 Int32 local_id = fi.local_id;
762 Real distance = fi.distance;
763 if ((rays_face[ray]==NULL_ITEM_LOCAL_ID) || distance<distances[ray]){
764 distances[ray] = distance;
765 intersections[ray] =
Real3(fi.intersection.
x,fi.intersection.
y,fi.intersection.
z);
766 rays_face[ray] = fi.face_local_id;
767 rays_user_value[ray] = fi.user_value;
768 rays_new_owner[ray] = fi.contrib_owner;
788 orig_faces[index] = rays_orig_face[iitem];
789 user_values[index] = rays_user_value[iitem];
796 compute(local_positions,local_directions,orig_faces,user_values,out_intersections,out_distances,out_faces);
801 intersections[iitem] = out_intersections[index];
802 distances[iitem] = out_distances[index];
803 rays_face[iitem] = out_faces[index];
812 local_directions.
resize(nb_new_ray);
813 local_positions.
resize(nb_new_ray);
816 local_distances[index] = distances[iitem];
817 local_directions[index] = rays_direction[iitem];
818 local_positions[index] = rays_position[iitem];
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
Integer size() const
Nombre d'éléments du vecteur.
void fill(const T &o) noexcept
Remplit le tableau avec la valeur o.
void fill(const DataType &data)
Remplissage du tableau.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
const T * data() const
Accès à la racine du tableau hors toute protection.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
bool computeIntersection(Real3 origin, Real3 direction, Int32 orig_face_local_id, Int32 face_local_id, Real3ConstArrayView face_nodes, Int32 *user_value, Real *distance, Real3 *position)
Calcul l'intersection entre un rayon et une face.
Service basique de calcul d'intersection entre segments et maillage.
virtual void build()
Construction de niveau build du service.
virtual void setFaceIntersector(IRayFaceIntersector *intersector)
Positionne le callback d'intersection.
virtual IRayFaceIntersector * faceIntersector()
Intersecteur utilisé (0 si aucun spécifié)
virtual void compute(Real3ConstArrayView segments_position, Real3ConstArrayView segments_direction, Int32ConstArrayView segments_orig_face, Int32ArrayView user_values, Real3ArrayView intersections, RealArrayView distances, Int32ArrayView faces_local_id)
Calcule l'intersection.
Classe de base de service lié à un sous-domaine.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Exception lorsqu'une erreur fatale est survenue.
Interface d'une famille d'entités.
virtual IParticleFamily * toParticleFamily()=0
Retourne l'interface de la famille de particule de cette famille.
virtual ItemGroup allItems() const =0
Groupe de toutes les entités.
virtual IMesh * mesh() const =0
Maillage associé
virtual Integer nbItem() const =0
Nombre d'entités.
virtual VariableItemInt32 & itemsNewOwner()=0
Variable contenant le numéro du nouveau sous-domaine propriétaire de l'entité.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual void allGatherVariable(ConstArrayView< char > send_buf, Array< char > &recv_buf)=0
Effectue un regroupement sur tous les processeurs.
virtual bool isParallel() const =0
Retourne true si l'exécution est parallèle.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
virtual void exchangeParticles()=0
Échange des entités.
Interface générique du calcul de l'intersection d'un rayon avec une face.
Calcul de l'intersection entre un ensemble de segments et la surface d'un maillage.
Interface du gestionnaire de traces.
Integer size() const
Nombre d'éléments du groupe.
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Int32 nbNode() const
Nombre de noeuds de l'entité
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
constexpr bool isOwn() const
true si l'entité est appartient au sous-domaine
Exception lorsqu'une fonction n'est pas implémentée.
Vue sur les informations des particules.
Calcul l'intersection d'un rayon avec un ensemble de triangles en 3D.
void setRays(Real3ConstArrayView origins, Real3ConstArrayView directions)
Position la liste des rayons dont on souhaite calculer l'intersection.
Real checkIntersection(Real3 origin, Real3 direction, Real3 p0, Real3 p1, Real3 p2)
Calcul l'intersection de la demi-droite [origin,direction) avec le triangle (p0,p1,...
void compute()
Calcul l'intersection de chaque rayon avec la liste des triangles. Si un rayon intersecte plusieurs t...
void setTriangles(Real3ConstArrayView coordinates, Int32ConstArrayView indexes)
Positionne la liste des triangles dont on souhaite calculer l'intersection avec les rayons....
Int32ConstArrayView intersectedTriangleIndexes()
Indices des triangles intersectés. Indice dans le tableau donnée par setTriangles() du triangle inter...
RealConstArrayView distances()
Distance de l'origine d'un rayon à son point d'intersection. Distance (exprimée relativivement à la n...
Classe gérant un vecteur de réel de dimension 3.
Structure contenant les informations pour créer un service.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
TraceMessage info() const
Flot pour un message d'information.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
__host__ __device__ Real dot(Real2 u, Real2 v)
Produit scalaire de u par v dans .
__host__ __device__ Real3 vecMul(Real3 u, Real3 v)
Produit vectoriel de u par v. dans .
ItemGroupT< Face > FaceGroup
Groupe de faces.
ItemEnumeratorT< Node > NodeEnumerator
Enumérateurs sur des noeuds.
MeshVariableScalarRefT< Particle, Real3 > VariableParticleReal3
Grandeur particulaire de type coordonnées.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
MeshVariableScalarRefT< Particle, Int32 > VariableParticleInt32
Grandeur particulaire de type entier 32 bits.
MeshVariableScalarRefT< Particle, Real > VariableParticleReal
Grandeur particulaire de type réel.
ItemVariableScalarRefT< Int32 > VariableItemInt32
Grandeur de type entier 32 bits.
@ ReduceSum
Somme des valeurs.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Integer arcaneCheckArraySize(unsigned long long size)
Vérifie que size peut être converti dans un 'Integer' pour servir de taille à un tableau....
ConstArrayView< Real3 > Real3ConstArrayView
Equivalent C d'un tableau à une dimension de Real3.
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
ArrayView< Real3 > Real3ArrayView
Equivalent C d'un tableau à une dimension de Real3.
Int32 Integer
Type représentant un entier.
UniqueArray< Real3 > Real3UniqueArray
Tableau dynamique à une dimension de vecteurs de rang 3.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
UniqueArray< Byte > ByteUniqueArray
Tableau dynamique à une dimension de caractères.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
UniqueArray< Real > RealUniqueArray
Tableau dynamique à une dimension de réels.
double Real
Type représentant un réel.
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
unsigned char Byte
Type d'un octet.
ArrayView< Real > RealArrayView
Equivalent C d'un tableau à une dimension de réels.
std::int32_t Int32
Type entier signé sur 32 bits.
ConstArrayView< Real > RealConstArrayView
Equivalent C d'un tableau à une dimension de réels.
Real y
deuxième composante du triplet
Real z
troisième composante du triplet
Real x
première composante du triplet