//////////////////////////////////////////////////////////////////////////////// 
// 
// step3d3.cpp -    
// 
// 1.                     - ConstrAxisOperations 
// 2.                 - ConstrAxis2Point    
// 3.  ,      - ConstrAxisEdge      
// 4.  ,    , 
//                - ConstrElem   
// 5.                      - ConstrPlane3Point   
// 
//////////////////////////////////////////////////////////////////////////////// 
#include "stdafx.h"
#include <afxdllx.h> 
#include "resource.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


//-------------------------------------------------------------------------------
//       DLL
// ---
static AFX_EXTENSION_MODULE StepDLL = { NULL, NULL };


//-------------------------------------------------------------------------------
//   
//    DLL
// ---
extern "C" int APIENTRY
DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
{
  UNREFERENCED_PARAMETER( lpReserved );

  if ( dwReason == DLL_PROCESS_ATTACH )
  {
    TRACE0( "DLL Initializing!" );
 
    if ( !AfxInitExtensionModule( StepDLL, hInstance ) )
      return 0;

    new CDynLinkLibrary( StepDLL );
  }
  else if ( dwReason == DLL_PROCESS_DETACH )
  {
    TRACE0( "DLL Terminating!" );
    AfxTermExtensionModule( StepDLL );
  }
  return 1;
}


//-------------------------------------------------------------------------------
//   
//  (  ,  ,  )   <res\step3d3.rc2> ,   <step3d3.rh> 
// ---
unsigned int WINAPI LIBRARYID()
{
  return IDR_LIBID;
}


//-------------------------------------------------------------------------------
//   
// ---
void ConstrAxisOperations( IPartPtr & part );
void ConstrAxis2Point( IPartPtr & part );
void ConstrAxisEdge( IPartPtr & part );
void ConstrPlane3Point( IPartPtr & part );
void ConstrElem( IPartPtr & part );


//-------------------------------------------------------------------------------
//   
// ---
void WINAPI LIBRARYENTRY( unsigned int comm )
{
  IDocument3DPtr pDocument3d( ksGetActive3dDocument(), false/*AddRef*/ ); //       
  if ( pDocument3d )
  {
    //           ( pNew_Part -  ,
    // pEdit_Part -  , pTop_Part  -   )
    IPartPtr part( pDocument3d->GetPart( pTop_Part ), false/*AddRef*/ ); 
    if ( part )
    {
      switch ( comm )
      {
        case 1  : ConstrAxisOperations( part ); break; //   
        case 2  : ConstrAxis2Point    ( part ); break; //     
        case 3  : ConstrAxisEdge      ( part ); break; //  ,   
        case 4  : ConstrElem          ( part ); break; //  ,    ,      -
        case 5  : ConstrPlane3Point   ( part ); break; //    
      }
    }
  }
  else
  {
    CString strError;
    strError.LoadString( IDS_3DDOCERROR ); // "      3D-"
    ErrorT( ( LPTSTR )( LPCTSTR )strError ); //    
  }
  if ( ReturnResult() == etError10 ) // "!  "
    ResultNULL(); //  
}


