1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // GEOM SKETCHER : basic sketcher
24 // File : Sketcher_Profile.cxx
25 // Author : Damien COQUERET
28 #include "Sketcher_Profile.hxx"
30 #include <TopoDS_Vertex.hxx>
31 #include <BRepBuilderAPI_MakeVertex.hxx>
32 #include <BRepBuilderAPI_MakeEdge.hxx>
33 #include <BRepBuilderAPI_MakeWire.hxx>
34 #include <BRepBuilderAPI_MakeFace.hxx>
36 #include <GeomAPI.hxx>
37 #include <Geom2d_Line.hxx>
38 #include <Geom2d_Circle.hxx>
40 #include <Precision.hxx>
44 #include "utilities.h"
47 \class Sketcher_Profile::Functor
48 \brief Generic functor class to process sketcher command
52 class Sketcher_Profile::Functor
58 virtual void init( const TCollection_AsciiString& );
60 virtual void initCommand() = 0;
61 virtual void addPoint( const TCollection_AsciiString& x,
62 const TCollection_AsciiString& y ) = 0;
63 virtual void addAngle( const TCollection_AsciiString& angle ) = 0;
64 virtual void addSegmentParalX( const TCollection_AsciiString& x ) = 0;
65 virtual void addSegmentParalXToZero() = 0;
66 virtual void addSegmentParalY( const TCollection_AsciiString& y ) = 0;
67 virtual void addSegmentParalYToZero() = 0;
68 virtual void addSegmentAbsolute( const TCollection_AsciiString& x,
69 const TCollection_AsciiString& y ) = 0;
70 virtual void addSegmentRelative( const TCollection_AsciiString& dx,
71 const TCollection_AsciiString& dy ) = 0;
72 virtual void addSegmentLength( const TCollection_AsciiString& length ) = 0;
73 virtual void addSegmentX( const TCollection_AsciiString& x,
74 int CurrentIndex ) = 0;
75 virtual void addSegmentY( const TCollection_AsciiString& y,
76 int CurrentIndex ) = 0;
77 virtual void addSegmentAngleLength( const TCollection_AsciiString& angle,
78 const TCollection_AsciiString& length,
79 int& CurrentIndex ) = 0;
80 virtual void addSegmentAngleX( const TCollection_AsciiString& angle,
81 const TCollection_AsciiString& x,
82 int& CurrentIndex ) = 0;
83 virtual void addSegmentAngleY( const TCollection_AsciiString& angle,
84 const TCollection_AsciiString& y,
85 int& CurrentIndex ) = 0;
86 virtual void addSegmentDirectionLength( const TCollection_AsciiString& dx,
87 const TCollection_AsciiString& dy,
88 const TCollection_AsciiString& length,
89 int& CurrentIndex ) = 0;
90 virtual void addSegmentDirectionX( const TCollection_AsciiString& dx,
91 const TCollection_AsciiString& dy,
92 const TCollection_AsciiString& x,
93 int& CurrentIndex ) = 0;
94 virtual void addSegmentDirectionY( const TCollection_AsciiString& dx,
95 const TCollection_AsciiString& dy,
96 const TCollection_AsciiString& y,
97 int& CurrentIndex ) = 0;
98 virtual void addArcAbsolute( const TCollection_AsciiString& x,
99 const TCollection_AsciiString& y ) = 0;
100 virtual void addArcRelative( const TCollection_AsciiString& dx,
101 const TCollection_AsciiString& dy ) = 0;
102 virtual void addArcRadiusAbsolute( const TCollection_AsciiString& x,
103 const TCollection_AsciiString& y,
104 const TCollection_AsciiString& radius,
105 const TCollection_AsciiString& flag ) = 0;
106 virtual void addArcRadiusRelative( const TCollection_AsciiString& dx,
107 const TCollection_AsciiString& dy,
108 const TCollection_AsciiString& radius,
109 const TCollection_AsciiString& flag ) = 0;
110 virtual void addArcCenterAbsolute( const TCollection_AsciiString& x,
111 const TCollection_AsciiString& y,
112 const TCollection_AsciiString& xc,
113 const TCollection_AsciiString& yc,
114 const TCollection_AsciiString& flag1,
115 const TCollection_AsciiString& flag2 ) = 0;
116 virtual void addArcCenterRelative( const TCollection_AsciiString& dx,
117 const TCollection_AsciiString& dy,
118 const TCollection_AsciiString& xc,
119 const TCollection_AsciiString& yc,
120 const TCollection_AsciiString& flag1,
121 const TCollection_AsciiString& flag2 ) = 0;
122 virtual void addArcRadiusLength( const TCollection_AsciiString& radius,
123 const TCollection_AsciiString& length ) = 0;
124 virtual void addArcAngleRadiusLength( const TCollection_AsciiString& angle,
125 const TCollection_AsciiString& radius,
126 const TCollection_AsciiString& length ,
127 int& CurrentIndex ) = 0;
128 virtual void addArcDirectionRadiusLength( const TCollection_AsciiString& dx,
129 const TCollection_AsciiString& dy,
130 const TCollection_AsciiString& radius,
131 const TCollection_AsciiString& length ,
132 int& CurrentIndex ) = 0;
133 virtual void closeWire() = 0;
134 virtual void closeWireAndBuildFace() = 0;
136 virtual void nextCommand( int& CurrentIndex ) = 0;
137 virtual void makeResult() = 0;
139 void setNumberOfCommand( int n );
144 int myNumberOfCommand;
150 \class Sketcher_Profile::ShapeFunctor
151 \brief Functor that creates a shape from sketcher command
155 class Sketcher_Profile::ShapeFunctor : public Functor
160 virtual void initCommand();
161 virtual void addPoint( const TCollection_AsciiString& x,
162 const TCollection_AsciiString& y );
163 virtual void addAngle( const TCollection_AsciiString& angle );
164 virtual void addSegmentParalX( const TCollection_AsciiString& x );
165 virtual void addSegmentParalXToZero();
166 virtual void addSegmentParalY( const TCollection_AsciiString& y );
167 virtual void addSegmentParalYToZero();
168 virtual void setAngle( const TCollection_AsciiString& angle );
169 virtual void setDirection( const TCollection_AsciiString& dx,
170 const TCollection_AsciiString& dy );
171 virtual void addSegmentAbsolute( const TCollection_AsciiString& x,
172 const TCollection_AsciiString& y );
173 virtual void addSegmentRelative( const TCollection_AsciiString& dx,
174 const TCollection_AsciiString& dy );
175 virtual void addSegmentLength( const TCollection_AsciiString& length );
176 virtual void addSegmentX( const TCollection_AsciiString& x,
178 virtual void addSegmentY( const TCollection_AsciiString& y,
180 virtual void addSegmentAngleLength( const TCollection_AsciiString& angle,
181 const TCollection_AsciiString& length,
183 virtual void addSegmentAngleX( const TCollection_AsciiString& angle,
184 const TCollection_AsciiString& x,
186 virtual void addSegmentAngleY( const TCollection_AsciiString& angle,
187 const TCollection_AsciiString& y,
189 virtual void addSegmentDirectionLength( const TCollection_AsciiString& dx,
190 const TCollection_AsciiString& dy,
191 const TCollection_AsciiString& length,
193 virtual void addSegmentDirectionX( const TCollection_AsciiString& dx,
194 const TCollection_AsciiString& dy,
195 const TCollection_AsciiString& x,
197 virtual void addSegmentDirectionY( const TCollection_AsciiString& dx,
198 const TCollection_AsciiString& dy,
199 const TCollection_AsciiString& y,
201 virtual void addArcAbsolute( const TCollection_AsciiString& x,
202 const TCollection_AsciiString& y );
203 virtual void addArcRelative( const TCollection_AsciiString& dx,
204 const TCollection_AsciiString& dy );
205 virtual void addArcRadiusAbsolute( const TCollection_AsciiString& x,
206 const TCollection_AsciiString& y,
207 const TCollection_AsciiString& radius,
208 const TCollection_AsciiString& flag );
209 virtual void addArcRadiusRelative( const TCollection_AsciiString& dx,
210 const TCollection_AsciiString& dy,
211 const TCollection_AsciiString& radius,
212 const TCollection_AsciiString& flag );
213 virtual void addArcCenterAbsolute( const TCollection_AsciiString& x,
214 const TCollection_AsciiString& y,
215 const TCollection_AsciiString& xc,
216 const TCollection_AsciiString& yc,
217 const TCollection_AsciiString& flag1,
218 const TCollection_AsciiString& flag2 );
219 virtual void addArcCenterRelative( const TCollection_AsciiString& dx,
220 const TCollection_AsciiString& dy,
221 const TCollection_AsciiString& xc,
222 const TCollection_AsciiString& yc,
223 const TCollection_AsciiString& flag1,
224 const TCollection_AsciiString& flag2 );
225 virtual void addArcRadiusLength( const TCollection_AsciiString& radius,
226 const TCollection_AsciiString& length );
227 virtual void addArcAngleRadiusLength( const TCollection_AsciiString& angle,
228 const TCollection_AsciiString& radius,
229 const TCollection_AsciiString& length ,
231 virtual void addArcDirectionRadiusLength( const TCollection_AsciiString& dx,
232 const TCollection_AsciiString& dy,
233 const TCollection_AsciiString& radius,
234 const TCollection_AsciiString& length ,
236 virtual void closeWire();
237 virtual void closeWireAndBuildFace();
239 virtual void nextCommand( int& CurrentIndex );
240 virtual void makeResult();
242 TopoDS_Shape getShape();
245 void setMove( int& CurrentIndex );
248 Standard_Real myX0, myY0, myX, myY, myDx, myDy;
249 Standard_Boolean myFirst, myStayFirst, myFace, myClose;
250 Standard_Real myLength, myRadius, myAngle;
252 enum {line, circle, point, none} myMove;
254 TopLoc_Location TheLocation; // ?????????
256 TopoDS_Vertex myVertex;
257 BRepBuilderAPI_MakeWire myMakeWire;
259 TopoDS_Shape myShape;
263 \class Sketcher_Profile::ShapeFunctor
264 \brief Functor that generates a Python script from sketcher command
268 class Sketcher_Profile::DumpFunctor : public Functor
273 virtual void init( const TCollection_AsciiString& );
275 virtual void initCommand();
276 virtual void addPoint( const TCollection_AsciiString& x,
277 const TCollection_AsciiString& y );
278 virtual void addAngle( const TCollection_AsciiString& angle );
279 virtual void addSegmentParalX( const TCollection_AsciiString& x );
280 virtual void addSegmentParalXToZero();
281 virtual void addSegmentParalY( const TCollection_AsciiString& y );
282 virtual void addSegmentParalYToZero();
283 virtual void addSegmentAbsolute( const TCollection_AsciiString& x,
284 const TCollection_AsciiString& y );
285 virtual void addSegmentRelative( const TCollection_AsciiString& dx,
286 const TCollection_AsciiString& dy );
287 virtual void addSegmentLength( const TCollection_AsciiString& length );
288 virtual void addSegmentX( const TCollection_AsciiString& x,
290 virtual void addSegmentY( const TCollection_AsciiString& y,
292 virtual void addSegmentAngleLength( const TCollection_AsciiString& angle,
293 const TCollection_AsciiString& length,
295 virtual void addSegmentAngleX( const TCollection_AsciiString& angle,
296 const TCollection_AsciiString& x,
298 virtual void addSegmentAngleY( const TCollection_AsciiString& angle,
299 const TCollection_AsciiString& y,
301 virtual void addSegmentDirectionLength( const TCollection_AsciiString& dx,
302 const TCollection_AsciiString& dy,
303 const TCollection_AsciiString& length,
305 virtual void addSegmentDirectionX( const TCollection_AsciiString& dx,
306 const TCollection_AsciiString& dy,
307 const TCollection_AsciiString& x,
309 virtual void addSegmentDirectionY( const TCollection_AsciiString& dx,
310 const TCollection_AsciiString& dy,
311 const TCollection_AsciiString& y,
313 virtual void addArcAbsolute( const TCollection_AsciiString& x,
314 const TCollection_AsciiString& y );
315 virtual void addArcRelative( const TCollection_AsciiString& dx,
316 const TCollection_AsciiString& dy );
317 virtual void addArcRadiusAbsolute( const TCollection_AsciiString& x,
318 const TCollection_AsciiString& y,
319 const TCollection_AsciiString& radius,
320 const TCollection_AsciiString& flag );
321 virtual void addArcRadiusRelative( const TCollection_AsciiString& dx,
322 const TCollection_AsciiString& dy,
323 const TCollection_AsciiString& radius,
324 const TCollection_AsciiString& flag );
325 virtual void addArcCenterAbsolute( const TCollection_AsciiString& x,
326 const TCollection_AsciiString& y,
327 const TCollection_AsciiString& xc,
328 const TCollection_AsciiString& yc,
329 const TCollection_AsciiString& flag1,
330 const TCollection_AsciiString& flag2 );
331 virtual void addArcCenterRelative( const TCollection_AsciiString& dx,
332 const TCollection_AsciiString& dy,
333 const TCollection_AsciiString& xc,
334 const TCollection_AsciiString& yc,
335 const TCollection_AsciiString& flag1,
336 const TCollection_AsciiString& flag2 );
337 virtual void addArcRadiusLength( const TCollection_AsciiString& radius,
338 const TCollection_AsciiString& length );
339 virtual void addArcAngleRadiusLength( const TCollection_AsciiString& angle,
340 const TCollection_AsciiString& radius,
341 const TCollection_AsciiString& length ,
343 virtual void addArcDirectionRadiusLength( const TCollection_AsciiString& dx,
344 const TCollection_AsciiString& dy,
345 const TCollection_AsciiString& radius,
346 const TCollection_AsciiString& length ,
348 virtual void closeWire();
349 virtual void closeWireAndBuildFace();
351 virtual void nextCommand( int& CurrentIndex );
352 virtual void makeResult();
354 TCollection_AsciiString getDescription();
357 TCollection_AsciiString myDescr;
358 TCollection_AsciiString mySketcherEntry;
359 TCollection_AsciiString myWPEntry;
360 TCollection_AsciiString myTail;
361 Standard_Boolean myFace;
364 //===========================================================================
365 // Sketcher_Profile::Functor
366 //===========================================================================
372 Sketcher_Profile::Functor::Functor() : myError( 0 ), myNumberOfCommand( 0 ), myOk( true )
380 Sketcher_Profile::Functor::~Functor()
385 \brief Initialize functor from the script
386 \param command sketcher command being parsed
389 void Sketcher_Profile::Functor::init( const TCollection_AsciiString& /*command*/ )
394 \brief Set total number of sketcher operators
395 \param n total number of sketcher operators
398 void Sketcher_Profile::Functor::setNumberOfCommand( int n )
400 myNumberOfCommand = n;
404 \brief Get error (numerical value that describes, e.g. a deviation of point from the specified arc)
405 \return numerical error
408 double Sketcher_Profile::Functor::error()
414 \brief Get result of parsing
415 \return \c true if parsing is successful or \c false otherwise
418 bool Sketcher_Profile::Functor::isOk()
423 //===========================================================================
424 // Sketcher_Profile::ShapeFunctor
425 //===========================================================================
431 Sketcher_Profile::ShapeFunctor::ShapeFunctor() : Functor()
438 myFirst = Standard_True;
439 myStayFirst = myFace = myClose = Standard_False;
441 myLength = myRadius = myAngle = 0;
445 myPlane = gp_Pln( gp_Ax3( gp::XOY() ) );
449 \brief Prepare functor for processing of new sketcher operator
452 void Sketcher_Profile::ShapeFunctor::initCommand()
454 myLength = myRadius = myAngle = 0;
459 \brief Add point with absolute coordinates (\a x, \a y)
460 \param x X coordinate
461 \param y Y coordinate
464 void Sketcher_Profile::ShapeFunctor::addPoint( const TCollection_AsciiString& x,
465 const TCollection_AsciiString& y )
468 MESSAGE("profile : The addPoint instruction must precede all moves");
471 myX0 = myX = x.RealValue();
472 myY0 = myY = y.RealValue();
473 myStayFirst = Standard_True;
481 void Sketcher_Profile::ShapeFunctor::addAngle( const TCollection_AsciiString& angle )
483 myAngle = angle.RealValue() * M_PI / 180.;
484 myDx = Cos( myAngle );
485 myDy = Sin( myAngle );
489 \brief Add new segment of \a x length along X axis
490 \param x length of segment
493 void Sketcher_Profile::ShapeFunctor::addSegmentParalX( const TCollection_AsciiString& x )
495 myLength = x.RealValue();
502 \brief Add new segment along X axis with X coordinate of end set to 0
505 void Sketcher_Profile::ShapeFunctor::addSegmentParalXToZero()
514 \brief Add new segment of \a y length along Y axis
515 \param y length of segment
518 void Sketcher_Profile::ShapeFunctor::addSegmentParalY( const TCollection_AsciiString& y )
520 myLength = y.RealValue();
527 \brief Add new segment along Y axis with Y coordinate of end set to 0
530 void Sketcher_Profile::ShapeFunctor::addSegmentParalYToZero()
539 \brief Set current angle
540 \param angle current working angle
543 void Sketcher_Profile::ShapeFunctor::setAngle( const TCollection_AsciiString& angle )
545 myAngle = angle.RealValue();
546 Standard_Real alpha = myAngle * M_PI / 180.;
547 Standard_Real c = Cos( alpha );
548 Standard_Real s = Sin( alpha );
549 Standard_Real t = c * myDx - s * myDy;
550 myDy = s * myDx + c * myDy;
555 \brief Set current direction
556 \param dx X component of direction vector
557 \param dy Y component of direction vector
560 void Sketcher_Profile::ShapeFunctor::setDirection( const TCollection_AsciiString& dx,
561 const TCollection_AsciiString& dy )
563 Standard_Real vx = dx.RealValue();
564 Standard_Real vy = dy.RealValue();
565 myLength = Sqrt( vx * vx + vy * vy );
566 if ( myLength > Precision::Confusion() ) {
567 myDx = vx / myLength;
568 myDy = vy / myLength;
575 \brief Add segment by absolute coordinates
576 \param x X coordinate of segment end
577 \param y Y coordinate of segment end
580 void Sketcher_Profile::ShapeFunctor::addSegmentAbsolute( const TCollection_AsciiString& x,
581 const TCollection_AsciiString& y )
583 Standard_Real vx = x.RealValue() - myX;
584 Standard_Real vy = y.RealValue() - myY;
585 myLength = Sqrt( vx * vx + vy * vy );
586 if ( myLength > Precision::Confusion() ) {
588 myDx = vx / myLength;
589 myDy = vy / myLength;
596 \brief Add segment by relativ coordinates
597 \param dx dX value specifing segment end
598 \param dy dY value specifing segment end
601 void Sketcher_Profile::ShapeFunctor::addSegmentRelative( const TCollection_AsciiString& dx,
602 const TCollection_AsciiString& dy )
604 Standard_Real vx = dx.RealValue();
605 Standard_Real vy = dy.RealValue();
606 myLength = Sqrt( vx * vx + vy * vy );
607 if ( myLength > Precision::Confusion() ) {
609 myDx = vx / myLength;
610 myDy = vy / myLength;
617 \brief Add segment with specified length along current direction
618 \param length segment length
621 void Sketcher_Profile::ShapeFunctor::addSegmentLength( const TCollection_AsciiString& length )
623 myLength = length.RealValue();
624 if ( Abs( myLength ) > Precision::Confusion() )
631 \brief Add segment along X axis to reach specified X coordinate
632 \param x X coordinate of segment end
633 \param CurrentIndex index of current operator
636 void Sketcher_Profile::ShapeFunctor::addSegmentX( const TCollection_AsciiString& x,
639 myLength = x.RealValue();
640 if ( Abs( myDx ) < Precision::Confusion() ) {
641 MESSAGE("profile : cannot intersect, arg "<<CurrentIndex-1);
644 myLength = ( myLength - myX ) / myDx;
645 if ( Abs( myLength ) > Precision::Confusion() )
652 \brief Add segment along Y axis to reach specified Y coordinate
653 \param y Y coordinate of segment end
654 \param CurrentIndex index of current operator
657 void Sketcher_Profile::ShapeFunctor::addSegmentY( const TCollection_AsciiString& y,
660 myLength = y.RealValue();
661 if ( Abs( myDy ) < Precision::Confusion() ) {
662 MESSAGE("profile : cannot intersect, arg "<<CurrentIndex-1);
665 myLength = ( myLength - myY ) / myDy;
666 if ( Abs( myLength ) > Precision::Confusion() )
673 \brief Add segment by specified angle and length
674 \param angle angle that specifies segment direction
675 \param length segment length
676 \param CurrentIndex index of current operator
679 void Sketcher_Profile::ShapeFunctor::addSegmentAngleLength( const TCollection_AsciiString& angle,
680 const TCollection_AsciiString& length,
684 setMove( CurrentIndex );
685 addSegmentLength( length );
689 \brief Add segment that crosses Y axis by specified angle and X coordinate
690 \param angle angle that specifies segment direction
691 \param x X coordinate of segment end
692 \param CurrentIndex index of current operator
695 void Sketcher_Profile::ShapeFunctor::addSegmentAngleX( const TCollection_AsciiString& angle,
696 const TCollection_AsciiString& x,
700 setMove( CurrentIndex );
701 addSegmentX( x, CurrentIndex );
705 \brief Add segment that crosses X axis by specified angle and Y coordinate
706 \param angle angle that specifies segment direction
707 \param y Y coordinate of segment end
708 \param CurrentIndex index of current operator
711 void Sketcher_Profile::ShapeFunctor::addSegmentAngleY( const TCollection_AsciiString& angle,
712 const TCollection_AsciiString& y,
716 setMove( CurrentIndex );
717 addSegmentY( y, CurrentIndex );
721 \brief Add segment by specified direction and length
722 \param dx X component of direction vector
723 \param dx Y component of direction vector
724 \param length segment length
725 \param CurrentIndex index of current operator
728 void Sketcher_Profile::ShapeFunctor::addSegmentDirectionLength( const TCollection_AsciiString& dx,
729 const TCollection_AsciiString& dy,
730 const TCollection_AsciiString& length,
733 setDirection( dx, dy );
734 setMove( CurrentIndex );
735 addSegmentLength( length );
739 \brief Add segment by specified direction and X coordinate
740 \param dx X component of direction vector
741 \param dx Y component of direction vector
742 \param x X coordinate of segment end
743 \param CurrentIndex index of current operator
746 void Sketcher_Profile::ShapeFunctor::addSegmentDirectionX( const TCollection_AsciiString& dx,
747 const TCollection_AsciiString& dy,
748 const TCollection_AsciiString& x,
751 setDirection( dx, dy );
752 setMove( CurrentIndex );
753 addSegmentX( x, CurrentIndex );
757 \brief Add segment by specified direction and Y coordinate
758 \param dx X component of direction vector
759 \param dx Y component of direction vector
760 \param y Y coordinate of segment end
761 \param CurrentIndex index of current operator
764 void Sketcher_Profile::ShapeFunctor::addSegmentDirectionY( const TCollection_AsciiString& dx,
765 const TCollection_AsciiString& dy,
766 const TCollection_AsciiString& y,
769 setDirection( dx, dy );
770 setMove( CurrentIndex );
771 addSegmentY( y, CurrentIndex );
775 \brief Add arc along current direction vector by specified absolute coordinates
776 \param x X coordinate of arc end
777 \param x Y coordinate of arc end
780 void Sketcher_Profile::ShapeFunctor::addArcAbsolute( const TCollection_AsciiString& x,
781 const TCollection_AsciiString& y )
783 Standard_Real vx = x.RealValue() - myX;
784 Standard_Real vy = y.RealValue() - myY;
785 Standard_Real det = myDx * vy - myDy * vx;
786 Standard_Real c = Sqrt( ( myDx * myDx + myDy * myDy ) * ( vx * vx + vy * vy ) );
787 if ( Abs( det ) > Precision::Confusion() && Abs( c ) > Precision::Confusion() ) {
788 // Cosine of alpha = arc of angle / 2 , alpha in [0,Pi]
789 c = ( myDx * vx + myDy * vy ) / c;
790 // radius = distance between start and end point / 2 * sin(alpha)
791 // radius is > 0 or < 0
792 myRadius = ( vx * vx + vy * vy )* Sqrt( myDx * myDx + myDy * myDy ) / ( 2.0 * det );
793 if ( Abs( myRadius ) > Precision::Confusion() ) {
794 myAngle = 2.0 * acos( c ); // angle in [0,2Pi]
805 \brief Add arc along current direction vector by specified relative coordinates
806 \param dx dX value specifing arc end
807 \param dy dY value specifing arc end
810 void Sketcher_Profile::ShapeFunctor::addArcRelative( const TCollection_AsciiString& dx,
811 const TCollection_AsciiString& dy )
813 Standard_Real vx = dx.RealValue();
814 Standard_Real vy = dy.RealValue();
815 Standard_Real det = myDx * vy - myDy * vx;
816 Standard_Real c = Sqrt( ( myDx * myDx + myDy * myDy ) * ( vx * vx + vy * vy ) );
817 if ( Abs( det ) > Precision::Confusion() && Abs( c ) > Precision::Confusion() ) {
818 // Cosine of alpha = arc of angle / 2 , alpha in [0,Pi]
819 c = ( myDx * vx + myDy * vy ) / c;
820 // radius = distance between start and end point / 2 * sin(alpha)
821 // radius is > 0 or < 0
822 myRadius = ( vx * vx + vy * vy )* Sqrt( myDx * myDx + myDy * myDy ) / ( 2.0 * det );
823 if ( Abs( myRadius ) > Precision::Confusion() ) {
824 myAngle = 2.0 * acos(c); // angle in [0,2Pi]
835 \brief Add arc with given radius by specified absolute coordinates
836 \param x X coordinate of arc end
837 \param x Y coordinate of arc end
838 \param radius arc radius
839 \param flag reverse direction flag
842 void Sketcher_Profile::ShapeFunctor::addArcRadiusAbsolute( const TCollection_AsciiString& x,
843 const TCollection_AsciiString& y,
844 const TCollection_AsciiString& radius,
845 const TCollection_AsciiString& flag )
847 Standard_Real vx = x.RealValue() - myX;
848 Standard_Real vy = y.RealValue() - myY;
849 myRadius = radius.RealValue();
850 int reversed = flag.IntegerValue();
851 Standard_Real length = Sqrt( vx * vx + vy * vy );
852 if ( Abs( myRadius ) > Precision::Confusion() &&
853 ( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) >= 0.0 ) && ( length > Precision::Confusion() ) ) {
854 // Cosine of alpha = arc angle / 2 , alpha in [0,Pi/2]
855 Standard_Real c = 0.5 * Sqrt( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) );
856 myAngle = 2.0 * acos( c ); // angle in [0,Pi]
858 myAngle = myAngle - 2 * M_PI;
859 myDx = 0.5 * ( vy * 1.0 / myRadius
860 + vx * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) );
861 myDy = -0.5 * ( vx * 1.0 / myRadius
862 - vy * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) );
871 \brief Add arc with given radius by specified relative coordinates
872 \param dx dX value specifing arc end
873 \param dy dY value specifing arc end
874 \param radius arc radius
875 \param flag reverse direction flag
878 void Sketcher_Profile::ShapeFunctor::addArcRadiusRelative( const TCollection_AsciiString& dx,
879 const TCollection_AsciiString& dy,
880 const TCollection_AsciiString& radius,
881 const TCollection_AsciiString& flag )
883 Standard_Real vx = dx.RealValue();
884 Standard_Real vy = dy.RealValue();
885 myRadius = radius.RealValue();
886 int reversed = flag.IntegerValue();
887 Standard_Real length = Sqrt( vx * vx + vy * vy );
888 if ( Abs( myRadius ) > Precision::Confusion() &&
889 ( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) >= 0.0 ) && ( length > Precision::Confusion() ) ) {
890 // Cosine of alpha = arc angle / 2 , alpha in [0,Pi/2]
891 Standard_Real c = 0.5 * Sqrt( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) );
892 myAngle = 2.0 * acos( c ); // angle in [0,Pi]
894 myAngle = myAngle - 2 * M_PI;
895 myDx = 0.5 * ( vy * 1.0 / myRadius
896 + vx * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) );
897 myDy = -0.5 * ( vx * 1.0 / myRadius
898 - vy * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) );
907 \brief Add arc with given center by specified absolute coordinates
908 \param x X coordinate of arc end
909 \param x Y coordinate of arc end
910 \param xc X coordinate of arc center
911 \param yc Y coordinate of arc center
912 \param flag1 reverse direction flag
913 \param flag2 tolerance
916 void Sketcher_Profile::ShapeFunctor::addArcCenterAbsolute( const TCollection_AsciiString& x,
917 const TCollection_AsciiString& y,
918 const TCollection_AsciiString& xc,
919 const TCollection_AsciiString& yc,
920 const TCollection_AsciiString& flag1,
921 const TCollection_AsciiString& flag2 )
923 Standard_Real vx = x.RealValue() - myX;
924 Standard_Real vy = y.RealValue() - myY;
925 Standard_Real vxc = xc.RealValue() - myX;
926 Standard_Real vyc = yc.RealValue() - myY;
927 int reversed = flag1.IntegerValue();
928 int control_Tolerance = flag2.IntegerValue();
930 myRadius = Sqrt( vxc * vxc + vyc * vyc );
931 Standard_Real det = vx * vyc - vy * vxc;
932 Standard_Real length = Sqrt( vx * vx + vy * vy );
933 Standard_Real length2 = Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) );
934 Standard_Real length3 = Sqrt( vxc * vxc + vyc * vyc );
935 Standard_Real error = Abs( length2 - myRadius );
937 if ( error > Precision::Confusion() ) {
938 MESSAGE("Warning : The specified end point is not on the Arc, distance = "<<error);
940 if ( error > Precision::Confusion() && control_Tolerance == 1 ) // Don't create the arc if the end point
941 myMove = none; // is too far from it
942 else if ( ( length > Precision::Confusion() ) &&
943 ( length2 > Precision::Confusion() ) &&
944 ( length3 > Precision::Confusion() ) ) {
945 Standard_Real c = ( myRadius * myRadius - ( vx * vxc + vy * vyc ) )
946 / ( myRadius * Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) ) ) ; // Cosine of arc angle
947 myAngle = acos(c); // angle in [0,Pi]
949 myAngle = myAngle - 2 * M_PI;
952 myDx = vyc / myRadius;
953 myDy = -vxc / myRadius;
962 \brief Add arc with given center by specified relative coordinates
963 \param dx dX value specifing arc end
964 \param dy dY value specifing arc end
965 \param xc X coordinate of arc center
966 \param yc Y coordinate of arc center
967 \param flag1 reverse direction flag
968 \param flag2 tolerance
971 void Sketcher_Profile::ShapeFunctor::addArcCenterRelative( const TCollection_AsciiString& dx,
972 const TCollection_AsciiString& dy,
973 const TCollection_AsciiString& xc,
974 const TCollection_AsciiString& yc,
975 const TCollection_AsciiString& flag1,
976 const TCollection_AsciiString& flag2 )
978 Standard_Real vx = dx.RealValue();
979 Standard_Real vy = dy.RealValue();
980 Standard_Real vxc = xc.RealValue();
981 Standard_Real vyc = yc.RealValue();
982 int reversed = flag1.IntegerValue();
983 int control_Tolerance = flag2.IntegerValue();
984 myRadius = Sqrt( vxc * vxc + vyc * vyc );
985 Standard_Real det = vx * vyc - vy * vxc;
986 Standard_Real length = Sqrt( vx * vx + vy * vy );
987 Standard_Real length2 = Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) );
988 Standard_Real length3 = Sqrt( vxc * vxc + vyc * vyc );
989 Standard_Real error = Abs( length2 - myRadius );
991 if ( error > Precision::Confusion() ) {
992 MESSAGE("Warning : The specified end point is not on the Arc, distance = "<<error);
994 if ( error > Precision::Confusion() && control_Tolerance == 1 ) // Don't create the arc if the end point
995 myMove = none; // is too far from it
996 else if ( ( length > Precision::Confusion() ) &&
997 ( length2 > Precision::Confusion() ) &&
998 ( length3 > Precision::Confusion() ) ) {
999 Standard_Real c = ( myRadius * myRadius - ( vx * vxc + vy * vyc ) )
1000 / ( myRadius * Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) ) ) ; // Cosine of arc angle
1001 myAngle = acos( c ); // angle in [0,Pi]
1002 if ( reversed == 2 )
1003 myAngle = myAngle - 2 * M_PI;
1006 myDx = vyc / myRadius;
1007 myDy = -vxc / myRadius;
1016 \brief Add arc with given radius by specified length
1017 \param radius arc radius
1018 \param length arc length
1021 void Sketcher_Profile::ShapeFunctor::addArcRadiusLength( const TCollection_AsciiString& radius,
1022 const TCollection_AsciiString& length )
1024 myRadius = radius.RealValue();
1025 if ( Abs( myRadius ) > Precision::Confusion() ) {
1026 myAngle = length.RealValue() * M_PI / 180.;
1034 \brief Add arc with given radius by specified angle and length
1035 \param angle angle between arc start tangent and current direction
1036 \param radius arc radius
1037 \param length arc length
1038 \param CurrentIndex index of current operator
1041 void Sketcher_Profile::ShapeFunctor::addArcAngleRadiusLength( const TCollection_AsciiString& angle,
1042 const TCollection_AsciiString& radius,
1043 const TCollection_AsciiString& length ,
1047 setMove( CurrentIndex );
1048 addArcRadiusLength( radius, length );
1052 \brief Add arc with given radius by specified direction and length
1053 \param dx X component of direction vector
1054 \param dx Y component of direction vector
1055 \param radius arc radius
1056 \param length arc length
1057 \param CurrentIndex index of current operator
1060 void Sketcher_Profile::ShapeFunctor::addArcDirectionRadiusLength( const TCollection_AsciiString& dx,
1061 const TCollection_AsciiString& dy,
1062 const TCollection_AsciiString& radius,
1063 const TCollection_AsciiString& length ,
1066 setDirection( dx, dy );
1067 setMove( CurrentIndex );
1068 addArcRadiusLength( radius, length );
1075 void Sketcher_Profile::ShapeFunctor::closeWire()
1077 myClose = Standard_True;
1081 \brief Close wire and build face
1084 void Sketcher_Profile::ShapeFunctor::closeWireAndBuildFace()
1086 myClose = Standard_True;
1087 myFace = Standard_True;
1091 \brief Set internal parameters according to the current operator type
1092 \param CurrentIndex index of current operator
1095 void Sketcher_Profile::ShapeFunctor::setMove( int& CurrentIndex )
1101 if ( myLength < 0 ) {
1102 myLength = -myLength;
1106 Handle(Geom2d_Line) l = new Geom2d_Line( gp_Pnt2d( myX, myY ),gp_Dir2d( myDx, myDy ) );
1107 BRepBuilderAPI_MakeEdge ME( GeomAPI::To3d( l, myPlane ), 0, myLength );
1110 myMakeWire.Add( ME );
1111 myX += myLength * myDx;
1112 myY += myLength * myDy;
1117 Standard_Boolean sense = Standard_True;
1118 if ( myRadius < 0 ) {
1119 myRadius = -myRadius;
1124 gp_Ax2d ax( gp_Pnt2d( myX - myRadius * myDy, myY + myRadius * myDx ), gp_Dir2d( myDy, -myDx ) );
1125 if ( myAngle < 0 ) {
1129 Handle(Geom2d_Circle) c = new Geom2d_Circle( ax, myRadius, sense );
1130 BRepBuilderAPI_MakeEdge ME( GeomAPI::To3d( c, myPlane ), 0, myAngle );
1133 myMakeWire.Add( ME );
1136 c->D1( myAngle, p, v );
1139 myDx = v.X() / myRadius;
1140 myDy = v.Y() / myRadius;
1145 myVertex = BRepBuilderAPI_MakeVertex( gp_Pnt( myX, myY, 0.0 ) );
1150 CurrentIndex = myNumberOfCommand - 1;
1157 \brief Complete parsing of current operator
1158 \param CurrentIndex index of current operator
1161 void Sketcher_Profile::ShapeFunctor::nextCommand( int& CurrentIndex )
1163 setMove( CurrentIndex );
1166 myFirst = myStayFirst;
1167 myStayFirst = Standard_False;
1170 if ( ( CurrentIndex == myNumberOfCommand ) && myClose ) {
1171 // the closing segment
1174 myLength = Sqrt( myDx * myDx + myDy * myDy );
1176 if ( myLength > Precision::Confusion() ) {
1177 myDx = myDx / myLength;
1178 myDy = myDy / myLength;
1179 setMove( CurrentIndex );
1185 \brief Finish parsing and create result
1188 void Sketcher_Profile::ShapeFunctor::makeResult()
1190 // get the result, face or wire
1191 if ( myMove == none ) {
1195 else if ( myMove == point ) {
1198 else if ( myFace ) {
1199 if ( !myMakeWire.IsDone() ) {
1203 BRepBuilderAPI_MakeFace MF ( myPlane, myMakeWire.Wire() );
1204 if ( !MF.IsDone() ) {
1211 if ( !myMakeWire.IsDone() ) {
1215 myShape = myMakeWire.Shape();
1218 if ( !TheLocation.IsIdentity() )
1219 myShape.Move( TheLocation );
1223 \brief Get resulting shape
1224 \return shape resulting from parsing of sketcher command
1227 TopoDS_Shape Sketcher_Profile::ShapeFunctor::getShape()
1232 //===========================================================================
1233 // Sketcher_Profile::DumpFunctor
1234 //===========================================================================
1240 Sketcher_Profile::DumpFunctor::DumpFunctor()
1242 myFace = Standard_False;
1246 \brief Initialize functor from the script
1247 \param command sketcher command being parsed
1250 void Sketcher_Profile::DumpFunctor::init( const TCollection_AsciiString& command )
1252 // parse only first line of the script
1253 TCollection_AsciiString aSubStr = command.Token( "\n\t" );
1254 if ( aSubStr.Length() < command.Length() )
1255 myTail = command.SubString( aSubStr.Length()+1, command.Length() );
1257 mySketcherEntry = aSubStr.Token( " =" );
1258 // Using this Working Plane for Sketcher
1259 myWPEntry = myWPEntry + "[" + aSubStr.Token( "[]", 2 ) + "]";
1260 // Using this Working Plane for SketcherOnPlane
1261 if ( aSubStr.Search( "MakeSketcherOnPlane" ) != -1 ) {
1262 myWPEntry = aSubStr.Token( ",)", 2 );
1263 myWPEntry.RemoveAll( ' ' );
1265 myDescr += "sk = geompy.Sketcher2D()";
1269 \brief Prepare functor for processing of new sketcher operator
1272 void Sketcher_Profile::DumpFunctor::initCommand()
1278 \brief Add point with absolute coordinates (\a x, \a y)
1279 \param x X coordinate
1280 \param y Y coordinate
1283 void Sketcher_Profile::DumpFunctor::addPoint( const TCollection_AsciiString& x,
1284 const TCollection_AsciiString& y )
1286 myDescr += "sk.addPoint(";
1287 myDescr += x + ", " + y + ")";
1295 void Sketcher_Profile::DumpFunctor::addAngle( const TCollection_AsciiString& angle )
1297 myDescr += "sk.addAngle(";
1298 myDescr += angle + ")";
1302 \brief Add new segment of \a x length along X axis
1303 \param x length of segment
1306 void Sketcher_Profile::DumpFunctor::addSegmentParalX( const TCollection_AsciiString& x )
1308 myDescr += "sk.addSegmentParalX(";
1313 \brief Add new segment along X axis with X coordinate of end set to 0
1316 void Sketcher_Profile::DumpFunctor::addSegmentParalXToZero()
1318 myDescr += "sk.addSegmentParalXToZero()";
1322 \brief Add new segment of \a y length along Y axis
1323 \param y length of segment
1326 void Sketcher_Profile::DumpFunctor::addSegmentParalY( const TCollection_AsciiString& y )
1328 myDescr += "sk.addSegmentParalY(";
1333 \brief Add new segment along Y axis with Y coordinate of end set to 0
1336 void Sketcher_Profile::DumpFunctor::addSegmentParalYToZero()
1338 myDescr += "sk.addSegmentParalYToZero()";
1342 \brief Add segment by absolute coordinates
1343 \param x X coordinate of segment end
1344 \param y Y coordinate of segment end
1347 void Sketcher_Profile::DumpFunctor::addSegmentAbsolute( const TCollection_AsciiString& x,
1348 const TCollection_AsciiString& y )
1350 myDescr += "sk.addSegmentAbsolute(";
1351 myDescr += x + ", " + y + ")";
1355 \brief Add segment by relativ coordinates
1356 \param dx dX value specifing segment end
1357 \param dy dY value specifing segment end
1360 void Sketcher_Profile::DumpFunctor::addSegmentRelative( const TCollection_AsciiString& dx,
1361 const TCollection_AsciiString& dy )
1363 myDescr += "sk.addSegmentRelative(";
1364 myDescr += dx + ", " + dy + ")";
1368 \brief Add segment with specified length along current direction
1369 \param length segment length
1372 void Sketcher_Profile::DumpFunctor::addSegmentLength( const TCollection_AsciiString& length )
1374 myDescr += "sk.addSegmentLength(";
1375 myDescr += length + ")";
1379 \brief Add segment along X axis to reach specified X coordinate
1380 \param x X coordinate of segment end
1381 \param CurrentIndex index of current operator
1384 void Sketcher_Profile::DumpFunctor::addSegmentX( const TCollection_AsciiString& x,
1387 myDescr += "sk.addSegmentX(";
1392 \brief Add segment along Y axis to reach specified Y coordinate
1393 \param y Y coordinate of segment end
1394 \param CurrentIndex index of current operator
1397 void Sketcher_Profile::DumpFunctor::addSegmentY( const TCollection_AsciiString& y,
1400 myDescr += "sk.addSegmentY(";
1405 \brief Add segment by specified angle and length
1406 \param angle angle that specifies segment direction
1407 \param length segment length
1408 \param CurrentIndex index of current operator
1411 void Sketcher_Profile::DumpFunctor::addSegmentAngleLength( const TCollection_AsciiString& angle,
1412 const TCollection_AsciiString& length,
1415 double aAngle = angle.RealValue();
1416 if ( aAngle == 90 ) {
1417 myDescr += "sk.addSegmentPerpLength(";
1418 myDescr += length + ")";
1421 myDescr += "sk.addSegmentAngleLength(";
1422 myDescr += angle + ", " + length + ")";
1427 \brief Add segment that crosses Y axis by specified angle and X coordinate
1428 \param angle angle that specifies segment direction
1429 \param x X coordinate of segment end
1430 \param CurrentIndex index of current operator
1433 void Sketcher_Profile::DumpFunctor::addSegmentAngleX( const TCollection_AsciiString& angle,
1434 const TCollection_AsciiString& x,
1437 double aAngle = angle.RealValue();
1438 if ( aAngle == 90 ) {
1439 myDescr += "sk.addSegmentPerpX(";
1443 myDescr += "sk.addSegmentAngleX(";
1444 myDescr += angle + ", " + x + ")";
1449 \brief Add segment that crosses X axis by specified angle and Y coordinate
1450 \param angle angle that specifies segment direction
1451 \param y Y coordinate of segment end
1452 \param CurrentIndex index of current operator
1455 void Sketcher_Profile::DumpFunctor::addSegmentAngleY( const TCollection_AsciiString& angle,
1456 const TCollection_AsciiString& y,
1459 double aAngle = angle.RealValue();
1460 if ( aAngle == 90 ) {
1461 myDescr += "sk.addSegmentPerpY(";
1465 myDescr += "sk.addSegmentAngleY(";
1466 myDescr += angle + ", " + y + ")";
1471 \brief Add segment by specified direction and length
1472 \param dx X component of direction vector
1473 \param dx Y component of direction vector
1474 \param length segment length
1475 \param CurrentIndex index of current operator
1478 void Sketcher_Profile::DumpFunctor::addSegmentDirectionLength( const TCollection_AsciiString& dx,
1479 const TCollection_AsciiString& dy,
1480 const TCollection_AsciiString& length,
1483 myDescr += "sk.addSegmentDirectionLength(";
1484 myDescr += dx + ", " + dy + ", " + length + ")";
1488 \brief Add segment by specified direction and X coordinate
1489 \param dx X component of direction vector
1490 \param dx Y component of direction vector
1491 \param x X coordinate of segment end
1492 \param CurrentIndex index of current operator
1495 void Sketcher_Profile::DumpFunctor::addSegmentDirectionX( const TCollection_AsciiString& dx,
1496 const TCollection_AsciiString& dy,
1497 const TCollection_AsciiString& x,
1500 myDescr += "sk.addSegmentDirectionX(";
1501 myDescr += dx + ", " + dy + ", " + x + ")";
1505 \brief Add segment by specified direction and Y coordinate
1506 \param dx X component of direction vector
1507 \param dx Y component of direction vector
1508 \param y Y coordinate of segment end
1509 \param CurrentIndex index of current operator
1512 void Sketcher_Profile::DumpFunctor::addSegmentDirectionY( const TCollection_AsciiString& dx,
1513 const TCollection_AsciiString& dy,
1514 const TCollection_AsciiString& y,
1517 myDescr += "sk.addSegmentDirectionY(";
1518 myDescr += dx + ", " + dy + ", " + y + ")";
1522 \brief Add arc along current direction vector by specified absolute coordinates
1523 \param x X coordinate of arc end
1524 \param x Y coordinate of arc end
1527 void Sketcher_Profile::DumpFunctor::addArcAbsolute( const TCollection_AsciiString& x,
1528 const TCollection_AsciiString& y )
1530 myDescr += "sk.addArcAbsolute(";
1531 myDescr += x + ", " + y + ")";
1535 \brief Add arc along current direction vector by specified relative coordinates
1536 \param dx dX value specifing arc end
1537 \param dy dY value specifing arc end
1540 void Sketcher_Profile::DumpFunctor::addArcRelative( const TCollection_AsciiString& dx,
1541 const TCollection_AsciiString& dy )
1543 myDescr += "sk.addArcRelative(";
1544 myDescr += dx + ", " + dy + ")";
1548 \brief Add arc with given radius by specified absolute coordinates
1549 \param x X coordinate of arc end
1550 \param x Y coordinate of arc end
1551 \param radius arc radius
1552 \param flag reverse direction flag
1555 void Sketcher_Profile::DumpFunctor::addArcRadiusAbsolute( const TCollection_AsciiString& x,
1556 const TCollection_AsciiString& y,
1557 const TCollection_AsciiString& radius,
1558 const TCollection_AsciiString& flag )
1560 myDescr += "sk.addArcRadiusAbsolute(";
1561 myDescr += x + ", " + y + ", " + radius + ", " + flag + ")";
1565 \brief Add arc with given radius by specified relative coordinates
1566 \param dx dX value specifing arc end
1567 \param dy dY value specifing arc end
1568 \param radius arc radius
1569 \param flag reverse direction flag
1572 void Sketcher_Profile::DumpFunctor::addArcRadiusRelative( const TCollection_AsciiString& dx,
1573 const TCollection_AsciiString& dy,
1574 const TCollection_AsciiString& radius,
1575 const TCollection_AsciiString& flag )
1577 myDescr += "sk.addArcRadiusRelative(";
1578 myDescr += dx + ", " + dy + ", " + radius + ", " + flag + ")";
1582 \brief Add arc with given center by specified absolute coordinates
1583 \param x X coordinate of arc end
1584 \param x Y coordinate of arc end
1585 \param xc X coordinate of arc center
1586 \param yc Y coordinate of arc center
1587 \param flag1 reverse direction flag
1588 \param flag2 tolerance
1591 void Sketcher_Profile::DumpFunctor::addArcCenterAbsolute( const TCollection_AsciiString& x,
1592 const TCollection_AsciiString& y,
1593 const TCollection_AsciiString& xc,
1594 const TCollection_AsciiString& yc,
1595 const TCollection_AsciiString& flag1,
1596 const TCollection_AsciiString& flag2 )
1598 myDescr += "sk.addArcCenterAbsolute(";
1599 myDescr += xc + ", " + yc + ", " + x + ", " + y + ", " + flag1 + ", " + flag2 + ")";
1603 \brief Add arc with given center by specified relative coordinates
1604 \param dx dX value specifing arc end
1605 \param dy dY value specifing arc end
1606 \param xc X coordinate of arc center
1607 \param yc Y coordinate of arc center
1608 \param flag1 reverse direction flag
1609 \param flag2 tolerance
1612 void Sketcher_Profile::DumpFunctor::addArcCenterRelative( const TCollection_AsciiString& dx,
1613 const TCollection_AsciiString& dy,
1614 const TCollection_AsciiString& xc,
1615 const TCollection_AsciiString& yc,
1616 const TCollection_AsciiString& flag1,
1617 const TCollection_AsciiString& flag2 )
1619 myDescr += "sk.addArcCenterRelative(";
1620 myDescr += xc + ", " + yc + ", " + dx + ", " + dy + ", " + flag1 + ", " + flag2 + ")";
1624 \brief Add arc with given radius by specified length
1625 \param radius arc radius
1626 \param length arc length
1629 void Sketcher_Profile::DumpFunctor::addArcRadiusLength( const TCollection_AsciiString& radius,
1630 const TCollection_AsciiString& length )
1632 myDescr += "sk.addArcRadiusLength(";
1633 myDescr += radius + ", " + length + ")";
1637 \brief Add arc with given radius by specified angle and length
1638 \param angle angle between arc start tangent and current direction
1639 \param radius arc radius
1640 \param length arc length
1641 \param CurrentIndex index of current operator
1644 void Sketcher_Profile::DumpFunctor::addArcAngleRadiusLength( const TCollection_AsciiString& angle,
1645 const TCollection_AsciiString& radius,
1646 const TCollection_AsciiString& length ,
1649 double aAngle = angle.RealValue();
1650 if ( aAngle == 90 ) {
1651 myDescr += "sk.addArcPerpRadiusLength(";
1652 myDescr += radius + ", " + length + ")";
1655 myDescr += "sk.addArcAngleRadiusLength(";
1656 myDescr += angle + ", " + radius + ", " + length + ")";
1661 \brief Add arc with given radius by specified direction and length
1662 \param dx X component of direction vector
1663 \param dx Y component of direction vector
1664 \param radius arc radius
1665 \param length arc length
1666 \param CurrentIndex index of current operator
1669 void Sketcher_Profile::DumpFunctor::addArcDirectionRadiusLength( const TCollection_AsciiString& dx,
1670 const TCollection_AsciiString& dy,
1671 const TCollection_AsciiString& radius,
1672 const TCollection_AsciiString& length ,
1675 myDescr += "sk.addArcDirectionRadiusLength(";
1676 myDescr += dx + ", " + dy + ", " + radius + ", " + length + ")";
1683 void Sketcher_Profile::DumpFunctor::closeWire()
1685 myDescr += "sk.close()";
1689 \brief Close wire and build face
1692 void Sketcher_Profile::DumpFunctor::closeWireAndBuildFace()
1694 myDescr += "sk.close()";
1695 myFace = Standard_True;
1699 \brief Complete parsing of current operator
1700 \param CurrentIndex index of current operator
1703 void Sketcher_Profile::DumpFunctor::nextCommand( int& CurrentIndex )
1709 \brief Finish parsing and create result
1712 void Sketcher_Profile::DumpFunctor::makeResult()
1714 if ( mySketcherEntry == "" ) {
1720 myDescr += mySketcherEntry + " = sk.face(" + myWPEntry + ")";
1722 myDescr += mySketcherEntry + " = sk.wire(" + myWPEntry + ")";
1727 \brief Get python script
1728 \return string representing Python dump resulting from parsing of sketcher command
1731 TCollection_AsciiString Sketcher_Profile::DumpFunctor::getDescription()
1736 //=======================================================================
1738 //=======================================================================
1742 \brief Default constructor
1744 Sketcher_Profile::Sketcher_Profile()
1750 \param command sketcher script to parse
1752 Sketcher_Profile::Sketcher_Profile( const char* command )
1754 SetCommand( command );
1758 \brief Set sketcher script to parse
1759 \param command sketcher script to parse
1761 void Sketcher_Profile::SetCommand( const char* command )
1763 myCommand = command;
1767 \brief Parse sketcher command and get resulting shape
1768 \param isDone if specified (non-zero), result of parsing is returned via this parameter
1769 \param error if specified (non-zero), numerical error is returned via this parameter
1770 \return shape resulting from parsing of sketcher command
1772 TopoDS_Shape Sketcher_Profile::GetShape( bool* isDone, double* error )
1774 ShapeFunctor functor;
1775 parse( myCommand, &functor );
1776 TopoDS_Shape s = functor.getShape();
1778 if ( isDone ) *isDone = functor.isOk();
1779 if ( error ) *error = functor.error();
1785 \brief Parse sketcher command and get resulting Python script
1786 \param isDone if specified (non-zero), result of parsing is returned via this parameter
1787 \return string representing Python dump resulting from parsing of sketcher command
1789 TCollection_AsciiString Sketcher_Profile::GetDump( bool* isDone )
1791 DumpFunctor functor;
1792 parse( myCommand, &functor );
1793 TCollection_AsciiString d = functor.getDescription();
1795 if ( isDone ) *isDone = functor.isOk();
1801 \brief Parse sketcher script using specified functor
1802 \param cmd sketcher script to parse
1805 void Sketcher_Profile::parse( const TCollection_AsciiString& cmd, Functor* functor )
1807 int CurrentIndex = 1;
1808 int NumberOfArg = 0;
1809 int NumberOfCommand = 0;
1811 functor->init( myCommand );
1812 TCollection_AsciiString command = extractCommand( myCommand );
1814 TCollection_AsciiString aToken = command.Token( ":", 1 );
1815 TColStd_Array1OfAsciiString aTab( 0, command.Length() - 1 );
1816 if ( command.Length() ) {
1817 while ( aToken.Length() != 0 ) {
1818 TCollection_AsciiString aNewToken = command.Token( ":", NumberOfCommand + 1 );
1819 if ( aNewToken.Length() > 0 )
1820 aTab( NumberOfCommand ) = aNewToken;
1821 aToken = command.Token( ":", ++NumberOfCommand );
1826 functor->setNumberOfCommand( NumberOfCommand );
1827 if ( aTab.Length() && aTab( 0 ).Length() ) {
1828 while ( CurrentIndex < NumberOfCommand ) {
1829 functor->initCommand();
1830 TColStd_Array1OfAsciiString a( 0, aTab( 0 ).Length() );
1831 findNextCommand( aTab, a, CurrentIndex, NumberOfArg );
1832 if ( a( 0 ) == "F" ) {
1833 if ( NumberOfArg != 3 ) badArgs();
1834 functor->addPoint( a.Value( 1 ), a.Value( 2 ) );
1836 else if ( a( 0 ) == "X" ) {
1837 if ( NumberOfArg != 2 ) badArgs();
1838 functor->addSegmentParalX( a.Value( 1 ) );
1840 else if ( a( 0 ) == "XX" ) {
1841 if ( NumberOfArg != 2 ) badArgs();
1842 functor->addSegmentParalXToZero();
1844 else if ( a( 0 ) == "Y" ) {
1845 if ( NumberOfArg != 2 ) badArgs();
1846 functor->addSegmentParalY( a.Value( 1 ) );
1848 else if ( a( 0 ) == "YY" ) {
1849 if ( NumberOfArg != 2 ) badArgs();
1850 functor->addSegmentParalYToZero();
1852 else if ( a( 0 ) == "RR" ) {
1853 if ( NumberOfArg != 2 ) badArgs();
1854 functor->addAngle( a.Value( 1 ) );
1856 else if ( a( 0 ) == "TT" ) {
1857 if ( NumberOfArg != 3 ) badArgs();
1858 functor->addSegmentAbsolute( a.Value( 1 ), a.Value( 2 ) );
1860 else if ( a( 0 ) == "T" ) {
1861 if ( NumberOfArg != 3 ) badArgs();
1862 functor->addSegmentRelative( a.Value( 1 ), a.Value( 2 ) );
1864 else if ( a( 0 ) == "L" ) {
1865 if ( NumberOfArg != 2 ) badArgs();
1866 functor->addSegmentLength( a.Value( 1 ) );
1868 else if ( a( 0 ) == "IX" ) {
1869 if ( NumberOfArg != 2 ) badArgs();
1870 functor->addSegmentX( a.Value( 1 ), CurrentIndex );
1872 else if ( a( 0 ) == "IY" ) {
1873 if ( NumberOfArg != 2 ) badArgs();
1874 functor->addSegmentY( a.Value( 1 ), CurrentIndex );
1876 else if ( a( 0 ) == "R" ) {
1877 if ( NumberOfArg != 2) badArgs();
1879 TColStd_Array1OfAsciiString aNew( 0, aTab( 0 ).Length() );
1880 findNextCommand( aTab, aNew, CurrentIndex, NumberOfArg );
1881 if ( aNew( 0 ) == "L" ) {
1882 if ( NumberOfArg != 2 ) badArgs();
1883 functor->addSegmentAngleLength( a.Value( 1 ), aNew.Value( 1 ), CurrentIndex );
1885 else if ( aNew( 0 ) == "IX" ) {
1886 if ( NumberOfArg != 2 ) badArgs();
1887 functor->addSegmentAngleX( a.Value( 1 ), aNew.Value( 1 ), CurrentIndex );
1889 else if ( aNew( 0 ) == "IY" ) {
1890 if ( NumberOfArg != 2 ) badArgs();
1891 functor->addSegmentAngleY( a.Value( 1 ), aNew.Value( 1 ), CurrentIndex );
1893 else if ( aNew( 0 ) == "C" ) {
1894 if ( NumberOfArg != 3 ) badArgs();
1895 functor->addArcAngleRadiusLength( a.Value( 1 ), aNew.Value( 1 ), aNew.Value( 2 ), CurrentIndex );
1898 else if ( a( 0 ) == "D" ) {
1899 if ( NumberOfArg != 3 ) badArgs();
1901 TColStd_Array1OfAsciiString aNew ( 0, aTab( 0 ).Length() );
1902 findNextCommand( aTab, aNew, CurrentIndex, NumberOfArg );
1903 if ( aNew( 0 ) == "L" ) {
1904 if ( NumberOfArg != 2 ) badArgs();
1905 functor->addSegmentDirectionLength( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), CurrentIndex );
1907 else if ( aNew( 0 ) == "IX" ) {
1908 if ( NumberOfArg != 2 ) badArgs();
1909 functor->addSegmentDirectionX( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), CurrentIndex );
1911 else if ( aNew( 0 ) == "IY" ) {
1912 if ( NumberOfArg != 2 ) badArgs();
1913 functor->addSegmentDirectionY( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), CurrentIndex );
1915 else if ( aNew( 0 ) == "C" ) {
1916 if ( NumberOfArg != 3 ) badArgs();
1917 functor->addArcDirectionRadiusLength( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), aNew.Value( 2 ), CurrentIndex );
1920 else if ( a( 0 ) == "AA" ) {
1921 if ( NumberOfArg != 3 ) badArgs();
1922 functor->addArcAbsolute( a.Value( 1 ), a.Value( 2 ) );
1924 else if ( a( 0 ) == "A" ) {
1925 if ( NumberOfArg != 3 ) badArgs();
1926 functor->addArcRelative( a.Value( 1 ), a.Value( 2 ) );
1928 else if ( a( 0 ) == "UU" ) {
1929 if ( NumberOfArg != 5 ) badArgs();
1930 functor->addArcRadiusAbsolute( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ) );
1932 else if ( a( 0 ) == "U" ) {
1933 if ( NumberOfArg != 5 ) badArgs();
1934 functor->addArcRadiusRelative( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ) );
1936 else if ( a( 0 ) == "EE" ) {
1937 if ( NumberOfArg != 7 ) badArgs();
1938 functor->addArcCenterAbsolute( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ), a.Value( 5 ), a.Value( 6 ) );
1940 else if ( a( 0 ) == "E" ) {
1941 if ( NumberOfArg != 7 ) badArgs();
1942 functor->addArcCenterRelative( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ), a.Value( 5 ), a.Value( 6 ) );
1944 else if ( a( 0 ) == "C" ) {
1945 if ( NumberOfArg != 3 ) badArgs();
1946 functor->addArcRadiusLength( a.Value( 1 ), a.Value( 2 ) );
1948 else if ( a( 0 ) == "WW" ) {
1949 functor->closeWire();
1950 CurrentIndex = NumberOfCommand - 1;
1952 else if ( a( 0 ) == "WF" ) {
1953 functor->closeWireAndBuildFace();
1954 CurrentIndex = NumberOfCommand - 1;
1957 MESSAGE("profile : unknown code " << a(CurrentIndex));
1960 functor->nextCommand( CurrentIndex );
1964 functor->makeResult();
1968 \brief Extract sketcher command from script
1969 \param cmd sketcher script to parse
1970 \return sketcher command
1973 TCollection_AsciiString Sketcher_Profile::extractCommand( const TCollection_AsciiString& cmd )
1975 // parse only first line of the script
1976 TCollection_AsciiString aSubStr = cmd.Token( "\n\t", 1 );
1977 return aSubStr.Token( "\"", aSubStr.Search( "=" ) != -1 ? 2 : 1 );
1981 \brief Print an error message if the number of arguments of sketcher operator is wrong
1984 void Sketcher_Profile::badArgs()
1986 MESSAGE("profile : bad number of arguments");
1990 \brief Find the next sketcher operator in the input string
1991 \param aTab all sketcher command data
1992 \param a sketcher operator with parameters is returned via this parameter
1993 \param CurrentIndex current operator index
1994 \param NumberOfArg number of operator arguments is returned via this parameter
1997 void Sketcher_Profile::findNextCommand( const TColStd_Array1OfAsciiString& aTab,
1998 TColStd_Array1OfAsciiString& a, int CurrentIndex,
2002 TCollection_AsciiString aToken = aTab(CurrentIndex).Token(" ", 1);
2003 while (aToken.Length() != 0) {
2004 if (aTab(CurrentIndex).Token(" ", n1 + 1).Length() > 0)
2005 a(n1) = aTab(CurrentIndex).Token(" ", n1 + 1);
2006 aToken = aTab(CurrentIndex).Token(" ", ++n1);