DHART
Loading...
Searching...
No Matches
VisibilityGraph

Functions

C_INTERFACE CreateVisibilityGraphAllToAll (HF::RayTracer::EmbreeRayTracer *ert, const float *nodes, int num_nodes, HF::SpatialStructures::Graph **out_graph, float height)
 Create a new directed visibility graph between all nodes in parameter nodes. More...
 
C_INTERFACE CreateVisibilityGraphAllToAllUndirected (HF::RayTracer::EmbreeRayTracer *ert, const float *nodes, int num_nodes, HF::SpatialStructures::Graph **out_graph, float height, const int cores)
 Create a new undirected visibility graph between all nodes in nodes. More...
 
C_INTERFACE CreateVisibilityGraphGroupToGroup (HF::RayTracer::EmbreeRayTracer *ert, const float *group_a, const int size_a, const float *group_b, const int size_b, HF::SpatialStructures::Graph **out_graph, float height)
 Create a new visibility graph from the nodes in group_a, into the nodes of group_b. More...
 

Detailed Description

Determine which points are visible from other points in space.

Function Documentation

◆ CreateVisibilityGraphAllToAll()

C_INTERFACE CreateVisibilityGraphAllToAll ( HF::RayTracer::EmbreeRayTracer ert,
const float *  nodes,
int  num_nodes,
HF::SpatialStructures::Graph **  out_graph,
float  height 
)

#include <Cinterface/visibility_graph_C.h>

Create a new directed visibility graph between all nodes in parameter nodes.

Parameters
ertThe raytracer to cast rays from
nodesCoordinates of nodes to use in generating the visibility graph. Every three floats (every three members in nodes) should represent a single node (point) {x, y, z}
num_nodesAmount of nodes (points) that will be used to generate the visibility graph. This should be equal to (size of nodes / 3), since every three floats represents a single point.
out_graphAddress of (HF::SpatialStructures::Graph *); address of a pointer to a HF::SpatialStructures::Graph. (out_graph) will point to memory allocated by CreateVisibilityGraphAllToAll.
heightHow far to offset nodes from the ground.
Returns
HF_STATUS::OK on completion
See also
Mesh setup (How to create a mesh), (How to destroy a mesh)
Raytracer setup (How to create a BVH), Raytracer teardown (How to destroy a BVH)

Begin by loading an .obj file (Mesh setup).
Then, create a BVH (Raytracer setup) using the mesh.

Set up the parameters for the visibility graph.

// The model is a flat plane, so only nodes 0, 2 should connect.
// Every three floats should represent a single (x, y, z) point.
const std::array<float, 9> points { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -10.0f, 0.0f, 2.0f, 0.0f };
// This should be the array element count within points.
const int points_size = static_cast<int>(points.size());
// Represents how far to offset nodes from the ground.
const float height = 1.7f;
// Total amount of nodes to use in the visibility graph.
const int points_count = points_size / 3;

Now we are ready to call CreateVisibilityGraphAllToAll .

// Declare a pointer to Graph.
//
// Notice that we pass the address of VG to CreateVisibilityAllToAll.
// CreateVisibilityAllToAll will assign the deferenced address to a pointer that points
// to memory on the free store. We will call DestroyGraph to release the memory resources later on.
status = CreateVisibilityGraphAllToAll(bvh, points.data(), points_count, &VG, height);
if (status != 1) {
// Error!
std::cerr << "Error at CreateVisibilityGraphAllToAll, code: " << status << std::endl;
}
C_INTERFACE CreateVisibilityGraphAllToAll(EmbreeRayTracer *ert, const float *nodes, int num_nodes, Graph **out_graph, float height)
Create a new directed visibility graph between all nodes in parameter nodes.
A Graph of nodes connected by edges that supports both integers and HF::SpatialStructures::Node.
Definition: graph.h:486

Very important: after generating/adding edges to a graph – it must be compressed.

// Always compress the graph after generating a graph/adding new edges
status = Compress(VG);
if (status != 1) {
// Error!
std::cerr << "Error at Compress, code: " << status << std::endl;
}
//
// VG, the visibility graph, is now ready for use.
//
C_INTERFACE Compress(Graph *graph)
Compress the given graph into a CSR representation.