//-------------------------------------------------------------------------------
//   
// ---
void ConstrAxisOperations( IPartPtr & part ) 
{
  //   
  IEntityPtr entitySketch( part->NewEntity( o3d_sketch ), false/*AddRef*/ );
  if ( entitySketch )
  {
    //        
    //   
    ISketchDefinitionPtr sketchDefinition( IUnknownPtr( entitySketch->GetDefinition(), false/*AddRef*/ ) );
    if ( sketchDefinition )
    {
      //     XOY
      IEntityPtr basePlane( part->GetDefaultEntity( o3d_planeXOY ), false/*AddRef*/ );
 
      //   
      sketchDefinition->SetPlane( basePlane ); //   XOY   

      //  
      entitySketch->Create(); 
      
      //     
      if ( sketchDefinition->BeginEdit() )
      {      
        //   
        Circle( 20, 0, 10, 1 );
        LineSeg( 0, 0, 0, 5, 3 );
        //     
        sketchDefinition->EndEdit();
      }             

      //  
      IEntityPtr entityRotate( part->NewEntity( o3d_baseRotated ), false/*AddRef*/ );
      if ( entityRotate ) 
      {
        //        
        //    
        IBaseRotatedDefinitionPtr baseRotatedDefinition( IUnknownPtr( entityRotate->GetDefinition(), false/*AddRef*/ ) ); 
        if ( baseRotatedDefinition ) 
        {
          //    
          IRotatedParamPtr rotatedParam( baseRotatedDefinition->RotatedParam(), false/*AddRef*/ );
          if ( rotatedParam ) 
          {
            rotatedParam->SetDirection( dtBoth );  //   ( dtNormal	-  ,
                                                   // dtReverse -  , dtBoth -   ,
                                                   // dtMiddlePlane -    )
            rotatedParam->SetToroidShape( false ); //   ( TRUE - , FALSE -  )
          }           
          //     
          baseRotatedDefinition->SetThinParam( true,   //    
                                               dtBoth, //     ( dtNormal	-  ,
                                                       // dtReverse -  , dtBoth -   ,
                                                       // dtMiddlePlane -    )
                                               1,      //     
                                               1 );    //        
          //       
          baseRotatedDefinition->SetSideParam( true,   //   ( TRUE - , FALSE -  )
                                               180 );  //   
          baseRotatedDefinition->SetSideParam( false, 180 ); 
          baseRotatedDefinition->SetSketch( entitySketch ); //    
          entityRotate->Create(); //   
        }
      }

      //   
      IEntityPtr entityAxisOperation( part->NewEntity( o3d_axisOperation ), false/*AddRef*/ );
      if ( entityAxisOperation ) 
      {
        //        
        //   
        IAxisOperationsDefinitionPtr axisOperationsDefinition( IUnknownPtr( entityAxisOperation->GetDefinition(), false/*AddRef*/ ) );
        if ( axisOperationsDefinition ) 
        {
          axisOperationsDefinition->SetOperation( entityRotate ); //    
          entityAxisOperation->Create(); // C  
        }
      }
      MessageT( _T(" ") );
    }
  }
}


//-------------------------------------------------------------------------------
//     
// ---
void ConstrAxis2Point( IPartPtr & part ) 
{
  //   
  IEntityPtr entitySketch( part->NewEntity( o3d_sketch ), false/*AddRef*/ );
  if ( entitySketch )
  {
    //        
    //   
    ISketchDefinitionPtr sketchDefinition( IUnknownPtr( entitySketch->GetDefinition(), false/*AddRef*/ ) );
    if ( sketchDefinition )
    {
      //     XOY
      IEntityPtr basePlane( part->GetDefaultEntity( o3d_planeXOY ), false/*AddRef*/ );
 
      //   
      sketchDefinition->SetPlane( basePlane ); //   XOY   
 
      //  
      entitySketch->Create(); 
        
      //     
      if ( sketchDefinition->BeginEdit() )
      {
        //    - 
        LineSeg(  50,  50, -50,  50, 1 );
        LineSeg(  50, -50, -50, -50, 1 );
        LineSeg(  50, -50,  50,  50, 1 );
        LineSeg( -50, -50, -50,  50, 1 );
        //     
        sketchDefinition->EndEdit();                  
      }

      //   
      IEntityPtr entityExtrusion( part->NewEntity( o3d_baseExtrusion ), false/*AddRef*/ );
      if ( entityExtrusion ) 
      {
        //        
        //    
        IBaseExtrusionDefinitionPtr baseExtrusionDefinition( IUnknownPtr( entityExtrusion->GetDefinition(), false/*AddRef*/ ) ); 
        if ( baseExtrusionDefinition ) 
        {
          baseExtrusionDefinition->SetDirectionType( dtNormal );  //   ( dtNormal	-  ,
                                                                  // dtReverse -  , dtBoth -   ,
                                                                  // dtMiddlePlane -    )
          //      
          baseExtrusionDefinition->SetSideParam( true,    //   ( TRUE -  , FALSE -   )
                                                 etBlind, //   ( etBlind	-   ,
                                                          // etThroughAll -   , etUpToVertexTo -    ,
                                                          // etUpToVertexFrom -    , etUpToSurfaceTo	-    ,
                                                          // etUpToSurfaceFrom	-    , etUpToNearSurface	-    )
                                                 20,      //  
                                                 0,       //  
                                                 false ); //   ( TRUE -  , FALSE -   )
          //     
          baseExtrusionDefinition->SetThinParam( true,   //    
                                                 dtBoth, //     ( dtNormal	-  ,
                                                         // dtReverse -  , dtBoth -   ,
                                                         // dtMiddlePlane -    )
                                                 20,     //     
                                                 20 );   //       
          baseExtrusionDefinition->SetSketch( entitySketch ); //   
          entityExtrusion->Create(); //   
        }
      }
    }

    //    
    //          -     
    IEntityCollectionPtr entityCollection( part->EntityCollection( o3d_vertex ), false/*AddRef*/ );     
    if ( (bool)entityCollection && entityCollection->GetCount() ) 
    {
      //     
      IEntityPtr entityAxis2Point( part->NewEntity( o3d_axis2Points ), false/*AddRef*/ );
      if ( entityAxis2Point ) 
      {
        //        
        //   ,    
        IAxis2PointsDefinitionPtr axis2PointsDefinition( IUnknownPtr( entityAxis2Point->GetDefinition(), false/*AddRef*/ ) );
        if ( axis2PointsDefinition ) 
        {
          //        
          IEntityPtr ePtr1( entityCollection->GetByIndex( 0 ), false/*AddRef*/ );
          axis2PointsDefinition->SetPoint( 1, ePtr1 ); //       (1  2)
                                            
          IEntityPtr ePtr2( entityCollection->GetByIndex( entityCollection->GetCount()- 1 ), false/*AddRef*/ );
          axis2PointsDefinition->SetPoint( 2, ePtr2 );
          entityAxis2Point->Create(); //   ,    
        }
      }
    }
  }
}


