Skip to content

Commit

Permalink
Merge pull request #170 from tlorantfy/FilterElements
Browse files Browse the repository at this point in the history
New commands: FilterElements and GetCurrentWindowType
  • Loading branch information
tlorantfy committed Aug 26, 2024
2 parents ec5858d + c798588 commit 0eacb85
Show file tree
Hide file tree
Showing 15 changed files with 390 additions and 26 deletions.
19 changes: 19 additions & 0 deletions archicad-addon/Examples/filter_elements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import aclib

allElements = aclib.RunCommand ('API.GetAllElements', {})['elements']
print ('All elements: {}'.format (len (allElements)))

for flag in ['IsEditable',
'IsVisibleByLayer',
'IsVisibleByRenovation',
'IsVisibleByStructureDisplay',
'IsVisibleIn3D',
'OnActualFloor',
'OnActualLayout',
'InMyWorkspace',
'IsIndependent',
'InCroppedView',
'HasAccessRight',
'IsOverriddenByRenovation']:
response = aclib.RunTapirCommand ('FilterElements', { 'elements': allElements, 'filters': [flag] })
print ('{} {}'.format (flag, len (response['filteredElements'])))
6 changes: 6 additions & 0 deletions archicad-addon/Examples/get_current_window.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import aclib
import json

response = aclib.RunTapirCommand ('GetCurrentWindowType', {})

print (json.dumps (response['currentWindowType'], indent = 4))
10 changes: 8 additions & 2 deletions archicad-addon/Sources/AddOnMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ GSErrCode Initialize (void)
applicationCommands, "0.1.0",
"Performs a quit operation on the currently running Archicad instance."
);
err |= RegisterCommand<GetCurrentWindowTypeCommand> (
applicationCommands, "1.0.7",
"Returns the type of the current (active) window."
);
gCommandGroups.push_back (applicationCommands);
}

Expand Down Expand Up @@ -140,6 +144,10 @@ GSErrCode Initialize (void)
elementCommands, "0.1.0",
"Gets the list of the currently selected elements."
);
err |= RegisterCommand<FilterElementsCommand> (
elementCommands, "1.0.7",
"Tests an elements by the given criterias."
);
err |= RegisterCommand<GetDetailsOfElementsCommand> (
elementCommands, "1.0.7",
"Gets the details of the given elements (geometry parameters etc)."
Expand All @@ -148,12 +156,10 @@ GSErrCode Initialize (void)
elementCommands, "1.0.6",
"Gets the subelements of the given hierarchical elements."
);
#ifdef ServerMainVers_2600
err |= RegisterCommand<HighlightElementsCommand> (
elementCommands, "1.0.3",
"Highlights the elements given in the elements array. In case of empty elements array removes all previously set highlights."
);
#endif
err |= RegisterCommand<MoveElementsCommand> (
elementCommands, "1.0.2",
"Moves elements with a given vector."
Expand Down
63 changes: 63 additions & 0 deletions archicad-addon/Sources/ApplicationCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,66 @@ GS::ObjectState QuitArchicadCommand::Execute (const GS::ObjectState& /*parameter

return {};
}

GetCurrentWindowTypeCommand::GetCurrentWindowTypeCommand () :
CommandBase (CommonSchema::Used)
{
}

GS::String GetCurrentWindowTypeCommand::GetName () const
{
return "GetCurrentWindowType";
}

GS::Optional<GS::UniString> GetCurrentWindowTypeCommand::GetResponseSchema () const
{
return R"({
"type": "object",
"properties": {
"currentWindowType": {
"$ref": "#/WindowType"
}
},
"additionalProperties": false,
"required": [
"currentWindowType"
]
})";
}

static GS::UniString ConvertWindowTypeToString (API_WindowTypeID type)
{
switch (type) {
case APIWind_FloorPlanID: return "FloorPlan";
case APIWind_SectionID: return "Section";
case APIWind_DetailID: return "Details";
case APIWind_3DModelID: return "3DModel";
case APIWind_LayoutID: return "Layout";
case APIWind_DrawingID: return "Drawing";
case APIWind_MyTextID: return "CustomText";
case APIWind_MyDrawID: return "CustomDraw";
case APIWind_MasterLayoutID: return "MasterLayout";
case APIWind_ElevationID: return "Elevation";
case APIWind_InteriorElevationID: return "InteriorElevation";
case APIWind_WorksheetID: return "Worksheet";
case APIWind_ReportID: return "Report";
case APIWind_DocumentFrom3DID: return "3DDocument";
case APIWind_External3DID: return "External3D";
case APIWind_Movie3DID: return "Movie3D";
case APIWind_MovieRenderingID: return "MovieRendering";
case APIWind_RenderingID: return "Rendering";
case APIWind_ModelCompareID: return "ModelCompare";
case APIWind_IESCommonDrawingID: return "Interactive Schedule";
default: return "Unknown";
}
}

GS::ObjectState GetCurrentWindowTypeCommand::Execute (const GS::ObjectState& /*parameters*/, GS::ProcessControl& /*processControl*/) const
{
API_WindowInfo windowInfo;
GSErrCode err = ACAPI_Window_GetCurrentWindow (&windowInfo);
if (err != NoError) {
return CreateErrorResponse (err, "Failed to get the current window!");
}
return GS::ObjectState ("currentWindowType", ConvertWindowTypeToString (windowInfo.typeID));
}
9 changes: 9 additions & 0 deletions archicad-addon/Sources/ApplicationCommands.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,12 @@ class QuitArchicadCommand : public CommandBase
virtual GS::String GetName () const override;
virtual GS::ObjectState Execute (const GS::ObjectState& parameters, GS::ProcessControl& processControl) const override;
};

