Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages | Examples

3DPublish/3DPublish_UTF8.cpp

This sample shows how to create a 3D DWF (DWFToolkit::DWFModel, DWFToolkit::DWFPackagePublisher), use the include library (DWFToolkit::DWFIncludeSegment), texture shells (DWFToolkit::DWFTexture), build a navigable object tree (DWFToolkit::DWFSegment), embed fonts (DWFToolkit::DWFEmbeddedFont), add a thumbnail (DWFToolkit::DWFImage), add end-user adjustable items like spotlights (TK_Spot_Light) and cutting planes (TK_Cutting_Plane) and more.

// SimpleEnumReader.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

using namespace std;
using namespace DWFCore;
using namespace DWFToolkit;


//
//
// Some of this sample code is taken from the HOOPS/Stream toolkit (v.10.00) samples
//
//


void CreateSphere( float *center, 
                   float radius, 
                   int numsides, 
                   int *pcount_out, 
                   float **points_out, 
                   int *flistlen_out, 
                   int **faces_out );

void do_model( DWFToolkit::DWFModel& rModel,
               bool bIncludeNormals );



int main(int argc, char* argv[])
{

    if (argc < 2)
    {
        wcout << L"Usage:" << argv[0] << L" file.dwf" << endl;
        return ( 0 );
    }

    try
    {
        //
        // 
        //
        DWFCore::DWFFile oDWF( argv[1] );
        DWFToolkit::DWFPackagePublisher oPublisher( oDWF );

        //
        // start with a new model
        //
        DWFToolkit::DWFModel oModel( L"3D Publish Model Test", L"3DPublish.cpp" );
        
        oModel.open( DWFToolkit::DWFModel::eHandednessNone,
                     DWFToolkit::DWFUnits::eCentimeters,
                     NULL,                      // transform
                     true,                      // default lights
                     false,                     // published edges
                     true );                    // silhouettes


        W3DCamera oDefault;
        oDefault.setProjection( W3DCamera::eOrthographic );
        oDefault.setPosition( 0.0f, 0.0f, -15.0f );
        oDefault.setTarget( 1.0f, 1.4f, -0.1f );
        oDefault.setUpVector( 1.0f, 1.0f , 0.1f );
        oDefault.setField( 15.0f, 15.0f );

        oModel.createView( "default", oDefault );

        //
        // create the graphics, etc.
        //
        do_model( oModel, true );

        //
        // add some properties that apply to the model as a whole
        //
        oModel.addProperty( DWFCORE_ALLOC_OBJECT(DWFProperty(L"Cutting Plane", L"Hide", L"View Modifier")), true );
        oModel.addProperty( DWFCORE_ALLOC_OBJECT(DWFProperty(L"Origin", L"DWFToolkit Sample Applications", L"General")), true );
        oModel.addProperty( DWFCORE_ALLOC_OBJECT(DWFProperty(L"Project", L"Bianchi", L"General")), true );
        oModel.addProperty( DWFCORE_ALLOC_OBJECT(DWFProperty(L"OS", L"Red Hat Enterprise 3.0", L"General")), true );

        //
        // close the model
        //
        oModel.close();

        //
        // publish the model "into" the publisher
        //
        oModel.publish( oPublisher );

        //
        // create the DWF
        //
        oPublisher.publish();

        //
        // smoke
        //
        wcout << L"OK" << endl;
    }
    catch (DWFException& ex)
    {
        wcout << ex.type() << L": " << ex.message() << endl;
        wcout << L"(function) " << ex.function() << endl;
        wcout << L"(file) " << ex.file() << endl;
        wcout << L"(line) " << ex.line() << endl;
    }

        return 0;
}


#define countof(x) (int)(sizeof(x)/sizeof(x[0]))


class HPoint 
{ 
public:
    float        x;     
    float        y;     
    float        z;     
    inline void Set(float X,float Y,float Z=0.0) { x=X,y=Y,z=Z; }

}; 

const float PI=3.1415926f;


