This commit is contained in:
ninja
2025-12-15 23:22:33 +08:00
parent 019570564b
commit 8782765fbc
809 changed files with 118753 additions and 18289 deletions

View File

@@ -0,0 +1,40 @@
/***********************************************************************************************************************
*
* 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 "entity.h"
namespace he
{
Entity::Entity(A3DMiscCascadedAttributes* attrib) : attributes(attrib) {}
Entity::~Entity()
{
if (attributes)
{
if (A3DMiscCascadedAttributesDelete(attributes) != A3D_SUCCESS)
status = 1;
}
}
std::vector<A3DEntity*> Entity::sub_levels() const
{
return {};
}
namespace structure
{
int create_cascaded_attributes(const A3DRootBaseWithGraphics* entity, const A3DMiscCascadedAttributes* parent, A3DMiscCascadedAttributes*& attributes)
{
if (A3DMiscCascadedAttributesCreate(&attributes) != 0)
return 1;
if (A3DMiscCascadedAttributesPush(attributes, entity, parent))
return 1;
return 0;
}
}
}

View File

@@ -0,0 +1,45 @@
/***********************************************************************************************************************
*
* 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.
*
***********************************************************************************************************************/
#ifndef ENTITY_H
#define ENTITY_H
#include <vector>
#include <A3DSDKIncludes.h>
namespace he
{
namespace structure
{
int create_cascaded_attributes(const A3DRootBaseWithGraphics* entity, const A3DMiscCascadedAttributes* parent, A3DMiscCascadedAttributes*& attributes);
}
class Entity
{
protected:
int status = A3D_SUCCESS;
A3DMiscCascadedAttributes* attributes = nullptr;
public:
Entity(A3DMiscCascadedAttributes* attributes = nullptr);
~Entity();
int get_status() const {
return status;
}
const A3DMiscCascadedAttributes* get_attributes() const {
return attributes;
}
virtual std::vector<A3DEntity*> sub_levels() const;
};
}
#endif // ENTITY_H

View File

@@ -0,0 +1,60 @@
/***********************************************************************************************************************
*
* 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 "model_file.h"
#include "part.h"
#include "product_occurrence.h"
namespace he
{
namespace structure
{
ModelFile::ModelFile(A3DAsmModelFile* mdlFile)
{
A3D_INITIALIZE_DATA(A3DAsmModelFileData, data);
status = A3DAsmModelFileGet(mdlFile, &data);
if (status != A3D_SUCCESS)
return;
status = A3DMiscCascadedAttributesCreate(&attributes);
}
ModelFile::~ModelFile()
{
A3DAsmModelFileGet(nullptr, &data);
}
int ModelFile::collect(std::vector<Part>& parts)
{
if (status)
return 1;
A3DMiscCascadedAttributes* mdl_attribs = nullptr;
A3DMiscCascadedAttributesCreate(&mdl_attribs);
for (const auto po_entity : sub_levels())
{
A3DMiscCascadedAttributes* new_attributes = nullptr;
if (create_cascaded_attributes(po_entity, mdl_attribs, new_attributes) != 0)
return 1;
if (A3DMiscCascadedAttributesEntityReferencePush(new_attributes, po_entity, nullptr) != 0)
continue;
ProductOccurrence po(po_entity, new_attributes);
po.collect(parts, nullptr);
}
return 0;
}
std::vector<A3DEntity*> ModelFile::sub_levels() const
{
return std::vector<A3DEntity*>(data.m_ppPOccurrences, data.m_ppPOccurrences + data.m_uiPOccurrencesSize);
}
}
}

View File

@@ -0,0 +1,39 @@
/***********************************************************************************************************************
*
* 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.
*
***********************************************************************************************************************/
#ifndef MDL_FILE_H
#define MDL_FILE_H
#include "entity.h"
#include "part.h"
namespace he
{
namespace structure
{
class ModelFile : public Entity
{
A3DAsmModelFileData data;
A3DAsmModelFile* entity;
public:
ModelFile(A3DAsmModelFile* mdlFile);
~ModelFile();
const A3DAsmModelFileData& get_data() const {
return data;
}
std::vector<A3DEntity*> sub_levels() const override;
int collect(std::vector<Part>& parts);
};
}
}
#endif // MDL_FILE_H

View File