class GetCurrentWindowTypeCommand : public CommandBase
{
public:
GetCurrentWindowTypeCommand ();
virtual GS::String GetName () const override;
virtual GS::Optional<GS::UniString> GetResponseSchema () const override;
virtual GS::ObjectState Execute (const GS::ObjectState& parameters, GS::ProcessControl& processControl) const override;
};
16 changes: 2 additions & 14 deletions archicad-addon/Sources/AttributeCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,13 +207,7 @@ GS::ObjectState CreateAttributesCommandBase::Execute (const GS::ObjectState& par
}
}

GS::ObjectState attributeId;
attributeId.Add ("guid", APIGuidToString (attr.header.guid));

GS::ObjectState attributeIdArrayItem;
attributeIdArrayItem.Add ("attributeId", attributeId);

attributeIds (attributeIdArrayItem);
attributeIds (CreateAttributeIdObjectState (attr.header.guid));
}

return response;
Expand Down Expand Up @@ -703,13 +697,7 @@ GS::ObjectState CreateCompositesCommand::Execute (const GS::ObjectState& paramet
}
}

GS::ObjectState attributeId;
attributeId.Add ("guid", APIGuidToString (composite.header.guid));

GS::ObjectState attributeIdArrayItem;
attributeIdArrayItem.Add ("attributeId", attributeId);

attributeIds (attributeIdArrayItem);
attributeIds (CreateAttributeIdObjectState (composite.header.guid));
ACAPI_DisposeAttrDefsHdlsExt (&compositeDefs);
}

Expand Down
5 changes: 5 additions & 0 deletions archicad-addon/Sources/CommandBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ GS::ObjectState Create2DCoordinateObjectState (const API_Coord& c)
return GS::ObjectState ("x", c.x, "y", c.y);
}

GS::ObjectState CreateIdObjectState (const GS::String& idFieldName, const API_Guid& guid)
{
return GS::ObjectState (idFieldName, GS::ObjectState ("guid", APIGuidToString (guid)));
}

API_Coord3D Get3DCoordinateFromObjectState (const GS::ObjectState& objectState)
{
API_Coord3D coordinate = {};
Expand Down
5 changes: 4 additions & 1 deletion archicad-addon/Sources/CommandBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ GS::ObjectState CreateSuccessfulExecutionResult ();

API_Guid GetGuidFromObjectState (const GS::ObjectState& os);
API_Coord Get2DCoordinateFromObjectState (const GS::ObjectState& objectState);
GS::ObjectState Create2DCoordinateObjectState (const API_Coord& c);
API_Coord3D Get3DCoordinateFromObjectState (const GS::ObjectState& objectState);
GS::ObjectState Create2DCoordinateObjectState (const API_Coord& c);
GS::ObjectState CreateIdObjectState (const GS::String& idFieldName, const API_Guid& guid);
inline GS::ObjectState CreateElementIdObjectState (const API_Guid& guid) { return CreateIdObjectState ("elementId", guid); }
inline GS::ObjectState CreateAttributeIdObjectState (const API_Guid& guid) { return CreateIdObjectState ("attributeId", guid); }

struct Story {
Story (short _index, double _level)
Expand Down
124 changes: 116 additions & 8 deletions archicad-addon/Sources/ElementCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,13 +314,7 @@ GS::ObjectState GetSelectedElementsCommand::Execute (const GS::ObjectState& /*pa
elemGuid = element.sectElem.parentGuid;
}

GS::ObjectState elemId;
elemId.Add ("guid", APIGuidToString (elemGuid));

GS::ObjectState elemIdArrayItem;
elemIdArrayItem.Add ("elementId", elemId);

elementsList (elemIdArrayItem);
elementsList (CreateElementIdObjectState (elemGuid));
}

return response;
Expand Down Expand Up @@ -467,7 +461,7 @@ static void AddSubelementsToObjectState (GS::ObjectState& subelements, APIElemTy

const auto& subelementsWithThisType = subelements.AddList<GS::ObjectState> (subelementType);
for (GSIndex i = 0; i < nSubelementsWithThisType; ++i) {
subelementsWithThisType (GS::ObjectState ("elementId", GS::ObjectState ("guid", APIGuidToString (subelemArray[i].head.guid))));
subelementsWithThisType (CreateElementIdObjectState (subelemArray[i].head.guid));
}
}

Expand Down Expand Up @@ -1222,6 +1216,120 @@ GS::ObjectState SetGDLParametersOfElementsCommand::Execute (const GS::ObjectStat
return {};
}

FilterElementsCommand::FilterElementsCommand () :
CommandBase (CommonSchema::Used)
{
}

GS::String FilterElementsCommand::GetName () const
{
return "FilterElements";
}

GS::Optional<GS::UniString> FilterElementsCommand::GetInputParametersSchema () const
{
return R"({
"type": "object",
"properties": {
"elements": {
"$ref": "#/Elements"
},
"filters": {
"type": "array",
"items": {
"$ref": "#/ElementFilter"
},
"minItems": 1
}
},
"additionalProperties": false,
"required": [
"elements"
]
})";
}

GS::Optional<GS::UniString> FilterElementsCommand::GetResponseSchema () const
{
return R"({
"type": "object",
"properties": {
"filteredElements": {
"$ref": "#/Elements"
}
},
"additionalProperties": false,
"required": [
"filteredElements"
]
})";
}

static API_ElemFilterFlags ConvertFilterStringToFlag (const GS::UniString& filter)
{
if (filter == "IsEditable")
return APIFilt_IsEditable;
if (filter == "IsVisibleByLayer")
return APIFilt_OnVisLayer;
if (filter == "IsVisibleByRenovation")
return APIFilt_IsVisibleByRenovation;
if (filter == "IsVisibleByStructureDisplay")
return APIFilt_IsInStructureDisplay;
if (filter == "IsVisibleIn3D")
return APIFilt_In3D;
if (filter == "OnActualFloor")
return APIFilt_OnActFloor;
if (filter == "OnActualLayout")
return APIFilt_OnActLayout;
if (filter == "InMyWorkspace")
return APIFilt_InMyWorkspace;
if (filter == "IsIndependent")
return APIFilt_IsIndependent;
if (filter == "InCroppedView")
return APIFilt_InCroppedView;
if (filter == "HasAccessRight")
return APIFilt_HasAccessRight;
if (filter == "IsOverriddenByRenovation")
return APIFilt_IsOverridden;
return APIFilt_None;
}

GS::ObjectState FilterElementsCommand::Execute (const GS::ObjectState& parameters, GS::ProcessControl& /*processControl*/) const
{
GS::Array<GS::ObjectState> elements;
parameters.Get ("elements", elements);

GS::Array<GS::UniString> filters;
parameters.Get ("filters", filters);

API_ElemFilterFlags filterFlags = APIFilt_None;
for (const GS::UniString& filter : filters) {
filterFlags |= ConvertFilterStringToFlag (filter);
}
if (filterFlags == APIFilt_None) {
return CreateErrorResponse (APIERR_BADPARS, "Invalid or missing filters!");
}

GS::ObjectState response;
const auto& filteredElements = response.AddList<GS::ObjectState> ("filteredElements");

for (const GS::ObjectState& element : elements) {
const GS::ObjectState* elementId = element.Get ("elementId");
if (elementId == nullptr) {
continue;
}

const API_Guid elemGuid = GetGuidFromObjectState (*elementId);
if (!ACAPI_Element_Filter (elemGuid, filterFlags)) {
continue;
}

filteredElements (CreateElementIdObjectState (elemGuid));
}

return response;
}

HighlightElementsCommand::HighlightElementsCommand () :
CommandBase (CommonSchema::Used)
{
Expand Down
10 changes: 10 additions & 0 deletions archicad-addon/Sources/ElementCommands.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ class SetGDLParametersOfElementsCommand : public CommandBase
virtual GS::ObjectState Execute (const GS::ObjectState& parameters, GS::ProcessControl& processControl) const override;
};

class FilterElementsCommand : public CommandBase
{
public:
FilterElementsCommand ();
virtual GS::String GetName () const override;
virtual GS::Optional<GS::UniString> GetInputParametersSchema () const override;
virtual GS::Optional<GS::UniString> GetResponseSchema () const override;
virtual GS::ObjectState Execute (const GS::ObjectState& parameters, GS::ProcessControl& processControl) const override;
};

class HighlightElementsCommand : public CommandBase
{
public:
Expand Down
2 changes: 1 addition & 1 deletion archicad-addon/Sources/ElementCreationCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ GS::ObjectState CreateElementsCommandBase::Execute (const GS::ObjectState& param
continue;
}

elements (GS::ObjectState ("elementId", GS::ObjectState ("guid", APIGuidToString (element.header.guid))));
elements (CreateElementIdObjectState (element.header.guid));
}

return NoError;
Expand Down
5 changes: 5 additions & 0 deletions archicad-addon/Sources/MigrationHelper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ inline GSErrCode ACAPI_Hotlink_GetHotlinkNodeTree (const API_Guid* hotlinkNodeGu
return ACAPI_Database (APIDb_GetHotlinkNodeTreeID, (void*) hotlinkNodeGuid, (void*) hotlinkNodeTree);
}

inline GSErrCode ACAPI_Window_GetCurrentWindow (API_WindowInfo* windowInfo)
{
return ACAPI_Database (APIDb_GetCurrentWindowID, (void*) windowInfo);
}

inline GSErrCode ACAPI_Navigator_GetNavigatorSetNum (Int32* setNum)
{
return ACAPI_Navigator (APINavigator_GetNavigatorSetNumID, setNum);
Expand Down
Loading

0 comments on commit 0eacb85

Please sign in to comment.