DXF import: add import of DXF splines that are converted to Bezier curves.
Fix also a lot of bugs related to Bezier curves (S_CURVE shape in DRAW_SEGMENT class) in Pcbnew code. Add missing code to handle these Bezier curves
This commit is contained in:
parent
3d4e61ddb8
commit
72d1597201
|
@ -941,7 +941,7 @@ add_subdirectory( 3d-viewer )
|
|||
add_subdirectory( cvpcb )
|
||||
add_subdirectory( eeschema )
|
||||
add_subdirectory( gerbview )
|
||||
add_subdirectory( lib_dxf )
|
||||
add_subdirectory( dxflib_qcad )
|
||||
add_subdirectory( pcbnew )
|
||||
add_subdirectory( polygon )
|
||||
add_subdirectory( pagelayout_editor )
|
||||
|
|
|
@ -45,9 +45,10 @@ static inline double sqrt_len( int dx, int dy )
|
|||
}
|
||||
|
||||
|
||||
void BEZIER_POLY::GetPoly( std::vector<wxPoint>& aOutput )
|
||||
void BEZIER_POLY::GetPoly( std::vector<wxPoint>& aOutput, int aMinSegLen )
|
||||
{
|
||||
wxCHECK( !m_ctrlPts.empty(), /* void */ );
|
||||
m_minSegLen = std::max( 1, aMinSegLen );
|
||||
m_output = &aOutput;
|
||||
m_output->clear();
|
||||
m_output->push_back( wxPoint( m_ctrlPts.front() ) );
|
||||
|
|
|
@ -30,18 +30,22 @@
|
|||
|
||||
/**
|
||||
* Bezier curves to polygon converter.
|
||||
* Only quadratic and cubic Bezier curves are handled
|
||||
*/
|
||||
class BEZIER_POLY
|
||||
{
|
||||
public:
|
||||
/** cubic Bezier curve */
|
||||
BEZIER_POLY( int x1, int y1, int x2, int y2, int x3, int y3 )
|
||||
{
|
||||
m_ctrlPts.emplace_back( x1, y1 );
|
||||
m_ctrlPts.emplace_back( x2, y2 );
|
||||
m_ctrlPts.emplace_back( x3, y3 );
|
||||
m_output = nullptr;
|
||||
m_minSegLen = 0;
|
||||
}
|
||||
|
||||
/** Quadratic and cubic Bezier curve */
|
||||
BEZIER_POLY( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 )
|
||||
{
|
||||
m_ctrlPts.emplace_back( x1, y1 );
|
||||
|
@ -49,21 +53,28 @@ public:
|
|||
m_ctrlPts.emplace_back( x3, y3 );
|
||||
m_ctrlPts.emplace_back( x4, y4 );
|
||||
m_output = nullptr;
|
||||
m_minSegLen = 0;
|
||||
}
|
||||
|
||||
BEZIER_POLY( const std::vector<wxPoint>& aControlPoints )
|
||||
: m_ctrlPts( aControlPoints )
|
||||
{
|
||||
m_output = nullptr;
|
||||
m_minSegLen = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts Bezier curve to a polygon.
|
||||
* @param aOutput will be used as an output vector storing polygon points.
|
||||
* @param aMinSegLen is the min dist between 2 successve points.
|
||||
* It can be used to reduce the number of points.
|
||||
* (the last point is always generated)
|
||||
*/
|
||||
void GetPoly( std::vector<wxPoint>& aOutput );
|
||||
void GetPoly( std::vector<wxPoint>& aOutput, int aMinSegLen = 0 );
|
||||
|
||||
private:
|
||||
int m_minSegLen;
|
||||
|
||||
///> Control points
|
||||
std::vector<wxPoint> m_ctrlPts;
|
||||
|
||||
|
@ -72,7 +83,11 @@ private:
|
|||
|
||||
void addSegment( const wxPoint& aSegment )
|
||||
{
|
||||
if( m_output->back() != aSegment )
|
||||
int seglen = std::abs( m_output->back().x - aSegment.x )
|
||||
+ std::abs( m_output->back().y - aSegment.y );
|
||||
|
||||
// m_minSegLen is always > 0, so never store a 0 len segment
|
||||
if( seglen >= m_minSegLen )
|
||||
m_output->push_back( aSegment );
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ include_directories(
|
|||
../polygon
|
||||
../common/dialogs
|
||||
./exporters
|
||||
../lib_dxf
|
||||
../dxflib_qcad
|
||||
./import_dxf
|
||||
../utils/idftools
|
||||
${GLM_INCLUDE_DIR}
|
||||
|
|
|
@ -533,10 +533,11 @@ void MoveMarkedItems( MODULE* module, wxPoint offset )
|
|||
case PCB_MODULE_EDGE_T:
|
||||
{
|
||||
EDGE_MODULE* em = (EDGE_MODULE*) item;
|
||||
em->SetStart( em->GetStart() + offset );
|
||||
em->SetEnd( em->GetEnd() + offset );
|
||||
em->Move( offset );
|
||||
em->SetStart0( em->GetStart0() + offset );
|
||||
em->SetEnd0( em->GetEnd0() + offset );
|
||||
em->SetBezier0_C1( em->GetBezier0_C1() + offset );
|
||||
em->SetBezier0_C2( em->GetBezier0_C2() + offset );
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <bezier_curves.h>
|
||||
#include <base_units.h> // for IU_PER_MM
|
||||
#include <draw_graphic_text.h>
|
||||
#include <pcbnew.h>
|
||||
|
@ -602,7 +603,19 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerB
|
|||
}
|
||||
break;
|
||||
|
||||
case S_CURVE: // Bezier curve (TODO: not yet in use)
|
||||
case S_CURVE: // Bezier curve
|
||||
{
|
||||
std::vector<wxPoint> ctrlPoints = { m_Start, m_BezierC1, m_BezierC2, m_End };
|
||||
BEZIER_POLY converter( ctrlPoints );
|
||||
std::vector< wxPoint> poly;
|
||||
converter.GetPoly( poly, m_Width );
|
||||
|
||||
for( unsigned ii = 1; ii < poly.size(); ii++ )
|
||||
{
|
||||
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
|
||||
poly[ii-1], poly[ii], aCircleToSegmentsCount, linewidth );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -91,6 +91,18 @@ void DRAWSEGMENT::Move( const wxPoint& aMoveVector )
|
|||
(*iter) += VECTOR2I( aMoveVector );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CURVE:
|
||||
m_BezierC1 += aMoveVector;
|
||||
m_BezierC2 += aMoveVector;
|
||||
|
||||
for( unsigned int ii = 0; ii < m_BezierPoints.size(); ii++ )
|
||||
{
|
||||
m_BezierPoints[ii] += aMoveVector;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -119,6 +131,8 @@ void DRAWSEGMENT::Rotate( const wxPoint& aRotCentre, double aAngle )
|
|||
case S_CURVE:
|
||||
RotatePoint( &m_Start, aRotCentre, aAngle);
|
||||
RotatePoint( &m_End, aRotCentre, aAngle);
|
||||
RotatePoint( &m_BezierC1, aRotCentre, aAngle);
|
||||
RotatePoint( &m_BezierC2, aRotCentre, aAngle);
|
||||
|
||||
for( unsigned int ii = 0; ii < m_BezierPoints.size(); ii++ )
|
||||
{
|
||||
|
@ -145,21 +159,51 @@ void DRAWSEGMENT::Flip( const wxPoint& aCentre )
|
|||
case S_ARC:
|
||||
m_Angle = -m_Angle;
|
||||
break;
|
||||
|
||||
case S_POLYGON:
|
||||
for( auto iter = m_Poly.Iterate(); iter; iter++ )
|
||||
{
|
||||
iter->y = aCentre.y - (iter->y - aCentre.y);
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CURVE:
|
||||
{
|
||||
m_BezierC1.y = aCentre.y - (m_BezierC1.y - aCentre.y);
|
||||
m_BezierC2.y = aCentre.y - (m_BezierC2.y - aCentre.y);
|
||||
|
||||
// Rebuild the poly points shape
|
||||
std::vector<wxPoint> ctrlPoints = { m_Start, m_BezierC1, m_BezierC2, m_End };
|
||||
BEZIER_POLY converter( ctrlPoints );
|
||||
converter.GetPoly( m_BezierPoints, m_Width );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// DRAWSEGMENT items are not allowed on copper layers, so
|
||||
// copper layers count is not taken in accoun in Flip transform
|
||||
// copper layers count is not taken in account in Flip transform
|
||||
SetLayer( FlipLayer( GetLayer() ) );
|
||||
}
|
||||
|
||||
|
||||
void DRAWSEGMENT::RebuildBezierToSegmentsPointsList( int aMinSegLen )
|
||||
{
|
||||
// Has meaning only for S_CURVE DRAW_SEGMENT shape
|
||||
if( m_Shape != S_CURVE )
|
||||
{
|
||||
m_BezierPoints.clear();
|
||||
return;
|
||||
}
|
||||
// Rebuild the m_BezierPoints vertex list that approximate the Bezier curve
|
||||
std::vector<wxPoint> ctrlPoints = { m_Start, m_BezierC1, m_BezierC2, m_End };
|
||||
BEZIER_POLY converter( ctrlPoints );
|
||||
converter.GetPoly( m_BezierPoints, aMinSegLen );
|
||||
}
|
||||
|
||||
|
||||
const wxPoint DRAWSEGMENT::GetCenter() const
|
||||
{
|
||||
wxPoint c;
|
||||
|
@ -340,29 +384,24 @@ void DRAWSEGMENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
|
|||
|
||||
case S_CURVE:
|
||||
{
|
||||
std::vector<wxPoint> ctrlPoints = { m_Start, m_BezierC1, m_BezierC2, m_End };
|
||||
BEZIER_POLY converter( ctrlPoints );
|
||||
converter.GetPoly( m_BezierPoints );
|
||||
}
|
||||
RebuildBezierToSegmentsPointsList( m_Width );
|
||||
|
||||
for( unsigned int i=1; i < m_BezierPoints.size(); i++ )
|
||||
{
|
||||
if( filled )
|
||||
wxPoint& startp = m_BezierPoints[0];
|
||||
|
||||
for( unsigned int i = 1; i < m_BezierPoints.size(); i++ )
|
||||
{
|
||||
GRFillCSegm( panel->GetClipBox(), DC,
|
||||
m_BezierPoints[i].x, m_BezierPoints[i].y,
|
||||
m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
|
||||
m_Width, color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRCSegm( panel->GetClipBox(), DC,
|
||||
m_BezierPoints[i].x, m_BezierPoints[i].y,
|
||||
m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
|
||||
m_Width, color );
|
||||
wxPoint& endp = m_BezierPoints[i];
|
||||
|
||||
if( filled )
|
||||
GRFilledSegment( panel->GetClipBox(), DC,
|
||||
startp+aOffset, endp+aOffset, m_Width, color );
|
||||
else
|
||||
GRCSegm( panel->GetClipBox(), DC,
|
||||
startp+aOffset, endp+aOffset, m_Width, color );
|
||||
|
||||
startp = m_BezierPoints[i];
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case S_POLYGON:
|
||||
|
@ -518,6 +557,15 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const
|
|||
bbox.SetEnd( p_end );
|
||||
break;
|
||||
}
|
||||
|
||||
case S_CURVE:
|
||||
// Rebuild the poly points shape
|
||||
((DRAWSEGMENT*)this)->RebuildBezierToSegmentsPointsList( m_Width );
|
||||
|
||||
for( unsigned ii = 0; ii < m_BezierPoints.size(); ++ii )
|
||||
bbox.Merge( m_BezierPoints[ii] );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -578,6 +626,8 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const
|
|||
break;
|
||||
|
||||
case S_CURVE:
|
||||
((DRAWSEGMENT*)this)->RebuildBezierToSegmentsPointsList( m_Width );
|
||||
|
||||
for( unsigned int i= 1; i < m_BezierPoints.size(); i++)
|
||||
{
|
||||
if( TestSegmentHit( aPosition, m_BezierPoints[i-1], m_BezierPoints[i-1], m_Width / 2 ) )
|
||||
|
@ -711,6 +761,35 @@ bool DRAWSEGMENT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy
|
|||
break;
|
||||
|
||||
case S_CURVE: // not yet handled
|
||||
if( aContained )
|
||||
{
|
||||
return arect.Contains( bb );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fast test: if aRect is outside the polygon bounding box,
|
||||
// rectangles cannot intersect
|
||||
if( !arect.Intersects( bb ) )
|
||||
return false;
|
||||
|
||||
// Account for the width of the line
|
||||
arect.Inflate( GetWidth() / 2 );
|
||||
unsigned count = m_BezierPoints.size();
|
||||
|
||||
for( unsigned ii = 1; ii < count; ii++ )
|
||||
{
|
||||
wxPoint vertex = m_BezierPoints[ii-1];
|
||||
wxPoint vertexNext = m_BezierPoints[ii];
|
||||
|
||||
// Test if the point is within aRect
|
||||
if( arect.Contains( ( wxPoint ) vertex ) )
|
||||
return true;
|
||||
|
||||
// Test if this edge intersects aRect
|
||||
if( arect.Intersects( vertex, vertexNext ) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
|
|
@ -194,6 +194,16 @@ public:
|
|||
m_BezierPoints = aPoints;
|
||||
}
|
||||
|
||||
/** Rebuild the m_BezierPoints vertex list that approximate the Bezier curve
|
||||
* by a list of segments
|
||||
* Has meaning only for S_CURVE DRAW_SEGMENT shape
|
||||
* @param aMinSegLen is the min length of segments approximating the shape.
|
||||
* the last segment can be shorter
|
||||
* This param avoid having too many very short segment in list.
|
||||
* a good value is m_Width/2 to m_Width
|
||||
*/
|
||||
void RebuildBezierToSegmentsPointsList( int aMinSegLen );
|
||||
|
||||
void SetPolyPoints( const std::vector<wxPoint>& aPoints );
|
||||
|
||||
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
|
||||
|
|
|
@ -75,14 +75,19 @@ void EDGE_MODULE::SetLocalCoord()
|
|||
{
|
||||
m_Start0 = m_Start;
|
||||
m_End0 = m_End;
|
||||
m_Bezier0_C1 = m_BezierC1;
|
||||
m_Bezier0_C2 = m_BezierC2;
|
||||
return;
|
||||
}
|
||||
|
||||
m_Start0 = m_Start - module->GetPosition();
|
||||
m_End0 = m_End - module->GetPosition();
|
||||
m_Bezier0_C1 = m_BezierC1 - module->GetPosition();
|
||||
m_Bezier0_C2 = m_BezierC2 - module->GetPosition();
|
||||
double angle = module->GetOrientation();
|
||||
RotatePoint( &m_Start0.x, &m_Start0.y, -angle );
|
||||
RotatePoint( &m_End0.x, &m_End0.y, -angle );
|
||||
RotatePoint( &m_Bezier0_C1.x, &m_Bezier0_C1.y, -angle );
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,15 +97,23 @@ void EDGE_MODULE::SetDrawCoord()
|
|||
|
||||
m_Start = m_Start0;
|
||||
m_End = m_End0;
|
||||
m_BezierC1 = m_Bezier0_C1;
|
||||
m_BezierC2 = m_Bezier0_C2;
|
||||
|
||||
if( module )
|
||||
{
|
||||
RotatePoint( &m_Start.x, &m_Start.y, module->GetOrientation() );
|
||||
RotatePoint( &m_End.x, &m_End.y, module->GetOrientation() );
|
||||
RotatePoint( &m_End.x, &m_End.y, module->GetOrientation() );
|
||||
RotatePoint( &m_BezierC1.x, &m_BezierC1.y, module->GetOrientation() );
|
||||
RotatePoint( &m_BezierC2.x, &m_BezierC2.y, module->GetOrientation() );
|
||||
|
||||
m_Start += module->GetPosition();
|
||||
m_End += module->GetPosition();
|
||||
m_BezierC1 += module->GetPosition();
|
||||
m_BezierC2 += module->GetPosition();
|
||||
}
|
||||
|
||||
RebuildBezierToSegmentsPointsList( m_Width );
|
||||
}
|
||||
|
||||
|
||||
|
@ -225,6 +238,28 @@ void EDGE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
|
|||
}
|
||||
break;
|
||||
|
||||
case S_CURVE:
|
||||
{
|
||||
RebuildBezierToSegmentsPointsList( m_Width );
|
||||
|
||||
wxPoint& startp = m_BezierPoints[0];
|
||||
|
||||
for( unsigned int i = 1; i < m_BezierPoints.size(); i++ )
|
||||
{
|
||||
wxPoint& endp = m_BezierPoints[i];
|
||||
|
||||
if( filled )
|
||||
GRFilledSegment( panel->GetClipBox(), DC,
|
||||
startp-offset, endp-offset, m_Width, color );
|
||||
else
|
||||
GRCSegm( panel->GetClipBox(), DC,
|
||||
startp-offset, endp-offset, m_Width, color );
|
||||
|
||||
startp = m_BezierPoints[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -290,6 +325,7 @@ void EDGE_MODULE::Flip( const wxPoint& aCentre )
|
|||
//Fall through
|
||||
default:
|
||||
case S_SEGMENT:
|
||||
case S_CURVE:
|
||||
pt = GetStart();
|
||||
MIRROR( pt.y, aCentre.y );
|
||||
SetStart( pt );
|
||||
|
@ -298,8 +334,14 @@ void EDGE_MODULE::Flip( const wxPoint& aCentre )
|
|||
MIRROR( pt.y, aCentre.y );
|
||||
SetEnd( pt );
|
||||
|
||||
MIRROR( m_BezierC1.y, aCentre.y );
|
||||
MIRROR( m_BezierC2.y, aCentre.y );
|
||||
|
||||
MIRROR( m_Start0.y, 0 );
|
||||
MIRROR( m_End0.y, 0 );
|
||||
MIRROR( m_Bezier0_C1.y, 0 );
|
||||
MIRROR( m_Bezier0_C2.y, 0 );
|
||||
RebuildBezierToSegmentsPointsList( m_Width );
|
||||
break;
|
||||
|
||||
case S_POLYGON:
|
||||
|
@ -336,18 +378,32 @@ void EDGE_MODULE::Mirror( wxPoint aCentre, bool aMirrorAroundXAxis )
|
|||
SetAngle( -GetAngle() );
|
||||
//Fall through
|
||||
default:
|
||||
case S_CURVE:
|
||||
case S_SEGMENT:
|
||||
if( aMirrorAroundXAxis )
|
||||
{
|
||||
MIRROR( m_Start0.y, aCentre.y );
|
||||
MIRROR( m_End0.y, aCentre.y );
|
||||
MIRROR( m_Bezier0_C1.y, aCentre.y );
|
||||
MIRROR( m_Bezier0_C2.y, aCentre.y );
|
||||
}
|
||||
else
|
||||
{
|
||||
MIRROR( m_Start0.x, aCentre.x );
|
||||
MIRROR( m_End0.x, aCentre.x );
|
||||
MIRROR( m_Bezier0_C1.x, aCentre.x );
|
||||
MIRROR( m_Bezier0_C2.x, aCentre.x );
|
||||
}
|
||||
break;
|
||||
|
||||
for( unsigned ii = 0; ii < m_BezierPoints.size(); ii++ )
|
||||
{
|
||||
if( aMirrorAroundXAxis )
|
||||
MIRROR( m_BezierPoints[ii].y, aCentre.y );
|
||||
else
|
||||
MIRROR( m_BezierPoints[ii].x, aCentre.x );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case S_POLYGON:
|
||||
// polygon corners coordinates are always relative to the
|
||||
|
@ -383,6 +439,8 @@ void EDGE_MODULE::Move( const wxPoint& aMoveVector )
|
|||
// This is a footprint shape modification.
|
||||
m_Start0 += aMoveVector;
|
||||
m_End0 += aMoveVector;
|
||||
m_Bezier0_C1 += aMoveVector;
|
||||
m_Bezier0_C2 += aMoveVector;
|
||||
|
||||
switch( GetShape() )
|
||||
{
|
||||
|
|
|
@ -96,6 +96,12 @@ public:
|
|||
void SetEnd0( const wxPoint& aPoint ) { m_End0 = aPoint; }
|
||||
const wxPoint& GetEnd0() const { return m_End0; }
|
||||
|
||||
void SetBezier0_C1( const wxPoint& aPoint ) { m_Bezier0_C1 = aPoint; }
|
||||
const wxPoint& GetBezier0_C1() const { return m_Bezier0_C1; }
|
||||
|
||||
void SetBezier0_C2( const wxPoint& aPoint ) { m_Bezier0_C2 = aPoint; }
|
||||
const wxPoint& GetBezier0_C2() const { return m_Bezier0_C2; }
|
||||
|
||||
/**
|
||||
* Set relative coordinates from draw coordinates.
|
||||
* Call in only when the geometry ov the footprint is modified
|
||||
|
@ -134,8 +140,10 @@ public:
|
|||
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
|
||||
#endif
|
||||
|
||||
wxPoint m_Start0; // Start point or center, relative to module origin, orient 0.
|
||||
wxPoint m_End0; // End point, relative to module origin, orient 0.
|
||||
wxPoint m_Start0; ///< Start point or center, relative to module origin, orient 0.
|
||||
wxPoint m_End0; ///< End point, relative to module origin, orient 0.
|
||||
wxPoint m_Bezier0_C1; ///< Bezier Control Point 1, relative to module origin, orient 0.
|
||||
wxPoint m_Bezier0_C2; ///< Bezier Control Point 2, relative to module origin, orient 0.
|
||||
};
|
||||
|
||||
#endif // CLASS_EDGE_MOD_H_
|
||||
|
|
|
@ -79,11 +79,7 @@ void FOOTPRINT_EDIT_FRAME::Place_EdgeMod( EDGE_MODULE* aEdge )
|
|||
if( aEdge == NULL )
|
||||
return;
|
||||
|
||||
aEdge->SetStart( aEdge->GetStart() - MoveVector );
|
||||
aEdge->SetEnd( aEdge->GetEnd() - MoveVector );
|
||||
|
||||
aEdge->SetStart0( aEdge->GetStart0() - MoveVector );
|
||||
aEdge->SetEnd0( aEdge->GetEnd0() - MoveVector );
|
||||
aEdge->Move( -MoveVector );
|
||||
|
||||
aEdge->ClearFlags();
|
||||
m_canvas->SetMouseCapture( NULL, NULL );
|
||||
|
|
|
@ -101,8 +101,7 @@ static void Move_Segment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPos
|
|||
wxPoint delta;
|
||||
delta = aPanel->GetParent()->GetCrossHairPosition() - s_LastPosition;
|
||||
|
||||
segment->SetStart( segment->GetStart() + delta );
|
||||
segment->SetEnd( segment->GetEnd() + delta );
|
||||
segment->Move( delta );
|
||||
|
||||
s_LastPosition = aPanel->GetParent()->GetCrossHairPosition();
|
||||
|
||||
|
|
|
@ -300,7 +300,15 @@ bool DIALOG_DXF_IMPORT::TransferDataFromWindow()
|
|||
// Read dxf file:
|
||||
m_dxfImporter.ImportDxfFile( m_dxfFilename );
|
||||
|
||||
return true;
|
||||
// Get messages:
|
||||
std::string& messages = m_dxfImporter.GetMessages();
|
||||
|
||||
if( messages.empty() )
|
||||
return true;
|
||||
|
||||
// Show messages (list of net handled dxf items
|
||||
wxMessageBox( messages.c_str(), _( "Not Handled DXF Items" ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -35,7 +35,6 @@
|
|||
// this function just add the BOARD entity from dxf parameters (start and end point ...)
|
||||
|
||||
|
||||
#include "libdxfrw.h"
|
||||
#include "dxf2brd_items.h"
|
||||
#include <wx/arrstr.h>
|
||||
#include <wx/regex.h>
|
||||
|
@ -48,13 +47,12 @@
|
|||
#include <class_pcb_text.h>
|
||||
#include <class_text_mod.h>
|
||||
#include "common.h"
|
||||
#include <drw_base.h>
|
||||
|
||||
// minimum bulge value before resorting to a line segment;
|
||||
// the value 0.0218 is equivalent to about 5 degrees arc,
|
||||
#define MIN_BULGE 0.0218
|
||||
|
||||
DXF2BRD_CONVERTER::DXF2BRD_CONVERTER() : DRW_Interface()
|
||||
DXF2BRD_CONVERTER::DXF2BRD_CONVERTER() : DL_CreationAdapter()
|
||||
{
|
||||
m_xOffset = 0.0; // X coord offset for conversion (in mm)
|
||||
m_yOffset = 0.0; // Y coord offset for conversion (in mm)
|
||||
|
@ -92,26 +90,78 @@ int DXF2BRD_CONVERTER::mapDim( double aDxfValue )
|
|||
|
||||
int DXF2BRD_CONVERTER::mapWidth( double aDxfWidth )
|
||||
{
|
||||
// Always return the default line width
|
||||
#if 0
|
||||
// mapWidth returns the aDxfValue if aDxfWidth > 0 m_defaultThickness
|
||||
if( aDxfWidth > 0.0 )
|
||||
return Millimeter2iu( aDxfWidth * m_DXF2mm );
|
||||
|
||||
#endif
|
||||
return Millimeter2iu( m_defaultThickness );
|
||||
}
|
||||
|
||||
bool DXF2BRD_CONVERTER::ImportDxfFile( const wxString& aFile )
|
||||
{
|
||||
LOCALE_IO locale;
|
||||
dxfRW* dxf = new dxfRW( aFile.ToUTF8() );
|
||||
bool success = dxf->read( this, true );
|
||||
|
||||
delete dxf;
|
||||
DL_Dxf dxf_reader;
|
||||
std::string filename = TO_UTF8( aFile );
|
||||
bool success = true;
|
||||
|
||||
if( !dxf_reader.in( filename, this ) ) // if file open failed
|
||||
success = false;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::addLayer( const DRW_Layer& aData )
|
||||
void DXF2BRD_CONVERTER::reportMsg( const char* aMessage )
|
||||
{
|
||||
// Add message to keep trace of not handled dxf entities
|
||||
m_messages += aMessage;
|
||||
m_messages += '\n';
|
||||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::addSpline( const DL_SplineData& aData )
|
||||
{
|
||||
// Called when starting reading a spline
|
||||
m_curr_entity.Clear();
|
||||
m_curr_entity.m_EntityParseStatus = 1;
|
||||
m_curr_entity.m_EntityFlag = aData.flags;
|
||||
m_curr_entity.m_EntityType = DL_ENTITY_SPLINE;
|
||||
m_curr_entity.m_SplineDegree = aData.degree;
|
||||
m_curr_entity.m_SplineTangentStartX = aData.tangentStartX;
|
||||
m_curr_entity.m_SplineTangentStartY = aData.tangentStartY;
|
||||
m_curr_entity.m_SplineTangentEndX = aData.tangentEndX;
|
||||
m_curr_entity.m_SplineTangentEndY = aData.tangentEndY;
|
||||
m_curr_entity.m_SplineKnotsCount = aData.nKnots;
|
||||
m_curr_entity.m_SplineControlCount = aData.nControl;
|
||||
m_curr_entity.m_SplineFitCount = aData.nFit;
|
||||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::addControlPoint( const DL_ControlPointData& aData )
|
||||
{
|
||||
// Called for every spline control point, when reading a spline entity
|
||||
m_curr_entity.m_SplineControlPointList.push_back( SPLINE_CTRL_POINT( aData.x , aData.y, aData.w ) );
|
||||
}
|
||||
|
||||
void DXF2BRD_CONVERTER::addFitPoint( const DL_FitPointData& aData )
|
||||
{
|
||||
// Called for every spline fit point, when reading a spline entity
|
||||
// we store only the X,Y coord values in a wxRealPoint
|
||||
m_curr_entity.m_SplineFitPointList.push_back( wxRealPoint( aData.x, aData.y ) );
|
||||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::addKnot( const DL_KnotData& aData)
|
||||
{
|
||||
// Called for every spline knot value, when reading a spline entity
|
||||
m_curr_entity.m_SplineKnotsList.push_back( aData.k );
|
||||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::addLayer( const DL_LayerData& aData )
|
||||
{
|
||||
// Not yet useful in Pcbnew.
|
||||
#if 0
|
||||
|
@ -121,129 +171,110 @@ void DXF2BRD_CONVERTER::addLayer( const DRW_Layer& aData )
|
|||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::addLine( const DRW_Line& aData )
|
||||
void DXF2BRD_CONVERTER::addLine( const DL_LineData& aData )
|
||||
{
|
||||
DRAWSEGMENT* segm = ( m_importAsfootprintGraphicItems ) ?
|
||||
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 ) );
|
||||
wxPoint start( mapX( aData.x1 ), mapY( aData.y1 ) );
|
||||
segm->SetStart( start );
|
||||
wxPoint end( mapX( aData.secPoint.x ), mapY( aData.secPoint.y ) );
|
||||
wxPoint end( mapX( aData.x2 ), mapY( aData.y2 ) );
|
||||
segm->SetEnd( end );
|
||||
segm->SetWidth( mapWidth( aData.thickness ) );
|
||||
segm->SetWidth( mapWidth( attributes.getWidth() ) );
|
||||
m_newItemsList.push_back( segm );
|
||||
}
|
||||
|
||||
void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& aData )
|
||||
|
||||
void DXF2BRD_CONVERTER::addPolyline(const DL_PolylineData& aData )
|
||||
{
|
||||
// Convert DXF Polylines into a series of KiCad Lines and Arcs.
|
||||
// A Polyline (as opposed to a LWPolyline) may be a 3D line or
|
||||
// even a 3D Mesh. The only type of Polyline which is guaranteed
|
||||
// to import correctly is a 2D Polyline in X and Y, which is what
|
||||
// we assume of all Polylines. The width used is the width of the
|
||||
// Polyline; per-vertex line widths, if present, are ignored.
|
||||
// we assume of all Polylines. The width used is the width of the Polyline.
|
||||
// per-vertex line widths, if present, are ignored.
|
||||
|
||||
wxRealPoint seg_start;
|
||||
wxRealPoint poly_start;
|
||||
double bulge = 0.0;
|
||||
int lineWidth = mapWidth( aData.thickness );
|
||||
|
||||
for( unsigned ii = 0; ii < aData.vertlist.size(); ii++ )
|
||||
{
|
||||
DRW_Vertex* vertex = aData.vertlist[ii];
|
||||
|
||||
if( ii == 0 )
|
||||
{
|
||||
seg_start.x = m_xOffset + vertex->basePoint.x * m_DXF2mm;
|
||||
seg_start.y = m_yOffset - vertex->basePoint.y * m_DXF2mm;
|
||||
bulge = vertex->bulge;
|
||||
poly_start = seg_start;
|
||||
continue;
|
||||
}
|
||||
|
||||
wxRealPoint seg_end( m_xOffset + vertex->basePoint.x * m_DXF2mm,
|
||||
m_yOffset - vertex->basePoint.y * m_DXF2mm );
|
||||
|
||||
if( std::abs( bulge ) < MIN_BULGE )
|
||||
insertLine( seg_start, seg_end, lineWidth );
|
||||
else
|
||||
insertArc( seg_start, seg_end, bulge, lineWidth );
|
||||
|
||||
bulge = vertex->bulge;
|
||||
seg_start = seg_end;
|
||||
}
|
||||
|
||||
// LWPolyline flags bit 0 indicates closed (1) or open (0) polyline
|
||||
if( aData.flags & 1 )
|
||||
{
|
||||
if( std::abs( bulge ) < MIN_BULGE )
|
||||
insertLine( seg_start, poly_start, lineWidth );
|
||||
else
|
||||
insertArc( seg_start, poly_start, bulge, lineWidth );
|
||||
}
|
||||
m_curr_entity.Clear();
|
||||
m_curr_entity.m_EntityParseStatus = 1;
|
||||
m_curr_entity.m_EntityFlag = aData.flags;
|
||||
m_curr_entity.m_EntityType = DL_ENTITY_POLYLINE;
|
||||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::addLWPolyline(const DRW_LWPolyline& aData )
|
||||
void DXF2BRD_CONVERTER::addVertex( const DL_VertexData& aData )
|
||||
{
|
||||
// Currently, Pcbnew does not know polylines, for boards.
|
||||
// So we have to convert a polyline to a set of segments.
|
||||
// The import is a simplified import: the width of segment is
|
||||
// (obviously constant and is the width of the DRW_LWPolyline.
|
||||
// the variable width of each vertex (when exists) is not used.
|
||||
wxRealPoint seg_start;
|
||||
wxRealPoint poly_start;
|
||||
double bulge = 0.0;
|
||||
int lineWidth = mapWidth( aData.thickness );
|
||||
if( m_curr_entity.m_EntityParseStatus == 0 )
|
||||
return; // Error
|
||||
|
||||
for( unsigned ii = 0; ii < aData.vertlist.size(); ii++ )
|
||||
int lineWidth = mapWidth( attributes.getWidth() );
|
||||
|
||||
const DL_VertexData* vertex = &aData;
|
||||
|
||||
if( m_curr_entity.m_EntityParseStatus == 1 ) // This is the first vertex of an entity
|
||||
{
|
||||
DRW_Vertex2D* vertex = aData.vertlist[ii];
|
||||
|
||||
if( ii == 0 )
|
||||
{
|
||||
seg_start.x = m_xOffset + vertex->x * m_DXF2mm;
|
||||
seg_start.y = m_yOffset - vertex->y * m_DXF2mm;
|
||||
bulge = vertex->bulge;
|
||||
poly_start = seg_start;
|
||||
continue;
|
||||
}
|
||||
|
||||
wxRealPoint seg_end( m_xOffset + vertex->x * m_DXF2mm, m_yOffset - vertex->y * m_DXF2mm );
|
||||
|
||||
if( std::abs( bulge ) < MIN_BULGE )
|
||||
insertLine( seg_start, seg_end, lineWidth );
|
||||
else
|
||||
insertArc( seg_start, seg_end, bulge, lineWidth );
|
||||
|
||||
bulge = vertex->bulge;
|
||||
seg_start = seg_end;
|
||||
m_curr_entity.m_LastCoordinate.x = m_xOffset + vertex->x * m_DXF2mm;
|
||||
m_curr_entity.m_LastCoordinate.y = m_yOffset - vertex->y * m_DXF2mm;
|
||||
m_curr_entity.m_PolylineStart = m_curr_entity.m_LastCoordinate;
|
||||
m_curr_entity.m_BulgeVertex = vertex->bulge;
|
||||
m_curr_entity.m_EntityParseStatus = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
// LWPolyline flags bit 0 indicates closed (1) or open (0) polyline
|
||||
if( aData.flags & 1 )
|
||||
{
|
||||
if( std::abs( bulge ) < MIN_BULGE )
|
||||
insertLine( seg_start, poly_start, lineWidth );
|
||||
else
|
||||
insertArc( seg_start, poly_start, bulge, lineWidth );
|
||||
}
|
||||
|
||||
wxRealPoint seg_end( m_xOffset + vertex->x * m_DXF2mm,
|
||||
m_yOffset - vertex->y * m_DXF2mm );
|
||||
|
||||
if( std::abs( m_curr_entity.m_BulgeVertex ) < MIN_BULGE )
|
||||
insertLine( m_curr_entity.m_LastCoordinate, seg_end, lineWidth );
|
||||
else
|
||||
insertArc( m_curr_entity.m_LastCoordinate, seg_end, m_curr_entity.m_BulgeVertex, lineWidth );
|
||||
|
||||
m_curr_entity.m_LastCoordinate = seg_end;
|
||||
m_curr_entity.m_BulgeVertex = vertex->bulge;
|
||||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::addCircle( const DRW_Circle& aData )
|
||||
void DXF2BRD_CONVERTER::endEntity()
|
||||
{
|
||||
if( m_curr_entity.m_EntityType == DL_ENTITY_POLYLINE ||
|
||||
m_curr_entity.m_EntityType == DL_ENTITY_LWPOLYLINE )
|
||||
{
|
||||
// Polyline flags bit 0 indicates closed (1) or open (0) polyline
|
||||
if( m_curr_entity.m_EntityFlag & 1 )
|
||||
{
|
||||
int lineWidth = mapWidth( attributes.getWidth() );
|
||||
|
||||
if( std::abs( m_curr_entity.m_BulgeVertex ) < MIN_BULGE )
|
||||
insertLine( m_curr_entity.m_LastCoordinate, m_curr_entity.m_PolylineStart, lineWidth );
|
||||
else
|
||||
insertArc( m_curr_entity.m_LastCoordinate, m_curr_entity.m_PolylineStart,
|
||||
m_curr_entity.m_BulgeVertex, lineWidth );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_curr_entity.m_EntityType == DL_ENTITY_SPLINE )
|
||||
{
|
||||
int lineWidth = mapWidth( attributes.getWidth() );
|
||||
insertSpline( lineWidth );
|
||||
}
|
||||
|
||||
m_curr_entity.Clear();
|
||||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::addCircle( const DL_CircleData& aData )
|
||||
{
|
||||
DRAWSEGMENT* segm = ( m_importAsfootprintGraphicItems ) ?
|
||||
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 ) );
|
||||
wxPoint center( mapX( aData.cx ), mapY( aData.cy ) );
|
||||
segm->SetCenter( center );
|
||||
wxPoint circle_start( mapX( aData.basePoint.x + aData.radious ), mapY( aData.basePoint.y ) );
|
||||
wxPoint circle_start( mapX( aData.cx + aData.radius ), mapY( aData.cy ) );
|
||||
segm->SetArcStart( circle_start );
|
||||
segm->SetWidth( mapWidth( aData.thickness ) );
|
||||
segm->SetWidth( mapWidth( attributes.getWidth() ) );
|
||||
m_newItemsList.push_back( segm );
|
||||
}
|
||||
|
||||
|
@ -251,7 +282,7 @@ void DXF2BRD_CONVERTER::addCircle( const DRW_Circle& aData )
|
|||
/*
|
||||
* Import Arc entities.
|
||||
*/
|
||||
void DXF2BRD_CONVERTER::addArc( const DRW_Arc& data )
|
||||
void DXF2BRD_CONVERTER::addArc( const DL_ArcData& data )
|
||||
{
|
||||
DRAWSEGMENT* segm = ( m_importAsfootprintGraphicItems ) ?
|
||||
static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT;
|
||||
|
@ -260,18 +291,18 @@ void DXF2BRD_CONVERTER::addArc( const DRW_Arc& data )
|
|||
segm->SetShape( S_ARC );
|
||||
|
||||
// Init arc centre:
|
||||
wxPoint center( mapX( data.basePoint.x ), mapY( data.basePoint.y ) );
|
||||
wxPoint center( mapX( data.cx ), mapY( data.cy ) );
|
||||
segm->SetCenter( center );
|
||||
|
||||
// Init arc start point
|
||||
double arcStartx = data.radious;
|
||||
double arcStartx = data.radius;
|
||||
double arcStarty = 0;
|
||||
double startangle = data.staangle;
|
||||
double endangle = data.endangle;
|
||||
double startangle = data.angle1;
|
||||
double endangle = data.angle2;
|
||||
|
||||
RotatePoint( &arcStartx, &arcStarty, -RAD2DECIDEG( startangle ) );
|
||||
wxPoint arcStart( mapX( arcStartx + data.basePoint.x ),
|
||||
mapY( arcStarty + data.basePoint.y ) );
|
||||
wxPoint arcStart( mapX( arcStartx + data.cx ),
|
||||
mapY( arcStarty + data.cy ) );
|
||||
segm->SetArcStart( arcStart );
|
||||
|
||||
// calculate arc angle (arcs are CCW, and should be < 0 in Pcbnew)
|
||||
|
@ -282,12 +313,12 @@ void DXF2BRD_CONVERTER::addArc( const DRW_Arc& data )
|
|||
|
||||
segm->SetAngle( angle );
|
||||
|
||||
segm->SetWidth( mapWidth( data.thickness ) );
|
||||
segm->SetWidth( mapWidth( attributes.getWidth() ) );
|
||||
m_newItemsList.push_back( segm );
|
||||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::addText( const DRW_Text& aData )
|
||||
void DXF2BRD_CONVERTER::addText( const DL_TextData& aData )
|
||||
{
|
||||
BOARD_ITEM* brdItem;
|
||||
EDA_TEXT* textItem;
|
||||
|
@ -307,12 +338,12 @@ void DXF2BRD_CONVERTER::addText( const DRW_Text& aData )
|
|||
|
||||
brdItem->SetLayer( ToLAYER_ID( m_brdLayer ) );
|
||||
|
||||
wxPoint refPoint( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) );
|
||||
wxPoint secPoint( mapX( aData.secPoint.x ), mapY( aData.secPoint.y ) );
|
||||
wxPoint refPoint( mapX( aData.ipx ), mapY( aData.ipy ) );
|
||||
wxPoint secPoint( mapX( aData.apx ), mapY( aData.apy ) );
|
||||
|
||||
if( aData.alignV != 0 || aData.alignH != 0 || aData.alignH == DRW_Text::HMiddle )
|
||||
if( aData.vJustification != 0 || aData.hJustification != 0 || aData.hJustification == 4 )
|
||||
{
|
||||
if( aData.alignH != DRW_Text::HAligned && aData.alignH != DRW_Text::HFit )
|
||||
if( aData.hJustification != 3 && aData.hJustification != 5 )
|
||||
{
|
||||
wxPoint tmp = secPoint;
|
||||
secPoint = refPoint;
|
||||
|
@ -320,50 +351,50 @@ void DXF2BRD_CONVERTER::addText( const DRW_Text& aData )
|
|||
}
|
||||
}
|
||||
|
||||
switch( aData.alignV )
|
||||
switch( aData.vJustification )
|
||||
{
|
||||
case DRW_Text::VBaseLine:
|
||||
case 0: //DRW_Text::VBaseLine:
|
||||
textItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
|
||||
break;
|
||||
|
||||
case DRW_Text::VBottom:
|
||||
case 1: //DRW_Text::VBottom:
|
||||
textItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
|
||||
break;
|
||||
|
||||
case DRW_Text::VMiddle:
|
||||
case 2: //DRW_Text::VMiddle:
|
||||
textItem->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
|
||||
break;
|
||||
|
||||
case DRW_Text::VTop:
|
||||
case 3: //DRW_Text::VTop:
|
||||
textItem->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
|
||||
break;
|
||||
}
|
||||
|
||||
switch( aData.alignH )
|
||||
switch( aData.hJustification )
|
||||
{
|
||||
case DRW_Text::HLeft:
|
||||
case 0: //DRW_Text::HLeft:
|
||||
textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
|
||||
break;
|
||||
|
||||
case DRW_Text::HCenter:
|
||||
case 1: //DRW_Text::HCenter:
|
||||
textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
|
||||
break;
|
||||
|
||||
case DRW_Text::HRight:
|
||||
case 2: //DRW_Text::HRight:
|
||||
textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
|
||||
break;
|
||||
|
||||
case DRW_Text::HAligned:
|
||||
case 3: //DRW_Text::HAligned:
|
||||
// no equivalent options in text pcb.
|
||||
textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
|
||||
break;
|
||||
|
||||
case DRW_Text::HMiddle:
|
||||
case 4: //DRW_Text::HMiddle:
|
||||
// no equivalent options in text pcb.
|
||||
textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
|
||||
break;
|
||||
|
||||
case DRW_Text::HFit:
|
||||
case 5: //DRW_Text::HFit:
|
||||
// no equivalent options in text pcb.
|
||||
textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
|
||||
break;
|
||||
|
@ -392,14 +423,14 @@ void DXF2BRD_CONVERTER::addText( const DRW_Text& aData )
|
|||
// The 0.8 factor gives a better height/width ratio with our font
|
||||
textItem->SetTextWidth( mapDim( aData.height * 0.8 ) );
|
||||
textItem->SetTextHeight( mapDim( aData.height ) );
|
||||
textItem->SetThickness( mapWidth( aData.thickness ) );
|
||||
textItem->SetThickness( mapWidth( aData.height * 0.15 ) ); // Gives a reasonable text thickness
|
||||
textItem->SetText( text );
|
||||
|
||||
m_newItemsList.push_back( static_cast< BOARD_ITEM* >( brdItem ) );
|
||||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::addMText( const DRW_MText& aData )
|
||||
void DXF2BRD_CONVERTER::addMText( const DL_MTextData& aData )
|
||||
{
|
||||
wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) );
|
||||
wxString attrib, tmp;
|
||||
|
@ -446,7 +477,7 @@ void DXF2BRD_CONVERTER::addMText( const DRW_MText& aData )
|
|||
}
|
||||
|
||||
brdItem->SetLayer( ToLAYER_ID( m_brdLayer ) );
|
||||
wxPoint textpos( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) );
|
||||
wxPoint textpos( mapX( aData.ipx ), mapY( aData.ipy ) );
|
||||
|
||||
textItem->SetTextPos( textpos );
|
||||
textItem->SetTextAngle( aData.angle * 10 );
|
||||
|
@ -454,15 +485,15 @@ void DXF2BRD_CONVERTER::addMText( const DRW_MText& aData )
|
|||
// The 0.8 factor gives a better height/width ratio with our font
|
||||
textItem->SetTextWidth( mapDim( aData.height * 0.8 ) );
|
||||
textItem->SetTextHeight( mapDim( aData.height ) );
|
||||
textItem->SetThickness( mapWidth( aData.thickness ) );
|
||||
textItem->SetThickness( mapWidth( aData.height * 0.15 ) ); // Gives a reasonable text thickness
|
||||
textItem->SetText( text );
|
||||
|
||||
// Initialize text justifications:
|
||||
if( aData.textgen <= 3 )
|
||||
if( aData.attachmentPoint <= 3 )
|
||||
{
|
||||
textItem->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
|
||||
}
|
||||
else if( aData.textgen <= 6 )
|
||||
else if( aData.attachmentPoint <= 6 )
|
||||
{
|
||||
textItem->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
|
||||
}
|
||||
|
@ -471,11 +502,11 @@ void DXF2BRD_CONVERTER::addMText( const DRW_MText& aData )
|
|||
textItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
|
||||
}
|
||||
|
||||
if( aData.textgen % 3 == 1 )
|
||||
if( aData.attachmentPoint % 3 == 1 )
|
||||
{
|
||||
textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
|
||||
}
|
||||
else if( aData.textgen % 3 == 2 )
|
||||
else if( aData.attachmentPoint % 3 == 2 )
|
||||
{
|
||||
textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
|
||||
}
|
||||
|
@ -484,7 +515,7 @@ void DXF2BRD_CONVERTER::addMText( const DRW_MText& aData )
|
|||
textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
|
||||
}
|
||||
|
||||
#if 0 // These setting have no mening in Pcbnew
|
||||
#if 0 // These setting have no meaning in Pcbnew
|
||||
if( data.alignH == 1 )
|
||||
{
|
||||
// Text is left to right;
|
||||
|
@ -512,86 +543,92 @@ void DXF2BRD_CONVERTER::addMText( const DRW_MText& aData )
|
|||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::addHeader( const DRW_Header* data )
|
||||
void DXF2BRD_CONVERTER::setVariableInt( const std::string& key, int value, int code )
|
||||
{
|
||||
std::map<std::string, DRW_Variant*>::const_iterator it;
|
||||
m_DXF2mm = 1.0; // assume no scale factor
|
||||
// Called for every int variable in the DXF file (e.g. "$INSUNITS").
|
||||
|
||||
for( it = data->vars.begin(); it != data->vars.end(); ++it )
|
||||
if( key == "$DWGCODEPAGE" )
|
||||
{
|
||||
std::string key = ( (*it).first ).c_str();
|
||||
|
||||
if( key == "$DWGCODEPAGE" )
|
||||
{
|
||||
DRW_Variant* var = (*it).second;
|
||||
m_codePage = ( *var->content.s );
|
||||
}
|
||||
else if( key == "$INSUNITS" )
|
||||
{
|
||||
DRW_Variant* var = (*it).second;
|
||||
|
||||
switch( var->content.i )
|
||||
{
|
||||
case 1: // inches
|
||||
m_DXF2mm = 25.4;
|
||||
break;
|
||||
|
||||
case 2: // feet
|
||||
m_DXF2mm = 304.8;
|
||||
break;
|
||||
|
||||
case 5: // centimeters
|
||||
m_DXF2mm = 10.0;
|
||||
break;
|
||||
|
||||
case 6: // meters
|
||||
m_DXF2mm = 1000.0;
|
||||
break;
|
||||
|
||||
case 8: // microinches
|
||||
m_DXF2mm = 2.54e-5;
|
||||
break;
|
||||
|
||||
case 9: // mils
|
||||
m_DXF2mm = 0.0254;
|
||||
break;
|
||||
|
||||
case 10: // yards
|
||||
m_DXF2mm = 914.4;
|
||||
break;
|
||||
|
||||
case 11: // Angstroms
|
||||
m_DXF2mm = 1.0e-7;
|
||||
break;
|
||||
|
||||
case 12: // nanometers
|
||||
m_DXF2mm = 1.0e-6;
|
||||
break;
|
||||
|
||||
case 13: // micrometers
|
||||
m_DXF2mm = 1.0e-3;
|
||||
break;
|
||||
|
||||
case 14: // decimeters
|
||||
m_DXF2mm = 100.0;
|
||||
break;
|
||||
|
||||
default:
|
||||
// use the default of 1.0 for:
|
||||
// 0: Unspecified Units
|
||||
// 4: mm
|
||||
// 3: miles
|
||||
// 7: kilometers
|
||||
// 15: decameters
|
||||
// 16: hectometers
|
||||
// 17: gigameters
|
||||
// 18: AU
|
||||
// 19: lightyears
|
||||
// 20: parsecs
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_codePage = value;
|
||||
return;
|
||||
}
|
||||
|
||||
if( key == "$INSUNITS" ) // Drawing units
|
||||
{
|
||||
switch( value )
|
||||
{
|
||||
case 1: // inches
|
||||
m_DXF2mm = 25.4;
|
||||
break;
|
||||
|
||||
case 2: // feet
|
||||
m_DXF2mm = 304.8;
|
||||
break;
|
||||
|
||||
case 4: // mm
|
||||
m_DXF2mm = 1.0;
|
||||
break;
|
||||
|
||||
case 5: // centimeters
|
||||
m_DXF2mm = 10.0;
|
||||
break;
|
||||
|
||||
case 6: // meters
|
||||
m_DXF2mm = 1000.0;
|
||||
break;
|
||||
|
||||
case 8: // microinches
|
||||
m_DXF2mm = 2.54e-5;
|
||||
break;
|
||||
|
||||
case 9: // mils
|
||||
m_DXF2mm = 0.0254;
|
||||
break;
|
||||
|
||||
case 10: // yards
|
||||
m_DXF2mm = 914.4;
|
||||
break;
|
||||
|
||||
case 11: // Angstroms
|
||||
m_DXF2mm = 1.0e-7;
|
||||
break;
|
||||
|
||||
case 12: // nanometers
|
||||
m_DXF2mm = 1.0e-6;
|
||||
break;
|
||||
|
||||
case 13: // micrometers
|
||||
m_DXF2mm = 1.0e-3;
|
||||
break;
|
||||
|
||||
case 14: // decimeters
|
||||
m_DXF2mm = 100.0;
|
||||
break;
|
||||
|
||||
default:
|
||||
// use the default of 1.0 for:
|
||||
// 0: Unspecified Units
|
||||
// 3: miles
|
||||
// 7: kilometers
|
||||
// 15: decameters
|
||||
// 16: hectometers
|
||||
// 17: gigameters
|
||||
// 18: AU
|
||||
// 19: lightyears
|
||||
// 20: parsecs
|
||||
m_DXF2mm = 1.0;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::setVariableString( const std::string& key, const std::string& value,
|
||||
int code )
|
||||
{
|
||||
// Called for every string variable in the DXF file (e.g. "$ACADVER").
|
||||
}
|
||||
|
||||
|
||||
|
@ -723,7 +760,7 @@ wxString DXF2BRD_CONVERTER::toNativeString( const wxString& aData )
|
|||
}
|
||||
|
||||
|
||||
void DXF2BRD_CONVERTER::addTextStyle( const DRW_Textstyle& aData )
|
||||
void DXF2BRD_CONVERTER::addTextStyle( const DL_StyleData& aData )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
@ -743,7 +780,6 @@ void DXF2BRD_CONVERTER::insertLine( const wxRealPoint& aSegStart,
|
|||
segm->SetWidth( aWidth );
|
||||
|
||||
m_newItemsList.push_back( segm );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
@ -825,3 +861,82 @@ void DXF2BRD_CONVERTER::insertArc( const wxRealPoint& aSegStart, const wxRealPoi
|
|||
m_newItemsList.push_back( segm );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#include "tinyspline_lib/tinysplinecpp.h"
|
||||
|
||||
void DXF2BRD_CONVERTER::insertSpline( int aWidth )
|
||||
{
|
||||
#if 0 // Debug only
|
||||
wxLogMessage("spl deg %d kn %d ctr %d fit %d",
|
||||
m_curr_entity.m_SplineDegree,
|
||||
m_curr_entity.m_SplineKnotsList.size(),
|
||||
m_curr_entity.m_SplineControlPointList.size(),
|
||||
m_curr_entity.m_SplineFitPointList.size() );
|
||||
#endif
|
||||
|
||||
// Very basic conversion to segments
|
||||
unsigned imax = m_curr_entity.m_SplineControlPointList.size();
|
||||
|
||||
if( imax < 2 ) // malformed spline
|
||||
return;
|
||||
|
||||
#if 0 // set to 1 to approximate the spline by segments between 2 control points
|
||||
wxPoint startpoint( mapX( m_curr_entity.m_SplineControlPointList[0].m_x ),
|
||||
mapY( m_curr_entity.m_SplineControlPointList[0].m_y ) );
|
||||
|
||||
for( unsigned int ii = 1; ii < imax; ++ii )
|
||||
{
|
||||
wxPoint endpoint( mapX( m_curr_entity.m_SplineControlPointList[ii].m_x ),
|
||||
mapY( m_curr_entity.m_SplineControlPointList[ii].m_y ) );
|
||||
|
||||
if( startpoint != endpoint )
|
||||
{
|
||||
DRAWSEGMENT* segm = ( m_importAsfootprintGraphicItems ) ?
|
||||
static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) :
|
||||
new DRAWSEGMENT;
|
||||
segm->SetLayer( ToLAYER_ID( m_brdLayer ) );
|
||||
segm->SetStart( startpoint );
|
||||
segm->SetEnd( endpoint );
|
||||
segm->SetWidth( aWidth );
|
||||
m_newItemsList.push_back( segm );
|
||||
startpoint = endpoint;
|
||||
}
|
||||
}
|
||||
#else // Use bezier curves, supported by pcbnew, to approximate the spline
|
||||
tinyspline::BSpline dxfspline( m_curr_entity.m_SplineControlPointList.size(),
|
||||
/* coord dim */ 2, m_curr_entity.m_SplineDegree );
|
||||
std::vector<double> ctrlp;
|
||||
|
||||
for( unsigned ii = 0; ii < imax; ++ii )
|
||||
{
|
||||
ctrlp.push_back( m_curr_entity.m_SplineControlPointList[ii].m_x );
|
||||
ctrlp.push_back( m_curr_entity.m_SplineControlPointList[ii].m_y );
|
||||
}
|
||||
|
||||
dxfspline.setCtrlp( ctrlp );
|
||||
dxfspline.setKnots( m_curr_entity.m_SplineKnotsList );
|
||||
tinyspline::BSpline beziers( dxfspline.toBeziers() );
|
||||
|
||||
std::vector<double> coords = beziers.ctrlp();
|
||||
|
||||
// Each Bezier curve uses 4 vertices (a start point, 2 control points and a end point).
|
||||
// So we can have more than one Bezier curve ( there are one curve each four vertices)
|
||||
for( unsigned ii = 0; ii < coords.size(); ii += 8 )
|
||||
{
|
||||
DRAWSEGMENT* segm = ( m_importAsfootprintGraphicItems ) ?
|
||||
static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) :
|
||||
new DRAWSEGMENT;
|
||||
segm->SetLayer( ToLAYER_ID( m_brdLayer ) );
|
||||
segm->SetShape( S_CURVE );
|
||||
segm->SetStart( wxPoint( mapX( coords[ii] ), mapY( coords[ii+1] ) ) );
|
||||
segm->SetBezControl1( wxPoint( mapX( coords[ii+2] ), mapY( coords[ii+3] ) ) );
|
||||
segm->SetBezControl2( wxPoint( mapX( coords[ii+4] ), mapY( coords[ii+5] ) ) );
|
||||
segm->SetEnd( wxPoint( mapX( coords[ii+6] ), mapY( coords[ii+7] ) ) );
|
||||
segm->SetWidth( aWidth );
|
||||
segm->RebuildBezierToSegmentsPointsList( aWidth );
|
||||
m_newItemsList.push_back( segm );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1,32 +1,33 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** This file comes from the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2011 Rallaz, rallazz@gmail.com
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License as published by the Free Software
|
||||
** Foundation either version 2 of the License, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#ifndef FILTERDXFRW_H
|
||||
#define FILTERDXFRW_H
|
||||
#ifndef DXF2BRD_ITEMS_H
|
||||
#define DXF2BRD_ITEMS_H
|
||||
|
||||
#include "drw_interface.h"
|
||||
#include "dl_dxf.h"
|
||||
#include "dl_creationadapter.h"
|
||||
#include "wx/wx.h"
|
||||
#include <list>
|
||||
|
||||
|
@ -34,12 +35,81 @@ class BOARD;
|
|||
class BOARD_ITEM;
|
||||
|
||||
/**
|
||||
* This format filter class can import and export DXF files.
|
||||
* It depends on the dxflib library.
|
||||
*
|
||||
* @author Rallaz
|
||||
* A helper class to store a spline control point (in X,Y plane only)
|
||||
*/
|
||||
class DXF2BRD_CONVERTER : public DRW_Interface
|
||||
struct SPLINE_CTRL_POINT
|
||||
{
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_weight;
|
||||
|
||||
SPLINE_CTRL_POINT( double a_x, double a_y, double a_weight )
|
||||
: m_x( a_x ), m_y( a_y ), m_weight( a_weight )
|
||||
{}
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper class to parse a DXF entity (polyline and spline)
|
||||
*/
|
||||
class DXF2BRD_ENTITY_DATA
|
||||
{
|
||||
public:
|
||||
int m_EntityType; // the DXF type of entity
|
||||
int m_EntityParseStatus; // Inside a entity: status od parsing:
|
||||
// 0 = no entity
|
||||
// 1 = first item of entity
|
||||
// 2 = entity in progress
|
||||
int m_EntityFlag; // a info flag to parse entities
|
||||
|
||||
wxRealPoint m_LastCoordinate; // the last vertex coordinate read (unit = mm)
|
||||
wxRealPoint m_PolylineStart; // The first point of the polyline entity, when reading a polyline (unit = mm)
|
||||
double m_BulgeVertex; // the last vertex bulge value read
|
||||
|
||||
// for spline parsing: parameters
|
||||
unsigned int m_SplineDegree;
|
||||
unsigned int m_SplineKnotsCount;
|
||||
unsigned int m_SplineControlCount;
|
||||
unsigned int m_SplineFitCount;
|
||||
double m_SplineTangentStartX; // tangeant dir X for the start point
|
||||
double m_SplineTangentStartY; // tangeant dir Y for the start point
|
||||
double m_SplineTangentEndX; // tangeant dir X for the end point
|
||||
double m_SplineTangentEndY; // tangeant dir Y for the end point
|
||||
|
||||
// for spline parsing: buffers to store control points, fit points and knot
|
||||
std::vector<double> m_SplineKnotsList; // knots list, code 40
|
||||
// control points list coordinates, code 10, 20 & 30 (only X and Y cood and Weight)
|
||||
std::vector<SPLINE_CTRL_POINT> m_SplineControlPointList;
|
||||
// fit points list, code 11, 21 & 31 (only X and Y cood)
|
||||
std::vector<wxRealPoint> m_SplineFitPointList;
|
||||
|
||||
DXF2BRD_ENTITY_DATA() { Clear(); };
|
||||
|
||||
// Reset the entity parameters
|
||||
void Clear()
|
||||
{
|
||||
m_EntityType = DL_UNKNOWN;
|
||||
m_EntityParseStatus = 0;
|
||||
m_EntityFlag = 0;
|
||||
m_SplineDegree = 1;
|
||||
m_SplineKnotsCount = 0;
|
||||
m_SplineControlCount = 0;
|
||||
m_SplineFitCount = 0;
|
||||
m_SplineTangentStartX = 0.0;
|
||||
m_SplineTangentStartY = 0.0;
|
||||
m_SplineTangentEndX = 0.0;
|
||||
m_SplineTangentEndY = 0.0;
|
||||
m_SplineKnotsList.clear();
|
||||
m_SplineControlPointList.clear();
|
||||
m_SplineFitPointList.clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This class import DXF ASCII files and convert basic entities to board entities.
|
||||
* It depends on the dxflib library.
|
||||
*/
|
||||
class DXF2BRD_CONVERTER : public DL_CreationAdapter
|
||||
{
|
||||
private:
|
||||
std::list<BOARD_ITEM*> m_newItemsList; // The list of new items added to the board
|
||||
|
@ -52,6 +122,10 @@ private:
|
|||
std::string m_codePage; // The code page, not used here
|
||||
bool m_importAsfootprintGraphicItems; // Use module items instead of board items when true.
|
||||
// true when the items are imported in the footprint editor
|
||||
std::string m_messages; // messages generated during dxf file parsing.
|
||||
// Each message ends by '\n'
|
||||
DXF2BRD_ENTITY_DATA m_curr_entity; // the current entity parameters when parsing a DXF entity
|
||||
|
||||
|
||||
public:
|
||||
DXF2BRD_CONVERTER();
|
||||
|
@ -115,7 +189,15 @@ public:
|
|||
return m_newItemsList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of messages in one string. Each message ends by '\n'
|
||||
*/
|
||||
std::string& GetMessages() { return m_messages; }
|
||||
|
||||
private:
|
||||
// report message to keep trace of not supported dxf entities:
|
||||
void reportMsg( const char* aMessage );
|
||||
|
||||
// coordinate conversions from dxf to internal units
|
||||
int mapX( double aDxfCoordX );
|
||||
int mapY( double aDxfCoordY );
|
||||
|
@ -124,59 +206,88 @@ private:
|
|||
// or m_defaultThickness
|
||||
int mapWidth( double aDxfWidth );
|
||||
|
||||
// Functions to aid in the creation of a LWPolyline
|
||||
// Functions to aid in the creation of a Polyline
|
||||
void insertLine( const wxRealPoint& aSegStart, const wxRealPoint& aSegEnd, int aWidth );
|
||||
void insertArc( const wxRealPoint& aSegStart, const wxRealPoint& aSegEnd,
|
||||
double aBulge, int aWidth );
|
||||
// Add a dxf spline (stored in m_curr_entity) to the board, after conversion to segments
|
||||
void insertSpline( int aWidth );
|
||||
|
||||
// Methods from DRW_CreationInterface:
|
||||
// They are "call back" fonctions, called when the corresponding object
|
||||
// is read in dxf file
|
||||
// Depending of the application, they can do something or not
|
||||
virtual void addHeader( const DRW_Header* aData ) override;
|
||||
virtual void addLType( const DRW_LType& aData ) override {}
|
||||
virtual void addLayer( const DRW_Layer& aData ) override;
|
||||
virtual void addDimStyle( const DRW_Dimstyle& aData ) override {}
|
||||
virtual void addBlock( const DRW_Block& aData ) override {}
|
||||
virtual void endBlock() override {}
|
||||
virtual void addPoint( const DRW_Point& aData ) override {}
|
||||
virtual void addLine( const DRW_Line& aData) override;
|
||||
virtual void addRay( const DRW_Ray& aData ) override {}
|
||||
virtual void addXline( const DRW_Xline& aData ) override {}
|
||||
virtual void addCircle( const DRW_Circle& aData ) override;
|
||||
virtual void addArc( const DRW_Arc& aData ) override;
|
||||
virtual void addEllipse( const DRW_Ellipse& aData ) override {}
|
||||
virtual void addLWPolyline( const DRW_LWPolyline& aData ) override;
|
||||
virtual void addText( const DRW_Text& aData ) override;
|
||||
virtual void addPolyline( const DRW_Polyline& aData ) override;
|
||||
virtual void addSpline( const DRW_Spline* aData ) override {}
|
||||
virtual void addKnot( const DRW_Entity&) override {}
|
||||
virtual void addInsert( const DRW_Insert& aData ) override {}
|
||||
virtual void addTrace( const DRW_Trace& aData ) override {}
|
||||
virtual void addSolid( const DRW_Solid& aData ) override {}
|
||||
virtual void addMText( const DRW_MText& aData) override;
|
||||
virtual void addDimAlign( const DRW_DimAligned* aData ) override {}
|
||||
virtual void addDimLinear( const DRW_DimLinear* aData ) override {}
|
||||
virtual void addDimRadial( const DRW_DimRadial* aData ) override {}
|
||||
virtual void addDimDiametric( const DRW_DimDiametric* aData ) override {}
|
||||
virtual void addDimAngular( const DRW_DimAngular* aData ) override {}
|
||||
virtual void addDimAngular3P( const DRW_DimAngular3p* aData ) override {}
|
||||
virtual void addDimOrdinate( const DRW_DimOrdinate* aData ) override {}
|
||||
virtual void addLeader( const DRW_Leader* aData ) override {}
|
||||
virtual void addHatch( const DRW_Hatch* aData ) override {}
|
||||
virtual void addImage( const DRW_Image* aData ) override {}
|
||||
virtual void linkImage( const DRW_ImageDef* aData ) override {}
|
||||
// Methods from DL_CreationAdapter:
|
||||
// They are something like"call back" fonctions,
|
||||
// called when the corresponding object is read in dxf file
|
||||
|
||||
virtual void add3dFace( const DRW_3Dface& aData ) override {}
|
||||
virtual void addComment( const char*) override {}
|
||||
/**
|
||||
* Called for every string variable in the DXF file (e.g. "$ACADVER").
|
||||
*/
|
||||
virtual void setVariableString( const std::string& key, const std::string& value,
|
||||
int code ) override;
|
||||
|
||||
virtual void addVport( const DRW_Vport& aData ) override {}
|
||||
/**
|
||||
* Called for every int variable in the DXF file (e.g. "$ACADMAINTVER").
|
||||
*/
|
||||
virtual void setVariableInt( const std::string& key, int value, int code ) override;
|
||||
|
||||
virtual void addTextStyle( const DRW_Textstyle& aData ) override;
|
||||
/**
|
||||
* Called for every double variable in the DXF file (e.g. "$DIMEXO").
|
||||
*/
|
||||
virtual void setVariableDouble( const std::string& key, double value, int code ) override {}
|
||||
|
||||
virtual void addViewport( const DRW_Viewport& aData ) override {}
|
||||
virtual void addLayer( const DL_LayerData& aData ) override;
|
||||
virtual void addLine( const DL_LineData& aData) override;
|
||||
virtual void addCircle( const DL_CircleData& aData ) override;
|
||||
virtual void addArc( const DL_ArcData& aData ) override;
|
||||
//virtual void addLWPolyline( const DRW_LWPolyline& aData ) override;
|
||||
virtual void addText( const DL_TextData& aData ) override;
|
||||
virtual void addPolyline( const DL_PolylineData& aData ) override;
|
||||
|
||||
virtual void setBlock( const int aHandle ) override {}
|
||||
/** Called for every polyline vertex */
|
||||
virtual void addVertex( const DL_VertexData& aData ) override;
|
||||
virtual void addMText( const DL_MTextData& aData) override;
|
||||
virtual void addTextStyle( const DL_StyleData& aData ) override;
|
||||
|
||||
virtual void endEntity() override;
|
||||
|
||||
/** Called for every spline */
|
||||
virtual void addSpline( const DL_SplineData& aData ) override;
|
||||
|
||||
/** Called for every spline control point */
|
||||
virtual void addControlPoint( const DL_ControlPointData& aData ) override;
|
||||
|
||||
/** Called for every spline fit point */
|
||||
virtual void addFitPoint( const DL_FitPointData& aData ) override;
|
||||
|
||||
/** Called for every spline knot value */
|
||||
virtual void addKnot( const DL_KnotData& aData ) override;
|
||||
|
||||
// Not yet handled DXF entities:
|
||||
virtual void addDimAlign( const DL_DimensionData&,
|
||||
const DL_DimAlignedData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
||||
virtual void addDimLinear( const DL_DimensionData&,
|
||||
const DL_DimLinearData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
||||
virtual void addDimRadial( const DL_DimensionData&,
|
||||
const DL_DimRadialData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
||||
virtual void addDimDiametric( const DL_DimensionData&,
|
||||
const DL_DimDiametricData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
||||
virtual void addDimAngular( const DL_DimensionData&,
|
||||
const DL_DimAngularData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
||||
virtual void addDimAngular3P( const DL_DimensionData&,
|
||||
const DL_DimAngular3PData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
||||
virtual void addDimOrdinate( const DL_DimensionData&,
|
||||
const DL_DimOrdinateData& ) override { reportMsg( "DL_Dimension not managed" ); }
|
||||
virtual void addLeader( const DL_LeaderData& ) override { reportMsg( "DL_Leader not managed" ); }
|
||||
virtual void addLeaderVertex( const DL_LeaderVertexData& ) override { reportMsg( "DL_LeaderVertex not managed" ); }
|
||||
|
||||
virtual void addHatch( const DL_HatchData& ) override { reportMsg( "DL_Hatch not managed" ); }
|
||||
|
||||
virtual void addTrace( const DL_TraceData& ) override { reportMsg( "DL_Trace not managed" ); }
|
||||
virtual void add3dFace( const DL_3dFaceData& ) override { reportMsg( "DL_3dFace not managed" ); }
|
||||
virtual void addSolid( const DL_SolidData& ) override { reportMsg( "DL_Solid not managed" ); }
|
||||
|
||||
virtual void addImage( const DL_ImageData& ) override { reportMsg( "DL_ImageDa not managed" ); }
|
||||
virtual void linkImage( const DL_ImageDefData& ) override { reportMsg( "DL_ImageDef not managed" ); }
|
||||
virtual void addHatchLoop( const DL_HatchLoopData& ) override { reportMsg( "DL_HatchLoop not managed" ); }
|
||||
virtual void addHatchEdge( const DL_HatchEdgeData& ) override { reportMsg( "DL_HatchEdge not managed" ); }
|
||||
|
||||
/**
|
||||
* Converts a native unicode string into a DXF encoded string.
|
||||
|
@ -193,23 +304,8 @@ private:
|
|||
*/
|
||||
static wxString toNativeString( const wxString& aData );
|
||||
|
||||
// These functions are not used in Kicad.
|
||||
// But because they are virtual pure in DRW_Interface, they should be defined
|
||||
virtual void writeTextstyles() override {}
|
||||
virtual void writeVports() override {}
|
||||
virtual void writeHeader( DRW_Header& aData ) override {}
|
||||
virtual void writeEntities() override {}
|
||||
virtual void writeLTypes() override {}
|
||||
virtual void writeLayers() override {}
|
||||
virtual void writeBlockRecords() override {}
|
||||
virtual void writeBlocks() override {}
|
||||
virtual void writeDimstyles() override {}
|
||||
|
||||
void writeLine();
|
||||
void writeMtext();
|
||||
|
||||
virtual void addAppId( const DRW_AppId& data ) override {}
|
||||
virtual void writeAppId() override {}
|
||||
};
|
||||
|
||||
#endif // FILTERDXFRW_H
|
||||
#endif // DXF2BRD_ITEMS_H
|
||||
|
|
|
@ -984,8 +984,8 @@ void PCB_IO::format( EDGE_MODULE* aModuleDrawing, int aNestLevel ) const
|
|||
case S_CURVE: // Bezier curve
|
||||
m_out->Print( aNestLevel, "(fp_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))",
|
||||
FMT_IU( aModuleDrawing->GetStart0() ).c_str(),
|
||||
FMT_IU( aModuleDrawing->GetBezControl1() ).c_str(),
|
||||
FMT_IU( aModuleDrawing->GetBezControl2() ).c_str(),
|
||||
FMT_IU( aModuleDrawing->GetBezier0_C1() ).c_str(),
|
||||
FMT_IU( aModuleDrawing->GetBezier0_C2() ).c_str(),
|
||||
FMT_IU( aModuleDrawing->GetEnd0() ).c_str() );
|
||||
break;
|
||||
|
||||
|
|
|
@ -961,7 +961,7 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer )
|
|||
std::copy( points.begin(), points.end(), std::back_inserter( pointsList ) );
|
||||
pointsList.push_back( points[0] );
|
||||
|
||||
m_gal->SetLineWidth( aSegment->GetWidth() );
|
||||
m_gal->SetLineWidth( thickness );
|
||||
m_gal->SetIsFill( true );
|
||||
m_gal->SetIsStroke( true );
|
||||
m_gal->DrawPolygon( pointsList );
|
||||
|
@ -971,6 +971,9 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer )
|
|||
}
|
||||
|
||||
case S_CURVE:
|
||||
m_gal->SetIsFill( false );
|
||||
m_gal->SetIsStroke( true );
|
||||
m_gal->SetLineWidth( thickness );
|
||||
m_gal->DrawCurve( VECTOR2D( aSegment->GetStart() ),
|
||||
VECTOR2D( aSegment->GetBezControl1() ),
|
||||
VECTOR2D( aSegment->GetBezControl2() ),
|
||||
|
|
|
@ -2209,8 +2209,8 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE()
|
|||
Expecting( T_pts );
|
||||
|
||||
segment->SetStart0( parseXY() );
|
||||
segment->SetBezControl1( parseXY() );
|
||||
segment->SetBezControl2( parseXY() );
|
||||
segment->SetBezier0_C1( parseXY() );
|
||||
segment->SetBezier0_C2( parseXY() );
|
||||
segment->SetEnd0( parseXY() );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014-2017 CERN
|
||||
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -762,6 +762,15 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
|
|||
|
||||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::DXF );
|
||||
|
||||
// Now move the new items to the current cursor position:
|
||||
cursorPos = m_controls->GetCursorPosition();
|
||||
delta = cursorPos - firstItem->GetPosition();
|
||||
|
||||
for( auto item : preview )
|
||||
static_cast<BOARD_ITEM*>( item )->Move( wxPoint( delta.x, delta.y ) );
|
||||
|
||||
m_view->Update( &preview );
|
||||
|
||||
Activate();
|
||||
|
||||
// Main loop: keep receiving events
|
||||
|
|
|
@ -26,10 +26,10 @@ add_library( idf3 STATIC ${IDF3_FILES} )
|
|||
|
||||
add_executable( idfcyl idf_cylinder.cpp )
|
||||
add_executable( idfrect idf_rect.cpp )
|
||||
add_executable( dxf2idf dxf2idfmain.cpp dxf2idf.cpp )
|
||||
#add_executable( dxf2idf dxf2idfmain.cpp dxf2idf.cpp )
|
||||
add_executable( idf2vrml idf2vrml.cpp )
|
||||
|
||||
target_link_libraries( dxf2idf lib_dxf idf3 ${wxWidgets_LIBRARIES} )
|
||||
#target_link_libraries( dxf2idf lib_dxf idf3 ${wxWidgets_LIBRARIES} )
|
||||
|
||||
target_link_libraries( idf2vrml idf3 common ${OPENGL_LIBRARIES} ${wxWidgets_LIBRARIES} )
|
||||
|
||||
|
@ -39,7 +39,8 @@ if( APPLE )
|
|||
RUNTIME_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_BIN_DIR}
|
||||
)
|
||||
else()
|
||||
install( TARGETS idfcyl idfrect dxf2idf idf2vrml
|
||||
install( TARGETS idfcyl idfrect idf2vrml
|
||||
#dxf2idf
|
||||
DESTINATION ${KICAD_BIN}
|
||||
COMPONENT binary )
|
||||
endif()
|
||||
|
|
Loading…
Reference in New Issue