X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSKETCHER%2FSketcher_Profile.cxx;h=516f34abe7b8f96ade0cf39ea5b31dd8da556494;hb=8370b4a1c488f6ef18d8944869d6a8cd3a2d18d2;hp=ad436a67dd2d3347c1a6b7d1e01797c48156e2ef;hpb=a8a220072be66fa1a086a9292345b06f3b7e6f3c;p=modules%2Fgeom.git diff --git a/src/SKETCHER/Sketcher_Profile.cxx b/src/SKETCHER/Sketcher_Profile.cxx index ad436a67d..516f34abe 100644 --- a/src/SKETCHER/Sketcher_Profile.cxx +++ b/src/SKETCHER/Sketcher_Profile.cxx @@ -1,38 +1,33 @@ -// GEOM SKETCHER : basic sketcher -// -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library 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 -// Lesser General Public License for more details. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// This library 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 +// Lesser General Public License for more details. // +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + +// GEOM SKETCHER : basic sketcher // File : Sketcher_Profile.cxx // Author : Damien COQUERET // Module : GEOM -// $Header: - -#include -#include +#include "Sketcher_Profile.hxx" #include -#include -#include #include #include #include @@ -41,367 +36,1974 @@ #include #include #include -#include #include #include #include -#include -#include - #include "utilities.h" -//======================================================================= -// profile -// command to build a profile -//======================================================================= -Sketcher_Profile::Sketcher_Profile() +/*! + \class Sketcher_Profile::Functor + \brief Generic functor class to process sketcher command + \internal +*/ + +class Sketcher_Profile::Functor +{ +public: + Functor(); + virtual ~Functor(); + + virtual void init( const TCollection_AsciiString& ); + + virtual void initCommand() = 0; + virtual void addPoint( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) = 0; + virtual void addAngle( const TCollection_AsciiString& angle ) = 0; + virtual void addSegmentParalX( const TCollection_AsciiString& x ) = 0; + virtual void addSegmentParalXToZero() = 0; + virtual void addSegmentParalY( const TCollection_AsciiString& y ) = 0; + virtual void addSegmentParalYToZero() = 0; + virtual void addSegmentAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) = 0; + virtual void addSegmentRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) = 0; + virtual void addSegmentLength( const TCollection_AsciiString& length ) = 0; + virtual void addSegmentX( const TCollection_AsciiString& x, + int CurrentIndex ) = 0; + virtual void addSegmentY( const TCollection_AsciiString& y, + int CurrentIndex ) = 0; + virtual void addSegmentAngleLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& length, + int& CurrentIndex ) = 0; + virtual void addSegmentAngleX( const TCollection_AsciiString& angle, + const TCollection_AsciiString& x, + int& CurrentIndex ) = 0; + virtual void addSegmentAngleY( const TCollection_AsciiString& angle, + const TCollection_AsciiString& y, + int& CurrentIndex ) = 0; + virtual void addSegmentDirectionLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& length, + int& CurrentIndex ) = 0; + virtual void addSegmentDirectionX( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& x, + int& CurrentIndex ) = 0; + virtual void addSegmentDirectionY( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& y, + int& CurrentIndex ) = 0; + virtual void addArcAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) = 0; + virtual void addArcRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) = 0; + virtual void addArcRadiusAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ) = 0; + virtual void addArcRadiusRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ) = 0; + virtual void addArcCenterAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ) = 0; + virtual void addArcCenterRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ) = 0; + virtual void addArcRadiusLength( const TCollection_AsciiString& radius, + const TCollection_AsciiString& length ) = 0; + virtual void addArcAngleRadiusLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ) = 0; + virtual void addArcDirectionRadiusLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ) = 0; + virtual void closeWire() = 0; + virtual void closeWireAndBuildFace() = 0; + + virtual void nextCommand( int& CurrentIndex ) = 0; + virtual void makeResult() = 0; + + void setNumberOfCommand( int n ); + double error(); + bool isOk(); + +protected: + int myNumberOfCommand; + double myError; + bool myOk; +}; + +/*! + \class Sketcher_Profile::ShapeFunctor + \brief Functor that creates a shape from sketcher command + \internal +*/ + +class Sketcher_Profile::ShapeFunctor : public Functor +{ +public: + ShapeFunctor(); + + virtual void initCommand(); + virtual void addPoint( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ); + virtual void addAngle( const TCollection_AsciiString& angle ); + virtual void addSegmentParalX( const TCollection_AsciiString& x ); + virtual void addSegmentParalXToZero(); + virtual void addSegmentParalY( const TCollection_AsciiString& y ); + virtual void addSegmentParalYToZero(); + virtual void setAngle( const TCollection_AsciiString& angle ); + virtual void setDirection( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ); + virtual void addSegmentAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ); + virtual void addSegmentRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ); + virtual void addSegmentLength( const TCollection_AsciiString& length ); + virtual void addSegmentX( const TCollection_AsciiString& x, + int CurrentIndex ); + virtual void addSegmentY( const TCollection_AsciiString& y, + int CurrentIndex ); + virtual void addSegmentAngleLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& length, + int& CurrentIndex ); + virtual void addSegmentAngleX( const TCollection_AsciiString& angle, + const TCollection_AsciiString& x, + int& CurrentIndex ); + virtual void addSegmentAngleY( const TCollection_AsciiString& angle, + const TCollection_AsciiString& y, + int& CurrentIndex ); + virtual void addSegmentDirectionLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& length, + int& CurrentIndex ); + virtual void addSegmentDirectionX( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& x, + int& CurrentIndex ); + virtual void addSegmentDirectionY( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& y, + int& CurrentIndex ); + virtual void addArcAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ); + virtual void addArcRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ); + virtual void addArcRadiusAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ); + virtual void addArcRadiusRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ); + virtual void addArcCenterAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ); + virtual void addArcCenterRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ); + virtual void addArcRadiusLength( const TCollection_AsciiString& radius, + const TCollection_AsciiString& length ); + virtual void addArcAngleRadiusLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ); + virtual void addArcDirectionRadiusLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ); + virtual void closeWire(); + virtual void closeWireAndBuildFace(); + + virtual void nextCommand( int& CurrentIndex ); + virtual void makeResult(); + + TopoDS_Shape getShape(); + +private: + void setMove( int& CurrentIndex ); + +private: + Standard_Real myX0, myY0, myX, myY, myDx, myDy; + Standard_Boolean myFirst, myStayFirst, myFace, myClose; + Standard_Real myLength, myRadius, myAngle; + + enum {line, circle, point, none} myMove; + + TopLoc_Location TheLocation; // ????????? + gp_Pln myPlane; + TopoDS_Vertex myVertex; + BRepBuilderAPI_MakeWire myMakeWire; + + TopoDS_Shape myShape; +}; + +/*! + \class Sketcher_Profile::ShapeFunctor + \brief Functor that generates a Python script from sketcher command + \internal +*/ + +class Sketcher_Profile::DumpFunctor : public Functor +{ +public: + DumpFunctor(); + + virtual void init( const TCollection_AsciiString& ); + + virtual void initCommand(); + virtual void addPoint( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ); + virtual void addAngle( const TCollection_AsciiString& angle ); + virtual void addSegmentParalX( const TCollection_AsciiString& x ); + virtual void addSegmentParalXToZero(); + virtual void addSegmentParalY( const TCollection_AsciiString& y ); + virtual void addSegmentParalYToZero(); + virtual void addSegmentAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ); + virtual void addSegmentRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ); + virtual void addSegmentLength( const TCollection_AsciiString& length ); + virtual void addSegmentX( const TCollection_AsciiString& x, + int CurrentIndex ); + virtual void addSegmentY( const TCollection_AsciiString& y, + int CurrentIndex ); + virtual void addSegmentAngleLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& length, + int& CurrentIndex ); + virtual void addSegmentAngleX( const TCollection_AsciiString& angle, + const TCollection_AsciiString& x, + int& CurrentIndex ); + virtual void addSegmentAngleY( const TCollection_AsciiString& angle, + const TCollection_AsciiString& y, + int& CurrentIndex ); + virtual void addSegmentDirectionLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& length, + int& CurrentIndex ); + virtual void addSegmentDirectionX( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& x, + int& CurrentIndex ); + virtual void addSegmentDirectionY( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& y, + int& CurrentIndex ); + virtual void addArcAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ); + virtual void addArcRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ); + virtual void addArcRadiusAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ); + virtual void addArcRadiusRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ); + virtual void addArcCenterAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ); + virtual void addArcCenterRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ); + virtual void addArcRadiusLength( const TCollection_AsciiString& radius, + const TCollection_AsciiString& length ); + virtual void addArcAngleRadiusLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ); + virtual void addArcDirectionRadiusLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ); + virtual void closeWire(); + virtual void closeWireAndBuildFace(); + + virtual void nextCommand( int& CurrentIndex ); + virtual void makeResult(); + + TCollection_AsciiString getDescription(); + +private: + TCollection_AsciiString myDescr; + TCollection_AsciiString mySketcherEntry; + TCollection_AsciiString myWPEntry; + TCollection_AsciiString myTail; + Standard_Boolean myFace; +}; + +//=========================================================================== +// Sketcher_Profile::Functor +//=========================================================================== + +/*! + \brief Constructor + \internal +*/ +Sketcher_Profile::Functor::Functor() : myError( 0 ), myNumberOfCommand( 0 ), myOk( true ) { } +/*! + \brief Destructor + \internal +*/ +Sketcher_Profile::Functor::~Functor() +{ +} -//======================================================================= -// profile -// command to build a profile -//======================================================================= -Sketcher_Profile::Sketcher_Profile(const char* aCmd) -{ - enum {line, circle, point, none} move; - - Standard_Integer i = 1; - Standard_Real x0, y0, x, y, dx, dy; - x0 = y0 = x = y = dy = 0; - dx = 1; - - Standard_Boolean first, stayfirst, face, close; - first = Standard_True; - stayfirst = face = close = Standard_False; - - TopoDS_Shape S; - TopoDS_Vertex MP; - BRepBuilderAPI_MakeWire MW; - gp_Ax3 DummyHP(gp::XOY()); - gp_Pln P(DummyHP); - TopLoc_Location TheLocation; - Handle(Geom_Surface) Surface; - - myOK = Standard_False; - - //TCollection_AsciiString aCommand(CORBA::string_dup(aCmd)); - TCollection_AsciiString aCommand ((char*)aCmd); - TCollection_AsciiString aToken = aCommand.Token(":", 1); - int n = 0; - // porting to WNT - TColStd_Array1OfAsciiString aTab (0, aCommand.Length() - 1); - if ( aCommand.Length() ) - { - while(aToken.Length() != 0) { - if(aCommand.Token(":", n + 1).Length() > 0) - aTab(n) = aCommand.Token(":", n + 1); - aToken = aCommand.Token(":", ++n); +/*! + \brief Initialize functor from the script + \param command sketcher command being parsed + \internal +*/ +void Sketcher_Profile::Functor::init( const TCollection_AsciiString& /*command*/ ) +{ +} + +/*! + \brief Set total number of sketcher operators + \param n total number of sketcher operators + \internal +*/ +void Sketcher_Profile::Functor::setNumberOfCommand( int n ) +{ + myNumberOfCommand = n; +} + +/*! + \brief Get error (numerical value that describes, e.g. a deviation of point from the specified arc) + \return numerical error + \internal +*/ +double Sketcher_Profile::Functor::error() +{ + return myError; +} + +/*! + \brief Get result of parsing + \return \c true if parsing is successful or \c false otherwise + \internal +*/ +bool Sketcher_Profile::Functor::isOk() +{ + return myOk; +} + +//=========================================================================== +// Sketcher_Profile::ShapeFunctor +//=========================================================================== + +/*! + \brief Constructor + \internal +*/ +Sketcher_Profile::ShapeFunctor::ShapeFunctor() : Functor() +{ + myX0 = myY0 = 0; + myX = myY = 0; + myDy = 0; + myDx = 1; + + myFirst = Standard_True; + myStayFirst = myFace = myClose = Standard_False; + + myLength = myRadius = myAngle = 0; + + myMove = point; + + myPlane = gp_Pln( gp_Ax3( gp::XOY() ) ); +} + +/*! + \brief Prepare functor for processing of new sketcher operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::initCommand() +{ + myLength = myRadius = myAngle = 0; + myMove = point; +} + +/*! + \brief Add point with absolute coordinates (\a x, \a y) + \param x X coordinate + \param y Y coordinate + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addPoint( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) +{ + if ( !myFirst ) { + MESSAGE("profile : The addPoint instruction must precede all moves"); + return; + } + myX0 = myX = x.RealValue(); + myY0 = myY = y.RealValue(); + myStayFirst = Standard_True; +} + +/*! + \brief Add angle + \param angle angle + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addAngle( const TCollection_AsciiString& angle ) +{ + myAngle = angle.RealValue() * M_PI / 180.; + myDx = Cos( myAngle ); + myDy = Sin( myAngle ); +} + +/*! + \brief Add new segment of \a x length along X axis + \param x length of segment + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentParalX( const TCollection_AsciiString& x ) +{ + myLength = x.RealValue(); + myDx = 1; + myDy = 0; + myMove = line; +} + +/*! + \brief Add new segment along X axis with X coordinate of end set to 0 + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentParalXToZero() +{ + myLength -= myX; + myDx = 1; + myDy = 0; + myMove = line; +} + +/*! + \brief Add new segment of \a y length along Y axis + \param y length of segment + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentParalY( const TCollection_AsciiString& y ) +{ + myLength = y.RealValue(); + myDx = 0; + myDy = 1; + myMove = line; +} + +/*! + \brief Add new segment along Y axis with Y coordinate of end set to 0 + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentParalYToZero() +{ + myLength -= myY; + myDx = 0; + myDy = 1; + myMove = line; +} + +/*! + \brief Set current angle + \param angle current working angle + \internal +*/ +void Sketcher_Profile::ShapeFunctor::setAngle( const TCollection_AsciiString& angle ) +{ + myAngle = angle.RealValue(); + Standard_Real alpha = myAngle * M_PI / 180.; + Standard_Real c = Cos( alpha ); + Standard_Real s = Sin( alpha ); + Standard_Real t = c * myDx - s * myDy; + myDy = s * myDx + c * myDy; + myDx = t; +} + +/*! + \brief Set current direction + \param dx X component of direction vector + \param dy Y component of direction vector + \internal +*/ +void Sketcher_Profile::ShapeFunctor::setDirection( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) +{ + Standard_Real vx = dx.RealValue(); + Standard_Real vy = dy.RealValue(); + myLength = Sqrt( vx * vx + vy * vy ); + if ( myLength > Precision::Confusion() ) { + myDx = vx / myLength; + myDy = vy / myLength; + } + else + myMove = none; +} + +/*! + \brief Add segment by absolute coordinates + \param x X coordinate of segment end + \param y Y coordinate of segment end + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) +{ + Standard_Real vx = x.RealValue() - myX; + Standard_Real vy = y.RealValue() - myY; + myLength = Sqrt( vx * vx + vy * vy ); + if ( myLength > Precision::Confusion() ) { + myMove = line; + myDx = vx / myLength; + myDy = vy / myLength; + } + else + myMove = none; +} + +/*! + \brief Add segment by relativ coordinates + \param dx dX value specifing segment end + \param dy dY value specifing segment end + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) +{ + Standard_Real vx = dx.RealValue(); + Standard_Real vy = dy.RealValue(); + myLength = Sqrt( vx * vx + vy * vy ); + if ( myLength > Precision::Confusion() ) { + myMove = line; + myDx = vx / myLength; + myDy = vy / myLength; + } + else + myMove = none; +} + +/*! + \brief Add segment with specified length along current direction + \param length segment length + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentLength( const TCollection_AsciiString& length ) +{ + myLength = length.RealValue(); + if ( Abs( myLength ) > Precision::Confusion() ) + myMove = line; + else + myMove = none; +} + +/*! + \brief Add segment along X axis to reach specified X coordinate + \param x X coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentX( const TCollection_AsciiString& x, + int CurrentIndex ) +{ + myMove = none; + myLength = x.RealValue(); + if ( Abs( myDx ) < Precision::Confusion() ) { + MESSAGE("profile : cannot intersect, arg "< Precision::Confusion() ) + myMove = line; +} + +/*! + \brief Add segment along Y axis to reach specified Y coordinate + \param y Y coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentY( const TCollection_AsciiString& y, + int CurrentIndex ) +{ + myMove = none; + myLength = y.RealValue(); + if ( Abs( myDy ) < Precision::Confusion() ) { + MESSAGE("profile : cannot intersect, arg "< Precision::Confusion() ) + myMove = line; +} + +/*! + \brief Add segment by specified angle and length + \param angle angle that specifies segment direction + \param length segment length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentAngleLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& length, + int& CurrentIndex ) +{ + setAngle( angle ); + setMove( CurrentIndex ); + addSegmentLength( length ); +} + +/*! + \brief Add segment that crosses Y axis by specified angle and X coordinate + \param angle angle that specifies segment direction + \param x X coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentAngleX( const TCollection_AsciiString& angle, + const TCollection_AsciiString& x, + int& CurrentIndex ) +{ + setAngle( angle ); + setMove( CurrentIndex ); + addSegmentX( x, CurrentIndex ); +} + +/*! + \brief Add segment that crosses X axis by specified angle and Y coordinate + \param angle angle that specifies segment direction + \param y Y coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentAngleY( const TCollection_AsciiString& angle, + const TCollection_AsciiString& y, + int& CurrentIndex ) +{ + setAngle( angle ); + setMove( CurrentIndex ); + addSegmentY( y, CurrentIndex ); +} + +/*! + \brief Add segment by specified direction and length + \param dx X component of direction vector + \param dx Y component of direction vector + \param length segment length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentDirectionLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& length, + int& CurrentIndex ) +{ + setDirection( dx, dy ); + setMove( CurrentIndex ); + addSegmentLength( length ); +} + +/*! + \brief Add segment by specified direction and X coordinate + \param dx X component of direction vector + \param dx Y component of direction vector + \param x X coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentDirectionX( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& x, + int& CurrentIndex ) +{ + setDirection( dx, dy ); + setMove( CurrentIndex ); + addSegmentX( x, CurrentIndex ); +} + +/*! + \brief Add segment by specified direction and Y coordinate + \param dx X component of direction vector + \param dx Y component of direction vector + \param y Y coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentDirectionY( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& y, + int& CurrentIndex ) +{ + setDirection( dx, dy ); + setMove( CurrentIndex ); + addSegmentY( y, CurrentIndex ); +} + +/*! + \brief Add arc along current direction vector by specified absolute coordinates + \param x X coordinate of arc end + \param x Y coordinate of arc end + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) +{ + Standard_Real vx = x.RealValue() - myX; + Standard_Real vy = y.RealValue() - myY; + Standard_Real det = myDx * vy - myDy * vx; + Standard_Real c = Sqrt( ( myDx * myDx + myDy * myDy ) * ( vx * vx + vy * vy ) ); + if ( Abs( det ) > Precision::Confusion() && Abs( c ) > Precision::Confusion() ) { + // Cosine of alpha = arc of angle / 2 , alpha in [0,Pi] + c = ( myDx * vx + myDy * vy ) / c; + // radius = distance between start and end point / 2 * sin(alpha) + // radius is > 0 or < 0 + myRadius = ( vx * vx + vy * vy )* Sqrt( myDx * myDx + myDy * myDy ) / ( 2.0 * det ); + if ( Abs( myRadius ) > Precision::Confusion() ) { + myAngle = 2.0 * acos( c ); // angle in [0,2Pi] + myMove = circle; } - n = n - 1; - } - if ( aTab.Length() && aTab(0).Length() ) - while(i < n) { - Standard_Real length = 0, radius = 0, angle = 0; - move = point; - - int n1 = 0; - TColStd_Array1OfAsciiString a (0, aTab(0).Length()); - aToken = aTab(i).Token(" ", 1); - while (aToken.Length() != 0) { - if (aTab(i).Token(" ", n1 + 1).Length() > 0) - a(n1) = aTab(i).Token(" ", n1 + 1); - aToken = aTab(i).Token(" ", ++n1); - } - n1 = n1 - 1; - - switch(a(0).Value(1)) - { - case 'F': - { - if (n1 != 3) goto badargs; - if (!first) { - MESSAGE("profile : The F instruction must precede all moves"); - return; - } - x0 = x = a(1).RealValue(); - y0 = y = a(2).RealValue(); - stayfirst = Standard_True; - break; - } - case 'O': - { - if (n1 != 4) goto badargs; - P.SetLocation(gp_Pnt(a(1).RealValue(), a(2).RealValue(), a(3).RealValue())); - stayfirst = Standard_True; - break; - } - case 'P': - { - if (n1 != 7) goto badargs; - gp_Vec vn(a(1).RealValue(), a(2).RealValue(), a(3).RealValue()); - gp_Vec vx(a(4).RealValue(), a(5).RealValue(), a(6).RealValue()); - if (vn.Magnitude() <= Precision::Confusion() || vx.Magnitude() <= Precision::Confusion()) { - MESSAGE("profile : null direction"); - return; - } - gp_Ax2 ax(P.Location(), vn, vx); - P.SetPosition(ax); - stayfirst = Standard_True; - break; - } - case 'X': - { - if (n1 != 2) goto badargs; - length = a(1).RealValue(); - if (a(0) == "XX") - length -= x; - dx = 1; dy = 0; - move = line; - break; - } - case 'Y': - { - if (n1 != 2) goto badargs; - length = a(1).RealValue(); - if (a(0) == "YY") - length -= y; - dx = 0; dy = 1; - move = line; - break; - } - case 'L': - { - if (n1 != 2) goto badargs; - length = a(1).RealValue(); - if (Abs(length) > Precision::Confusion()) - move = line; - else - move = none; - break; - } - case 'T': - { - if (n1 != 3) goto badargs; - Standard_Real vx = a(1).RealValue(); - Standard_Real vy = a(2).RealValue(); - if (a(0) == "TT") { - vx -= x; - vy -= y; - } - length = Sqrt(vx * vx + vy * vy); - if (length > Precision::Confusion()) { - move = line; - dx = vx / length; - dy = vy / length; - } - else - move = none; - break; - } - case 'R': - { - if (n1 != 2) goto badargs; - angle = a(1).RealValue() * PI180; - if (a(0) == "RR") { - dx = Cos(angle); - dy = Sin(angle); - } - else { - Standard_Real c = Cos(angle); - Standard_Real s = Sin(angle); - Standard_Real t = c * dx - s * dy; - dy = s * dx + c * dy; - dx = t; - } - break; - } - case 'D': - { - if (n1 != 3) goto badargs; - Standard_Real vx = a(1).RealValue(); - Standard_Real vy = a(2).RealValue(); - length = Sqrt(vx * vx + vy * vy); - if (length > Precision::Confusion()) { - dx = vx / length; - dy = vy / length; - } - else - move = none; - break; - } - case 'C': - { - if (n1 != 3) goto badargs; - radius = a(1).RealValue(); - if (Abs(radius) > Precision::Confusion()) { - angle = a(2).RealValue() * PI180; - move = circle; - } - else - move = none; - break; - } - case 'I': - { - if (n1 != 2) goto badargs; - length = a(1).RealValue(); - if (a(0) == "IX") { - if (Abs(dx) < Precision::Confusion()) { - MESSAGE("profile : cannot intersect, arg "< Precision::Confusion()) - move = line; - else - move = none; - break; - } - case 'W': - { - if (a(0) == "WW") - close = Standard_True; - else if(a(0) == "WF") { - close = Standard_True; - face = Standard_True; - } - i = n - 1; - break; - } - default: - { - MESSAGE("profile : unknown code " << a(i)); - return; - } + else + myMove = none; + } + else + myMove = none; +} + +/*! + \brief Add arc along current direction vector by specified relative coordinates + \param dx dX value specifing arc end + \param dy dY value specifing arc end + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) +{ + Standard_Real vx = dx.RealValue(); + Standard_Real vy = dy.RealValue(); + Standard_Real det = myDx * vy - myDy * vx; + Standard_Real c = Sqrt( ( myDx * myDx + myDy * myDy ) * ( vx * vx + vy * vy ) ); + if ( Abs( det ) > Precision::Confusion() && Abs( c ) > Precision::Confusion() ) { + // Cosine of alpha = arc of angle / 2 , alpha in [0,Pi] + c = ( myDx * vx + myDy * vy ) / c; + // radius = distance between start and end point / 2 * sin(alpha) + // radius is > 0 or < 0 + myRadius = ( vx * vx + vy * vy )* Sqrt( myDx * myDx + myDy * myDy ) / ( 2.0 * det ); + if ( Abs( myRadius ) > Precision::Confusion() ) { + myAngle = 2.0 * acos(c); // angle in [0,2Pi] + myMove = circle; } + else + myMove = none; + } + else + myMove = none; +} + +/*! + \brief Add arc with given radius by specified absolute coordinates + \param x X coordinate of arc end + \param x Y coordinate of arc end + \param radius arc radius + \param flag reverse direction flag + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcRadiusAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ) +{ + Standard_Real vx = x.RealValue() - myX; + Standard_Real vy = y.RealValue() - myY; + myRadius = radius.RealValue(); + int reversed = flag.IntegerValue(); + Standard_Real length = Sqrt( vx * vx + vy * vy ); + if ( Abs( myRadius ) > Precision::Confusion() && + ( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) >= 0.0 ) && ( length > Precision::Confusion() ) ) { + // Cosine of alpha = arc angle / 2 , alpha in [0,Pi/2] + Standard_Real c = 0.5 * Sqrt( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) ); + myAngle = 2.0 * acos( c ); // angle in [0,Pi] + if ( reversed == 2 ) + myAngle = myAngle - 2 * M_PI; + myDx = 0.5 * ( vy * 1.0 / myRadius + + vx * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) ); + myDy = -0.5 * ( vx * 1.0 / myRadius + - vy * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) ); + myMove = circle; + } + else { + myMove = none; + } +} + +/*! + \brief Add arc with given radius by specified relative coordinates + \param dx dX value specifing arc end + \param dy dY value specifing arc end + \param radius arc radius + \param flag reverse direction flag + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcRadiusRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ) +{ + Standard_Real vx = dx.RealValue(); + Standard_Real vy = dy.RealValue(); + myRadius = radius.RealValue(); + int reversed = flag.IntegerValue(); + Standard_Real length = Sqrt( vx * vx + vy * vy ); + if ( Abs( myRadius ) > Precision::Confusion() && + ( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) >= 0.0 ) && ( length > Precision::Confusion() ) ) { + // Cosine of alpha = arc angle / 2 , alpha in [0,Pi/2] + Standard_Real c = 0.5 * Sqrt( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) ); + myAngle = 2.0 * acos( c ); // angle in [0,Pi] + if ( reversed == 2 ) + myAngle = myAngle - 2 * M_PI; + myDx = 0.5 * ( vy * 1.0 / myRadius + + vx * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) ); + myDy = -0.5 * ( vx * 1.0 / myRadius + - vy * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) ); + myMove = circle; + } + else { + myMove = none; + } +} + +/*! + \brief Add arc with given center by specified absolute coordinates + \param x X coordinate of arc end + \param x Y coordinate of arc end + \param xc X coordinate of arc center + \param yc Y coordinate of arc center + \param flag1 reverse direction flag + \param flag2 tolerance + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcCenterAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ) +{ + Standard_Real vx = x.RealValue() - myX; + Standard_Real vy = y.RealValue() - myY; + Standard_Real vxc = xc.RealValue() - myX; + Standard_Real vyc = yc.RealValue() - myY; + int reversed = flag1.IntegerValue(); + int control_Tolerance = flag2.IntegerValue(); -again : - switch (move) + myRadius = Sqrt( vxc * vxc + vyc * vyc ); + Standard_Real det = vx * vyc - vy * vxc; + Standard_Real length = Sqrt( vx * vx + vy * vy ); + Standard_Real length2 = Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) ); + Standard_Real length3 = Sqrt( vxc * vxc + vyc * vyc ); + Standard_Real error = Abs( length2 - myRadius ); + myError = error; + if ( error > Precision::Confusion() ) { + MESSAGE("Warning : The specified end point is not on the Arc, distance = "< Precision::Confusion() && control_Tolerance == 1 ) // Don't create the arc if the end point + myMove = none; // is too far from it + else if ( ( length > Precision::Confusion() ) && + ( length2 > Precision::Confusion() ) && + ( length3 > Precision::Confusion() ) ) { + Standard_Real c = ( myRadius * myRadius - ( vx * vxc + vy * vyc ) ) + / ( myRadius * Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) ) ) ; // Cosine of arc angle + myAngle = acos(c); // angle in [0,Pi] + if ( reversed == 2 ) + myAngle = myAngle - 2 * M_PI; + if ( det < 0 ) + myAngle = -myAngle; + myDx = vyc / myRadius; + myDy = -vxc / myRadius; + myMove = circle; + } + else { + myMove = none; + } +} + +/*! + \brief Add arc with given center by specified relative coordinates + \param dx dX value specifing arc end + \param dy dY value specifing arc end + \param xc X coordinate of arc center + \param yc Y coordinate of arc center + \param flag1 reverse direction flag + \param flag2 tolerance + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcCenterRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ) +{ + Standard_Real vx = dx.RealValue(); + Standard_Real vy = dy.RealValue(); + Standard_Real vxc = xc.RealValue(); + Standard_Real vyc = yc.RealValue(); + int reversed = flag1.IntegerValue(); + int control_Tolerance = flag2.IntegerValue(); + myRadius = Sqrt( vxc * vxc + vyc * vyc ); + Standard_Real det = vx * vyc - vy * vxc; + Standard_Real length = Sqrt( vx * vx + vy * vy ); + Standard_Real length2 = Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) ); + Standard_Real length3 = Sqrt( vxc * vxc + vyc * vyc ); + Standard_Real error = Abs( length2 - myRadius ); + myError = error; + if ( error > Precision::Confusion() ) { + MESSAGE("Warning : The specified end point is not on the Arc, distance = "< Precision::Confusion() && control_Tolerance == 1 ) // Don't create the arc if the end point + myMove = none; // is too far from it + else if ( ( length > Precision::Confusion() ) && + ( length2 > Precision::Confusion() ) && + ( length3 > Precision::Confusion() ) ) { + Standard_Real c = ( myRadius * myRadius - ( vx * vxc + vy * vyc ) ) + / ( myRadius * Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) ) ) ; // Cosine of arc angle + myAngle = acos( c ); // angle in [0,Pi] + if ( reversed == 2 ) + myAngle = myAngle - 2 * M_PI; + if ( det < 0 ) + myAngle = -myAngle; + myDx = vyc / myRadius; + myDy = -vxc / myRadius; + myMove = circle; + } + else { + myMove = none; + } +} + +/*! + \brief Add arc with given radius by specified length + \param radius arc radius + \param length arc length + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcRadiusLength( const TCollection_AsciiString& radius, + const TCollection_AsciiString& length ) +{ + myRadius = radius.RealValue(); + if ( Abs( myRadius ) > Precision::Confusion() ) { + myAngle = length.RealValue() * M_PI / 180.; + myMove = circle; + } + else + myMove = none; +} + +/*! + \brief Add arc with given radius by specified angle and length + \param angle angle between arc start tangent and current direction + \param radius arc radius + \param length arc length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcAngleRadiusLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ) +{ + setAngle( angle ); + setMove( CurrentIndex ); + addArcRadiusLength( radius, length ); +} + +/*! + \brief Add arc with given radius by specified direction and length + \param dx X component of direction vector + \param dx Y component of direction vector + \param radius arc radius + \param length arc length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcDirectionRadiusLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ) +{ + setDirection( dx, dy ); + setMove( CurrentIndex ); + addArcRadiusLength( radius, length ); +} + +/*! + \brief Close wire + \internal +*/ +void Sketcher_Profile::ShapeFunctor::closeWire() +{ + myClose = Standard_True; +} + +/*! + \brief Close wire and build face + \internal +*/ +void Sketcher_Profile::ShapeFunctor::closeWireAndBuildFace() +{ + myClose = Standard_True; + myFace = Standard_True; +} + +/*! + \brief Set internal parameters according to the current operator type + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::setMove( int& CurrentIndex ) +{ + switch ( myMove ) + { + case line : { - case line : - { - if (length < 0) { - length = -length; - dx = -dx; - dy = -dy; - } - Handle(Geom2d_Line) l = new Geom2d_Line(gp_Pnt2d(x,y),gp_Dir2d(dx,dy)); - BRepBuilderAPI_MakeEdge ME (GeomAPI::To3d(l,P),0,length); - if (!ME.IsDone()) - return; - MW.Add(ME); - x += length*dx; - y += length*dy; - break; - } - case circle : - { - Standard_Boolean sense = Standard_True; - if (radius < 0) { - radius = -radius; - sense = !sense; - dx = -dx; - dy = -dy; - } - gp_Ax2d ax(gp_Pnt2d(x-radius*dy,y+radius*dx),gp_Dir2d(dy,-dx)); - if (angle < 0) { - angle = -angle; - sense = !sense; - } - Handle(Geom2d_Circle) c = new Geom2d_Circle(ax,radius,sense); - BRepBuilderAPI_MakeEdge ME (GeomAPI::To3d(c,P),0,angle); - if (!ME.IsDone()) - return; - MW.Add(ME); - gp_Pnt2d p; - gp_Vec2d v; - c->D1(angle,p,v); - x = p.X(); - y = p.Y(); - dx = v.X() / radius; - dy = v.Y() / radius; - break; + if ( myLength < 0 ) { + myLength = -myLength; + myDx = -myDx; + myDy = -myDy; } - case point: - { - MP = BRepBuilderAPI_MakeVertex(gp_Pnt(x, y, 0.0)); - break; + Handle(Geom2d_Line) l = new Geom2d_Line( gp_Pnt2d( myX, myY ),gp_Dir2d( myDx, myDy ) ); + BRepBuilderAPI_MakeEdge ME( GeomAPI::To3d( l, myPlane ), 0, myLength ); + if ( !ME.IsDone() ) + return; + myMakeWire.Add( ME ); + myX += myLength * myDx; + myY += myLength * myDy; + break; + } + case circle : + { + Standard_Boolean sense = Standard_True; + if ( myRadius < 0 ) { + myRadius = -myRadius; + sense = !sense; + myDx = -myDx; + myDy = -myDy; } - case none: - { - i = n - 1; - break; + gp_Ax2d ax( gp_Pnt2d( myX - myRadius * myDy, myY + myRadius * myDx ), gp_Dir2d( myDy, -myDx ) ); + if ( myAngle < 0 ) { + myAngle = -myAngle; + sense = !sense; } + Handle(Geom2d_Circle) c = new Geom2d_Circle( ax, myRadius, sense ); + BRepBuilderAPI_MakeEdge ME( GeomAPI::To3d( c, myPlane ), 0, myAngle ); + if ( !ME.IsDone() ) + return; + myMakeWire.Add( ME ); + gp_Pnt2d p; + gp_Vec2d v; + c->D1( myAngle, p, v ); + myX = p.X(); + myY = p.Y(); + myDx = v.X() / myRadius; + myDy = v.Y() / myRadius; + break; + } + case point: + { + myVertex = BRepBuilderAPI_MakeVertex( gp_Pnt( myX, myY, 0.0 ) ); + break; } + case none: + { + CurrentIndex = myNumberOfCommand - 1; + break; + } + } +} - // update first - first = stayfirst; - stayfirst = Standard_False; +/*! + \brief Complete parsing of current operator + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::nextCommand( int& CurrentIndex ) +{ + setMove( CurrentIndex ); + CurrentIndex ++; + // update first + myFirst = myStayFirst; + myStayFirst = Standard_False; - if(!(dx == 0 && dy == 0)) - myLastDir.SetCoord(dx, dy, 0.0); - else - return; - myLastPoint.SetX(x); - myLastPoint.SetY(y); - - // next segment.... - i++; - if ((i == n) && close) { - // the closing segment - dx = x0 - x; - dy = y0 - y; - length = Sqrt(dx * dx + dy * dy); - move = line; - if (length > Precision::Confusion()) { - dx = dx / length; - dy = dy / length; - goto again; - } + // next segment.... + if ( ( CurrentIndex == myNumberOfCommand ) && myClose ) { + // the closing segment + myDx = myX0 - myX; + myDy = myY0 - myY; + myLength = Sqrt( myDx * myDx + myDy * myDy ); + myMove = line; + if ( myLength > Precision::Confusion() ) { + myDx = myDx / myLength; + myDy = myDy / myLength; + setMove( CurrentIndex ); } } +} +/*! + \brief Finish parsing and create result + \internal +*/ +void Sketcher_Profile::ShapeFunctor::makeResult() +{ // get the result, face or wire - if (move == none) { + if ( myMove == none ) { + myOk = false; return; - } else if (move == point) { - S = MP; - } else if (face) { - if (!MW.IsDone()) { + } + else if ( myMove == point ) { + myShape = myVertex; + } + else if ( myFace ) { + if ( !myMakeWire.IsDone() ) { + myOk = false; return; } - BRepBuilderAPI_MakeFace MF (P, MW.Wire()); - if (!MF.IsDone()) { + BRepBuilderAPI_MakeFace MF ( myPlane, myMakeWire.Wire() ); + if ( !MF.IsDone() ) { + myOk = false; return; } - S = MF; - } else { - if (!MW.IsDone()) { + myShape = MF; + } + else { + if ( !myMakeWire.IsDone() ) { + myOk = false; return; } - S = MW; + myShape = myMakeWire.Shape(); + } + + if ( !TheLocation.IsIdentity() ) + myShape.Move( TheLocation ); +} + +/*! + \brief Get resulting shape + \return shape resulting from parsing of sketcher command + \internal +*/ +TopoDS_Shape Sketcher_Profile::ShapeFunctor::getShape() +{ + return myShape; +} + +//=========================================================================== +// Sketcher_Profile::DumpFunctor +//=========================================================================== + +/*! + \brief Constructor + \internal +*/ +Sketcher_Profile::DumpFunctor::DumpFunctor() +{ + myFace = Standard_False; +} + +/*! + \brief Initialize functor from the script + \param command sketcher command being parsed + \internal +*/ +void Sketcher_Profile::DumpFunctor::init( const TCollection_AsciiString& command ) +{ + // parse only first line of the script + TCollection_AsciiString aSubStr = command.Token( "\n\t" ); + if ( aSubStr.Length() < command.Length() ) + myTail = command.SubString( aSubStr.Length()+1, command.Length() ); + // get sketch entry + mySketcherEntry = aSubStr.Token( " =" ); + // Using this Working Plane for Sketcher + myWPEntry = myWPEntry + "[" + aSubStr.Token( "[]", 2 ) + "]"; + // Using this Working Plane for SketcherOnPlane + if ( aSubStr.Search( "MakeSketcherOnPlane" ) != -1 ) { + myWPEntry = aSubStr.Token( ",)", 2 ); + myWPEntry.RemoveAll( ' ' ); + } + myDescr += "sk = geompy.Sketcher2D()"; +} + +/*! + \brief Prepare functor for processing of new sketcher operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::initCommand() +{ + myDescr += "\n\t"; +} + +/*! + \brief Add point with absolute coordinates (\a x, \a y) + \param x X coordinate + \param y Y coordinate + \internal +*/ +void Sketcher_Profile::DumpFunctor::addPoint( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) +{ + myDescr += "sk.addPoint("; + myDescr += x + ", " + y + ")"; +} + +/*! + \brief Add angle + \param angle angle + \internal +*/ +void Sketcher_Profile::DumpFunctor::addAngle( const TCollection_AsciiString& angle ) +{ + myDescr += "sk.addAngle("; + myDescr += angle + ")"; +} + +/*! + \brief Add new segment of \a x length along X axis + \param x length of segment + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentParalX( const TCollection_AsciiString& x ) +{ + myDescr += "sk.addSegmentParalX("; + myDescr += x + ")"; +} + +/*! + \brief Add new segment along X axis with X coordinate of end set to 0 + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentParalXToZero() +{ + myDescr += "sk.addSegmentParalXToZero()"; +} + +/*! + \brief Add new segment of \a y length along Y axis + \param y length of segment + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentParalY( const TCollection_AsciiString& y ) +{ + myDescr += "sk.addSegmentParalY("; + myDescr += y + ")"; +} + +/*! + \brief Add new segment along Y axis with Y coordinate of end set to 0 + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentParalYToZero() +{ + myDescr += "sk.addSegmentParalYToZero()"; +} + +/*! + \brief Add segment by absolute coordinates + \param x X coordinate of segment end + \param y Y coordinate of segment end + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) +{ + myDescr += "sk.addSegmentAbsolute("; + myDescr += x + ", " + y + ")"; +} + +/*! + \brief Add segment by relativ coordinates + \param dx dX value specifing segment end + \param dy dY value specifing segment end + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) +{ + myDescr += "sk.addSegmentRelative("; + myDescr += dx + ", " + dy + ")"; +} + +/*! + \brief Add segment with specified length along current direction + \param length segment length + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentLength( const TCollection_AsciiString& length ) +{ + myDescr += "sk.addSegmentLength("; + myDescr += length + ")"; +} + +/*! + \brief Add segment along X axis to reach specified X coordinate + \param x X coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentX( const TCollection_AsciiString& x, + int CurrentIndex ) +{ + myDescr += "sk.addSegmentX("; + myDescr += x + ")"; +} + +/*! + \brief Add segment along Y axis to reach specified Y coordinate + \param y Y coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentY( const TCollection_AsciiString& y, + int CurrentIndex ) +{ + myDescr += "sk.addSegmentY("; + myDescr += y + ")"; +} + +/*! + \brief Add segment by specified angle and length + \param angle angle that specifies segment direction + \param length segment length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentAngleLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& length, + int& CurrentIndex ) +{ + double aAngle = angle.RealValue(); + if ( aAngle == 90 ) { + myDescr += "sk.addSegmentPerpLength("; + myDescr += length + ")"; + } + else { + myDescr += "sk.addSegmentAngleLength("; + myDescr += angle + ", " + length + ")"; + } +} + +/*! + \brief Add segment that crosses Y axis by specified angle and X coordinate + \param angle angle that specifies segment direction + \param x X coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentAngleX( const TCollection_AsciiString& angle, + const TCollection_AsciiString& x, + int& CurrentIndex ) +{ + double aAngle = angle.RealValue(); + if ( aAngle == 90 ) { + myDescr += "sk.addSegmentPerpX("; + myDescr += x + ")"; + } + else { + myDescr += "sk.addSegmentAngleX("; + myDescr += angle + ", " + x + ")"; + } +} + +/*! + \brief Add segment that crosses X axis by specified angle and Y coordinate + \param angle angle that specifies segment direction + \param y Y coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentAngleY( const TCollection_AsciiString& angle, + const TCollection_AsciiString& y, + int& CurrentIndex ) +{ + double aAngle = angle.RealValue(); + if ( aAngle == 90 ) { + myDescr += "sk.addSegmentPerpY("; + myDescr += y + ")"; + } + else { + myDescr += "sk.addSegmentAngleY("; + myDescr += angle + ", " + y + ")"; + } +} + +/*! + \brief Add segment by specified direction and length + \param dx X component of direction vector + \param dx Y component of direction vector + \param length segment length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentDirectionLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& length, + int& CurrentIndex ) +{ + myDescr += "sk.addSegmentDirectionLength("; + myDescr += dx + ", " + dy + ", " + length + ")"; +} + +/*! + \brief Add segment by specified direction and X coordinate + \param dx X component of direction vector + \param dx Y component of direction vector + \param x X coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentDirectionX( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& x, + int& CurrentIndex ) +{ + myDescr += "sk.addSegmentDirectionX("; + myDescr += dx + ", " + dy + ", " + x + ")"; +} + +/*! + \brief Add segment by specified direction and Y coordinate + \param dx X component of direction vector + \param dx Y component of direction vector + \param y Y coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentDirectionY( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& y, + int& CurrentIndex ) +{ + myDescr += "sk.addSegmentDirectionY("; + myDescr += dx + ", " + dy + ", " + y + ")"; +} + +/*! + \brief Add arc along current direction vector by specified absolute coordinates + \param x X coordinate of arc end + \param x Y coordinate of arc end + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) +{ + myDescr += "sk.addArcAbsolute("; + myDescr += x + ", " + y + ")"; +} + +/*! + \brief Add arc along current direction vector by specified relative coordinates + \param dx dX value specifing arc end + \param dy dY value specifing arc end + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) +{ + myDescr += "sk.addArcRelative("; + myDescr += dx + ", " + dy + ")"; +} + +/*! + \brief Add arc with given radius by specified absolute coordinates + \param x X coordinate of arc end + \param x Y coordinate of arc end + \param radius arc radius + \param flag reverse direction flag + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcRadiusAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ) +{ + myDescr += "sk.addArcRadiusAbsolute("; + myDescr += x + ", " + y + ", " + radius + ", " + flag + ")"; +} + +/*! + \brief Add arc with given radius by specified relative coordinates + \param dx dX value specifing arc end + \param dy dY value specifing arc end + \param radius arc radius + \param flag reverse direction flag + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcRadiusRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ) +{ + myDescr += "sk.addArcRadiusRelative("; + myDescr += dx + ", " + dy + ", " + radius + ", " + flag + ")"; +} + +/*! + \brief Add arc with given center by specified absolute coordinates + \param x X coordinate of arc end + \param x Y coordinate of arc end + \param xc X coordinate of arc center + \param yc Y coordinate of arc center + \param flag1 reverse direction flag + \param flag2 tolerance + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcCenterAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ) +{ + myDescr += "sk.addArcCenterAbsolute("; + myDescr += xc + ", " + yc + ", " + x + ", " + y + ", " + flag1 + ", " + flag2 + ")"; +} + +/*! + \brief Add arc with given center by specified relative coordinates + \param dx dX value specifing arc end + \param dy dY value specifing arc end + \param xc X coordinate of arc center + \param yc Y coordinate of arc center + \param flag1 reverse direction flag + \param flag2 tolerance + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcCenterRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ) +{ + myDescr += "sk.addArcCenterRelative("; + myDescr += xc + ", " + yc + ", " + dx + ", " + dy + ", " + flag1 + ", " + flag2 + ")"; +} + +/*! + \brief Add arc with given radius by specified length + \param radius arc radius + \param length arc length + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcRadiusLength( const TCollection_AsciiString& radius, + const TCollection_AsciiString& length ) +{ + myDescr += "sk.addArcRadiusLength("; + myDescr += radius + ", " + length + ")"; +} + +/*! + \brief Add arc with given radius by specified angle and length + \param angle angle between arc start tangent and current direction + \param radius arc radius + \param length arc length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcAngleRadiusLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ) +{ + double aAngle = angle.RealValue(); + if ( aAngle == 90 ) { + myDescr += "sk.addArcPerpRadiusLength("; + myDescr += radius + ", " + length + ")"; + } + else { + myDescr += "sk.addArcAngleRadiusLength("; + myDescr += angle + ", " + radius + ", " + length + ")"; } +} + +/*! + \brief Add arc with given radius by specified direction and length + \param dx X component of direction vector + \param dx Y component of direction vector + \param radius arc radius + \param length arc length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcDirectionRadiusLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ) +{ + myDescr += "sk.addArcDirectionRadiusLength("; + myDescr += dx + ", " + dy + ", " + radius + ", " + length + ")"; +} - if(!TheLocation.IsIdentity()) - S.Move(TheLocation); +/*! + \brief Close wire + \internal +*/ +void Sketcher_Profile::DumpFunctor::closeWire() +{ + myDescr += "sk.close()"; +} - myShape = S; - myOK = true; - return; +/*! + \brief Close wire and build face + \internal +*/ +void Sketcher_Profile::DumpFunctor::closeWireAndBuildFace() +{ + myDescr += "sk.close()"; + myFace = Standard_True; +} + +/*! + \brief Complete parsing of current operator + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::nextCommand( int& CurrentIndex ) +{ + CurrentIndex++; +} - badargs : - MESSAGE("profile : bad number of arguments"); +/*! + \brief Finish parsing and create result + \internal +*/ +void Sketcher_Profile::DumpFunctor::makeResult() +{ + if ( mySketcherEntry == "" ) { + myOk = false; return; + } + myDescr += "\n\t"; + if ( myFace ) + myDescr += mySketcherEntry + " = sk.face(" + myWPEntry + ")"; + else + myDescr += mySketcherEntry + " = sk.wire(" + myWPEntry + ")"; + myDescr += myTail; +} + +/*! + \brief Get python script + \return string representing Python dump resulting from parsing of sketcher command + \internal +*/ +TCollection_AsciiString Sketcher_Profile::DumpFunctor::getDescription() +{ + return myDescr; +} + +//======================================================================= +// Sketcher_Profile +//======================================================================= + + +/*! + \brief Default constructor +*/ +Sketcher_Profile::Sketcher_Profile() +{ +} + +/*! + \brief Constructor + \param command sketcher script to parse +*/ +Sketcher_Profile::Sketcher_Profile( const char* command ) +{ + SetCommand( command ); +} + +/*! + \brief Set sketcher script to parse + \param command sketcher script to parse +*/ +void Sketcher_Profile::SetCommand( const char* command ) +{ + myCommand = command; +} + +/*! + \brief Parse sketcher command and get resulting shape + \param isDone if specified (non-zero), result of parsing is returned via this parameter + \param error if specified (non-zero), numerical error is returned via this parameter + \return shape resulting from parsing of sketcher command +*/ +TopoDS_Shape Sketcher_Profile::GetShape( bool* isDone, double* error ) +{ + ShapeFunctor functor; + parse( myCommand, &functor ); + TopoDS_Shape s = functor.getShape(); + + if ( isDone ) *isDone = functor.isOk(); + if ( error ) *error = functor.error(); + + return s; +} + +/*! + \brief Parse sketcher command and get resulting Python script + \param isDone if specified (non-zero), result of parsing is returned via this parameter + \return string representing Python dump resulting from parsing of sketcher command +*/ +TCollection_AsciiString Sketcher_Profile::GetDump( bool* isDone ) +{ + DumpFunctor functor; + parse( myCommand, &functor ); + TCollection_AsciiString d = functor.getDescription(); + + if ( isDone ) *isDone = functor.isOk(); + + return d; +} + +/*! + \brief Parse sketcher script using specified functor + \param cmd sketcher script to parse + \internal +*/ +void Sketcher_Profile::parse( const TCollection_AsciiString& cmd, Functor* functor ) +{ + int CurrentIndex = 1; + int NumberOfArg = 0; + int NumberOfCommand = 0; + + functor->init( myCommand ); + TCollection_AsciiString command = extractCommand( myCommand ); + + TCollection_AsciiString aToken = command.Token( ":", 1 ); + TColStd_Array1OfAsciiString aTab( 0, command.Length() - 1 ); + if ( command.Length() ) { + while ( aToken.Length() != 0 ) { + TCollection_AsciiString aNewToken = command.Token( ":", NumberOfCommand + 1 ); + if ( aNewToken.Length() > 0 ) + aTab( NumberOfCommand ) = aNewToken; + aToken = command.Token( ":", ++NumberOfCommand ); + } + --NumberOfCommand; + } + + functor->setNumberOfCommand( NumberOfCommand ); + if ( aTab.Length() && aTab( 0 ).Length() ) { + while ( CurrentIndex < NumberOfCommand ) { + functor->initCommand(); + TColStd_Array1OfAsciiString a( 0, aTab( 0 ).Length() ); + findNextCommand( aTab, a, CurrentIndex, NumberOfArg ); + if ( a( 0 ) == "F" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addPoint( a.Value( 1 ), a.Value( 2 ) ); + } + else if ( a( 0 ) == "X" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentParalX( a.Value( 1 ) ); + } + else if ( a( 0 ) == "XX" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentParalXToZero(); + } + else if ( a( 0 ) == "Y" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentParalY( a.Value( 1 ) ); + } + else if ( a( 0 ) == "YY" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentParalYToZero(); + } + else if ( a( 0 ) == "RR" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addAngle( a.Value( 1 ) ); + } + else if ( a( 0 ) == "TT" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addSegmentAbsolute( a.Value( 1 ), a.Value( 2 ) ); + } + else if ( a( 0 ) == "T" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addSegmentRelative( a.Value( 1 ), a.Value( 2 ) ); + } + else if ( a( 0 ) == "L" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentLength( a.Value( 1 ) ); + } + else if ( a( 0 ) == "IX" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentX( a.Value( 1 ), CurrentIndex ); + } + else if ( a( 0 ) == "IY" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentY( a.Value( 1 ), CurrentIndex ); + } + else if ( a( 0 ) == "R" ) { + if ( NumberOfArg != 2) badArgs(); + CurrentIndex++; + TColStd_Array1OfAsciiString aNew( 0, aTab( 0 ).Length() ); + findNextCommand( aTab, aNew, CurrentIndex, NumberOfArg ); + if ( aNew( 0 ) == "L" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentAngleLength( a.Value( 1 ), aNew.Value( 1 ), CurrentIndex ); + } + else if ( aNew( 0 ) == "IX" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentAngleX( a.Value( 1 ), aNew.Value( 1 ), CurrentIndex ); + } + else if ( aNew( 0 ) == "IY" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentAngleY( a.Value( 1 ), aNew.Value( 1 ), CurrentIndex ); + } + else if ( aNew( 0 ) == "C" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addArcAngleRadiusLength( a.Value( 1 ), aNew.Value( 1 ), aNew.Value( 2 ), CurrentIndex ); + } + } + else if ( a( 0 ) == "D" ) { + if ( NumberOfArg != 3 ) badArgs(); + CurrentIndex++; + TColStd_Array1OfAsciiString aNew ( 0, aTab( 0 ).Length() ); + findNextCommand( aTab, aNew, CurrentIndex, NumberOfArg ); + if ( aNew( 0 ) == "L" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentDirectionLength( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), CurrentIndex ); + } + else if ( aNew( 0 ) == "IX" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentDirectionX( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), CurrentIndex ); + } + else if ( aNew( 0 ) == "IY" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentDirectionY( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), CurrentIndex ); + } + else if ( aNew( 0 ) == "C" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addArcDirectionRadiusLength( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), aNew.Value( 2 ), CurrentIndex ); + } + } + else if ( a( 0 ) == "AA" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addArcAbsolute( a.Value( 1 ), a.Value( 2 ) ); + } + else if ( a( 0 ) == "A" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addArcRelative( a.Value( 1 ), a.Value( 2 ) ); + } + else if ( a( 0 ) == "UU" ) { + if ( NumberOfArg != 5 ) badArgs(); + functor->addArcRadiusAbsolute( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ) ); + } + else if ( a( 0 ) == "U" ) { + if ( NumberOfArg != 5 ) badArgs(); + functor->addArcRadiusRelative( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ) ); + } + else if ( a( 0 ) == "EE" ) { + if ( NumberOfArg != 7 ) badArgs(); + functor->addArcCenterAbsolute( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ), a.Value( 5 ), a.Value( 6 ) ); + } + else if ( a( 0 ) == "E" ) { + if ( NumberOfArg != 7 ) badArgs(); + functor->addArcCenterRelative( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ), a.Value( 5 ), a.Value( 6 ) ); + } + else if ( a( 0 ) == "C" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addArcRadiusLength( a.Value( 1 ), a.Value( 2 ) ); + } + else if ( a( 0 ) == "WW" ) { + functor->closeWire(); + CurrentIndex = NumberOfCommand - 1; + } + else if ( a( 0 ) == "WF" ) { + functor->closeWireAndBuildFace(); + CurrentIndex = NumberOfCommand - 1; + } + else { + MESSAGE("profile : unknown code " << a(CurrentIndex)); + return; + } + functor->nextCommand( CurrentIndex ); + } + } + + functor->makeResult(); +} + +/*! + \brief Extract sketcher command from script + \param cmd sketcher script to parse + \return sketcher command + \internal +*/ +TCollection_AsciiString Sketcher_Profile::extractCommand( const TCollection_AsciiString& cmd ) +{ + // parse only first line of the script + TCollection_AsciiString aSubStr = cmd.Token( "\n\t", 1 ); + return aSubStr.Token( "\"", aSubStr.Search( "=" ) != -1 ? 2 : 1 ); +} + +/*! + \brief Print an error message if the number of arguments of sketcher operator is wrong + \internal +*/ +void Sketcher_Profile::badArgs() +{ + MESSAGE("profile : bad number of arguments"); +} + +/*! + \brief Find the next sketcher operator in the input string + \param aTab all sketcher command data + \param a sketcher operator with parameters is returned via this parameter + \param CurrentIndex current operator index + \param NumberOfArg number of operator arguments is returned via this parameter + \internal +*/ +void Sketcher_Profile::findNextCommand( const TColStd_Array1OfAsciiString& aTab, + TColStd_Array1OfAsciiString& a, int CurrentIndex, + int& NumberOfArg) +{ + int n1 = 0; + TCollection_AsciiString aToken = aTab(CurrentIndex).Token(" ", 1); + while (aToken.Length() != 0) { + if (aTab(CurrentIndex).Token(" ", n1 + 1).Length() > 0) + a(n1) = aTab(CurrentIndex).Token(" ", n1 + 1); + aToken = aTab(CurrentIndex).Token(" ", ++n1); + } + n1 = n1 - 1; + NumberOfArg = n1; } +