I'm having trouble applying colors to triangles that are shown via a DirectContext3DServer. I use a ColorWithTransparency object as a basis. Lines working fine, but here is the issue with triangles:
I can apply the color via the EffectInstance, but only if I set it's Emissive Color through .SetEmissiveColor(). If I set all it's other colors like, Color, DiffuseColor, SpecularColor or AmbientColor it stays black. Changing transparency works fine. The biggest issue if I'd like to apply the colors per vertices it wont work. I'm using
Solved! Go to Solution.
Solved by tamas.deri. Go to Solution.
Can you provide a minimal reproducible case for the development team to analyse?
https://thebuildingcoder.typepad.com/blog/about-the-author.html#1b
As a small motivation, note that doing so has often led to a solution in the past:
Hi Jeremy!
The funny thing is that I tried to put together the reproducible case, and I've just found out what the issue was. Somehow I left a line in the code which set the EffectInstance's transparency, and I think if any property of the EffectInstance is set than it overrides all vertex properties. Thats whythe vertex colors got ignored, and it falled back to transparent black. Once I removed that line, and kept only the just-constructed EffectInstance it worked as intended.
PS.: This could be mentioned somewhere in the documentation that vertex level colorization can only be used with an untouched EffectInstance, even if it seems straightforward for me now.
Congratulations on solving this!
Would it be possible to share a minimal generic sample and a screen snapshot or two for the community to see a working example of using this API?
That might also offer a good opportunity to ensure that your information about the untouched EffectInstance gains appropriate visibility.
Thank you!
Sure! This is only a partial code that updates the buffers if it is neccessary. The rest is similar to what is available at other sources regarding DirectContext3D.
def update_buffer(self):
if self.penetrations is None: return False
try:
lines = []
triangles = []
colors = []
for pen_item in self.penetrations:
if pen_item.proposed:
primitives = pen_item.proposed.get_wireframe()
else:
primitives = pen_item.current.get_wireframe()
lines.extend(primitives[0])
triangles.extend(primitives[1])
colors.append(pen_item.status_color)
tri_f_bits = dc.VertexFormatBits.PositionNormalColored
tri_vertex_format = dc.VertexFormat(tri_f_bits)
tri_effect_instance = dc.EffectInstance(tri_f_bits)
# If you try to handle transparency globally it will also
# overrides vertex colors, and overrides them to black
# tri_effect_instance.SetTransparency(0.8)
tri_vertex_buffer_size = \
dc.VertexPositionNormalColored.GetSizeInFloats() \
* len(triangles) * 3
tri_vertex_buffer = dc.VertexBuffer(tri_vertex_buffer_size)
tri_index_buffer_size = \
dc.IndexTriangle.GetSizeInShortInts() * len(triangles)
tri_index_buffer = dc.IndexBuffer(tri_index_buffer_size)
tri_vertex_buffer.Map(tri_vertex_buffer_size)
tri_index_buffer.Map(tri_index_buffer_size)
tri_vertex_stream_p = \
tri_vertex_buffer.GetVertexStreamPositionNormalColored()
tri_index_stream_p = tri_index_buffer.GetIndexStreamTriangle()
for triangle in triangles:
triangle_index = triangles.index(triangle)
first_idx = triangle_index * 3
tri_vertex_stream_p.AddVertex(dc.VertexPositionNormalColored(
triangle[1], triangle[0], colors[triangle_index / 12]
))
tri_vertex_stream_p.AddVertex(dc.VertexPositionNormalColored(
triangle[2], triangle[0], colors[triangle_index / 12]
))
tri_vertex_stream_p.AddVertex(dc.VertexPositionNormalColored(
triangle[3], triangle[0], colors[triangle_index / 12]
))
tri_index_stream_p.AddTriangle(dc.IndexTriangle(
first_idx,
first_idx + 1,
first_idx + 2
))
tri_vertex_buffer.Unmap()
tri_index_buffer.Unmap()
self.triangle_buffer = (
tri_vertex_buffer,
tri_vertex_buffer_size,
tri_index_buffer,
tri_index_buffer_size,
tri_vertex_format,
tri_effect_instance,
dc.PrimitiveType.TriangleList,
0,
len(triangles)
)
line_f_bits = dc.VertexFormatBits.PositionColored
line_vertex_format = dc.VertexFormat(line_f_bits)
line_effect_instance = dc.EffectInstance(line_f_bits)
line_vertex_buffer_size = \
dc.VertexPositionColored.GetSizeInFloats() * len(lines) * 2
line_vertex_buffer = dc.VertexBuffer(line_vertex_buffer_size)
line_index_buffer_size = \
dc.IndexLine.GetSizeInShortInts() * len(lines)
line_index_buffer = dc.IndexBuffer(line_index_buffer_size)
line_vertex_buffer.Map(line_vertex_buffer_size)
line_index_buffer.Map(line_index_buffer_size)
line_vertex_stream_p = \
line_vertex_buffer.GetVertexStreamPositionColored()
line_index_stream_p = line_index_buffer.GetIndexStreamLine()
for line in lines:
line_index = lines.index(line)
first_idx = line_index * 2
line_vertex_stream_p.AddVertex(dc.VertexPositionColored(
line.GetEndPoint(0), colors[line_index / 12]
))
line_vertex_stream_p.AddVertex(dc.VertexPositionColored(
line.GetEndPoint(1), colors[line_index / 12]
))
line_index_stream_p.AddLine(dc.IndexLine(
first_idx,
first_idx + 1
))
line_vertex_buffer.Unmap()
line_index_buffer.Unmap()
self.line_buffer = (
line_vertex_buffer,
line_vertex_buffer_size,
line_index_buffer,
line_index_buffer_size,
line_vertex_format,
line_effect_instance,
dc.PrimitiveType.LineList,
0,
len(lines)
)
self.update_flag = False
return True
except:
return False
EDIT: I've tried to reproduce the previous issue and provide screenshots, but I just couldn't. It is weird. I even reverted my whole branch to the state where it didn't work, but now it is working.
So... I have to withdraw everything I said, because I can't prove none of the above, and it remains and assumption.
At least there is some python example of DirectContext3D 😉
I've managed to figure out why the vertex colors were not applied. It is still related to the EffectInstance, but it has nothing to do with its colors. The problem was that I've been using an EffectInstance created as
if any([
display_style == DB.DisplayStyle.Shading,
display_style == DB.DisplayStyle.ShadingWithEdges
]):
tri_effect_instance = dc.EffectInstance(
dc.VertexFormatBits.PositionNormalColored
)
else:
tri_effect_instance = dc.EffectInstance(
dc.VertexFormatBits.PositionColored
)
Now it works on all views as expected, and I was able to keep the vertices as VertexPositionNormalColored in all cases. The EffectInstance did the trick by itself.
Thank you very much, Tamas, for the nice sample code and in-depth research. Preserved here for posterity:
https://thebuildingcoder.typepad.com/blog/2022/09/point-clouds-coloured-triangles-and-faces.html#3