void CreateSphere( float *center, 
                   float radius, 
                   int numsides, 
                   int *pcount_out, 
                   float **points_out, 
                   int *flistlen_out, 
                   int **faces_out )
{
    int i, j, htile, wtile, pts_cnt, flist_cnt;
    float theta, phi, dt, dp, x, y, z;
    HPoint *points;
    int *faces;

    htile = numsides/2;
    wtile = numsides;
    pts_cnt = htile*wtile;
    points = new HPoint[ pts_cnt ];
    // faces need wtile + 1 numbers to specify each sphere end cap
    // and 5*numsides numbers for each strip between the end caps.
    // There will be numsides/2-1 of these strips.
    flist_cnt = (wtile+1)*2 + 5*(htile-1)*wtile;
    faces = new int[ flist_cnt ];

    dt = 2.0f * PI / wtile;
    dp = 1.0f * PI / (htile+1);
    phi = dp;
    for( i = 0 ; i < htile ; i++ ) {
        theta = 0;
        for( j = 0 ; j < wtile ; j++ ) {
            x = radius * (float)cos(theta) * (float)sin(phi);
            y = radius * (float)cos(phi);
            z = radius * (float)sin(theta) * (float)sin(phi);
            points[ i*wtile + j ].Set( center[0] + x, center[1] + y, center[2] + z );
            theta += dt;
        }
        phi += dp;
    }

    // set the number of points in the end caps of the sphere in the connectivity list
    faces[5*(htile-1)*wtile] = wtile;
    faces[5*(htile-1)*wtile+wtile+1] = wtile;
    for (i = 0; i < (htile-1); i++)
    {
        for (j = 0; j < wtile; j++)
        {
            // generate the connectivity list for the side quads of the cylinder
            faces[(i*wtile + j)*5] = 4; // number of points in this polygon
            faces[(i*wtile + j)*5+1]=i*wtile + j;
            faces[(i*wtile + j)*5+2]=i*wtile + (j+1)%wtile; //next point along circle; wrap at numsides
            faces[(i*wtile + j)*5+3]=(i+1)*wtile + (j+1)%wtile;  // correcsponding point at top of cylinder
            faces[(i*wtile + j)*5+4]=(i+1)*wtile + j; //next point along circle; wrap at numsides
        }
    }
    for (j = 0; j < wtile; j++)
    {
        // generate the connectivity list for the ends of the cylinder
        faces[(htile-1)*wtile*5 + j + 1]= (wtile - j - 1);
        faces[(htile-1)*wtile*5 + j + 1 + wtile + 1]= wtile*(htile-1) + j;
    }
    *pcount_out = pts_cnt;
    *points_out = (float *)points;
    *flistlen_out = flist_cnt;
    *faces_out = (int *)faces;
}


