Skip to content

Commit

Permalink
feat(Archicad): Revit add support for Zones - Archicad side (speckles…
Browse files Browse the repository at this point in the history
…ystems#2877)

* Revit add support for Zones - Archicad side
* build fix
---------
Co-authored-by: József L. Kiss <>
  • Loading branch information
jozseflkiss authored Sep 5, 2023
1 parent 70b6010 commit 7bd5988
Show file tree
Hide file tree
Showing 13 changed files with 271 additions and 85 deletions.
4 changes: 2 additions & 2 deletions ConnectorArchicad/AddOn/Sources/AddOn/AddOnMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
#include "Commands/GetElementBaseData.hpp"
#include "Commands/GetObjectData.hpp"
#include "Commands/GetSlabData.hpp"
#include "Commands/GetRoomData.hpp"
#include "Commands/GetRoofData.hpp"
#include "Commands/GetShellData.hpp"
#include "Commands/GetSkylightData.hpp"
#include "Commands/GetProjectInfo.hpp"
#include "Commands/GetSubElementInfo.hpp"
#include "Commands/GetZoneData.hpp"
#include "Commands/CreateWall.hpp"
#include "Commands/CreateDoor.hpp"
#include "Commands/CreateWindow.hpp"
Expand Down Expand Up @@ -198,12 +198,12 @@ static GSErrCode RegisterAddOnCommands ()
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetColumnData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetElementBaseData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetObjectData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetRoomData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetRoofData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetShellData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetSkylightData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetSlabData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetProjectInfo> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetZoneData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::CreateWall> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::CreateDoor> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::CreateWindow> ()));
Expand Down
11 changes: 9 additions & 2 deletions ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateZone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ GSErrCode CreateZone::GetElementFromObjectState (const GS::ObjectState& os,
ACAPI_ELEMENT_MASK_SET (mask, API_ZoneType, poly.nArcs);

zoneShape.SetToMemo (memo, Objects::ElementShape::MemoMainPolygon);

element.zone.manual = true;
ACAPI_ELEMENT_MASK_SET (mask, API_ZoneType, manual);
}

