Compare commits

...

33 Commits

Author SHA1 Message Date
David Kekesi a330baf5da cleanup 2024-11-07 11:08:56 +01:00
David Kekesi ea103f3849 disabled sending grid elements, disabled element change subscription on new element event 2024-11-07 11:05:16 +01:00
Ralph Wessel 664fdaf39a Merge pull request #17 from specklesystems/david/cnx-716-documentless-state-in-archicad
cnx 716 documentless state in archicad
2024-11-06 19:35:38 +00:00
David Kekesi a6f15e9a53 review comments fixed 2024-11-06 20:34:46 +01:00
David Kekesi 0e0dc7da2d switching to 3D window before send operation implemented 2024-11-06 20:24:03 +01:00
Ralph Wessel cdd4df09ca Added setDefaultTable and getDefaultTable for BIMElementDatabase 2024-11-06 19:18:37 +00:00
David Kekesi e612ed1192 attaching observer to all elements is too slow, commented out for now 2024-11-06 20:18:36 +01:00
David Kekesi ed75c2110c Merge branch 'develop' into david/cnx-716-documentless-state-in-archicad 2024-11-06 19:44:40 +01:00
David Kekesi 96759f7e9e very slow in a 3D view - attaching element observers to all elements 2024-11-06 19:43:01 +01:00
Ralph Wessel 902ddcc8f1 Updated VS projects 2024-11-06 18:11:45 +00:00
Ralph Wessel b62201cf95 BIMElementDatabase::getTables and bringToFront added
BIMElementDatabase::getElements allows a target table to be specified
2024-11-06 18:03:26 +00:00
Ralph Wessel 4e60d95ce9 DocumentID is now generated, saved and recalled using ModelCardDatabase 2024-11-06 16:25:13 +00:00
Ralph Wessel 03ad5a80af Merge branch 'develop' of https://github.com/specklesystems/speckle-cpp-connectors into develop 2024-11-06 13:06:38 +00:00
Ralph Wessel fbbf559e83 ConnectorProject should add its model card database to the add-on as a subscriber in order to receive document events, e.g. merge 2024-11-06 13:06:25 +00:00
David Kekesi da457a3438 subscribing all elements to element events 2024-11-06 11:51:29 +01:00
Ralph Wessel 767e379ff3 Updated Windows resources 2024-11-05 19:05:30 +00:00
Ralph Wessel 08c15c87a2 Updated menu icons 2024-11-05 18:50:14 +00:00
Ralph Wessel 1827323712 Added Speckle menu icon 2024-11-05 18:30:17 +00:00
Ralph Wessel 653824c498 Updated VS projects
GetDocumentInfo returns null if no project open
2024-11-05 17:01:51 +00:00
Ralph Wessel 0dc823785d Removed test code from ConnectorPalette 2024-11-05 16:37:27 +00:00
Ralph Wessel bacdbc4d61 Added ConnectorProject as a container for ModelCardDatabase
Moved ownership of ModelCardDatabase from Addon to ConnectorProject
Tools requiring access to the model card database now need to check for an open project first and then obtain the database from it (prevents attempts to access model cards when no project is open)
2024-11-05 16:34:49 +00:00
Ralph Wessel ef989ad8c7 Merge pull request #16 from specklesystems/david/cnx-720-no-objects-were-found-to-convert-please-update-your-publish
cnx 720 no objects were found to convert please update your publish
2024-11-05 11:53:44 +00:00
David Kekesi 8d8934657c get the selected element ids from the modelcard instead of the application during a send operation 2024-11-05 12:46:14 +01:00
Ralph Wessel d7a95fd37c Added BIMElementDatabase::findObjects 2024-11-05 11:25:33 +00:00
Ralph Wessel 74d4871fbd Added ArchicadElementDBaseEngine::find
Implemented ArchicadElementDBaseEngine::getObjects
2024-11-05 11:15:53 +00:00
Ralph Wessel f634f158f9 Use FastDoubleWrap for serialising Mesh vertices 2024-11-05 08:33:53 +00:00
Ralph Wessel 48988fbe53 Updated VS projects
Renamed Element/Mesh.cpp for VS compilation
2024-11-01 23:25:49 +00:00
Ralph Wessel 2c0d53c186 Added materials quants for mesh, morph, roof, shell, slab and wall 2024-11-01 22:57:47 +00:00
Ralph Wessel 51370ababc Updated VS projects 2024-11-01 22:56:39 +00:00
Ralph Wessel 8132eec03e Material quantities add, implement for column and beam segments
Added Material class
Renamed variables for finishes from "material" to "finish"
Fixed major memory leak in ModelElement::getBody
Updated element BIMLink to include a type identifier
2024-11-01 17:01:56 +00:00
Ralph Wessel 82bd96de61 Updated Xcode project 2024-10-30 22:55:23 +00:00
Ralph Wessel 51ed951d7d Added Platform::openURL to open a URL cross-platform 2024-10-30 22:54:17 +00:00
Ralph Wessel cc6c884f47 Merge pull request #15 from specklesystems/david/wire-in-view-button
view button on modelcard works
2024-10-30 22:42:57 +00:00
87 changed files with 4118 additions and 307 deletions
+1
View File
@@ -3,6 +3,7 @@ build/
Documents/
ResourceObjects/
Install/
enc_temp_folder/
.vs/
.vscode/
xcuserdata/
+2
View File
@@ -94,6 +94,7 @@
<ItemGroup>
<ClCompile Include="Connector\Connector.cpp" />
<ClCompile Include="Connector\Database\ModelCardDatabase.cpp" />
<ClCompile Include="Connector\Environment\ConnectorProject.cpp" />
<ClCompile Include="Connector\Interface\Browser\Bridge\Account\AccountBridge.cpp" />
<ClCompile Include="Connector\Interface\Browser\Bridge\Account\GetAccounts.cpp" />
<ClCompile Include="Connector\Interface\Browser\Bridge\Base\AddModel.cpp" />
@@ -150,6 +151,7 @@
<ClInclude Include="Connector\ConnectorResource.h" />
<ClInclude Include="Connector\Database\Identity\RecordID.h" />
<ClInclude Include="Connector\Database\ModelCardDatabase.h" />
<ClInclude Include="Connector\Environment\ConnectorProject.h" />
<ClInclude Include="Connector\Event\ConnectorEventID.h" />
<ClInclude Include="Connector\Interface\Browser\Bridge\Account\AccountBridge.h" />
<ClInclude Include="Connector\Interface\Browser\Bridge\Account\GetAccounts.h" />
@@ -71,6 +71,9 @@
<Filter Include="Connector\Interface\Browser\Bridge\Selection\Arg">
<UniqueIdentifier>{8bb3df60-affe-4b66-8d78-f1b98e6ba8df}</UniqueIdentifier>
</Filter>
<Filter Include="Connector\Environment">
<UniqueIdentifier>{1d9a10c3-cac6-4b15-afb9-f117b99b3a24}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="RFIX.win\Connector.rc2">
@@ -249,6 +252,9 @@
<ClCompile Include="Connector\Interface\Browser\Bridge\Base\OpenUrl.cpp">
<Filter>Connector\Interface\Browser\Bridge\Base</Filter>
</ClCompile>
<ClCompile Include="Connector\Environment\ConnectorProject.cpp">
<Filter>Connector\Environment</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Connector\ConnectorResource.h">
@@ -423,5 +429,8 @@
<ClInclude Include="Connector\Interface\Browser\Bridge\Base\OpenUrl.h">
<Filter>Connector\Interface\Browser\Bridge\Base</Filter>
</ClInclude>
<ClInclude Include="Connector\Environment\ConnectorProject.h">
<Filter>Connector\Environment</Filter>
</ClInclude>
</ItemGroup>
</Project>
@@ -23,6 +23,7 @@
/* Begin PBXBuildFile section */
210CC8832C80E6A300610F58 /* TriggerEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 210CC8812C80E6A300610F58 /* TriggerEvent.cpp */; };
21384BCD2CD2EE7400D4602B /* OpenUrl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21384BC92CD2EE7400D4602B /* OpenUrl.cpp */; };
213CC39C2B1101F500088049 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2151077C2AEDB9070022CD24 /* Cocoa.framework */; };
214B7A372C764BCD00D586C1 /* UpdateConfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21F69FBD2C7630B3008B6A06 /* UpdateConfig.cpp */; };
215F082A2C947F4400CD343B /* CardMover.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 215F08262C947F4400CD343B /* CardMover.cpp */; };
@@ -30,6 +31,7 @@
215F08372C95808B00CD343B /* ReceiverModelCard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 215F08362C95808B00CD343B /* ReceiverModelCard.cpp */; };
215F08462C9633A800CD343B /* EverythingSendFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 215F08452C9633A800CD343B /* EverythingSendFilter.cpp */; };
2192460D2CA3469D00CF5703 /* ProjectCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2192460B2CA3469D00CF5703 /* ProjectCollection.cpp */; };
2199BB552CDA4B1700A4BEEC /* ConnectorProject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2199BB522CDA4B1700A4BEEC /* ConnectorProject.cpp */; };
219F30422C769283009834E9 /* ConfigTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 219F30402C769282009834E9 /* ConfigTests.cpp */; };
21A0FB982CB723240023F24E /* FinishProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21A0FB942CB723240023F24E /* FinishProxy.cpp */; };
21A79EC92CCDA45C001754E4 /* HighlightModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21A79EC52CCDA45C001754E4 /* HighlightModel.cpp */; };
@@ -296,6 +298,8 @@
/* Begin PBXFileReference section */
210CC8812C80E6A300610F58 /* TriggerEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TriggerEvent.cpp; sourceTree = "<group>"; };
210CC8822C80E6A300610F58 /* TriggerEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TriggerEvent.h; sourceTree = "<group>"; };
21384BC92CD2EE7400D4602B /* OpenUrl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenUrl.cpp; sourceTree = "<group>"; };
21384BCC2CD2EE7400D4602B /* OpenUrl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenUrl.h; sourceTree = "<group>"; };
213CC3A52B1101F500088049 /* Speckle Connector.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Speckle Connector.bundle"; sourceTree = BUILT_PRODUCTS_DIR; };
2151077C2AEDB9070022CD24 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
215F08262C947F4400CD343B /* CardMover.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CardMover.cpp; sourceTree = "<group>"; };
@@ -313,6 +317,10 @@
2192460B2CA3469D00CF5703 /* ProjectCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProjectCollection.cpp; sourceTree = "<group>"; };
2192460C2CA3469D00CF5703 /* ProjectCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectCollection.h; sourceTree = "<group>"; };
219388682C4E5DE2002A0180 /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
2199BB512CDA481A00A4BEEC /* ConnectorFix.grc */ = {isa = PBXFileReference; lastKnownFileType = text; name = ConnectorFix.grc; path = RFIX/ConnectorFix.grc; sourceTree = "<group>"; };
2199BB522CDA4B1700A4BEEC /* ConnectorProject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConnectorProject.cpp; sourceTree = "<group>"; };
2199BB532CDA4B1700A4BEEC /* ConnectorProject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConnectorProject.h; sourceTree = "<group>"; };
2199BB5C2CDA93CE00A4BEEC /* ConnectorImagesFix.grc */ = {isa = PBXFileReference; lastKnownFileType = text; name = ConnectorImagesFix.grc; path = RFIX/ConnectorImagesFix.grc; sourceTree = "<group>"; };
219F30352C768F0A009834E9 /* Connector-AC27-Test.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Connector-AC27-Test.bundle"; sourceTree = BUILT_PRODUCTS_DIR; };
219F30402C769282009834E9 /* ConfigTests.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = ConfigTests.cpp; sourceTree = "<group>"; };
219F30432C7693B6009834E9 /* Connector-AC27-Debug.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Connector-AC27-Debug.xctestplan"; sourceTree = SOURCE_ROOT; };
@@ -545,7 +553,6 @@
21D1E9AC2BF14AF200957EAA /* TeamworkProductVersion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = TeamworkProductVersion.framework; path = "../Archicad 27/Support/Frameworks/TeamworkProductVersion.framework"; sourceTree = "<group>"; };
21D1EA452BF14B0700957EAA /* VWMM.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VWMM.framework; path = "../Vectorworks 2024/SDKLib/LibMac/Release/VWMM.framework"; sourceTree = "<group>"; };
21D1EA4A2BF14BBC00957EAA /* Connector.grc */ = {isa = PBXFileReference; lastKnownFileType = text; name = Connector.grc; path = RINT/Connector.grc; sourceTree = "<group>"; };
21D1EA4B2BF14BC700957EAA /* ConnectorFix.grc */ = {isa = PBXFileReference; lastKnownFileType = text; name = ConnectorFix.grc; path = RFIX/ConnectorFix.grc; sourceTree = "<group>"; };
21D1EA4C2BF14BF000957EAA /* Module-Info27.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Module-Info27.plist"; path = "RINT.Archicad/EN-GB/Module-Info27.plist"; sourceTree = "<group>"; };
21F69EC62C64C035008B6A06 /* SpeckleLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SpeckleLib.xcodeproj; path = ../SpeckleLib/SpeckleLib.xcodeproj; sourceTree = "<group>"; };
21F69EDB2C64ED10008B6A06 /* ConnectorMenu.grc */ = {isa = PBXFileReference; lastKnownFileType = text; name = ConnectorMenu.grc; path = RINT/ConnectorMenu.grc; sourceTree = "<group>"; };
@@ -965,6 +972,24 @@
path = Identity;
sourceTree = "<group>";
};
2199BB4E2CDA47F900A4BEEC /* Fixed */ = {
isa = PBXGroup;
children = (
2199BB512CDA481A00A4BEEC /* ConnectorFix.grc */,
2199BB5C2CDA93CE00A4BEEC /* ConnectorImagesFix.grc */,
);
name = Fixed;
sourceTree = "<group>";
};
2199BB542CDA4B1700A4BEEC /* Environment */ = {
isa = PBXGroup;
children = (
2199BB522CDA4B1700A4BEEC /* ConnectorProject.cpp */,
2199BB532CDA4B1700A4BEEC /* ConnectorProject.h */,
);
path = Environment;
sourceTree = "<group>";
};
219F30412C769282009834E9 /* ConnectorTests */ = {
isa = PBXGroup;
children = (
@@ -1031,6 +1056,8 @@
21B67CAA2C77329800FD64FC /* GetSourceApplicationVersion.h */,
21A79EC52CCDA45C001754E4 /* HighlightModel.cpp */,
21A79EC82CCDA45C001754E4 /* HighlightModel.h */,
21384BC92CD2EE7400D4602B /* OpenUrl.cpp */,
21384BCC2CD2EE7400D4602B /* OpenUrl.h */,
21D0BDD52C935DAE0077E104 /* RemoveModel.cpp */,
21D0BDD62C935DAE0077E104 /* RemoveModel.h */,
21D0BDD22C935D1A0077E104 /* UpdateModel.cpp */,
@@ -1158,7 +1185,6 @@
isa = PBXGroup;
children = (
21D1EA4A2BF14BBC00957EAA /* Connector.grc */,
21D1EA4B2BF14BC700957EAA /* ConnectorFix.grc */,
21F69EDB2C64ED10008B6A06 /* ConnectorMenu.grc */,
21D1EA4C2BF14BF000957EAA /* Module-Info27.plist */,
21F69EFE2C66AD55008B6A06 /* SpecklePalette.grc */,
@@ -1211,6 +1237,7 @@
21B67CCD2C77694500FD64FC /* Connector.h */,
21F69F102C677BC0008B6A06 /* ConnectorResource.h */,
21B67CCB2C77670400FD64FC /* Database */,
2199BB542CDA4B1700A4BEEC /* Environment */,
21F69F092C677BC0008B6A06 /* Event */,
21F69F0E2C677BC0008B6A06 /* Interface */,
21D0BDD82C9387E60077E104 /* Record */,
@@ -1291,6 +1318,7 @@
81494D9D09DA5892006864FB /* Resource */ = {
isa = PBXGroup;
children = (
2199BB4E2CDA47F900A4BEEC /* Fixed */,
7EA5F91E157FA18400693CEA /* EN-GB */,
);
name = Resource;
@@ -1525,7 +1553,9 @@
215F08372C95808B00CD343B /* ReceiverModelCard.cpp in Sources */,
21D0BDD72C935DAE0077E104 /* RemoveModel.cpp in Sources */,
21A890BC2CC15C540087E732 /* SelectionInfo.cpp in Sources */,
2199BB552CDA4B1700A4BEEC /* ConnectorProject.cpp in Sources */,
21AEF9EF2CAB5720000B8681 /* SendObject.cpp in Sources */,
21384BCD2CD2EE7400D4602B /* OpenUrl.cpp in Sources */,
21B67CDC2C78C88000FD64FC /* SayHi.cpp in Sources */,
215F082E2C94C5C000CD343B /* FilterMover.cpp in Sources */,
21F69F122C677BC0008B6A06 /* ConnectorMenu.cpp in Sources */,
+9 -8
View File
@@ -1,7 +1,7 @@
#include "Active/File/Directory.h"
#include "ConnectorResource.h"
#include "Connector/Connector.h"
#include "Connector/Database/ModelCardDatabase.h"
#include "Connector/Environment/ConnectorProject.h"
#include "Connector/Interface/ConnectorMenu.h"
#include "Connector/Interface/ConnectorPalette.h"
#include "Speckle/Database/AccountDatabase.h"
@@ -11,7 +11,7 @@
using namespace active::file;
using namespace active::environment;
using namespace connector;
using namespace connector::database;
using namespace connector::environment;
using namespace speckle::database;
using namespace speckle::environment;
using namespace speckle::utility;
@@ -29,8 +29,6 @@ namespace {
ConnectorInstance(const String& name) : ConnectorAddon{name} {
add<ConnectorMenu>();
add<ConnectorPalette>();
//The connector 'owns' the model card database, so the publisher list should only hold a weak reference
addWeak(m_modelCards.getSubscription());
}
// MARK: Functions (const)
@@ -40,15 +38,18 @@ namespace {
@return The account database
*/
const AccountDatabase* getAccountDatabase() const override;
protected:
/*!
Get the model card database
@return The model card database
Make a new new project. Allows Addon subclasses to define a Project subclass with additional functions/databases
@return A new project instance
*/
const ModelCardDatabase* getModelCardDatabase() const override { return &m_modelCards; }
virtual std::shared_ptr<Project> makeProject() const override {
return std::dynamic_pointer_cast<Project>(std::make_shared<ConnectorProject>());
}
private:
mutable std::unique_ptr<AccountDatabase> m_account;
ModelCardDatabase m_modelCards;
};
///The active addon instance
-9
View File
@@ -3,10 +3,6 @@
namespace speckle::database {
class AccountDatabase;
class BIMElementDatabase;
}
namespace connector::database {
class ModelCardDatabase;
}
namespace connector {
@@ -22,11 +18,6 @@ namespace connector {
@return The account database
*/
const virtual speckle::database::AccountDatabase* getAccountDatabase() const = 0;
/*!
Get the model card database
@return The model card database
*/
const virtual database::ModelCardDatabase* getModelCardDatabase() const = 0;
protected:
/*!
@@ -0,0 +1,33 @@
#include "Connector/Environment/ConnectorProject.h"
#include "Connector/Connector.h"
#include "Connector/Database/ModelCardDatabase.h"
using namespace active::event;
using namespace connector::database;
using namespace connector::environment;
using namespace speckle::utility;
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
ConnectorProject::ConnectorProject() {
m_modelCards = std::make_shared<ModelCardDatabase>();
connector()->addWeak(m_modelCards->getSubscription());
}
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
ConnectorProject::~ConnectorProject() {}
/*--------------------------------------------------------------------
Get the model card database
return; The model card database
--------------------------------------------------------------------*/
const ModelCardDatabase* ConnectorProject::getModelCardDatabase() const {
return m_modelCards.get();
} //ConnectorProject::getModelCardDatabase
@@ -0,0 +1,53 @@
#ifndef CONNECTOR_ENVIRONMENT_CONNECTOR_PROJECT
#define CONNECTOR_ENVIRONMENT_CONNECTOR_PROJECT
#include "Speckle/Environment/Project.h"
namespace connector::database {
class ModelCardDatabase;
}
namespace connector::environment {
/*!
A BIM project contained Speckle connector data, e.g. a model card database
*/
class ConnectorProject : public speckle::environment::Project {
public:
// MARK: - Types
///Shared pointer
using Shared = std::shared_ptr<ConnectorProject>;
///Weak pointer
using Weak = std::weak_ptr<ConnectorProject>;
// MARK: - Constructors
/*!
Default constructor
*/
ConnectorProject();
ConnectorProject(const ConnectorProject&) = delete;
/*!
Destructor
*/
~ConnectorProject();
// MARK: - Functions (const)
/*!
Get the model card database
@return The model card database
*/
const connector::database::ModelCardDatabase* getModelCardDatabase() const;
private:
///The model card database
std::shared_ptr<connector::database::ModelCardDatabase> m_modelCards;
};
}
#endif //CONNECTOR_ENVIRONMENT_CONNECTOR_PROJECT
@@ -1,10 +1,12 @@
#include "Connector/Interface/Browser/Bridge/Base/AddModel.h"
#include "Connector/Connector.h"
#include "Connector/Environment/ConnectorProject.h"
#include "Connector/Database/ModelCardDatabase.h"
using namespace active::container;
using namespace active::serialise;
using namespace connector::environment;
using namespace connector::record;
using namespace connector::interfac::browser::bridge;
using namespace speckle::utility;
@@ -23,6 +25,10 @@ AddModel::AddModel() : BridgeMethod{"AddModel", [&](const ModelCardEventWrapper&
card: The card to add
--------------------------------------------------------------------*/
void AddModel::run(const ModelCard& card) const {
if (auto modelCardDBase = connector()->getModelCardDatabase(); modelCardDBase != nullptr)
auto project = connector()->getActiveProject().lock();
auto connectorProject = dynamic_cast<ConnectorProject*>(project.get());
if (!connectorProject)
return;
if (auto modelCardDBase = connectorProject->getModelCardDatabase(); modelCardDBase != nullptr)
modelCardDBase->write(card);
} //AddModel::run
@@ -11,8 +11,37 @@
#include "Connector/Interface/Browser/Bridge/Base/OpenUrl.h"
#include "Speckle/Event/Type/ProjectEvent.h"
#include "Speckle/Environment/Project.h"
#include "Speckle/Record/Element/Element.h"
#include "Connector/Connector.h"
#include "Connector/ConnectorResource.h"
#include "Speckle/Database/Identity/RecordID.h"
#include "Speckle/Database/BIMElementDatabase.h"
#include "Connector/Record/Model/SenderModelCard.h"
#include "Connector/Record/Model/Filter/SendFilter.h"
#include "Connector/Database/ModelCardDatabase.h"
using namespace connector::interfac::browser::bridge;
namespace {
#ifdef ARCHICAD
void subscribeAllElementsToElementChangeEvents()
{
auto project = connector::connector()->getActiveProject().lock();
if (!project)
return;
auto elementDatabase = project->getElementDatabase();
//auto table = elementDatabase->getTables(speckle::database::ElementStorage::TableType::primary2D);
//auto allElements = elementDatabase->findElements(nullptr, *table.begin());
auto allElements = elementDatabase->findElements();
for (const auto& id : allElements)
ACAPI_Element_AttachObserver(id);
}
#endif
}
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
@@ -28,6 +57,10 @@ BaseBridge::BaseBridge() : BrowserBridge{"baseBinding"} {
addMethod<UpdateModel>();
addMethod<HighlightModel>();
addMethod<OpenUrl>();
// POC: Attaching Observer to all elements is too slow, registration is commented out for now
// subscribeAllElementsToElementChangeEvents();
} //BaseBridge::BaseBridge
/*--------------------------------------------------------------------
@@ -40,9 +73,11 @@ BaseBridge::BaseBridge() : BrowserBridge{"baseBinding"} {
bool BaseBridge::handle(const speckle::event::ProjectEvent& event) {
using enum speckle::event::ProjectEvent::Type;
switch (event.getType()) {
case open:
case open: {
sendEvent("documentChanged");
break;
// POC: Attaching Observer to all elements is too slow, registration is commented out for now
// subscribeAllElementsToElementChangeEvents();
} break;
default:
break;
}
@@ -2,6 +2,7 @@
#include "Active/Serialise/CargoHold.h"
#include "Connector/Connector.h"
#include "Connector/Environment/ConnectorProject.h"
#include "Connector/Database/ModelCardDatabase.h"
#include "Connector/Interface/Browser/Bridge/Base/Arg/DocumentInfo.h"
#include "Speckle/Environment/Project.h"
@@ -9,6 +10,7 @@
using namespace active::container;
using namespace active::serialise;
using namespace connector::environment;
using namespace connector::interfac::browser::bridge;
using namespace speckle::utility;
@@ -33,14 +35,17 @@ GetDocumentInfo::GetDocumentInfo() : BridgeMethod{"GetDocumentInfo", [&]() {
--------------------------------------------------------------------*/
std::unique_ptr<Cargo> GetDocumentInfo::run() const {
auto docInfo = std::make_unique<DocumentInfo>();
if (auto project = connector()->getActiveProject().lock(); project) {
auto info = project->getInfo();
docInfo->name = info.name;
if (info.path)
docInfo->location = *info.path;
if (auto cardDatabase = connector()->getModelCardDatabase(); cardDatabase != nullptr)
docInfo->ID = cardDatabase->getStoreID();
auto project = connector()->getActiveProject().lock();
auto connectorProject = dynamic_cast<ConnectorProject*>(project.get());
if (!connectorProject)
return nullptr;
auto info = connectorProject->getInfo();
docInfo->name = info.name;
if (info.path)
docInfo->location = *info.path;
if (auto cardDatabase = connectorProject->getModelCardDatabase(); cardDatabase != nullptr)
docInfo->ID = cardDatabase->getStoreID();
else
docInfo->ID = Guid{true}.operator String();
}
return std::make_unique<WrappedValue>(std::move(docInfo));
} //GetDocumentInfo::run
@@ -1,15 +1,13 @@
#include "Connector/Interface/Browser/Bridge/Base/GetDocumentState.h"
#include "Active/Serialise/CargoHold.h"
#include "Connector/Connector.h"
#include "Connector/Record/Model/ModelCard.h"
#include "Connector/Environment/ConnectorProject.h"
#include "Connector/Database/ModelCardDatabase.h"
using namespace active::container;
using namespace active::serialise;
using namespace connector::environment;
using namespace connector::interfac::browser::bridge;
using namespace connector::database;
using namespace connector::record;
using namespace speckle::utility;
/*--------------------------------------------------------------------
@@ -26,7 +24,11 @@ GetDocumentState::GetDocumentState() : BridgeMethod{"GetDocumentState", [&]() {
return: The document model cards
--------------------------------------------------------------------*/
std::unique_ptr<Cargo> GetDocumentState::run() const {
if (auto modelCardDBase = connector()->getModelCardDatabase(); modelCardDBase != nullptr) {
auto project = connector()->getActiveProject().lock();
auto connectorProject = dynamic_cast<ConnectorProject*>(project.get());
if (!connectorProject)
return nullptr;
if (auto modelCardDBase = connectorProject->getModelCardDatabase(); modelCardDBase != nullptr) {
return modelCardDBase->wrapper();
}
return nullptr;
@@ -1,6 +1,7 @@
#include "Connector/Interface/Browser/Bridge/Base/HighlightModel.h"
#include "Connector/Connector.h"
#include "Connector/ConnectorResource.h"
#include "Connector/Environment/ConnectorProject.h"
#include "Connector/Database/ModelCardDatabase.h"
#include "Connector/Interface/Browser/Bridge/Send/Arg/SendError.h"
#include "Connector/Record/Model/SenderModelCard.h"
@@ -11,6 +12,7 @@
#include "Speckle/Environment/Project.h"
using namespace speckle::record::element;
using namespace connector::environment;
using namespace connector::interfac::browser::bridge;
using namespace connector::record;
using namespace speckle::utility;
@@ -29,8 +31,12 @@ HighlightModel::HighlightModel() : BridgeMethod{"HighlightModel", [&](const Send
modelCardID: The ID of the target model card
--------------------------------------------------------------------*/
void HighlightModel::run(const String& modelCardID) const {
// Find the specified model card
auto modelCardDatabase = connector()->getModelCardDatabase();
auto project = connector()->getActiveProject().lock();
auto connectorProject = dynamic_cast<ConnectorProject*>(project.get());
if (!connectorProject)
return;
//Find the specified model card
auto modelCardDatabase = connectorProject->getModelCardDatabase();
auto modelCard = modelCardDatabase->getCard(modelCardID);
if (!modelCard) {
getBridge()->sendEvent("setModelError",
@@ -1,6 +1,9 @@
#include "Connector/Interface/Browser/Bridge/Base/OpenUrl.h"
#include "Speckle/Environment/Platform.h"
using namespace connector::interfac::browser::bridge;
using namespace speckle::environment;
using namespace speckle::utility;
/*--------------------------------------------------------------------
@@ -17,6 +20,5 @@ OpenUrl::OpenUrl() : BridgeMethod{"OpenUrl", [&](const SendArgs& args) {
url: The URL to open
--------------------------------------------------------------------*/
void OpenUrl::run(const String& url) const {
std::string command = "start " + url;
system(command.c_str());
platform()->openURL(url);
} //OpenUrl::run
@@ -1,22 +1,16 @@
#include "Connector/Interface/Browser/Bridge/Base/RemoveModel.h"
#include "Connector/Connector.h"
#include "Connector/Environment/ConnectorProject.h"
#include "Connector/Database/ModelCardDatabase.h"
#include "Connector/Interface/Browser/Bridge/Base/Arg/DocumentInfo.h"
using namespace active::container;
using namespace active::serialise;
using namespace connector::database;
using namespace connector::environment;
using namespace connector::record;
using namespace connector::interfac::browser::bridge;
using namespace speckle::utility;
namespace {
using WrappedValue = active::serialise::CargoHold<PackageWrap, DocumentInfo>;
}
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
@@ -31,6 +25,10 @@ RemoveModel::RemoveModel() : BridgeMethod{"RemoveModel", [&](const ModelCardEven
card: The card to add
--------------------------------------------------------------------*/
void RemoveModel::run(const ModelCard& card) const {
if (auto modelCardDBase = connector()->getModelCardDatabase(); modelCardDBase != nullptr)
auto project = connector()->getActiveProject().lock();
auto connectorProject = dynamic_cast<ConnectorProject*>(project.get());
if (!connectorProject)
return;
if (auto modelCardDBase = connectorProject->getModelCardDatabase(); modelCardDBase != nullptr)
modelCardDBase->erase(card.getID());
} //RemoveModel::run
@@ -2,11 +2,12 @@
#include "Connector/Connector.h"
#include "Connector/Database/ModelCardDatabase.h"
#include "Connector/Environment/ConnectorProject.h"
#include "Connector/Interface/Browser/Bridge/Base/Arg/DocumentInfo.h"
using namespace active::container;
using namespace active::serialise;
using namespace connector::database;
using namespace connector::environment;
using namespace connector::record;
using namespace connector::interfac::browser::bridge;
using namespace speckle::utility;
@@ -31,6 +32,10 @@ UpdateModel::UpdateModel() : BridgeMethod{"UpdateModel", [&](const ModelCardEven
card: The card to update
--------------------------------------------------------------------*/
void UpdateModel::run(const ModelCard& card) const {
if (auto modelCardDBase = connector()->getModelCardDatabase(); modelCardDBase != nullptr)
auto project = connector()->getActiveProject().lock();
auto connectorProject = dynamic_cast<ConnectorProject*>(project.get());
if (!connectorProject)
return;
if (auto modelCardDBase = connectorProject->getModelCardDatabase(); modelCardDBase != nullptr)
modelCardDBase->write(card);
} //UpdateModel::run
@@ -5,22 +5,25 @@
#include "Connector/Connector.h"
#include "Connector/ConnectorResource.h"
#include "Connector/Database/ModelCardDatabase.h"
#include "Connector/Environment/ConnectorProject.h"
#include "Connector/Interface/Browser/Bridge/Send/Arg/SendError.h"
#include "Connector/Interface/Browser/Bridge/Send/Arg/SendViaBrowserArgs.h"
#include "Connector/Record/Collection/ProjectCollection.h"
#include "Connector/Record/Model/SenderModelCard.h"
#include "Connector/Record/Model/Filter/SendFilter.h"
#include "Speckle/Database/AccountDatabase.h"
#include "Speckle/Database/Content/BIMRecord.h"
#include "Speckle/Interface/Browser/Bridge/BrowserBridge.h"
#include "Speckle/Record/Credentials/Account.h"
#include "Speckle/Serialise/Detached/Storage/DetachedMemoryStore.h"
#include "Speckle/Utility/Exception.h"
#include "Speckle/Database/BIMElementDatabase.h"
#include "Speckle/Environment/Project.h"
#include "Speckle/Record/Element/Element.h"
using namespace speckle::record::element;
using namespace speckle::record::element;
using namespace active::serialise;
using namespace connector::environment;
using namespace connector::interfac::browser::bridge;
using namespace connector::record;
using namespace speckle::database;
@@ -41,8 +44,25 @@ Send::Send() : BridgeMethod{"Send", [&](const SendArgs& args) {
modelCardID: The ID of the model card identifying the objects to send
--------------------------------------------------------------------*/
void Send::run(const String& modelCardID) const {
#ifdef ARCHICAD
// we currently rely on the ModelerAPI instead of the ModelAccessAPI
// we have to open a 3D window to get the Mesh data of the model elements
ACAPI_View_ShowAllIn3D();
#endif
//Get the active project
auto project = connector()->getActiveProject().lock();
if (!project) {
getBridge()->sendEvent("setModelError",
std::make_unique<SendError>(connector()->getLocalString(errorString, noProjectOpenID), modelCardID));
return;
}
auto connectorProject = dynamic_cast<ConnectorProject*>(project.get());
if (!connectorProject)
return;
//Find the specified model card
auto modelCardDatabase = connector()->getModelCardDatabase();
auto modelCardDatabase = connectorProject->getModelCardDatabase();
auto modelCard = modelCardDatabase->getCard(modelCardID);
if (!modelCard) {
getBridge()->sendEvent("setModelError",
@@ -57,21 +77,13 @@ void Send::run(const String& modelCardID) const {
std::make_unique<SendError>(connector()->getLocalString(errorString, accountNotFoundID), modelCardID));
return;
}
//Get the active project
auto project = connector()->getActiveProject().lock();
if (!project) {
getBridge()->sendEvent("setModelError",
std::make_unique<SendError>(connector()->getLocalString(errorString, noProjectOpenID), modelCardID));
return;
}
//Get the selected elements
//Get the selected elements from the modelcard
auto elementDatabase = project->getElementDatabase();
auto selected = elementDatabase->getSelection();
if (selected.empty()) {
getBridge()->sendEvent("setModelError",
std::make_unique<SendError>(connector()->getLocalString(errorString, noSelectedModelItemsID), modelCardID));
return;
ElementIDList selected{};
if (auto senderCard = dynamic_cast<SenderModelCard*>(modelCard.get())) {
selected = senderCard->getFilter().getElementIDs();
}
//Build a collection from the selected elements
auto collection = std::make_unique<ProjectCollection>(project);
for (const auto& link : selected) {
@@ -5,6 +5,7 @@
#include "Connector/Connector.h"
#include "Connector/ConnectorResource.h"
#include "Connector/Database/ModelCardDatabase.h"
#include "Connector/Environment/ConnectorProject.h"
#include "Speckle/Event/Type/ElementEvent.h"
#include "Speckle/Record/Element/Element.h"
#include "Speckle/Database/BIMElementDatabase.h"
@@ -16,6 +17,7 @@
#include "Connector/Record/Model/Filter/SendFilter.h"
using namespace speckle::database;
using namespace connector::environment;
using namespace connector::interfac::browser::bridge;
using namespace speckle::utility;
using namespace speckle::event;
@@ -30,22 +32,6 @@ SendBridge::SendBridge() : BrowserBridge{"sendBinding"} {
addMethod<GetSendFilters>();
addMethod<GetSendSettings>();
addMethod<Send>();
// POC: do we have a better place to attach observer to elements?
#ifdef ARCHICAD
auto project = connector()->getActiveProject().lock();
if (!project) {
// TODO: is this OK? should this throw?
return;
}
auto elementDatabase = project->getElementDatabase();
auto elements = elementDatabase->getElements();
ElementIDList elementIds;
for (const auto& id : elementIds) {
ACAPI_Element_AttachObserver(id);
}
#endif
} //SendBridge::SendBridge
@@ -64,9 +50,13 @@ bool SendBridge::handle(const ElementEvent& event) {
m_changedElements.clear();
break;
case end: {
auto modelCardDatabase = connector()->getModelCardDatabase();
auto project = connector()->getActiveProject().lock();
auto connectorProject = dynamic_cast<ConnectorProject*>(project.get());
if (!connectorProject)
return false;
auto modelCardDatabase = connectorProject->getModelCardDatabase();
auto modelCards = modelCardDatabase->getCards();
// POC: this is probably not efficient, should test, review and refactor it
// POC: this is probably not efficient, should test, review and refactor it
RecordIDList expiredModelCardIds;
for (const auto& modelCard : modelCards) {
if (auto senderCard = dynamic_cast<SenderModelCard*>(modelCard.get())) {
@@ -93,5 +83,5 @@ bool SendBridge::handle(const ElementEvent& event) {
default:
break;
}
return true;
return false;
} //SendBridge::handle
@@ -17,6 +17,8 @@
#include "Speckle/Event/Type/MenuEvent.h"
#include "Speckle/Interface/Browser/JSPortal.h"
#include "Speckle/Event/Type/ProjectEvent.h"
#include <ACAPinc.h>
#include <DGModule.hpp>
#include <DGBrowser.hpp>
@@ -108,7 +110,9 @@ ConnectorPalette::ConnectorPalette() {
return: The subscription list (an empty list will put the subscriber into a suspended state)
--------------------------------------------------------------------*/
ConnectorPalette::Subscription ConnectorPalette::subscription() const {
return { {toggleConnectorPaletteID} };
auto result = ProjectSubscriber::subscription();
result.insert(toggleConnectorPaletteID);
return result;
} //ConnectorPalette::subscription
@@ -130,16 +134,49 @@ bool ConnectorPalette::start() {
return: True if the event should be closed
--------------------------------------------------------------------*/
bool ConnectorPalette::receive(const active::event::Event& event) {
if (BrowserPalette::HasInstance() && BrowserPalette::GetInstance().IsVisible()) {
BrowserPalette::GetInstance().Hide ();
} else {
if (!BrowserPalette::HasInstance())
BrowserPalette::CreateInstance();
BrowserPalette::GetInstance().Show();
if (event == toggleConnectorPaletteID) {
if (BrowserPalette::HasInstance() && BrowserPalette::GetInstance().IsVisible()) {
BrowserPalette::GetInstance().Hide();
}
else {
if (!BrowserPalette::HasInstance())
BrowserPalette::CreateInstance();
BrowserPalette::GetInstance().Show();
}
return true;
}
return true;
return ProjectSubscriber::receive(event);
} //ConnectorPalette::receive
/*--------------------------------------------------------------------
Handle a project event
event: The project event
return: True if the event should be closed
--------------------------------------------------------------------*/
bool ConnectorPalette::handle(const speckle::event::ProjectEvent& event) {
using enum speckle::event::ProjectEvent::Type;
switch (event.getType()) {
case open: {
if (BrowserPalette::HasInstance() && !BrowserPalette::GetInstance().IsVisible()) {
BrowserPalette::GetInstance().Show();
BrowserPalette::GetInstance().EnableItems();
}
} break;
case close: {
if (BrowserPalette::HasInstance() && BrowserPalette::GetInstance().IsVisible()) {
BrowserPalette::GetInstance().Hide();
}
} break;
default:
break;
}
return false;
} //ConnectorPalette::handle
//NB: Following is placeholder from GS example code - will be refactored to better suit our purposes
@@ -228,8 +265,8 @@ void BrowserPalette::Hide() {
void BrowserPalette::InitBrowserControl() {
#ifdef TESTING_MODE
browser->LoadURL("https://deploy-preview-3180--boisterous-douhua-e3cefb.netlify.app/");
//browser->LoadURL("https://boisterous-douhua-e3cefb.netlify.app/test");
browser->LoadURL("https://boisterous-douhua-e3cefb.netlify.app");
#else
browser->LoadURL("https://boisterous-douhua-e3cefb.netlify.app/");
#endif
@@ -282,18 +319,10 @@ GSErrCode __ACENV_CALL BrowserPalette::PaletteControlCallBack(Int32, API_Palette
break;
case APIPalMsg_HidePalette_End:
if(HasInstance() && !GetInstance().IsVisible())
if (HasInstance() && !GetInstance().IsVisible())
{
GetInstance().Show();
break;
case APIPalMsg_DisableItems_Begin:
if(HasInstance() && GetInstance().IsVisible())
GetInstance().DisableItems();
break;
case APIPalMsg_DisableItems_End:
if(HasInstance() && GetInstance().IsVisible())
GetInstance().EnableItems();
}
break;
case APIPalMsg_IsPaletteVisible:
@@ -2,10 +2,11 @@
#define CONNECTOR_CONNECTOR_PALETTE
#include "Active/Event/Subscriber.h"
#include "Speckle/Event/Subscriber/ProjectSubscriber.h"
namespace connector {
class ConnectorPalette : public active::event::Subscriber {
class ConnectorPalette : public speckle::event::ProjectSubscriber {
public:
/*!
Default constructor
@@ -32,6 +33,13 @@ namespace connector {
@return True if the event should be closed
*/
bool receive(const active::event::Event& event) override;
protected:
/*!
Handle the project events
@param event The project event
@return True if the event should be closed
*/
bool handle(const speckle::event::ProjectEvent& event) override;
};
}
@@ -115,12 +115,12 @@ bool ProjectCollection::addElement(const speckle::record::element::Element& elem
return: True if the material proxy was added (false typically means the record already exists)
--------------------------------------------------------------------*/
bool ProjectCollection::addMaterialProxy(const speckle::database::BIMIndex& materialIndex, const speckle::database::BIMRecordID& objectID) {
bool ProjectCollection::addFinishProxy(const speckle::database::BIMIndex& materialIndex, const speckle::database::BIMRecordID& objectID) {
auto iter = m_finishProxies.find(materialIndex);
if (iter == m_finishProxies.end())
iter = m_finishProxies.insert({materialIndex, {}}).first;
return iter->second.insert(objectID).second;
} //ProjectCollection::addMaterialProxy
} //ProjectCollection::addFinishProxy
#ifdef ARCHICAD
@@ -132,12 +132,12 @@ bool ProjectCollection::addMaterialProxy(const speckle::database::BIMIndex& mate
return: True if the material proxy was added (false typically means the record already exists)
--------------------------------------------------------------------*/
bool ProjectCollection::addMaterialProxy(const Finish& finish, const speckle::database::BIMRecordID& objectID) {
bool ProjectCollection::addFinishProxy(const Finish& finish, const speckle::database::BIMRecordID& objectID) {
auto iter = m_finishes->find(finish.getBIMID());
if (iter == m_finishes->end())
iter = m_finishes->insert({finish.getBIMID(), finish}).first;
return addMaterialProxy(speckle::database::BIMIndex{finish.getBIMID()}, objectID);
} //ProjectCollection::addMaterialProxy
return addFinishProxy(speckle::database::BIMIndex{finish.getBIMID()}, objectID);
} //ProjectCollection::addFinishProxy
#endif
@@ -69,14 +69,14 @@ namespace connector::record {
@param objectID The object the material is applied to
@return True if the material proxy was added (false typically means the record already exists)
*/
bool addMaterialProxy(const speckle::database::BIMIndex& materialIndex, const speckle::database::BIMRecordID& objectID) override;
bool addFinishProxy(const speckle::database::BIMIndex& materialIndex, const speckle::database::BIMRecordID& objectID) override;
/*!
Add a ModelerAPI material to the collection (NB: These are not persistent so need to be captured by this method)
@param finish A finish
@param objectID The object the material is applied to
@return True if the material proxy was added (false typically means the record already exists)
*/
bool addMaterialProxy(const speckle::record::attribute::Finish& finish, const speckle::database::BIMRecordID& objectID) override;
bool addFinishProxy(const speckle::record::attribute::Finish& finish, const speckle::database::BIMRecordID& objectID) override;
// MARK: - Serialisation
@@ -100,7 +100,7 @@ namespace connector::record {
///Finish proxies accumulated from meshes generated from the collection elements
FinishProxies m_finishProxies;
class FinishCache;
///Finishes cached from ModelerAPI materials
///Finishes cache
std::unique_ptr<FinishCache> m_finishes;
};
+1
View File
@@ -11,5 +11,6 @@
#include "Speckle.grc.rc2"
#include "ConnectorFix.grc.rc2"
#include "ConnectorImagesFix.grc.rc2"
1 ICON LOADONCALL MOVEABLE IMPURE ACAP.ico
@@ -0,0 +1,10 @@
#ifdef macintosh
'GICN' 32500 "Speckle menu icon" {
"32500Mac"
}
#else
'GICN' 32500 "Speckle menu icon" {
"32500Win"
}
#endif
@@ -0,0 +1,5 @@
<svg width="52" height="52" viewBox="0 0 52 52" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 10L2 4V44L9 50V10Z" stroke="black" stroke-width="3" stroke-linejoin="round"/>
<path d="M43 2L2 4L9 10L50 8L43 2Z" stroke="black" stroke-width="3" stroke-linejoin="round"/>
<path d="M50 8L9 10V50L50 48V8Z" stroke="black" stroke-width="3" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 378 B

@@ -0,0 +1,5 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 8L0 2V42L7 48V8Z" fill="#313BCF"/>
<path d="M41 0L0 2L7 8L48 6L41 0Z" fill="#7BBCFF"/>
<path d="M48 6L7 8V48L48 46V6Z" fill="#047EFB"/>
</svg>

After

Width:  |  Height:  |  Size: 251 B

+1 -1
View File
@@ -1,5 +1,5 @@
'STR#' 32500 "Connector Menu" {
/*[ 1]*/ "Speckle Connector^E3^EL^ES^ED^EE^EI^EW^ET^"
/*[ 1]*/ "Speckle Connector^E3^EL^ES^ED^EE^EI^EW^ET^32500"
}
@@ -33,8 +33,9 @@ namespace speckle::database {
};
///Element database storage declaration
class BIMElementDatabase::Store : public Storage<Element, UnboxedTransport, BIMRecordID, BIMRecordID, BIMRecordID, BIMRecordID> {
using base = Storage<Element, UnboxedTransport, BIMRecordID, BIMRecordID, BIMRecordID, BIMRecordID>;
class BIMElementDatabase::Store : public Storage<Element, UnboxedTransport, BIMRecordID, BIMRecordID,
BIMRecordID, BIMRecordID, ElementStorage::TableType> {
using base = Storage<Element, UnboxedTransport, BIMRecordID, BIMRecordID, BIMRecordID, BIMRecordID, ElementStorage::TableType>;
using base::base;
};
@@ -75,6 +76,48 @@ BIMElementDatabase::BIMElementDatabase() {
BIMElementDatabase::~BIMElementDatabase() {}
/*--------------------------------------------------------------------
Get the available element tables
targetType: An optional filtr for table type to retrieve, e.g. get all sections (nullopt = all table types)
return: A list of available tables
--------------------------------------------------------------------*/
BIMRecordIDList BIMElementDatabase::getTables(std::optional<TableType> targetType) const {
return m_engine->getTables(targetType);
} //BIMElementDatabase::getTables
/*--------------------------------------------------------------------
Get the default dbase table
return: The default dbase table (nullopt if no table is available)
--------------------------------------------------------------------*/
std::optional<BIMRecordID> BIMElementDatabase::getDefaultTable() const {
return m_engine->getDefaultTable();
} //BIMElementDatabase::getDefaultTable
/*--------------------------------------------------------------------
Set the default dbase table
tableID: The new default dbase table
--------------------------------------------------------------------*/
void BIMElementDatabase::setDefaultTable(const BIMRecordID& tableID) const {
m_engine->setDefaultTable(tableID);
} //BIMElementDatabase::setDefaultTable
/*--------------------------------------------------------------------
Bring the view of this database to the front (i.e. so the user sees it)
tableID: The ID of the table to bring to the front
--------------------------------------------------------------------*/
void BIMElementDatabase::bringViewToFront(BIMRecordID tableID) const {
m_engine->bringViewToFront(tableID);
} //BIMElementDatabase::bringViewToFront
/*--------------------------------------------------------------------
Get the current user element selection
@@ -101,10 +144,27 @@ void BIMElementDatabase::clearSelection() const {
} //BIMElementDatabase::clearSelection
/*--------------------------------------------------------------------
Find a filtered list of objects
filter: The object filter (nullptr = find all objects)
tableID: Optional table ID (defaults to the first table)
documentID: Optional document ID (filter for this document only - nullopt = all objects)
return: A list containing IDs of found elements (empty if none found)
--------------------------------------------------------------------*/
BIMRecordIDList BIMElementDatabase::findElements(const Filter& filter, std::optional<BIMRecordID> tableID,
std::optional<BIMRecordID> documentID) const {
return m_engine->findObjects(filter, tableID, documentID);
} //BIMElementDatabase::findElements
/*--------------------------------------------------------------------
Get a specified element
elementID: The ID of the target element
tableID: Optional table ID (defaults to the first table)
documentID: Optional document ID (filter for this document only - nullopt = all objects)
return: The requested element (nullptr on failure)
--------------------------------------------------------------------*/
@@ -117,10 +177,14 @@ Element::Unique BIMElementDatabase::getElement(const BIMRecordID& elementID, std
/*--------------------------------------------------------------------
Get all elements
tableID: Optional table ID (defaults to the first table)
documentID: Optional document ID (filter for this document only - nullopt = all objects)
return: All the elements
--------------------------------------------------------------------*/
Vector<Element> BIMElementDatabase::getElements() const {
return m_store->getObjects();
Vector<Element> BIMElementDatabase::getElements(std::optional<BIMRecordID> tableID,
std::optional<BIMRecordID> documentID) const {
return m_store->getObjects(tableID, documentID);
} //BIMElementDatabase::getElements
@@ -2,6 +2,7 @@
#define CONNECTOR_DATABASE_BIM_ELEMENT_DATABASE
#include "Speckle/Database/Identity/BIMLink.h"
#include "Speckle/Database/Storage/Element/ElementStorage.h"
#include "Speckle/Record/Element/Element.h"
#include "Speckle/Record/Element/Interface/Part.h"
#include "Speckle/Utility/Guid.h"
@@ -19,7 +20,7 @@ namespace speckle::database {
/*!
Database of model elements relating to a specific project
*/
class BIMElementDatabase {
class BIMElementDatabase : public ElementStorage {
public:
// MARK: - Constructors
@@ -36,6 +37,27 @@ namespace speckle::database {
// MARK: - Functions (const)
/*!
Get the available element tables
@param targetType An optional filtr for table type to retrieve, e.g. get all sections (nullopt = all table types)
@return A set of available tables
*/
BIMRecordIDList getTables(std::optional<TableType> targetType) const;
/*!
Get the default dbase table
@return The default dbase table (nullopt if no table is available)
*/
std::optional<BIMRecordID> getDefaultTable() const;
/*!
Set the default dbase table
@param tableID The new default dbase table
*/
void setDefaultTable(const BIMRecordID& tableID) const;
/*!
Bring the view of this database to the front (i.e. so the user sees it)
@param tableID The ID of the table to bring to the front
*/
void bringViewToFront(BIMRecordID tableID) const;
/*!
Get the current user element selection
@return A list of selected element IDs
@@ -49,6 +71,15 @@ namespace speckle::database {
Clear the element selection
*/
void clearSelection() const;
/*!
Find a filtered list of objects
@param filter The object filter (nullptr = find all objects)
@param tableID Optional table ID (defaults to the first table)
@param documentID Optional document ID (filter for this document only - nullopt = all objects)
@return A list containing IDs of found elements (empty if none found)
*/
BIMRecordIDList findElements(const Filter& filter = nullptr, std::optional<BIMRecordID> tableID = std::nullopt,
std::optional<BIMRecordID> documentID = std::nullopt) const;
/*!
Get a specified element
@param elementID The ID of the target element
@@ -66,9 +97,12 @@ namespace speckle::database {
std::unique_ptr<record::element::Element> getElement(const BIMLink& link) const { return getElement(link, link.tableID, link.docID); }
/*!
Get all model elements
@param tableID Optional table ID (defaults to the first table)
@param documentID Optional document ID (filter for this document only - nullopt = all objects)
@return All the elements
*/
active::container::Vector<record::element::Element> getElements() const;
active::container::Vector<record::element::Element> getElements(std::optional<BIMRecordID> tableID = std::nullopt,
std::optional<BIMRecordID> documentID = std::nullopt) const;
/*!
Get memo memo (supplementary) data for a specified element
@param elementID The of the source element
@@ -62,7 +62,7 @@ namespace speckle::database {
Get a link to the BIM record
@return The BIM record link
*/
BIMLink getBIMLink() const { return BIMLink{ BIMLink::base {m_applicationID, m_applicationTableID} }; }
virtual BIMLink getBIMLink() const { return BIMLink{BIMLink::base{m_applicationID, m_applicationTableID}}; }
/*!
Get the record unit type
@return The record unit type (nullopt if the record has no applicable unit type)
@@ -34,6 +34,7 @@ namespace speckle::database {
using Attribute = record::attribute::Attribute;
using Filter = base::Filter;
using Outline = base::Outline;
using ObjIDList = base::ObjIDList;
// MARK: - Constructors
@@ -51,6 +52,15 @@ namespace speckle::database {
// MARK: - Functions (const)
/*!
Find a filtered list of objects
@param filter The object filter (nullptr = find all objects)
@param tableID Optional table ID (defaults to the first table)
@param documentID Optional document ID (filter for this document only - nullopt = all objects)
@return A list containing IDs of found elements (empty if none found)
*/
virtual ObjIDList findObjects(const Filter& filter = nullptr, std::optional<BIMRecordID> tableID = std::nullopt,
std::optional<BIMRecordID> documentID = std::nullopt) const override { return {}; } //Implement when required
/*!
Get an object by ID
@param objID The object ID
@@ -64,7 +74,7 @@ namespace speckle::database {
@param objID The object ID
@param tableID Optional table ID (defaults to the floor plan)
@param documentID Optional document ID (when the object is bound to a specific document)
@return: The requested wrapped cargo (nullptr on failure)
@return The requested wrapped cargo (nullptr on failure)
*/
active::serialise::Cargo::Unique getObjectCargo(const BIMRecordID& objID, std::optional<BIMRecordID> tableID = std::nullopt, std::optional<BIMRecordID> documentID = std::nullopt) const override;
/*!
@@ -16,6 +16,12 @@
#include "Speckle/Record/Element/Beam.h"
#include "Speckle/Record/Element/BeamSegment.h"
#include "Speckle/Record/Element/Memo.h"
#include "Speckle/Record/Element/MeshElem.h"
#include "Speckle/Record/Element/Morph.h"
#include "Speckle/Record/Element/Roof.h"
#include "Speckle/Record/Element/Shell.h"
#include "Speckle/Record/Element/Slab.h"
#include "Speckle/Record/Element/Wall.h"
#include "Speckle/Utility/Guid.h"
#include "Speckle/Utility/String.h"
@@ -35,14 +41,24 @@ using enum ArchicadDBaseCore::Status;
namespace {
//ID for the floor plan view
static const Guid primary2DViewID{String{"ddad27c0-c17b-4ad3-b76b-53d1e176d5ef"}};
//ID for the 3D view
static const Guid primary3DViewID{String{"ec368939-fb7d-4d8c-bc88-6d29806d9212"}};
/*!
Get information about a specified Archicad table
@param tableID The ID of the target table
@return The requested table info (nullopt on failure)
*/
std::optional<API_DatabaseInfo> getTableInfo(const BIMRecordID& tableID) {
API_DatabaseInfo dbaseInfo;
dbaseInfo.databaseUnId.elemSetId = tableID;
API_DatabaseInfo dbaseInfo{};
if (tableID == primary2DViewID)
dbaseInfo.typeID = APIWind_FloorPlanID;
else if (tableID == primary3DViewID)
dbaseInfo.typeID = APIWind_3DModelID;
else
dbaseInfo.databaseUnId.elemSetId = tableID;
if (auto err = ACAPI_Window_GetDatabaseInfo(&dbaseInfo); err == NoError)
return dbaseInfo;
return std::nullopt;
@@ -56,7 +72,7 @@ namespace {
*/
bool setActiveTable(const BIMRecordID& tableID) {
if (!tableID)
return false; //Null guid doens't point to anything
return false; //Null guid doesn't point to anything
if (auto activeTable = ArchicadElementDBaseEngine::getActiveTable(); activeTable && *activeTable == tableID)
return true;
auto dbaseInfo = getTableInfo(tableID);
@@ -82,6 +98,22 @@ namespace {
return std::make_unique<Beam>(elementData, tableID);
case API_BeamSegmentID:
return std::make_unique<BeamSegment>(elementData, tableID);
case API_MeshID:
return std::make_unique<Mesh>(elementData, tableID);
case API_MorphID:
return std::make_unique<Morph>(elementData, tableID);
case API_RoofID:
return std::make_unique<Roof>(elementData, tableID);
case API_ShellID:
return std::make_unique<Shell>(elementData, tableID);
case API_SlabID:
return std::make_unique<Slab>(elementData, tableID);
case API_WallID:
return std::make_unique<Wall>(elementData, tableID);
case API_ObjectID:
// POC: change this case once we are ready to convert Grid Elements
if (elementData.header.type.variationID == APIVarId_GridElement)
return nullptr;
default:
return std::make_unique<GenericModelElement>(elementData, tableID);
}
@@ -96,12 +128,34 @@ namespace {
std::optional<BIMRecordID> ArchicadElementDBaseEngine::getActiveTable() {
API_WindowInfo dbaseInfo;
active::utility::Memory::erase(dbaseInfo);
if (auto err = ACAPI_Database_GetCurrentDatabase(&dbaseInfo); err == NoError)
if (auto err = ACAPI_Database_GetCurrentDatabase(&dbaseInfo); err == NoError) {
if (dbaseInfo.typeID == APIWind_FloorPlanID)
return primary2DViewID;
else if (dbaseInfo.typeID == APIWind_3DModelID)
return primary3DViewID;
return dbaseInfo.databaseUnId.elemSetId;
}
return std::nullopt;
} //ArchicadElementDBaseEngine::getActiveTable
/*--------------------------------------------------------------------
Bring the view of this database to the front (i.e. so the user sees it)
tableID: The ID of the table to bring to the front
--------------------------------------------------------------------*/
void ArchicadElementDBaseEngine::bringViewToFront(BIMRecordID tableID) const {
auto dbaseInfo = getTableInfo(tableID);
if (!dbaseInfo)
return;
API_WindowInfo windowInfo{};
windowInfo.typeID = dbaseInfo->typeID;
if ((windowInfo.typeID != APIWind_FloorPlanID) && (windowInfo.typeID != APIWind_3DModelID))
windowInfo.databaseUnId = dbaseInfo->databaseUnId;
ACAPI_Window_ChangeWindow(&windowInfo);
} //ArchicadElementDBaseEngine::bringViewToFront
/*--------------------------------------------------------------------
Get the current user element selection
@@ -144,6 +198,73 @@ void ArchicadElementDBaseEngine::clearSelection() const {
} //ArchicadElementDBaseEngine::clearSelection
/*--------------------------------------------------------------------
Get the available dbase tables
targetType: An optional filtr for table type/group to retrieve
return: A list of available tables
--------------------------------------------------------------------*/
ArchicadElementDBaseEngine::TableIDList ArchicadElementDBaseEngine::getTables(std::optional<TableType> targetType) const {
using enum ElementStorage::TableType;
TableIDList result;
if (!targetType || (targetType == primary2D))
result.insert(primary2DViewID);
if (!targetType || (targetType == primary3D))
result.insert(primary3DViewID);
return result;
} //ArchicadElementDBaseEngine::getTables
/*--------------------------------------------------------------------
Get the default dbase table
return: The default dbase table (nullopt if no table is available)
--------------------------------------------------------------------*/
std::optional<BIMRecordID> ArchicadElementDBaseEngine::getDefaultTable() const {
return ArchicadElementDBaseEngine::getActiveTable();
} //ArchicadElementDBaseEngine::getDefaultTable
/*--------------------------------------------------------------------
Set the default dbase table
tableID: The new default dbase table
--------------------------------------------------------------------*/
void ArchicadElementDBaseEngine::setDefaultTable(const BIMRecordID& tableID) const {
setActiveTable(tableID);
} //ArchicadElementDBaseEngine::setDefaultTable
/*--------------------------------------------------------------------
Find a filtered list of objects
filter: The object filter (nullptr = find all objects)
tableID: Optional table ID (defaults to the first table)
documentID: Optional document ID (filter for this document only - nullopt = all objects)
return: A list containing IDs of found elements (empty if none found)
--------------------------------------------------------------------*/
BIMRecordIDList ArchicadElementDBaseEngine::findObjects(const Filter& filter, std::optional<BIMRecordID> tableID,
std::optional<BIMRecordID> documentID) const {
//Switch to the target table (when specified). Otherwise the currently active table will be used
if (tableID)
setActiveTable(*tableID);
//First check for no filter (in which case we return all objects)
if (filter == nullptr) {
GS::Array<API_Guid> found;
if ((ACAPI_Element_GetElemList({}, &found) != NoError) || found.IsEmpty())
return {};
BIMRecordIDList result;
for (const auto& item : found)
result.insert(item);
return result;
}
//Implement other filtering as required - ideally identify characteristics supported by API, e.g. filter by type/renovation etc
return {};
} //ArchicadElementDBaseEngine::findObjects
/*--------------------------------------------------------------------
Get an object by index
@@ -211,7 +332,19 @@ active::container::Vector<Element> ArchicadElementDBaseEngine::getObjects(std::o
std::optional<BIMRecordID> documentID) const {
if (tableID)
setActiveTable(*tableID);
return {}; //TODO: Implement
else {
//Use the active table if none is specified
tableID = getActiveTable();
if (!tableID)
return {};
}
//Retrieve the element objects to build the result
active::container::Vector<Element> result;
auto objectIDs = findObjects();
for (const auto& ID : objectIDs)
if (auto element = getObject(ID, tableID); element)
result.emplace_back(std::move(element));
return result;
} //ArchicadElementDBaseEngine::getObjects
@@ -4,6 +4,7 @@
#include "Active/Database/Storage/DBaseEngine.h"
#include "Active/Serialise/UnboxedTransport.h"
#include "Speckle/Database/Storage/ArchicadDBase/ArchicadDBaseCore.h"
#include "Speckle/Database/Storage/Element/ElementStorage.h"
#include "Speckle/Database/Identity/BIMLink.h"
#include "Speckle/Record/Element/Element.h"
#include "Speckle/Utility/Guid.h"
@@ -17,16 +18,17 @@ 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> {
class ArchicadElementDBaseEngine : public ArchicadDBaseCore, public ElementStorage,
public active::database::DBaseEngine<record::element::Element, BIMRecordID, BIMRecordID, BIMRecordID, ElementStorage::TableType> {
public:
// MARK: - Types
using base = active::database::DBaseEngine<record::element::Element, BIMRecordID, BIMRecordID, BIMRecordID>;
using Element = record::element::Element;
using Filter = base::Filter;
using Filter = ElementStorage::Filter;
using Outline = base::Outline;
using ObjIDList = base::ObjIDList;
// MARK: - Constants
@@ -53,6 +55,11 @@ namespace speckle::database {
// MARK: - Functions (const)
/*!
Bring the view of this database to the front (i.e. so the user sees it)
@param tableID The ID of the table to bring to the front
*/
void bringViewToFront(BIMRecordID tableID) const;
/*!
Get the current user element selection
@return A list of selected element IDs
@@ -66,6 +73,31 @@ namespace speckle::database {
Clear the element selection
*/
void clearSelection() const;
/*!
Get the available dbase tables
@param targetType An optional filtr for table type/group to retrieve
@return A list of available tables
*/
TableIDList getTables(std::optional<TableType> targetType) const override;
/*!
Get the default dbase table
@return The default dbase table (nullopt if no table is available)
*/
std::optional<BIMRecordID> getDefaultTable() const;
/*!
Set the default dbase table
@param tableID The new default dbase table
*/
void setDefaultTable(const BIMRecordID& tableID) const;
/*!
Find a filtered list of objects
@param filter The object filter (nullptr = find all objects)
@param tableID Optional table ID (defaults to the first table)
@param documentID Optional document ID (filter for this document only - nullopt = all objects)
@return A list containing IDs of found elements (empty if none found)
*/
virtual BIMRecordIDList findObjects(const Filter& filter = nullptr, std::optional<BIMRecordID> tableID = std::nullopt,
std::optional<BIMRecordID> documentID = std::nullopt) const override;
/*!
Get an object by index
@param objID The object ID
@@ -79,7 +111,7 @@ namespace speckle::database {
@param objID The object ID
@param tableID Optional table ID (defaults to the floor plan)
@param documentID Optional document ID (when the object is bound to a specific document)
@return: The requested wrapped cargo (nullptr on failure)
@return The requested wrapped cargo (nullptr on failure)
*/
active::serialise::Cargo::Unique getObjectCargo(const BIMRecordID& objID, std::optional<BIMRecordID> tableID = std::nullopt, std::optional<BIMRecordID> documentID = std::nullopt) const override;
/*!
@@ -29,6 +29,7 @@ namespace speckle::database {
using Group = record::property::Group;
using Filter = base::Filter;
using Outline = base::Outline;
using ObjIDList = base::ObjIDList;
// MARK: - Constructors
@@ -46,6 +47,15 @@ namespace speckle::database {
// MARK: - Functions (const)
/*!
Find a filtered list of objects
@param filter The object filter (nullptr = find all objects)
@param tableID Optional table ID (defaults to the first table)
@param documentID Optional document ID (filter for this document only - nullopt = all objects)
@return A list containing IDs of found elements (empty if none found)
*/
virtual ObjIDList findObjects(const Filter& filter = nullptr, std::optional<BIMRecordID> tableID = std::nullopt,
std::optional<BIMRecordID> documentID = std::nullopt) const override { return {}; } //Implement when required
/*!
Get an object by ID
@param objID The object ID
@@ -59,7 +69,7 @@ namespace speckle::database {
@param objID The object ID
@param tableID Optional table ID (default selected based on record type)
@param documentID Optional document ID (when the object is bound to a specific document)
@return: The requested wrapped cargo (nullptr on failure)
@return The requested wrapped cargo (nullptr on failure)
*/
active::serialise::Cargo::Unique getObjectCargo(const BIMRecordID& objID, std::optional<BIMRecordID> tableID = std::nullopt, std::optional<BIMRecordID> documentID = std::nullopt) const override;
/*!
@@ -30,6 +30,7 @@ namespace speckle::database {
using Template = record::property::Template;
using Filter = base::Filter;
using Outline = base::Outline;
using ObjIDList = base::ObjIDList;
// MARK: - Constructors
@@ -47,6 +48,15 @@ namespace speckle::database {
// MARK: - Functions (const)
/*!
Find a filtered list of objects
@param filter The object filter (nullptr = find all objects)
@param tableID Optional table ID (defaults to the first table)
@param documentID Optional document ID (filter for this document only - nullopt = all objects)
@return A list containing IDs of found elements (empty if none found)
*/
virtual ObjIDList findObjects(const Filter& filter = nullptr, std::optional<BIMRecordID> tableID = std::nullopt,
std::optional<BIMRecordID> documentID = std::nullopt) const override { return {}; } //Implement when required
/*!
Find all property templates linked to specified classifications
@param classifications The classifications
@@ -66,7 +76,7 @@ namespace speckle::database {
@param objID The object ID
@param tableID Optional table ID (default selected based on record type)
@param documentID Optional document ID (when the object is bound to a specific document)
@return: The requested wrapped cargo (nullptr on failure)
@return The requested wrapped cargo (nullptr on failure)
*/
active::serialise::Cargo::Unique getObjectCargo(const BIMRecordID& objID, std::optional<BIMRecordID> tableID = std::nullopt, std::optional<BIMRecordID> documentID = std::nullopt) const override;
/*!
@@ -46,6 +46,7 @@ namespace speckle::database {
using base = active::database::DBaseEngine<Obj, ObjID, RecordID, RecordID>;
using Filter = base::Filter;
using Outline = base::Outline;
using ObjIDList = base::ObjIDList;
using Cache = active::database::RecordCache<Obj, ObjWrapper, ObjID, RecordID, RecordID>;
// MARK: - Constructors
@@ -59,6 +60,15 @@ namespace speckle::database {
// MARK: - Functions (const)
/*!
Find a filtered list of objects
@param filter The object filter (nullptr = find all objects)
@param tableID Optional table ID (defaults to the first table)
@param documentID Optional document ID (filter for this document only - nullopt = all objects)
@return A list containing IDs of found elements (empty if none found)
*/
virtual ObjIDList findObjects(const Filter& filter = nullptr, std::optional<RecordID> tableID = std::nullopt,
std::optional<RecordID> documentID = std::nullopt) const override { return {}; } //Implement when required
/*!
Get an object by index
@param ID The object ID
@@ -72,7 +82,7 @@ namespace speckle::database {
@param ID The object ID
@param tableID Optional table ID (defaults to the first table)
@param documentID Optional document ID (when the object is bound to a specific document)
@return: The requested wrapped cargo (nullptr on failure)
@return The requested wrapped cargo (nullptr on failure)
*/
active::serialise::Cargo::Unique getObjectCargo(const ObjID& objID, std::optional<RecordID> tableID = std::nullopt, std::optional<RecordID> documentID = std::nullopt) const override;
/*!
@@ -171,8 +181,10 @@ namespace speckle::database {
//Read the data stored in the document
auto storedData = readStore();
m_cache = std::make_unique<Cache>();
if (!storedData)
if (!storedData) {
m_cache->setID(speckle::utility::Guid{true}.operator speckle::utility::String()); //Needs an ID - substitute for the Speckle 'document ID'
return m_cache.get(); //Return an empty container if there's no data
}
//Import the document data into the record cache
if constexpr (std::is_same_v<ObjWrapper, Obj>)
Transport().receive(std::forward<active::serialise::Cargo&&>(*m_cache), active::serialise::Identity{}, storedData);
@@ -0,0 +1,29 @@
#ifndef SPECKLE_DATABASE_ELEMENT_STORAGE
#define SPECKLE_DATABASE_ELEMENT_STORAGE
#include "Speckle/Record/Element/Element.h"
namespace speckle::database {
/*!
Fundamental concepts for element storage
*/
class ElementStorage {
public:
// MARK: - Types
///Element storage table types
enum class TableType {
primary2D,
primary3D,
section,
elevation,
};
///Element filter
using Filter = std::function<bool(const record::element::Element&)>;
};
}
#endif //SPECKLE_DATABASE_ELEMENT_STORAGE
+11
View File
@@ -2,6 +2,7 @@
#include "Speckle/Environment/Project.h"
#include "Speckle/Event/Type/ProjectEvent.h"
#include "Speckle/Event/Subscriber/ProjectSubscriber.h"
#include <limits>
@@ -18,6 +19,14 @@ namespace {
//An object representing the active addon
Addon* m_addonInstance = nullptr;
///An instance of this class is used to force project notifications to be issued from the moment the add-on is launched
class DummyProjectSubscriber : public ProjectSubscriber {
public:
bool start() override { return ProjectSubscriber::start(); }
bool handle(const ProjectEvent& event) override { return false; }
};
}
/*--------------------------------------------------------------------
@@ -121,6 +130,8 @@ bool Addon::attach() {
return: True if the participant is able to continue
--------------------------------------------------------------------*/
bool Addon::start() {
//Force project notifications to be published
DummyProjectSubscriber().start();
//Add add-on functionality as required
return App::start();
} //Addon::start
+1 -1
View File
@@ -40,7 +40,7 @@ namespace speckle::environment {
Get the active project
@return The active project (nullptr = no open project)
*/
std::weak_ptr<Project> getActiveProject() const;
virtual std::weak_ptr<Project> getActiveProject() const;
/*!
Get the session index
@return The session index (non-recursive entries into the add-on)
@@ -27,6 +27,22 @@ void Platform::writeToConsole(const active::utility::String& message) {
} //Platform::writeToConsole
/*--------------------------------------------------------------------
Open a URL
URL: The URL to open
--------------------------------------------------------------------*/
void Platform::openURL(const active::utility::String& URL) {
#if WINDOWS
std::system((String{"start "} + URL).data());
#elif __APPLE__
std::system((String{"open "} + URL).data());
#elif __linux__
std::system((String{"xdg-open"} + url).data());
#endif
} //Platform::openURL
/*--------------------------------------------------------------------
Get an object representing the parent process/application
@@ -18,6 +18,11 @@ namespace speckle::environment {
@param message The message to write
*/
void writeToConsole(const active::utility::String& message);
/*!
Open a URL
@param URL The URL to open
*/
void openURL(const active::utility::String& URL);
};
+1 -1
View File
@@ -48,7 +48,7 @@ namespace speckle::environment {
/*!
Destructor
*/
~Project();
virtual ~Project();
// MARK: - Functions (const)
@@ -31,7 +31,8 @@ namespace {
switch (elemType->notifID)
{
case APINotifyElement_New: {
ACAPI_Element_AttachObserver(elemType->elemHead.guid);
// POC: Put this back once we decide to use Object Tracking
// ACAPI_Element_AttachObserver(elemType->elemHead.guid);
addon()->publishExternal(ElementEvent{newElem, ElementID{elemType->elemHead.guid}});
} break;
case APINotifyElement_Change: {
+3 -2
View File
@@ -1,6 +1,7 @@
#include "Speckle/Primitive/Mesh/Mesh.h"
#include "Active/Serialise/Item/Wrapper/ValueWrap.h"
#include "Active/Serialise/Item/Wrapper/FastDoubleWrap.h"
#include "Active/Serialise/Package/Wrapper/PackageWrap.h"
#include "Active/Serialise/Package/Wrapper/ContainerWrap.h"
#include "Active/Serialise/Inventory/Identity.h"
@@ -78,7 +79,7 @@ Cargo::Unique Mesh::getCargo(const Inventory::Item& item) const {
using namespace active::serialise;
switch (item.index) {
case vertexID:
return std::make_unique<ContainerWrap<std::vector<double>>>(m_vertices);
return std::make_unique<ContainerWrap<std::vector<double>, FastDoubleWrap>>(m_vertices);
case faceID:
return std::make_unique<ContainerWrap<std::vector<int>>>(m_faces);
case colorID:
@@ -98,6 +99,6 @@ void Mesh::useManagement(Management* management) const {
//NB: This object only exists to populate the finish collection - it doesn't carry any serialisable content
if (management != nullptr) {
if (auto collector = management->get<FinishCollector>(); collector != nullptr)
collector->addMaterialProxy(m_finish, getBIMID());
collector->addFinishProxy(m_finish, getBIMID());
}
} //Mesh::useManagement
@@ -0,0 +1,196 @@
#include "Speckle/Record/Attribute/Material.h"
#include "Active/Serialise/Item/Wrapper/ValueWrap.h"
#include "Active/Serialise/Management/Management.h"
#include "Active/Serialise/CargoHold.h"
#include "Active/Utility/BufferOut.h"
#include "Speckle/Serialise/Collection/FinishCollector.h"
#include "Speckle/Serialise/Types/ArchicadRGB.h"
#include "Speckle/Utility/Guid.h"
using namespace active::serialise;
using namespace speckle::database;
using namespace speckle::record::attribute;
using namespace speckle::serialise;
using namespace speckle::utility;
#include <array>
#include <memory>
namespace speckle::record::attribute {
///Internal representation of a rendered finish on a 3D body, i.e. the surface colour/texture etc.
class Material::Data {
public:
#ifdef ARCHICAD
/*!
Constructor from Archicad material
@param attr An Archicad attribute
*/
Data(const API_Attribute& attr) : root{attr.buildingMaterial} {
}
///Archicad representation of a building material
API_BuildingMaterialType root;
#endif
};
}
namespace {
///Serialisation fields
enum FieldIndex {
thermConductID,
//TODO: Add other fields as required
};
///Serialisation field IDs
static std::array fieldID = {
Identity{"thermalConductivity"},
//TODO: Add other fields as required
};
}
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
Material::Material() {
} //Material::Material
/*--------------------------------------------------------------------
Constructor
ID: The attribute ID
--------------------------------------------------------------------*/
Material::Material(const database::BIMRecordID& ID) : base{ID, Material::table} {
} //Material::Material
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Constructor
attrData: Archicad attribute data
tableID: The ID of the parent table
--------------------------------------------------------------------*/
Material::Material(const API_Attribute& attrData, const BIMRecordID& tableID) : base{attrData.header.guid, Material::table} {
m_data = std::make_unique<Data>(attrData);
setUnit(std::nullopt); //Finishes have no unit
}
#endif
/*--------------------------------------------------------------------
Copy constructor
source: The object to copy
--------------------------------------------------------------------*/
Material::Material(const Material& source) : base{source} {
m_data = source.m_data ? std::make_unique<Data>(*source.m_data) : nullptr;
} //Material::Material
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
Material::~Material() {}
/*--------------------------------------------------------------------
Assignment operator
source: The object to assign
return: A reference to this
--------------------------------------------------------------------*/
Material& Material::operator=(const Material& source) {
if (this != &source) {
base::operator=(source);
m_data = source.m_data ? std::make_unique<Data>(*source.m_data) : nullptr;
}
return *this;
} //Material::operator=
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Get the (immutable) API attribute header data
return: The attribute header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
const API_Attr_Head& Material::getHead() const {
confirmData();
return m_data->root.head;
} //Material::getHead
/*--------------------------------------------------------------------
Get the (mutable) API attribute header data
return: The attribute header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
API_Attr_Head& Material::getHead() {
confirmData();
return m_data->root.head;
} //Material::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 Material::fillInventory(Inventory& inventory) const {
using enum Entry::Type;
inventory.merge(Inventory{
{
{ fieldID[thermConductID], thermConductID, element },
},
}.withType(&typeid(Material)));
return base::fillInventory(inventory);
} //Material::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique Material::getCargo(const Inventory::Item& item) const {
if (item.ownerType != &typeid(Material))
return base::getCargo(item);
confirmData();
using namespace active::serialise;
switch (item.index) {
case thermConductID:
return std::make_unique<DoubleWrap>(m_data->root.thermalConductivity);
default:
return nullptr; //Requested an unknown index
}
} //Material::getCargo
/*--------------------------------------------------------------------
Set to the default package content
--------------------------------------------------------------------*/
void Material::setDefault() {
m_data->root = {};
} //Material::setDefault
/*--------------------------------------------------------------------
Confirm the internal data, either loading from the BIM application or setting a default
--------------------------------------------------------------------*/
void Material::confirmData() const {
if (m_data)
return;
m_data = std::make_unique<Data>(getData());
} //Material::confirmData
@@ -0,0 +1,143 @@
#ifndef SPECKLE_RECORD_ATTRIBUTE_MATERIAL
#define SPECKLE_RECORD_ATTRIBUTE_MATERIAL
#include "Speckle/Record/Attribute/Attribute.h"
#ifdef ARCHICAD
namespace ModelerAPI {
class Material;
}
#endif
namespace speckle::record::attribute {
/*!
Class to represent the construction material of a building element, e.g. concrete, timber, glass, stone etc
Note the difference with a Finish (which is only applied to the surface).
In Archicad this attribute is represented by `API_BuildingMaterialType`
*/
class Material : public Attribute {
public:
// MARK: - Types
using base = Attribute;
///Unique pointer
using Unique = std::unique_ptr<Material>;
///Shared pointer
using Shared = std::shared_ptr<Material>;
///Optional
using Option = std::optional<Material>;
// MARK: - Constants
#ifdef ARCHICAD
///The finishes table identifier
static constexpr active::utility::Guid table{active::utility::Guid::fromInt(API_BuildingMaterialID)};
#endif
// MARK: - Constructors
using base::base;
/*!
Default constructor
*/
Material();
/*!
Constructor
@param ID The attribute ID
*/
Material(const database::BIMRecordID& ID);
#ifdef ARCHICAD
/*!
Constructor
@param attrData Archicad attribute data
@param tableID The ID of the parent table
*/
Material(const API_Attribute& attrData, const database::BIMRecordID& tableID);
#endif
/*!
Copy constructor
@param source The object to copy
*/
Material(const Material& source);
/*!
Destructor
*/
~Material();
/*!
Object cloning
@return A clone of this object
*/
Material* clonePtr() const override { return new Material{*this}; }
// MARK: - Operators
/*!
Assignment operator
@param source The object to assign
@return A reference to this
*/
Material& operator=(const Material& source);
// 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.Other.Material"; }
#ifdef ARCHICAD
/*!
Get the (immutable) API attribute header data
@return The attribute header data (only use this data for low-level operations - for normal code, call getters/setters)
*/
const API_Attr_Head& getHead() const override;
#endif
// MARK: - Functions (mutating)
#ifdef ARCHICAD
/*!
Get the (mutable) API attribute header data
@return The attribute header data (only use this data for low-level operations - for normal code, call getters/setters)
*/
API_Attr_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:
/*!
Confirm the internal data, either loading from the BIM application or setting a default
*/
void confirmData() const;
class Data;
///The attribute data - mutable to support lazy loading
mutable std::unique_ptr<Data> m_data;
};
}
#endif //SPECKLE_RECORD_ATTRIBUTE_MATERIAL
+4 -12
View File
@@ -1,15 +1,8 @@
#include "Speckle/Record/Element/Beam.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;
@@ -24,12 +17,11 @@ namespace speckle::record::element {
friend class Beam;
#ifdef ARCHICAD
Data(const API_Element& elem) : root{ std::make_unique<API_BeamType>(elem.beam) } {}
Data(const Data& source) : root{ std::make_unique<API_BeamType>(*source.root) } {}
Data(const API_Element& elem) : root{elem.beam} {}
#endif
private:
std::unique_ptr<API_BeamType> root;
API_BeamType root;
};
}
@@ -91,7 +83,7 @@ Beam::~Beam() {}
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
const API_Elem_Head& Beam::getHead() const {
return m_data->root->head;
return m_data->root.head;
} //Beam::getHead
/*--------------------------------------------------------------------
@@ -100,7 +92,7 @@ const API_Elem_Head& Beam::getHead() const {
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
API_Elem_Head& Beam::getHead() {
return m_data->root->head;
return m_data->root.head;
} //Beam::getHead
@@ -1,21 +1,17 @@
#include "Speckle/Record/Element/BeamSegment.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"
#include "Speckle/Record/Element/Quants/Surveyor.h"
#include "Speckle/Record/Element/Setting/Conversion.h"
#include "Speckle/Utility/BIMMemory.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::record::element::quants;
using namespace speckle::utility;
#include <array>
@@ -28,11 +24,10 @@ namespace speckle::record::element {
friend class BeamSegment;
#ifdef ARCHICAD
Data(const API_BeamSegmentType& seg) : root{ std::make_unique<API_BeamSegmentType>(seg) } {}
Data(const Data& source) : root{ std::make_unique<API_BeamSegmentType>(*source.root) } {}
Data(const API_BeamSegmentType& seg) : root{seg} {}
private:
std::unique_ptr<API_BeamSegmentType> root;
API_BeamSegmentType root;
#endif
};
@@ -102,6 +97,46 @@ BeamSegment::BeamSegment(BeamSegment&& source) noexcept : base{source} {
BeamSegment::~BeamSegment() {}
/*--------------------------------------------------------------------
Get the composition of materials in the element
return: The material composition (element with ordered material composition should override)
--------------------------------------------------------------------*/
ModelElement::Composition BeamSegment::getComposition() const {
#ifdef ARCHICAD
return convert(m_data->root.assemblySegmentData.modelElemStructureType);
#endif
} //BeamSegment::getComposition
/*--------------------------------------------------------------------
Get the element material (applicable to elements with a single, homogenous material)
return: The element material (nullopt if not applicable to the element)
--------------------------------------------------------------------*/
std::optional<Material> BeamSegment::getMaterial() const {
#ifdef ARCHICAD
return Material{Guid{Guid::fromInt(m_data->root.assemblySegmentData.buildingMaterial.GenerateHashValue())}};
#endif
} //BeamSegment::getMaterial
/*--------------------------------------------------------------------
Get a spatial measurement from this element (area/volume, as used for material quantities)
return: The element measurement (empty if unavailable)
--------------------------------------------------------------------*/
ModelElement::SpatialMeasure BeamSegment::getSpatialMeasure() const {
#ifdef ARCHICAD
Surveyor surveyor;
BIMMemory::setMask(&surveyor.elementMask().beamSegment.rightSurface);
BIMMemory::setMask(&surveyor.elementMask().beamSegment.volume);
surveyor.measure(getBIMLink());
return SpatialMeasure{surveyor.quantity().beamSegment.rightSurface, surveyor.quantity().beamSegment.volume};
#endif
} //BeamSegment::getSpatialMeasure
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Get the (immutable) API element header data
@@ -109,7 +144,7 @@ BeamSegment::~BeamSegment() {}
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
const API_Elem_Head& BeamSegment::getHead() const {
return m_data->root->head;
return m_data->root.head;
} //BeamSegment::getHead
@@ -119,7 +154,7 @@ const API_Elem_Head& BeamSegment::getHead() const {
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
API_Elem_Head& BeamSegment::getHead() {
return m_data->root->head;
return m_data->root.head;
} //BeamSegment::getHead
#endif
@@ -64,6 +64,21 @@ namespace speckle::record::element {
// MARK: - Functions (const)
/*!
Get the composition of materials in the element
@return The material composition (element with ordered material composition should override)
*/
Composition getComposition() const override;
/*!
Get the element material (applicable to elements with a single, homogenous material)
@return The element material (nullopt if not applicable to the element)
*/
std::optional<record::attribute::Material> getMaterial() const override;
/*!
Get a spatial measurement from this element (area/volume, as used for material quantities)
@return The element measurement (empty if unavailable)
*/
SpatialMeasure getSpatialMeasure() const override;
#ifdef ARCHICAD
/*!
Get the (immutable) API element header data
+4 -12
View File
@@ -1,15 +1,8 @@
#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;
@@ -24,12 +17,11 @@ namespace speckle::record::element {
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) } {}
Data(const API_Element& elem) : root{elem.column} {}
#endif
private:
std::unique_ptr<API_ColumnType> root;
API_ColumnType root;
};
}
@@ -91,7 +83,7 @@ Column::~Column() {}
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;
return m_data->root.head;
} //Column::getHead
/*--------------------------------------------------------------------
@@ -100,7 +92,7 @@ const API_Elem_Head& Column::getHead() const {
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;
return m_data->root.head;
} //Column::getHead
@@ -1,21 +1,17 @@
#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"
#include "Speckle/Record/Element/Quants/Surveyor.h"
#include "Speckle/Record/Element/Setting/Conversion.h"
#include "Speckle/Utility/BIMMemory.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::record::element::quants;
using namespace speckle::utility;
#include <array>
@@ -28,11 +24,10 @@ namespace speckle::record::element {
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) } {}
Data(const API_ColumnSegmentType& seg) : root{seg} {}
private:
std::unique_ptr<API_ColumnSegmentType> root;
API_ColumnSegmentType root;
#endif
};
@@ -102,6 +97,46 @@ ColumnSegment::ColumnSegment(ColumnSegment&& source) noexcept : base{source} {
ColumnSegment::~ColumnSegment() {}
/*--------------------------------------------------------------------
Get the composition of materials in the element
return: The material composition (element with ordered material composition should override)
--------------------------------------------------------------------*/
ModelElement::Composition ColumnSegment::getComposition() const {
#ifdef ARCHICAD
return convert(m_data->root.assemblySegmentData.modelElemStructureType);
#endif
} //ColumnSegment::getComposition
/*--------------------------------------------------------------------
Get the element material (applicable to elements with a single, homogenous material)
return: The element material (nullopt if not applicable to the element)
--------------------------------------------------------------------*/
std::optional<Material> ColumnSegment::getMaterial() const {
#ifdef ARCHICAD
return Material{Guid{Guid::fromInt(m_data->root.assemblySegmentData.buildingMaterial.GenerateHashValue())}};
#endif
} //ColumnSegment::getMaterial
/*--------------------------------------------------------------------
Get a spatial measurement from this element (area/volume, as used for material quantities)
return: The element measurement (empty if unavailable)
--------------------------------------------------------------------*/
ModelElement::SpatialMeasure ColumnSegment::getSpatialMeasure() const {
#ifdef ARCHICAD
Surveyor surveyor;
BIMMemory::setMask(&surveyor.elementMask().columnSegment.coreNetSurface);
BIMMemory::setMask(&surveyor.elementMask().columnSegment.volume);
surveyor.measure(getBIMLink());
return SpatialMeasure{surveyor.quantity().columnSegment.coreNetSurface, surveyor.quantity().columnSegment.volume};
#endif
} //ColumnSegment::getSpatialMeasure
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Get the (immutable) API element header data
@@ -109,7 +144,7 @@ ColumnSegment::~ColumnSegment() {}
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;
return m_data->root.head;
} //ColumnSegment::getHead
@@ -119,7 +154,7 @@ const API_Elem_Head& ColumnSegment::getHead() const {
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;
return m_data->root.head;
} //ColumnSegment::getHead
#endif
@@ -64,6 +64,21 @@ namespace speckle::record::element {
// MARK: - Functions (const)
/*!
Get the composition of materials in the element
@return The material composition (element with ordered material composition should override)
*/
Composition getComposition() const override;
/*!
Get the element material (applicable to elements with a single, homogenous material)
@return The element material (nullopt if not applicable to the element)
*/
std::optional<record::attribute::Material> getMaterial() const override;
/*!
Get a spatial measurement from this element (area/volume, as used for material quantities)
@return The element measurement (empty if unavailable)
*/
SpatialMeasure getSpatialMeasure() const override;
#ifdef ARCHICAD
/*!
Get the (immutable) API element header data
@@ -1,15 +1,6 @@
#include "Speckle/Record/Element/DrawingElement.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;
+16 -5
View File
@@ -1,17 +1,14 @@
#include "Speckle/Record/Element/Element.h"
#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/Record/Element/Setting/TypeSetting.h"
#include "Speckle/SpeckleResource.h"
#include "Speckle/Utility/Guid.h"
using namespace active::serialise;
using namespace speckle::database;
using namespace speckle::environment;
using namespace speckle::record::attribute;
using namespace speckle::record::element;
@@ -74,6 +71,20 @@ Storey::Option Element::getStorey() const {
} //Element::getStorey
/*--------------------------------------------------------------------
Get a link to the BIM record
return: The BIM record link
--------------------------------------------------------------------*/
BIMLink Element::getBIMLink() const {
auto result = base::getBIMLink();
#ifdef ARCHICAD
result.emplace_back(std::make_unique<TypeSetting>(getHead()));
#endif
return result;
} //Element::getLink
/*--------------------------------------------------------------------
Get the element type name, e.g. "Wall", "Roof" etc
@@ -71,6 +71,11 @@ namespace speckle::record::element {
@return The element storey (nullopt if the element isn't linked to a storey)
*/
virtual attribute::Storey::Option getStorey() const;
/*!
Get a link to the BIM record
@return The BIM record link
*/
database::BIMLink getBIMLink() const override;
#ifdef ARCHICAD
/*!
Get the (immutable) API element header data
@@ -1,15 +1,6 @@
#include "Speckle/Record/Element/GenericDrawingElement.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;
@@ -24,12 +15,11 @@ namespace speckle::record::element {
friend class GenericDrawingElement;
#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) } {}
Data(const API_Element& elem) : root{elem} {}
#endif
private:
std::unique_ptr<API_Element> root;
API_Element root;
};
}
@@ -75,7 +65,7 @@ GenericDrawingElement::~GenericDrawingElement() {}
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
const API_Elem_Head& GenericDrawingElement::getHead() const {
return m_data->root->header;
return m_data->root.header;
} //GenericDrawingElement::getHead
/*--------------------------------------------------------------------
@@ -84,7 +74,7 @@ const API_Elem_Head& GenericDrawingElement::getHead() const {
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
API_Elem_Head& GenericDrawingElement::getHead() {
return m_data->root->header;
return m_data->root.header;
} //GenericDrawingElement::getHead
#endif
@@ -1,15 +1,6 @@
#include "Speckle/Record/Element/GenericModelElement.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;
@@ -24,12 +15,11 @@ namespace speckle::record::element {
friend class GenericModelElement;
#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) } {}
Data(const API_Element& elem) : root{elem} {}
#endif
private:
std::unique_ptr<API_Element> root;
API_Element root;
};
}
@@ -75,7 +65,7 @@ GenericModelElement::~GenericModelElement() {}
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
const API_Elem_Head& GenericModelElement::getHead() const {
return m_data->root->header;
return m_data->root.header;
} //GenericModelElement::getHead
/*--------------------------------------------------------------------
@@ -84,7 +74,7 @@ const API_Elem_Head& GenericModelElement::getHead() const {
return: The element header data (only use this data for low-level operations - for normal code, call getters/setters)
--------------------------------------------------------------------*/
API_Elem_Head& GenericModelElement::getHead() {
return m_data->root->header;
return m_data->root.header;
} //GenericModelElement::getHead
#endif
@@ -0,0 +1,164 @@
#include "Speckle/Record/Element/MeshElem.h"
#include "Speckle/Record/Element/Quants/Surveyor.h"
#include "Speckle/Record/Element/Setting/Conversion.h"
#include "Speckle/Utility/BIMMemory.h"
#ifdef ARCHICAD
#include <ACAPinc.h>
#endif
using namespace active::serialise;
using namespace speckle::record::attribute;
using namespace speckle::record::element;
using namespace speckle::record::element::quants;
using namespace speckle::utility;
#include <array>
#include <memory>
namespace speckle::record::element {
class Mesh::Data {
public:
friend class Mesh;
#ifdef ARCHICAD
Data(const API_MeshType& seg) : root{seg} {}
private:
API_MeshType root;
#endif
};
}
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
Mesh::Mesh() {
} //Mesh::Mesh
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Constructor
elemData: Archicad element data
tableID: The element table ID (AC database, e.g. floor plan, 3D)
--------------------------------------------------------------------*/
Mesh::Mesh(const API_Element& elemData, const speckle::utility::Guid& tableID) : base{ elemData.header.guid, tableID } {
m_data = std::make_unique<Data>(elemData.mesh);
} //Mesh::Mesh
#endif
/*--------------------------------------------------------------------
Copy constructor
source: The object to copy
--------------------------------------------------------------------*/
Mesh::Mesh(const Mesh& source) : base{ source } {
m_data = source.m_data ? std::make_unique<Data>(*source.m_data) : nullptr;
} //Mesh::Mesh
/*--------------------------------------------------------------------
Move constructor
source: The object to move
--------------------------------------------------------------------*/
Mesh::Mesh(Mesh&& source) noexcept : base{source} {
m_data = std::move(source.m_data);
} //Mesh::Mesh
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
Mesh::~Mesh() {}
/*--------------------------------------------------------------------
Get the element material (applicable to elements with a single, homogenous material)
return: The element material (nullopt if not applicable to the element)
--------------------------------------------------------------------*/
std::optional<Material> Mesh::getMaterial() const {
#ifdef ARCHICAD
return Material{Guid{Guid::fromInt(m_data->root.buildingMaterial.GenerateHashValue())}};
#endif
} //Mesh::getMaterial
/*--------------------------------------------------------------------
Get a spatial measurement from this element (area/volume, as used for material quantities)
return: The element measurement (empty if unavailable)
--------------------------------------------------------------------*/
ModelElement::SpatialMeasure Mesh::getSpatialMeasure() const {
#ifdef ARCHICAD
Surveyor surveyor;
BIMMemory::setMask(&surveyor.elementMask().mesh.topSurface);
BIMMemory::setMask(&surveyor.elementMask().mesh.volume);
surveyor.measure(getBIMLink());
return SpatialMeasure{surveyor.quantity().mesh.topSurface, surveyor.quantity().mesh.volume};
#endif
} //Mesh::getSpatialMeasure
#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& Mesh::getHead() const {
return m_data->root.head;
} //Mesh::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& Mesh::getHead() {
return m_data->root.head;
} //Mesh::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 Mesh::fillInventory(Inventory& inventory) const {
using enum Entry::Type;
//TODO: Implement other fields as required
return base::fillInventory(inventory);
} //Mesh::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique Mesh::getCargo(const Inventory::Item& item) const {
//TODO: Implement other fields as required
return base::getCargo(item);
} //Mesh::getCargo
/*--------------------------------------------------------------------
Set to the default package content
--------------------------------------------------------------------*/
void Mesh::setDefault() {
m_data.reset();
} //Mesh::setDefault
@@ -0,0 +1,120 @@
#ifndef SPECKLE_RECORD_ELEMENT_MESH
#define SPECKLE_RECORD_ELEMENT_MESH
#include "Speckle/Record/Element/ModelElement.h"
#include "Speckle/Record/Element/Interface/Assembly/Segment.h"
namespace speckle::record::element {
/*!
BIM mesh class
*/
class Mesh : public ModelElement {
public:
// MARK: - Types
using base = ModelElement;
///Unique pointer
using Unique = std::unique_ptr<Mesh>;
///Shared pointer
using Shared = std::shared_ptr<Mesh>;
///Optional
using Option = std::optional<Mesh>;
// MARK: - Constructors
using base::base;
/*!
Default constructor
*/
Mesh();
#ifdef ARCHICAD
/*!
Constructor
@param elemData Archicad element data
@param tableID The element table ID (AC database, e.g. floor plan, 3D)
*/
Mesh(const API_Element& elemData, const speckle::utility::Guid& tableID);
#endif
/*!
Copy constructor
@param source The object to copy
*/
Mesh(const Mesh& source);
/*!
Move constructor
@param source The object to move
*/
Mesh(Mesh&& source) noexcept;
/*!
Destructor
*/
~Mesh();
/*!
Object cloning
@return A clone of this object
*/
Mesh* clonePtr() const override { return new Mesh{*this}; }
// MARK: - Functions (const)
/*!
Get the element material (applicable to elements with a single, homogenous material)
@return The element material (nullopt if not applicable to the element)
*/
std::optional<record::attribute::Material> getMaterial() const override;
/*!
Get a spatial measurement from this element (area/volume, as used for material quantities)
@return The element measurement (empty if unavailable)
*/
SpatialMeasure getSpatialMeasure() const override;
#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;
private:
class Data;
///The beam data
std::unique_ptr<Data> m_data;
};
}
#endif //SPECKLE_RECORD_ELEMENT_MESH
@@ -1,13 +1,12 @@
#include "Speckle/Record/Element/ModelElement.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/Record/Element/Memo.h"
#include "Speckle/Record/Property/Wrapper/PropertiedWrapper.h"
#include "Speckle/SpeckleResource.h"
#include "Speckle/Utility/Guid.h"
#include "Speckle/Utility/BIMMemory.h"
#ifdef ARCHICAD
#include <exp.h>
@@ -26,6 +25,7 @@ using namespace speckle::database;
using namespace speckle::environment;
using namespace speckle::record::attribute;
using namespace speckle::record::element;
using namespace speckle::record::element::quants;
using namespace speckle::record::property;
using namespace speckle::utility;
@@ -78,6 +78,7 @@ namespace speckle::record::element {
};
///Allocation for the ModelElement finishes cache (used because repeated API access is very slow)
std::unique_ptr<ModelElement::FinishCache> ModelElement::m_finishCache;
}
@@ -87,76 +88,96 @@ namespace {
///Serialisation fields
enum FieldIndex {
bodyID,
materialQuantsID,
propertyID,
};
///Serialisation field IDs
static std::array fieldID = {
Identity{"displayValue"},
Identity{"materialQuantities"},
Identity{"properties"},
};
#ifdef ARCHICAD
/*!
Collect the IDs of individual parts from an assembly (e.g. stair, curtain wall)
@param parts A pointer to the assembly parts
@param partIDs The assembly part IDs
*/
template<typename T>
void getSubElementIds(T* ptr, std::set<API_Guid>& subIds)
{
GSSize nSubElements = BMGetPtrSize(reinterpret_cast<GSPtr>(ptr)) / sizeof(T);
void getPartIDs(T* parts, std::set<API_Guid>& partIDs) {
GSSize nSubElements = BMGetPtrSize(reinterpret_cast<GSPtr>(parts)) / sizeof(T);
for (Int32 idx = 0; idx < nSubElements; ++idx)
subIds.insert(ptr[idx].head.guid);
partIDs.insert(parts[idx].head.guid);
}
/*!
Measure material quantities from the composite materials of a specified element
@param guid The ID of the element to measure
@param elementQuantity Quantities extracted from the target element (out)
@param extendedQuantity Optional extended quantities calculated for some element types
@param quantityMask Mask to determine which quantities are required (minimise calculation time)
*/
void measureQuantities(const API_Guid& guid, API_ElementQuantity& elementQuantity,
API_Quantities& extendedQuantity, const API_QuantitiesMask& quantityMask) {
extendedQuantity.elements = &elementQuantity;
GS::Array<API_ElemPartQuantity> elementPartQuantities;
API_QuantityPar quantityParameters{};
quantityParameters.minOpeningSize = Eps;
ACAPI_Element_GetQuantities(guid, &quantityParameters, &extendedQuantity, &quantityMask);
} //measureQuantities
/*!
Collect the IDs of individual parts from an element (e.g. stair, curtain wall)
@param elemId The element to collect part IDs from
@param typeID The element type identifier
@param memo The element memo data
*/
std::set<API_Guid> collectPartIDs(const API_Guid& elemId, API_ElemTypeID typeID, const Memo& memo) {
std::set<API_Guid> partIDs{};
partIDs.insert(elemId);
if (!memo)
return partIDs;
switch (typeID) {
case API_StairID:
getPartIDs(memo.root()->stairRisers, partIDs);
getPartIDs(memo.root()->stairTreads, partIDs);
getPartIDs(memo.root()->stairStructures, partIDs);
break;
case API_RailingID:
getPartIDs(memo.root()->railingSegments, partIDs);
getPartIDs(memo.root()->railingPatterns, partIDs);
getPartIDs(memo.root()->railingRails, partIDs);
getPartIDs(memo.root()->railingHandrails, partIDs);
getPartIDs(memo.root()->railingToprails, partIDs);
getPartIDs(memo.root()->railingBalusterSets, partIDs);
getPartIDs(memo.root()->railingBalusters, partIDs);
getPartIDs(memo.root()->railingPanels, partIDs);
getPartIDs(memo.root()->railingInnerPosts, partIDs);
std::set<API_Guid> collectSubIds(API_Guid elemId)
{
API_Element elem{};
elem.header.guid = elemId;
ACAPI_Element_Get(&elem);
API_ElementMemo memo{};
ACAPI_Element_GetMemo(elemId, &memo);
std::set<API_Guid> subIds{};
subIds.insert(elemId);
if (elem.header.type.typeID == API_StairID)
{
getSubElementIds(memo.stairRisers, subIds);
getSubElementIds(memo.stairTreads, subIds);
getSubElementIds(memo.stairStructures, subIds);
getPartIDs(memo.root()->railingNodes, partIDs);
getPartIDs(memo.root()->railingRailConnections, partIDs);
getPartIDs(memo.root()->railingHandrailConnections, partIDs);
getPartIDs(memo.root()->railingToprailConnections, partIDs);
getPartIDs(memo.root()->railingPosts, partIDs);
getPartIDs(memo.root()->railingRailEnds, partIDs);
getPartIDs(memo.root()->railingHandrailEnds, partIDs);
getPartIDs(memo.root()->railingToprailEnds, partIDs);
break;
case API_CurtainWallID:
getPartIDs(memo.root()->cWallSegments, partIDs);
getPartIDs(memo.root()->cWallFrames, partIDs);
getPartIDs(memo.root()->cWallPanels, partIDs);
getPartIDs(memo.root()->cWallJunctions, partIDs);
getPartIDs(memo.root()->cWallAccessories, partIDs);
break;
default:
break;
}
if (elem.header.type.typeID == API_RailingID)
{
// segments
getSubElementIds(memo.railingSegments, subIds);
getSubElementIds(memo.railingPatterns, subIds);
getSubElementIds(memo.railingRails, subIds);
getSubElementIds(memo.railingHandrails, subIds);
getSubElementIds(memo.railingToprails, subIds);
getSubElementIds(memo.railingBalusterSets, subIds);
getSubElementIds(memo.railingBalusters, subIds);
getSubElementIds(memo.railingPanels, subIds);
getSubElementIds(memo.railingInnerPosts, subIds);
// nodes
getSubElementIds(memo.railingNodes, subIds);
getSubElementIds(memo.railingRailConnections, subIds);
getSubElementIds(memo.railingHandrailConnections, subIds);
getSubElementIds(memo.railingToprailConnections, subIds);
getSubElementIds(memo.railingPosts, subIds);
getSubElementIds(memo.railingRailEnds, subIds);
getSubElementIds(memo.railingHandrailEnds, subIds);
getSubElementIds(memo.railingToprailEnds, subIds);
}
if (elem.header.type.typeID == API_CurtainWallID)
{
getSubElementIds(memo.cWallSegments, subIds);
getSubElementIds(memo.cWallFrames, subIds);
getSubElementIds(memo.cWallPanels, subIds);
getSubElementIds(memo.cWallJunctions, subIds);
getSubElementIds(memo.cWallAccessories, subIds);
}
return subIds;
return partIDs;
}
#endif
@@ -233,6 +254,52 @@ void ModelElement::resetCache() {
} //ModelElement::resetCache
/*--------------------------------------------------------------------
Get material quantities measured from this element
return: An list of material quantities
--------------------------------------------------------------------*/
MaterialQuantityList ModelElement::getMaterialQuantities() const {
using enum Composition;
MaterialQuantityList result;
switch (getComposition()) {
case unordered: {
//Get the material and spatial measurements
auto material = getMaterial();
if (!material)
return result;
auto spatialMeasure = getSpatialMeasure();
if (!spatialMeasure)
return result;
//Create a material quantity from the quantity takeoff
result.push_back({material->getBIMID(), spatialMeasure.area, spatialMeasure.volume});
break;
}
case skinned: {
#ifdef ARCHICAD
API_ElementQuantity elementQuantity{};
API_Quantities extendedQuantity{};
GS::Array<API_CompositeQuantity> compositeQuantity{};
extendedQuantity.composites = &compositeQuantity;
API_QuantitiesMask quantityMask{};
//Set the appropriate masks for composite material volume/area quantity takeoffs
BIMMemory::setMask(&quantityMask.composites.buildMatIndices);
BIMMemory::setMask(&quantityMask.composites.volumes);
BIMMemory::setMask(&quantityMask.composites.projectedArea);
measureQuantities(getHead().guid, elementQuantity, extendedQuantity, quantityMask);
//Create material quantities from the quantity takeoff (one oer skin in the composite structure)
for (auto& skinQuant : compositeQuantity)
result.push_back({Guid{Guid::fromInt(skinQuant.buildMatIndices.GenerateHashValue())}, skinQuant.projectedArea, skinQuant.volumes});
#endif
break;
}
case profiled:
break;
}
return result;
} //ModelElement::getMaterialQuantities
/*--------------------------------------------------------------------
Get the element body as a list of faces or Meshes
@@ -257,13 +324,18 @@ ModelElement::Body* ModelElement::getBody() const {
auto elementBody = new ModelElement::Body();
// Map to collect meshes per material name
std::unordered_map<String, primitive::Mesh> materialMeshMap;
auto subIds = collectSubIds(getHead().guid);
std::unique_ptr<Memo> memo;
loadMemo(APIMemoMask_All, memo);
auto partIDs = collectPartIDs(getHead().guid, getHead().type.typeID, *memo);
memo.reset();
Int32 nElements = acModel.GetElementCount();
for (Int32 iElement = 1; iElement <= nElements; iElement++) {
ModelerAPI::Element elem{};
acModel.GetElement(iElement, &elem);
API_Guid apiGuid{GSGuid2APIGuid(elem.GetElemGuid())};
if (subIds.find(apiGuid) == subIds.end())
if (partIDs.find(apiGuid) == partIDs.end())
continue;
Int32 nBodies = elem.GetTessellatedBodyCount();
ModelerAPI::Material material{};
@@ -327,6 +399,7 @@ bool ModelElement::fillInventory(Inventory& inventory) const {
inventory.merge(Inventory{
{
{ fieldID[bodyID], bodyID, element },
{ fieldID[materialQuantsID], materialQuantsID, element },
{ fieldID[propertyID], propertyID, element },
},
}.withType(&typeid(ModelElement)));
@@ -348,9 +421,12 @@ Cargo::Unique ModelElement::getCargo(const Inventory::Item& item) const {
switch (item.index) {
case bodyID:
if (auto body = getBody(); body != nullptr)
return Cargo::Unique{ new active::serialise::ContainerWrap{*body} };
else
return nullptr;
return Cargo::Unique{new active::serialise::ContainerWrap{*body}};
return nullptr;
case materialQuantsID:
if (auto quants = getMaterialQuantities(); !quants.empty())
return Cargo::Unique{new CargoHold<ContainerWrap<MaterialQuantityList>, MaterialQuantityList>{quants}};
return nullptr;
case propertyID:
return std::make_unique<PropertiedWrapper>(*this);
default:
@@ -1,13 +1,15 @@
#ifndef SPECKLE_RECORD_MODEL_ELEMENT
#define SPECKLE_RECORD_MODEL_ELEMENT
#include "Speckle/Record/Attribute/Material.h"
#include "Speckle/Record/Classification/Classified.h"
#include "Speckle/Record/Element/Element.h"
#include "Speckle/Record/Element/Element.h"
#include "Speckle/Record/Element/Quants/MaterialQuantity.h"
#include "Speckle/Record/Property/Propertied.h"
namespace speckle::record::attribute {
class Finish;
class Material;
}
namespace speckle::record::element {
@@ -29,8 +31,23 @@ namespace speckle::record::element {
using Option = std::optional<ModelElement>;
///A model element 3D body primitive
using Body = std::vector<primitive::Mesh>;
//Material composition
enum class Composition {
unordered, ///<Element is composed of materials with no fixed relationship
skinned, ///<Element is composed of layered materials 'skins', e.g. brick/air/insulation/block in a wall
profiled, ///<Element is composed of materials extruded through a profile along a space-curve, e.g. window frames
};
///Model element spatial measurements
struct SpatialMeasure {
///Element area
double area = 0.0;
///Element volume
double volume = 0.0;
///True if either a volume or area has been measured
operator bool() const { return active::math::isGreaterZero(area) || active::math::isGreaterZero(volume); }
};
// MARK: - Constructors
// MARK: - Static functions
/*!
Get a mesh finish from the cache
@@ -79,6 +96,26 @@ namespace speckle::record::element {
// MARK: - Functions (const)
/*!
Get the composition of materials in the element
@return The material composition (element with ordered material composition should override)
*/
virtual Composition getComposition() const { return Composition::unordered; }
/*!
Get the element material (applicable to elements with a single, homogenous material)
@return The element material (nullopt if not applicable to the element)
*/
virtual std::optional<record::attribute::Material> getMaterial() const { return std::nullopt; }
/*!
Get a spatial measurement from this element (area/volume, as used for material quantities)
@return The element measurement (empty if unavailable)
*/
virtual SpatialMeasure getSpatialMeasure() const { return SpatialMeasure{}; }
/*!
Get material quantities measured from this element
@return An list of material quantities
*/
quants::MaterialQuantityList getMaterialQuantities() const;
/*!
Get the element body
@return An array of meshes from the element body (nullptr if no body data is available)
+164
View File
@@ -0,0 +1,164 @@
#include "Speckle/Record/Element/Morph.h"
#include "Speckle/Record/Element/Quants/Surveyor.h"
#include "Speckle/Record/Element/Setting/Conversion.h"
#include "Speckle/Utility/BIMMemory.h"
#ifdef ARCHICAD
#include <ACAPinc.h>
#endif
using namespace active::serialise;
using namespace speckle::record::attribute;
using namespace speckle::record::element;
using namespace speckle::record::element::quants;
using namespace speckle::utility;
#include <array>
#include <memory>
namespace speckle::record::element {
class Morph::Data {
public:
friend class Morph;
#ifdef ARCHICAD
Data(const API_MorphType& seg) : root{seg} {}
private:
API_MorphType root;
#endif
};
}
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
Morph::Morph() {
} //Morph::Morph
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Constructor
elemData: Archicad element data
tableID: The element table ID (AC database, e.g. floor plan, 3D)
--------------------------------------------------------------------*/
Morph::Morph(const API_Element& elemData, const speckle::utility::Guid& tableID) : base{ elemData.header.guid, tableID } {
m_data = std::make_unique<Data>(elemData.morph);
} //Morph::Morph
#endif
/*--------------------------------------------------------------------
Copy constructor
source: The object to copy
--------------------------------------------------------------------*/
Morph::Morph(const Morph& source) : base{ source } {
m_data = source.m_data ? std::make_unique<Data>(*source.m_data) : nullptr;
} //Morph::Morph
/*--------------------------------------------------------------------
Move constructor
source: The object to move
--------------------------------------------------------------------*/
Morph::Morph(Morph&& source) noexcept : base{source} {
m_data = std::move(source.m_data);
} //Morph::Morph
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
Morph::~Morph() {}
/*--------------------------------------------------------------------
Get the element material (applicable to elements with a single, homogenous material)
return: The element material (nullopt if not applicable to the element)
--------------------------------------------------------------------*/
std::optional<Material> Morph::getMaterial() const {
#ifdef ARCHICAD
return Material{Guid{Guid::fromInt(m_data->root.buildingMaterial.GenerateHashValue())}};
#endif
} //Morph::getMaterial
/*--------------------------------------------------------------------
Get a spatial measurement from this element (area/volume, as used for material quantities)
return: The element measurement (empty if unavailable)
--------------------------------------------------------------------*/
ModelElement::SpatialMeasure Morph::getSpatialMeasure() const {
#ifdef ARCHICAD
Surveyor surveyor;
BIMMemory::setMask(&surveyor.elementMask().morph.surface);
BIMMemory::setMask(&surveyor.elementMask().morph.volume);
surveyor.measure(getBIMLink());
return SpatialMeasure{surveyor.quantity().morph.surface, surveyor.quantity().morph.volume};
#endif
} //Morph::getSpatialMeasure
#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& Morph::getHead() const {
return m_data->root.head;
} //Morph::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& Morph::getHead() {
return m_data->root.head;
} //Morph::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 Morph::fillInventory(Inventory& inventory) const {
using enum Entry::Type;
//TODO: Implement other fields as required
return base::fillInventory(inventory);
} //Morph::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique Morph::getCargo(const Inventory::Item& item) const {
//TODO: Implement other fields as required
return base::getCargo(item);
} //Morph::getCargo
/*--------------------------------------------------------------------
Set to the default package content
--------------------------------------------------------------------*/
void Morph::setDefault() {
m_data.reset();
} //Morph::setDefault
+120
View File
@@ -0,0 +1,120 @@
#ifndef SPECKLE_RECORD_ELEMENT_MORPH
#define SPECKLE_RECORD_ELEMENT_MORPH
#include "Speckle/Record/Element/ModelElement.h"
#include "Speckle/Record/Element/Interface/Assembly/Segment.h"
namespace speckle::record::element {
/*!
BIM morph class
*/
class Morph : public ModelElement {
public:
// MARK: - Types
using base = ModelElement;
///Unique pointer
using Unique = std::unique_ptr<Morph>;
///Shared pointer
using Shared = std::shared_ptr<Morph>;
///Optional
using Option = std::optional<Morph>;
// MARK: - Constructors
using base::base;
/*!
Default constructor
*/
Morph();
#ifdef ARCHICAD
/*!
Constructor
@param elemData Archicad element data
@param tableID The element table ID (AC database, e.g. floor plan, 3D)
*/
Morph(const API_Element& elemData, const speckle::utility::Guid& tableID);
#endif
/*!
Copy constructor
@param source The object to copy
*/
Morph(const Morph& source);
/*!
Move constructor
@param source The object to move
*/
Morph(Morph&& source) noexcept;
/*!
Destructor
*/
~Morph();
/*!
Object cloning
@return A clone of this object
*/
Morph* clonePtr() const override { return new Morph{*this}; }
// MARK: - Functions (const)
/*!
Get the element material (applicable to elements with a single, homogenous material)
@return The element material (nullopt if not applicable to the element)
*/
std::optional<record::attribute::Material> getMaterial() const override;
/*!
Get a spatial measurement from this element (area/volume, as used for material quantities)
@return The element measurement (empty if unavailable)
*/
SpatialMeasure getSpatialMeasure() const override;
#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;
private:
class Data;
///The beam data
std::unique_ptr<Data> m_data;
};
}
#endif //SPECKLE_RECORD_ELEMENT_MORPH
@@ -0,0 +1,78 @@
#include "Speckle/Record/Element/Quants/MaterialQuantity.h"
#include "Active/Serialise/Item/Wrapper/ValueOptionWrap.h"
#include "Active/Serialise/Item/Wrapper/ValueWrap.h"
#include "Speckle/Record/Attribute/Material.h"
#include "Speckle/Record/Element/Quants/MaterialWrap.h"
#include "Speckle/Serialise/Types/Units/LengthUnit.h"
using namespace active::serialise;
using namespace speckle::database;
using namespace speckle::record::attribute;
using namespace speckle::record::element::quants;
namespace {
///Serialisation fields
enum FieldIndex {
areaID,
volumeID,
unitID,
matID,
};
///Serialisation field IDs
static std::array fieldID = {
Identity{"area"},
Identity{"volume"},
Identity{"units"},
Identity{"material"},
};
}
/*--------------------------------------------------------------------
Fill an inventory with the cargo items
inventory: The inventory to receive the cargo items
return: True if items have been added to the inventory
--------------------------------------------------------------------*/
bool MaterialQuantity::fillInventory(active::serialise::Inventory& inventory) const {
using enum Entry::Type;
inventory.merge(Inventory{
{
{ fieldID[areaID], areaID, element },
{ fieldID[volumeID], volumeID, element },
{ fieldID[unitID], unitID, element },
{ fieldID[matID], matID, element },
},
}.withType(&typeid(MaterialQuantity)));
return true;
} //MaterialQuantity::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique MaterialQuantity::getCargo(const active::serialise::Inventory::Item& item) const {
if (item.ownerType != &typeid(MaterialQuantity))
return nullptr;
using namespace active::serialise;
switch (item.index) {
case areaID:
return std::make_unique<ValueWrap<double>>(m_area);
case volumeID:
return std::make_unique<ValueWrap<double>>(m_volume);
case unitID:
return std::make_unique<ValueOptionWrap<active::measure::LengthType>>(m_unit);
case matID:
return std::make_unique<MaterialWrap>(m_materialID);
default:
return nullptr; //Requested an unknown index
}
} //MaterialQuantity::getCargo
@@ -0,0 +1,95 @@
#ifndef SPECKLE_RECORD_ELEMENT_MATERIAL_QUANTITY
#define SPECKLE_RECORD_ELEMENT_MATERIAL_QUANTITY
#include "Active/Serialise/Package/Package.h"
#include "Active/Setting/Values/Measurement/Units/LengthUnit.h"
#include "Speckle/Database/Identity/BIMRecordID.h"
namespace speckle::record::element::quants {
/*!
Measured material quantities extracted from an element
This object pairs a material (BuildingMaterial in Archicad) with measurements of surface are ands volume (pssibly more in future).
An element may be constructed of many materials, e.g. the skins of a wall, in which case the quants extracted from the element will
be an array of MaterialQuantity.
*/
class MaterialQuantity final : public active::serialise::Package {
public:
// MARK: - Types
///Unique pointer
using Unique = std::unique_ptr<MaterialQuantity>;
///Shared pointer
using Shared = std::shared_ptr<MaterialQuantity>;
///Optional
using Option = std::optional<MaterialQuantity>;
// MARK: - Constructors
/*!
Default constructor
*/
MaterialQuantity() {}
/*!
Constructor
@param materialID The ID of the measured material record
@param area The measured surface area (see notes on member variable)
@param volume The measured volume of the material
*/
MaterialQuantity(const database::BIMRecordID& materialID, double area = 0.0, double volume = 0.0) :
m_materialID{materialID}, m_area{area}, m_volume{volume} {}
// MARK: - Functions (const)
/*!
Get the ID of the measured material
@return The material record ID (in the BIM attribute database)
*/
const database::BIMRecordID& getMaterialID() const { return m_materialID; }
/*!
Get the measure surface area of the material
@return The material surface area
*/
double getArea() const { return m_area; }
/*!
Get the measure volume of the material
@return The material volume
*/
double getVolume() const { return m_volume; }
// MARK: - Functions (mutating)
//MARK: - Serialisation
/*!
Fill an inventory with the cargo items
@param inventory The inventory to receive the cargo items
@return True if items have been added 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;
private:
///Surface area of the material. Total surface area for basic elements, area of the primary face for 'skinned' elements, e.g. slab top
double m_area = 0.0;
///Volume of the material
double m_volume = 0.0;
///The BIM record unit of length measurement
std::optional<active::measure::LengthType> m_unit = active::measure::LengthType::metre;
///ID of the measured building material
database::BIMRecordID m_materialID;
};
using MaterialQuantityList = std::vector<MaterialQuantity>;
}
#endif //SPECKLE_RECORD_ELEMENT_MATERIAL_QUANTITY
@@ -0,0 +1,68 @@
#include "Speckle/Record/Element/Quants/MaterialWrap.h"
#include "Active/Serialise/Item/Wrapper/ValueWrap.h"
#include "Speckle/Record/Attribute/Material.h"
using namespace active::serialise;
using namespace speckle::database;
using namespace speckle::record::attribute;
using namespace speckle::record::element::quants;
using namespace speckle::utility;
namespace {
///Serialisation fields
enum FieldIndex {
nameID,
};
///Serialisation field IDs
static std::array fieldID = {
Identity{"name"},
};
}
/*--------------------------------------------------------------------
Constructor
--------------------------------------------------------------------*/
MaterialWrap::MaterialWrap(const BIMRecordID& materialID) : m_name{Material{materialID}.getName()} {
} //MaterialWrap::MaterialWrap
/*--------------------------------------------------------------------
Fill an inventory with the cargo items
inventory: The inventory to receive the cargo items
return: True if items have been added to the inventory
--------------------------------------------------------------------*/
bool MaterialWrap::fillInventory(active::serialise::Inventory& inventory) const {
using enum Entry::Type;
inventory.merge(Inventory{
{
{ fieldID[nameID], nameID, element },
},
}.withType(&typeid(MaterialWrap)));
return true;
} //MaterialWrap::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique MaterialWrap::getCargo(const active::serialise::Inventory::Item& item) const {
if (item.ownerType != &typeid(MaterialWrap))
return nullptr;
using namespace active::serialise;
switch (item.index) {
case nameID:
return std::make_unique<ValueWrap<String>>(m_name);
default:
return nullptr; //Requested an unknown index
}
} //MaterialWrap::getCargo
@@ -0,0 +1,47 @@
#ifndef SPECKLE_RECORD_ELEMENT_MATERIAL_WRAP
#define SPECKLE_RECORD_ELEMENT_MATERIAL_WRAP
#include "Active/Serialise/Package/Package.h"
#include "Speckle/Database/Identity/BIMRecordID.h"
namespace speckle::record::element::quants {
/*!
Wrapper for a material exported with a quantity
NB: This wrapper primarily exports the material name. In future this might be linked to a material proxy, in which case this simple wrapper
will become a MaterialProxy
*/
class MaterialWrap final : public active::serialise::Package {
public:
// MARK: - Constructors
/*!
Constructor
*/
MaterialWrap(const database::BIMRecordID& materialID);
//MARK: - Serialisation
/*!
Fill an inventory with the cargo items
@param inventory The inventory to receive the cargo items
@return True if items have been added 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;
private:
///The wrapped material name
utility::String m_name;
};
}
#endif //SPECKLE_RECORD_ELEMENT_MATERIAL_WRAP
+86
View File
@@ -0,0 +1,86 @@
#include "Speckle/Record/Element/Quants/Surveyor.h"
#include "Active/Utility/Memory.h"
#include "Speckle/Record/Element/Setting/TypeSetting.h"
using namespace active::math;
using namespace speckle::database;
using namespace speckle::record::element::quants;
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
Surveyor::Surveyor() {
#ifdef ARCHICAD
active::utility::Memory::erase(m_quantity);
active::utility::Memory::erase(m_mask);
m_extendedQuantity.elements = &m_quantity;
m_extendedQuantity.composites = &m_composites;
#endif
} //Surveyor::Surveyor
/*--------------------------------------------------------------------
Copy constructor
source: The object to copy
--------------------------------------------------------------------*/
Surveyor::Surveyor(const Surveyor& source) : m_quantity(source.m_quantity), m_mask(source.m_mask), m_composites{source.m_composites} {
#ifdef ARCHICAD
m_extendedQuantity.elements = &m_quantity;
m_extendedQuantity.composites = &m_composites;
#endif
} //Surveyor::Surveyor
/*--------------------------------------------------------------------
Assignment operator
source: The object to copy
--------------------------------------------------------------------*/
Surveyor& Surveyor::operator= (const Surveyor& source) {
if (this != &source) {
#ifdef ARCHICAD
m_quantity = source.m_quantity;
m_mask = source.m_mask;
m_composites = source.m_composites;
m_extendedQuantity.elements = &m_quantity;
m_extendedQuantity.composites = &m_composites;
#endif
}
return *this;
} //Surveyor::operator=
/*--------------------------------------------------------------------
Measure quantities from a specified element
elementLink: Link to the target element
return: True if measurements were successfully taken
--------------------------------------------------------------------*/
bool Surveyor::measure(const BIMLink& elementLink) {
bool result = false;
#ifdef ARCHICAD
API_QuantityPar quantParams;
active::utility::Memory::erase(quantParams);
active::utility::Memory::erase(m_quantity);
GS::Array<API_ElemPartQuantity> elemPartQuantities;
bool isPartQuantities = false;
if (auto typeSetting = elementLink.find<TypeSetting>(TypeSetting::ID); typeSetting != nullptr)
isPartQuantities = (typeSetting->type == API_MorphID);
m_extendedQuantity.elemPartQuantities = isPartQuantities ? &elemPartQuantities : nullptr;
quantParams.minOpeningSize = eps;
m_composites.Clear();
result = (ACAPI_Element_GetQuantities(elementLink, &quantParams, &m_extendedQuantity, &m_mask) == NoError);
if (isPartQuantities) {
if (result && (elemPartQuantities.GetSize() > 0)) {
m_quantity.morph.baseLevel = elemPartQuantities[0].quantity.morph.baseLevel;
m_quantity.morph.baseHeight = elemPartQuantities[0].quantity.morph.baseHeight;
m_quantity.morph.wholeHeight = elemPartQuantities[0].quantity.morph.wholeHeight;
}
m_extendedQuantity.elemPartQuantities = nullptr;
}
#endif
return result;
} //Surveyor::measure
+97
View File
@@ -0,0 +1,97 @@
#ifndef SPECKLE_RECORD_ELEMENT_QUANTS_SURVEYOR
#define SPECKLE_RECORD_ELEMENT_QUANTS_SURVEYOR
#include "Speckle/Database/Identity/BIMLink.h"
#ifdef ARCHICAD
#include "APIdefs_Elements.h"
#endif
namespace speckle::record::element::quants {
/*!
A utility class to measure element quantities
*/
class Surveyor {
public:
/*!
Default constructor
*/
Surveyor();
/*!
Copy constructor
@param source The object to copy
*/
Surveyor(const Surveyor& source);
/*!
Assignment operator
@param source The object to copy
@return A reference to this
*/
Surveyor& operator= (const Surveyor& source);
#ifdef ARCHICAD
/*!
Get the quantity measurement values
@return The quantity valuse
*/
API_ElementQuantity& quantity() { return m_quantity; }
/*!
Get the mask specifying the values to measure
@return The quantity mask
*/
API_QuantitiesMask& mask() { return m_mask; }
/*!
Get the mask specifying the element values to measure
@return The element quantity mask
*/
API_ElementQuantityMask& elementMask() { return mask().elements; }
/*!
Get the mask specifying the composite values to measure
@return The composite quantity mask
*/
API_CompositeQuantityMask& compositeMask() { return mask().composites; }
#endif
/*!
Measure quantities from a specified element
@param elementLink Link to the target element
@return True if measurements were successfully taken
*/
bool measure(const database::BIMLink& elementLink);
#ifdef ARCHICAD
/*!
Get the quantity measurement values
@return The quantity valuse
*/
const API_ElementQuantity& quantity() const { return m_quantity; }
/*!
Get the mask specifying the values to measure
@return The quantity mask
*/
const API_QuantitiesMask& mask() const { return m_mask; }
/*!
Get the mask specifying the composite values to measure
@return The composite quantity mask
*/
const GS::Array<API_CompositeQuantity>& composites() const { return m_composites; }
#endif
private:
#ifdef ARCHICAD
///Archicad quantity measurement values
API_ElementQuantity m_quantity;
///Mask specifying the values to measure
API_QuantitiesMask m_mask;
///Optional additional values to measure, e.g. composite skins, assembly parts etc
API_Quantities m_extendedQuantity;
///Measurements taken from copmposite skins, e.g. the construction layers of a roof/wall
GS::Array<API_CompositeQuantity> m_composites;
#endif
};
}
#endif //SPECKLE_RECORD_ELEMENT_QUANTS_SURVEYOR
+176
View File
@@ -0,0 +1,176 @@
#include "Speckle/Record/Element/Roof.h"
#include "Speckle/Record/Element/Quants/Surveyor.h"
#include "Speckle/Record/Element/Setting/Conversion.h"
#include "Speckle/Utility/BIMMemory.h"
#ifdef ARCHICAD
#include <ACAPinc.h>
#endif
using namespace active::serialise;
using namespace speckle::record::attribute;
using namespace speckle::record::element;
using namespace speckle::record::element::quants;
using namespace speckle::utility;
#include <array>
#include <memory>
namespace speckle::record::element {
class Roof::Data {
public:
friend class Roof;
#ifdef ARCHICAD
Data(const API_RoofType& seg) : root{seg} {}
private:
API_RoofType root;
#endif
};
}
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
Roof::Roof() {
} //Roof::Roof
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Constructor
elemData: Archicad element data
tableID: The element table ID (AC database, e.g. floor plan, 3D)
--------------------------------------------------------------------*/
Roof::Roof(const API_Element& elemData, const speckle::utility::Guid& tableID) : base{ elemData.header.guid, tableID } {
m_data = std::make_unique<Data>(elemData.roof);
} //Roof::Roof
#endif
/*--------------------------------------------------------------------
Copy constructor
source: The object to copy
--------------------------------------------------------------------*/
Roof::Roof(const Roof& source) : base{ source } {
m_data = source.m_data ? std::make_unique<Data>(*source.m_data) : nullptr;
} //Roof::Roof
/*--------------------------------------------------------------------
Move constructor
source: The object to move
--------------------------------------------------------------------*/
Roof::Roof(Roof&& source) noexcept : base{source} {
m_data = std::move(source.m_data);
} //Roof::Roof
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
Roof::~Roof() {}
/*--------------------------------------------------------------------
Get the composition of materials in the element
return: The material composition (element with ordered material composition should override)
--------------------------------------------------------------------*/
ModelElement::Composition Roof::getComposition() const {
#ifdef ARCHICAD
return convert(m_data->root.shellBase.modelElemStructureType);
#endif
} //Roof::getComposition
/*--------------------------------------------------------------------
Get the element material (applicable to elements with a single, homogenous material)
return: The element material (nullopt if not applicable to the element)
--------------------------------------------------------------------*/
std::optional<Material> Roof::getMaterial() const {
#ifdef ARCHICAD
return Material{Guid{Guid::fromInt(m_data->root.shellBase.buildingMaterial.GenerateHashValue())}};
#endif
} //Roof::getMaterial
/*--------------------------------------------------------------------
Get a spatial measurement from this element (area/volume, as used for material quantities)
return: The element measurement (empty if unavailable)
--------------------------------------------------------------------*/
ModelElement::SpatialMeasure Roof::getSpatialMeasure() const {
#ifdef ARCHICAD
Surveyor surveyor;
BIMMemory::setMask(&surveyor.elementMask().roof.topSurface);
BIMMemory::setMask(&surveyor.elementMask().roof.volume);
surveyor.measure(getBIMLink());
return SpatialMeasure{surveyor.quantity().roof.topSurface, surveyor.quantity().roof.volume};
#endif
} //Roof::getSpatialMeasure
#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& Roof::getHead() const {
return m_data->root.head;
} //Roof::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& Roof::getHead() {
return m_data->root.head;
} //Roof::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 Roof::fillInventory(Inventory& inventory) const {
using enum Entry::Type;
//TODO: Implement other fields as required
return base::fillInventory(inventory);
} //Roof::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique Roof::getCargo(const Inventory::Item& item) const {
//TODO: Implement other fields as required
return base::getCargo(item);
} //Roof::getCargo
/*--------------------------------------------------------------------
Set to the default package content
--------------------------------------------------------------------*/
void Roof::setDefault() {
m_data.reset();
} //Roof::setDefault
+125
View File
@@ -0,0 +1,125 @@
#ifndef SPECKLE_RECORD_ELEMENT_ROOF
#define SPECKLE_RECORD_ELEMENT_ROOF
#include "Speckle/Record/Element/ModelElement.h"
#include "Speckle/Record/Element/Interface/Assembly/Segment.h"
namespace speckle::record::element {
/*!
BIM roof class
*/
class Roof : public ModelElement {
public:
// MARK: - Types
using base = ModelElement;
///Unique pointer
using Unique = std::unique_ptr<Roof>;
///Shared pointer
using Shared = std::shared_ptr<Roof>;
///Optional
using Option = std::optional<Roof>;
// MARK: - Constructors
using base::base;
/*!
Default constructor
*/
Roof();
#ifdef ARCHICAD
/*!
Constructor
@param elemData Archicad element data
@param tableID The element table ID (AC database, e.g. floor plan, 3D)
*/
Roof(const API_Element& elemData, const speckle::utility::Guid& tableID);
#endif
/*!
Copy constructor
@param source The object to copy
*/
Roof(const Roof& source);
/*!
Move constructor
@param source The object to move
*/
Roof(Roof&& source) noexcept;
/*!
Destructor
*/
~Roof();
/*!
Object cloning
@return A clone of this object
*/
Roof* clonePtr() const override { return new Roof{*this}; }
// MARK: - Functions (const)
/*!
Get the composition of materials in the element
@return The material composition (element with ordered material composition should override)
*/
Composition getComposition() const override;
/*!
Get the element material (applicable to elements with a single, homogenous material)
@return The element material (nullopt if not applicable to the element)
*/
std::optional<record::attribute::Material> getMaterial() const override;
/*!
Get a spatial measurement from this element (area/volume, as used for material quantities)
@return The element measurement (empty if unavailable)
*/
SpatialMeasure getSpatialMeasure() const override;
#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;
private:
class Data;
///The beam data
std::unique_ptr<Data> m_data;
};
}
#endif //SPECKLE_RECORD_ELEMENT_ROOF
@@ -0,0 +1,30 @@
#ifndef SPECKLE_RECORD_ELEMENT_CONVERSION
#define SPECKLE_RECORD_ELEMENT_CONVERSION
#include "Speckle/Record/Element/ModelElement.h"
#ifdef ARCHICAD
#include "APIdefs_Elements.h"
#endif
namespace speckle::record::element {
#ifdef ARCHICAD
/*!
Convert an Archicad structure type to an element composition
*/
inline ModelElement::Composition convert(API_ModelElemStructureType structType) {
switch (structType) {
case API_CompositeStructure:
return ModelElement::Composition::skinned;
case API_ProfileStructure:
return ModelElement::Composition::profiled;
default:
return ModelElement::Composition::unordered;
}
}
#endif
}
#endif //SPECKLE_RECORD_ELEMENT_CONVERSION
@@ -0,0 +1,82 @@
#include "Speckle/Record/Element/Setting/TypeSetting.h"
using namespace speckle::record::element;
/*--------------------------------------------------------------------
Equality operator
ref: The value to compare
return: True if the values are identical
--------------------------------------------------------------------*/
bool TypeSetting::operator==(const BIMIdentity& ref) const {
return type == ref;
} //TypeSetting::operator==
/*--------------------------------------------------------------------
Equality operator
ref: The value to compare
return: True if the values are identical
--------------------------------------------------------------------*/
bool TypeSetting::operator==(const Setting& ref) const {
if (auto refType = dynamic_cast<const TypeSetting*>(&ref); refType != nullptr)
return type == refType->type;
return false;
} //TypeSetting::operator==
/*--------------------------------------------------------------------
Less-than operator
@param ref The value to compare
@return True if this is less than ref
--------------------------------------------------------------------*/
bool TypeSetting::operator<(const Setting& ref) const {
auto refType = dynamic_cast<const TypeSetting*>(&ref);
if (refType == nullptr)
return true;
#ifdef ARCHICAD
if (type.typeID < refType->type.typeID)
return true;
if (type.typeID == refType->type.typeID) {
if (type.variationID < refType->type.variationID)
return true;
if (type.variationID == refType->type.variationID)
return (type.classID < refType->type.classID);
}
return false;
#endif
} //TypeSetting::operator==
/*--------------------------------------------------------------------
Assignment operator
@param source The object to copy
@return A reference to this
--------------------------------------------------------------------*/
TypeSetting& TypeSetting::operator=(const Setting& source) {
if (auto refType = dynamic_cast<const TypeSetting*>(&source); refType != nullptr)
type = refType->type;
return *this;
} //TypeSetting::operator==
/*--------------------------------------------------------------------
///True if the setting is empty
--------------------------------------------------------------------*/
bool TypeSetting::empty() const {
#ifdef ARCHICAD
return type.typeID == API_ZombieElemID;
#endif
} //TypeSetting::operator==
/*--------------------------------------------------------------------
Clear the setting (remove any values)
--------------------------------------------------------------------*/
void TypeSetting::clear() {
type = BIMIdentity{};
} //TypeSetting::clear
@@ -0,0 +1,113 @@
#ifndef SPECKLE_RECORD_ELEMENT_TYPE_SETTING
#define SPECKLE_RECORD_ELEMENT_TYPE_SETTING
#include "Active/Setting/Setting.h"
#ifdef ARCHICAD
#include "APIdefs_Elements.h"
#endif
namespace speckle::record::element {
///Setting identifying an element type
class TypeSetting : public active::setting::Setting {
public:
// MARK: - Types
using base = active::setting::Setting;
///BIM platform-specific typoe identifier
#ifdef ARCHICAD
using BIMIdentity = API_ElemType;
#endif
///Unique pointer
using Unique = std::unique_ptr<TypeSetting>;
///Shared pointer
using Shared = std::shared_ptr<TypeSetting>;
///Optional
using Option = std::optional<TypeSetting>;
// MARK: - Constants
static const inline active::utility::NameID ID{active::utility::String{"element type"}};
// MARK: - Constructors
/*!
Constructor
@param identifier A BIM element type identifier
*/
TypeSetting(const BIMIdentity& identifier = BIMIdentity{}) : base{ID}, type{identifier} {}
#ifdef ARCHICAD
/*!
Constructor
@param head An Archicad element header
*/
TypeSetting(const API_Elem_Head& head) : base{ID}, type{head.type} {}
#endif
/*!
Clone method
@return A clone of this object
*/
virtual TypeSetting* clonePtr() const override { return new TypeSetting{*this}; }
// MARK: - Public variables
///Platform-specific type identifier
BIMIdentity type;
// MARK: Operators
/*!
Equality operator
@param ref The value to compare
@return True if the values are identical
*/
bool operator==(const BIMIdentity& ref) const;
/*!
Equality operator
@param ref The value to compare
@return True if the values are identical
*/
bool operator==(const Setting& ref) const override;
/*!
Less-than operator
@param ref The value to compare
@return True if this is less than ref
*/
bool operator<(const Setting& ref) const override;
/*!
Assignment operator
@param source The object to copy
@return A reference to this
*/
TypeSetting& operator=(const Setting& source) override;
/*!
Conversion operator
@return True if the setting is not empty
*/
operator bool() const { return !empty(); }
// MARK: - Functions (const)
/*!
True if the setting is empty
*/
bool empty() const override;
// MARK: Functions (mutating)
/*!
Clear the setting (remove any values)
*/
void clear() override;
/*!
Assign a default to the setting
*/
void setDefault() override { clear(); }
};
}
#endif //SPECKLE_RECORD_ELEMENT_TYPE_SETTING
+164
View File
@@ -0,0 +1,164 @@
#include "Speckle/Record/Element/Shell.h"
#include "Speckle/Record/Element/Quants/Surveyor.h"
#include "Speckle/Record/Element/Setting/Conversion.h"
#include "Speckle/Utility/BIMMemory.h"
#ifdef ARCHICAD
#include <ACAPinc.h>
#endif
using namespace active::serialise;
using namespace speckle::record::attribute;
using namespace speckle::record::element;
using namespace speckle::record::element::quants;
using namespace speckle::utility;
#include <array>
#include <memory>
namespace speckle::record::element {
class Shell::Data {
public:
friend class Shell;
#ifdef ARCHICAD
Data(const API_ShellType& seg) : root{seg} {}
private:
API_ShellType root;
#endif
};
}
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
Shell::Shell() {
} //Shell::Shell
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Constructor
elemData: Archicad element data
tableID: The element table ID (AC database, e.g. floor plan, 3D)
--------------------------------------------------------------------*/
Shell::Shell(const API_Element& elemData, const speckle::utility::Guid& tableID) : base{ elemData.header.guid, tableID } {
m_data = std::make_unique<Data>(elemData.shell);
} //Shell::Shell
#endif
/*--------------------------------------------------------------------
Copy constructor
source: The object to copy
--------------------------------------------------------------------*/
Shell::Shell(const Shell& source) : base{ source } {
m_data = source.m_data ? std::make_unique<Data>(*source.m_data) : nullptr;
} //Shell::Shell
/*--------------------------------------------------------------------
Move constructor
source: The object to move
--------------------------------------------------------------------*/
Shell::Shell(Shell&& source) noexcept : base{source} {
m_data = std::move(source.m_data);
} //Shell::Shell
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
Shell::~Shell() {}
/*--------------------------------------------------------------------
Get the element material (applicable to elements with a single, homogenous material)
return: The element material (nullopt if not applicable to the element)
--------------------------------------------------------------------*/
std::optional<Material> Shell::getMaterial() const {
#ifdef ARCHICAD
return Material{Guid{Guid::fromInt(m_data->root.shellBase.buildingMaterial.GenerateHashValue())}};
#endif
} //Shell::getMaterial
/*--------------------------------------------------------------------
Get a spatial measurement from this element (area/volume, as used for material quantities)
return: The element measurement (empty if unavailable)
--------------------------------------------------------------------*/
ModelElement::SpatialMeasure Shell::getSpatialMeasure() const {
#ifdef ARCHICAD
Surveyor surveyor;
BIMMemory::setMask(&surveyor.elementMask().shell.referenceSurface);
BIMMemory::setMask(&surveyor.elementMask().shell.volume);
surveyor.measure(getBIMLink());
return SpatialMeasure{surveyor.quantity().shell.referenceSurface, surveyor.quantity().shell.volume};
#endif
} //Shell::getSpatialMeasure
#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& Shell::getHead() const {
return m_data->root.head;
} //Shell::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& Shell::getHead() {
return m_data->root.head;
} //Shell::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 Shell::fillInventory(Inventory& inventory) const {
using enum Entry::Type;
//TODO: Implement other fields as required
return base::fillInventory(inventory);
} //Shell::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique Shell::getCargo(const Inventory::Item& item) const {
//TODO: Implement other fields as required
return base::getCargo(item);
} //Shell::getCargo
/*--------------------------------------------------------------------
Set to the default package content
--------------------------------------------------------------------*/
void Shell::setDefault() {
m_data.reset();
} //Shell::setDefault
+120
View File
@@ -0,0 +1,120 @@
#ifndef SPECKLE_RECORD_ELEMENT_SHELL
#define SPECKLE_RECORD_ELEMENT_SHELL
#include "Speckle/Record/Element/ModelElement.h"
#include "Speckle/Record/Element/Interface/Assembly/Segment.h"
namespace speckle::record::element {
/*!
BIM shell class
*/
class Shell : public ModelElement {
public:
// MARK: - Types
using base = ModelElement;
///Unique pointer
using Unique = std::unique_ptr<Shell>;
///Shared pointer
using Shared = std::shared_ptr<Shell>;
///Optional
using Option = std::optional<Shell>;
// MARK: - Constructors
using base::base;
/*!
Default constructor
*/
Shell();
#ifdef ARCHICAD
/*!
Constructor
@param elemData Archicad element data
@param tableID The element table ID (AC database, e.g. floor plan, 3D)
*/
Shell(const API_Element& elemData, const speckle::utility::Guid& tableID);
#endif
/*!
Copy constructor
@param source The object to copy
*/
Shell(const Shell& source);
/*!
Move constructor
@param source The object to move
*/
Shell(Shell&& source) noexcept;
/*!
Destructor
*/
~Shell();
/*!
Object cloning
@return A clone of this object
*/
Shell* clonePtr() const override { return new Shell{*this}; }
// MARK: - Functions (const)
/*!
Get the element material (applicable to elements with a single, homogenous material)
@return The element material (nullopt if not applicable to the element)
*/
std::optional<record::attribute::Material> getMaterial() const override;
/*!
Get a spatial measurement from this element (area/volume, as used for material quantities)
@return The element measurement (empty if unavailable)
*/
SpatialMeasure getSpatialMeasure() const override;
#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;
private:
class Data;
///The beam data
std::unique_ptr<Data> m_data;
};
}
#endif //SPECKLE_RECORD_ELEMENT_SHELL
+176
View File
@@ -0,0 +1,176 @@
#include "Speckle/Record/Element/Slab.h"
#include "Speckle/Record/Element/Quants/Surveyor.h"
#include "Speckle/Record/Element/Setting/Conversion.h"
#include "Speckle/Utility/BIMMemory.h"
#ifdef ARCHICAD
#include <ACAPinc.h>
#endif
using namespace active::serialise;
using namespace speckle::record::attribute;
using namespace speckle::record::element;
using namespace speckle::record::element::quants;
using namespace speckle::utility;
#include <array>
#include <memory>
namespace speckle::record::element {
class Slab::Data {
public:
friend class Slab;
#ifdef ARCHICAD
Data(const API_SlabType& seg) : root{seg} {}
private:
API_SlabType root;
#endif
};
}
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
Slab::Slab() {
} //Slab::Slab
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Constructor
elemData: Archicad element data
tableID: The element table ID (AC database, e.g. floor plan, 3D)
--------------------------------------------------------------------*/
Slab::Slab(const API_Element& elemData, const speckle::utility::Guid& tableID) : base{ elemData.header.guid, tableID } {
m_data = std::make_unique<Data>(elemData.slab);
} //Slab::Slab
#endif
/*--------------------------------------------------------------------
Copy constructor
source: The object to copy
--------------------------------------------------------------------*/
Slab::Slab(const Slab& source) : base{ source } {
m_data = source.m_data ? std::make_unique<Data>(*source.m_data) : nullptr;
} //Slab::Slab
/*--------------------------------------------------------------------
Move constructor
source: The object to move
--------------------------------------------------------------------*/
Slab::Slab(Slab&& source) noexcept : base{source} {
m_data = std::move(source.m_data);
} //Slab::Slab
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
Slab::~Slab() {}
/*--------------------------------------------------------------------
Get the composition of materials in the element
return: The material composition (element with ordered material composition should override)
--------------------------------------------------------------------*/
ModelElement::Composition Slab::getComposition() const {
#ifdef ARCHICAD
return convert(m_data->root.modelElemStructureType);
#endif
} //Slab::getComposition
/*--------------------------------------------------------------------
Get the element material (applicable to elements with a single, homogenous material)
return: The element material (nullopt if not applicable to the element)
--------------------------------------------------------------------*/
std::optional<Material> Slab::getMaterial() const {
#ifdef ARCHICAD
return Material{Guid{Guid::fromInt(m_data->root.buildingMaterial.GenerateHashValue())}};
#endif
} //Slab::getMaterial
/*--------------------------------------------------------------------
Get a spatial measurement from this element (area/volume, as used for material quantities)
return: The element measurement (empty if unavailable)
--------------------------------------------------------------------*/
ModelElement::SpatialMeasure Slab::getSpatialMeasure() const {
#ifdef ARCHICAD
Surveyor surveyor;
BIMMemory::setMask(&surveyor.elementMask().slab.topSurface);
BIMMemory::setMask(&surveyor.elementMask().slab.volume);
surveyor.measure(getBIMLink());
return SpatialMeasure{surveyor.quantity().slab.topSurface, surveyor.quantity().slab.volume};
#endif
} //Slab::getSpatialMeasure
#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& Slab::getHead() const {
return m_data->root.head;
} //Slab::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& Slab::getHead() {
return m_data->root.head;
} //Slab::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 Slab::fillInventory(Inventory& inventory) const {
using enum Entry::Type;
//TODO: Implement other fields as required
return base::fillInventory(inventory);
} //Slab::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique Slab::getCargo(const Inventory::Item& item) const {
//TODO: Implement other fields as required
return base::getCargo(item);
} //Slab::getCargo
/*--------------------------------------------------------------------
Set to the default package content
--------------------------------------------------------------------*/
void Slab::setDefault() {
m_data.reset();
} //Slab::setDefault
+125
View File
@@ -0,0 +1,125 @@
#ifndef SPECKLE_RECORD_ELEMENT_SLAB
#define SPECKLE_RECORD_ELEMENT_SLAB
#include "Speckle/Record/Element/ModelElement.h"
#include "Speckle/Record/Element/Interface/Assembly/Segment.h"
namespace speckle::record::element {
/*!
BIM slab class
*/
class Slab : public ModelElement {
public:
// MARK: - Types
using base = ModelElement;
///Unique pointer
using Unique = std::unique_ptr<Slab>;
///Shared pointer
using Shared = std::shared_ptr<Slab>;
///Optional
using Option = std::optional<Slab>;
// MARK: - Constructors
using base::base;
/*!
Default constructor
*/
Slab();
#ifdef ARCHICAD
/*!
Constructor
@param elemData Archicad element data
@param tableID The element table ID (AC database, e.g. floor plan, 3D)
*/
Slab(const API_Element& elemData, const speckle::utility::Guid& tableID);
#endif
/*!
Copy constructor
@param source The object to copy
*/
Slab(const Slab& source);
/*!
Move constructor
@param source The object to move
*/
Slab(Slab&& source) noexcept;
/*!
Destructor
*/
~Slab();
/*!
Object cloning
@return A clone of this object
*/
Slab* clonePtr() const override { return new Slab{*this}; }
// MARK: - Functions (const)
/*!
Get the composition of materials in the element
@return The material composition (element with ordered material composition should override)
*/
Composition getComposition() const override;
/*!
Get the element material (applicable to elements with a single, homogenous material)
@return The element material (nullopt if not applicable to the element)
*/
std::optional<record::attribute::Material> getMaterial() const override;
/*!
Get a spatial measurement from this element (area/volume, as used for material quantities)
@return The element measurement (empty if unavailable)
*/
SpatialMeasure getSpatialMeasure() const override;
#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;
private:
class Data;
///The beam data
std::unique_ptr<Data> m_data;
};
}
#endif //SPECKLE_RECORD_ELEMENT_SLAB
+176
View File
@@ -0,0 +1,176 @@
#include "Speckle/Record/Element/Wall.h"
#include "Speckle/Record/Element/Quants/Surveyor.h"
#include "Speckle/Record/Element/Setting/Conversion.h"
#include "Speckle/Utility/BIMMemory.h"
#ifdef ARCHICAD
#include <ACAPinc.h>
#endif
using namespace active::serialise;
using namespace speckle::record::attribute;
using namespace speckle::record::element;
using namespace speckle::record::element::quants;
using namespace speckle::utility;
#include <array>
#include <memory>
namespace speckle::record::element {
class Wall::Data {
public:
friend class Wall;
#ifdef ARCHICAD
Data(const API_WallType& seg) : root{seg} {}
private:
API_WallType root;
#endif
};
}
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
Wall::Wall() {
} //Wall::Wall
#ifdef ARCHICAD
/*--------------------------------------------------------------------
Constructor
elemData: Archicad element data
tableID: The element table ID (AC database, e.g. floor plan, 3D)
--------------------------------------------------------------------*/
Wall::Wall(const API_Element& elemData, const speckle::utility::Guid& tableID) : base{ elemData.header.guid, tableID } {
m_data = std::make_unique<Data>(elemData.wall);
} //Wall::Wall
#endif
/*--------------------------------------------------------------------
Copy constructor
source: The object to copy
--------------------------------------------------------------------*/
Wall::Wall(const Wall& source) : base{ source } {
m_data = source.m_data ? std::make_unique<Data>(*source.m_data) : nullptr;
} //Wall::Wall
/*--------------------------------------------------------------------
Move constructor
source: The object to move
--------------------------------------------------------------------*/
Wall::Wall(Wall&& source) noexcept : base{source} {
m_data = std::move(source.m_data);
} //Wall::Wall
/*--------------------------------------------------------------------
Destructor
--------------------------------------------------------------------*/
Wall::~Wall() {}
/*--------------------------------------------------------------------
Get the composition of materials in the element
return: The material composition (element with ordered material composition should override)
--------------------------------------------------------------------*/
ModelElement::Composition Wall::getComposition() const {
#ifdef ARCHICAD
return convert(m_data->root.modelElemStructureType);
#endif
} //Wall::getComposition
/*--------------------------------------------------------------------
Get the element material (applicable to elements with a single, homogenous material)
return: The element material (nullopt if not applicable to the element)
--------------------------------------------------------------------*/
std::optional<Material> Wall::getMaterial() const {
#ifdef ARCHICAD
return Material{Guid{Guid::fromInt(m_data->root.buildingMaterial.GenerateHashValue())}};
#endif
} //Wall::getMaterial
/*--------------------------------------------------------------------
Get a spatial measurement from this element (area/volume, as used for material quantities)
return: The element measurement (empty if unavailable)
--------------------------------------------------------------------*/
ModelElement::SpatialMeasure Wall::getSpatialMeasure() const {
#ifdef ARCHICAD
Surveyor surveyor;
BIMMemory::setMask(&surveyor.elementMask().wall.surface1);
BIMMemory::setMask(&surveyor.elementMask().wall.volume);
surveyor.measure(getBIMLink());
return SpatialMeasure{surveyor.quantity().wall.surface1, surveyor.quantity().wall.volume};
#endif
} //Wall::getSpatialMeasure
#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& Wall::getHead() const {
return m_data->root.head;
} //Wall::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& Wall::getHead() {
return m_data->root.head;
} //Wall::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 Wall::fillInventory(Inventory& inventory) const {
using enum Entry::Type;
//TODO: Implement other fields as required
return base::fillInventory(inventory);
} //Wall::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique Wall::getCargo(const Inventory::Item& item) const {
//TODO: Implement other fields as required
return base::getCargo(item);
} //Wall::getCargo
/*--------------------------------------------------------------------
Set to the default package content
--------------------------------------------------------------------*/
void Wall::setDefault() {
m_data.reset();
} //Wall::setDefault
+125
View File
@@ -0,0 +1,125 @@
#ifndef SPECKLE_RECORD_ELEMENT_WALL
#define SPECKLE_RECORD_ELEMENT_WALL
#include "Speckle/Record/Element/ModelElement.h"
#include "Speckle/Record/Element/Interface/Assembly/Segment.h"
namespace speckle::record::element {
/*!
BIM wall class
*/
class Wall : public ModelElement {
public:
// MARK: - Types
using base = ModelElement;
///Unique pointer
using Unique = std::unique_ptr<Wall>;
///Shared pointer
using Shared = std::shared_ptr<Wall>;
///Optional
using Option = std::optional<Wall>;
// MARK: - Constructors
using base::base;
/*!
Default constructor
*/
Wall();
#ifdef ARCHICAD
/*!
Constructor
@param elemData Archicad element data
@param tableID The element table ID (AC database, e.g. floor plan, 3D)
*/
Wall(const API_Element& elemData, const speckle::utility::Guid& tableID);
#endif
/*!
Copy constructor
@param source The object to copy
*/
Wall(const Wall& source);
/*!
Move constructor
@param source The object to move
*/
Wall(Wall&& source) noexcept;
/*!
Destructor
*/
~Wall();
/*!
Object cloning
@return A clone of this object
*/
Wall* clonePtr() const override { return new Wall{*this}; }
// MARK: - Functions (const)
/*!
Get the composition of materials in the element
@return The material composition (element with ordered material composition should override)
*/
Composition getComposition() const override;
/*!
Get the element material (applicable to elements with a single, homogenous material)
@return The element material (nullopt if not applicable to the element)
*/
std::optional<record::attribute::Material> getMaterial() const override;
/*!
Get a spatial measurement from this element (area/volume, as used for material quantities)
@return The element measurement (empty if unavailable)
*/
SpatialMeasure getSpatialMeasure() const override;
#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;
private:
class Data;
///The beam data
std::unique_ptr<Data> m_data;
};
}
#endif //SPECKLE_RECORD_ELEMENT_WALL
@@ -29,14 +29,14 @@ namespace speckle::serialise {
@param objectID The object the material is applied to
@return True if the material proxy was added (false typically means the record already exists)
*/
virtual bool addMaterialProxy(const speckle::database::BIMIndex& materialIndex, const speckle::database::BIMRecordID& objectID) = 0;
virtual bool addFinishProxy(const speckle::database::BIMIndex& materialIndex, const speckle::database::BIMRecordID& objectID) = 0;
/*!
Add a ModelerAPI material to the collection (NB: These are not persistent so need to be captured by this method)
@param finish A finish
@param objectID The object the material is applied to
@return True if the material proxy was added (false typically means the record already exists)
*/
virtual bool addMaterialProxy(const record::attribute::Finish& finish, const speckle::database::BIMRecordID& objectID) = 0;
virtual bool addFinishProxy(const record::attribute::Finish& finish, const speckle::database::BIMRecordID& objectID) = 0;
};
}
@@ -27,13 +27,13 @@ namespace speckle::serialise {
/*!
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
@return True if the package has added items to the inventory
*/
bool fillInventory(active::serialise::Inventory& inventory) const {
//NB: This object only exists to populate the finish collection - it doesn't carry any serialisable content
if (management() != nullptr) {
if (auto collector = management()->get<FinishCollector>(); collector != nullptr)
collector->addMaterialProxy(m_material, m_objectID);
collector->addFinishProxy(m_material, m_objectID);
}
return true;
} //DocumentInfo::fillInventory
@@ -21,7 +21,7 @@ namespace active::serialise {
@param source The source string to convert
@return The equivalent colour (nullopt on failure)
*/
std::optional<API_RGBColor> convertToAPI_RGBColor(const utility::String& source) {
inline std::optional<API_RGBColor> convertToAPI_RGBColor(const utility::String& source) {
auto intValue = source.toUInt32();
if (!intValue)
return std::nullopt;
+7
View File
@@ -7,6 +7,8 @@ namespace speckle::utility {
/*!
BIM memory functions
NB: These functions are primarily relevant to C-based BIM APIs that require low-level memory management, e.g. Archicad
*/
class BIMMemory {
public:
@@ -16,6 +18,11 @@ namespace speckle::utility {
@return The allocated pointer size
*/
static size_t getPtrSize(void* pointer);
/*!
Set a mask in a specified byte, i.e. fill with 1s
@param byte A pointer to the target byte
*/
static void setMask(void* byte) { *(reinterpret_cast<unsigned char*>(byte)) = 0xFF; }
};
}
+120 -2
View File
@@ -20,6 +20,29 @@
21384BC52CD24AB200D4602B /* ElementSubscriber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21384BC12CD24AB200D4602B /* ElementSubscriber.cpp */; };
21384BC62CD24AB200D4602B /* ElementSubscriber.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384BC42CD24AB200D4602B /* ElementSubscriber.h */; };
21384BC82CD24ADC00D4602B /* ElementEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384BC72CD24ADC00D4602B /* ElementEvent.h */; };
21384BE82CD3DD6200D4602B /* MaterialQuantity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21384BE32CD3DD6200D4602B /* MaterialQuantity.cpp */; };
21384BE92CD3DD6200D4602B /* MaterialQuantity.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384BE42CD3DD6200D4602B /* MaterialQuantity.h */; };
21384BEC2CD3EBE200D4602B /* Material.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384BEA2CD3EBE200D4602B /* Material.h */; };
21384BED2CD3EBE200D4602B /* Material.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21384BEB2CD3EBE200D4602B /* Material.cpp */; };
21384BF02CD3F3A500D4602B /* MaterialWrap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21384BEE2CD3F3A500D4602B /* MaterialWrap.cpp */; };
21384BF12CD3F3A500D4602B /* MaterialWrap.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384BEF2CD3F3A500D4602B /* MaterialWrap.h */; };
21384BF42CD4D65700D4602B /* Surveyor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21384BF22CD4D65700D4602B /* Surveyor.cpp */; };
21384BF52CD4D65700D4602B /* Surveyor.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384BF32CD4D65700D4602B /* Surveyor.h */; };
21384BF82CD50CD400D4602B /* TypeSetting.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384BF62CD50CD400D4602B /* TypeSetting.h */; };
21384BFA2CD51B6F00D4602B /* TypeSetting.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21384BF92CD51B6F00D4602B /* TypeSetting.cpp */; };
21384BFC2CD52C7500D4602B /* Conversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384BFB2CD52C7500D4602B /* Conversion.h */; };
21384BFF2CD558D100D4602B /* Slab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21384BFD2CD558D000D4602B /* Slab.cpp */; };
21384C002CD558D100D4602B /* Slab.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384BFE2CD558D000D4602B /* Slab.h */; };
21384C032CD57CA500D4602B /* Wall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21384C012CD57CA500D4602B /* Wall.cpp */; };
21384C042CD57CA500D4602B /* Wall.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384C022CD57CA500D4602B /* Wall.h */; };
21384C182CD585A600D4602B /* Roof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21384C162CD585A600D4602B /* Roof.cpp */; };
21384C192CD585A600D4602B /* Roof.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384C172CD585A600D4602B /* Roof.h */; };
21384C1C2CD586D800D4602B /* Morph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21384C1A2CD586D800D4602B /* Morph.cpp */; };
21384C1D2CD586D800D4602B /* Morph.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384C1B2CD586D800D4602B /* Morph.h */; };
21384C202CD5880400D4602B /* Shell.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384C1E2CD5880400D4602B /* Shell.h */; };
21384C212CD5880400D4602B /* Shell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21384C1F2CD5880400D4602B /* Shell.cpp */; };
21384C242CD59B4100D4602B /* MeshElem.h in Headers */ = {isa = PBXBuildFile; fileRef = 21384C222CD59B4100D4602B /* MeshElem.h */; };
21384C252CD59B4100D4602B /* MeshElem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21384C232CD59B4100D4602B /* MeshElem.cpp */; };
215F08552C99DA8D00CD343B /* Project.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 215F08512C99DA8D00CD343B /* Project.cpp */; };
215F08562C99DA8D00CD343B /* Project.h in Headers */ = {isa = PBXBuildFile; fileRef = 215F08542C99DA8D00CD343B /* Project.h */; };
215F08662C9B006800CD343B /* ProjectEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 215F08652C9B006700CD343B /* ProjectEvent.cpp */; };
@@ -206,6 +229,29 @@
21384BC12CD24AB200D4602B /* ElementSubscriber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ElementSubscriber.cpp; sourceTree = "<group>"; };
21384BC42CD24AB200D4602B /* ElementSubscriber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementSubscriber.h; sourceTree = "<group>"; };
21384BC72CD24ADC00D4602B /* ElementEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementEvent.h; sourceTree = "<group>"; };
21384BE32CD3DD6200D4602B /* MaterialQuantity.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MaterialQuantity.cpp; sourceTree = "<group>"; };
21384BE42CD3DD6200D4602B /* MaterialQuantity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MaterialQuantity.h; sourceTree = "<group>"; };
21384BEA2CD3EBE200D4602B /* Material.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Material.h; sourceTree = "<group>"; };
21384BEB2CD3EBE200D4602B /* Material.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Material.cpp; sourceTree = "<group>"; };
21384BEE2CD3F3A500D4602B /* MaterialWrap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MaterialWrap.cpp; sourceTree = "<group>"; };
21384BEF2CD3F3A500D4602B /* MaterialWrap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MaterialWrap.h; sourceTree = "<group>"; };
21384BF22CD4D65700D4602B /* Surveyor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Surveyor.cpp; sourceTree = "<group>"; };
21384BF32CD4D65700D4602B /* Surveyor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Surveyor.h; sourceTree = "<group>"; };
21384BF62CD50CD400D4602B /* TypeSetting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeSetting.h; sourceTree = "<group>"; };
21384BF92CD51B6F00D4602B /* TypeSetting.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypeSetting.cpp; sourceTree = "<group>"; };
21384BFB2CD52C7500D4602B /* Conversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Conversion.h; sourceTree = "<group>"; };
21384BFD2CD558D000D4602B /* Slab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Slab.cpp; sourceTree = "<group>"; };
21384BFE2CD558D000D4602B /* Slab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Slab.h; sourceTree = "<group>"; };
21384C012CD57CA500D4602B /* Wall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Wall.cpp; sourceTree = "<group>"; };
21384C022CD57CA500D4602B /* Wall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Wall.h; sourceTree = "<group>"; };
21384C162CD585A600D4602B /* Roof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Roof.cpp; sourceTree = "<group>"; };
21384C172CD585A600D4602B /* Roof.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Roof.h; sourceTree = "<group>"; };
21384C1A2CD586D800D4602B /* Morph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Morph.cpp; sourceTree = "<group>"; };
21384C1B2CD586D800D4602B /* Morph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Morph.h; sourceTree = "<group>"; };
21384C1E2CD5880400D4602B /* Shell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Shell.h; sourceTree = "<group>"; };
21384C1F2CD5880400D4602B /* Shell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Shell.cpp; sourceTree = "<group>"; };
21384C222CD59B4100D4602B /* MeshElem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MeshElem.h; sourceTree = "<group>"; };
21384C232CD59B4100D4602B /* MeshElem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MeshElem.cpp; sourceTree = "<group>"; };
214EA4C52BA374FD008E5358 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
214EA4C62BA3762D008E5358 /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = SOURCE_ROOT; };
215F08512C99DA8D00CD343B /* Project.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Project.cpp; sourceTree = "<group>"; };
@@ -257,6 +303,7 @@
2196F3022CB57E7F00450DFC /* Storey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Storey.h; sourceTree = "<group>"; };
2196F3032CB57E7F00450DFC /* Storey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Storey.cpp; sourceTree = "<group>"; };
219712682BE7E2D500D9EF7E /* Serialisation.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = Serialisation.md; sourceTree = "<group>"; };
2199BB5F2CDB761B00A4BEEC /* ElementStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementStorage.h; sourceTree = "<group>"; };
21A0FB9F2CB880690023F24E /* FinishCollector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FinishCollector.h; sourceTree = "<group>"; };
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>"; };
@@ -455,6 +502,29 @@
name = Products;
sourceTree = "<group>";
};
21384BE52CD3DD6200D4602B /* Quants */ = {
isa = PBXGroup;
children = (
21384BE32CD3DD6200D4602B /* MaterialQuantity.cpp */,
21384BE42CD3DD6200D4602B /* MaterialQuantity.h */,
21384BEE2CD3F3A500D4602B /* MaterialWrap.cpp */,
21384BEF2CD3F3A500D4602B /* MaterialWrap.h */,
21384BF22CD4D65700D4602B /* Surveyor.cpp */,
21384BF32CD4D65700D4602B /* Surveyor.h */,
);
path = Quants;
sourceTree = "<group>";
};
21384BF72CD50CD400D4602B /* Setting */ = {
isa = PBXGroup;
children = (
21384BFB2CD52C7500D4602B /* Conversion.h */,
21384BF92CD51B6F00D4602B /* TypeSetting.cpp */,
21384BF62CD50CD400D4602B /* TypeSetting.h */,
);
path = Setting;
sourceTree = "<group>";
};
215F08612C9AE3D200CD343B /* RINT */ = {
isa = PBXGroup;
children = (
@@ -482,11 +552,25 @@
21A890CB2CC1B87B0087E732 /* GenericDrawingElement.h */,
21A890CD2CC1B87C0087E732 /* GenericModelElement.cpp */,
21A890CC2CC1B87B0087E732 /* GenericModelElement.h */,
21A0FC0C2CBE92F10023F24E /* ModelElement.cpp */,
21A0FC0D2CBE92F10023F24E /* ModelElement.h */,
21A0FBE72CBD6B1A0023F24E /* Interface */,
21A0FBF32CBD6B700023F24E /* Memo.cpp */,
21A0FBF22CBD6B700023F24E /* Memo.h */,
21384C232CD59B4100D4602B /* MeshElem.cpp */,
21384C222CD59B4100D4602B /* MeshElem.h */,
21A0FC0C2CBE92F10023F24E /* ModelElement.cpp */,
21A0FC0D2CBE92F10023F24E /* ModelElement.h */,
21384C1A2CD586D800D4602B /* Morph.cpp */,
21384C1B2CD586D800D4602B /* Morph.h */,
21384BE52CD3DD6200D4602B /* Quants */,
21384C162CD585A600D4602B /* Roof.cpp */,
21384C172CD585A600D4602B /* Roof.h */,
21384BF72CD50CD400D4602B /* Setting */,
21384C1F2CD5880400D4602B /* Shell.cpp */,
21384C1E2CD5880400D4602B /* Shell.h */,
21384BFD2CD558D000D4602B /* Slab.cpp */,
21384BFE2CD558D000D4602B /* Slab.h */,
21384C012CD57CA500D4602B /* Wall.cpp */,
21384C022CD57CA500D4602B /* Wall.h */,
);
path = Element;
sourceTree = "<group>";
@@ -609,6 +693,8 @@
2196F2EE2CB4823C00450DFC /* Attribute.h */,
2196F2F32CB483D600450DFC /* Finish.cpp */,
2196F2F22CB483D600450DFC /* Finish.h */,
21384BEB2CD3EBE200D4602B /* Material.cpp */,
21384BEA2CD3EBE200D4602B /* Material.h */,
2196F3032CB57E7F00450DFC /* Storey.cpp */,
2196F3022CB57E7F00450DFC /* Storey.h */,
);
@@ -623,6 +709,14 @@
path = SpeckleLibDoctest;
sourceTree = "<group>";
};
2199BB602CDB761B00A4BEEC /* Element */ = {
isa = PBXGroup;
children = (
2199BB5F2CDB761B00A4BEEC /* ElementStorage.h */,
);
path = Element;
sourceTree = "<group>";
};
21A0FBA02CB880690023F24E /* Collection */ = {
isa = PBXGroup;
children = (
@@ -801,6 +895,7 @@
21D0BDB02C8F8AB60077E104 /* Storage */ = {
isa = PBXGroup;
children = (
2199BB602CDB761B00A4BEEC /* Element */,
215F088A2CA195EC00CD343B /* ArchicadDBase */,
21D0BDAF2C8F8AB60077E104 /* DocumentStore */,
);
@@ -937,6 +1032,7 @@
21A0FBF42CBD6B700023F24E /* Memo.h in Headers */,
215F088C2CA195EC00CD343B /* ArchicadDBaseCore.h in Headers */,
21AE19AD2CC8F214004DBCFC /* SegmentedBeam.h in Headers */,
21384C1D2CD586D800D4602B /* Morph.h in Headers */,
21D0BDE72C943D3F0077E104 /* RecordID.h in Headers */,
21D0BD212C86F0280077E104 /* AccountDatabase.h in Headers */,
21A0FBB52CBA5E380023F24E /* Str256.h in Headers */,
@@ -949,6 +1045,7 @@
21B67D0D2C7E0E8D00FD64FC /* ErrorReport.h in Headers */,
21AE19A92CC8F1F8004DBCFC /* Beam.h in Headers */,
215F08962CA19AF800CD343B /* BIMElementDatabase.h in Headers */,
21384BEC2CD3EBE200D4602B /* Material.h in Headers */,
2196F2F12CB4823C00450DFC /* Attribute.h in Headers */,
21D0BD332C86FE090077E104 /* Link.h in Headers */,
21AE19612CC2D358004DBCFC /* Setting.h in Headers */,
@@ -956,18 +1053,22 @@
21A890C92CC1B5FF0087E732 /* DrawingElement.h in Headers */,
21D0BD562C890B1C0077E104 /* ServerMigration.h in Headers */,
210CC88F2C81A98500610F58 /* Guid64.h in Headers */,
21384C242CD59B4100D4602B /* MeshElem.h in Headers */,
21AEF9DD2CAAA4EA000B8681 /* DetachedObjectStore.h in Headers */,
21A0FBF12CBD6B1A0023F24E /* Column.h in Headers */,
21AE19662CC2F702004DBCFC /* BIMPropertyDatabase.h in Headers */,
21A0FC072CBE59A80023F24E /* Path.h in Headers */,
21A0FBA42CB880690023F24E /* FinishCollector.h in Headers */,
21384C192CD585A600D4602B /* Roof.h in Headers */,
21AE19802CC7D265004DBCFC /* PropertiedWrapper.h in Headers */,
21A0FC0B2CBE5E220023F24E /* Segment.h in Headers */,
215F088D2CA195EC00CD343B /* ArchicadElementDBaseEngine.h in Headers */,
21384BC82CD24ADC00D4602B /* ElementEvent.h in Headers */,
21384C202CD5880400D4602B /* Shell.h in Headers */,
2196F2F42CB483D600450DFC /* Finish.h in Headers */,
21A0FBED2CBD6B1A0023F24E /* Part.h in Headers */,
21B67D002C7CE15100FD64FC /* Exception.h in Headers */,
21384BF52CD4D65700D4602B /* Surveyor.h in Headers */,
21A0FBEB2CBD6B1A0023F24E /* ColumnSegment.h in Headers */,
21D0BD2C2C86FC350077E104 /* Record.h in Headers */,
21D0BDB42C8F8AB60077E104 /* DocumentStoreCore.h in Headers */,
@@ -980,20 +1081,26 @@
21AE198F2CC80541004DBCFC /* ArchicadGroupDBaseEngine.h in Headers */,
21D0BD4D2C8901A00077E104 /* ServerInfo.h in Headers */,
2196F3042CB57E8000450DFC /* Storey.h in Headers */,
21384C042CD57CA500D4602B /* Wall.h in Headers */,
21AE196F2CC64D37004DBCFC /* Classified.h in Headers */,
21AE19522CC273F1004DBCFC /* Property.h in Headers */,
21A0FBF92CBDB9A70023F24E /* BIMMemory.h in Headers */,
21AE19AA2CC8F1F8004DBCFC /* BeamSegment.h in Headers */,
21384BF12CD3F3A500D4602B /* MaterialWrap.h in Headers */,
21AE19942CC82866004DBCFC /* BIMGroupDatabase.h in Headers */,
21AE19542CC273F1004DBCFC /* Template.h in Headers */,
21A0FBBC2CBBC04C0023F24E /* ArchicadRGB.h in Headers */,
21384BFC2CD52C7500D4602B /* Conversion.h in Headers */,
21AE19842CC7D517004DBCFC /* PropertyWrapper.h in Headers */,
21A0FC052CBE59A80023F24E /* SegmentedColumn.h in Headers */,
21A0FC0F2CBE92F10023F24E /* ModelElement.h in Headers */,
21D0BDB52C8F8AB60077E104 /* DocumentStoreEngine.h in Headers */,
21384BE92CD3DD6200D4602B /* MaterialQuantity.h in Headers */,
21A890D02CC1B87C0087E732 /* GenericModelElement.h in Headers */,
21384C002CD558D100D4602B /* Slab.h in Headers */,
21A890C52CC171D80087E732 /* ArchicadPropertyDBaseEngine.h in Headers */,
21384BAB2CCDA9B400D4602B /* Host.h in Headers */,
21384BF82CD50CD400D4602B /* TypeSetting.h in Headers */,
21D0BDC52C9241940077E104 /* ProjectSubscriber.h in Headers */,
21AE196A2CC57832004DBCFC /* Propertied.h in Headers */,
2196F2EC2CB4816B00450DFC /* ArchicadAttributeDBaseEngine.h in Headers */,
@@ -1133,6 +1240,7 @@
215F088B2CA195EC00CD343B /* ArchicadDBaseCore.cpp in Sources */,
2193517B2C624FC100E5A69C /* MenuSubscriber.cpp in Sources */,
2196F2F02CB4823C00450DFC /* Attribute.cpp in Sources */,
21384C032CD57CA500D4602B /* Wall.cpp in Sources */,
21F69F612C6D0286008B6A06 /* GetBindingsMethodNames.cpp in Sources */,
215F08662C9B006800CD343B /* ProjectEvent.cpp in Sources */,
21AE19932CC82866004DBCFC /* BIMGroupDatabase.cpp in Sources */,
@@ -1147,6 +1255,8 @@
2196F2F82CB51ED400450DFC /* BIMAttributeDatabase.cpp in Sources */,
21D0BD4E2C8901A00077E104 /* ServerInfo.cpp in Sources */,
21AE19512CC273F1004DBCFC /* Property.cpp in Sources */,
21384BED2CD3EBE200D4602B /* Material.cpp in Sources */,
21384C252CD59B4100D4602B /* MeshElem.cpp in Sources */,
21B67D0E2C7E0E8D00FD64FC /* ErrorReport.cpp in Sources */,
21AE19902CC80541004DBCFC /* ArchicadGroupDBaseEngine.cpp in Sources */,
21AE19692CC57832004DBCFC /* Propertied.cpp in Sources */,
@@ -1154,13 +1264,16 @@
2196F3052CB57E8000450DFC /* Storey.cpp in Sources */,
219245FE2CA2CC4300CF5703 /* BIMRecord.cpp in Sources */,
21AE19572CC27DB3004DBCFC /* Value.cpp in Sources */,
21384BFF2CD558D100D4602B /* Slab.cpp in Sources */,
21AE19A82CC8F1F8004DBCFC /* BeamSegment.cpp in Sources */,
21AEF9BE2CA6FDA4000B8681 /* DetachedWrap.cpp in Sources */,
21A0FC062CBE59A80023F24E /* Path.cpp in Sources */,
2196F2F52CB483D600450DFC /* Finish.cpp in Sources */,
21A0FBEA2CBD6B1A0023F24E /* ColumnSegment.cpp in Sources */,
21384BFA2CD51B6F00D4602B /* TypeSetting.cpp in Sources */,
2193519B2C6278D900E5A69C /* SelectionSubscriber.cpp in Sources */,
21D0BD2B2C86FC350077E104 /* Record.cpp in Sources */,
21384BF02CD3F3A500D4602B /* MaterialWrap.cpp in Sources */,
219246042CA2CE2700CF5703 /* BIMLink.cpp in Sources */,
21A890CE2CC1B87C0087E732 /* GenericDrawingElement.cpp in Sources */,
215F08952CA19AF800CD343B /* BIMElementDatabase.cpp in Sources */,
@@ -1175,17 +1288,21 @@
21D0BD592C8910400077E104 /* UserInfo.cpp in Sources */,
210CC8902C81A98500610F58 /* Guid64.cpp in Sources */,
21D0BDC42C9241940077E104 /* ProjectSubscriber.cpp in Sources */,
21384BE82CD3DD6200D4602B /* MaterialQuantity.cpp in Sources */,
21AE19622CC2D358004DBCFC /* Setting.cpp in Sources */,
219351B32C62CC1A00E5A69C /* String.cpp in Sources */,
219351B12C62CC1A00E5A69C /* Guid.cpp in Sources */,
21F69F512C6CCC25008B6A06 /* BrowserBridge.cpp in Sources */,
21A0FC112CBEE5C30023F24E /* Part.cpp in Sources */,
21384C212CD5880400D4602B /* Shell.cpp in Sources */,
21A890D12CC1B87C0087E732 /* GenericModelElement.cpp in Sources */,
21AEF9BC2CA6DF84000B8681 /* DetachmentManager.cpp in Sources */,
215F08552C99DA8D00CD343B /* Project.cpp in Sources */,
21AE19882CC7FF5F004DBCFC /* Group.cpp in Sources */,
21384C182CD585A600D4602B /* Roof.cpp in Sources */,
21F69F3B2C6B880C008B6A06 /* JSBaseTransport.cpp in Sources */,
21384BC52CD24AB200D4602B /* ElementSubscriber.cpp in Sources */,
21384BF42CD4D65700D4602B /* Surveyor.cpp in Sources */,
2196F2EB2CB4816B00450DFC /* ArchicadAttributeDBaseEngine.cpp in Sources */,
21AE19532CC273F1004DBCFC /* Template.cpp in Sources */,
21384BAC2CCDA9B400D4602B /* Host.cpp in Sources */,
@@ -1196,6 +1313,7 @@
21F69F962C71087A008B6A06 /* Account.cpp in Sources */,
21A0FBF82CBDB9A70023F24E /* BIMMemory.cpp in Sources */,
21A0FBF52CBD6B700023F24E /* Memo.cpp in Sources */,
21384C1C2CD586D800D4602B /* Morph.cpp in Sources */,
21AEF9BA2CA606B5000B8681 /* DetachedReference.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
+26 -2
View File
@@ -38,6 +38,7 @@
<ClInclude Include="Speckle\Database\Storage\ArchicadDBase\Property\ArchicadPropertyDBaseEngine.h" />
<ClInclude Include="Speckle\Database\Storage\DocumentStore\DocumentStoreCore.h" />
<ClInclude Include="Speckle\Database\Storage\DocumentStore\DocumentStoreEngine.h" />
<ClInclude Include="Speckle\Database\Storage\Element\ElementStorage.h" />
<ClInclude Include="Speckle\Environment\Addon.h" />
<ClInclude Include="Speckle\Environment\Host.h" />
<ClInclude Include="Speckle\Environment\Platform.h" />
@@ -72,6 +73,7 @@
<ClInclude Include="Speckle\Primitive\Mesh\Mesh.h" />
<ClInclude Include="Speckle\Record\Attribute\Attribute.h" />
<ClInclude Include="Speckle\Record\Attribute\Finish.h" />
<ClInclude Include="Speckle\Record\Attribute\Material.h" />
<ClInclude Include="Speckle\Record\Attribute\Storey.h" />
<ClInclude Include="Speckle\Record\Classification\Classified.h" />
<ClInclude Include="Speckle\Record\Credentials\Account.h" />
@@ -92,7 +94,18 @@
<ClInclude Include="Speckle\Record\Element\Interface\SegmentedBeam.h" />
<ClInclude Include="Speckle\Record\Element\Interface\SegmentedColumn.h" />
<ClInclude Include="Speckle\Record\Element\Memo.h" />
<ClInclude Include="Speckle\Record\Element\MeshElem.h" />
<ClInclude Include="Speckle\Record\Element\ModelElement.h" />
<ClInclude Include="Speckle\Record\Element\Morph.h" />
<ClInclude Include="Speckle\Record\Element\Quants\MaterialQuantity.h" />
<ClInclude Include="Speckle\Record\Element\Quants\MaterialWrap.h" />
<ClInclude Include="Speckle\Record\Element\Quants\Surveyor.h" />
<ClInclude Include="Speckle\Record\Element\Roof.h" />
<ClInclude Include="Speckle\Record\Element\Setting\Conversion.h" />
<ClInclude Include="Speckle\Record\Element\Setting\TypeSetting.h" />
<ClInclude Include="Speckle\Record\Element\Shell.h" />
<ClInclude Include="Speckle\Record\Element\Slab.h" />
<ClInclude Include="Speckle\Record\Element\Wall.h" />
<ClInclude Include="Speckle\Record\Property\Group.h" />
<ClInclude Include="Speckle\Record\Property\Propertied.h" />
<ClInclude Include="Speckle\Record\Property\Property.h" />
@@ -156,6 +169,7 @@
<ClCompile Include="Speckle\Primitive\Mesh\Mesh.cpp" />
<ClCompile Include="Speckle\Record\Attribute\Attribute.cpp" />
<ClCompile Include="Speckle\Record\Attribute\Finish.cpp" />
<ClCompile Include="Speckle\Record\Attribute\Material.cpp" />
<ClCompile Include="Speckle\Record\Attribute\Storey.cpp" />
<ClCompile Include="Speckle\Record\Classification\Classified.cpp" />
<ClCompile Include="Speckle\Record\Credentials\Account.cpp" />
@@ -176,7 +190,17 @@
<ClCompile Include="Speckle\Record\Element\Interface\SegmentedBeam.cpp" />
<ClCompile Include="Speckle\Record\Element\Interface\SegmentedColumn.cpp" />
<ClCompile Include="Speckle\Record\Element\Memo.cpp" />
<ClCompile Include="Speckle\Record\Element\MeshElem.cpp" />
<ClCompile Include="Speckle\Record\Element\ModelElement.cpp" />
<ClCompile Include="Speckle\Record\Element\Morph.cpp" />
<ClCompile Include="Speckle\Record\Element\Quants\MaterialQuantity.cpp" />
<ClCompile Include="Speckle\Record\Element\Quants\MaterialWrap.cpp" />
<ClCompile Include="Speckle\Record\Element\Quants\Surveyor.cpp" />
<ClCompile Include="Speckle\Record\Element\Roof.cpp" />
<ClCompile Include="Speckle\Record\Element\Setting\TypeSetting.cpp" />
<ClCompile Include="Speckle\Record\Element\Shell.cpp" />
<ClCompile Include="Speckle\Record\Element\Slab.cpp" />
<ClCompile Include="Speckle\Record\Element\Wall.cpp" />
<ClCompile Include="Speckle\Record\Property\Group.cpp" />
<ClCompile Include="Speckle\Record\Property\Propertied.cpp" />
<ClCompile Include="Speckle\Record\Property\Property.cpp" />
@@ -325,7 +349,7 @@
<WarningLevel>Level3</WarningLevel>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>DEBUG;WINDOWS;ARCHICAD;ACExtension;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>DEBUG;WINDOWS;ARCHICAD;ACExtension;_SILENCE_CXX20_IS_POD_DEPRECATION_WARNING;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>
@@ -365,7 +389,7 @@
<FunctionLevelLinking>false</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WINDOWS;ARCHICAD;ACExtension;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WINDOWS;ARCHICAD;ACExtension;_SILENCE_CXX20_IS_POD_DEPRECATION_WARNING;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>
+81
View File
@@ -116,6 +116,15 @@
<Filter Include="Speckle\Database\Storage\ArchicadDBase\Property">
<UniqueIdentifier>{f9b0554b-d0a5-40c0-ac20-22032dc8f30c}</UniqueIdentifier>
</Filter>
<Filter Include="Speckle\Record\Element\Setting">
<UniqueIdentifier>{453f429b-4ca8-400b-b60c-df80c6d0ec5f}</UniqueIdentifier>
</Filter>
<Filter Include="Speckle\Record\Element\Quants">
<UniqueIdentifier>{c05efdee-e236-4db7-9338-a982c9cc673f}</UniqueIdentifier>
</Filter>
<Filter Include="Speckle\Database\Storage\Element">
<UniqueIdentifier>{f4cd84a1-f6c1-449f-98cd-d902cc3d9e8c}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Speckle\Environment\Addon.h">
@@ -421,6 +430,45 @@
<ClInclude Include="Speckle\Event\Subscriber\ElementSubscriber.h">
<Filter>Speckle\Event\Subscriber</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Attribute\Material.h">
<Filter>Speckle\Record\Attribute</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Quants\MaterialQuantity.h">
<Filter>Speckle\Record\Element\Quants</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Quants\MaterialWrap.h">
<Filter>Speckle\Record\Element\Quants</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Quants\Surveyor.h">
<Filter>Speckle\Record\Element\Quants</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Setting\Conversion.h">
<Filter>Speckle\Record\Element\Setting</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Setting\TypeSetting.h">
<Filter>Speckle\Record\Element\Setting</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\MeshElem.h">
<Filter>Speckle\Record\Element</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Morph.h">
<Filter>Speckle\Record\Element</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Roof.h">
<Filter>Speckle\Record\Element</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Shell.h">
<Filter>Speckle\Record\Element</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Slab.h">
<Filter>Speckle\Record\Element</Filter>
</ClInclude>
<ClInclude Include="Speckle\Record\Element\Wall.h">
<Filter>Speckle\Record\Element</Filter>
</ClInclude>
<ClInclude Include="Speckle\Database\Storage\Element\ElementStorage.h">
<Filter>Speckle\Database\Storage\Element</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Speckle\Environment\Addon.cpp">
@@ -642,6 +690,39 @@
<ClCompile Include="Speckle\Event\Subscriber\ElementSubscriber.cpp">
<Filter>Speckle\Event\Subscriber</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Attribute\Material.cpp">
<Filter>Speckle\Record\Attribute</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Quants\MaterialQuantity.cpp">
<Filter>Speckle\Record\Element\Quants</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Quants\MaterialWrap.cpp">
<Filter>Speckle\Record\Element\Quants</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Quants\Surveyor.cpp">
<Filter>Speckle\Record\Element\Quants</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Setting\TypeSetting.cpp">
<Filter>Speckle\Record\Element\Setting</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\MeshElem.cpp">
<Filter>Speckle\Record\Element</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Morph.cpp">
<Filter>Speckle\Record\Element</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Roof.cpp">
<Filter>Speckle\Record\Element</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Shell.cpp">
<Filter>Speckle\Record\Element</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Slab.cpp">
<Filter>Speckle\Record\Element</Filter>
</ClCompile>
<ClCompile Include="Speckle\Record\Element\Wall.cpp">
<Filter>Speckle\Record\Element</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="Speckle\CMakeLists.txt">