/* * Import Arc entities. */ void DXF2BRD_CONVERTER::addArc( const DRW_Arc& data ) { DRAWSEGMENT* segm = ( m_useModuleItems ) ? static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT; segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); segm->SetShape( S_ARC ); // Init arc centre: wxPoint center( mapX( data.basePoint.x ), mapY( data.basePoint.y ) ); segm->SetCenter( center ); // Init arc start point double arcStartx = data.radious; double arcStarty = 0; double startangle = data.staangle; double endangle = data.endangle; RotatePoint( &arcStartx, &arcStarty, -RAD2DECIDEG( startangle ) ); wxPoint arcStart( mapX( arcStartx + data.basePoint.x ), mapY( arcStarty + data.basePoint.y ) ); segm->SetArcStart( arcStart ); // calculate arc angle (arcs are CCW, and should be < 0 in Pcbnew) double angle = -RAD2DECIDEG( endangle - startangle ); if( angle > 0.0 ) angle -= 3600.0; segm->SetAngle( angle ); segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness : data.thickness ) ); m_newItemsList.push_back( segm ); }
/* * Import Arc entities. */ void DXF2BRD_CONVERTER::addArc( const DRW_Arc& data ) { DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd ); segm->SetLayer( m_brdLayer ); segm->SetShape( S_ARC ); // Init arc centre: wxPoint center( mapX( data.basePoint.x ), mapY( data.basePoint.y ) ); segm->SetCenter( center ); // Init arc start point double arcStartx = data.radious; double arcStarty = 0; double startangle = data.staangle; double endangle = data.endangle; RotatePoint( &arcStartx, &arcStarty, -RAD2DECIDEG( startangle ) ); wxPoint arcStart( mapX( arcStartx + data.basePoint.x ), mapY( arcStarty + data.basePoint.y ) ); segm->SetArcStart( arcStart ); // calculate arc angle (arcs are CCW, and should be < 0 in Pcbnew) double angle = -RAD2DECIDEG( endangle - startangle ); if( angle > 0.0 ) angle -= 3600.0; segm->SetAngle( angle ); segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness : data.thickness ) ); appendToBoard( segm ); }
void DIALOG_GRAPHIC_ITEM_PROPERTIES::OnOkClick( wxCommandEvent& event ) /*******************************************************************/ /* Copy values in text control to the item parameters */ { m_parent->SaveCopyInUndoList( m_Item, UR_CHANGED ); wxString msg; if( m_DC ) m_Item->Draw( m_parent->GetCanvas(), m_DC, GR_XOR ); msg = m_Center_StartXCtrl->GetValue(); m_Item->SetStartX( ReturnValueFromString( g_UserUnit, msg, m_parent->GetInternalUnits() )); msg = m_Center_StartYCtrl->GetValue(); m_Item->SetStartY( ReturnValueFromString( g_UserUnit, msg, m_parent->GetInternalUnits() )); msg = m_EndX_Radius_Ctrl->GetValue(); m_Item->SetEndX( ReturnValueFromString( g_UserUnit, msg, m_parent->GetInternalUnits() )); msg = m_EndY_Ctrl->GetValue(); m_Item->SetEndY( ReturnValueFromString( g_UserUnit, msg, m_parent->GetInternalUnits() )); msg = m_ThicknessCtrl->GetValue(); m_Item->SetWidth( ReturnValueFromString( g_UserUnit, msg, m_parent->GetInternalUnits() )); msg = m_DefaultThicknessCtrl->GetValue(); int thickness = ReturnValueFromString( g_UserUnit, msg, m_parent->GetInternalUnits() ); m_Item->SetLayer( m_LayerSelectionCtrl->GetCurrentSelection() + FIRST_NO_COPPER_LAYER); if( m_Item->GetLayer() == EDGE_N ) m_brdSettings.m_EdgeSegmentWidth = thickness; else m_brdSettings.m_DrawSegmentWidth = thickness; if( m_Item->GetShape() == S_ARC ) { double angle; m_Angle_Ctrl->GetValue().ToDouble( &angle ); NORMALIZE_ANGLE_360(angle); m_Item->SetAngle( angle ); } m_parent->OnModify(); if( m_DC ) m_Item->Draw( m_parent->GetCanvas(), m_DC, GR_OR ); m_Item->DisplayInfo( m_parent ); m_parent->SetDesignSettings( m_brdSettings ); Close( true ); }
void DIALOG_GRAPHIC_ITEM_PROPERTIES::OnOkClick( wxCommandEvent& event ) { if( !itemValuesOK() ) return; m_parent->SaveCopyInUndoList( m_item, UR_CHANGED ); wxString msg; if( m_DC ) m_item->Draw( m_parent->GetCanvas(), m_DC, GR_XOR ); msg = m_Center_StartXCtrl->GetValue(); m_item->SetStartX( ValueFromString( g_UserUnit, msg ) ); msg = m_Center_StartYCtrl->GetValue(); m_item->SetStartY( ValueFromString( g_UserUnit, msg ) ); msg = m_EndX_Radius_Ctrl->GetValue(); m_item->SetEndX( ValueFromString( g_UserUnit, msg ) ); msg = m_EndY_Ctrl->GetValue(); m_item->SetEndY( ValueFromString( g_UserUnit, msg ) ); msg = m_ThicknessCtrl->GetValue(); m_item->SetWidth( ValueFromString( g_UserUnit, msg ) ); msg = m_DefaultThicknessCtrl->GetValue(); int thickness = ValueFromString( g_UserUnit, msg ); m_item->SetLayer( ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) ); if( m_item->GetLayer() == Edge_Cuts ) m_brdSettings.m_EdgeSegmentWidth = thickness; else m_brdSettings.m_DrawSegmentWidth = thickness; if( m_item->GetShape() == S_ARC ) { double angle; m_Angle_Ctrl->GetValue().ToDouble( &angle ); NORMALIZE_ANGLE_360( angle ); m_item->SetAngle( angle ); } m_parent->OnModify(); if( m_DC ) m_item->Draw( m_parent->GetCanvas(), m_DC, GR_OR ); m_parent->SetMsgPanel( m_item ); m_parent->SetDesignSettings( m_brdSettings ); Close( true ); }
bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataFromWindow() { if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataFromWindow() ) return false; m_parent->SaveCopyInUndoList( m_item, UR_CHANGED ); wxString msg; if( m_DC ) m_item->Draw( m_parent->GetCanvas(), m_DC, GR_XOR ); msg = m_Center_StartXCtrl->GetValue(); m_item->SetStartX( ValueFromString( g_UserUnit, msg ) ); msg = m_Center_StartYCtrl->GetValue(); m_item->SetStartY( ValueFromString( g_UserUnit, msg ) ); msg = m_EndX_Radius_Ctrl->GetValue(); m_item->SetEndX( ValueFromString( g_UserUnit, msg ) ); msg = m_EndY_Ctrl->GetValue(); m_item->SetEndY( ValueFromString( g_UserUnit, msg ) ); msg = m_ThicknessCtrl->GetValue(); m_item->SetWidth( ValueFromString( g_UserUnit, msg ) ); msg = m_DefaultThicknessCtrl->GetValue(); int thickness = ValueFromString( g_UserUnit, msg ); m_item->SetLayer( ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) ); if( m_item->GetLayer() == Edge_Cuts ) m_brdSettings.m_EdgeSegmentWidth = thickness; else m_brdSettings.m_DrawSegmentWidth = thickness; if( m_item->GetShape() == S_ARC ) { m_item->SetAngle( m_AngleValue * 10.0 ); } m_parent->OnModify(); if( m_DC ) m_item->Draw( m_parent->GetCanvas(), m_DC, GR_OR ); m_parent->SetMsgPanel( m_item ); m_parent->SetDesignSettings( m_brdSettings ); return true; }
void DXF2BRD_CONVERTER::addLine( const DRW_Line& aData ) { DRAWSEGMENT* segm = ( m_useModuleItems ) ? static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT; segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); wxPoint start( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) ); segm->SetStart( start ); wxPoint end( mapX( aData.secPoint.x ), mapY( aData.secPoint.y ) ); segm->SetEnd( end ); segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); m_newItemsList.push_back( segm ); }
/* * Import line entities. */ void DXF2BRD_CONVERTER::addLine( const DRW_Line& data ) { DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd ); segm->SetLayer( m_brdLayer ); wxPoint start( mapX( data.basePoint.x ), mapY( data.basePoint.y ) ); segm->SetStart( start ); wxPoint end( mapX( data.secPoint.x ), mapY( data.secPoint.y ) ); segm->SetEnd( end ); segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness : data.thickness ) ); appendToBoard( segm ); }
void BRDITEMS_PLOTTER::PlotPcbTarget( PCB_TARGET* aMire ) { int dx1, dx2, dy1, dy2, radius; if( !m_layerMask[aMire->GetLayer()] ) return; m_plotter->SetColor( getColor( aMire->GetLayer() ) ); DRAWSEGMENT draw; draw.SetShape( S_CIRCLE ); draw.SetWidth( ( GetMode() == LINE ) ? -1 : aMire->GetWidth() ); draw.SetLayer( aMire->GetLayer() ); draw.SetStart( aMire->GetPosition() ); radius = aMire->GetSize() / 3; if( aMire->GetShape() ) // shape X radius = aMire->GetSize() / 2; // Draw the circle draw.SetEnd( wxPoint( draw.GetStart().x + radius, draw.GetStart().y )); PlotDrawSegment( &draw ); draw.SetShape( S_SEGMENT ); radius = aMire->GetSize() / 2; dx1 = radius; dy1 = 0; dx2 = 0; dy2 = radius; if( aMire->GetShape() ) // Shape X { dx1 = dy1 = radius; dx2 = dx1; dy2 = -dy1; } wxPoint mirePos( aMire->GetPosition() ); // Draw the X or + shape: draw.SetStart( wxPoint( mirePos.x - dx1, mirePos.y - dy1 )); draw.SetEnd( wxPoint( mirePos.x + dx1, mirePos.y + dy1 )); PlotDrawSegment( &draw ); draw.SetStart( wxPoint( mirePos.x - dx2, mirePos.y - dy2 )); draw.SetEnd( wxPoint( mirePos.x + dx2, mirePos.y + dy2 )); PlotDrawSegment( &draw ); }
void DXF2BRD_CONVERTER::addCircle( const DRW_Circle& aData ) { DRAWSEGMENT* segm = ( m_useModuleItems ) ? static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT; segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); segm->SetShape( S_CIRCLE ); wxPoint center( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) ); segm->SetCenter( center ); wxPoint circle_start( mapX( aData.basePoint.x + aData.radious ), mapY( aData.basePoint.y ) ); segm->SetArcStart( circle_start ); segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); m_newItemsList.push_back( segm ); }
void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& aData ) { // Currently, Pcbnew does not know polylines, for boards. // So we have to convert a polyline to a set of segments. // Obviously, the z coordinate is ignored wxPoint polyline_startpoint; wxPoint segment_startpoint; for( unsigned ii = 0; ii < aData.vertlist.size(); ii++ ) { DRW_Vertex* vertex = aData.vertlist[ii]; if( ii == 0 ) { segment_startpoint.x = mapX( vertex->basePoint.x ); segment_startpoint.y = mapY( vertex->basePoint.y ); polyline_startpoint = segment_startpoint; continue; } DRAWSEGMENT* segm = ( m_useModuleItems ) ? static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT; segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); segm->SetStart( segment_startpoint ); wxPoint segment_endpoint( mapX( vertex->basePoint.x ), mapY( vertex->basePoint.y ) ); segm->SetEnd( segment_endpoint ); segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); m_newItemsList.push_back( segm ); segment_startpoint = segment_endpoint; } // Polyline flags bit 0 indicates closed (1) or open (0) polyline if( aData.flags & 1 ) { DRAWSEGMENT* closing_segm = ( m_useModuleItems ) ? static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT; closing_segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); closing_segm->SetStart( segment_startpoint ); closing_segm->SetEnd( polyline_startpoint ); closing_segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); m_newItemsList.push_back( closing_segm ); } }
/* * Import Circle entities. */ void DXF2BRD_CONVERTER::addCircle( const DRW_Circle& data ) { DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd ); segm->SetLayer( m_brdLayer ); segm->SetShape( S_CIRCLE ); wxPoint center( mapX( data.basePoint.x ), mapY( data.basePoint.y ) ); segm->SetCenter( center ); wxPoint circle_start( mapX( data.basePoint.x + data.radious ), mapY( data.basePoint.y ) ); segm->SetArcStart( circle_start ); segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness : data.thickness ) ); appendToBoard( segm ); }
void DXF2BRD_CONVERTER::insertLine( const wxRealPoint& aSegStart, const wxRealPoint& aSegEnd, int aWidth ) { DRAWSEGMENT* segm = ( m_useModuleItems ) ? static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT; wxPoint segment_startpoint( Millimeter2iu( aSegStart.x ), Millimeter2iu( aSegStart.y ) ); wxPoint segment_endpoint( Millimeter2iu( aSegEnd.x ), Millimeter2iu( aSegEnd.y ) ); segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); segm->SetStart( segment_startpoint ); segm->SetEnd( segment_endpoint ); segm->SetWidth( aWidth ); m_newItemsList.push_back( segm ); return; }
void BRDITEMS_PLOTTER::PlotDimension( DIMENSION* aDim ) { if( !m_layerMask[aDim->GetLayer()] ) return; DRAWSEGMENT draw; draw.SetWidth( (GetMode() == LINE) ? -1 : aDim->GetWidth() ); draw.SetLayer( aDim->GetLayer() ); EDA_COLOR_T color = aDim->GetBoard()->GetLayerColor( aDim->GetLayer() ); // Set plot color (change WHITE to LIGHTGRAY because // the white items are not seen on a white paper or screen m_plotter->SetColor( color != WHITE ? color : LIGHTGRAY); PlotTextePcb( &aDim->Text() ); draw.SetStart( aDim->m_crossBarO ); draw.SetEnd( aDim->m_crossBarF ); PlotDrawSegment( &draw ); draw.SetStart( aDim->m_featureLineGO); draw.SetEnd( aDim->m_featureLineGF ); PlotDrawSegment( &draw ); draw.SetStart( aDim->m_featureLineDO ); draw.SetEnd( aDim->m_featureLineDF ); PlotDrawSegment( &draw ); draw.SetStart( aDim->m_crossBarF ); draw.SetEnd( aDim->m_arrowD1F ); PlotDrawSegment( &draw ); draw.SetStart( aDim->m_crossBarF ); draw.SetEnd( aDim->m_arrowD2F ); PlotDrawSegment( &draw ); draw.SetStart( aDim->m_crossBarO ); draw.SetEnd( aDim->m_arrowG1F ); PlotDrawSegment( &draw ); draw.SetStart( aDim->m_crossBarO ); draw.SetEnd( aDim->m_arrowG2F ); PlotDrawSegment( &draw ); }
bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic ) { bool clockwise = true; // drawing direction of the arc double startAngle = 0.0f; // angle of the first arc line VECTOR2I cursorPos = m_controls->GetCursorPosition(); DRAWSEGMENT helperLine; helperLine.SetShape( S_SEGMENT ); helperLine.SetLayer( Dwgs_User ); helperLine.SetWidth( 1 ); // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); Activate(); enum ARC_STEPS { SET_ORIGIN = 0, SET_END, SET_ANGLE, FINISHED }; int step = SET_ORIGIN; // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() || evt->IsActivate() ) { preview.Clear(); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); delete aGraphic; aGraphic = NULL; break; } else if( evt->IsClick( BUT_LEFT ) ) { switch( step ) { case SET_ORIGIN: { LAYER_ID layer = m_frame->GetScreen()->m_Active_Layer; if( IsCopperLayer( layer ) ) { DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) ); --step; } else { // Init the new item attributes aGraphic->SetShape( S_ARC ); aGraphic->SetAngle( 0.0 ); aGraphic->SetWidth( getSegmentWidth( layer ) ); aGraphic->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); aGraphic->SetLayer( layer ); helperLine.SetStart( aGraphic->GetCenter() ); helperLine.SetEnd( aGraphic->GetCenter() ); preview.Add( aGraphic ); preview.Add( &helperLine ); m_controls->SetAutoPan( true ); m_controls->CaptureCursor( true ); } } break; case SET_END: { if( wxPoint( cursorPos.x, cursorPos.y ) != aGraphic->GetCenter() ) { VECTOR2D startLine( aGraphic->GetArcStart() - aGraphic->GetCenter() ); startAngle = startLine.Angle(); aGraphic->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); } else --step; // one another chance to draw a proper arc } break; case SET_ANGLE: { if( wxPoint( cursorPos.x, cursorPos.y ) != aGraphic->GetArcStart() && aGraphic->GetAngle() != 0 ) { assert( aGraphic->GetArcStart() != aGraphic->GetArcEnd() ); assert( aGraphic->GetWidth() > 0 ); m_view->Add( aGraphic ); aGraphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); preview.Remove( aGraphic ); preview.Remove( &helperLine ); } else --step; // one another chance to draw a proper arc } break; } if( ++step == FINISHED ) break; } else if( evt->IsMotion() ) { switch( step ) { case SET_END: helperLine.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); aGraphic->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); break; case SET_ANGLE: { VECTOR2D endLine( wxPoint( cursorPos.x, cursorPos.y ) - aGraphic->GetCenter() ); double newAngle = RAD2DECIDEG( endLine.Angle() - startAngle ); // Adjust the new angle to (counter)clockwise setting if( clockwise && newAngle < 0.0 ) newAngle += 3600.0; else if( !clockwise && newAngle > 0.0 ) newAngle -= 3600.0; aGraphic->SetAngle( newAngle ); } break; } // Show a preview of the item preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsAction( &COMMON_ACTIONS::incWidth ) ) { aGraphic->SetWidth( aGraphic->GetWidth() + WIDTH_STEP ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsAction( &COMMON_ACTIONS::decWidth ) ) { int width = aGraphic->GetWidth(); if( width > WIDTH_STEP ) { aGraphic->SetWidth( width - WIDTH_STEP ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } else if( evt->IsAction( &COMMON_ACTIONS::arcPosture ) ) { if( clockwise ) aGraphic->SetAngle( aGraphic->GetAngle() - 3600.0 ); else aGraphic->SetAngle( aGraphic->GetAngle() + 3600.0 ); clockwise = !clockwise; preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } m_controls->ShowCursor( false ); m_controls->SetSnapping( false ); m_controls->SetAutoPan( false ); m_controls->CaptureCursor( false ); m_view->Remove( &preview ); return ( step > SET_ORIGIN ); }
int DRAWING_TOOL::drawZone( bool aKeepout ) { ZONE_CONTAINER* zone = NULL; DRAWSEGMENT line45; DRAWSEGMENT* helperLine = NULL; // we will need more than one helper line // if one day it is possible to draw zones in the footprint editor, // then hereby I'm letting you know that this tool does not handle UR_MODEDIT undo yet assert( !m_editModules ); // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); Activate(); VECTOR2I origin; int numPoints = 0; bool direction45 = false; // 45 degrees only mode // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { bool updatePreview = false; // should preview be updated VECTOR2I cursorPos = m_controls->GetCursorPosition(); // Enable 45 degrees lines only mode by holding control if( direction45 != ( evt->Modifier( MD_CTRL ) && numPoints > 0 ) ) { direction45 = evt->Modifier( MD_CTRL ); if( direction45 ) { preview.Add( &line45 ); make45DegLine( helperLine, &line45 ); } else { preview.Remove( &line45 ); helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); } updatePreview = true; } if( evt->IsCancel() || evt->IsActivate() ) { if( numPoints > 0 ) // cancel the current zone { delete zone; zone = NULL; m_controls->SetAutoPan( false ); m_controls->CaptureCursor( false ); if( direction45 ) { preview.Remove( &line45 ); direction45 = false; } preview.FreeItems(); updatePreview = true; numPoints = 0; } else // there is no zone currently drawn - just stop the tool break; if( evt->IsActivate() ) // now finish unconditionally break; } else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) ) { // Check if it is double click / closing line (so we have to finish the zone) if( evt->IsDblClick( BUT_LEFT ) || ( numPoints > 0 && cursorPos == origin ) ) { if( numPoints > 2 ) // valid zone consists of more than 2 points { assert( zone->GetNumCorners() > 2 ); // Finish the zone if( direction45 ) zone->AppendCorner( cursorPos == origin ? line45.GetStart() : line45.GetEnd() ); zone->Outline()->CloseLastContour(); zone->Outline()->RemoveNullSegments(); m_board->Add( zone ); m_view->Add( zone ); if( !aKeepout ) static_cast<PCB_EDIT_FRAME*>( m_frame )->Fill_Zone( zone ); zone->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); m_board->GetRatsnest()->Update( zone ); m_frame->OnModify(); m_frame->SaveCopyInUndoList( zone, UR_NEW ); zone = NULL; } else { delete zone; zone = NULL; } numPoints = 0; m_controls->SetAutoPan( false ); m_controls->CaptureCursor( false ); if( direction45 ) { preview.Remove( &line45 ); direction45 = false; } preview.FreeItems(); updatePreview = true; } else { if( numPoints == 0 ) // it's the first click { // Get the current default settings for zones ZONE_SETTINGS zoneInfo = m_frame->GetZoneSettings(); zoneInfo.m_CurrentZone_Layer = m_frame->GetScreen()->m_Active_Layer; m_controls->SetAutoPan( true ); m_controls->CaptureCursor( true ); // Show options dialog ZONE_EDIT_T dialogResult; if( aKeepout ) dialogResult = InvokeKeepoutAreaEditor( m_frame, &zoneInfo ); else { if( IsCopperLayer( zoneInfo.m_CurrentZone_Layer ) ) dialogResult = InvokeCopperZonesEditor( m_frame, &zoneInfo ); else dialogResult = InvokeNonCopperZonesEditor( m_frame, NULL, &zoneInfo ); } if( dialogResult == ZONE_ABORT ) { m_controls->SetAutoPan( false ); m_controls->CaptureCursor( false ); continue; } // Apply the selected settings zone = new ZONE_CONTAINER( m_board ); zoneInfo.ExportSetting( *zone ); m_frame->GetGalCanvas()->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); // Add the first point zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer, cursorPos.x, cursorPos.y, zone->GetHatchStyle() ); origin = cursorPos; // Helper line represents the currently drawn line of the zone polygon helperLine = new DRAWSEGMENT; helperLine->SetShape( S_SEGMENT ); helperLine->SetWidth( 1 ); helperLine->SetLayer( zoneInfo.m_CurrentZone_Layer ); helperLine->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); line45 = *helperLine; preview.Add( helperLine ); } else { zone->AppendCorner( helperLine->GetEnd() ); helperLine = new DRAWSEGMENT( *helperLine ); helperLine->SetStart( helperLine->GetEnd() ); preview.Add( helperLine ); } ++numPoints; updatePreview = true; } } else if( evt->IsMotion() && numPoints > 0 ) { // 45 degree lines if( direction45 ) make45DegLine( helperLine, &line45 ); else helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); // Show a preview of the item updatePreview = true; } if( updatePreview ) preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } m_controls->ShowCursor( false ); m_controls->SetSnapping( false ); m_controls->SetAutoPan( false ); m_controls->CaptureCursor( false ); m_view->Remove( &preview ); m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); return 0; }
void DXF2BRD_CONVERTER::insertArc( const wxRealPoint& aSegStart, const wxRealPoint& aSegEnd, double aBulge, int aWidth ) { DRAWSEGMENT* segm = ( m_useModuleItems ) ? static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT; wxPoint segment_startpoint( Millimeter2iu( aSegStart.x ), Millimeter2iu( aSegStart.y ) ); wxPoint segment_endpoint( Millimeter2iu( aSegEnd.x ), Millimeter2iu( aSegEnd.y ) ); // ensure aBulge represents an angle from +/- ( 0 .. approx 359.8 deg ) if( aBulge < -2000.0 ) aBulge = -2000.0; else if( aBulge > 2000.0 ) aBulge = 2000.0; double ang = 4.0 * atan( aBulge ); // reflect the Y values to put everything in a RHCS wxRealPoint sp( aSegStart.x, -aSegStart.y ); wxRealPoint ep( aSegEnd.x, -aSegEnd.y ); // angle from end->start double offAng = atan2( ep.y - sp.y, ep.x - sp.x ); // length of subtended segment = 1/2 distance between the 2 points double d = 0.5 * sqrt( (sp.x - ep.x) * (sp.x - ep.x) + (sp.y - ep.y) * (sp.y - ep.y) ); // midpoint of the subtended segment double xm = ( sp.x + ep.x ) * 0.5; double ym = ( sp.y + ep.y ) * 0.5; double radius = d / sin( ang * 0.5 ); if( radius < 0.0 ) radius = -radius; // calculate the height of the triangle with base d and hypotenuse r double dh2 = radius * radius - d * d; // this should only ever happen due to rounding errors when r == d if( dh2 < 0.0 ) dh2 = 0.0; double h = sqrt( dh2 ); if( ang < 0.0 ) offAng -= M_PI_2; else offAng += M_PI_2; // for angles greater than 180 deg we need to flip the // direction in which the arc center is found relative // to the midpoint of the subtended segment. if( ang < -M_PI ) offAng += M_PI; else if( ang > M_PI ) offAng -= M_PI; // center point double cx = h * cos( offAng ) + xm; double cy = h * sin( offAng ) + ym; segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); segm->SetShape( S_ARC ); segm->SetCenter( wxPoint( Millimeter2iu( cx ), Millimeter2iu( -cy ) ) ); if( ang < 0.0 ) { segm->SetArcStart( wxPoint( Millimeter2iu( ep.x ), Millimeter2iu( -ep.y ) ) ); segm->SetAngle( RAD2DECIDEG( ang ) ); } else { segm->SetArcStart( wxPoint( Millimeter2iu( sp.x ), Millimeter2iu( -sp.y ) ) ); segm->SetAngle( RAD2DECIDEG( -ang ) ); } segm->SetWidth( aWidth ); m_newItemsList.push_back( segm ); return; }