You are now ready to use the visibility graph. Start by retrieving the CSR representation of the graph:

// Retrieve CSR representation of graph
// The parameter default name refers to an alternate edge cost type.
// An empty string means we are using the default cost type
// (the costs that the graph was created with),
// but alternate edge costs could also be 'CrossSlope' or 'EnergyExpenditure', etc.
const char* default_name = "";
status = GetCSRPointers(VG,
&csr.nnz, &csr.rows, &csr.cols,
&csr.data, &csr.inner_indices, &csr.outer_indices,
default_name);
if (status != 1) {
// Error!
std::cerr << "Error at GetCSRPointers, code: " << status << std::endl;
}
C_INTERFACE GetCSRPointers(Graph *graph, int *out_nnz, int *out_num_rows, int *out_num_cols, float **out_data_ptr, int **out_inner_indices_ptr, int **out_outer_indices_ptr, const char *cost_type)
Retrieve all information for a graph's CSR representation. This will compress the graph if it was not...
A struct to hold all necessary information for a CSR.
Definition: graph.h:54
int * outer_indices
Stores for each column (resp. row) the index of the first non-zero in the previous two arrays.
Definition: graph.h:60
int cols
Number of columns in this CSR.
Definition: graph.h:57
int nnz
Number of non-zeros contained by the CSR.
Definition: graph.h:55
int * inner_indices
Stores the row (resp. column) indices of the non-zeros.
Definition: graph.h:61
float * data
Stores the coefficient values of the non-zeros.
Definition: graph.h:59
int rows
Number of rows in this CSR.
Definition: graph.h:56

Set up the pointers required to iterate over the CSR. Then output the CSR to the console:

//
// Setting up a CSR 'iterator'
//
float* curr = csr.data; // address of current position within edge data
float* data_end = csr.data + csr.nnz; // address of one-past the last element within edge data
int* inner = csr.inner_indices; // address of current position within child node id buffer (column value)
int row = 0; // value denoting the current parent node id (row number)
while (curr < data_end) {
// While edge data remains...
// Note the current position within the edge data buffer.
// This is the address that denotes the beginning of a row.
float* row_begin = curr;
// If we are at the last row index,
// row_end is data_end -- else,
// row_end is the address of the next row's (row + 1) initial value.
float* row_end =
(row == csr.rows - 1)
? data_end : csr.data + csr.outer_indices[row + 1];
while (curr < row_end) {
// While curr is not at the end of the current row...
// row is the parent node id
// *inner is the child node id
// *curr is the edge value between parent node id and child node id
std::cout << "(" << row << ", " << *inner << ")"
<< "\t\t" << *curr << std::endl;
++inner; // advance the address of inner (child node id buffer)
++curr; // advance the address of curr (edge data buffer)
}
++row; // advance the row value (parent node id)
}

After use, the visibility graph resources must be relinquished:

// destroy VG (visibility graph)
status = DestroyGraph(VG);
if (status != 1) {
std::cerr << "Error at DestroyGraph, code: " << status << std::endl;
}
C_INTERFACE DestroyGraph(HF::SpatialStructures::Graph *graph_to_destroy)
Delete a graph.
Definition: CInterface.cpp:80

From here, please review the example at Raytracer teardown for instructions
on how to free the remainder of the resources used by the visibility graph –
which are the (vector<HF::Geometry::MeshInfo> *) and (HF::Raytracer::EmbreeRayTracer *) instances.

>>> LoadOBJ loaded mesh successfully into loaded_obj at address 0000014ECADE5200, code: 1
>>> CreateRaytracer created EmbreeRayTracer successfully into bvh at address 0000014ECAD825A0, code: 1
>>> (0, 2) 2.23607
>>> (2, 0) 2.23607

Definition at line 16 of file visibility_graph_C.cpp.

References HF::VisibilityGraph::AllToAll(), ConvertRawFloatArrayToPoints(), and HF::Exceptions::OK.

+ Here is the call graph for this function:

◆ CreateVisibilityGraphAllToAllUndirected()

C_INTERFACE CreateVisibilityGraphAllToAllUndirected ( HF::RayTracer::EmbreeRayTracer ert,
const float *  nodes,
int  num_nodes,
HF::SpatialStructures::Graph **  out_graph,
float  height,
const int  cores 
)

