DHART
Loading...
Searching...
No Matches
raytracer_C.cpp
Go to the documentation of this file.
1#include <raytracer_C.h>
2#include <iostream>
3
4#include <embree_raytracer.h>
5#include <meshinfo.h>
6#include <HFExceptions.h>
7#include <cinterface_utils.h>
8
9using std::vector;
12using namespace HF::Exceptions;
13//TODO: Use a template for this
14
15C_INTERFACE CreateRaytracer(MeshInfo * mesh, EmbreeRayTracer** out_raytracer, bool use_precise)
16{
17 // Create the raytracer with the first mesh.
18 try {
19
20 // Iterate through all of the meshes in our input and add
21 // them to the raytracer
22 *out_raytracer = new EmbreeRayTracer(*mesh, use_precise);
23 return OK;
24 }
25 // Thrown if Embree is missing
26 catch (const HF::Exceptions::MissingDependency & e) {
27 if (*out_raytracer != NULL)
28 delete *out_raytracer;
29 return MISSING_DEPEND;
30 }
31 catch (const HF::Exceptions::InvalidOBJ & e) {
32 if (*out_raytracer != NULL)
33 delete *out_raytracer;
34 return INVALID_OBJ;
35 }
36 return GENERIC_ERROR;
37}
38
39C_INTERFACE CreateRaytracerMultiMesh(MeshInfo** meshes, int num_meshes, EmbreeRayTracer** out_raytracer, bool use_precise)
40{
41 // Create the raytracer with the first mesh.
42 *out_raytracer = new EmbreeRayTracer(use_precise);
43 try {
44
45 // Iterate through all of the meshes in our input and add
46 // them to the raytracer
47 for (int i = 0; i < num_meshes; i++) {
48 // Only commit to scene if this is the final mesh in the array
49 bool should_commit = (i == num_meshes - 1);
50
51 (*out_raytracer)->AddMesh(*(meshes[i]), should_commit);
52 }
53
54 return OK;
55 }
56 // Thrown if Embree is missing
57 catch (const HF::Exceptions::MissingDependency& e) {
58 if (*out_raytracer != NULL)
59 delete* out_raytracer;
60 return MISSING_DEPEND;
61 }
62 catch (const HF::Exceptions::InvalidOBJ& e) {
63 if (*out_raytracer != NULL)
64 delete* out_raytracer;
65 return INVALID_OBJ;
66 }
67 return GENERIC_ERROR;
68}
69
70
72{
73 // Iterate through each input mesh, only committing the scene
74 // at the final mesh.
75 for (int i = 0; i < number_of_meshes; i++) {
76 bool should_commit = (i == number_of_meshes - 1);
77
78 ERT->AddMesh(*(MI[i]), should_commit);
79 }
80
81 return HF_STATUS::OK;
82}
83
85{
86 ERT->AddMesh(*MI, true);
87
88 return HF_STATUS::OK;
89}
90
92{
93 if (rt_to_destroy)
94 delete rt_to_destroy;
95 return OK;
96}
97
100 const float* origin,
101 const float* direction,
102 const float max_distance,
103 float* out_distance,
104 int* out_meshid
105)
106{
107 ert->IntersectOutputArguments(origin, direction, *out_distance, *out_meshid);
109}
110
113 float* origins,
114 int num_origins,
115 float* directions,
116 int num_directions,
117 std::vector<RayResult>** out_results,
118 RayResult** results_data
119)
120{
121 enum CastType {
122 ONE_ORIGIN,
123 ONE_DIRECTION,
124 MULTIPLE_RAY
125 };
126 CastType type;
127 if (num_origins == num_directions)
128 type = MULTIPLE_RAY;
129 else if (num_origins == 1 && num_directions > 1)
130 type = ONE_ORIGIN;
131 else if (num_origins > 1 && num_directions == 1)
132 type = ONE_DIRECTION;
133 else {
134 fprintf(stderr, "[C++] Invalid input. num_origins = %d, num_directions = %d\n", num_origins, num_directions);
136 }
137 std::vector<RayResult>* output_results;
138
139 switch (type) {
140 case MULTIPLE_RAY:
141 {
142 auto origin_pts = ConvertRawFloatArrayToPoints(origins, num_origins);
143 auto direction_pts = ConvertRawFloatArrayToPoints(directions, num_directions);
144
145 output_results = new std::vector<RayResult>(num_origins);
146
147#pragma omp parallel for schedule(dynamic)
148 for (int i = 0; i < num_origins; i++) {
149 float out_distance = -1;
150 int out_id = -1;
151 if (ert->IntersectOutputArguments(origin_pts[i], direction_pts[i], out_distance, out_id))
152 (*output_results)[i].SetHit(origin_pts[i], direction_pts[i], out_distance, out_id);
153 }
154 break;
155 }
156
157 case ONE_ORIGIN:
158 {
159 std::array<float, 3> origin = { origins[0], origins[1], origins[2] };
160 auto direction_pts = ConvertRawFloatArrayToPoints(directions, num_directions);
161
162 output_results = new std::vector<RayResult>(num_origins);
163 #pragma omp parallel for schedule(dynamic)
164 for (int i = 0; i < num_directions; i++) {
165 float out_distance = -1; int out_id = -1;
166 if (ert->IntersectOutputArguments(origin, direction_pts[i], out_distance, out_id))
167 (*output_results)[i].SetHit(origin, direction_pts[i], out_distance, out_id);
168 }
169 break;
170 }
171 case ONE_DIRECTION:
172 {
173 std::array<float, 3> direction = { directions[0], directions[1], directions[2] };
174 auto origin_pts = ConvertRawFloatArrayToPoints(origins, num_origins);
175
176 output_results = new std::vector<RayResult>(num_origins);
177 #pragma omp parallel for schedule(dynamic)
178 for (int i = 0; i < num_origins; i++) {
179 float out_distance = -1; int out_id = -1;
180 if (ert->IntersectOutputArguments(origin_pts[i], direction, out_distance, out_id))
181 (*output_results)[i].SetHit(origin_pts[i], direction, out_distance, out_id);
182
183 }
184 break;
185 }
186 }
187
188 *out_results = output_results;
189 *results_data = output_results->data();
190 return OK;
191}
192
193C_INTERFACE CastRay(EmbreeRayTracer* ert, float& x, float& y, float& z, float dx, float dy, float dz, float max_distance, bool& result)
194{
195 result = ert->PointIntersection(x, y, z, dx, dy, dz, max_distance);
196 return OK;
197}
198
200 EmbreeRayTracer* ert,
201 float* origins,
202 const float* directions,
203 int size,
204 float max_distance,
205 bool* result_array
206) {
207 auto origin_array = ConvertRawFloatArrayToPoints(origins, size);
208 auto dir_array = ConvertRawFloatArrayToPoints(directions, size);
209 auto results = ert->PointIntersections(origin_array, dir_array, size, true, max_distance);
210
211 for (int i = 0; i < size; i++) {
212 if (results[i])
213 {
214 const int offset = i * 3;
215 const auto& hit_point = origin_array[i];
216 origins[offset] = hit_point[0];
217 origins[offset + 1] = hit_point[1];
218 origins[offset + 2] = hit_point[2];
219 result_array[i] = true;
220 }
221 else
222 result_array[i] = false;
223 }
224 return OK;
225}
226
227C_INTERFACE CastMultipleOriginsOneDirection(EmbreeRayTracer* ert, float* origins, const float* direction, int size, float max_distance, bool* result_array)
228{
229 auto origin_array = ConvertRawFloatArrayToPoints(origins, size);
230 auto dir_array = ConvertRawFloatArrayToPoints(direction, 1);
231 auto results = ert->PointIntersections(origin_array, dir_array, size, true, max_distance);
232
233 for (int i = 0; i < size; i++) {
234 if (results[i])
235 {
236 const int offset = i * 3;
237 const auto& hit_point = origin_array[i];
238 origins[offset] = hit_point[0];
239 origins[offset + 1] = hit_point[1];
240 origins[offset + 2] = hit_point[2];
241 result_array[i] = true;
242 }
243 else
244 result_array[i] = false;
245 }
246 return OK;
247}
248
249C_INTERFACE CastMultipleDirectionsOneOrigin(EmbreeRayTracer* ert, const float* origin, float* directions, int size, float max_distance, bool* result_array)
250{
251 auto origin_array = ConvertRawFloatArrayToPoints(origin, 1);
252 auto dir_array = ConvertRawFloatArrayToPoints(directions, size);
253 auto results = ert->PointIntersections(origin_array, dir_array, size, true, max_distance);
254
255 for (int i = 0; i < size; i++) {
256 if (results[i])
257 {
258 const int offset = i * 3;
259 const auto& hit_point = dir_array[i];
260 directions[offset] = hit_point[0];
261 directions[offset + 1] = hit_point[1];
262 directions[offset + 2] = hit_point[2];
263 result_array[i] = true;
264 }
265 else
266 result_array[i] = false;
267 }
268 return OK;
269}
270
271C_INTERFACE CastOcclusionRays(EmbreeRayTracer* ert, const float* origins, const float* directions, int origin_size, int direction_size, float max_distance, bool* result_array)
272{
273 auto origin_array = ConvertRawFloatArrayToPoints(origins, origin_size);
274 auto direction_array = ConvertRawFloatArrayToPoints(directions, direction_size);
275 const auto results = ert->Occlusions(origin_array, direction_array, max_distance, true);
276
277 std::copy(results.begin(), results.end(), result_array);
278 return OK;
279}
280
281C_INTERFACE DestroyRayResultVector(std::vector<RayResult>* var) {
282 DeleteRawPtr(var);
283 return OK;
284}
285
288 double x,
289 double y,
290 double z,
291 double dx,
292 double dy,
293 double dz,
294 double * out_distance)
295{
296
297 *out_distance = -1.0;
298 HF::RayTracer::HitStruct<double> hs = RT->Intersect(x, y, z, dx, dy, dz, -1.0, -1);
299
300 *out_distance = hs.distance;
301
302 return OK;
303}
Contains definitions for the Exceptions namespace.
Contains definitions for the MeshInfo class.
Contains definitions for the EmbreeRayTracer
std::vector< std::array< float, 3 > > ConvertRawFloatArrayToPoints(const float *raw_array, int size)
Convert a raw array from an external caller to an organized vector of points
Definition: CInterface.cpp:24
#define C_INTERFACE
Definition: analysis_C.h:16
void DeleteRawPtr(T *ptr)
Delete some object pointed to by ptr
C Interface header file for Raytracer functionality.
C_INTERFACE AddMeshes(HF::RayTracer::EmbreeRayTracer *ERT, MeshInfo **MI, int number_of_meshes)
Add a new mesh to a raytracer.
Definition: raytracer_C.cpp:71
C_INTERFACE CastSingleRayDistance(HF::RayTracer::EmbreeRayTracer *ert, const float *origin, const float *direction, const float max_distance, float *out_distance, int *out_meshid)
Cast a single ray and get the distance to its hit and the mesh ID if it hit anything....
Definition: raytracer_C.cpp:98
C_INTERFACE CreateRaytracer(MeshInfo *mesh, EmbreeRayTracer **out_raytracer, bool use_precise)
Create a new raytracer using several meshes.
Definition: raytracer_C.cpp:15
C_INTERFACE DestroyRayResultVector(std::vector< RayResult > *var)
Destroy a vector of rayresults.
C_INTERFACE CastMultipleRays(EmbreeRayTracer *ert, float *origins, const float *directions, int size, float max_distance, bool *result_array)
Cast multiple rays at once in parallel and receive their hitpoints in return. The number of direction...
C_INTERFACE AddMesh(HF::RayTracer::EmbreeRayTracer *ERT, MeshInfo *MI)
Add a new mesh to a raytracer.
Definition: raytracer_C.cpp:84
C_INTERFACE CastRaysDistance(HF::RayTracer::EmbreeRayTracer *ert, float *origins, int num_origins, float *directions, int num_directions, std::vector< RayResult > **out_results, RayResult **results_data)
Cast rays for each node in origins/directions as ordered pairs and get distance back as a result.
C_INTERFACE CastMultipleDirectionsOneOrigin(EmbreeRayTracer *ert, const float *origin, float *directions, int size, float max_distance, bool *result_array)
Cast rays from a single origin point in multiple directions and get a the points where they intersect...
C_INTERFACE CastRay(EmbreeRayTracer *ert, float &x, float &y, float &z, float dx, float dy, float dz, float max_distance, bool &result)
Cast a single ray from the raytracer and receive a point in return.
C_INTERFACE CreateRaytracerMultiMesh(MeshInfo **meshes, int num_meshes, EmbreeRayTracer **out_raytracer, bool use_precise)
Create a new raytracer using several meshes.
Definition: raytracer_C.cpp:39
C_INTERFACE DestroyRayTracer(HF::RayTracer::EmbreeRayTracer *rt_to_destroy)
Delete an existing raytracer.
Definition: raytracer_C.cpp:91
C_INTERFACE PreciseIntersection(HF::RayTracer::EmbreeRayTracer *RT, double x, double y, double z, double dx, double dy, double dz, double *out_distance)
C_INTERFACE CastOcclusionRays(EmbreeRayTracer *ert, const float *origins, const float *directions, int origin_size, int direction_size, float max_distance, bool *result_array)
Cast one or more occlusion rays in parallel.
C_INTERFACE CastMultipleOriginsOneDirection(EmbreeRayTracer *ert, float *origins, const float *direction, int size, float max_distance, bool *result_array)
Cast rays from each origin point in the given direction.
Custom exceptions and error codes used interally by DHARTAPI.
Definition: HFExceptions.h:22
@ INVALID_OBJ
The given path did not point to a valid obj file.
Definition: HFExceptions.h:40
@ OK
Operation was successful.
Definition: HFExceptions.h:32
@ MISSING_DEPEND
A dependency for this object is missing.
Definition: HFExceptions.h:43
@ GENERIC_ERROR
Not sure what happened here (If this gets thrown, either fix it or give it a status code!...
Definition: HFExceptions.h:38
The OBJ file was not valid.
Definition: HFExceptions.h:65
Thrown when a dependency is missing such as Embree.
Definition: HFExceptions.h:74
A collection of vertices and indices representing geometry.
Definition: meshinfo.h:124
A wrapper for Intel's Embree Library.
std::vector< char > PointIntersections(std::vector< std::array< float, 3 > > &origins, std::vector< std::array< float, 3 > > &directions, bool use_parallel=true, float max_distance=-1, int mesh_id=-1)
Cast multiple rays and recieve hitpoints in return.
bool AddMesh(std::vector< std::array< float, 3 > > &Mesh, int ID, bool Commit=false)
Add a new mesh to this raytracer's BVH with the specified ID.
bool IntersectOutputArguments(const N &node, const V &direction, return_type &out_distance, int &out_meshid, float max_distance=-1.0f)
Cast a ray from origin in direction and update the parameters instead of returning a hitstruct.
bool PointIntersection(std::array< float, 3 > &origin, const std::array< float, 3 > &dir, float distance=-1, int mesh_id=-1)
Cast a ray and overwrite the origin with the hitpoint if it intersects any geometry.
HitStruct< return_type > Intersect(const N &node, const V &direction, float max_distance=-1.0f, int mesh_id=-0.1f)
Cast a ray from origin in direction.
std::vector< char > Occlusions(const std::vector< std::array< float, 3 > > &origins, const std::vector< std::array< float, 3 > > &directions, float max_distance=-1, bool use_parallel=true)
Cast multiple occlusion rays in parallel.
A simple hit struct to carry all relevant information about hits.
Definition: HitStruct.h:7
numeric_type distance
Distance from the origin point to the hit point. Set to -1 if no hit was recorded.
Definition: HitStruct.h:8
The result of casting a ray at an object. Contains distance to the hitpoint and the ID of the mesh.
Definition: raytracer_C.h:89