void do_model( DWFToolkit::DWFModel& rModel,
               bool bIncludeNormals )
{
    //
    // 
    //
    DWFToolkit::DWFProperty oProperty( L"", L"" );

    HPoint center; center.Set( 0.0, 0.0, 0.0 );

    float radius = 1.0f;
    float bbox[6];
    float *points, *normals;
    int p_count, flist_length, *flist, i;

    //
    // the first thing to do is create an include segment
    // that defines a collection of graphics that will be
    // reused throughout the model
    //
    DWFToolkit::DWFIncludeSegment oSphere_include = rModel.openIncludeSegment();

    //
    // segments are always first acquired from their aggregating component (i.e. Model or another Segment)
    // and then opened.  Include segments must be opened with a name. 
    //
    oSphere_include.open( "Sphere" );
    {
        //
        // we will define our sphere as a shell
        // notice that the handler is returned as a reference
        // be sure to obtain it this way; if you try and copy
        // it, you will get a compile time error since there
        // is no copy constructor defined for these objects
        //
        TK_Shell& rSphere = oSphere_include.getShellHandler();
        {
            //
            // it's always a good idea to set the bounding volume on your shells.
            //
            bbox[0] = center.x - radius;
            bbox[1] = center.y - radius;
            bbox[2] = center.z - radius;
            bbox[3] = center.x + radius;
            bbox[4] = center.y + radius;
            bbox[5] = center.z + radius;
            rSphere.SetBounding( bbox );

            //
            // Original HOOPS/Stream comment:
            // This is where you will go out to your gfx database and get the data defining the shell.
            // We're using a simple sphere generator to create a point cloud and some connectivity
            //
            CreateSphere( (float *)&center, radius, 30, &p_count, &points, &flist_length, &flist );
            
            //
            // set the vertex list for the shell
            //
            rSphere.SetPoints( p_count, points );

            //
            // set the face list for the shell
            //
            rSphere.SetFaces( flist_length, flist );

                //
                // HOOPS 3DGS will calculate simple average normals from the faces
                // usually this adequate and saves space if we don't need to store
                // normals data in the file.  Edge normals should always be defined
                // with original data.  Also, normals are quantized by default to save
                // space while preserving visual fidelity.  A sphere is going to be
                // the worst case scenario for this compression mechanism but it is
                // worth adjusting this parameter as much as possible to acheive the
                // best visual results in the smallest file.
                //
            if (bIncludeNormals)
            {
                normals = new float[ 3 * p_count ];
                for ( i = 0 ; i < p_count * 3 ; i += 3) 
                {
                    normals[ i + 0 ] = points[ i + 0 ] - center.x;
                    normals[ i + 1 ] = points[ i + 1 ] - center.y;
                    normals[ i + 2 ] = points[ i + 2 ] - center.z;
                }
             
                rSphere.SetVertexNormals( normals );

                //
                // NOTE here that the opcode handlers will always
                // copy the data that they are given
                //
                delete [] normals;
            }

            //
            // clean up
            //
            //delete [] indices;
            delete [] points;
            delete [] flist;
        }
        
        //
        // once we are completely finished with a handler,
        // we must call serialize().  this will write all
        // of our graphics into the stream and reset the handler
        // for future use
        //
        rSphere.serialize();

        //
        // let's create a property on this segment
        //
        oProperty.setName( L"Material" );
        oProperty.setValue( L"Plastic" );

        //
        // add the property to the segment
        //
        oSphere_include.addProperty( oProperty );

        //
        // also add a set of properties 
        //
        DWFToolkit::DWFPropertyContainer* pProperties = DWFCORE_ALLOC_OBJECT( DWFToolkit::DWFPropertyContainer );

        oProperty.setName( L"Cost" );
        oProperty.setValue( L"$4.44" );
        oProperty.setCategory( L"Sphere Properties" );
        pProperties->addProperty( &oProperty, false );

        oProperty.setName( L"Vendor" );
        oProperty.setValue( L"Foo Ball" );
        pProperties->addProperty( &oProperty, false );

        oProperty.setName( L"Manufacturer" );
        oProperty.setValue( L"Ball Co." );
        pProperties->addProperty( &oProperty, false );

        //
        // add the property set to the segment
        //
        oSphere_include.addPropertyContainer( pProperties );
    }

    //
    // close the segment - this will serialize everything about the segment
    // into the graphics stream. we can now use this segment as a reference
    // part in our scene graph
    //
    oSphere_include.close();


    //
    // it is preferrable to "side-stream" texture images
    // in the DWF package rather than embedded them directly
    // in the graphics channel
    // so let's add our texture images up here
    //

    //
    // first, create the texture resource and add it to the model
    // here we load an image from disk...
    //
    DWFCore::DWFStreamFileDescriptor* pTextureFile = DWFCORE_ALLOC_OBJECT( DWFCore::DWFStreamFileDescriptor("hank.jpg", "rb") );
    pTextureFile->open();

    DWFCore::DWFFileInputStream* pTextureStream = DWFCORE_ALLOC_OBJECT( DWFCore::DWFFileInputStream );
    pTextureStream->attach( pTextureFile, true );

    DWFToolkit::DWFTexture* pTexture = DWFCORE_ALLOC_OBJECT( DWFToolkit::DWFTexture("hank",
                                                                                    DWFCore::DWFMIME::kzMIMEType_JPG,
                                                                                    24, 320, 240) );

    pTexture->attach( pTextureStream, true );
    rModel.addResource( pTexture );


    //
    // create a simple scene
    //
    DWFToolkit::DWFSegment oRootSegment = rModel.openSegment();
    
    //
    // segments don't have to be named - in this case
    // we will set up some attributes that will affect
    // the entire scene unless overridden in subsegments
    //
    oRootSegment.open();
    {
        TK_Color_RGB& rColor = oRootSegment.getColorRGBHandler();
        
        //
        // red lines
        //
        rColor.SetGeometry( TKO_Geo_Line );
        rColor.SetRGB( 1.0f, 0.0f, 0.0f );
        rColor.serialize();

        //
        // we can reuse the handler 
        // green text
        //
        rColor.SetGeometry( TKO_Geo_Text );
        rColor.SetRGB( 0.0f, 0.8f, 0.1f );
        rColor.serialize();

        //
        // we can reuse the handler 
        // blue faces
        //
        rColor.SetGeometry( TKO_Geo_Face );
        rColor.SetRGB( 0.0f, 0.0f, 0.75f );
        rColor.serialize();

        //
        // a simple set of properties
        //
        DWFToolkit::DWFPropertyContainer* pPartProperties = DWFCORE_ALLOC_OBJECT( DWFToolkit::DWFPropertyContainer );

        oProperty.setName( L"Cost" );
        oProperty.setValue( L"$23.55" );
        oProperty.setCategory( L"Part Properties" );
        pPartProperties->addProperty( &oProperty, false );


        //
        // now let's create a segment that will show up in the nav tree
        // note that this is built off the root segment not the model
        //
        DWFToolkit::DWFSegment oPart1 = oRootSegment.openSegment();

        //
        // open with a name, this will show in the nav tree
        //
        oPart1.open( L"First Part" );
        {
            //
            // add the sphere from our include library
            // since the segment that we are including the spehere in
            // is already named, it will "become" a part of this segment.
            // that is, selecting "First Part" in the tree will highlight the
            // sphere and vice-versa - there will be no tree node called "Sphere"
            //
            oPart1.include( oSphere_include );

            //
            // let's draw some lines
            // these lines will finish the element named "First Part"
            // all of the geometry built into this segment will be
            // treated as a single selected part
            //
            TK_Line& rLine = oPart1.getLineHandler();

            rLine.SetPoints( 0.0f,
                             0.0f,
                             0.0f,
                             center.x + 2.0f*radius,
                             center.y + 2.0f*radius,
                             center.z + 2.0f*radius );

            rLine.serialize();

            rLine.SetPoints( center.x - 2.0f*radius,
                             center.y - 2.0f*radius,
                             center.z - 2.0f*radius,
                             0.0f,
                             0.0f,
                             0.0f );

            rLine.serialize();

            oPart1.addPropertyContainer( pPartProperties );

            //
            // test textures
            //
            DWFToolkit::DWFSegment oTexturePart = oPart1.openSegment();
            oTexturePart.open( L"Hank Box" );
            {
                //
                // make a cube
                //
                float anPoints[24] = {  0.0f, 0.0f, 6.67f,
                                        0.0f, 6.67f, 6.67f,
                                        6.67f, 6.67f, 6.67f,
                                        6.67f, 0.0f, 6.67f,
                                        0.0f, 0.0f, 13.34f,
                                        0.0f, 6.67f, 13.34f,
                                        6.67f, 6.67f, 13.34f,
                                        6.67f, 0.0f, 13.34f };

                int anFaces[30] = { 4, 0, 1, 2, 3,
                                    4, 1, 5, 6, 2,
                                    4, 5, 4, 7, 6,
                                    4, 4, 0, 3, 7,
                                    4, 3, 5, 6, 7,
                                    4, 1, 0, 4, 5 };

                TK_Shell& rCube = oTexturePart.getShellHandler();
                rCube.SetPoints( 8, anPoints );
                rCube.SetFaces( 30, anFaces );
                rCube.SetVertexParameters( anPoints );
                rCube.serialize();

                //
                // texture the cube
                //
                TK_Texture& rShellTexture = oTexturePart.getTextureHandler();

                //
                // this creates a texture from our earlier image
                // NOTE: the image is required to exist already
                //
                rShellTexture.SetFlags( 0 );
                rShellTexture.SetImage( "hank" );
                rShellTexture.SetName( "hank texture" );
                rShellTexture.serialize();

                TK_Color& rTextureColor = oTexturePart.getColorHandler();

                //
                // set the attribute for this DWFSegment such that
                // faces are "colored" with our new (named) texture
                // NOTE: the texture is required to exist already
                //
                rTextureColor.SetGeometry( TKO_Geo_Face );
                rTextureColor.SetChannels( 1 << TKO_Channel_Diffuse );
                rTextureColor.SetDiffuseName( "hank texture" );
                rTextureColor.serialize();
            }
            oTexturePart.close();

        }
        oPart1.close();

        //
        // create another part
        //
        DWFToolkit::DWFSegment oPart2 = oRootSegment.openSegment();

        oPart2.open( L"Second Part" );
        {
            //
            // let's first reposition everything in this segment
            //
            float anTransform[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
                                      0.0f, 1.0f, 0.0f, 0.0f,
                                      0.0f, 0.0f, 1.0f, 0.0f,
                                      2.33f, 0.67f, 0.0f, 1.0f };

            TK_Matrix& rMatrix = oPart2.getModellingMatrixHandler();
            rMatrix.SetMatrix( anTransform );
            rMatrix.serialize();

            //
            // open an unnamed segment
            //
            DWFToolkit::DWFSegment oSubpart = oPart2.openSegment();
            oSubpart.open();
            {
                //
                // add our sphere - this time, the sphere will appear
                // as it's own element in the nav tree.  this is due
                // to the fact that we are referencing the sphere
                // in an unnamed segment.  we could rename this element
                // if we wanted to. regardless, the behavior here is that
                // we are using a named part to build up the higher level
                // element, i.e. "Second Part"
                //
                oSubpart.include( oSphere_include );

                //
                // note that since we didn't name the segment into which this
                // part was included, we cannot modify the properties on JUST
                // the sphere, since the next named node up the tree is "Second Part"
                // any properties we add would end up there. 
                //
            }
            oSubpart.close();

            //
            // let's add a text box - use it's own segment or else
            // we will affect the included sphere - well it's not really
            // a text box but rather a polygon with some text in front of it
            //
            oSubpart = oSubpart.openSegment();
            oSubpart.open();
            {
                //
                // face
                //
                rColor.SetGeometry( TKO_Geo_Face );
                rColor.SetRGB( 0.11f, 0.88f, 0.44f );
                rColor.serialize();

                //
                // solid face
                //
                TK_Enumerated& rPatternEnum = oSubpart.getFacePatternHandler();
                rPatternEnum.SetIndex( TKO_Fill_Pattern_Solid );
                rPatternEnum.serialize();

                //
                // solid edges
                // by the way, be sure to turn on edges in the viewer -
                // "Shaded with Edges" since they are off by default
                //
                TK_Linear_Pattern& rLinePattern = oSubpart.getEdgePatternHandler();
                rLinePattern.SetPattern( TKO_Line_Pattern_Solid );
                rLinePattern.serialize();

                //
                // edge weight
                // by the way, be sure to turn on edges in the viewer -
                // "Shaded with Edges" since they are off by default
                //
                TK_Size& rPatternSize = oSubpart.getEdgeWeightHandler();
                rPatternSize.SetSize( 5.0f, TKO_Generic_Size_Points );
                rPatternSize.serialize();

                //
                // the polygon
                //
                TK_Polypoint& rPolygon = oSubpart.getPolygonHandler();

                float anBox[15] = { 2.0, 2.0, 2.0,
                                    2.0, 1.0, 2.0,
                                    1.0, 1.0, 2.0,
                                    1.0, 2.0, 2.0,
                                    2.0, 2.0, 2.0 };

                rPolygon.SetPoints( 5, anBox );
                rPolygon.serialize();

                //
                // override the green text with black
                //
                rColor.SetGeometry( TKO_Geo_Text );
                rColor.SetRGB( 0.0f, 0.0f, 0.0f );
                rColor.serialize();

                //
                // draw some text on the polygon
                //
                TK_Text& rText = oSubpart.getTextWithEncodingHandler();
                rText.SetEncoding( TKO_Enc_Unicode );
                rText.SetPosition( 1.5f, 1.5f, 1.5f );
                rText.SetString( (unsigned short const *)(const wchar_t*)L"3D DWF" );
                rText.serialize();

                //
                // by default, HOOPS draws text in 'annotation' mode only
                // we can turn this off and make our text part of the scene:
                //
                TK_Text_Font& rFont = oSubpart.getTextFontHandler();
                rFont.SetTransforms( TKO_Font_Transform_Full );
                
                rFont.SetMask( TKO_Font_Transforms );
                rFont.serialize();
            }
            oSubpart.close();

            //
            // let's make this kind of look like our first part and add some lines
            // this time we will make them a selectable unit
            //
            DWFToolkit::DWFSegment oLinesPart = oPart2.openSegment();
            
            oLinesPart.open( L"Lines" );
            {
                TK_Line& rLine = oLinesPart.getLineHandler();

                rLine.SetPoints( 0.0f,
                                 0.0f,
                                 0.0f,
                                 center.x + 2.0f*radius,
                                 center.y + 2.0f*radius,
                                 center.z + 2.0f*radius );

                rLine.serialize();

                rLine.SetPoints( center.x - 2.0f*radius,
                                 center.y - 2.0f*radius,
                                 center.z - 2.0f*radius,
                                 0.0f,
                                 0.0f,
                                 0.0f );

                rLine.serialize();
            }
            oLinesPart.close();

            //
            // add the property set to the part (by reference - part 1 owns it)
            //
            oPart2.referencePropertyContainer( *pPartProperties );

        }
        oPart2.close();

        //
        // create another part
        //
        DWFToolkit::DWFSegment oPart3 = oRootSegment.openSegment();

        oPart3.open( L"Third Part" );
        {
            //
            // red faces
            //
            rColor.SetGeometry( TKO_Geo_Face );
            rColor.SetRGB( 0.67f, 0.0f, 0.05f );
            rColor.serialize();

            //
            // let's first reposition everything in this segment
            //
            float anTransform[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
                                      0.0f, 1.0f, 0.0f, 0.0f,
                                      0.0f, 0.0f, 1.0f, 0.0f,
                                      -4.33f, -1.34f, -0.134f, 1.0f };

            TK_Matrix& rMatrix = oPart3.getModellingMatrixHandler();
            rMatrix.SetMatrix( anTransform );
            rMatrix.serialize();

            //
            // expliciting naming the segment
            //
            DWFToolkit::DWFSegment oSubpart1 = oPart3.openSegment();
            oSubpart1.open( L"Ball 1" );
            {
                //
                // add our sphere 
                //
                oSubpart1.include( oSphere_include );

                //
                // override the sphere properties
                //
                //oProperty.setName( L"Cost" );
                //oProperty.setValue( L"$3.00" );
                //oProperty.setCategory( L"Sphere Properties" );
//                oProperty.setName( L"いくらですか?" );
//                oProperty.setValue( L"さんぜん円" );
//                oProperty.setCategory( L"プロプルチズ" );
//                oSubpart1.addProperty( oProperty );

                oProperty.setName( L"Vendor" );
                oProperty.setValue( L"Dun & Broadstreet" );
                oSubpart1.addProperty( oProperty );
            }
            oSubpart1.close();

            //
            // unnamed segment
            //
            DWFToolkit::DWFSegment oSubpart2 = oPart3.openSegment();
            oSubpart2.open();
            {
                float anTransform[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
                                          0.0f, 1.0f, 0.0f, 0.0f,
                                          0.0f, 0.0f, 1.0f, 0.0f,
                                          1.0f, 1.0f, 1.0f, 1.0f };

                TK_Matrix& rMatrix = oPart3.getModellingMatrixHandler();
                rMatrix.SetMatrix( anTransform );
                rMatrix.serialize();

                //
                // including with a different name
                //
                oSubpart2.include( oSphere_include, L"Ball 2" );
            }
            oSubpart2.close();

            DWFToolkit::DWFSegment oSubpart3 = oPart3.openSegment();
            oSubpart3.open( L"Ball 3" );
            {
                float anTransform[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
                                          0.0f, 1.0f, 0.0f, 0.0f,
                                          0.0f, 0.0f, 1.0f, 0.0f,
                                          1.0f, -1.0f, -1.0f, 1.0f };

                TK_Matrix& rMatrix = oPart3.getModellingMatrixHandler();
                rMatrix.SetMatrix( anTransform );
                rMatrix.serialize();

                //
                // including with a different name
                //
                oSubpart3.include( oSphere_include );
            }
            oSubpart3.close();

            //
            // 
            //
            DWFToolkit::DWFSegment oCut = oPart3.openSegment();
            oCut.open( L"Cutting Plane" );
            {
                TK_Cutting_Plane& rCut = oCut.getCuttingPlaneHandler();
                rCut.SetPlane( -1.0f, -1.0f, 0.0f, 0.0f );
                rCut.serialize();
            }
            oCut.close();

        }
        oPart3.close();

        //
        // test embedded fonts 
        //
        DWFToolkit::DWFSegment oPart4 = oRootSegment.openSegment();
        oPart4.open();
        {
            //
            // we'll add some japanese text in MS PGothic
            // we aren't modifying the transform mask so this text will be billboarded
            //
            TK_Text_Font& rFont = oPart4.getTextFontHandler();
            rFont.SetNames( "MS PGothic" );
            rFont.SetMask( TKO_Font_Names );
            rFont.serialize();

            //
            // the text
            //
            TK_Text& rText = oPart4.getTextWithEncodingHandler();
            rText.SetEncoding( TKO_Enc_Unicode );
            rText.SetPosition( -2.0f, 4.0f, 0.0f );
//            rText.SetString( (unsigned short const *)(const wchar_t*)L"日本語のテキスト" );
            rText.serialize();

            //
            // font handling is a platform specific issue
            // unfortunately right now
            //
#ifdef  _DWFCORE_WIN32_SYSTEM

            //
            // now embed the font in the DWF package
            // notice that this is win32 specific code
            //
            HFONT hFont = CreateFontW(100, 0, 0, 0, FW_NORMAL, 0, 0, 0, 0, 0, 0, 0, 0, L"MS PGothic");

            DWFToolkit::DWFEmbeddedFontImpl_Win32* pImpl2 = new DWFToolkit::DWFEmbeddedFontImpl_Win32( hFont );
            DWFToolkit::DWFEmbeddedFont* pFont = new DWFToolkit::DWFEmbeddedFont( pImpl2 );

            //
            // add just the characters that were used
            //
            pFont->addCharacters( L"日本語のテキスト" );

            rModel.embedFont( pFont );
#endif

        }
        oPart4.close();


        //
        // add a spotlight that can be turned on and off in the viewer
        //
        DWFToolkit::DWFSegment oLightSegment = oRootSegment.openSegment();
        oLightSegment.open( L"Purple Spotlight" );
        {
            //
            // the light
            //
            TK_Spot_Light& rSpotLight = oLightSegment.getSpotLightHandler();
            rSpotLight.SetOptions( TKO_Spot_Concentration );
            rSpotLight.SetPosition( 10.0, 10.0, 10.0 );
            rSpotLight.SetTarget( 0.0, 0.0, 0.0 );
            rSpotLight.SetConcentration( 1.0 );
            rSpotLight.serialize();

            //
            // add color
            //
            TK_Color_RGB& rColor = oLightSegment.getColorRGBHandler();
            rColor.SetRGB( 1.0, 0.0, 1.0 );
            rColor.SetGeometry( TKO_Geo_Light );
            rColor.serialize();
        }
        oLightSegment.close();

    }
    oRootSegment.close();

    rModel.setBoundingSphere( 0.0f, 0.0f, 0.0f, 15.0f );

    //
    // we can also add a thumbnail image for DWF Composer R2
    //

    //
    // open as a streaming binary file
    //
    DWFCore::DWFStreamFileDescriptor* pThumbnailFile = new DWFCore::DWFStreamFileDescriptor( "thumbnail.png", "rb" );
    pThumbnailFile->open();

    //
    // create a stream and attach the file descriptor
    //
    DWFCore::DWFFileInputStream* pThumbnailStream = new DWFFileInputStream;
    pThumbnailStream->attach( pThumbnailFile, false );

    //
    // create a thumbnail image and attach the file stream
    //
    DWFToolkit::DWFImage* pThumbnail = DWFCORE_ALLOC_OBJECT( DWFToolkit::DWFImage(DWFCore::DWFMIME::kzMIMEType_PNG, 
                                                          DWFToolkit::DWFImage::eThumbnail, 
                                                          24, 
                                                          218, 
                                                          213) );

    if (pThumbnail)
    {
        pThumbnail->attach( pThumbnailStream, true );

        //
        // add to the model
        //
        rModel.addResource( pThumbnail );
    }
}

Generated on Tue May 17 12:38:49 2005 for Autodesk DWF Toolkit by  doxygen 1.4.1