if (os.Contains (Room::Height)) {
Expand All @@ -68,11 +71,15 @@ GSErrCode CreateZone::GetElementFromObjectState (const GS::ObjectState& os,

// The name and number of the zone
if (os.Contains (Room::Name)) {
os.Get (Room::Name, element.zone.roomName);
GS::UniString str;
os.Get (Room::Name, str);
GS::ucscpy (element.zone.roomName, str.ToUStr ());
ACAPI_ELEMENT_MASK_SET (mask, API_ZoneType, roomName);
}
if (os.Contains (Room::Number)) {
os.Get (Room::Number, element.zone.roomNoStr);
GS::UniString str;
os.Get (Room::Number, str);
GS::ucscpy (element.zone.roomNoStr, str.ToUStr ());
ACAPI_ELEMENT_MASK_SET (mask, API_ZoneType, roomNoStr);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "GetRoomData.hpp"
#include "GetZoneData.hpp"
#include <locale>
#include "ResourceIds.hpp"
#include "ObjectState.hpp"
Expand All @@ -14,19 +14,19 @@ namespace AddOnCommands
{


GS::String GetRoomData::GetFieldName () const
GS::String GetZoneData::GetFieldName () const
{
return Zones;
}


API_ElemTypeID GetRoomData::GetElemTypeID () const
API_ElemTypeID GetZoneData::GetElemTypeID () const
{
return API_ZoneID;
}


GS::ErrCode GetRoomData::SerializeElementType (const API_Element& element,
GS::ErrCode GetZoneData::SerializeElementType (const API_Element& element,
const API_ElementMemo& memo,
GS::ObjectState& os) const
{
Expand Down Expand Up @@ -60,30 +60,39 @@ GS::ErrCode GetRoomData::SerializeElementType (const API_Element& element,

// The base point of the room
double level = Utility::GetStoryLevel (element.zone.head.floorInd) + element.zone.roomBaseLev;
os.Add (Room::BasePoint, Objects::Point3D (0, 0, level));
{
Geometry::Polygon2DData polygon;
Utility::ConstructPoly2DDataFromElementMemo (memo, polygon);

const Box2DData boundingBox = polygon.boundBox;
GS::Array<Sector> sectors;
bool res = Geometry::IntersectLineWithPolygon (polygon,
boundingBox.GetMidPoint(),
boundingBox.GetWidth() > boundingBox.GetHeight() ? Vector2D (1.0, 0.0) : Vector2D (0.0, 1.0),
&sectors);

Geometry::FreePolygon2DData (&polygon);

Objects::Point3D basePoint (0, 0, level);
if (res && sectors.GetSize() > 0) {
Sector sector = sectors[sectors.GetSize() / 2];
basePoint = Objects::Point3D (sector.GetMidPoint ().GetX (), sector.GetMidPoint ().GetY (), level);
}

os.Add (Room::BasePoint, Objects::Point3D (basePoint.x, basePoint.y, basePoint.z));
}
os.Add (ElementBase::Shape, Objects::ElementShape (element.zone.poly, memo, Objects::ElementShape::MemoMainPolygon, level));

// double polyCoords [zone.poly.nCoords*3];
//
// for (Int32 point_index = 0, coord_index = 0; point_index < zone.poly.nCoords; ++point_index, coord_index+=3)
// {
// const API_Coord coord = (*memo.coords)[point_index];
// polyCoords[coord_index] = coord.x;
// polyCoords[coord_index+1] = coord.y;
// polyCoords[coord_index+2] = level;
// }

// Room Props
os.Add (Room::Height, element.zone.roomHeight);
os.Add (Room::Area, quantity.zone.area);
os.Add (Room::Volume, quantity.zone.volume);


return NoError;
}


GS::String GetRoomData::GetName () const
GS::String GetZoneData::GetName () const
{
return GetRoomDataCommandName;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef GET_ROOM_DATA_HPP
#ifndef GET_ROOM_DATA_HPP
#define GET_ROOM_DATA_HPP

#include "GetDataCommand.hpp"
Expand All @@ -7,7 +7,7 @@
namespace AddOnCommands {


class GetRoomData : public GetDataCommand {
class GetZoneData : public GetDataCommand {
GS::String GetFieldName () const override;
API_ElemTypeID GetElemTypeID () const override;
GS::ErrCode SerializeElementType (const API_Element& elem,
Expand All @@ -22,4 +22,4 @@ class GetRoomData : public GetDataCommand {
}


#endif
#endif
49 changes: 49 additions & 0 deletions ConnectorArchicad/AddOn/Sources/AddOn/Utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "FieldNames.hpp"
#include "TypeNameTables.hpp"
#include "ResourceStrings.hpp"
#include "Polygon2DData.h"
using namespace FieldNames;

namespace Utility {
Expand Down Expand Up @@ -1157,4 +1158,52 @@ GSErrCode CreateTransform (const GS::ObjectState& os, API_Tranmat& transform)
return NoError;
}


GSErrCode ConstructPoly2DDataFromElementMemo (const API_ElementMemo& memo, Geometry::Polygon2DData& polygon2DData)
{
GSErrCode err = NoError;

Geometry::InitPolygon2DData (&polygon2DData);

static_assert (sizeof (API_Coord) == sizeof (Coord), "sizeof (API_Coord) != sizeof (Coord)");
static_assert (sizeof (API_PolyArc) == sizeof (PolyArcRec), "sizeof (API_PolyArc) != sizeof (PolyArcRec)");

polygon2DData.nVertices = BMGetHandleSize (reinterpret_cast<GSHandle> (memo.coords)) / sizeof (Coord) - 1;
polygon2DData.vertices = reinterpret_cast<Coord**> (BMAllocateHandle ((polygon2DData.nVertices + 1) * sizeof (Coord), ALLOCATE_CLEAR, 0));
if (polygon2DData.vertices != nullptr)
BNCopyMemory (*polygon2DData.vertices, *memo.coords, (polygon2DData.nVertices + 1) * sizeof (Coord));
else
err = APIERR_MEMFULL;

if (err == NoError && memo.parcs != nullptr) {
polygon2DData.nArcs = BMGetHandleSize (reinterpret_cast<GSHandle> (memo.parcs)) / sizeof (PolyArcRec);
if (polygon2DData.nArcs > 0) {
polygon2DData.arcs = reinterpret_cast<PolyArcRec**> (BMAllocateHandle ((polygon2DData.nArcs + 1) * sizeof (PolyArcRec), ALLOCATE_CLEAR, 0));
if (polygon2DData.arcs != nullptr)
BNCopyMemory (*polygon2DData.arcs + 1, *memo.parcs, polygon2DData.nArcs * sizeof (PolyArcRec));
else
err = APIERR_MEMFULL;
}
}

if (err == NoError) {
polygon2DData.nContours = BMGetHandleSize (reinterpret_cast<GSHandle> (memo.pends)) / sizeof (Int32) - 1;
polygon2DData.contourEnds = reinterpret_cast<UIndex**> (BMAllocateHandle ((polygon2DData.nContours + 1) * sizeof (UIndex), ALLOCATE_CLEAR, 0));
if (polygon2DData.contourEnds != nullptr)
BNCopyMemory (*polygon2DData.contourEnds, *memo.pends, (polygon2DData.nContours + 1) * sizeof (UIndex));
else
err = APIERR_MEMFULL;
}

if (err == NoError) {
Geometry::GetPolygon2DDataBoundBox (polygon2DData, &polygon2DData.boundBox);
polygon2DData.status.isBoundBoxValid = true;
} else {
Geometry::FreePolygon2DData (&polygon2DData);
}

return err;
}


}
4 changes: 4 additions & 0 deletions ConnectorArchicad/AddOn/Sources/AddOn/Utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "APIEnvir.h"
#include "ACAPinc.h"
#include "ResourceIds.hpp"
#include "Polygon2DData.h"

#define UNUSED(x) (void)(x)

Expand Down Expand Up @@ -86,6 +87,9 @@ GS::UniString ComposeLogMessage (const Int32 resourceIndex, Args... args)
return GS::UniString::Printf (errMsgFromatString, args...);
}

// Geometry helpers
GSErrCode ConstructPoly2DDataFromElementMemo (const API_ElementMemo& memo, Geometry::Polygon2DData& polygon2DData);

}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Threading.Tasks;
using Speckle.Core.Models;
using Speckle.Newtonsoft.Json;
using Objects.BuiltElements.Archicad;

namespace Archicad.Communication.Commands
{
Expand All @@ -12,9 +11,9 @@ sealed internal class CreateRoom : ICommand<IEnumerable<ApplicationObject>>
public sealed class Parameters
{
[JsonProperty("zones")]
private IEnumerable<ArchicadRoom> Datas { get; }
private IEnumerable<Archicad.Room> Datas { get; }

public Parameters(IEnumerable<ArchicadRoom> datas)
public Parameters(IEnumerable<Archicad.Room> datas)
{
Datas = datas;
}
Expand All @@ -27,9 +26,9 @@ private sealed class Result
public IEnumerable<ApplicationObject> ApplicationObjects { get; private set; }
}

private IEnumerable<ArchicadRoom> Datas { get; }
private IEnumerable<Archicad.Room> Datas { get; }

public CreateRoom(IEnumerable<ArchicadRoom> datas)
public CreateRoom(IEnumerable<Archicad.Room> datas)
{
Datas = datas;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Archicad.Communication.Commands
{
sealed internal class GetRoomData : ICommand<IEnumerable<ArchicadRoom>>
sealed internal class GetRoomData : ICommand<IEnumerable<Archicad.Room>>
{
[JsonObject(MemberSerialization.OptIn)]
public sealed class Parameters
Expand All @@ -24,7 +24,7 @@ public Parameters(IEnumerable<string> applicationIds)
private sealed class Result
{
[JsonProperty("zones")]
public IEnumerable<ArchicadRoom> Rooms { get; private set; }
public IEnumerable<Archicad.Room> Rooms { get; private set; }
}

private IEnumerable<string> ApplicationIds { get; }
Expand All @@ -34,11 +34,9 @@ public GetRoomData(IEnumerable<string> applicationIds)
ApplicationIds = applicationIds;
}

public async Task<IEnumerable<ArchicadRoom>> Execute()
public async Task<IEnumerable<Archicad.Room>> Execute()
{
var result = await HttpCommandExecutor.Execute<Parameters, Result>("GetRoomData", new Parameters(ApplicationIds));
foreach (var room in result.Rooms)
room.units = Units.Meters;

return result.Rooms;
}
Expand Down
Loading

0 comments on commit 7bd5988

Please sign in to comment.