#include <Cinterface/visibility_graph_C.h>

Create a new undirected visibility graph between all nodes in nodes.

Parameters
ertThe raytracer to cast rays from
nodesCoordinates of nodes to use in generating the visibility graph. Every three floats (every three members in nodes) should represent a single node (point) {x, y, z}
num_nodesAmount of nodes (points) that will be used to generate the visibility graph. This should be equal to (size of nodes / 3), since every three floats represents a single point.
out_graphAddress of (HF::SpatialStructures::Graph *); address of a pointer to a HF::SpatialStructures::Graph. (out_graph) will point to memory allocated by CreateVisibilityGraphAllToAllUndirected.
heightHow far to offset nodes from the ground.
coresCPU core count. A value of (-1) means to use all available cores on the system.
Returns
HF_STATUS::OK on completion
See also
Raytracer setup (How to create a BVH), Raytracer teardown (How to destroy a BVH)
Mesh setup (How to create a mesh), (How to destroy a mesh)
Raytracer setup (How to create a BVH), Raytracer teardown (How to destroy a BVH)

Begin by loading an .obj file (Mesh setup).
Then, create a BVH (Raytracer setup) using the mesh.

// The model is a flat plane, so only nodes 0, 2 should connect.
// Every three floats should represent a single (x, y, z) point.
const std::array<float, 9> points { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -10.0f, 0.0f, 2.0f, 0.0f };
// This should be the array element count within points.
const int points_size = points.size();
// Represents how far to offset nodes from the ground.
const float height = 1.7f;
// Total amount of nodes to use in the visibility graph.
const int points_count = points_size / 3;
// CPU core count. -1 means to use all avaiable cores on the client system.
const int core_count = -1;

Now we are ready to call CreateVisibilityGraphAllToAllUndirected .

// Declare a pointer to Graph.
//
// Notice that we pass the address of VG to CreateVisibilityAllToAllUndirected.
// CreateVisibilityAllToAllUndirected will assign the deferenced address to a pointer that points
// to memory on the free store. We will call DestroyGraph to release the memory resources later on.
status = CreateVisibilityGraphAllToAllUndirected(bvh, points.data(), points_count, &VG, height, core_count);
if (status != 1) {
// Error!
std::cerr << "Error at CreateVisibilityGraphAllToAllUndirected, code: " << status << std::endl;
}
C_INTERFACE CreateVisibilityGraphAllToAllUndirected(EmbreeRayTracer *ert, const float *nodes, int num_nodes, Graph **out_graph, float height, const int cores)
Create a new undirected visibility graph between all nodes in nodes.

Very important: after generating/adding edges to a graph – it must be compressed.

// Always compress the graph after generating a graph/adding new edges
status = Compress(VG);
if (status != 1) {
// Error!
std::cerr << "Error at Compress, code: " << status << std::endl;
}
//
// VG, the visibility graph, is now ready for use.
//

You are now ready to use the visibility graph. Start by retrieving the CSR representation of the graph:

// Retrieve CSR representation of graph
// The parameter default name refers to an alternate edge cost type.
// An empty string means we are using the default cost type
// (the costs that the graph was created with),
// but alternate edge costs could also be 'CrossSlope' or 'EnergyExpenditure', etc.
const char* default_name = "";
status = GetCSRPointers(VG,
&csr.nnz, &csr.rows, &csr.cols,
&csr.data, &csr.inner_indices, &csr.outer_indices,
default_name);
if (status != 1) {
// Error!
std::cerr << "Error at GetCSRPointers, code: " << status << std::endl;
}

Set up the pointers required to iterate over the CSR. Then output the CSR to the console:

