Skip to content

Commit 0aba7c0

Browse files
authored
Merge pull request #1104 from compas-dev/rhino-mesh-vertexcolors
Add per-vertex color specification option to mesh drawing in Rhino
2 parents e81a8c2 + 8411b0f commit 0aba7c0

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
* Added option for per-vertex color specification to `compas_rhino.utilities.drawing.draw_mesh`.
13+
1214
### Changed
1315

1416
* Fixed strange point values in RhinoNurbsCurve caused by conversion `ControlPoint` to COMPAS instead of `ControlPoint.Location`.

src/compas_rhino/utilities/drawing.py

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ def draw_spheres(spheres, **kwargs):
757757

758758

759759
@wrap_drawfunc
760-
def draw_mesh(vertices, faces, name=None, color=None, disjoint=False, **kwargs):
760+
def draw_mesh(vertices, faces, name=None, color=None, vertex_color=None, disjoint=False, **kwargs):
761761
"""Draw a mesh and optionally set individual name, color, and layer properties.
762762
763763
Parameters
@@ -767,7 +767,13 @@ def draw_mesh(vertices, faces, name=None, color=None, disjoint=False, **kwargs):
767767
faces : list[list[int]]
768768
A list of faces as lists of indices into `vertices`.
769769
name : str, optional
770+
The name of the mesh object in Rhino.
770771
color : tuple[[int, int, int]], optional
772+
The base color of the mesh.
773+
vertex_color : dict[int, tuple[int, int, int]], optional
774+
A color per vertex of the mesh.
775+
Vertices without a color specification in this mapping, will receive the base color.
776+
For example: ``vertex_color = {vertex: Color.from_i(random.random()).rgb255 for face in faces for vertex in face}``
771777
disjoint : bool, optional
772778
If True, draw the mesh with disjoint faces.
773779
@@ -776,7 +782,19 @@ def draw_mesh(vertices, faces, name=None, color=None, disjoint=False, **kwargs):
776782
System.Guid
777783
778784
"""
785+
786+
def average_color(colors):
787+
c = len(colors)
788+
r, g, b = zip(*colors)
789+
r = sum(r) / c
790+
g = sum(g) / c
791+
b = sum(b) / c
792+
return int(r), int(g), int(b)
793+
794+
vertex_color = vertex_color or {}
795+
vertexcolors = []
779796
mesh = RhinoMesh()
797+
780798
if disjoint:
781799
for face in faces:
782800
f = len(face)
@@ -786,29 +804,44 @@ def draw_mesh(vertices, faces, name=None, color=None, disjoint=False, **kwargs):
786804
a = mesh.Vertices.Add(*vertices[face[0]])
787805
b = mesh.Vertices.Add(*vertices[face[1]])
788806
c = mesh.Vertices.Add(*vertices[face[2]])
807+
vertexcolors.append(vertex_color.get(face[0], color))
808+
vertexcolors.append(vertex_color.get(face[1], color))
809+
vertexcolors.append(vertex_color.get(face[2], color))
789810
mesh.Faces.AddFace(a, b, c)
790811
elif f == 4:
791812
a = mesh.Vertices.Add(*vertices[face[0]])
792813
b = mesh.Vertices.Add(*vertices[face[1]])
793814
c = mesh.Vertices.Add(*vertices[face[2]])
794815
d = mesh.Vertices.Add(*vertices[face[3]])
816+
vertexcolors.append(vertex_color.get(face[0], color))
817+
vertexcolors.append(vertex_color.get(face[1], color))
818+
vertexcolors.append(vertex_color.get(face[2], color))
819+
vertexcolors.append(vertex_color.get(face[3], color))
795820
mesh.Faces.AddFace(a, b, c, d)
796821
else:
797822
if MeshNgon:
823+
cornercolors = [vertex_color.get(vertex, color) for vertex in face]
824+
vertexcolors += cornercolors
825+
vertexcolors.append(average_color(cornercolors))
826+
798827
points = [vertices[vertex] for vertex in face]
799828
centroid = centroid_polygon(points)
800829
indices = []
801830
for point in points:
802831
indices.append(mesh.Vertices.Add(*point))
803832
c = mesh.Vertices.Add(*centroid)
833+
804834
facets = []
805835
for i, j in pairwise(indices + indices[:1]):
806836
facets.append(mesh.Faces.AddFace(i, j, c))
807837
ngon = MeshNgon.Create(indices, facets)
808838
mesh.Ngons.AddNgon(ngon)
839+
809840
else:
810-
for x, y, z in vertices:
841+
for index, (x, y, z) in enumerate(vertices):
811842
mesh.Vertices.Add(x, y, z)
843+
vertexcolors.append(vertex_color.get(index, color))
844+
812845
for face in faces:
813846
f = len(face)
814847
if f < 3:
@@ -819,8 +852,12 @@ def draw_mesh(vertices, faces, name=None, color=None, disjoint=False, **kwargs):
819852
mesh.Faces.AddFace(*face)
820853
else:
821854
if MeshNgon:
855+
cornercolors = [vertex_color.get(index, color) for index in face]
856+
vertexcolors.append(average_color(cornercolors))
857+
822858
centroid = centroid_polygon([vertices[index] for index in face])
823859
c = mesh.Vertices.Add(*centroid)
860+
824861
facets = []
825862
for i, j in pairwise(face + face[:1]):
826863
facets.append(mesh.Faces.AddFace(i, j, c))
@@ -833,6 +870,12 @@ def draw_mesh(vertices, faces, name=None, color=None, disjoint=False, **kwargs):
833870
guid = add_mesh(mesh)
834871

835872
if guid != System.Guid.Empty:
873+
if vertexcolors:
874+
try:
875+
compas_rhino.set_mesh_vertex_colors(guid, vertexcolors)
876+
except Exception:
877+
pass
878+
836879
obj = find_object(guid)
837880
if obj:
838881
attr = obj.Attributes

0 commit comments

Comments
 (0)