@@ -0,0 +1,130 @@
/***********************************************************************************************************************
*
* 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 "part.h"
#include <algorithm>
#include <A3DSDKIncludes.h>
namespace he
{
namespace structure
{
Part::Part(const Part& other) : Entity(other)
{
this->entity = other.entity;
this->contexts = other.contexts;
}
Part& Part::operator=(const Part& other)
{
if (this != &other)
{
this->entity = other.entity;
this->contexts = other.contexts;
}
return *this;
}
Part::Part(Part&& other) noexcept
{
this->entity = other.entity;
this->contexts = std::move(other.contexts);
}
Part& Part::operator=(Part&& other) noexcept
{
if (this != &other)
{
this->entity = other.entity;
this->contexts = std::move(other.contexts);
}
return *this;
}
Part::Part(A3DAsmPartDefinition* part, const A3DMiscCascadedAttributes* attributes, const glm::mat4& parentPosition) : entity(part)
{
A3DMiscCascadedAttributesData graphics_data;
A3D_INITIALIZE_DATA(A3DMiscCascadedAttributesData, graphics_data);
status = A3DMiscCascadedAttributesGet(attributes, &graphics_data);
contexts.push_back({ attributes, graphics_data, {parentPosition} });
}
const A3DAsmPartDefinition* Part::get_entity() const
{
return entity;
}
const std::vector<Context>& Part::get_contexts() const
{
return contexts;
}
std::vector<Context>& Part::grab_contexts()
{
return contexts;
}
bool Part::isSame(const A3DAsmPartDefinition* part_def, const A3DMiscCascadedAttributes* graphics, glm::mat4&& position)
{
if (this->entity != part_def)
return false;
A3DMiscCascadedAttributesData graphics_data;
A3D_INITIALIZE_DATA(A3DMiscCascadedAttributesData, graphics_data);
status = A3DMiscCascadedAttributesGet(graphics, &graphics_data);
if (status != A3D_SUCCESS)
return false;
auto it = std::find_if(
contexts.begin(),
contexts.end(),
[&] (Context& context)
{
const auto& gpx = std::get<1>(context);
auto& positions = std::get<2>(context);
if (graphics_data.m_sStyle.m_dWidth != gpx.m_sStyle.m_dWidth || graphics_data.m_sStyle.m_bVPicture != gpx.m_sStyle.m_bVPicture || graphics_data.m_sStyle.m_uiLinePatternIndex != gpx.m_sStyle.m_uiLinePatternIndex || graphics_data.m_sStyle.m_bMaterial != gpx.m_sStyle.m_bMaterial || graphics_data.m_sStyle.m_uiRgbColorIndex != gpx.m_sStyle.m_uiRgbColorIndex || graphics_data.m_sStyle.m_bIsTransparencyDefined != gpx.m_sStyle.m_bIsTransparencyDefined || graphics_data.m_sStyle.m_ucTransparency != gpx.m_sStyle.m_ucTransparency || graphics_data.m_sStyle.m_bSpecialCulling != gpx.m_sStyle.m_bSpecialCulling || graphics_data.m_sStyle.m_bFrontCulling != gpx.m_sStyle.m_bFrontCulling || graphics_data.m_sStyle.m_bBackCulling != gpx.m_sStyle.m_bBackCulling || graphics_data.m_sStyle.m_bNoLight != gpx.m_sStyle.m_bNoLight || graphics_data.m_sStyle.m_eRenderingMode != gpx.m_sStyle.m_eRenderingMode
// || graphics_data.m_usLayer != gpx.m_usLayer
)
{
contexts.push_back({ graphics, graphics_data, {position} });
return true;
}
positions.push_back(position);
return true;
});
if (it == contexts.end())
contexts.push_back({ graphics, graphics_data, {position} });
return true;
}
void traverse_ri(A3DRiRepresentationItem* ri, std::vector<A3DRiRepresentationItem*>& ri_list)
{
A3DEEntityType type = kA3DTypeUnknown;
A3DEntityGetType(ri, &type);
if (type == kA3DTypeRiSet)
{
A3DRiSetData data;
A3D_INITIALIZE_DATA(A3DRiSetData, data);
if (A3D_SUCCESS != A3DRiSetGet(ri, &data))
return;
for (A3DUns32 i = 0; i < data.m_uiRepItemsSize; i++)
traverse_ri(data.m_ppRepItems[i], ri_list);
}
else if(type != kA3DTypeRiPlane)
ri_list.push_back(ri);
};
void Part::ri_list(std::vector<A3DRiRepresentationItem*>& ri_list) const
{
A3DAsmPartDefinitionData data;
A3D_INITIALIZE_DATA(A3DAsmPartDefinitionData, data);
if (A3D_SUCCESS != A3DAsmPartDefinitionGet(entity, &data) || data.m_uiRepItemsSize == 0)
return;
for (A3DUns32 i = 0; i < data.m_uiRepItemsSize; i++)
traverse_ri(data.m_ppRepItems[i], ri_list);
A3DAsmPartDefinitionGet(nullptr, &data);
}
}
}

View File

@@ -0,0 +1,50 @@
/***********************************************************************************************************************
*
* 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.
*
***********************************************************************************************************************/
#ifndef PART_H
#define PART_H
#include <tuple>
#include <vector>
#include <glm/mat4x4.hpp>
#include "entity.h"
namespace he
{
namespace structure
{
using Context = std::tuple<const A3DMiscCascadedAttributes*, A3DMiscCascadedAttributesData, std::vector<glm::mat4>>;
class Part : public Entity
{
A3DAsmPartDefinition* entity = nullptr;
std::vector<Context> contexts;
public:
Part(A3DAsmPartDefinition* part, const A3DMiscCascadedAttributes* attributes, const glm::mat4& parentPosition);
~Part() = default;
Part(const Part& other);
Part& operator=(const Part& other);
Part(Part&& other) noexcept;
Part& operator=(Part&& other) noexcept;
public:
bool isSame(const A3DAsmPartDefinition* part_def, const A3DMiscCascadedAttributes* graphics, glm::mat4&& position);
const A3DAsmPartDefinition* get_entity() const;
void ri_list(std::vector<A3DRiRepresentationItem*>& ri_list) const;
const std::vector<Context>& get_contexts() const;
std::vector<Context>& grab_contexts();
};
}
}
#endif // PART_H