//
// Setting up a CSR 'iterator'
//
float* curr = csr.data; // address of current position within edge data
float* data_end = csr.data + csr.nnz; // address of one-past the last element within edge data
int* inner = csr.inner_indices; // address of current position within child node id buffer (column value)
int row = 0; // value denoting the current parent node id (row number)
while (curr < data_end) {
// While edge data remains...
// Note the current position within the edge data buffer.
// This is the address that denotes the beginning of a row.
float* row_begin = curr;
// If we are at the last row index,
// row_end is data_end -- else,
// row_end is the address of the next row's (row + 1) initial value.
float* row_end =
(row == csr.rows - 1)
? data_end : csr.data + csr.outer_indices[row + 1];
while (curr < row_end) {
// While curr is not at the end of the current row...
// row is the parent node id
// *inner is the child node id
// *curr is the edge value between parent node id and child node id
std::cout << "(" << row << ", " << *inner << ")"
<< "\t\t" << *curr << std::endl;
++inner; // advance the address of inner (child node id buffer)
++curr; // advance the address of curr (edge data buffer)
}
++row; // advance the row value (parent node id)
}

After use, the visibility graph resources must be relinquished:

// destroy VG (visibility graph)
status = DestroyGraph(VG);
if (status != 1) {
std::cerr << "Error at DestroyGraph, code: " << status << std::endl;
}

From here, please review the example at Raytracer teardown for instructions
on how to free the remainder of the resources used by the visibility graph –
which are the (vector<HF::Geometry::MeshInfo> *) and (HF::Raytracer::EmbreeRayTracer *) instances.

>>> LoadOBJ loaded mesh successfully into loaded_obj at address 0000014ECADE5140, code: 1
>>> CreateRaytracer created EmbreeRayTracer successfully into bvh at address 0000014ECAD82AA0, code: 1
>>> (0, 2) 2.23607

Definition at line 40 of file visibility_graph_C.cpp.

References HF::VisibilityGraph::AllToAllUndirected(), ConvertRawFloatArrayToPoints(), and HF::Exceptions::OK.

+ Here is the call graph for this function:

◆ CreateVisibilityGraphGroupToGroup()

C_INTERFACE CreateVisibilityGraphGroupToGroup ( HF::RayTracer::EmbreeRayTracer ert,
const float *  group_a,
const int  size_a,
const float *  group_b,
const int  size_b,
HF::SpatialStructures::Graph **  out_graph,
float  height 
)

#include <Cinterface/visibility_graph_C.h>

Create a new visibility graph from the nodes in group_a, into the nodes of group_b.

Parameters
ertThe raytracer to cast rays from
group_aCoordinates of nodes to cast rays from. (source node coordinates) Every three floats (every three members in nodes) should represent a single node (point) {x, y, z}
size_aAmount of nodes (points) in group_a. This should be equal to (size of group_a / 3), since every three floats represents a single point.
group_bCoordinates of nodes to cast rays at. (destination node coordinates)
size_bAmount of nodes (points) in group_b. This should be equal to (size of group_b / 3), since every three floats represents a single point.
out_graphAddress of (HF::SpatialStructures::Graph *); address of a pointer to a HF::SpatialStructures::Graph. (out_graph) will point to memory allocated by CreateVisibilityGraphGroupToGroup.
heightHow far to offset nodes from the ground.
Returns
HF_STATUS::OK on completion
See also
Mesh setup (How to create a mesh), (How to destroy a mesh)
Raytracer setup (How to create a BVH), Raytracer teardown (How to destroy a BVH)

Begin by loading an .obj file (Mesh setup).
Then, create a BVH (Raytracer setup) using the mesh.

Set up the parameters for the visibility graph.

// The first coordinate array - the source node coordinates.
const std::array<float, 9> coords_a { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -10.0f, 0.0f, 2.0f, 0.0f };
// Element count of the first coordinate array, 'coords_a'.
const int size_coords_a = static_cast<int>(coords_a.size());
// Total count of nodes in coords_a.
// Every three coordinates { x, y, z } represents a single node (point).
const int count_nodes_a = size_coords_a / 3;
// The second coordinates array - the destination node coordinates.
const std::array<float, 9> coords_b { 10.0f, 10.0f, 11.0f, 10.0f, 10.0f, 0.0f, 10.0f, 12.0f, 10.0f };
// Element count of the second coordinate array, 'coords_b'.
const int size_coords_b = static_cast<int>(coords_b.size());
// Total count of nodes in coords_b.
// Every three coordinates { x, y, z } represents a single node (point).
const int count_nodes_b = size_coords_b / 3;
// Distance of node offset from the ground.
const float height = 1.7f;

Now we are ready to call CreateVisibilityGraphGroupToGroup .

