3D-PDF Export

The 3D-PDF Export tool creates a PDF document with embedded 3D graphic. The tool is particularly focused on structural models and reinforcement.

  1. Click BiMTOOLS tab > 3D-PDF Export panel > icon_3D_PDF_Export (Export)

    The Settings dialog displays.

  2. Choose your preferred settings and click OK.

    The PDF file will be created in the project folder.

Tip

If Use ActiveView Geometry is checked, the program exports the geometry represented the active view, taking into account section boxes, displacements and other view dependent features.

../_images/mainpic.png

Workflow

The process to generate a 3D PDF document using SOFiSTiK 3D-PDF Export can be structured in the following points:

  1. Get the geometric definition of the elements Revit and organize it as a set of 3D objects formed by a triangular mesh.

  2. Create a U3D file using the previously collected geometric data.

  3. Generate a standard PDF document and embed on one of its pages the 3D model that was stored in U3D format.

In order to complete this workflow, two external libraries are implemented. Firstly, to create the required U3D file an open source library called “Universal 3D Sample Software”; this one allows writing, reading and editing data in the referred format. The complete library and source code can be found in the following web page:

http://sourceforge.net/projects/u3d/develop

On the other hand, the PDF file is created by means of another external library, i.e. “libHaru” which is a free, cross platform, open source library for generating PDF files. So then, libHaru is able to incorporate different kind of external objects into a PDF document, such as U3D files. The version 2.3.0 is included in the SOFiSTiK PDF Export, likewise another two libraries are implemented according to the requirements of libHaru: zlib (v 1.2.5) and libpng (1.5.8). The complete library and source code can be found in the following web page:

http://libharu.org/

Summarizing the “SOFiSTiK 3D-PDF Export” workflow can be depicted as follows:

../_images/workflow.png

Java Script Support

JavaScript Support extends possibilities to modify 3D objects and their appearance programmatically.

Include JavaScript files into the project using Settings Dialog (Tab Other)

  1. Create Java Script file with your own code or use prepared example

  2. Click Add-Ins tab > SOFiSTiK 3D-PDF Export panel > icon_Export (Export)

The Settings dialog displays.

../_images/mpic_SettingsTab_Other1.png
  1. In Tab Other, check ‘Include JavaScript file’ box and select the directory of proper JavaScript file in ‘File location’.

  2. Check other setting and click OK to create 3D-PDF file.

Example

You can use following code to create Java Script file.

  1. Create and open new “.txt” file

  2. Copy whole code, paste into the “.txt” file, save it and close.

  3. Change the extension of the file into “.js”

Following example of JavaScript enables you to change the color of an element temporarly by holding a cursor on it.

