Create View 3D while Active Direct 3D Context

Create View 3D while Active Direct 3D Context

Moustafa_K
Collaborator Collaborator
596 Views
5 Replies
Message 1 of 6

Create View 3D while Active Direct 3D Context

Moustafa_K
Collaborator
Collaborator

I encountered an issue while running the Direct 3D Context Service. When the service is running but not / actively drawing anything, and I either click or create a 3D view  or assembly ortho View  via the API or UI, the view does not zoom to the extent as it normally would when the service is not running. Please refer to this video for a better demonstration.

 

Has any one faced the same?

 

 

Steps to Reproduce:

  1. Register the Direct 3D service: ExternalServices.BuiltInExternalServices.DirectContext3DService
  2. Create a 3D view.

 

Moustafa_K_0-1718429325804.gif

 

 

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
0 Likes
Accepted solutions (1)
597 Views
5 Replies
Replies (5)
Message 2 of 6

ricaun
Advisor
Advisor
What do you mean by service is running with no drawing?

A code sample of the service would help.

My guess is that the boundbox of the DirectContext service is to big, the view see that boundbox and zoom out.
Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

0 Likes
Message 3 of 6

Moustafa_K
Collaborator
Collaborator

@ricaun wrote:
What do you mean by service is running with no drawing?


I am refereeing to IDirectContext3D and there is no any geometry supplied, it doesn't matter. in both cases has geometry or no, it behaves the same !!!

 

 I also checked the bounding box thing, tried both returns, but  still same behavior

 

public Outline GetBoundingBox(View dBView)
{
    return new Outline(XYZ.Zero, new XYZ(5,5,5));
    
    return new Outline(dBView.CropBox.Min, dBView.CropBox.Max);
}

 

 

The code very simple

Just register a service, and on the UI click on the View 3D

 

public void DummyService()
{
    try
    {
        var d3dServer = new D3DServer();
        d3dServer.RegisterServer();
     }
    catch (Exception ex)
    {
    }
}

public void RegisterServer()
{
    ExternalService service = ExternalServiceRegistry.GetService(GetServiceId());


    if (service is MultiServerService multiServerService)
    {
        // register the service so Revit calls it when ever needed

        IList<Guid> activeServerIds = multiServerService.GetActiveServerIds();
        if (!activeServerIds.Contains(SourceId))
        {
            service.AddServer(this);
            activeServerIds.Add(SourceId);
            multiServerService.SetActiveServers(activeServerIds);
        }
    }
}

 

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
0 Likes
Message 4 of 6

ricaun
Advisor
Advisor
Accepted solution

Looks like the BoundingBox is doing his job.

 

The BoundingBox still gonna be count inside the view even if the RenderScene is empty.

 

You could draw a box where the BoundingBox is located to confirm that.

 

And if you are not drawing anything, you probably should use the CanExecute to disable the IDirectContext3DServer in the view, pretty sure the BoundingBox is not gonna be count inside the view.

 

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

0 Likes
Message 5 of 6

Moustafa_K
Collaborator
Collaborator

 

Initially, while studying the D3DContext service, I understood that using this service has no effect on the document database. Thus, collecting the size of the view does not depend on this service, but rather on the actual visible elements that are part of the document.

 

Upon a second review of the documentation, I realized I had missed an important detail.

 

The outline box of the supplied geometry should be returned when implementing the interface, rather than the view crop box size. This ensures that the view box accurately reflects the size of the graphics supplied to the GPU.

To manage this, returning a dummy outline (1,1,1) is not a good solution. Instead, controlling CanExecute will help prevent triggering GetBoundingBox, thereby not affecting the size of the view.

 

I believe this is a robust approach. Thanks to @ricaun  for the insight.

public bool CanExecute(View dBView)
{
    return AugmentedObjects.Any();
}

public Outline GetBoundingBox(View dBView)
{
    return GeometryOutLine ?? new Outline(XYZ.Zero, new XYZ(1, 1, 1));
}

 

 

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
Message 6 of 6

ricaun
Advisor
Advisor

I usually return null in the GetBoundingBox when don't have a defined Outline for the graphics, works similar like the view.CropBox.

 

Yes setting the correct Outline for the GetBoundingBox makes the IDirectContext3DServer work so much cleaner.

 


@Moustafa_K wrote:

Thanks to @ricaun  for the insight.


Cheers! When I started playing with DirectContext3D I had the same issue at the time. 😆

 

 

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

0 Likes