View File

@@ -0,0 +1,227 @@
/***********************************************************************************************************************
*
* 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 "product_occurrence.h"
#include <algorithm>
#include <tuple>
#include <glm/gtc/type_ptr.hpp>
#include <glm/mat4x4.hpp>
namespace he
{
namespace structure
{
ProductOccurrence::ProductOccurrence(const A3DAsmProductOccurrence* entity,
A3DMiscCascadedAttributes* attributes) : Entity(attributes)
{
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, data);
status = A3DAsmProductOccurrenceGet(entity, &data);
if (status != A3D_SUCCESS)
return;
A3D_INITIALIZE_DATA(A3DMiscCascadedAttributesData, attribute_data);
status = A3DMiscCascadedAttributesGet(attributes, &attribute_data);
if (status != A3D_SUCCESS)
return;
}
ProductOccurrence::~ProductOccurrence()
{
status = A3DMiscCascadedAttributesGet(nullptr, &attribute_data);
A3DAsmProductOccurrenceGet(nullptr, &data);
}
A3DAsmProductOccurrence* ProductOccurrence::get_reference()
{
if (data.m_pPrototype)
{
return data.m_pPrototype;
}
if (data.m_pExternalData)
{
return data.m_pExternalData;
}
return nullptr;
}
A3DMiscTransformation* ProductOccurrence::get_position()
{
if (data.m_pLocation)
{
return data.m_pLocation;
}
auto reference = get_reference();
if (reference)
{
ProductOccurrence next(reference);
return next.get_position();
}
return nullptr;
}
A3DAsmPartDefinition* ProductOccurrence::get_partdefinition()
{
if (data.m_pPart)
{
return data.m_pPart;
}
auto reference = get_reference();
if (reference)
{
ProductOccurrence next(reference);
return next.get_partdefinition();
}
return nullptr;
}
A3DVector3dData cross_product(const A3DVector3dData& X, const A3DVector3dData& Y)
{
A3DVector3dData Z;
Z.m_dX = X.m_dY * Y.m_dZ - X.m_dZ * Y.m_dY;
Z.m_dY = X.m_dZ * Y.m_dX - X.m_dX * Y.m_dZ;
Z.m_dZ = X.m_dX * Y.m_dY - X.m_dY * Y.m_dX;
return Z;
}
int get_glm_matrix(const A3DMiscTransformation* transfo, glm::mat4& matrix_out)
{
A3DEEntityType type = kA3DTypeUnknown;
A3DEntityGetType(transfo, &type);
if (type == kA3DTypeMiscCartesianTransformation)
{
A3DMiscCartesianTransformationData data;
A3D_INITIALIZE_DATA(A3DMiscCartesianTransformationData, data);
if (A3DMiscCartesianTransformationGet(transfo, &data))
return 1;
const auto sZVector = cross_product(data.m_sXVector, data.m_sYVector);
const double dMirror = ( data.m_ucBehaviour & kA3DTransformationMirror ) ? -1. : 1.;
double matrix[16];
matrix[12] = data.m_sOrigin.m_dX;
matrix[13] = data.m_sOrigin.m_dY;
matrix[14] = data.m_sOrigin.m_dZ;
matrix[15] = 1.;
matrix[0] = data.m_sXVector.m_dX * data.m_sScale.m_dX;
matrix[1] = data.m_sXVector.m_dY * data.m_sScale.m_dX;
matrix[2] = data.m_sXVector.m_dZ * data.m_sScale.m_dX;
matrix[3] = 0.;
matrix[4] = data.m_sYVector.m_dX * data.m_sScale.m_dY;
matrix[5] = data.m_sYVector.m_dY * data.m_sScale.m_dY;
matrix[6] = data.m_sYVector.m_dZ * data.m_sScale.m_dY;
matrix[7] = 0.;
matrix[8] = dMirror * sZVector.m_dX * data.m_sScale.m_dZ;
matrix[9] = dMirror * sZVector.m_dY * data.m_sScale.m_dZ;
matrix[10] = dMirror * sZVector.m_dZ * data.m_sScale.m_dZ;
matrix[11] = 0.;
matrix_out = glm::make_mat4(matrix);
if (A3DMiscCartesianTransformationGet(nullptr, &data))
return 1;
return 0;
}
else
{
return 1;
}
}
glm::mat4 ProductOccurrence::compute_position(const glm::mat4* parent_position)
{
A3DMiscTransformation* pLocation = get_position();
glm::mat4 local_position = glm::mat4(1.f);
if (pLocation)
get_glm_matrix(pLocation, local_position);
if (parent_position)
local_position = ( *parent_position ) * local_position;
return local_position;
}
int compare(const A3DMiscCascadedAttributesData& data1, const A3DMiscCascadedAttributesData& data2)
{
return ( data1.m_sStyle.m_dWidth == data2.m_sStyle.m_dWidth
&& data1.m_sStyle.m_bVPicture == data2.m_sStyle.m_bVPicture
&& data1.m_sStyle.m_uiLinePatternIndex == data2.m_sStyle.m_uiLinePatternIndex
&& data1.m_sStyle.m_bMaterial == data2.m_sStyle.m_bMaterial
&& data1.m_sStyle.m_uiRgbColorIndex == data2.m_sStyle.m_uiRgbColorIndex
&& data1.m_sStyle.m_bIsTransparencyDefined == data2.m_sStyle.m_bIsTransparencyDefined
&& data1.m_sStyle.m_ucTransparency == data2.m_sStyle.m_ucTransparency
&& data1.m_sStyle.m_bSpecialCulling == data2.m_sStyle.m_bSpecialCulling
&& data1.m_sStyle.m_bFrontCulling == data2.m_sStyle.m_bFrontCulling
&& data1.m_sStyle.m_bBackCulling == data2.m_sStyle.m_bBackCulling
&& data1.m_sStyle.m_bNoLight == data2.m_sStyle.m_bNoLight
&& data1.m_sStyle.m_eRenderingMode == data2.m_sStyle.m_eRenderingMode
);
}
void ProductOccurrence::push_part(std::vector<Part>& parts, const glm::mat4& new_position)
{
auto new_part = get_partdefinition();
if (!new_part)
return;
A3DMiscCascadedAttributes* new_attributes;
create_cascaded_attributes(new_part, attributes, new_attributes);
auto it = std::find_if(parts.begin(), parts.end(), [&new_part] (Part& part)
{ return part.get_entity() == new_part; });
if (it == parts.end())
parts.emplace_back(Part(new_part, new_attributes, new_position));
else
{
A3DMiscCascadedAttributesData attrib_data;
A3D_INITIALIZE_DATA(A3DMiscCascadedAttributesData, attrib_data);
A3DMiscCascadedAttributesGet(new_attributes, &attrib_data);
std::vector<Context>& contexes = ( it )->grab_contexts();
auto context_it = std::find_if(contexes.begin(), contexes.end(), [&attrib_data] (const Context& context) {
const auto& gpx = std::get<1>(context);
return compare(attrib_data, gpx);
});
if (context_it == contexes.end())
contexes.push_back({ new_attributes, attrib_data, {new_position} });
else
{
auto& positions = std::get<2>(*context_it);
positions.push_back(new_position);
}
}
}
std::vector<A3DEntity*> ProductOccurrence::sub_levels() const
{
return std::vector<A3DEntity*>(data.m_ppPOccurrences, data.m_ppPOccurrences + data.m_uiPOccurrencesSize);
}
bool ProductOccurrence::skip() const
{
return (
!attribute_data.m_bShow || attribute_data.m_bRemoved || data.m_ucBehaviour != 1 );
}
int ProductOccurrence::collect(std::vector<Part>& parts, const glm::mat4* parent_position)
{
auto new_position = compute_position(parent_position);
push_part(parts, new_position);
for (const auto& po_entity : sub_levels())
{
A3DMiscCascadedAttributes* new_attributes;
if (create_cascaded_attributes(po_entity, get_attributes(), new_attributes) != 0)
continue;
if (A3DMiscCascadedAttributesEntityReferencePush(new_attributes, po_entity, nullptr) != 0)
continue;
ProductOccurrence po(po_entity, new_attributes);
if (po.collect(parts, &new_position))
return 1;
}
return 0;
}
}
}

View File

@@ -0,0 +1,51 @@
/***********************************************************************************************************************
*
* 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.
*
***********************************************************************************************************************/
#ifndef PRODUCT_OCCURENCE_H
#define PRODUCT_OCCURENCE_H
#include "entity.h"
#include "part.h"
namespace he
{
namespace structure
{
class ProductOccurrence : public Entity
{
A3DAsmProductOccurrenceData data;
A3DMiscCascadedAttributesData attribute_data;
private:
A3DMiscTransformation* get_position();
A3DAsmPartDefinition* get_partdefinition();
A3DAsmProductOccurrence* get_reference();
glm::mat4 compute_position(const glm::mat4* parent_position);
void push_part(std::vector<Part>& parts, const glm::mat4& new_position);
public:
ProductOccurrence(const A3DAsmProductOccurrence* asmProductOccurrence,
A3DMiscCascadedAttributes* attributes = nullptr);
~ProductOccurrence();
const A3DAsmProductOccurrenceData& get_data() const {
return data;
}
const A3DMiscCascadedAttributesData& get_attribute_data() const {
return attribute_data;
}
std::vector<A3DEntity*> sub_levels() const override;
bool skip() const;
int collect(std::vector<Part>& parts, const glm::mat4* parent_position);
};
}
}
#endif // PRODUCT_OCCURENCE_H

View File

@@ -0,0 +1,171 @@
/***********************************************************************************************************************
*
* 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);
}
}
}
}

View File

@@ -0,0 +1,36 @@
/***********************************************************************************************************************
*
* 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.
*
***********************************************************************************************************************/
#ifndef REP_ITEM_H
#define REP_ITEM_H
#include "entity.h"
#include "../../utils/geometry.h"
namespace he
{
namespace geometry
{
class RepresentationItem : public Entity
{
A3DMeshData mesh_data;
public:
RepresentationItem(A3DRiRepresentationItem* rep_item, const A3DMiscCascadedAttributes* cascaded_attributes);
~RepresentationItem();
bool is_unicolor() const;
void prepare_render_buffer(std::vector <utils::geometry::BufferData>& buffer_data_array);
private:
void build_one_buffer(utils::geometry::BufferData& buffer_data) const;
void build_buffer_per_style(std::vector <utils::geometry::BufferData>& buffers_data) const;
};
}
}
#endif // REP_ITEM_H