Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

DirectContext3D Colorized Triangles

6 REPLIES 6
SOLVED
Reply
Message 1 of 7
tamas.deri
438 Views, 6 Replies

DirectContext3D Colorized Triangles

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 

VertexFormatBits.PositionNormalColored, and set for instance 
ColorWithTransparency(255,0,0,200) as it's color, but all triangles will be transparent black. Any idea what could be the issue? No exceptions thrown, all buffers are valid, the geometries are being shown, but without the right color applied.
6 REPLIES 6
Message 2 of 7
jeremy_tammik
in reply to: tamas.deri

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:

 

https://thebuildingcoder.typepad.com/blog/2017/01/virtues-of-reproduction-research-mep-settings-onto...

  

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 3 of 7
tamas.deri
in reply to: jeremy_tammik

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.

Message 4 of 7
jeremy_tammik
in reply to: tamas.deri

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!

  

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 5 of 7
tamas.deri
in reply to: jeremy_tammik

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 😉

Message 6 of 7
tamas.deri
in reply to: tamas.deri

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 

EffectInstance(VertexFormatBits.PositionNormalColored) eventhough my displaystyle was not shaded. This made all my triangles black on non shaded views, but they did work fine on shaded views. So I added the following lines:

 

 

            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.

Message 7 of 7
jeremy_tammik
in reply to: tamas.deri

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

   

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community