From ec17455d35469d7ecbec242f9ede436544816194 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Thu, 9 Apr 2015 20:53:36 +0200 Subject: [PATCH] board_items_to_polygon_shape_transform.cpp: remove full duplicate code between DRAWSEGMENT and EDGE_MODULE, and fix incorrect conversion of DRAWSEGMENT polygon type to its polygonal shape. Gerbview: better info from X2 filefunction attribute displayed in layer manager about copper layers --- common/wildcards_and_files_ext.cpp | 3 +- gerbview/class_GERBER.cpp | 18 ++- gerbview/class_X2_gerber_attributes.cpp | 25 +++- gerbview/class_X2_gerber_attributes.h | 17 ++- include/wildcards_and_files_ext.h | 1 + ...board_items_to_polygon_shape_transform.cpp | 121 ++++++++++-------- 6 files changed, 120 insertions(+), 65 deletions(-) diff --git a/common/wildcards_and_files_ext.cpp b/common/wildcards_and_files_ext.cpp index e05ca5e123..de343ecc47 100644 --- a/common/wildcards_and_files_ext.cpp +++ b/common/wildcards_and_files_ext.cpp @@ -54,8 +54,9 @@ const wxString DrillFileExtension( wxT( "drl" ) ); const wxString SVGFileExtension( wxT( "svg" ) ); const wxString ReportFileExtension( wxT( "rpt" ) ); const wxString FootprintPlaceFileExtension( wxT( "pos" ) ); +const wxString KiCadLib3DShapesPathExtension( wxT( "3dshapes" ) ); ///< 3D shapes default libpath -const wxString KiCadFootprintLibPathExtension( wxT( "pretty" ) ); ///< KICAD PLUGIN libpath +const wxString KiCadFootprintLibPathExtension( wxT( "pretty" ) ); ///< KICAD PLUGIN libpath const wxString LegacyFootprintLibPathExtension( wxT( "mod" ) ); const wxString EagleFootprintLibPathExtension( wxT( "lbr" ) ); diff --git a/gerbview/class_GERBER.cpp b/gerbview/class_GERBER.cpp index 8c04e7e430..59d7615035 100644 --- a/gerbview/class_GERBER.cpp +++ b/gerbview/class_GERBER.cpp @@ -463,9 +463,21 @@ const wxString GERBER_IMAGE_LIST::GetDisplayName( int aIdx ) if( gerber && IsUsed(aIdx ) ) { if( gerber->m_FileFunction ) - name.Printf( _( "Layer %d (%s, %s)" ), aIdx + 1, - GetChars( gerber->m_FileFunction->GetFileType() ), - GetChars( gerber->m_FileFunction->GetBrdLayerId() ) ); + { + if( gerber->m_FileFunction->IsCopper() ) + { + name.Printf( _( "Layer %d (%s, %s, %s)" ), aIdx + 1, + GetChars( gerber->m_FileFunction->GetFileType() ), + GetChars( gerber->m_FileFunction->GetBrdLayerId() ), + GetChars( gerber->m_FileFunction->GetBrdLayerSide() ) ); + } + else + { + name.Printf( _( "Layer %d (%s, %s)" ), aIdx + 1, + GetChars( gerber->m_FileFunction->GetFileType() ), + GetChars( gerber->m_FileFunction->GetBrdLayerId() ) ); + } + } else name.Printf( _( "Layer %d *" ), aIdx + 1 ); } diff --git a/gerbview/class_X2_gerber_attributes.cpp b/gerbview/class_X2_gerber_attributes.cpp index 4b5801a23a..52d59b19e8 100644 --- a/gerbview/class_X2_gerber_attributes.cpp +++ b/gerbview/class_X2_gerber_attributes.cpp @@ -189,18 +189,35 @@ const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetFileType() const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetBrdLayerId() { - // the brd layer identifier: Top, Bot, Ln + // the brd layer identifier: Ln (for Copper type) or Top, Bot return m_Prms.Item( 2 ); } +const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetBrdLayerSide() +{ + if( IsCopper() ) + // the brd layer identifier: Top, Bot, Inr + return m_Prms.Item( 3 ); + else + // the brd layer identifier: Top, Bot ( same as GetBrdLayerId() ) + return m_Prms.Item( 2 ); +} const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetLabel() { - // the filefunction label, if any - return m_Prms.Item( 3 ); + if( IsCopper() ) + return m_Prms.Item( 4 ); + else + return m_Prms.Item( 3 ); } +bool X2_ATTRIBUTE_FILEFUNCTION::IsCopper() +{ + // the filefunction label, if any + return GetFileType().IsSameAs( wxT( "Copper" ), false ); +} + // Initialize the z order priority of the current file, from its attributes // this priority is the order of layers from top to bottom to draw/display gerber images // Stack up is( from external copper layer to external) @@ -211,7 +228,7 @@ void X2_ATTRIBUTE_FILEFUNCTION::set_Z_Order() m_z_order = -100; // low level m_z_sub_order = 0; - if( GetFileType().IsSameAs( wxT( "Copper" ), false ) ) + if( IsCopper() ) { // Copper layer: the priority is the layer Id m_z_order = 0; diff --git a/gerbview/class_X2_gerber_attributes.h b/gerbview/class_X2_gerber_attributes.h index d51ddbbf53..cdd68b558f 100644 --- a/gerbview/class_X2_gerber_attributes.h +++ b/gerbview/class_X2_gerber_attributes.h @@ -153,12 +153,19 @@ class X2_ATTRIBUTE_FILEFUNCTION : public X2_ATTRIBUTE public: X2_ATTRIBUTE_FILEFUNCTION( X2_ATTRIBUTE& aAttributeBase ); - const wxString& GetFileType(); ///< the type of layer (Copper , Soldermask ... ) - const wxString& GetBrdLayerId(); ///< the brd layer identifier: Top, Bot, Ln - const wxString& GetLabel(); ///< the filefunction label, if any + bool IsCopper(); ///< return true if the filefunction type is "Copper" - int GetZOrder() { return m_z_order; } ///< the Order of the bdr layer, from front (Top side) to back side - int GetZSubOrder() { return m_z_sub_order; } ///< the Order of the bdr copper layer, from front (Top side) to back side + const wxString& GetFileType(); ///< the type of layer (Copper, Soldermask ... ) + const wxString& GetBrdLayerId(); ///< the brd layer identifier: Ln, only for Copper type + ///< or Top, Bot for other types + const wxString& GetBrdLayerSide(); ///< the brd layer Pos: Top, Bot, Inr + ///< same as GetBrdLayerId() for non copper type + const wxString& GetLabel(); ///< the filefunction label, if any + + int GetZOrder() { return m_z_order; } ///< the Order of the board layer, + ///< from front (Top) side to back (Bot) side + int GetZSubOrder() { return m_z_sub_order; } ///< the Order of the bdr copper layer, + ///< from front (Top) side to back (Bot) side private: diff --git a/include/wildcards_and_files_ext.h b/include/wildcards_and_files_ext.h index def50bc230..94ad151eab 100644 --- a/include/wildcards_and_files_ext.h +++ b/include/wildcards_and_files_ext.h @@ -71,6 +71,7 @@ extern const wxString GedaPcbFootprintLibFileExtension; extern const wxString EagleFootprintLibPathExtension; extern const wxString ComponentFileExtensionWildcard; extern const wxString PageLayoutDescrFileWildcard; +extern const wxString KiCadLib3DShapesPathExtension; /// Proper wxFileDialog wild card definitions. extern const wxString SchematicSymbolFileWildcard; diff --git a/pcbnew/board_items_to_polygon_shape_transform.cpp b/pcbnew/board_items_to_polygon_shape_transform.cpp index e21ec89141..db62471743 100644 --- a/pcbnew/board_items_to_polygon_shape_transform.cpp +++ b/pcbnew/board_items_to_polygon_shape_transform.cpp @@ -227,52 +227,13 @@ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet( case PCB_MODULE_EDGE_T: outline = (EDGE_MODULE*) item; + if( outline->GetLayer() != aLayer ) break; - - switch( outline->GetShape() ) - { - case S_SEGMENT: - TransformRoundedEndsSegmentToPolygon( aCornerBuffer, - outline->GetStart(), - outline->GetEnd(), - aCircleToSegmentsCount, - outline->GetWidth() ); - break; - - case S_CIRCLE: - TransformRingToPolygon( aCornerBuffer, outline->GetCenter(), - outline->GetRadius(), aCircleToSegmentsCount, - outline->GetWidth() ); - break; - - case S_ARC: - TransformArcToPolygon( aCornerBuffer, - outline->GetCenter(), outline->GetArcStart(), - outline->GetAngle(), - aCircleToSegmentsCount, outline->GetWidth() ); - break; - - case S_POLYGON: - // for outline shape = S_POLYGON: - // We must compute true coordinates from m_PolyPoints - // which are relative to module position and module orientation = 0 - for( unsigned ii = 0; ii < outline->GetPolyPoints().size(); ii++ ) - { - CPolyPt corner( outline->GetPolyPoints()[ii] ); - RotatePoint( &corner.x, &corner.y, GetOrientation() ); - corner.x += GetPosition().x; - corner.y += GetPosition().y; - aCornerBuffer.Append( corner ); - } - aCornerBuffer.CloseLastContour(); - break; - - default: - DBG( printf( "Error: Shape %d not implemented!\n", - outline->GetShape() ); ) - break; - } + outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, + 0, + aCircleToSegmentsCount, + aCorrectionFactor ); break; default: @@ -332,7 +293,7 @@ void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet( // add filled areas polygons aCornerBuffer.Append( m_FilledPolysList ); - // add filled areas outlines, which are drawn with thich lines + // add filled areas outlines, which are drawn with thick lines wxPoint seg_start, seg_end; int i_start_contour = 0; for( unsigned ic = 0; ic < cornerscount; ic++ ) @@ -473,25 +434,81 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( CPOLYGONS_LIST& aCornerB int aCircleToSegmentsCount, double aCorrectionFactor ) const { + // The full width of the lines to create: + int linewidth = m_Width + (2 * aClearanceValue); + switch( m_Shape ) { case S_CIRCLE: TransformRingToPolygon( aCornerBuffer, GetCenter(), GetRadius(), - aCircleToSegmentsCount, - m_Width + (2 * aClearanceValue) ) ; + aCircleToSegmentsCount, linewidth ) ; break; case S_ARC: TransformArcToPolygon( aCornerBuffer, GetCenter(), GetArcStart(), m_Angle, - aCircleToSegmentsCount, - m_Width + (2 * aClearanceValue) ); + aCircleToSegmentsCount, linewidth ); + break; + + case S_SEGMENT: + TransformRoundedEndsSegmentToPolygon( aCornerBuffer, m_Start, m_End, + aCircleToSegmentsCount, linewidth ); + break; + + case S_POLYGON: + if ( GetPolyPoints().size() < 2 ) + break; // Malformed polygon. + { + // The polygon is expected to be a simple polygon + // not self intersecting, no hole. + MODULE* module = GetParentModule(); // NULL for items not in footprints + double orientation = module ? module->GetOrientation() : 0.0; + + // Build the polygon with the actual position and orientation: + std::vector< wxPoint> poly; + poly = GetPolyPoints(); + + for( unsigned ii = 0; ii < poly.size(); ii++ ) + { + RotatePoint( &poly[ii], orientation ); + poly[ii] += GetPosition(); + } + + // Generate polygons for the outline + clearance + // This code is compatible with a polygon with holes linked to external outline + // by overlapping segments. + if( linewidth ) // Add thick outlines + { + CPolyPt corner1( poly[poly.size()-1] ); + + for( unsigned ii = 0; ii < poly.size(); ii++ ) + { + CPolyPt corner2( poly[ii] ); + + if( corner2 != corner1 ) + { + TransformRoundedEndsSegmentToPolygon( aCornerBuffer, + corner1, corner2, aCircleToSegmentsCount, linewidth ); + } + + corner1 = corner2; + } + } + + // Polygon for the inside + for( unsigned ii = 0; ii < poly.size(); ii++ ) + { + CPolyPt corner( poly[ii] ); + aCornerBuffer.Append( corner ); + } + aCornerBuffer.CloseLastContour(); + } + break; + + case S_CURVE: // Bezier curve (TODO: not yet in use) break; default: - TransformRoundedEndsSegmentToPolygon( aCornerBuffer, m_Start, m_End, - aCircleToSegmentsCount, - m_Width + (2 * aClearanceValue) ); break; } }