//-------------------------------------------------------------------------------
//  ,   
// ---
void ConstrAxisEdge( IPartPtr& part ) 
{
  //   
  IEntityPtr entitySketch( part->NewEntity( o3d_sketch ), false/*AddRef*/ );
  if ( entitySketch )
  {
    //        
    //   
    ISketchDefinitionPtr  sketchDefinition( IUnknownPtr( entitySketch->GetDefinition(), false/*AddRef*/ ) );
    if ( sketchDefinition )
    {
      //     XOY
      IEntityPtr basePlane( part->GetDefaultEntity( o3d_planeXOY ), false/*AddRef*/ );
 
      //   
      sketchDefinition->SetPlane( basePlane ); //   XOY   
 
      //  
      entitySketch->Create(); 
        
      //     
      if ( sketchDefinition->BeginEdit() )
      { 
        //    - 
        LineSeg(  50,  50, -50,  50, 1 );
        LineSeg(  50, -50, -50, -50, 1 );
        LineSeg(  50, -50,  50,  50, 1 );
        LineSeg( -50, -50, -50,  50, 1 );
        //     
        sketchDefinition->EndEdit();  
      }

      //   
      IEntityPtr entityExtrusion( part->NewEntity( o3d_baseExtrusion ), false/*AddRef*/ );
      if ( entityExtrusion ) 
      {
        //        
        //    
        IBaseExtrusionDefinitionPtr baseExtrusionDefinition( IUnknownPtr( entityExtrusion->GetDefinition(), false/*AddRef*/ ) ); 
        if ( baseExtrusionDefinition ) 
        {
          baseExtrusionDefinition->SetDirectionType( dtNormal );  //   ( dtNormal	-  ,
                                                                  // dtReverse -  , dtBoth -   ,
                                                                  // dtMiddlePlane -    )
          //      
          baseExtrusionDefinition->SetSideParam( true,    //   ( TRUE -  , FALSE -   )
                                                 etBlind, //   ( etBlind	-   ,
                                                          // etThroughAll -   , etUpToVertexTo -    ,
                                                          // etUpToVertexFrom -    , etUpToSurfaceTo	-    ,
                                                          // etUpToSurfaceFrom	-    , etUpToNearSurface	-    )
                                                 20,      //  
                                                 0,       //  
                                                 false ); //   ( TRUE -  , FALSE -   )
          //     
          baseExtrusionDefinition->SetThinParam( true,   //    
                                                 dtBoth, //     ( dtNormal	-  ,
                                                         // dtReverse -  , dtBoth -   ,
                                                         // dtMiddlePlane -    )
                                                 20,     //     
                                                 20 );   //       
          baseExtrusionDefinition->SetSketch( entitySketch ); //   
          entityExtrusion->Create(); //   
        }
      }
    }
       
    //   
    //          -    
    IEntityCollectionPtr entityCollection( part->EntityCollection( o3d_edge ), false/*AddRef*/ );
    if ( (bool)entityCollection && entityCollection->GetCount() ) 
    {
      //    
      IEntityPtr entityAxisEdge( part->NewEntity( o3d_axisEdge ), false/*AddRef*/ );
      if ( entityAxisEdge ) 
      {
        //        
        //   ,    
        IAxisEdgeDefinitionPtr axisEdgeDefinition( IUnknownPtr( entityAxisEdge->GetDefinition(), false/*AddRef*/ ) );
        if ( axisEdgeDefinition ) 
        {
          //      
          IEntityPtr ePtr( entityCollection->GetByIndex(0), false/*AddRef*/ );
          axisEdgeDefinition->SetEdge( ePtr );
          entityAxisEdge->Create(); //   ,    
        }
      }
    }
  }
}


