171 lines
6.0 KiB
C++
171 lines
6.0 KiB
C++
/***********************************************************************************************************************
|
|
*
|
|
* Copyright (c) 2010 - 2025 by Tech Soft 3D, Inc.
|
|
* The information contained herein is confidential and proprietary to Tech Soft 3D, Inc., and considered a trade secret
|
|
* as defined under civil and criminal statutes. Tech Soft 3D shall pursue its civil and criminal remedies in the event
|
|
* of unauthorized use or misappropriation of its trade secrets. Use of this information by anyone other than authorized
|
|
* employees of Tech Soft 3D, Inc. is granted only under a written non-disclosure agreement, expressly prescribing the
|
|
* scope and manner of such use.
|
|
*
|
|
***********************************************************************************************************************/
|
|
|
|
#include <map>
|
|
#include "representation_item.h"
|
|
#include "../../utils/properties.h"
|
|
#include "../../utils/bounding_box.h"
|
|
#include "../../utils/geometry.h"
|
|
#include "../../model/exchange.h"
|
|
|
|
namespace he
|
|
{
|
|
namespace geometry
|
|
{
|
|
|
|
RepresentationItem::RepresentationItem(A3DRiRepresentationItem* rep_item, const A3DMiscCascadedAttributes* cascaded_attributes) :
|
|
Entity()
|
|
{
|
|
A3D_INITIALIZE_DATA(A3DMeshData, mesh_data);
|
|
// for each representation item list, we compute a mesh based on triangle only.
|
|
status = A3DRiComputeMesh(rep_item, cascaded_attributes, &mesh_data, nullptr);
|
|
if (status != A3D_SUCCESS)
|
|
{
|
|
A3DRWParamsTessellationData tess_params;
|
|
A3D_INITIALIZE_DATA(A3DRWParamsTessellationData, tess_params);
|
|
tess_params.m_eTessellationLevelOfDetail = kA3DTessLODMedium;
|
|
A3DRiRepresentationItemComputeTessellation(rep_item, &tess_params);
|
|
status = A3DRiComputeMesh(rep_item, cascaded_attributes, &mesh_data, nullptr);
|
|
}
|
|
}
|
|
|
|
RepresentationItem::~RepresentationItem()
|
|
{
|
|
A3DRiComputeMesh(nullptr, nullptr, &mesh_data, nullptr);
|
|
}
|
|
|
|
bool RepresentationItem::is_unicolor() const
|
|
{
|
|
return mesh_data.m_puiStyleIndexPerFace == nullptr;
|
|
}
|
|
|
|
|
|
|
|
void RepresentationItem::prepare_render_buffer(std::vector <utils::geometry::BufferData>& buffer_data_array)
|
|
{
|
|
if (is_unicolor())
|
|
{
|
|
utils::geometry::BufferData buffer_data;
|
|
build_one_buffer(buffer_data);
|
|
buffer_data_array.push_back(buffer_data);
|
|
}
|
|
else
|
|
{
|
|
build_buffer_per_style(buffer_data_array);
|
|
}
|
|
|
|
}
|
|
|
|
void RepresentationItem::build_one_buffer(utils::geometry::BufferData& buffer_data) const
|
|
{
|
|
buffer_data.vertices.reserve(mesh_data.m_uiCoordSize / 3);
|
|
|
|
// For each mesh, we create model buffer, and store graphical information, and all positions
|
|
// associated to it.
|
|
for (A3DUns32 vertex_i = 0; vertex_i < mesh_data.m_uiCoordSize; vertex_i+=3)
|
|
{
|
|
utils::geometry::Vertex vertex;
|
|
vertex.position = glm::vec3(mesh_data.m_pdCoords[vertex_i],
|
|
mesh_data.m_pdCoords[vertex_i + 1],
|
|
mesh_data.m_pdCoords[vertex_i + 2]);
|
|
vertex.normal = glm::vec3(mesh_data.m_pdNormals[vertex_i],
|
|
mesh_data.m_pdNormals[vertex_i + 1],
|
|
mesh_data.m_pdNormals[vertex_i + 2]);
|
|
|
|
buffer_data.mesh_box.add_point(vertex.position);
|
|
buffer_data.vertices.push_back(vertex);
|
|
}
|
|
|
|
// Count the total number of indices
|
|
size_t indiceCount = 0;
|
|
for (A3DUns32 face_i = 0; face_i < mesh_data.m_uiFaceSize; ++face_i) {
|
|
indiceCount += mesh_data.m_puiTriangleCountPerFace[face_i];
|
|
}
|
|
indiceCount *= 3; // 3 indices per triangle
|
|
buffer_data.indices.reserve(indiceCount);
|
|
|
|
for (A3DUns32 vertex_i = 0; vertex_i < indiceCount; vertex_i++)
|
|
buffer_data.indices.push_back(mesh_data.m_puiVertexIndicesPerFace[vertex_i]);
|
|
|
|
buffer_data.graphics = model::exchange::convert_style(mesh_data.m_uiStyleIndex);
|
|
}
|
|
|
|
void RepresentationItem::build_buffer_per_style(std::vector <utils::geometry::BufferData>& buffers_data) const
|
|
{
|
|
int idx = 0;
|
|
|
|
// sort face by style, and create one buffer data per style
|
|
|
|
std::map<A3DUns32, std::vector<A3DUns32>> style_face_indices;
|
|
std::vector<std::vector<A3DUns32>> vertex_indices_per_face(mesh_data.m_uiFaceSize);
|
|
A3DUns32 vertex_index = 0;
|
|
|
|
for (A3DUns32 f = 0; f < mesh_data.m_uiFaceSize; f++)
|
|
{
|
|
const A3DUns32 triangle_count = mesh_data.m_puiTriangleCountPerFace[f];
|
|
if (triangle_count == 0)
|
|
continue;
|
|
A3DUns32 face_style = mesh_data.m_puiStyleIndexPerFace[f];
|
|
style_face_indices[face_style].push_back(f);
|
|
|
|
// Store vertex indices per face
|
|
const A3DUns32 start_index = vertex_index;
|
|
const A3DUns32 end_index = vertex_index + (triangle_count * 3);
|
|
for (A3DUns32 v = start_index; v < end_index; ++v)
|
|
{
|
|
vertex_indices_per_face[f].push_back(mesh_data.m_puiVertexIndicesPerFace[v]);
|
|
}
|
|
vertex_index = end_index;
|
|
}
|
|
|
|
// for each mesh, we create OnpenGL model (buffer), and store graphical information, and all positions
|
|
// associated to it.
|
|
|
|
for (auto iter = style_face_indices.begin(); iter != style_face_indices.end(); ++iter)
|
|
{
|
|
utils::geometry::BufferData buffer_data;
|
|
buffer_data.graphics = model::exchange::convert_style(iter->first);
|
|
|
|
idx = 0;
|
|
for (auto& f : iter->second)
|
|
{
|
|
// for each face
|
|
A3DUns32 triangle_count = mesh_data.m_puiTriangleCountPerFace[f];
|
|
const std::vector<A3DUns32>& vertex_indices = vertex_indices_per_face[f];
|
|
|
|
std::vector<utils::geometry::Vertex> vertices;
|
|
utils::geometry::BoundingBox box;
|
|
utils::geometry::Vertex vertex;
|
|
for (A3DUns32 t = 0; t < triangle_count; t++)
|
|
{
|
|
// for each triangle
|
|
for (A3DUns32 v = 0; v < 3; v++)
|
|
{
|
|
const uint32_t indice = vertex_indices[t * 3 + v] * 3;
|
|
vertex.position = glm::vec3(mesh_data.m_pdCoords[indice],
|
|
mesh_data.m_pdCoords[indice + 1],
|
|
mesh_data.m_pdCoords[indice + 2]);
|
|
vertex.normal = glm::vec3(mesh_data.m_pdNormals[indice],
|
|
mesh_data.m_pdNormals[indice + 1],
|
|
mesh_data.m_pdNormals[indice + 2]);
|
|
|
|
buffer_data.mesh_box.add_point(vertex.position);
|
|
buffer_data.vertices.push_back(vertex);
|
|
buffer_data.indices.push_back(idx++);
|
|
}
|
|
}
|
|
}
|
|
buffers_data.push_back(buffer_data);
|
|
}
|
|
}
|
|
|
|
}
|
|
} |