// Declare a pointer to Graph.
//
// Notice that we pass the address of VG to CreateVisibilityGraphGroupToGroup.
// CreateVisibilityGraphGroupToGroup will assign the deferenced address to a pointer that points
// to memory on the free store. We will call DestroyGraph to release the memory resources later on.
status = CreateVisibilityGraphGroupToGroup(bvh, coords_a.data(), count_nodes_a, coords_b.data(), count_nodes_b, &VG, height);
if (status != 1) {
// Error!
std::cerr << "Error at CreateVisibilityGraphGroupToGroup, code: " << status << std::endl;
}
C_INTERFACE CreateVisibilityGraphGroupToGroup(HF::RayTracer::EmbreeRayTracer *ert, const float *group_a, const int size_a, const float *group_b, const int size_b, Graph **out_graph, float height)
Create a new visibility graph from the nodes in group_a, into the nodes of group_b.

Very important: after generating/adding edges to a graph – it must be compressed.

// Always compress the graph after generating a graph/adding new edges
status = Compress(VG);
if (status != 1) {
// Error!
std::cerr << "Error at Compress, code: " << status << std::endl;
}

You are now ready to use the visibility graph. Start by retrieving the CSR representation of the graph:

// Retrieve CSR representation of graph
// The parameter default name refers to an alternate edge cost type.
// An empty string means we are using the default cost type
// (the costs that the graph was created with),
// but alternate edge costs could also be 'CrossSlope' or 'EnergyExpenditure', etc.
const char* default_name = "";
status = GetCSRPointers(VG,
&csr.nnz, &csr.rows, &csr.cols,
&csr.data, &csr.inner_indices, &csr.outer_indices,
default_name);
if (status != 1) {
// Error!
std::cerr << "Error at GetCSRPointers, code: " << status << std::endl;
}

Set up the pointers required to iterate over the CSR. Then output the CSR to the console:

//
// Setting up a CSR 'iterator'
//
float* curr = csr.data; // address of current position within edge data
float* data_end = csr.data + csr.nnz; // address of one-past the last element within edge data
int* inner = csr.inner_indices; // address of current position within child node id buffer (column value)
int row = 0; // value denoting the current parent node id (row number)
while (curr < data_end) {
// While edge data remains...
// Note the current position within the edge data buffer.
// This is the address that denotes the beginning of a row.
float* row_begin = curr;
// If we are at the last row index,
// row_end is data_end -- else,
// row_end is the address of the next row's (row + 1) initial value.
float* row_end =
(row == csr.rows - 1)
? data_end : csr.data + csr.outer_indices[row + 1];
while (curr < row_end) {
// While curr is not at the end of the current row...
// row is the parent node id
// *inner is the child node id
// *curr is the edge value between parent node id and child node id
std::cout << "(" << row << ", " << *inner << ")"
<< "\t\t" << *curr << std::endl;
++inner; // advance the address of inner (child node id buffer)
++curr; // advance the address of curr (edge data buffer)
}
++row; // advance the row value (parent node id)
}

After use, the visibility graph resources must be relinquished:

// destroy VG (visibility graph)
status = DestroyGraph(VG);
if (status != 1) {
std::cerr << "Error at DestroyGraph, code: " << status << std::endl;
}

From here, please review the example at Raytracer teardown for instructions
on how to free the remainder of the resources used by the visibility graph –
which are the (vector<HF::Geometry::MeshInfo> *) and (HF::Raytracer::EmbreeRayTracer *) instances.

>>> LoadOBJ loaded mesh successfully into loaded_obj at address 0000014ECADE4C60, code: 1
>>> CreateRaytracer created EmbreeRayTracer successfully into bvh at address 0000014ECAD82320, code: 1
>>> (0, 3) 17.3205
>>> (0, 4) 14.1774
>>> (0, 5) 18.0278
>>> (2, 3) 16.8819
>>> (2, 4) 12.8062
>>> (2, 5) 17.3205

Definition at line 64 of file visibility_graph_C.cpp.

References ConvertRawFloatArrayToPoints(), HF::VisibilityGraph::GroupToGroup(), HF::Exceptions::NO_GRAPH, and HF::Exceptions::OK.

+ Here is the call graph for this function: