Skip to content

Commit

Permalink
HighlightElementsComponent (#194)
Browse files Browse the repository at this point in the history
* HighlightElementsComponent

* Boolean toggle input to clear highlight and DocumentContextChanged eventhandler

* Rename Clear input to Enabled and use AddBooleanParameter with default true

* Minor changes and OnParameterSourcesChanged eventhandler to clear highlight when input was removed

* Change the order of parameters.

* Fix API error of using transparency from the non-highlighted color.

* Merge from main.

* Minor modifications.

---------

Co-authored-by: Viktor Kovacs <[email protected]>
  • Loading branch information
tlorantfy and kovacsv authored Nov 3, 2024
1 parent a6824a0 commit 0a6bc32
Show file tree
Hide file tree
Showing 7 changed files with 240 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ public override void AddedToDocument (GH_Document document)
{
base.AddedToDocument (document);

ElementTypeValueList.AddAsSource (this, 0, ElementTypeValueListType.AllElements);
if (Params.Input[0].SourceCount == 0) {
ElementTypeValueList.AddAsSource (this, 0, ElementTypeValueListType.AllElements);
}
}

protected override void SolveInstance (IGH_DataAccess DA)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ public override void AddedToDocument (GH_Document document)
{
base.AddedToDocument (document);

ElementTypeValueList.AddAsSource (this, 1, ElementTypeValueListType.SubElementsOnly);
if (Params.Input[1].SourceCount == 0) {
ElementTypeValueList.AddAsSource (this, 1, ElementTypeValueListType.SubElementsOnly);
}
}

protected override void SolveInstance (IGH_DataAccess DA)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
using Grasshopper.Kernel;
using Grasshopper.Kernel.Types;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using TapirGrasshopperPlugin.Data;
using TapirGrasshopperPlugin.Utilities;
using System.Windows.Forms;
using System.Xml.Linq;

namespace TapirGrasshopperPlugin.Components.ElementsComponents
{

public class HighlightElementsComponent : ArchicadAccessorComponent
{
public HighlightElementsComponent ()
: base (
"Highlight Elements",
"HighlightElems",
"Highlight Elements.",
"Elements"
)
{
Params.ParameterSourcesChanged += OnParameterSourcesChanged;
}

public override void DocumentContextChanged (GH_Document document, GH_DocumentContext context)
{
base.DocumentContextChanged (document, context);
if (context == GH_DocumentContext.Close || context == GH_DocumentContext.Unloaded) {
ClearHighlight ();
}
}

public override void RemovedFromDocument (GH_Document document)
{
base.RemovedFromDocument (document);
ClearHighlight ();
}

public override void AddedToDocument (GH_Document document)
{
int counter = 0;
GH_Document doc = OnPingDocument ();
if (doc != null) {
foreach (IGH_DocumentObject obj in doc.Objects)
if (obj.ComponentGuid == ComponentGuid) {
counter++;
if (counter > 1) {
break;
}
}
}

if (counter > 1) {
doc.RemoveObject (this, true);
MessageBox.Show ("Only one instance can be created.", "Highlight Elements");
} else {
base.AddedToDocument (document);
}
}

protected override void RegisterInputParams (GH_InputParamManager pManager)
{
pManager.AddBooleanParameter ("Enable", "Enable", "Enable highlight.", GH_ParamAccess.item, @default: true);
pManager.AddGenericParameter ("ElementIds", "ElementIds", "Elements to highlight.", GH_ParamAccess.list);
pManager.AddColourParameter ("HighligtedColors", "Colors", "Colors for the elements.", GH_ParamAccess.list);
pManager.AddColourParameter ("NonHighligtedColor", "NHColor", "Color for the non-highlighted elements.", GH_ParamAccess.item);
pManager.AddBooleanParameter ("NonHighligtedWireframe", "NHWire3D", "Switch non-highlighted elements in the 3D window to wireframe", GH_ParamAccess.item, @default: false);
pManager.AddNumberParameter ("Transparency", "Transparency", "Sets the transparency of the highlight (0.0: opaque, 1.0: transparent).", GH_ParamAccess.item, @default: 0.0);
}

protected override void RegisterOutputParams (GH_OutputParamManager pManager)
{
}

protected override void SolveInstance (IGH_DataAccess DA)
{
bool enabled = true;
if (DA.GetData (0, ref enabled) && !enabled) {
ClearHighlight ();
return;
}

ElementsObj inputElements = ElementsObj.Create (DA, 1);
if (inputElements == null) {
AddRuntimeMessage (GH_RuntimeMessageLevel.Error, "Input ElementIds failed to collect data.");
return;
}

List<GH_Colour> highlightedColors = new List<GH_Colour> ();
if (!DA.GetDataList (2, highlightedColors)) {
return;
}

if (highlightedColors.Count != 1 && inputElements.Elements.Count != highlightedColors.Count) {
AddRuntimeMessage (GH_RuntimeMessageLevel.Error, "The count of highlighted colors must be 1 or the same as the count of ElementIds.");
return;
}

GH_Colour nonHighlightedColor = new GH_Colour ();
if (!DA.GetData (3, ref nonHighlightedColor)) {
return;
}

bool wireframe3D = false;
if (!DA.GetData (4, ref wireframe3D)) {
return;
}

double transparency = 0.0;
if (!DA.GetData<double> (5, ref transparency)) {
return;
}
if (transparency < 0.0) {
transparency = 0.0;
} else if (transparency > 1.0) {
transparency = 1.0;
}

// There is an error in the Archicad API implementation: the transparency
// always comes from the non-highlighted element color.
HighlightElementsObj highlightElements = new HighlightElementsObj () {
Elements = inputElements.Elements,
HighlightedColors = Utilities.Convert.ToRGBColors (highlightedColors, 255, inputElements.Elements.Count),
NonHighlightedColor = Utilities.Convert.ToRGBColor (nonHighlightedColor, System.Convert.ToInt32 (transparency * 255.0)),
Wireframe3D = wireframe3D
};
JObject highlightElementsObj = JObject.FromObject (highlightElements);
CommandResponse response = SendArchicadAddOnCommand ("TapirCommand", "HighlightElements", highlightElementsObj);
if (!response.Succeeded) {
AddRuntimeMessage (GH_RuntimeMessageLevel.Error, response.GetErrorMessage ());
return;
}
}

private void ClearHighlight ()
{
HighlightElementsObj highlightElements = new HighlightElementsObj ();
JObject highlightElementsObj = JObject.FromObject (highlightElements);
CommandResponse response = SendArchicadAddOnCommand ("TapirCommand", "HighlightElements", highlightElementsObj);
if (!response.Succeeded) {
AddRuntimeMessage (GH_RuntimeMessageLevel.Error, response.GetErrorMessage ());
return;
}
}

public void OnParameterSourcesChanged (object source, EventArgs e)
{
foreach (IGH_Param param in Params.Input) {
if (!param.Optional && param.SourceCount == 0) {
ClearHighlight ();
break;
}
}
}

protected override System.Drawing.Bitmap Icon => TapirGrasshopperPlugin.Properties.Resources.HighlightElems;

public override Guid ComponentGuid => new Guid ("9ba098dd-63c5-4126-b4cc-3caa56082c8f");
}
}
21 changes: 21 additions & 0 deletions grasshopper-plugin/TapirGrasshopperPlugin/Data/ElementData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,27 @@ public class ElementPropertyValuesObj
public List<ElementPropertyValueObj> ElementPropertyValues;
}

public class HighlightElementsObj
{
public HighlightElementsObj ()
{
Elements = new List<ElementIdItemObj> ();
HighlightedColors = new List<List<int>> ();
}

[JsonProperty ("elements")]
public List<ElementIdItemObj> Elements;

[JsonProperty ("highlightedColors")]
public List<List<int>> HighlightedColors;

[JsonProperty ("nonHighlightedColor", NullValueHandling = NullValueHandling.Ignore)]
public List<int> NonHighlightedColor;

[JsonProperty ("wireframe3D")]
public bool Wireframe3D;
}

public class DetailsOfElementObj
{
[JsonProperty ("type")]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,7 @@
<data name="SnapPt" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\SnapPt.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="HighlightElems" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\HighlightElems.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Grasshopper.Kernel.Types;

namespace TapirGrasshopperPlugin.Utilities
{
public class Convert
{
static public List<int> ToRGBColor (GH_Colour colorRGBA, int alpha)
{
if (colorRGBA == null) {
return null;
}
return new List<int> {
colorRGBA.Value.R,
colorRGBA.Value.G,
colorRGBA.Value.B,
alpha
};
}

static public List<List<int>> ToRGBColors (List<GH_Colour> colorRGBAs, int alpha, int minSize)
{
if (colorRGBAs == null) {
return null;
}
List<List<int>> colors = new List<List<int>> ();
foreach (GH_Colour colorRGBA in colorRGBAs) {
colors.Add (ToRGBColor (colorRGBA, alpha));
}
for (int i = colors.Count; i < minSize; ++i) {
colors.Add (colors.Last ());
}
return colors;
}
}
}

0 comments on commit 0a6bc32

Please sign in to comment.