bool Model::LoadS3O(const char *filename, IProgressCtl& /*progctl*/) { S3OHeader header; size_t read_result; FILE *file = fopen (filename, "rb"); if (!file) return false; read_result = fread (&header, sizeof(S3OHeader), 1, file); if (read_result != (size_t)1) throw std::runtime_error ("Couldn't read S3O header."); logger.Trace (NL_Error,"Wrong version. Only version 1 is supported"); if (memcmp (header.magic, S3O_ID, 12)) { logger.Trace (NL_Error, "S3O model %s has wrong identification", filename); fclose (file); return false; } if (header.version != 0) { logger.Trace (NL_Error, "S3O model %s has wrong version (%d, wanted: %d)", filename, header.version, 0); fclose (file); return false; } radius = header.radius; mid.set (-header.midx, header.midy, header.midz); height = header.height; root = S3O_LoadObject (file, header.rootPiece); MirrorX(root); string mdlPath = GetFilePath (filename); // load textures for (int tex=0;tex<2;tex++) { if ( !(tex ? header.texture2 : header.texture1)) continue; texBindings.push_back(TextureBinding()); TextureBinding &tb = texBindings.back (); tb.name = ReadString (tex ? header.texture2 : header.texture1, file); tb.texture = new Texture (tb.name, mdlPath); if (!tb.texture->IsLoaded ()) tb.texture = 0; } mapping = MAPPING_S3O; fclose (file); return true; }
bool Model::SaveS3O(const char *filename, IProgressCtl& /*progctl*/) { S3OHeader header; size_t write_result; memset (&header,0,sizeof(S3OHeader)); memcpy (header.magic, S3O_ID, 12); if (!root) return false; FILE *f = fopen (filename, "wb"); if (!f) return false; fseek (f, sizeof(S3OHeader), SEEK_SET); header.rootPiece = ftell(f); if (root) { MdlObject *cloned = root->Clone(); IterateObjects (cloned, ApplyOrientationAndScaling); MirrorX(cloned); S3O_SaveObject (f, cloned); delete cloned; } for (uint tex=0;tex<texBindings.size();tex++) { if (tex >= texBindings.size ()) break; TextureBinding &tb = texBindings[tex]; if (!tb.name.empty()) { if (tex==0) header.texture1 = ftell(f); if (tex==1) header.texture2 = ftell(f); WriteZStr (f, tb.name); } } header.radius = radius; header.height = height; header.midx = -mid.x; header.midy = mid.y; header.midz = mid.z; fseek (f, 0, SEEK_SET); write_result = fwrite (&header, sizeof(S3OHeader), 1, f); if (write_result != (size_t)1) throw std::runtime_error ("Couldn't write S3O header."); fclose (f); return true; }
static void MirrorX(MdlObject *o) { PolyMesh* pm = o->GetPolyMesh(); if (pm) { for (int a=0;a<pm->verts.size();a++) { pm->verts[a].pos.x *= -1.0f; pm->verts[a].normal.x *= -1.0f; } for (int a=0;a<pm->poly.size();a++) pm->poly[a]->Flip(); } o->position.x *= -1.0f; for (int a=0;a<o->childs.size();a++) MirrorX(o->childs[a]); }
bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC ) { bool nextcmd = false; bool zoom_command = false; BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate; if( block->GetCount() ) { BLOCK_STATE_T state = block->GetState(); BLOCK_COMMAND_T command = block->GetCommand(); m_canvas->CallEndMouseCapture( aDC ); block->SetState( state ); block->SetCommand( command ); m_canvas->SetMouseCapture( DrawAndSizingBlockOutlines, AbortBlockCurrentCommand ); SetCrossHairPosition( block->GetEnd() ); if( block->GetCommand() != BLOCK_ABORT ) m_canvas->MoveCursorToCrossHair(); } if( m_canvas->IsMouseCaptured() ) { switch( block->GetCommand() ) { case BLOCK_IDLE: DisplayError( this, wxT( "Error in HandleBlockPLace()" ) ); break; case BLOCK_ROTATE: GetScreen()->UpdatePickList(); DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false ); if( block->GetCount() ) { // Compute the rotation center and put it on grid: wxPoint rotationPoint = block->Centre(); rotationPoint = GetNearestGridPosition( rotationPoint ); SetCrossHairPosition( rotationPoint ); SaveCopyInUndoList( block->GetItems(), UR_ROTATED, rotationPoint ); RotateListOfItems( block->GetItems(), rotationPoint ); OnModify(); } block->ClearItemsList(); GetScreen()->TestDanglingEnds( m_canvas, aDC ); m_canvas->Refresh(); break; case BLOCK_DRAG: case BLOCK_DRAG_ITEM: // Drag from a drag command GetScreen()->BreakSegmentsOnJunctions(); // fall through case BLOCK_MOVE: case BLOCK_COPY: if( block->GetCommand() == BLOCK_DRAG_ITEM && GetScreen()->GetCurItem() != NULL ) { // This is a drag command, not a mouse block command // Only this item is put in list ITEM_PICKER picker; picker.SetItem( GetScreen()->GetCurItem() ); block->PushItem( picker ); } else { // Collect all items in the locate block GetScreen()->UpdatePickList(); } // fall through case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/ if( block->GetCount() ) { nextcmd = true; GetScreen()->SelectBlockItems(); m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false ); m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines ); m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false ); block->SetState( STATE_BLOCK_MOVE ); } else { m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false ); m_canvas->SetMouseCapture( NULL, NULL ); } break; case BLOCK_DELETE: GetScreen()->UpdatePickList(); DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false ); if( block->GetCount() ) { DeleteItemsInList( m_canvas, block->GetItems() ); OnModify(); } block->ClearItemsList(); GetScreen()->TestDanglingEnds( m_canvas, aDC ); m_canvas->Refresh(); break; case BLOCK_SAVE: // Save a copy of items in paste buffer GetScreen()->UpdatePickList(); DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false ); if( block->GetCount() ) { wxPoint move_vector = -GetScreen()->m_BlockLocate.GetLastCursorPosition(); copyBlockItems( block->GetItems() ); MoveItemsInList( m_blockItems.GetItems(), move_vector ); } block->ClearItemsList(); break; case BLOCK_PASTE: block->SetState( STATE_BLOCK_MOVE ); break; case BLOCK_ZOOM: zoom_command = true; break; case BLOCK_MIRROR_X: GetScreen()->UpdatePickList(); DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false ); if( block->GetCount() ) { // Compute the mirror center and put it on grid. wxPoint mirrorPoint = block->Centre(); mirrorPoint = GetNearestGridPosition( mirrorPoint ); SetCrossHairPosition( mirrorPoint ); SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_X, mirrorPoint ); MirrorX( block->GetItems(), mirrorPoint ); OnModify(); } GetScreen()->TestDanglingEnds( m_canvas, aDC ); m_canvas->Refresh(); break; case BLOCK_MIRROR_Y: GetScreen()->UpdatePickList(); DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false ); if( block->GetCount() ) { // Compute the mirror center and put it on grid. wxPoint mirrorPoint = block->Centre(); mirrorPoint = GetNearestGridPosition( mirrorPoint ); SetCrossHairPosition( mirrorPoint ); SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_Y, mirrorPoint ); MirrorY( block->GetItems(), mirrorPoint ); OnModify(); } GetScreen()->TestDanglingEnds( m_canvas, aDC ); m_canvas->Refresh(); break; default: break; } } if( block->GetCommand() == BLOCK_ABORT ) { GetScreen()->ClearDrawingState(); m_canvas->Refresh(); } if( ! nextcmd ) { block->SetState( STATE_NO_BLOCK ); block->SetCommand( BLOCK_IDLE ); GetScreen()->SetCurItem( NULL ); m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false ); } if( zoom_command ) Window_Zoom( GetScreen()->m_BlockLocate ); return nextcmd; }
void SCH_EDIT_FRAME::HandleBlockEndByPopUp( int Command, wxDC* DC ) { bool blockCmdFinished = true; /* set to false for block command which * have a next step * and true if the block command is finished here */ BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate; // can convert only a block move command to an other command if( block->m_Command != BLOCK_MOVE ) return; // Useless if the new command is block move because we are already in block move. if( Command == BLOCK_MOVE ) return; block->m_Command = (CmdBlockType) Command; block->SetMessageBlock( this ); switch( block->m_Command ) { case BLOCK_COPY: /* move to copy */ block->m_State = STATE_BLOCK_MOVE; blockCmdFinished = false; break; case BLOCK_DRAG: /* move to Drag */ if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); // Clear list of items to move, and rebuild it with items to drag: block->ClearItemsList(); GetScreen()->BreakSegmentsOnJunctions(); GetScreen()->UpdatePickList(); if( block->GetCount() ) { blockCmdFinished = false; GetScreen()->SelectBlockItems(); if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); block->m_State = STATE_BLOCK_MOVE; } break; case BLOCK_DELETE: /* move to Delete */ if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); if( block->GetCount() ) { DeleteItemsInList( m_canvas, block->m_ItemsSelection ); OnModify(); } GetScreen()->TestDanglingEnds( m_canvas, DC ); m_canvas->Refresh(); break; case BLOCK_SAVE: /* Save list in paste buffer*/ if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); if( block->GetCount() ) { wxPoint move_vector = -GetScreen()->m_BlockLocate.m_BlockLastCursorPosition; copyBlockItems( block->m_ItemsSelection ); MoveItemsInList( m_blockItems.m_ItemsSelection, move_vector ); } break; case BLOCK_ZOOM: /* Window Zoom */ m_canvas->CallEndMouseCapture( DC ); m_canvas->SetCursor( (wxStockCursor) m_canvas->GetDefaultCursor() ); Window_Zoom( GetScreen()->m_BlockLocate ); break; case BLOCK_ROTATE: if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); if( block->GetCount() ) { /* Compute the rotation center and put it on grid */ wxPoint rotationPoint = block->Centre(); rotationPoint = GetScreen()->GetNearestGridPosition( rotationPoint ); GetScreen()->SetCrossHairPosition( rotationPoint ); SaveCopyInUndoList( block->m_ItemsSelection, UR_ROTATED, rotationPoint ); RotateListOfItems( block->m_ItemsSelection, rotationPoint ); OnModify(); } GetScreen()->TestDanglingEnds( m_canvas, DC ); m_canvas->Refresh(); break; case BLOCK_MIRROR_X: if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); if( block->GetCount() ) { /* Compute the mirror center and put it on grid */ wxPoint mirrorPoint = block->Centre(); mirrorPoint = GetScreen()->GetNearestGridPosition( mirrorPoint ); GetScreen()->SetCrossHairPosition( mirrorPoint ); SaveCopyInUndoList( block->m_ItemsSelection, UR_MIRRORED_X, mirrorPoint ); MirrorX( block->m_ItemsSelection, mirrorPoint ); OnModify(); } GetScreen()->TestDanglingEnds( m_canvas, DC ); m_canvas->Refresh(); break; case BLOCK_MIRROR_Y: if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); if( block->GetCount() ) { /* Compute the mirror center and put it on grid */ wxPoint mirrorPoint = block->Centre(); mirrorPoint = GetScreen()->GetNearestGridPosition( mirrorPoint ); GetScreen()->SetCrossHairPosition( mirrorPoint ); SaveCopyInUndoList( block->m_ItemsSelection, UR_MIRRORED_Y, mirrorPoint ); MirrorY( block->m_ItemsSelection, mirrorPoint ); OnModify(); } GetScreen()->TestDanglingEnds( m_canvas, DC ); m_canvas->Refresh(); break; default: break; } if( blockCmdFinished ) { block->Clear(); GetScreen()->SetCurItem( NULL ); m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false ); } }