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"
56class RayTriangle3DIntersection
71 m_rays_origin = origins;
72 m_rays_direction = directions;
83 m_triangles_coordinates = coordinates;
84 m_triangles_indexes = indexes;
115 return m_intersected_triangle_indexes;
143 Integer nb_ray = m_rays_origin.size();
144 m_distances.resize(nb_ray);
145 m_distances.fill(1.0e100);
146 m_intersected_triangle_indexes.resize(nb_ray);
147 m_intersected_triangle_indexes.fill(-1);
148 Integer nb_index = m_triangles_indexes.size();
149 if ((nb_index % 3) != 0)
151 Integer nb_triangle = nb_index / 3;
152 info() <<
"COMPUTE RAY INTERSECTION nb_ray=" << nb_ray
153 <<
" nb_triangle=" << nb_triangle;
155 for (
Integer i = 0; i < nb_triangle; ++i) {
156 Real3 p0 = m_triangles_coordinates[m_triangles_indexes[(i * 3)]];
157 Real3 p1 = m_triangles_coordinates[m_triangles_indexes[(i * 3) + 1]];
158 Real3 p2 = m_triangles_coordinates[m_triangles_indexes[(i * 3) + 2]];
159 _compute2(i, p0, p1, p2);
162 for (
Integer i = 0; i < nb_ray; ++i) {
163 Int32 tid = m_intersected_triangle_indexes[i];
165 m_distances[i] = -1.0;
172void RayTriangle3DIntersection::
176 for (
Integer i = 0; i < nb_ray; ++i) {
179 info() <<
"Segment " << i <<
" intersect triangle " << triangle_id <<
" T=" << t;
180 if (t < m_distances[i]) {
182 m_intersected_triangle_indexes[i] = triangle_id;
183 info() <<
"Get this triangle";
224 Real ZERO_TOLERANCE = 1.0e-14;
226 Real3 kDiff = origin - p0;
227 Real3 kEdge1 = p1 - p0;
228 Real3 kEdge2 = p2 - p0;
233 if (fDdN > ZERO_TOLERANCE) {
236 else if (fDdN < -ZERO_TOLERANCE) {
247 if (fDdQxE2 >= (
Real)0.0) {
249 if (fDdE1xQ >= (
Real)0.0) {
250 Real diff = fDdN - (fDdQxE2 + fDdE1xQ);
256 if (diff >= 0.0 || diff > -ZERO_TOLERANCE) {
263 Real fExtDdN = m_pkSegment->Extent*fDdN;
264 if (-fExtDdN <= fQdN && fQdN <= fExtDdN)
271 Real t = fQdN * fInv;
294bool RayTriangle3DIntersection::
297 Real3 box_center = (box_max + box_min) * 0.5;
298 Real afWdU[3], afAWdU[3], afDdU[3], afADdU[3], afAWxDdU[3], fRhs;
300 Real3 kDiff = origin - box_center;
305 Axis[0] =
Real3(1.0, 0.0, 0.0);
306 Axis[1] =
Real3(0.0, 1.0, 0.0);
307 Axis[2] =
Real3(0.0, 0.0, 1.0);
309 Extent[0] = box_max.
x - box_min.
x;
310 Extent[1] = box_max.
y - box_min.
y;
311 Extent[2] = box_max.
z - box_min.
z;
313 afWdU[0] =
math::dot(direction, Axis[0]);
314 afAWdU[0] = math::abs(afWdU[0]);
316 afADdU[0] = math::abs(afDdU[0]);
317 if (afADdU[0] > Extent[0] && afDdU[0] * afWdU[0] >= (
Real)0.0) {
321 afWdU[1] =
math::dot(direction, Axis[1]);
322 afAWdU[1] = math::abs(afWdU[1]);
324 afADdU[1] = math::abs(afDdU[1]);
325 if (afADdU[1] > Extent[1] && afDdU[1] * afWdU[1] >= (Real)0.0) {
329 afWdU[2] =
math::dot(direction, Axis[2]);
330 afAWdU[2] = math::abs(afWdU[2]);
332 afADdU[2] = math::abs(afDdU[2]);
333 if (afADdU[2] > Extent[2] && afDdU[2] * afWdU[2] >= (
Real)0.0) {
339 afAWxDdU[0] = math::abs(
math::dot(kWxD, Axis[0]));
340 fRhs = Extent[1] * afAWdU[2] + Extent[2] * afAWdU[1];
341 if (afAWxDdU[0] > fRhs) {
345 afAWxDdU[1] = math::abs(
math::dot(kWxD, Axis[1]));
346 fRhs = Extent[0] * afAWdU[2] + Extent[2] * afAWdU[0];
347 if (afAWxDdU[1] > fRhs) {
351 afAWxDdU[2] = math::abs(
math::dot(kWxD, Axis[2]));
352 fRhs = Extent[0] * afAWdU[1] + Extent[1] * afAWdU[0];
353 if (afAWxDdU[2] > fRhs) {
363class BasicRayFaceIntersector
369 : m_triangle_intersector(tm)
376 Int32 orig_face_local_id,
382 ARCANE_UNUSED(orig_face_local_id);
383 ARCANE_UNUSED(face_local_id);
388 Real3 center = (face_nodes[0] + face_nodes[1] + face_nodes[2] + face_nodes[3]) / 4.0;
389 Real d0 = m_triangle_intersector.checkIntersection(origin, direction, center, face_nodes[0], face_nodes[1]);
390 Real d1 = m_triangle_intersector.checkIntersection(origin, direction, center, face_nodes[1], face_nodes[2]);
391 Real d2 = m_triangle_intersector.checkIntersection(origin, direction, center, face_nodes[2], face_nodes[3]);
392 Real d3 = m_triangle_intersector.checkIntersection(origin, direction, center, face_nodes[3], face_nodes[0]);
395 if (d0 >= 0.0 && d0 < d) {
399 if (d1 >= 0.0 && d1 < d) {
403 if (d2 >= 0.0 && d2 < d) {
407 if (d3 >= 0.0 && d3 < d) {
414 *position = origin + d * direction;
434class BasicRayMeshIntersection
441 virtual ~BasicRayMeshIntersection() {}
465 m_face_intersector = intersector;
469 return m_face_intersector;
474 inline void _checkBoundingBox(
Real3 p,
Real3* ARCANE_RESTRICT min_bounding_box,
475 Real3* ARCANE_RESTRICT max_bounding_box)
477 if (p.
x < min_bounding_box->x)
478 min_bounding_box->x = p.
x;
479 if (p.
y < min_bounding_box->y)
480 min_bounding_box->y = p.
y;
481 if (p.
z < min_bounding_box->z)
482 min_bounding_box->z = p.
z;
484 if (p.
x > max_bounding_box->x)
485 max_bounding_box->x = p.
x;
486 if (p.
y > max_bounding_box->y)
487 max_bounding_box->y = p.
y;
488 if (p.
z > max_bounding_box->z)
489 max_bounding_box->z = p.
z;
494 IRayFaceIntersector* m_face_intersector;
500BasicRayMeshIntersection::
503, m_face_intersector(0)
521 bool is_3d =
mesh->dimension() == 3;
522 info() <<
"COMPUTE INTERSECTION!!";
526 info() <<
"NB OUTER FACE=" << nb_face <<
" NB_SEGMENT=" << nb_segment;
528 const Real max_value = 1.0e100;
529 const Real3 max_bb(max_value, max_value, max_value);
530 const Real3 min_bb(-max_value, -max_value, -max_value);
532 Real3 mesh_min_bounding_box(max_bb);
533 Real3 mesh_max_bounding_box(min_bb);
534 Integer max_face_local_id =
mesh->faceFamily()->maxLocalId();
541 Int32 lid = iface.localId();
542 Real3 face_max_bb(max_bb);
543 Real3 face_min_bb(min_bb);
544 for (
NodeEnumerator inode((*iface).nodes()); inode.hasNext(); ++inode)
545 _checkBoundingBox(nodes_coordinates[inode], &face_min_bb, &face_max_bb);
546 _checkBoundingBox(face_min_bb, &mesh_min_bounding_box, &mesh_max_bounding_box);
547 _checkBoundingBox(face_max_bb, &mesh_min_bounding_box, &mesh_max_bounding_box);
550 faces_min_bb[lid] = face_min_bb;
551 faces_max_bb[lid] = face_max_bb;
556 segments_distance.
fill(max_value);
557 faces_local_id.
fill(NULL_ITEM_LOCAL_ID);
559 if (!m_face_intersector)
563 for (
Integer i = 0; i < nb_segment; ++i) {
564 Real3 position = segments_position[i];
565 Real3 direction = segments_direction[i];
566 Int32 orig_face_local_id = segments_orig_face[i];
568 Real distance = 1.0e100;
569 Int32 min_face_local_id = NULL_ITEM_LOCAL_ID;
570 Int32 user_value = 0;
572 const Face& face = *iface;
581 is_bb = RayTriangle3DIntersection::checkBoundingBox(position, direction, faces_min_bb[lid], faces_max_bb[lid]);
585 face_nodes.
resize(nb_node);
587 face_nodes[inode.index()] = nodes_coordinates[inode];
589 Real3 local_intersection;
591 bool is_found = m_face_intersector->computeIntersection(position, direction, orig_face_local_id, lid,
592 face_nodes, &uv, &d, &local_intersection);
599 if (is_found && !is_bb)
600 fatal() <<
"Intersection found but no bounding box intersection";
601 if (is_found && d < distance) {
603 min_face_local_id = lid;
604 intersection = local_intersection;
608 if (min_face_local_id == NULL_ITEM_LOCAL_ID)
610 segments_distance[i] = distance;
611 segments_intersection[i] = intersection;
612 faces_local_id[i] = min_face_local_id;
613 user_values[i] = user_value;
623 Int32 orig_face_local_id;
654 if (global_nb_ray == 0)
656 info() <<
"LOCAL_NB_RAY=" << nb_local_ray <<
" GLOBAL=" << global_nb_ray;
668 local_positions[index] = rays_position[iitem];
669 local_directions[index] = rays_direction[iitem];
678 local_ids[index] = iitem.localId();
679 unique_ids[index] = (*iitem).uniqueId();
690 local_owners.
fill(my_rank);
705 for (
Integer z = 0, zn = all_orig_faces.
size(); z < zn; ++z) {
706 if (all_owners[z] != my_rank)
707 all_orig_faces[z] = NULL_ITEM_LOCAL_ID;
709 compute(all_positions, all_directions, all_orig_faces, all_user_values, all_intersections, all_distances, all_faces);
719 for (
Integer i = 0; i < global_nb_ray; ++i) {
720 Int32 face_lid = all_faces[i];
721 if (face_lid == NULL_ITEM_LOCAL_ID)
724 fi.contrib_owner = my_rank;
725 fi.owner = all_owners[i];
726 fi.local_id = all_local_ids[i];
727 fi.face_local_id = all_faces[i];
728 fi.orig_face_local_id = all_orig_faces[i];
729 fi.user_value = all_user_values[i];
730 fi.intersection = all_intersections[i];
731 fi.distance = all_distances[i];
734 info() <<
"NB_FOUND=" << founds_info.
size();
742 Integer nb_total_found = global_founds_info.
size();
744 rays_face.fill(NULL_ITEM_LOCAL_ID);
747 rays_new_owner.fill(my_rank);
748 for (
Integer i = 0; i < nb_total_found; ++i) {
749 const FoundInfo& fi = global_founds_info[i];
750 Int32 owner = fi.owner;
752 if (owner != my_rank)
754 Int32 local_id = fi.local_id;
756 Real distance = fi.distance;
757 if ((rays_face[ray] == NULL_ITEM_LOCAL_ID) || distance < distances[ray]) {
758 distances[ray] = distance;
759 intersections[ray] =
Real3(fi.intersection.
x, fi.intersection.
y, fi.intersection.
z);
760 rays_face[ray] = fi.face_local_id;
761 rays_user_value[ray] = fi.user_value;
762 rays_new_owner[ray] = fi.contrib_owner;
782 orig_faces[index] = rays_orig_face[iitem];
783 user_values[index] = rays_user_value[iitem];
790 compute(local_positions, local_directions, orig_faces, user_values, out_intersections, out_distances, out_faces);
795 intersections[iitem] = out_intersections[index];
796 distances[iitem] = out_distances[index];
797 rays_face[iitem] = out_faces[index];
805 local_directions.
resize(nb_new_ray);
806 local_positions.
resize(nb_new_ray);
809 local_distances[index] = distances[iitem];
810 local_directions[index] = rays_direction[iitem];
811 local_positions[index] = rays_position[iitem];
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Registers a factory service for the class aclass.
Integer size() const
Number of elements in the vector.
void fill(const T &o) noexcept
Fills the array with the value o.
void fill(ConstReferenceType value)
Fills the array with the value value.
void resize(Int64 s)
Changes the number of elements in the array to s.
void add(ConstReferenceType val)
Adds element val to the end of the array.
const T * data() const
Access to the root of the array without any protection.
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)
Calculates the intersection between a ray and a face.
Basic service for calculating intersection between segments and mesh.
virtual void build()
Build-level construction of the service.
virtual void setFaceIntersector(IRayFaceIntersector *intersector)
Sets the intersection callback.
virtual IRayFaceIntersector * faceIntersector()
Intersector used (0 if none specified).
virtual void compute(Real3ConstArrayView segments_position, Real3ConstArrayView segments_direction, Int32ConstArrayView segments_orig_face, Int32ArrayView user_values, Real3ArrayView intersections, RealArrayView distances, Int32ArrayView faces_local_id)
Calculates the intersection.
Base class of a service linked to a subdomain.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Exception when a fatal error has occurred.
Interface of an entity family.
virtual IParticleFamily * toParticleFamily()=0
Returns the interface of the particle family for this family.
virtual ItemGroup allItems() const =0
Group of all entities.
virtual IMesh * mesh() const =0
Associated mesh.
virtual Integer nbItem() const =0
Number of entities.
virtual VariableItemInt32 & itemsNewOwner()=0
Variable containing the number of the new subdomain owning the entity.
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual void allGatherVariable(ConstArrayView< char > send_buf, Array< char > &recv_buf)=0
Performs an all-gather operation across all processors.
virtual bool isParallel() const =0
Returns true if the execution is parallel.
virtual char reduce(eReduceType rt, char v)=0
Performs a reduction of type rt on the real v and returns the value.
virtual void exchangeParticles()=0
Exchanging entities.
Generic interface for calculating the intersection of a ray with a face.
Calculation of the intersection between a set of segments and the surface of a mesh.
Integer size() const
Number of elements in the group.
NodeConnectedListViewType nodes() const
List of nodes of the entity.
Int32 nbNode() const
Number of nodes of the entity.
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
constexpr bool isOwn() const
true if the entity belongs to the subdomain
Exception when a function is not implemented.
View of particle information.
Calculates the intersection of a ray with a set of triangles in 3D.
void setRays(Real3ConstArrayView origins, Real3ConstArrayView directions)
Positions the list of rays for which intersection is desired.
Real checkIntersection(Real3 origin, Real3 direction, Real3 p0, Real3 p1, Real3 p2)
Calculates the intersection of the half-line [origin,direction) with the triangle (p0,...
void compute()
Calculates the intersection of each ray with the list of triangles. If a ray intersects multiple tria...
void setTriangles(Real3ConstArrayView coordinates, Int32ConstArrayView indexes)
Positions the list of triangles for which intersection is desired with the rays. The array indexes co...
Int32ConstArrayView intersectedTriangleIndexes()
Indices of intersected triangles. Index in the array provided by setTriangles() of the triangle inter...
RealConstArrayView distances()
Distance from the origin of a ray to its intersection point. Distance (expressed relative to the norm...
Class managing a 3-dimensional real vector.
Structure containing the information to create a service.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage fatal() const
Flow for a fatal error message.
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
1D data vector with value semantics (STL style).
__host__ __device__ Real dot(Real2 u, Real2 v)
Dot product of u by v in .
__host__ __device__ Real3 vecMul(Real3 u, Real3 v)
Vector cross product of u by v in .
ItemGroupT< Face > FaceGroup
Group of faces.
ItemEnumeratorT< Node > NodeEnumerator
Enumerators over nodes.
MeshVariableScalarRefT< Particle, Real3 > VariableParticleReal3
Coordinate type particle quantity.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
MeshVariableScalarRefT< Particle, Int32 > VariableParticleInt32
Particle quantity of 32-bit integer type.
MeshVariableScalarRefT< Particle, Real > VariableParticleReal
Real type particle quantity.
ItemVariableScalarRefT< Int32 > VariableItemInt32
32-bit integer type quantity
@ ReduceSum
Sum of values.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Integer arcaneCheckArraySize(unsigned long long size)
Checks that size can be converted into an 'Integer' to serve as the size of an array....
ConstArrayView< Real3 > Real3ConstArrayView
C equivalent of a 1D array of Real3.
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
ArrayView< Real3 > Real3ArrayView
C equivalent of a 1D array of Real3.
Int32 Integer
Type representing an integer.
UniqueArray< Real3 > Real3UniqueArray
Dynamic 1D array of rank 3 vectors.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
UniqueArray< Byte > ByteUniqueArray
Dynamic 1D array of characters.
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
ArrayView< Int32 > Int32ArrayView
C equivalent of a 1D array of 32-bit integers.
UniqueArray< Real > RealUniqueArray
Dynamic 1D array of reals.
double Real
Type representing a real number.
ConstArrayView< Byte > ByteConstArrayView
C equivalent of a 1D array of characters.
unsigned char Byte
Type of a byte.
ArrayView< Real > RealArrayView
C equivalent of a 1D array of reals.
std::int32_t Int32
Signed integer type of 32 bits.
ConstArrayView< Real > RealConstArrayView
C equivalent of a 1D array of reals.
Real y
second component of the triplet
Real z
third component of the triplet
Real x
first component of the triplet