function ModelPartObject()
{
        this.mouseEventHandler  = null;
        this.mesh               = null;
}
function MouseSelectionObject()
{
        owner = this;

        var DEFAULT_RENDER_MODE                 = "solid outline";
        var DEFAULT_MOUSE_OVER_RENDER_MODE  = "illustration";
        var DEFAULT_MOUSE_DOWN_RENDER_MODE  = "illustration";
        var DEFAULT_SELECTED_RENDER_MODE        = "illustration";

        var defaultRenderMode                   = DEFAULT_RENDER_MODE;
        var mouseOverRenderMode                 = DEFAULT_MOUSE_OVER_RENDER_MODE;
        var mouseDownRenderMode                 = DEFAULT_MOUSE_DOWN_RENDER_MODE;
        var selectedRenderMode                  = DEFAULT_SELECTED_RENDER_MODE;
        var mousePart = -1;
        var selectedPart = -1;
        var initialized = false;
        var numberOfModelParts = 0;
        var atLeastOnePartHasBeenCreated = false;
        var camera = this.scene.cameras.getByIndex( 0 );
        var generalMouseEventHandler = new MouseEventHandler();

        var maxNumModelParts = this.scene.meshes.count;
        var modelPart = new Array( maxNumModelParts );

        for (p=0; p<maxNumModelParts; p++)
        {
          modelPart[p] = new ModelPartObject();
        }
        generalMouseEventHandler.onMouseDown    = true;
        generalMouseEventHandler.onMouseMove    = true;
        generalMouseEventHandler.onMouseUp      = true;
        generalMouseEventHandler.onEvent = function( event )
        {
                if ( event.isMouseUp)
                {
                        if ( mousePart != -1 )
                        {
                                modelPart[ mousePart ].mesh.renderMode = defaultRenderMode;
                                mousePart = -1;
                        }
                }
        }

        runtime.addEventHandler( generalMouseEventHandler );
        this.myMouseHandlingFunction = function( event )
        {
                var m = 0;
                var lookingForMesh = true;
                while ( lookingForMesh )
                {
                        if ( this.target == modelPart[m].mesh )
                        {
                                lookingForMesh = false;
                                if ( event.isMouseOver )
                                {
                                        if ( ! event.leftButtonDown )
                                        {
                                                mousePart = m;
                                                modelPart[ m ].mesh.renderMode = mouseOverRenderMode;
                                        }
                                }

                                if ( event.isMouseOut )
                                {
                                        if (( ! event.leftButtonDown ))
                                        {
                                                mousePart = -1;
                                                modelPart[ m ].mesh.renderMode = defaultRenderMode;
                                        }
                                }
                                if ( event.isMouseDown )
                                {
                                        mousePart = m;
                                        modelPart[ m ].mesh.renderMode = mouseDownRenderMode;
                                }
                                if ( event.isMouseUp )
                                {
                                        if ( selectedPart != -1 )
                                                {modelPart[ selectedPart ].mesh.renderMode = defaultRenderMode; }

                                        selectedPart = m;
                                        mousePart = -1;
                                }
                        }

                        m ++;

                        if ( m > numberOfModelParts - 1 )
                                {lookingForMesh = false;}
                }
        }

        this.getMeshesFromModel = function()
        {
                numberOfModelParts = 0;

                for (p=0; p<this.scene.meshes.count; p++)
                {
                        var modelMesh = this.scene.meshes.getByIndex( p );
                        if ( modelMesh.material )
                        {
                                modelPart[ numberOfModelParts ].mesh = modelMesh;

                                if ( ! atLeastOnePartHasBeenCreated )
                                {atLeastOnePartHasBeenCreated = true;}
                                numberOfModelParts ++;
                        }
                }

        }

        this.initialize = function()
        {
                if ( ! initialized )
                {
                        owner.getMeshesFromModel();
                        for (var m=0; m<numberOfModelParts; m++)
                        {
                                modelPart[m].mouseEventHandler = new MouseEventHandler();
                                modelPart[m].mouseEventHandler.onMouseMove = true;
                                modelPart[m].mouseEventHandler.onMouseDown = true;
                                modelPart[m].mouseEventHandler.onMouseUp   = true;
                                modelPart[m].mouseEventHandler.onMouseOver = true;
                                modelPart[m].mouseEventHandler.onMouseOut  = true;
                                modelPart[m].mouseEventHandler.target      = modelPart[m].mesh;
                                modelPart[m].mouseEventHandler.onEvent     = owner.myMouseHandlingFunction;
                                runtime.addEventHandler( modelPart[m].mouseEventHandler );
                        }

                        for (p=0; p<this.scene.meshes.count; p++)
                        {
                                var mesh = this.scene.meshes.getByIndex(p);
                                if ( mesh.material )
                                {mesh.renderMode = defaultRenderMode;}
                        }
                        initialized = true;
                }

                return initialized;
        }

        this.setAllPartsToDefaultRenderMode = function()
        {
                for (var m=0; m<numberOfModelParts; m++)
                {modelPart[m].mesh.renderMode = defaultRenderMode;}
        }

        this.selectPart = function( partName )
        {owner.selectPartByIndex( getPartIndexFromName( partName ) );}

        this.unSelectPart = function( partName )
        {owner.unSelectPartByIndex( getPartIndexFromName( partName ) );}

        this.selectPartByIndex = function( partIndex )
        {
                selectedPart = partIndex;
                modelPart[ selectedPart ].mesh.renderMode = selectedRenderMode;
        }

        this.unSelectPartByIndex = function( partIndex )
        {
                if ( partIndex == selectedPart )
                {
                        modelPart[ selectedPart ].mesh.renderMode = defaultRenderMode;
                        selectedPart = -1;
                }
        }

        this.incrementSelectedPart = function()
        {
                if ( selectedPart == -1 )
                {owner.selectPartByIndex( 0 );}
                else
                {
                        var previouslySelectedPart = selectedPart;
                        owner.unSelectPartByIndex( selectedPart );
                        var nextPart = previouslySelectedPart + 1;

                        if ( nextPart >= numberOfModelParts )
                        {nextPart = 0;}

                        owner.selectPartByIndex( nextPart );
                }
        }

        this.decrementSelectedPart = function()
        {
                if ( selectedPart == -1 )
                {owner.selectPartByIndex( 0 );}
                else
                {
                        var previouslySelectedPart = selectedPart;
                        owner.unSelectPartByIndex( selectedPart );
                        var nextPart = previouslySelectedPart - 1;

                        if ( nextPart < 0 )
                        {nextPart = numberOfModelParts - 1;}

                        owner.selectPartByIndex( nextPart );
                }
        }

        this.getSelectedPartName = function()
        {
                result = "there is no selected part";
                if ( selectedPart != -1 )
                {result = modelPart[ selectedPart ].mesh.name; }
                return result;
        }

        this.unSelectSelectedPart = function()
        {owner.unSelectPartByIndex( selectedPart );}

        this.setDefaultRenderMode = function( renderMode )
        {
                defaultRenderMode = renderMode;
                owner.setAllPartsToDefaultRenderMode();
        }

        this.setMouseOverRenderMode = function( renderMode )
        {mouseOverRenderMode = renderMode;}

        this.setMouseDownRenderMode = function( renderMode )
        {mouseDownRenderMode = renderMode;}

        this.setSelectedRenderMode = function( renderMode )
        {selectedRenderMode = renderMode;}

        this.setAllMouseSelectionPartsToDefaultRenderMode = function()
        {setAllPartsToDefaultRenderMode();}

        this.getPartIndexFromName = function ( partName )
        {
                var index = -1;
                for (m=0; m<numberOfModelParts; m++)
                {
                        if ( partName == modelPart[m].mesh.name )
                        {index = m;}
                }

                return index;
        }

        owner.initialize();
        return this;
}

var mouseMoved=MouseSelectionObject();