Merge branch 'develop' into david/cnx-150-implement-selectionbinding

This commit is contained in:
Ralph Wessel
2024-10-16 15:04:07 +01:00
committed by GitHub
31 changed files with 1996 additions and 74 deletions
@@ -5,6 +5,7 @@
#include "Speckle/Database/Identity/RecordID.h"
#include "Speckle/Database/Storage/ArchicadDBase/Element/ArchicadElementDBaseEngine.h"
#include "Speckle/Record/Element/Element.h"
#include "Speckle/Record/Element/Memo.h"
#include <array>
@@ -107,6 +108,25 @@ Vector<Element> BIMElementDatabase::getElements() const {
} //BIMElementDatabase::getElements
/*--------------------------------------------------------------------
Get memo memo (supplementary) data for a specified element
elementID: The of the source element
filter: Filter for the required supplementary data
return: The requested element memo data (nullptr on failure)
--------------------------------------------------------------------*/
Memo::Unique BIMElementDatabase::getMemo(const BIMRecordID& elementID, Part::filter_bits filter) const {
//NB: The filter bits are passed as the source document ID
auto result = m_engine->getObject(elementID, ArchicadElementDBaseEngine::memoTable, Guid::fromInt(filter));
if (auto memo = dynamic_cast<Memo*>(result.get()); memo != nullptr) {
result.release();
return Memo::Unique{memo};
}
return nullptr;
} //BIMElementDatabase::getMemo
/*--------------------------------------------------------------------
Write an element to storage
@@ -3,12 +3,17 @@
#include "Speckle/Database/Identity/BIMLink.h"
#include "Speckle/Record/Element/Element.h"
#include "Speckle/Record/Element/Interface/Part.h"
#include "Speckle/Utility/Guid.h"
namespace active::event {
class Subscriber;
}
namespace speckle::record::element {
class Memo;
}
namespace speckle::database {
/*!
@@ -43,19 +48,26 @@ namespace speckle::database {
@param documentID Optional document ID (when the object is bound to a specific document)
@return The requested element (nullptr on failure)
*/
record::element::Element::Unique getElement(const BIMRecordID& elementID, std::optional<BIMRecordID> tableID = std::nullopt,
std::unique_ptr<record::element::Element> getElement(const BIMRecordID& elementID, std::optional<BIMRecordID> tableID = std::nullopt,
std::optional<BIMRecordID> documentID = std::nullopt) const;
/*!
Get a specified element
@param link A link to the target element
@return The requested element (nullptr on failure)
*/
record::element::Element::Unique getElement(const BIMLink& link) const { return getElement(link, link.tableID, link.docID); }
std::unique_ptr<record::element::Element> getElement(const BIMLink& link) const { return getElement(link, link.tableID, link.docID); }
/*!
Get all model elements
@return All the elements
*/
active::container::Vector<record::element::Element> getElements() const;
/*!
Get memo memo (supplementary) data for a specified element
@param elementID The of the source element
@param filter Filter for the required supplementary data
@return The requested element memo data (nullptr on failure)
*/
std::unique_ptr<record::element::Memo> getMemo(const BIMRecordID& elementID, record::element::Part::filter_bits filter) const;
/*!
Write an element to storage
@param element The element to write
@@ -40,7 +40,7 @@ bool Record::fillInventory(active::serialise::Inventory& inventory) const {
}.withType(&typeid(base)));
inventory.merge(Inventory{
{
{ Identity{fieldID[speckleTypeID]}, speckleTypeID, element },
{ Identity{fieldID[speckleTypeID]}, speckleTypeID, attribute },
},
}.withType(&typeid(Record)));
return true;
@@ -10,6 +10,10 @@
#include "Speckle/Environment/Project.h"
#include "Speckle/Event/Type/DocStoreMergeEvent.h"
#include "Speckle/Event/Type/ProjectEvent.h"
#include "Speckle/Record/Element/Column.h"
#include "Speckle/Record/Element/ColumnSegment.h"
#include "Speckle/Record/Element/GenericElement.h"
#include "Speckle/Record/Element/Memo.h"
#include "Speckle/Utility/Guid.h"
#include "Speckle/Utility/String.h"
@@ -67,9 +71,14 @@ namespace {
@return A new element object (nullptr on failure)
*/
Element::Unique makeElement(const API_Element& elementData, const BIMRecordID& tableID) {
//Implement an object factory in future as classes for specific element types are implemented, e.g. Wall, Roof etc. using hash map
//The fallback for undefined element types will always be the base Element class
return std::make_unique<Element>(elementData, tableID);
switch (elementData.header.type.typeID) {
case API_ColumnID:
return std::make_unique<Column>(elementData, tableID);
case API_ColumnSegmentID:
return std::make_unique<ColumnSegment>(elementData, tableID);
default:
return std::make_unique<GenericElement>(elementData, tableID);
}
}
}
@@ -120,7 +129,22 @@ BIMLinkList ArchicadElementDBaseEngine::getSelection() const {
--------------------------------------------------------------------*/
std::unique_ptr<Element> ArchicadElementDBaseEngine::getObject(const BIMRecordID& ID, std::optional<BIMRecordID> tableID,
std::optional<BIMRecordID> documentID) const {
//Check for memo table requests
if (tableID == memoTable) {
auto memo = std::make_unique<API_ElementMemo>();
active::utility::Memory::erase(*memo);
//Use memo filtering when requested
uint64_t filter = documentID ? Guid::toInt(*documentID) : APIMemoMask_All;
if (auto err = ACAPI_Element_GetMemo(ID, memo.get(), filter); err != NoError)
ACAPI_DisposeElemMemoHdls(memo.get());
else {
auto result = std::make_unique<Memo>();
result->set(std::move(memo));
return result;
}
}
if (!tableID) {
//Use the active table if none is specified
tableID = getActiveTable();
if (!tableID)
return nullptr;
@@ -18,16 +18,21 @@ namespace speckle::database {
A database engine to read/write elements in an Archicad project database (local file or cloud-based)
*/
class ArchicadElementDBaseEngine : public ArchicadDBaseCore,
public active::database::DBaseEngine<record::element::Element,BIMRecordID, BIMRecordID, BIMRecordID> {
public active::database::DBaseEngine<record::element::Element, BIMRecordID, BIMRecordID, BIMRecordID> {
public:
// MARK: - Types
using base = active::database::DBaseEngine<record::element::Element,BIMRecordID, BIMRecordID, BIMRecordID>;
using base = active::database::DBaseEngine<record::element::Element, BIMRecordID, BIMRecordID, BIMRecordID>;
using Element = record::element::Element;
using Filter = base::Filter;
using Outline = base::Outline;
// MARK: - Constants
///The memo table ID (supplementary element data)
static const inline utility::Guid memoTable{utility::String{"fdff96d2-8c34-4f8b-8a76-a96a2b242758"}};
// MARK: - Static functions
/*!
@@ -35,9 +35,6 @@ namespace {
}
//True if a selection change subscriber has already started (only one is required - there are no variants)
bool speckle::event::SelectionSubscriber::m_isStarted = false;
/*--------------------------------------------------------------------
Get the event subscription list
@@ -76,6 +73,7 @@ bool SelectionSubscriber::start() {
#endif
} //SelectionSubscriber::start
/*--------------------------------------------------------------------
Stop participation (release resources etc)
--------------------------------------------------------------------*/
@@ -45,13 +45,11 @@ namespace speckle::event {
@return True if the event should be closed
*/
bool receive(const active::event::Event& event) override;
/*!
Start the participant operation
@return True if the participant is able to continue
*/
virtual bool start() override;
/*!
Stop participation (release resources etc)
*/
@@ -60,15 +58,11 @@ namespace speckle::event {
protected:
/*!
Handle the menu selection
Handle a selection change
@param event The selection event
@return True if the event should be closed
*/
virtual bool handle(const SelectionEvent& event) = 0;
private:
///True if a selection change subscriber has already started (only one is required - there are no variants)
static bool m_isStarted;
};
}
@@ -128,7 +128,6 @@ Finish::Finish(const ModelerAPI::Material& material) : base{Guid{Guid::fromInt(m
attr.material.diffusePc = static_cast<short>(material.GetDiffuseReflection() * 100);
attr.material.specularPc = static_cast<short>(material.GetSpecularReflection() * 100);
attr.material.transpPc = static_cast<short>(material.GetTransparency() * 100);
auto temp = material.GetShining();
attr.material.shine = static_cast<short>(material.GetShining() * 100);
attr.material.transpAtt = static_cast<short>(material.GetTransparencyAttenuation() * 400);
attr.material.emissionAtt = static_cast<short>(material.GetEmissionAttenuation() * 65535);
@@ -0,0 +1,174 @@
#include "Speckle/Record/Element/Column.h"
#include "Active/Serialise/Item/Wrapper/ValueWrap.h"
#include "Active/Serialise/Package/Wrapper/PackageWrap.h"
#include "Active/Serialise/Package/Wrapper/ContainerWrap.h"
#include "Speckle/Environment/Addon.h"
#include "Speckle/Primitive/Mesh/Mesh.h"
#include "Speckle/SpeckleResource.h"
#include "Speckle/Utility/Guid.h"
using namespace active::serialise;
using namespace speckle::environment;
using namespace speckle::record::attribute;
using namespace speckle::record::element;
using namespace speckle::utility;
#include <array>
#include <memory>
namespace speckle::record::element {
class Column::Data {
public:
friend class Column;
#ifdef ARCHICAD
Data(const API_Element& elem) : root{ std::make_unique<API_ColumnType>(elem.column) } {}
Data(const Data& source) : root{ std::make_unique<API_ColumnType>(*source.root) } {}
#endif
private:
std::unique_ptr<API_ColumnType> root;
};
}
namespace {
///Serialisation fields
enum FieldIndex {
segmentID,
};
///Serialisation field IDs
static std::array fieldID = {
Identity{"segments"},
};
}
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
Column::Column() {
} //Column::Column
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Constructor
elemData: Archicad element data
tableID: The element table ID (AC database, e.g. floor plan, 3D)
--------------------------------------------------------------------*/
Column::Column(const API_Element& elemData, const speckle::utility::Guid& tableID) : base{ elemData.header.guid, tableID } {
m_data = std::make_unique<Data>(elemData);
} //Column::Column
#endif
/*--------------------------------------------------------------------
Copy constructor
source: The object to copy
--------------------------------------------------------------------*/
Column::Column(const Column& source) : base{ source } {
m_data = source.m_data ? std::make_unique<Data>(*m_data) : nullptr;
} //Column::Column
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
Column::~Column() {}
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Get the (immutable) API element header data
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
const API_Elem_Head& Column::getHead() const {
return m_data->root->head;
} //Column::getHead
/*--------------------------------------------------------------------
Get the (mutable) API element header data
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
API_Elem_Head& Column::getHead() {
return m_data->root->head;
} //Column::getHead
/*--------------------------------------------------------------------
Load the element memo structure (elements must override according to requirements)
filter: Filter bits specifying memo requirements
--------------------------------------------------------------------*/
void Column::loadMemo(filter_bits filter, std::unique_ptr<Memo>& memo) const {
//Establish the memo filter for this element
if (!SegmentedColumn::isMemoLoaded())
filter |= SegmentedColumn::getPartFilter();
Element::loadMemo(filter, memo);
//Receive the memo data into the element (when available)
if (memo) {
if (filter & SegmentedColumn::getPartFilter())
SegmentedColumn::receive(*memo);
}
SegmentedColumn::setMemoLoaded(true); //Always mark the data as loaded to prevent repeated attempts on error
} //Column::loadMemo
#endif
/*--------------------------------------------------------------------
Fill an inventory with the package items
inventory: The inventory to receive the package items
return: True if the package has added items to the inventory
--------------------------------------------------------------------*/
bool Column::fillInventory(Inventory& inventory) const {
using enum Entry::Type;
inventory.merge(Inventory{
{
{ fieldID[segmentID], segmentID, getSegmentCount(), std::nullopt }, //TODO: implement other fields
},
}.withType(&typeid(Column)));
return base::fillInventory(inventory);
} //Column::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique Column::getCargo(const Inventory::Item& item) const {
if (item.ownerType != &typeid(Column))
return base::getCargo(item);
using namespace active::serialise;
switch (item.index) {
case segmentID:
if (auto segment = getSegment(item.available); segment != nullptr) {
return Cargo::Unique{new PackageWrap{*segment}};
} else
return nullptr;
default:
return nullptr; //Requested an unknown index
}
} //Column::getCargo
/*--------------------------------------------------------------------
Set to the default package content
--------------------------------------------------------------------*/
void Column::setDefault() {
base::setDefault();
m_data.reset();
} //Column::setDefault
+142
View File
@@ -0,0 +1,142 @@
#ifndef SPECKLE_RECORD_ELEMENT_COLUMN
#define SPECKLE_RECORD_ELEMENT_COLUMN
#include "Speckle/Record/Element/ColumnSegment.h"
#include "Speckle/Record/Element/Element.h"
#include "Speckle/Record/Element/Interface/Assembly/Path.h"
#include "Speckle/Record/Element/Interface/SegmentedColumn.h"
namespace speckle::record::element {
class ColumnSegment;
/*!
BIM column class
*/
class Column : public Element, public SegmentedColumn, public assembly::Path {
public:
// MARK: - Types
using base = Element;
///Unique pointer
using Unique = std::unique_ptr<Column>;
///Shared pointer
using Shared = std::shared_ptr<Column>;
///Optional
using Option = std::optional<Column>;
// MARK: - Constructors
using base::base;
/*!
Default constructor
*/
Column();
#ifdef ARCHICAD
/*!
Constructor
@param elemData Archicad element data
@param tableID The column element ID (AC database, e.g. floor plan, 3D)
*/
Column(const API_Element& elemData, const speckle::utility::Guid& tableID);
#endif
/*!
Copy constructor
@param source The object to copy
*/
Column(const Column& source);
/*!
Destructor
*/
~Column();
/*!
Object cloning
@return A clone of this object
*/
Column* clonePtr() const override { return new Column{*this}; }
// MARK: - Functions (const)
/*!
Get the speckle type identifier
@return The speckle type (relevant objects should override as required)
*/
speckle::utility::String getSpeckleType() const override { return "Objects.BuiltElements.Element:Objects.BuiltElements.Column"; }
/*!
Get the BIM application parent table ID
@return The BIM table ID
*/
virtual database::BIMRecordID getTableID() const override { return Element::getTableID(); }
/*!
Get the element body
@return nullptr (Columns don't explicitly have a 3D body - this comes from its child segments)
*/
virtual Body* getBody() const override { return nullptr; }
/*!
Get the number of segments in the path (elements must override according to requirements)
@return The segment count
*/
virtual size_t getSegmentCount() const override { return SegmentedColumn::getSegmentCount(); }
/*!
Get a segment from the path (elements must override according to requirements)
@param index The index of the required segment
@return The requested segment (nullptr on failure)
*/
virtual ColumnSegment* getSegment(size_t index) const override { return SegmentedColumn::getSegment(index); }
#ifdef ARCHICAD
/*!
Get the (immutable) API element header data
@return The element header data (only use this data for low-level operations - for normal code, call getters/setters)
*/
const API_Elem_Head& getHead() const override;
#endif
// MARK: - Functions (mutating)
#ifdef ARCHICAD
/*!
Get the (mutable) API element header data
@return The element header data (only use this data for low-level operations - for normal code, call getters/setters)
*/
API_Elem_Head& getHead() override;
#endif
// MARK: - Serialisation
/*!
Fill an inventory with the package items
@param inventory The inventory to receive the package items
@return True if the package has added items to the inventory
*/
bool fillInventory(active::serialise::Inventory& inventory) const override;
/*!
Get the specified cargo
@param item The inventory item to retrieve
@return The requested cargo (nullptr on failure)
*/
Cargo::Unique getCargo(const active::serialise::Inventory::Item& item) const override;
/*!
Set to the default package content
*/
void setDefault() override;
protected:
/*!
Load the element memo structure (elements must override according to requirements)
@param filter Filter bits specifying memo requirements
*/
virtual void loadMemo(filter_bits filter, std::unique_ptr<Memo>& memo) const override;
private:
class Data;
///The column data
std::unique_ptr<Data> m_data;
};
}
#endif //SPECKLE_RECORD_ELEMENT_COLUMN
@@ -0,0 +1,159 @@
#include "Speckle/Record/Element/ColumnSegment.h"
#include "Active/Serialise/Item/Wrapper/ValueWrap.h"
#include "Active/Serialise/Package/Wrapper/PackageWrap.h"
#include "Active/Serialise/Package/Wrapper/ContainerWrap.h"
#include "Speckle/Environment/Addon.h"
#include "Speckle/Primitive/Mesh/Mesh.h"
#include "Speckle/SpeckleResource.h"
#include "Speckle/Utility/Guid.h"
#ifdef ARCHICAD
#include <ACAPinc.h>
#endif
using namespace active::serialise;
using namespace speckle::environment;
using namespace speckle::record::attribute;
using namespace speckle::record::element;
using namespace speckle::utility;
#include <array>
#include <memory>
namespace speckle::record::element {
class ColumnSegment::Data {
public:
friend class ColumnSegment;
#ifdef ARCHICAD
Data(const API_ColumnSegmentType& seg) : root{ std::make_unique<API_ColumnSegmentType>(seg) } {}
Data(const Data& source) : root{ std::make_unique<API_ColumnSegmentType>(*source.root) } {}
private:
std::unique_ptr<API_ColumnSegmentType> root;
#endif
};
}
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
ColumnSegment::ColumnSegment() {
} //ColumnSegment::ColumnSegment
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Constructor
elemData: Archicad element data
tableID: The element table ID (AC database, e.g. floor plan, 3D)
--------------------------------------------------------------------*/
ColumnSegment::ColumnSegment(const API_Element& elemData, const speckle::utility::Guid& tableID) : base{ elemData.header.guid, tableID } {
m_data = std::make_unique<Data>(elemData.columnSegment);
} //ColumnSegment::ColumnSegment
/*--------------------------------------------------------------------
Constructor
segment: The segment element data
tableID: The parent table ID
cutOrigin: Cut at the segment origin
cutEnd: Cut at the segment end
scheme: The segment scheme
profile: The segment profile (nullptr = none)
--------------------------------------------------------------------*/
ColumnSegment::ColumnSegment(const API_ColumnSegmentType& segment, const speckle::utility::Guid& tableID, const API_AssemblySegmentCutData& cutOrigin,
const API_AssemblySegmentCutData& cutEnd, const API_AssemblySegmentSchemeData& scheme,
const API_AssemblySegmentProfileData* profile) :
base{segment.head.guid, tableID}, assembly::Segment{cutOrigin, cutEnd, scheme, profile} {
m_data = std::make_unique<Data>(segment);
} //ColumnSegment::ColumnSegment
#endif
/*--------------------------------------------------------------------
Copy constructor
source: The object to copy
--------------------------------------------------------------------*/
ColumnSegment::ColumnSegment(const ColumnSegment& source) : base{ source } {
m_data = source.m_data ? std::make_unique<Data>(*m_data) : nullptr;
} //ColumnSegment::ColumnSegment
/*--------------------------------------------------------------------
Move constructor
source: The object to move
--------------------------------------------------------------------*/
ColumnSegment::ColumnSegment(ColumnSegment&& source) : base{source} {
m_data = std::move(source.m_data);
} //ColumnSegment::ColumnSegment
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
ColumnSegment::~ColumnSegment() {}
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Get the (immutable) API element header data
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
const API_Elem_Head& ColumnSegment::getHead() const {
return m_data->root->head;
} //ColumnSegment::getHead
/*--------------------------------------------------------------------
Get the (mutable) API element header data
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
API_Elem_Head& ColumnSegment::getHead() {
return m_data->root->head;
} //ColumnSegment::getHead
#endif
/*--------------------------------------------------------------------
Fill an inventory with the package items
inventory: The inventory to receive the package items
return: True if the package has added items to the inventory
--------------------------------------------------------------------*/
bool ColumnSegment::fillInventory(Inventory& inventory) const {
using enum Entry::Type;
//TODO: Implement other fields as required
return base::fillInventory(inventory);
} //ColumnSegment::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique ColumnSegment::getCargo(const Inventory::Item& item) const {
//TODO: Implement other fields as required
return base::getCargo(item);
} //ColumnSegment::getCargo
/*--------------------------------------------------------------------
Set to the default package content
--------------------------------------------------------------------*/
void ColumnSegment::setDefault() {
m_data.reset();
} //ColumnSegment::setDefault
@@ -0,0 +1,135 @@
#ifndef SPECKLE_RECORD_ELEMENT_COLUMN_SEGMENT
#define SPECKLE_RECORD_ELEMENT_COLUMN_SEGMENT
#include "Speckle/Record/Element/Element.h"
#include "Speckle/Record/Element/Interface/Assembly/Segment.h"
namespace speckle::record::element {
class SegmentedColumn;
/*!
BIM column class
*/
class ColumnSegment : public Element, public assembly::Segment {
public:
// MARK: - Types
using base = Element;
///Unique pointer
using Unique = std::unique_ptr<ColumnSegment>;
///Shared pointer
using Shared = std::shared_ptr<ColumnSegment>;
///Optional
using Option = std::optional<ColumnSegment>;
// MARK: - Constructors
using base::base;
/*!
Default constructor
*/
ColumnSegment();
#ifdef ARCHICAD
/*!
Constructor
@param elemData Archicad element data
@param tableID The element table ID (AC database, e.g. floor plan, 3D)
*/
ColumnSegment(const API_Element& elemData, const speckle::utility::Guid& tableID);
#endif
/*!
Copy constructor
@param source The object to copy
*/
ColumnSegment(const ColumnSegment& source);
/*!
Move constructor
@param source The object to move
*/
ColumnSegment(ColumnSegment&& source);
/*!
Destructor
*/
~ColumnSegment();
/*!
Object cloning
@return A clone of this object
*/
ColumnSegment* clonePtr() const override { return new ColumnSegment{*this}; }
// MARK: - Functions (const)
/*!
Get the speckle type identifier
@return The speckle type (relevant objects should override as required)
*/
speckle::utility::String getSpeckleType() const override { return "Objects.BuiltElements.Element:Objects.BuiltElements.ColumnSegment"; }
#ifdef ARCHICAD
/*!
Get the (immutable) API element header data
@return The element header data (only use this data for low-level operations - for normal code, call getters/setters)
*/
const API_Elem_Head& getHead() const override;
#endif
// MARK: - Functions (mutating)
#ifdef ARCHICAD
/*!
Get the (mutable) API element header data
@return The element header data (only use this data for low-level operations - for normal code, call getters/setters)
*/
API_Elem_Head& getHead() override;
#endif
// MARK: - Serialisation
/*!
Fill an inventory with the package items
@param inventory The inventory to receive the package items
@return True if the package has added items to the inventory
*/
bool fillInventory(active::serialise::Inventory& inventory) const override;
/*!
Get the specified cargo
@param item The inventory item to retrieve
@return The requested cargo (nullptr on failure)
*/
Cargo::Unique getCargo(const active::serialise::Inventory::Item& item) const override;
/*!
Set to the default package content
*/
void setDefault() override;
protected:
friend class SegmentedColumn;
#ifdef ARCHICAD
/*!
Constructor
@param segment The segment element data
@param tableID The parent table ID
@param cutOrigin Cut at the segment origin
@param cutEnd Cut at the segment end
@param scheme The segment scheme
@param profile The segment profile (nullptr = none)
*/
ColumnSegment(const API_ColumnSegmentType& segment, const speckle::utility::Guid& tableID, const API_AssemblySegmentCutData& cutOrigin,
const API_AssemblySegmentCutData& cutEnd, const API_AssemblySegmentSchemeData& scheme,
const API_AssemblySegmentProfileData* profile = nullptr);
#endif
private:
class Data;
///The column data
std::unique_ptr<Data> m_data;
};
}
#endif //SPECKLE_RECORD_ELEMENT_COLUMN_SEGMENT
+45 -39
View File
@@ -3,19 +3,22 @@
#include "Active/Serialise/Item/Wrapper/ValueWrap.h"
#include "Active/Serialise/Package/Wrapper/PackageWrap.h"
#include "Active/Serialise/Package/Wrapper/ContainerWrap.h"
#include "Speckle/Database/BIMElementDatabase.h"
#include "Speckle/Environment/Addon.h"
#include "Speckle/Environment/Project.h"
#include "Speckle/Primitive/Mesh/Mesh.h"
#include "Speckle/Record/Element/Memo.h"
#include "Speckle/SpeckleResource.h"
#include "Speckle/Utility/Guid.h"
#ifdef ARCHICAD
#include "Sight.hpp"
#include "Model.hpp"
#include "ModelMaterial.hpp"
#include "ModelElement.hpp"
#include "exp.h"
#include "ModelMeshBody.hpp"
#include "ConvexPolygon.hpp"
#include <Sight.hpp>
#include <Model.hpp>
#include <ModelMaterial.hpp>
#include <ModelElement.hpp>
#include <exp.h>
#include <ModelMeshBody.hpp>
#include <ConvexPolygon.hpp>
#endif
using namespace active::serialise;
@@ -32,14 +35,10 @@ namespace speckle::record::element {
class Element::Data {
public:
friend class Element;
#ifdef ARCHICAD
Data(const API_Element& elem) : root{ std::make_unique<API_Element>(elem) } {}
Data(const Data& source) : root{ std::make_unique<API_Element>(*source.root) } {}
#endif
Data() {}
Data(const Data& source) {}
private:
std::unique_ptr<API_Element> root;
std::unique_ptr<Element::Body> m_cache;
};
@@ -68,12 +67,13 @@ Element::Element() {
/*--------------------------------------------------------------------
Constructor
elemData: Archicad element data
tableID: The attribute table ID (attribute type)
ID: The record ID
tableID: The parent table ID
unit: The record unit type
--------------------------------------------------------------------*/
Element::Element(const API_Element& elemData, const speckle::utility::Guid& tableID) : base{ elemData.header.guid, tableID } {
m_data = std::make_unique<Data>(elemData);
Element::Element(const Guid& ID, const Guid& tableID, std::optional<active::measure::LengthType> unit) : base{ID, tableID, unit} {
m_data = std::make_unique<Data>();
} //Element::Element
@@ -87,6 +87,16 @@ Element::Element(const Element& source) : base{ source } {
} //Element::Element
/*--------------------------------------------------------------------
Move constructor
source: The object to move
--------------------------------------------------------------------*/
Element::Element(Element&& source) : base{source} {
m_data = std::move(source.m_data);
} //Element::Element
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
@@ -213,27 +223,6 @@ Element::Body* Element::getBody() const {
}
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Get the (immutable) API element header data
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
const API_Elem_Head& Element::getHead() const {
return m_data->root->header;
} //Element::getHead
/*--------------------------------------------------------------------
Get the (mutable) API element header data
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
API_Elem_Head& Element::getHead() {
return m_data->root->header;
} //Element::getHead
#endif
/*--------------------------------------------------------------------
Fill an inventory with the package items
@@ -285,3 +274,20 @@ void Element::setDefault() {
base::setDefault();
m_data.reset();
} //Element::setDefault
/*--------------------------------------------------------------------
Load the element memo structure (elements must override according to requirements)
filter: Filter bits specifying memo requirements
--------------------------------------------------------------------*/
void Element::loadMemo(Part::filter_bits filter, std::unique_ptr<Memo>& memo) const {
//If the memo data isn't loaded, fetch it now
if (!memo) {
auto project = addon()->getActiveProject().lock();
if (!project)
return;
if (auto loaded = project->getElementDatabase()->getMemo(getBIMID(), filter); loaded)
memo.reset(loaded.release());
}
} //Element::loadMemo
+22 -16
View File
@@ -2,6 +2,7 @@
#define SPECKLE_RECORD_ELEMENT
#include "Speckle/Database/Content/BIMRecord.h"
#include "Speckle/Record/Element/Interface/Part.h"
#include "Speckle/Record/Attribute/Storey.h"
#include "Speckle/Utility/String.h"
@@ -11,6 +12,8 @@ namespace speckle::primitive {
namespace speckle::record::element {
class Memo;
/*!
Base BIM element class
*/
@@ -32,37 +35,33 @@ namespace speckle::record::element {
// MARK: - Constructors
using base::base;
/*!
Default constructor
*/
Element();
#ifdef ARCHICAD
/*!
Constructor
@param elemData Archicad element data
@param tableID The element table ID (AC database, e.g. floor plan, 3D)
@param ID The record ID
@param tableID The parent table ID
@param unit The record unit type
*/
Element(const API_Element& elemData, const speckle::utility::Guid& tableID);
#endif
Element(const speckle::utility::Guid& ID, const speckle::utility::Guid& tableID,
std::optional<active::measure::LengthType> unit = active::measure::LengthType::metre);
/*!
Copy constructor
@param source The object to copy
*/
Element(const Element& source);
/*!
Move constructor
@param source The object to move
*/
Element(Element&& source);
/*!
Destructor
*/
~Element();
/*!
Object cloning
@return A clone of this object
*/
Element* clonePtr() const override { return new Element{*this}; }
// MARK: - Functions (const)
/*!
@@ -90,7 +89,7 @@ namespace speckle::record::element {
Get the (immutable) API element header data
@return The element header data (only use this data for low-level operations - for normal code, call getters/setters)
*/
virtual const API_Elem_Head& getHead() const;
virtual const API_Elem_Head& getHead() const = 0;
#endif
// MARK: - Functions (mutating)
@@ -100,7 +99,7 @@ namespace speckle::record::element {
Get the (mutable) API element header data
@return The element header data (only use this data for low-level operations - for normal code, call getters/setters)
*/
virtual API_Elem_Head& getHead();
virtual API_Elem_Head& getHead() = 0;
#endif
// MARK: - Serialisation
@@ -122,6 +121,13 @@ namespace speckle::record::element {
*/
void setDefault() override;
protected:
/*!
Load the element memo structure (elements must override according to requirements)
@param filter Filter bits specifying memo requirements
*/
virtual void loadMemo(Part::filter_bits filter, std::unique_ptr<Memo>& memo) const;
private:
class Data;
///The element data
@@ -0,0 +1,157 @@
#include "Speckle/Record/Element/GenericElement.h"
#include "Active/Serialise/Item/Wrapper/ValueWrap.h"
#include "Active/Serialise/Package/Wrapper/PackageWrap.h"
#include "Active/Serialise/Package/Wrapper/ContainerWrap.h"
#include "Speckle/Environment/Addon.h"
#include "Speckle/Primitive/Mesh/Mesh.h"
#include "Speckle/SpeckleResource.h"
#include "Speckle/Utility/Guid.h"
using namespace active::serialise;
using namespace speckle::environment;
using namespace speckle::record::attribute;
using namespace speckle::record::element;
using namespace speckle::utility;
#include <array>
#include <memory>
namespace speckle::record::element {
class GenericElement::Data {
public:
friend class GenericElement;
#ifdef ARCHICAD
Data(const API_Element& elem) : root{ std::make_unique<API_Element>(elem) } {}
Data(const Data& source) : root{ std::make_unique<API_Element>(*source.root) } {}
#endif
private:
std::unique_ptr<API_Element> root;
std::unique_ptr<GenericElement::Body> m_cache;
};
}
namespace {
///Serialisation fields
enum FieldIndex {
bodyID,
};
///Serialisation field IDs
static std::array fieldID = {
Identity{"displayValue"},
};
}
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
GenericElement::GenericElement() {
} //GenericElement::GenericElement
/*--------------------------------------------------------------------
Constructor
elemData: Archicad element data
tableID: The attribute table ID (attribute type)
--------------------------------------------------------------------*/
GenericElement::GenericElement(const API_Element& elemData, const speckle::utility::Guid& tableID) : base{ elemData.header.guid, tableID } {
m_data = std::make_unique<Data>(elemData);
} //GenericElement::GenericElement
/*--------------------------------------------------------------------
Copy constructor
source: The object to copy
--------------------------------------------------------------------*/
GenericElement::GenericElement(const GenericElement& source) : base{ source } {
m_data = source.m_data ? std::make_unique<Data>(*m_data) : nullptr;
} //GenericElement::GenericElement
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
GenericElement::~GenericElement() {}
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Get the (immutable) API element header data
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
const API_Elem_Head& GenericElement::getHead() const {
return m_data->root->header;
} //GenericElement::getHead
/*--------------------------------------------------------------------
Get the (mutable) API element header data
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
API_Elem_Head& GenericElement::getHead() {
return m_data->root->header;
} //GenericElement::getHead
#endif
/*--------------------------------------------------------------------
Fill an inventory with the package items
inventory: The inventory to receive the package items
return: True if the package has added items to the inventory
--------------------------------------------------------------------*/
bool GenericElement::fillInventory(Inventory& inventory) const {
using enum Entry::Type;
inventory.merge(Inventory{
{
{ fieldID[bodyID], bodyID, element }, //TODO: implement other fields
},
}.withType(&typeid(GenericElement)));
return base::fillInventory(inventory);
} //GenericElement::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique GenericElement::getCargo(const Inventory::Item& item) const {
if (item.ownerType != &typeid(GenericElement))
return base::getCargo(item);
using namespace active::serialise;
switch (item.index) {
case bodyID:
if (auto body = getBody(); body != nullptr)
{
return Cargo::Unique{ new active::serialise::ContainerWrap{*body} };
}
else
return nullptr;
default:
return nullptr; //Requested an unknown index
}
} //GenericElement::getCargo
/*--------------------------------------------------------------------
Set to the default package content
--------------------------------------------------------------------*/
void GenericElement::setDefault() {
base::setDefault();
m_data.reset();
} //GenericElement::setDefault
@@ -0,0 +1,112 @@
#ifndef SPECKLE_RECORD_GENERIC_ELEMENT
#define SPECKLE_RECORD_GENERIC_ELEMENT
#include "Speckle/Record/Element/Element.h"
namespace speckle::record::element {
/*!
Catch-all class for elements that are not represented by a specific class
*/
class GenericElement : public Element {
public:
///An element 3D body primitive
using Body = std::vector<primitive::Mesh>;
// MARK: - Types
using base = Element;
///Unique pointer
using Unique = std::unique_ptr<GenericElement>;
///Shared pointer
using Shared = std::shared_ptr<GenericElement>;
///Optional
using Option = std::optional<GenericElement>;
// MARK: - Constructors
using base::base;
/*!
Default constructor
*/
GenericElement();
#ifdef ARCHICAD
/*!
Constructor
@param elemData Archicad element data
@param tableID The element table ID (AC database, e.g. floor plan, 3D)
*/
GenericElement(const API_Element& elemData, const speckle::utility::Guid& tableID);
#endif
/*!
Copy constructor
@param source The object to copy
*/
GenericElement(const GenericElement& source);
/*!
Destructor
*/
~GenericElement();
/*!
Object cloning
@return A clone of this object
*/
GenericElement* clonePtr() const override { return new GenericElement{*this}; }
// MARK: - Functions (const)
/*!
Get the speckle type identifier
@return The speckle type (relevant objects should override as required)
*/
virtual speckle::utility::String getSpeckleType() const override { return "Objects.BuiltElements.GenericElement:Objects.BuiltElements.GenericElement"; }
#ifdef ARCHICAD
/*!
Get the (immutable) API element header data
@return The element header data (only use this data for low-level operations - for normal code, call getters/setters)
*/
virtual const API_Elem_Head& getHead() const override;
#endif
// MARK: - Functions (mutating)
#ifdef ARCHICAD
/*!
Get the (mutable) API element header data
@return The element header data (only use this data for low-level operations - for normal code, call getters/setters)
*/
virtual API_Elem_Head& getHead() override;
#endif
// MARK: - Serialisation
/*!
Fill an inventory with the package items
@param inventory The inventory to receive the package items
@return True if the package has added items to the inventory
*/
bool fillInventory(active::serialise::Inventory& inventory) const override;
/*!
Get the specified cargo
@param item The inventory item to retrieve
@return The requested cargo (nullptr on failure)
*/
Cargo::Unique getCargo(const active::serialise::Inventory::Item& item) const override;
/*!
Set to the default package content
*/
void setDefault() override;
private:
class Data;
///The element data
std::unique_ptr<Data> m_data;
};
}
#endif //SPECKLE_RECORD_GENERIC_ELEMENT
@@ -0,0 +1,23 @@
#include "Speckle/Record/Element/Interface/Assembly/Path.h"
#include "Active/Geometry/PolyEdge.h"
#ifdef ARCHICAD
#include <ACAPinc.h>
#endif
using namespace active::geometry;
using namespace speckle::database;
using namespace speckle::record::element::assembly;
/*--------------------------------------------------------------------
Get a specified edge from the segmented path
index: The index of the required edge
return: The requested edge (nullptr on failure)
--------------------------------------------------------------------*/
std::unique_ptr<active::geometry::PolyEdge> Path::getSegmentEdge(const database::BIMIndex& index) const {
//TODO: Complete when required
return nullptr;
}
@@ -0,0 +1,48 @@
#ifndef SPECKLE_RECORD_ELEMENT_ASSEMBLY_PATH
#define SPECKLE_RECORD_ELEMENT_ASSEMBLY_PATH
#include "Speckle/Database/Identity/BIMIndex.h"
#include <memory>
#include <optional>
namespace active::geometry {
class PolyEdge;
}
namespace speckle::record::element::assembly {
class Segment;
/*!
Interface for assemblies forming a path made up of a consecutive series of segments, e.g. a portal frame made from a series of beams
*/
class Path {
public:
// MARK: - Functions (const)
/*!
Get a specified edge from the segmented path
@param index The index of the required edge
@return The requested edge (nullptr on failure)
*/
std::unique_ptr<active::geometry::PolyEdge> getSegmentEdge(const database::BIMIndex& index) const;
protected:
/*!
Get the number of segments in the path (elements must override according to requirements)
@return The segment count
*/
virtual size_t getSegmentCount() const = 0;
/*!
Get a segment from the path (elements must override according to requirements)
@param index The index of the required segment
@return The requested segment (nullptr on failure)
*/
virtual Segment* getSegment(size_t index) const = 0;
};
}
#endif //SPECKLE_RECORD_ELEMENT_ASSEMBLY_PATH
@@ -0,0 +1,67 @@
#include "Speckle/Record/Element/Interface/Assembly/Segment.h"
#include "Active/Geometry/PolyEdge.h"
#include "Active/Utility/Memory.h"
#ifdef ARCHICAD
#include <ACAPinc.h>
#include <APIdefs_Elements.h>
#include <ProfileVectorImage.hpp>
#endif
using namespace active::geometry;
using namespace speckle::record::element::assembly;
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
Segment::Segment() :
m_cutOrigin{std::make_unique<API_AssemblySegmentCutData>()},
m_cutEnd{std::make_unique<API_AssemblySegmentCutData>()},
m_scheme{std::make_unique<API_AssemblySegmentSchemeData>()} {
} //Segment::Segment
/*--------------------------------------------------------------------
Constructor
cutOrigin: Cut at the segment origin
cutEnd: Cut at the segment end
scheme: The segment scheme
profile: The segment profile (nullptr = none)
--------------------------------------------------------------------*/
Segment::Segment(const API_AssemblySegmentCutData& cutOrigin, const API_AssemblySegmentCutData& cutEnd, const API_AssemblySegmentSchemeData& scheme,
const API_AssemblySegmentProfileData* profile) :
m_cutOrigin{std::make_unique<API_AssemblySegmentCutData>(cutOrigin)},
m_cutEnd{std::make_unique<API_AssemblySegmentCutData>(cutEnd)},
m_scheme{std::make_unique<API_AssemblySegmentSchemeData>(scheme)} {
if (profile != nullptr) {
if (profile->customOrigProfile != nullptr)
m_customProfile = std::make_unique<ProfileVectorImage>(*profile->customOrigProfile);
if (profile->stretchedProfile != nullptr)
m_stretchedProfile = std::make_unique<ProfileVectorImage>(*profile->stretchedProfile);
}
} //Segment::Segment
/*--------------------------------------------------------------------
Copy constructor
source: The object to copy
--------------------------------------------------------------------*/
Segment::Segment(const Segment& source) :
m_cutOrigin{std::make_unique<API_AssemblySegmentCutData>(*source.m_cutOrigin)},
m_cutEnd{std::make_unique<API_AssemblySegmentCutData>(*source.m_cutEnd)},
m_scheme{std::make_unique<API_AssemblySegmentSchemeData>(*source.m_scheme)},
m_edge{source.m_edge ? std::make_unique<PolyEdge>(*source.m_edge) : nullptr},
m_customProfile{source.m_customProfile ? std::make_unique<ProfileVectorImage>(*source.m_customProfile) : nullptr},
m_stretchedProfile{source.m_stretchedProfile ? std::make_unique<ProfileVectorImage>(*source.m_stretchedProfile) : nullptr} {
m_path = source.m_path;
} //Segment::Segment
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
Segment::~Segment() {}
@@ -0,0 +1,91 @@
#ifndef SPECKLE_RECORD_ELEMENT_ASSEMBLY_SEGMENT
#define SPECKLE_RECORD_ELEMENT_ASSEMBLY_SEGMENT
#include "Speckle/Database/Identity/BIMIndex.h"
#include <memory>
#include <optional>
#ifdef ARCHICAD
struct API_AssemblySegmentCutData;
struct API_AssemblySegmentSchemeData;
class ProfileVectorImage;
#endif
namespace active::geometry {
class PolyEdge;
}
namespace speckle::record::element::assembly {
class Path;
/*!
Interface for elements forming a path made up of a consecutive series of segments, e.g. a portal frame made from a series of beams
*/
class Segment {
public:
/*!
Default constructor
*/
Segment();
/*!
Copy constructor
@param source The object to copy
*/
Segment(const Segment& source);
/*!
Destructor
*/
~Segment();
// MARK: - Functions (const)
/*!
Get the segment path
@return The segment path (nullptr = undefined)
*/
const assembly::Path* getPath() const { return m_path; }
// MARK: - Functions (mutating)
/*!
Set the segment path
@param path The segment path
*/
void setPath(const assembly::Path* path) { m_path = path; }
protected:
/*!
Constructor
@param cutOrigin Cut at the segment origin
@param cutEnd Cut at the segment end
@param scheme The segment scheme
@param profile The segment profile (nullptr = none)
*/
Segment(const API_AssemblySegmentCutData& cutOrigin, const API_AssemblySegmentCutData& cutEnd, const API_AssemblySegmentSchemeData& scheme,
const API_AssemblySegmentProfileData* profile = nullptr);
private:
#ifdef ARCHICAD
//NB: The following properties are mutable to support lazy loading
///Cut at the segment origin
mutable std::unique_ptr<API_AssemblySegmentCutData> m_cutOrigin;
///Cut at the segment end
mutable std::unique_ptr<API_AssemblySegmentCutData> m_cutEnd;
///The segment scheme
mutable std::unique_ptr<API_AssemblySegmentSchemeData> m_scheme;
///An optional custom profile (nullptr = none)
mutable std::unique_ptr<ProfileVectorImage> m_customProfile;
///An optional stretched profile (nullptr = none)
mutable std::unique_ptr<ProfileVectorImage> m_stretchedProfile;
#endif
//The segment edge
mutable std::unique_ptr<active::geometry::PolyEdge> m_edge;
//The segment path
mutable const assembly::Path* m_path = nullptr;
};
}
#endif //SPECKLE_RECORD_ELEMENT_ASSEMBLY_SEGMENT
@@ -0,0 +1,23 @@
#include "Speckle/Record/Element/Interface/Part.h"
#include "Speckle/Record/Element/Memo.h"
using namespace active::serialise;
using namespace speckle::record::attribute;
using namespace speckle::record::element;
using namespace speckle::utility;
/*--------------------------------------------------------------------
Confirm that the element part data is loaded and valid (elements must override according to requirements)
filter: Filter bits specifying memo requirements
return: True if the part data is ready to use
--------------------------------------------------------------------*/
bool Part::confirmPart(filter_bits filter) const {
if (!isMemoLoaded()) {
std::unique_ptr<Memo> memo;
loadMemo(filter, memo);
}
return isMemoLoaded();
} //Part::confirmPart
@@ -0,0 +1,92 @@
#ifndef SPECKLE_RECORD_ELEMENT_PART
#define SPECKLE_RECORD_ELEMENT_PART
#include <memory>
#include <optional>
namespace speckle::record::element {
class Memo;
/*!
Interface for an element part, i.e. some component in an assembly element
Although this concept is slanted toward Archicad's memo structure, the fundamentals are applicable to any data structures that separate out
the constituent parts of an assembly to support lazy loading
Note that this class is intended to be an interface - management and/or storage of the data should be provided by subclassing
*/
class Part {
public:
///Filter bits for memo loading
using filter_bits = uint64_t;
// MARK: - Types
///Unique pointer
using Unique = std::unique_ptr<Part>;
///Shared pointer
using Shared = std::shared_ptr<Part>;
///Optional
using Option = std::optional<Part>;
// MARK: - Constructors
/*!
Destructor
*/
virtual ~Part() {}
// MARK: - Functions (const)
// MARK: - Functions (mutating)
protected:
/*!
Determine if the element memo data has been successfully loaded and validated
@return True if the element memo data is loaded
*/
bool isMemoLoaded() const { return m_isLoaded && isPartValid(); }
/*!
Determine if the element memo content has been validated (elements must override according to requirements)
@return True if the element memo content is valid
*/
virtual bool isPartValid() const = 0;
/*!
Confirm that the element part data is loaded and valid (elements must override according to requirements)
@param filter Filter bits specifying memo requirements
@return True if the part data is ready to use
*/
virtual bool confirmPart(filter_bits filter) const;
/*!
Load the element memo structure (elements must override according to requirements)
@param filter Filter bits specifying memo requirements
*/
virtual void loadMemo(filter_bits filter, std::unique_ptr<Memo>& memo) const = 0;
/*!
Set whether the element memo data has been loaded (does not establish validity, but prevents multiple attempts to reload)
@param state True if the element memo data is loaded
*/
void setMemoLoaded(bool state) const { m_isLoaded = state; }
/*!
Send the element part back to a memo structure for storage (elements must override according to requirements)
@param memo The memo to carry the data
@return True if the data was successfully sent
*/
virtual bool send(Memo* memo) const = 0;
/*!
Receive the element memo data from a memo structure (elements must override according to requirements)
@param memo The memo carrying the data
@return True if the data was successfully received
*/
virtual bool receive(const Memo& memo) const = 0;
private:
///True if the memo data has been loaded into the element (mutable to support lazy loading)
mutable bool m_isLoaded = false;
};
}
#endif //SPECKLE_RECORD_ELEMENT_PART
@@ -0,0 +1,158 @@
#include "Speckle/Record/Element/Interface/SegmentedColumn.h"
#include "Speckle/Record/Element/ColumnSegment.h"
#include "Speckle/Record/Element/Memo.h"
#include "Speckle/Record/Element/Interface/Assembly/Path.h"
#include "Speckle/Utility/BIMMemory.h"
using namespace active::serialise;
using namespace speckle::record::attribute;
using namespace speckle::record::element;
using namespace speckle::utility;
namespace speckle::record::element {
class SegmentedColumn::Data {
public:
friend class SegmentedColumn;
std::vector<ColumnSegment> segments;
};
}
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
SegmentedColumn::SegmentedColumn() {
} //SegmentedColumn::SegmentedColumn
/*--------------------------------------------------------------------
Copy constructor
source: The object to copy
--------------------------------------------------------------------*/
SegmentedColumn::SegmentedColumn(const SegmentedColumn& source) : base{ source } {
m_data = source.m_data ? std::make_unique<Data>(*m_data) : nullptr;
} //SegmentedColumn::SegmentedColumn
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
SegmentedColumn::~SegmentedColumn() {}
/*--------------------------------------------------------------------
Get the number of segments
return. The number of segments (0 on error)
--------------------------------------------------------------------*/
size_t SegmentedColumn::getSegmentCount() const {
confirmPart(getPartFilter());
return m_data ? m_data->segments.size() : 0;
} //SegmentedColumn::getSegmentCount
/*--------------------------------------------------------------------
Get a column segment
index: The index of the required segment
return: The requested segment, nullptr on error
--------------------------------------------------------------------*/
ColumnSegment* SegmentedColumn::getSegment(size_t index) const {
confirmPart(getPartFilter());
return (m_data && (index < m_data->segments.size())) ? &m_data->segments[index] : nullptr;
} //SegmentedColumn::getSegment
/*--------------------------------------------------------------------
Return the bits for the part filter required to load the data necessary to build this object
return: The required filter bits
--------------------------------------------------------------------*/
Part::filter_bits SegmentedColumn::getPartFilter() const {
return APIMemoMask_ColumnSegment | APIMemoMask_AssemblySegmentCut | APIMemoMask_AssemblySegmentScheme | APIMemoMask_AssemblySegmentProfile;
} //SegmentedColumn::getPartFilter
/*--------------------------------------------------------------------
Determine if the element memo content has been validated (elements must override according to requirements)
return: True if the element memo content is valid
--------------------------------------------------------------------*/
bool SegmentedColumn::isPartValid() const {
return m_data && !m_data->segments.empty();
} //SegmentedColumn::isPartValid
/*--------------------------------------------------------------------
Load the element memo structure (elements must override according to requirements)
filter: Filter bits specifying memo requirements
--------------------------------------------------------------------*/
void SegmentedColumn::loadMemo(filter_bits filter, std::unique_ptr<Memo>& memo) const {
} //SegmentedColumn::loadMemo
/*--------------------------------------------------------------------
Send the element part back to a memo structure for storage (elements must override according to requirements)
memo: The memo to carry the data
return: True if the data was successfully sent
--------------------------------------------------------------------*/
bool SegmentedColumn::send(Memo* memo) const {
//TODO: Complete when required
return false;
} //SegmentedColumn::send
/*--------------------------------------------------------------------
Receive the element memo data from a memo structure (elements must override according to requirements)
memo: The memo carrying the data
return: True if the data was successfully received
--------------------------------------------------------------------*/
bool SegmentedColumn::receive(const Memo& memo) const {
#ifdef ARCHICAD
if (!memo || (memo.root()->columnSegments == nullptr))
return false;
if (m_data)
m_data->segments.clear();
else
m_data = std::make_unique<Data>();
//Confirm that required data is present in the memo
auto segmentPtr = memo.root()->columnSegments;
auto cutPtr = memo.root()->assemblySegmentCuts;
auto schemePtr = memo.root()->assemblySegmentSchemes;
auto profilePtr = memo.root()->assemblySegmentProfiles;
if ((segmentPtr == nullptr) || (cutPtr == nullptr) || (schemePtr == nullptr))
return false;
//Determine available item count
auto segmentCount = BIMMemory::getPtrSize(segmentPtr) / sizeof(API_ColumnSegmentType);
auto cutCount = BIMMemory::getPtrSize(cutPtr) / sizeof(API_AssemblySegmentCutData);
auto schemeCount = BIMMemory::getPtrSize(schemePtr) / sizeof(API_AssemblySegmentSchemeData);
auto profileCount = BIMMemory::getPtrSize(profilePtr) / sizeof(API_AssemblySegmentProfileData);
if ((segmentCount == 0) || (cutCount != (segmentCount + 1)) || (schemeCount != segmentCount))
return false;
auto path = dynamic_cast<const assembly::Path*>(this);
for (size_t n = 0 ; n < segmentCount; ++n) {
const API_AssemblySegmentProfileData* thisProfile = nullptr;
for (size_t i = 0; i < profileCount; ++i) {
if (profilePtr[i].segmentIndex == n) {
thisProfile = profilePtr + i;
break;
}
}
m_data->segments.emplace_back(ColumnSegment{segmentPtr[n], getTableID(), cutPtr[n], cutPtr[n + 1], schemePtr[n], thisProfile});
m_data->segments.back().setPath(path);
}
setMemoLoaded(true);
#endif
return true;
} //SegmentedColumn::receive
@@ -0,0 +1,103 @@
#ifndef SPECKLE_RECORD_ELEMENT_SEGMENTED_COLUMN
#define SPECKLE_RECORD_ELEMENT_SEGMENTED_COLUMN
#include "Speckle/Database/Identity/BIMRecordID.h"
#include "Speckle/Record/Element/Interface/Part.h"
namespace speckle::record::element {
class ColumnSegment;
/*!
Interface for a column type that is made up of consecutive segments
Note that the child segments use lazy loading to avoid high overheads when accessing data relevant to the parent column only
*/
class SegmentedColumn : public Part {
public:
// MARK: - Types
using base = Part;
///Unique pointer
using Unique = std::unique_ptr<SegmentedColumn>;
///Shared pointer
using Shared = std::shared_ptr<SegmentedColumn>;
///Optional
using Option = std::optional<SegmentedColumn>;
// MARK: - Constructors
/*!
Default constructor
*/
SegmentedColumn();
/*!
Copy constructor
@param source The object to copy
*/
SegmentedColumn(const SegmentedColumn& source);
/*!
Destructor
*/
~SegmentedColumn();
// MARK: - Functions (const)
/*!
Get the BIM application parent table ID
@return The BIM table ID
*/
virtual database::BIMRecordID getTableID() const = 0;
/*!
Get the number of segments
@return The number of segments (0 on error)
*/
size_t getSegmentCount() const;
/*!
Get a column segment
@param index The index of the required segment
@return The requested segment, nullptr on error
*/
ColumnSegment* getSegment(size_t index) const;
// MARK: - Functions (mutating)
protected:
/*!
Return the bits for the part filter required to load the data necessary to build this object
@return The required filter bits */
filter_bits getPartFilter() const;
/*!
Determine if the element part content has been validated (elements must override according to requirements)
@return True if the element part content is valid
*/
bool isPartValid() const override;
/*!
Load the element memo structure (elements must override according to requirements)
@param filter Filter bits specifying memo requirements
*/
void loadMemo(filter_bits filter, std::unique_ptr<Memo>& memo) const override;
/*!
Send the element part back to a memo structure for storage (elements must override according to requirements)
@param memo The memo to carry the data
@return True if the data was successfully sent
*/
bool send(Memo* memo) const override;
/*!
Receive the element memo data from a memo structure (elements must override according to requirements)
@param memo The memo carrying the data
@return True if the data was successfully received
*/
bool receive(const Memo& memo) const override;
private:
class Data;
///The segment data - mutable to support lazy loading
mutable std::unique_ptr<Data> m_data;
};
}
#endif //SPECKLE_RECORD_ELEMENT_SEGMENTED_COLUMN
@@ -0,0 +1,54 @@
#include "Speckle/Record/Element/Memo.h"
#include "Active/Utility/Memory.h"
#ifdef ARCHICAD
#include <ACAPinc.h>
#endif
using namespace speckle::record::element;
namespace speckle::record::element {
API_Elem_Head Memo::m_dummy{};
}
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Default constructor
memo: A memo structure - this object will take ownership of anything passed to the constructor
--------------------------------------------------------------------*/
Memo::Memo(std::unique_ptr<API_ElementMemo> memo) : m_data{std::move(memo)} {
if (!memo) {
//If no data was supplied, we still allocate an empty in the event that a new element is being constructed
m_data = std::make_unique<API_ElementMemo>();
active::utility::Memory::erase(*m_data);
}
} //Memo::Memo
#endif
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
Memo::~Memo() {
#ifdef ARCHICAD
if (m_data)
ACAPI_DisposeElemMemoHdls(m_data.get());
#endif
} //Memo::Memo
/*--------------------------------------------------------------------
Conversion operator
return: True if the memo contains data
--------------------------------------------------------------------*/
Memo::operator bool() const {
#ifdef ARCHICAD
return m_data.operator bool();
#else
return false;
#endif
} //Memo::operator bool
+92
View File
@@ -0,0 +1,92 @@
#ifndef SPECKLE_RECORD_ELEMENT_MEMO
#define SPECKLE_RECORD_ELEMENT_MEMO
#include "Speckle/Record/Element/Element.h"
#include <memory>
#include <optional>
#ifdef ARCHICAD
struct API_ElementMemo;
#endif
namespace speckle::record::element {
/*!
Wrapper for Archicad memo data structure
The main purpose for this wrapper is memory safely. In addition to maneging ownership of the memo structure, each handle/pointer allocation
within the structure must be released to prevent leaks. This wrapper will ensure these calls are made
*/
class Memo : public Element {
public:
// MARK: - Types
///Unique pointer
using Unique = std::unique_ptr<Memo>;
///Shared pointer
using Shared = std::shared_ptr<Memo>;
///Optional
using Option = std::optional<Memo>;
// MARK: - Constructors
#ifdef ARCHICAD
/*!
Default constructor
@param memo A memo structure - this object will take ownership of anything passed to the constructor
*/
Memo(std::unique_ptr<API_ElementMemo> memo = nullptr);
#endif
/*!
Destructor
*/
virtual ~Memo();
// MARK: - Operators
/*!
Conversion operator
@return True if the memo contains data
*/
operator bool() const;
// MARK: - Functions (const)
#ifdef ARCHICAD
/*!
Get the memo root data
@return The memo root data (nullptr on failure)
*/
API_ElementMemo* root() const { return m_data.get(); }
#endif
// MARK: - Functions (mutating)
#ifdef ARCHICAD
/*!
Get the memo root data
@return The memo root data (nullptr on failure)
*/
Memo& set(std::unique_ptr<API_ElementMemo> memo) {
m_data = std::move(memo);
return *this;
}
#endif
private:
#ifdef ARCHICAD
//NB: The following is functionally redundant for memos - requirement of base class
static API_Elem_Head m_dummy;
virtual const API_Elem_Head& getHead() const { return m_dummy; }
virtual API_Elem_Head& getHead() { return m_dummy; }
///The memo data
std::unique_ptr<API_ElementMemo> m_data;
#endif
};
}
#endif //SPECKLE_RECORD_ELEMENT_MEMO
+39
View File
@@ -0,0 +1,39 @@
#include "Speckle/Utility/BIMMemory.h"
#ifdef ARCHICAD
#include "BM.hpp"
#endif
using namespace speckle::utility;
namespace {
#ifdef ARCHICAD
/*!
Get the error code from the last memory operation
@return The last error
*/
GSErr getLastError() {
return BMError();
}
#endif
}
/*--------------------------------------------------------------------
Get the size of an allocated pointer block
pointer: The target pointer
return: The allocated pointer size
--------------------------------------------------------------------*/
size_t BIMMemory::getPtrSize(void* pointer) {
#ifdef ARCHICAD
if (pointer == nullptr)
return 0;
auto size = BMGetPtrSize(reinterpret_cast<GSConstPtr>(pointer));
if (getLastError() != NoError)
throw; //TODO: Throw a specific exception type
return size;
#endif
} //BIMMemory::getPtrSize
+23
View File
@@ -0,0 +1,23 @@
#ifndef SPECKLE_UTILITY_BIM_MEMORY
#define SPECKLE_UTILITY_BIM_MEMORY
#include <memory>
namespace speckle::utility {
/*!
BIM memory functions
*/
class BIMMemory {
public:
/*!
Get the size of an allocated pointer block
@param pointer The target pointer
@return The allocated pointer size
*/
static size_t getPtrSize(void* pointer);
};
}
#endif //SPECKLE_UTILITY_BIM_MEMORY
@@ -51,6 +51,24 @@
21A0FBA42CB880690023F24E /* FinishCollector.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FB9F2CB880690023F24E /* FinishCollector.h */; };
21A0FBB52CBA5E380023F24E /* Str256.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FBB42CBA5E380023F24E /* Str256.h */; };
21A0FBBC2CBBC04C0023F24E /* ArchicadRGB.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FBB92CBBC04C0023F24E /* ArchicadRGB.h */; };
21A0FBEA2CBD6B1A0023F24E /* ColumnSegment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21A0FBDF2CBD6B1A0023F24E /* ColumnSegment.cpp */; };
21A0FBEB2CBD6B1A0023F24E /* ColumnSegment.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FBE22CBD6B1A0023F24E /* ColumnSegment.h */; };
21A0FBED2CBD6B1A0023F24E /* Part.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FBE42CBD6B1A0023F24E /* Part.h */; };
21A0FBF02CBD6B1A0023F24E /* Column.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21A0FBE82CBD6B1A0023F24E /* Column.cpp */; };
21A0FBF12CBD6B1A0023F24E /* Column.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FBE92CBD6B1A0023F24E /* Column.h */; };
21A0FBF42CBD6B700023F24E /* Memo.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FBF22CBD6B700023F24E /* Memo.h */; };
21A0FBF52CBD6B700023F24E /* Memo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21A0FBF32CBD6B700023F24E /* Memo.cpp */; };
21A0FBF82CBDB9A70023F24E /* BIMMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21A0FBF62CBDB9A70023F24E /* BIMMemory.cpp */; };
21A0FBF92CBDB9A70023F24E /* BIMMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FBF72CBDB9A70023F24E /* BIMMemory.h */; };
21A0FC042CBE59A80023F24E /* SegmentedColumn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21A0FBFF2CBE59A80023F24E /* SegmentedColumn.cpp */; };
21A0FC052CBE59A80023F24E /* SegmentedColumn.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FC002CBE59A80023F24E /* SegmentedColumn.h */; };
21A0FC062CBE59A80023F24E /* Path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21A0FC012CBE59A80023F24E /* Path.cpp */; };
21A0FC072CBE59A80023F24E /* Path.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FC022CBE59A80023F24E /* Path.h */; };
21A0FC0A2CBE5E220023F24E /* Segment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21A0FC082CBE5E220023F24E /* Segment.cpp */; };
21A0FC0B2CBE5E220023F24E /* Segment.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FC092CBE5E220023F24E /* Segment.h */; };
21A0FC0E2CBE92F10023F24E /* GenericElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21A0FC0C2CBE92F10023F24E /* GenericElement.cpp */; };
21A0FC0F2CBE92F10023F24E /* GenericElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FC0D2CBE92F10023F24E /* GenericElement.h */; };
21A0FC112CBEE5C30023F24E /* Part.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21A0FC102CBEE5C30023F24E /* Part.cpp */; };
21AEF9BA2CA606B5000B8681 /* DetachedReference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21AEF9B92CA606B4000B8681 /* DetachedReference.cpp */; };
21AEF9BC2CA6DF84000B8681 /* DetachmentManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21AEF9BB2CA6DF84000B8681 /* DetachmentManager.cpp */; };
21AEF9BE2CA6FDA4000B8681 /* DetachedWrap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21AEF9BD2CA6FDA4000B8681 /* DetachedWrap.cpp */; };
@@ -193,6 +211,24 @@
21A0FBA92CB9324A0023F24E /* FinishProxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FinishProxy.h; sourceTree = "<group>"; };
21A0FBB42CBA5E380023F24E /* Str256.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Str256.h; sourceTree = "<group>"; };
21A0FBB92CBBC04C0023F24E /* ArchicadRGB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArchicadRGB.h; sourceTree = "<group>"; };
21A0FBDF2CBD6B1A0023F24E /* ColumnSegment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ColumnSegment.cpp; sourceTree = "<group>"; };
21A0FBE22CBD6B1A0023F24E /* ColumnSegment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColumnSegment.h; sourceTree = "<group>"; };
21A0FBE42CBD6B1A0023F24E /* Part.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Part.h; sourceTree = "<group>"; };
21A0FBE82CBD6B1A0023F24E /* Column.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Column.cpp; sourceTree = "<group>"; };
21A0FBE92CBD6B1A0023F24E /* Column.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Column.h; sourceTree = "<group>"; };
21A0FBF22CBD6B700023F24E /* Memo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Memo.h; sourceTree = "<group>"; };
21A0FBF32CBD6B700023F24E /* Memo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Memo.cpp; sourceTree = "<group>"; };
21A0FBF62CBDB9A70023F24E /* BIMMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BIMMemory.cpp; sourceTree = "<group>"; };
21A0FBF72CBDB9A70023F24E /* BIMMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BIMMemory.h; sourceTree = "<group>"; };
21A0FBFF2CBE59A80023F24E /* SegmentedColumn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SegmentedColumn.cpp; sourceTree = "<group>"; };
21A0FC002CBE59A80023F24E /* SegmentedColumn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SegmentedColumn.h; sourceTree = "<group>"; };
21A0FC012CBE59A80023F24E /* Path.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Path.cpp; sourceTree = "<group>"; };
21A0FC022CBE59A80023F24E /* Path.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Path.h; sourceTree = "<group>"; };
21A0FC082CBE5E220023F24E /* Segment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Segment.cpp; sourceTree = "<group>"; };
21A0FC092CBE5E220023F24E /* Segment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Segment.h; sourceTree = "<group>"; };
21A0FC0C2CBE92F10023F24E /* GenericElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GenericElement.cpp; sourceTree = "<group>"; };
21A0FC0D2CBE92F10023F24E /* GenericElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericElement.h; sourceTree = "<group>"; };
21A0FC102CBEE5C30023F24E /* Part.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Part.cpp; path = Speckle/Record/Element/Interface/Part.cpp; sourceTree = SOURCE_ROOT; };
21AEF9B32CA5F7CF000B8681 /* DetachedWrap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetachedWrap.h; sourceTree = "<group>"; };
21AEF9B52CA5FA02000B8681 /* DetachedReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetachedReference.h; sourceTree = "<group>"; };
21AEF9B72CA5FCB6000B8681 /* DetachmentManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetachmentManager.h; sourceTree = "<group>"; };
@@ -340,8 +376,17 @@
215F087A2CA18E1400CD343B /* Element */ = {
isa = PBXGroup;
children = (
21A0FBE82CBD6B1A0023F24E /* Column.cpp */,
21A0FBE92CBD6B1A0023F24E /* Column.h */,
21A0FBDF2CBD6B1A0023F24E /* ColumnSegment.cpp */,
21A0FBE22CBD6B1A0023F24E /* ColumnSegment.h */,
215F08782CA18E1400CD343B /* Element.cpp */,
215F08792CA18E1400CD343B /* Element.h */,
21A0FC0C2CBE92F10023F24E /* GenericElement.cpp */,
21A0FC0D2CBE92F10023F24E /* GenericElement.h */,
21A0FBE72CBD6B1A0023F24E /* Interface */,
21A0FBF32CBD6B700023F24E /* Memo.cpp */,
21A0FBF22CBD6B700023F24E /* Memo.h */,
);
path = Element;
sourceTree = "<group>";
@@ -429,6 +474,8 @@
219351B02C62CC1A00E5A69C /* Utility */ = {
isa = PBXGroup;
children = (
21A0FBF62CBDB9A70023F24E /* BIMMemory.cpp */,
21A0FBF72CBDB9A70023F24E /* BIMMemory.h */,
21B67CFE2C7CE15100FD64FC /* Exception.h */,
219351AC2C62CC1A00E5A69C /* Guid.cpp */,
219351AD2C62CC1A00E5A69C /* Guid.h */,
@@ -499,6 +546,29 @@
path = Types;
sourceTree = "<group>";
};
21A0FBE72CBD6B1A0023F24E /* Interface */ = {
isa = PBXGroup;
children = (
21A0FC032CBE59A80023F24E /* Assembly */,
21A0FC102CBEE5C30023F24E /* Part.cpp */,
21A0FBE42CBD6B1A0023F24E /* Part.h */,
21A0FBFF2CBE59A80023F24E /* SegmentedColumn.cpp */,
21A0FC002CBE59A80023F24E /* SegmentedColumn.h */,
);
path = Interface;
sourceTree = "<group>";
};
21A0FC032CBE59A80023F24E /* Assembly */ = {
isa = PBXGroup;
children = (
21A0FC012CBE59A80023F24E /* Path.cpp */,
21A0FC022CBE59A80023F24E /* Path.h */,
21A0FC082CBE5E220023F24E /* Segment.cpp */,
21A0FC092CBE5E220023F24E /* Segment.h */,
);
path = Assembly;
sourceTree = "<group>";
};
21AEF9C72CA818EA000B8681 /* Detached */ = {
isa = PBXGroup;
children = (
@@ -705,6 +775,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
21A0FBF42CBD6B700023F24E /* Memo.h in Headers */,
215F088C2CA195EC00CD343B /* ArchicadDBaseCore.h in Headers */,
21D0BDE72C943D3F0077E104 /* RecordID.h in Headers */,
21D0BD212C86F0280077E104 /* AccountDatabase.h in Headers */,
@@ -721,10 +792,15 @@
21D0BD562C890B1C0077E104 /* ServerMigration.h in Headers */,
210CC88F2C81A98500610F58 /* Guid64.h in Headers */,
21AEF9DD2CAAA4EA000B8681 /* DetachedObjectStore.h in Headers */,
21A0FBF12CBD6B1A0023F24E /* Column.h in Headers */,
21A0FC072CBE59A80023F24E /* Path.h in Headers */,
21A0FBA42CB880690023F24E /* FinishCollector.h in Headers */,
21A0FC0B2CBE5E220023F24E /* Segment.h in Headers */,
215F088D2CA195EC00CD343B /* ArchicadElementDBaseEngine.h in Headers */,
2196F2F42CB483D600450DFC /* Finish.h in Headers */,
21A0FBED2CBD6B1A0023F24E /* Part.h in Headers */,
21B67D002C7CE15100FD64FC /* Exception.h in Headers */,
21A0FBEB2CBD6B1A0023F24E /* ColumnSegment.h in Headers */,
21D0BD2C2C86FC350077E104 /* Record.h in Headers */,
21D0BDB42C8F8AB60077E104 /* DocumentStoreCore.h in Headers */,
215F087E2CA18E1400CD343B /* Element.h in Headers */,
@@ -734,7 +810,10 @@
210CC8802C80CD2A00610F58 /* BridgeChild.h in Headers */,
21D0BD4D2C8901A00077E104 /* ServerInfo.h in Headers */,
2196F3042CB57E8000450DFC /* Storey.h in Headers */,
21A0FBF92CBDB9A70023F24E /* BIMMemory.h in Headers */,
21A0FBBC2CBBC04C0023F24E /* ArchicadRGB.h in Headers */,
21A0FC052CBE59A80023F24E /* SegmentedColumn.h in Headers */,
21A0FC0F2CBE92F10023F24E /* GenericElement.h in Headers */,
21D0BDB52C8F8AB60077E104 /* DocumentStoreEngine.h in Headers */,
21D0BDC52C9241940077E104 /* ProjectSubscriber.h in Headers */,
2196F2EC2CB4816B00450DFC /* ArchicadAttributeDBaseEngine.h in Headers */,
@@ -863,6 +942,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
21A0FC0A2CBE5E220023F24E /* Segment.cpp in Sources */,
21D0BD552C890B1C0077E104 /* ServerMigration.cpp in Sources */,
21F69FA62C733EDA008B6A06 /* BridgeArgument.cpp in Sources */,
21F69F682C6DFB01008B6A06 /* RunMethod.cpp in Sources */,
@@ -885,25 +965,33 @@
2196F3052CB57E8000450DFC /* Storey.cpp in Sources */,
219245FE2CA2CC4300CF5703 /* BIMRecord.cpp in Sources */,
21AEF9BE2CA6FDA4000B8681 /* DetachedWrap.cpp in Sources */,
21A0FC062CBE59A80023F24E /* Path.cpp in Sources */,
2196F2F52CB483D600450DFC /* Finish.cpp in Sources */,
21A0FBEA2CBD6B1A0023F24E /* ColumnSegment.cpp in Sources */,
2193519B2C6278D900E5A69C /* SelectionSubscriber.cpp in Sources */,
21D0BD2B2C86FC350077E104 /* Record.cpp in Sources */,
219246042CA2CE2700CF5703 /* BIMLink.cpp in Sources */,
215F08952CA19AF800CD343B /* BIMElementDatabase.cpp in Sources */,
21A0FC0E2CBE92F10023F24E /* GenericElement.cpp in Sources */,
219246122CA34DCE00CF5703 /* Mesh.cpp in Sources */,
21A0FBF02CBD6B1A0023F24E /* Column.cpp in Sources */,
21D0BD592C8910400077E104 /* UserInfo.cpp in Sources */,
210CC8902C81A98500610F58 /* Guid64.cpp in Sources */,
21D0BDC42C9241940077E104 /* ProjectSubscriber.cpp in Sources */,
219351B32C62CC1A00E5A69C /* String.cpp in Sources */,
219351B12C62CC1A00E5A69C /* Guid.cpp in Sources */,
21F69F512C6CCC25008B6A06 /* BrowserBridge.cpp in Sources */,
21A0FC112CBEE5C30023F24E /* Part.cpp in Sources */,
21AEF9BC2CA6DF84000B8681 /* DetachmentManager.cpp in Sources */,
215F08552C99DA8D00CD343B /* Project.cpp in Sources */,
21F69F3B2C6B880C008B6A06 /* JSBaseTransport.cpp in Sources */,
2196F2EB2CB4816B00450DFC /* ArchicadAttributeDBaseEngine.cpp in Sources */,
21A0FC042CBE59A80023F24E /* SegmentedColumn.cpp in Sources */,
210CC89F2C81E34400610F58 /* Platform.cpp in Sources */,
21D0BD202C86F0280077E104 /* AccountDatabase.cpp in Sources */,
21F69F962C71087A008B6A06 /* Account.cpp in Sources */,
21A0FBF82CBDB9A70023F24E /* BIMMemory.cpp in Sources */,
21A0FBF52CBD6B700023F24E /* Memo.cpp in Sources */,
21AEF9BA2CA606B5000B8681 /* DetachedReference.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
+18
View File
@@ -71,7 +71,15 @@
<ClInclude Include="Speckle\Record\Credentials\ServerInfo.h" />
<ClInclude Include="Speckle\Record\Credentials\ServerMigration.h" />
<ClInclude Include="Speckle\Record\Credentials\UserInfo.h" />
<ClInclude Include="Speckle\Record\Element\Column.h" />
<ClInclude Include="Speckle\Record\Element\ColumnSegment.h" />
<ClInclude Include="Speckle\Record\Element\Element.h" />
<ClInclude Include="Speckle\Record\Element\GenericElement.h" />
<ClInclude Include="Speckle\Record\Element\Interface\Assembly\Path.h" />
<ClInclude Include="Speckle\Record\Element\Interface\Assembly\Segment.h" />
<ClInclude Include="Speckle\Record\Element\Interface\Part.h" />
<ClInclude Include="Speckle\Record\Element\Interface\SegmentedColumn.h" />
<ClInclude Include="Speckle\Record\Element\Memo.h" />
<ClInclude Include="Speckle\Serialise\Collection\FinishCollector.h" />
<ClInclude Include="Speckle\Serialise\Collection\FinishProxy.h" />
<ClInclude Include="Speckle\Serialise\Detached\DetachedReference.h" />
@@ -84,6 +92,7 @@
<ClInclude Include="Speckle\Serialise\Types\Str256.h" />
<ClInclude Include="Speckle\Serialise\Types\Units\LengthUnit.h" />
<ClInclude Include="Speckle\SpeckleResource.h" />
<ClInclude Include="Speckle\Utility\BIMMemory.h" />
<ClInclude Include="Speckle\Utility\Exception.h" />
<ClInclude Include="Speckle\Utility\Guid.h" />
<ClInclude Include="Speckle\Utility\Guid64.h" />
@@ -124,12 +133,21 @@
<ClCompile Include="Speckle\Record\Credentials\ServerInfo.cpp" />
<ClCompile Include="Speckle\Record\Credentials\ServerMigration.cpp" />
<ClCompile Include="Speckle\Record\Credentials\UserInfo.cpp" />
<ClCompile Include="Speckle\Record\Element\Column.cpp" />
<ClCompile Include="Speckle\Record\Element\ColumnSegment.cpp" />
<ClCompile Include="Speckle\Record\Element\Element.cpp" />
<ClCompile Include="Speckle\Record\Element\GenericElement.cpp" />
<ClCompile Include="Speckle\Record\Element\Interface\Assembly\Path.cpp" />
<ClCompile Include="Speckle\Record\Element\Interface\Assembly\Segment.cpp" />
<ClCompile Include="Speckle\Record\Element\Interface\Part.cpp" />
<ClCompile Include="Speckle\Record\Element\Interface\SegmentedColumn.cpp" />
<ClCompile Include="Speckle\Record\Element\Memo.cpp" />
<ClCompile Include="Speckle\Serialise\Detached\DetachedReference.cpp" />
<ClCompile Include="Speckle\Serialise\Detached\DetachedWrap.cpp" />
<ClCompile Include="Speckle\Serialise\Detached\DetachmentManager.cpp" />
<ClCompile Include="Speckle\Serialise\JSBase\JSBaseTransport.cpp" />
<ClCompile Include="Speckle\Serialise\Types\Units\LengthUnit.cpp" />
<ClCompile Include="Speckle\Utility\BIMMemory.cpp" />
<ClCompile Include="Speckle\Utility\Guid.cpp" />
<ClCompile Include="Speckle\Utility\Guid64.cpp" />
<ClCompile Include="Speckle\Utility\String.cpp" />
+60
View File
@@ -98,6 +98,12 @@
<Filter Include="Speckle\Serialise\Types\Units">
<UniqueIdentifier>{7f43d4ea-b876-4587-a646-90eab81f7976}</UniqueIdentifier>
</Filter>
<Filter Include="Speckle\Record\Element\Interface">
<UniqueIdentifier>{b35abbfd-3c47-45dc-8dab-58911f233a87}</UniqueIdentifier>
</Filter>
<Filter Include="Speckle\Record\Element\Interface\Assembly">
<UniqueIdentifier>{8e7a76da-47ac-4105-9c09-7d7ed62d7136}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Speckle\Environment\Addon.h">
@@ -310,6 +316,33 @@
<ClInclude Include="Speckle\Serialise\Types\ArchicadRGB.h">
<Filter>Speckle\Serialise\Types</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Column.h">
<Filter>Speckle\Record\Element</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\ColumnSegment.h">
<Filter>Speckle\Record\Element</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Memo.h">
<Filter>Speckle\Record\Element</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Interface\Part.h">
<Filter>Speckle\Record\Element\Interface</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Interface\SegmentedColumn.h">
<Filter>Speckle\Record\Element\Interface</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Interface\Assembly\Path.h">
<Filter>Speckle\Record\Element\Interface\Assembly</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Interface\Assembly\Segment.h">
<Filter>Speckle\Record\Element\Interface\Assembly</Filter>
</ClInclude>
<ClInclude Include="Speckle\Utility\BIMMemory.h">
<Filter>Speckle\Utility</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\GenericElement.h">
<Filter>Speckle\Record\Element</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Speckle\Environment\Addon.cpp">
@@ -438,6 +471,33 @@
<ClCompile Include="Speckle\Serialise\Types\Units\LengthUnit.cpp">
<Filter>Speckle\Serialise\Types\Units</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Column.cpp">
<Filter>Speckle\Record\Element</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\ColumnSegment.cpp">
<Filter>Speckle\Record\Element</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Memo.cpp">
<Filter>Speckle\Record\Element</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Interface\Part.cpp">
<Filter>Speckle\Record\Element\Interface</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Interface\SegmentedColumn.cpp">
<Filter>Speckle\Record\Element\Interface</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Interface\Assembly\Path.cpp">
<Filter>Speckle\Record\Element\Interface\Assembly</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Interface\Assembly\Segment.cpp">
<Filter>Speckle\Record\Element\Interface\Assembly</Filter>
</ClCompile>
<ClCompile Include="Speckle\Utility\BIMMemory.cpp">
<Filter>Speckle\Utility</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\GenericElement.cpp">
<Filter>Speckle\Record\Element</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="Speckle\CMakeLists.txt">