Skip to content

Commit 56e8a8c

Browse files
Updated mesh intersection algorithm to return all times, not just postitive.
Fixed that normals were not sorted according to their times.
1 parent 18f6ac4 commit 56e8a8c

File tree

1 file changed

+65
-44
lines changed

1 file changed

+65
-44
lines changed

mcstas-comps/share/union-lib.c

Lines changed: 65 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3876,8 +3876,23 @@ int r_within_mesh(Coords pos,struct geometry_struct *geometry) {
38763876

38773877
return 0;
38783878
};
3879+
38793880

3880-
3881+
// Type for holding intersection and normal
3882+
typedef struct {
3883+
double t;
3884+
double nx, ny, nz;
3885+
int surface_index;
3886+
} Intersection;
3887+
3888+
// Function to sort intersection structs according to time
3889+
int compare_intersections(const void *a, const void *b) {
3890+
const Intersection *ia = a;
3891+
const Intersection *ib = b;
3892+
if (ia->t < ib->t) return -1;
3893+
if (ia->t > ib->t) return 1;
3894+
return 0;
3895+
}
38813896

38823897
int sample_mesh_intersect(double *t,
38833898
double *nx, double *ny, double*nz,
@@ -3969,58 +3984,64 @@ int sample_mesh_intersect(double *t,
39693984
//if (a > -UNION_EPSILON && a < UNION_EPSILON){
39703985
////printf("\n UNION_EPSILON fail");
39713986
//}
3972-
f = 1.0/a;
3973-
s = coords_sub(rotated_coordinates, coords_set(*(v1_x+iter),*(v1_y+iter),*(v1_z+iter)));
3974-
u = f * (Dot(s,h));
3975-
if (u < 0.0 || u > 1.0){
3976-
}else{
3977-
//q = vec_prod(s,edge1);
3978-
vec_prod(q.x,q.y,q.z,s.x,s.y,s.z,edge1.x,edge1.y,edge1.z);
3979-
V = f * Dot(rotated_velocity,q);
3980-
if (V < 0.0 || u + V > 1.0){
3981-
} else {
3982-
// At this stage we can compute t to find out where the intersection point is on the line.
3983-
//tmp = Dot(q,edge2)
3984-
if (f* Dot(q,edge2) > 0){
3985-
3986-
t_intersect[counter] = f* Dot(q,edge2);
3987-
facet_index[counter] = iter;
3988-
//printf("\nIntersects at time: t= %f\n",t_intersect[counter] );
3989-
counter++;
3990-
}
3991-
}
3987+
f = 1.0/a;
3988+
s = coords_sub(rotated_coordinates, coords_set(*(v1_x+iter),*(v1_y+iter),*(v1_z+iter)));
3989+
u = f * (Dot(s,h));
3990+
if (u < 0.0 || u > 1.0){
3991+
} else {
3992+
//q = vec_prod(s,edge1);
3993+
vec_prod(q.x,q.y,q.z,s.x,s.y,s.z,edge1.x,edge1.y,edge1.z);
3994+
V = f * Dot(rotated_velocity,q);
3995+
if (V < 0.0 || u + V > 1.0){
3996+
} else {
3997+
// At this stage we can compute t to find out where the intersection point is on the line.
3998+
t_intersect[counter] = f* Dot(q,edge2);
3999+
facet_index[counter] = iter;
4000+
//printf("\nIntersects at time: t= %f\n",t_intersect[counter] );
4001+
counter++;
39924002
}
4003+
}
39934004
}
3994-
3995-
// Return all t
3996-
int counter2=0;
3997-
double x_intersect, y_intersect, z_intersect;
3998-
*num_solutions =0;
3999-
for (iter=0; iter < counter ; iter++){
4000-
if (t_intersect[iter] > 0.0){
4001-
t[counter2] = t_intersect[iter];
4002-
x_intersect = t[counter2]*v[0] + x_new;
4003-
y_intersect = t[counter2]*v[1] + y_new;
4004-
z_intersect = t[counter2]*v[2] + z_new;
4005-
coordinates = coords_set(x_intersect,y_intersect,z_intersect);
4006-
NORM(coordinates.x, coordinates.y, coordinates.z);
4007-
nx[counter2] = normal_x[facet_index[iter]];
4008-
ny[counter2] = normal_x[facet_index[iter]];
4009-
nz[counter2] = normal_x[facet_index[iter]];
4010-
surface_index[counter2] = 0;
4011-
counter2++;
4012-
*num_solutions = counter2;
4013-
}
4014-
}
4015-
// Sort t:
4005+
4006+
*num_solutions = counter;
4007+
4008+
// Early exit if there are not solutions
40164009
if (*num_solutions == 0){
40174010
free(t_intersect);
40184011
free(facet_index);
40194012
return 0;
40204013
}
4021-
qsort(t,*num_solutions,sizeof (double), Sample_compare_doubles);
4014+
4015+
// Move times and normal's into structs to be sorted
4016+
Intersection *hits = malloc(*num_solutions * sizeof(Intersection));
4017+
if (!hits) {
4018+
fprintf(stderr,"Failure allocating Intersection list struct in Union function sample_mesh_intersect - Exit!\n");
4019+
exit(EXIT_FAILURE);
4020+
}
4021+
4022+
for (iter=0; iter < *num_solutions; iter++){
4023+
hits[iter].t = t_intersect[iter];;
4024+
hits[iter].nx = normal_x[facet_index[iter]];
4025+
hits[iter].ny = normal_y[facet_index[iter]];
4026+
hits[iter].nz = normal_z[facet_index[iter]];
4027+
surface_index[iter] = 0;
4028+
}
4029+
4030+
// Sort structs according to time
4031+
qsort(hits, *num_solutions, sizeof(Intersection), compare_intersections);
4032+
4033+
// Place the solutions into the pointers given in the function parameters for return
4034+
for (int i = 0; i < *num_solutions; i++) {
4035+
t[i] = hits[i].t;
4036+
nx[i] = - hits[i].nx;
4037+
ny[i] = - hits[i].ny;
4038+
nz[i] = - hits[i].nz;
4039+
surface_index[i] = hits[i].surface_index;
4040+
}
4041+
40224042
free(facet_index);
40234043
free(t_intersect);
4044+
free(hits);
40244045
return 1;
40254046
};
40264047

0 commit comments

Comments
 (0)