//-------------------------------------------------------------------------------
//    
// ---
void ConstrPlane3Point( IPartPtr& part )
{
  //   
  IEntityPtr entitySketch( part->NewEntity( o3d_sketch ), false/*AddRef*/ );
  if ( entitySketch )
  {
    //        
    //   
    ISketchDefinitionPtr sketchDefinition( IUnknownPtr( entitySketch->GetDefinition(), false/*AddRef*/ ) );
    if ( sketchDefinition )
    {
      //     XOY
      IEntityPtr basePlane( part->GetDefaultEntity( o3d_planeXOY ), false/*AddRef*/ );
 
      //   
      sketchDefinition->SetPlane( basePlane ); //   XOY   
 
      //  
      entitySketch->Create(); 
        
      //     
      if ( sketchDefinition->BeginEdit() )
      {
        //    - 
        LineSeg(  50,  50, -50,  50, 1 );
        LineSeg(  50, -50, -50, -50, 1 );
        LineSeg(  50, -50,  50,  50, 1 );
        LineSeg( -50, -50, -50,  50, 1 );
        //     
        sketchDefinition->EndEdit();
      }

      //   
      IEntityPtr entityExtrusion( part->NewEntity( o3d_baseExtrusion ), false/*AddRef*/ );
      if ( entityExtrusion ) 
      {
        //        
        //    
        IBaseExtrusionDefinitionPtr baseExtrusionDefinition( IUnknownPtr( entityExtrusion->GetDefinition(), false/*AddRef*/ ) ); 
        if ( baseExtrusionDefinition ) 
        {
          baseExtrusionDefinition->SetDirectionType( dtNormal );  //   ( dtNormal	-  ,
                                                                  // dtReverse -  , dtBoth -   ,
                                                                  // dtMiddlePlane -    )
          //      
          baseExtrusionDefinition->SetSideParam( true,    //   ( TRUE -  , FALSE -   )
                                                 etBlind, //   ( etBlind	-   ,
                                                        // etThroughAll -   , etUpToVertexTo -    ,
                                                            // etUpToVertexFrom -    , etUpToSurfaceTo	-    ,
                                                          // etUpToSurfaceFrom	-    , etUpToNearSurface	-    )
                                                 20,      //  
                                                 30,      //   
                                                 false ); //   ( TRUE -  , FALSE -   )
          //     
          baseExtrusionDefinition->SetThinParam( true,   //    
                                                 dtBoth, //     ( dtNormal	-  ,
                                                         // dtReverse -  , dtBoth -   ,
                                                         // dtMiddlePlane -    )
                                                 10,     //     
                                                 10 );   //       
          baseExtrusionDefinition->SetSketch( entitySketch ); //   
          entityExtrusion->Create(); //   
        }
      }
    }

    //    
    //          -   
    IEntityCollectionPtr entityCollection( part->EntityCollection( o3d_vertex ), false/*AddRef*/ );
    if ( (bool)entityCollection && entityCollection->GetCount() > 2 ) 
    {
      //  ,    
      IEntityPtr entityPlane3Point( part->NewEntity( o3d_plane3Points ), false/*AddRef*/ );
      if ( entityPlane3Point ) 
      {
        //        
        //  ,    
        IPlane3PointsDefinitionPtr plane3PointDefinition( IUnknownPtr( entityPlane3Point->GetDefinition(), false/*AddRef*/ ) );
        if ( plane3PointDefinition ) 
        {
          //        
          plane3PointDefinition->SetPoint( 1,                                    //   ( 1  3)
                                              IEntityPtr( entityCollection->GetByIndex( 0 ), false/*AddRef*/ ) );  //    
          plane3PointDefinition->SetPoint( 2, IEntityPtr( entityCollection->GetByIndex( 1 ), false/*AddRef*/ ) );
          plane3PointDefinition->SetPoint( 3, IEntityPtr( entityCollection->GetByIndex( 2 ), false/*AddRef*/ ) );
          entityPlane3Point->Create(); //  ,    
        }
      }
    }
  }
}


//-------------------------------------------------------------------------------
//   ,          
// ---
void ConstrElem( IPartPtr& part ) 
{
  //   
  IEntityPtr entityPlaneOffset( part->NewEntity( o3d_planeOffset ), false/*AddRef*/ );
  if ( entityPlaneOffset ) 
  {
    //        
    //    
    IPlaneOffsetDefinitionPtr planeOffsetDefinition( IUnknownPtr( entityPlaneOffset->GetDefinition(), false/*AddRef*/ ) );
    if ( planeOffsetDefinition ) 
    {
      //    
      planeOffsetDefinition->SetOffset( 150 ); //    
      
      //     XOY
      IEntityPtr basePlane( part->GetDefaultEntity( o3d_planeXOY ), false/*AddRef*/ );

      basePlane->SetName( _bstr_t(_T("XOX")) );         //    
      
      basePlane->Update();                          //    

      planeOffsetDefinition->SetPlane( basePlane ); //   XOY   

      planeOffsetDefinition->SetDirection( false ); //      ( TRUE -  , FALSE -   )
      entityPlaneOffset->SetName( _bstr_t(_T(" ")) ); //    

      entityPlaneOffset->Create(); //   

      MessageT( _T("   ") );  
      planeOffsetDefinition->SetOffset( 50 ); //     
      //     YOZ
      basePlane = part->GetDefaultEntity( o3d_planeYOZ );
      basePlane->SetName( _bstr_t(_T("YOZ")) );   //    
      basePlane->Update();                    //    
     
      planeOffsetDefinition->SetPlane( basePlane ); //   YOZ   
      planeOffsetDefinition->SetDirection( true );  //      
      
      entityPlaneOffset->Update(); //    

      MessageT( _T("    ") );

      //     XOY
      basePlane = part->GetDefaultEntity( o3d_planeXOY );
      basePlane->SetName( _bstr_t(_T("XOY")) ); //    
      basePlane->Update(); //    

      //     
      IEntityPtr entityAxis2Planes( part->NewEntity( o3d_axis2Planes ), false/*AddRef*/ );
      if ( entityAxis2Planes ) 
      {
        //        
        //   ,    
        IAxis2PlanesDefinitionPtr axis2PlanesDefinition( IUnknownPtr( entityAxis2Planes->GetDefinition(), false/*AddRef*/ ) );
        if ( axis2PlanesDefinition ) 
        {
          axis2PlanesDefinition->SetPlane( 1, entityPlaneOffset ); //    -  
          axis2PlanesDefinition->SetPlane( 2, basePlane );         //    -  XOY
          entityAxis2Planes->SetName( _bstr_t(_T("   ")) ); //   
          entityAxis2Planes->Create();  //  ,     

          MessageT( _T("       ") );

          //     XOZ
          basePlane = part->GetDefaultEntity( o3d_planeXOZ );
          basePlane->SetName( _bstr_t(_T("XOZ")) ); //    
          basePlane->Update(); //    
                                 
          axis2PlanesDefinition->SetPlane( 2, basePlane ); //    -  XOZ
          entityAxis2Planes->Update(); //    

          MessageT( _T("     \n    45") );

          //       
          IEntityPtr entityPlaneAngle( part->NewEntity( o3d_planeAngle ), false/*AddRef*/ );
          if ( entityPlaneAngle ) 
          {
            //        
            //       
            IPlaneAngleDefinitionPtr planeAngleDefinition( IUnknownPtr( entityPlaneAngle->GetDefinition(), false/*AddRef*/ ) );
            if ( planeAngleDefinition ) 
            {
              planeAngleDefinition->SetAngle( 45 ); //     
              planeAngleDefinition->SetPlane( entityPlaneOffset ); //   -  
              planeAngleDefinition->SetAxis( entityAxis2Planes );  //   - ,     
              entityPlaneAngle->SetName( _bstr_t(_T("     ")) );  //   
              entityPlaneAngle->Create();                          //       

              MessageT( _T("    ") );

              planeAngleDefinition->SetPlane( basePlane ); //   XOZ   
              entityPlaneAngle->Update(); //    
            }
          }
        }
      }
    }
  }
}