Attempt to support Bezier curves in STEP export. First code.
The bezier curves are in this code replaced by a segm between the 2 ends curves
This commit is contained in:
parent
07f5428951
commit
12b106aba4
|
@ -47,7 +47,8 @@ enum CURVE_TYPE
|
|||
CURVE_NONE = 0, // invalid curve
|
||||
CURVE_LINE,
|
||||
CURVE_ARC,
|
||||
CURVE_CIRCLE
|
||||
CURVE_CIRCLE,
|
||||
CURVE_BEZIER
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -50,14 +50,14 @@ KICADCURVE::~KICADCURVE()
|
|||
return;
|
||||
}
|
||||
|
||||
#include <sexpr/sexpr_parser.h>
|
||||
|
||||
bool KICADCURVE::Read( SEXPR::SEXPR* aEntry, CURVE_TYPE aCurveType )
|
||||
{
|
||||
if( CURVE_LINE != aCurveType && CURVE_ARC != aCurveType && CURVE_CIRCLE != aCurveType )
|
||||
if( CURVE_LINE != aCurveType && CURVE_ARC != aCurveType
|
||||
&& CURVE_CIRCLE != aCurveType && CURVE_BEZIER != aCurveType )
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << "* Unsupported curve type: " << aCurveType;
|
||||
wxLogMessage( "%s\n", ostr.str().c_str() );
|
||||
wxLogMessage( "* Unsupported curve type: %d\n", aCurveType );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -67,11 +67,10 @@ bool KICADCURVE::Read( SEXPR::SEXPR* aEntry, CURVE_TYPE aCurveType )
|
|||
|
||||
if( ( CURVE_CIRCLE == aCurveType && nchild < 5 )
|
||||
|| ( CURVE_ARC == aCurveType && nchild < 6 )
|
||||
|| ( CURVE_LINE == aCurveType && nchild < 5 ) )
|
||||
|| ( CURVE_LINE == aCurveType && nchild < 5 )
|
||||
|| ( CURVE_BEZIER == aCurveType && nchild < 5 ) )
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << "* bad curve data; not enough parameters";
|
||||
wxLogMessage( "%s\n", ostr.str().c_str() );
|
||||
wxLogMessage( "* bad curve data; not enough parameters\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -87,7 +86,45 @@ bool KICADCURVE::Read( SEXPR::SEXPR* aEntry, CURVE_TYPE aCurveType )
|
|||
|
||||
text = child->GetChild( 0 )->GetSymbol();
|
||||
|
||||
if( text == "start" || text == "center" )
|
||||
if( text == "pts" )
|
||||
{
|
||||
// Parse and extract the list of xy coordinates
|
||||
SEXPR::PARSER parser;
|
||||
std::unique_ptr<SEXPR::SEXPR> prms = parser.Parse( child->AsString() );
|
||||
|
||||
// We need 4 XY parametres (and "pts" that is the firast parameter)
|
||||
if( prms->GetNumberOfChildren() != 5 )
|
||||
return false;
|
||||
|
||||
// Extract xy coordintes from pts list
|
||||
SEXPR::SEXPR_VECTOR const* list = prms->GetChildren();
|
||||
int ii = 0;
|
||||
|
||||
// The first parameter is "pts", so skip it.
|
||||
for( std::vector<SEXPR::SEXPR*>::const_iterator it = list->begin()+1;
|
||||
it != list->end(); ++it, ++ii )
|
||||
{
|
||||
SEXPR::SEXPR* sub_child = (*it);
|
||||
text = sub_child->GetChild( 0 )->GetSymbol();
|
||||
|
||||
if( text == "xy" )
|
||||
{
|
||||
DOUBLET coord;
|
||||
|
||||
if( !Get2DCoordinate( sub_child, coord ) )
|
||||
return false;
|
||||
|
||||
switch( ii )
|
||||
{
|
||||
case 0: m_start = coord; break;
|
||||
case 1: m_bezierctrl1 = coord; break;
|
||||
case 2: m_bezierctrl2 = coord; break;
|
||||
case 3: m_end = coord; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( text == "start" || text == "center" )
|
||||
{
|
||||
if( !Get2DCoordinate( child, m_start ) )
|
||||
return false;
|
||||
|
@ -103,9 +140,7 @@ bool KICADCURVE::Read( SEXPR::SEXPR* aEntry, CURVE_TYPE aCurveType )
|
|||
|| ( !child->GetChild( 1 )->IsDouble()
|
||||
&& !child->GetChild( 1 )->IsInteger() ) )
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << "* bad angle data";
|
||||
wxLogMessage( "%s\n", ostr.str().c_str() );
|
||||
wxLogMessage( "* bad angle data\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -158,6 +193,11 @@ std::string KICADCURVE::Describe() const
|
|||
desc << "circle center: " << m_start << " radius: " << m_radius;
|
||||
break;
|
||||
|
||||
case CURVE_BEZIER:
|
||||
desc << "bezier start: " << m_start << " end: " << m_end
|
||||
<< " ctrl1: " << m_bezierctrl1 << " ctrl2: " << m_bezierctrl2 ;
|
||||
break;
|
||||
|
||||
default:
|
||||
desc << "<invalid curve type>";
|
||||
break;
|
||||
|
|
|
@ -50,13 +50,15 @@ public:
|
|||
///> Returns human-readable description of the curve.
|
||||
std::string Describe() const;
|
||||
|
||||
CURVE_TYPE m_form; // form of curve: line, arc, circle
|
||||
LAYERS m_layer; // layer of the glyph
|
||||
DOUBLET m_start; // start point of line or center for arc and circle
|
||||
DOUBLET m_end; // end point of line, first point on arc or circle
|
||||
DOUBLET m_ep; // actual endpoint, to be computed in the case of arcs
|
||||
double m_radius;// radius; to be computed in the case of arcs and circles
|
||||
double m_angle; // subtended angle of arc
|
||||
CURVE_TYPE m_form; // form of curve: line, arc, circle
|
||||
LAYERS m_layer; // layer of the glyph
|
||||
DOUBLET m_start; // start point of line or center for arc and circle
|
||||
DOUBLET m_end; // end point of line, first point on arc or circle
|
||||
DOUBLET m_ep; // actual endpoint, to be computed in the case of arcs
|
||||
DOUBLET m_bezierctrl1; // for bezier curve only first control point
|
||||
DOUBLET m_bezierctrl2; // for bezier curve only second control point
|
||||
double m_radius; // radius; to be computed in the case of arcs and circles
|
||||
double m_angle; // subtended angle of arc
|
||||
double m_startangle;
|
||||
double m_endangle;
|
||||
};
|
||||
|
|
|
@ -230,6 +230,8 @@ bool KICADPCB::parsePCB( SEXPR::SEXPR* data )
|
|||
result = result && parseRect( child );
|
||||
else if( symname == "gr_circle" )
|
||||
result = result && parseCurve( child, CURVE_CIRCLE );
|
||||
else if( symname == "gr_curve" )
|
||||
result = result && parseCurve( child, CURVE_BEZIER );
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -136,12 +136,19 @@ static void reverseCurve( KICADCURVE& aCurve )
|
|||
if( CURVE_NONE == aCurve.m_form || CURVE_CIRCLE == aCurve.m_form )
|
||||
return;
|
||||
|
||||
if( CURVE_LINE == aCurve.m_form )
|
||||
if( CURVE_LINE == aCurve.m_form )
|
||||
{
|
||||
std::swap( aCurve.m_start, aCurve.m_end );
|
||||
return;
|
||||
}
|
||||
|
||||
if( CURVE_BEZIER == aCurve.m_form )
|
||||
{
|
||||
std::swap( aCurve.m_start, aCurve.m_end );
|
||||
std::swap( aCurve.m_bezierctrl1, aCurve.m_bezierctrl2 );
|
||||
return;
|
||||
}
|
||||
|
||||
std::swap( aCurve.m_end, aCurve.m_ep );
|
||||
std::swap( aCurve.m_endangle, aCurve.m_startangle );
|
||||
aCurve.m_angle = -aCurve.m_angle;
|
||||
|
@ -259,7 +266,7 @@ bool PCBMODEL::AddOutlineSegment( KICADCURVE* aCurve )
|
|||
if( NULL == aCurve || LAYER_EDGE != aCurve->m_layer || CURVE_NONE == aCurve->m_form )
|
||||
return false;
|
||||
|
||||
if( CURVE_LINE == aCurve->m_form )
|
||||
if( CURVE_LINE == aCurve->m_form || CURVE_BEZIER == aCurve->m_form )
|
||||
{
|
||||
// reject zero - length lines
|
||||
double dx = aCurve->m_end.x - aCurve->m_start.x;
|
||||
|
@ -419,12 +426,27 @@ bool PCBMODEL::AddOutlineSegment( KICADCURVE* aCurve )
|
|||
|
||||
break;
|
||||
|
||||
case CURVE_BEZIER:
|
||||
if( aCurve->m_start.x < m_minx )
|
||||
{
|
||||
m_minx = aCurve->m_start.x;
|
||||
m_mincurve = --(m_curves.end());
|
||||
}
|
||||
|
||||
if( aCurve->m_end.x < m_minx )
|
||||
{
|
||||
m_minx = aCurve->m_end.x;
|
||||
m_mincurve = --(m_curves.end());
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// unexpected curve type
|
||||
do
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( " * AddOutlineSegment() unsupported curve type: %s\n",
|
||||
msg.Printf( " * AddOutlineSegment() unsupported curve type: %d\n",
|
||||
aCurve->m_form );
|
||||
ReportMessage( msg );
|
||||
} while( 0 );
|
||||
|
@ -1528,6 +1550,7 @@ bool OUTLINE::MakeShape( TopoDS_Shape& aShape, double aThickness )
|
|||
return true;
|
||||
}
|
||||
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
|
||||
bool OUTLINE::addEdge( BRepBuilderAPI_MakeWire* aWire, KICADCURVE& aCurve, DOUBLET& aLastPoint )
|
||||
{
|
||||
|
@ -1562,6 +1585,28 @@ bool OUTLINE::addEdge( BRepBuilderAPI_MakeWire* aWire, KICADCURVE& aCurve, DOUBL
|
|||
gp_Dir( 0.0, 0.0, 1.0 ) ), aCurve.m_radius ) );
|
||||
break;
|
||||
|
||||
case CURVE_BEZIER:
|
||||
{
|
||||
#if 0 // TODO: this code is not working. so fix it or replace the curve by a set of segments
|
||||
TColgp_Array1OfPnt poles(0, 3);
|
||||
gp_Pnt pt = gp_Pnt( aCurve.m_start.x, aCurve.m_start.y, 0.0 );
|
||||
poles(0) = pt;
|
||||
pt = gp_Pnt( aCurve.m_bezierctrl1.x, aCurve.m_bezierctrl1.y, 0.0 );
|
||||
poles(1) = pt;
|
||||
pt = gp_Pnt( aCurve.m_bezierctrl2.x, aCurve.m_bezierctrl2.y, 0.0 );
|
||||
poles(2) = pt;
|
||||
pt = gp_Pnt( endPoint.x, endPoint.y, 0.0 );
|
||||
poles(3) = pt;
|
||||
|
||||
Geom_BezierCurve* bezier_curve = new Geom_BezierCurve( poles );
|
||||
edge = BRepBuilderAPI_MakeEdge( bezier_curve );
|
||||
#else // Generate a segment between ends
|
||||
edge = BRepBuilderAPI_MakeEdge( gp_Pnt( aLastPoint.x, aLastPoint.y, 0.0 ),
|
||||
gp_Pnt( endPoint.x, endPoint.y, 0.0 ) );
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ReportMessage( wxString::Format( "unsupported curve type: %d\n", aCurve.m_form ) );
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue