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,
640 myLength = x.RealValue();
641 if ( Abs( myDx ) < Precision::Confusion() ) {
642 MESSAGE("profile : cannot intersect, arg "<<CurrentIndex-1);
645 myLength = ( myLength - myX ) / myDx;
646 if ( Abs( myLength ) > Precision::Confusion() )
651 \brief Add segment along Y axis to reach specified Y coordinate
652 \param y Y coordinate of segment end
653 \param CurrentIndex index of current operator
656 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() )
671 \brief Add segment by specified angle and length
672 \param angle angle that specifies segment direction
673 \param length segment length
674 \param CurrentIndex index of current operator
677 void Sketcher_Profile::ShapeFunctor::addSegmentAngleLength( const TCollection_AsciiString& angle,
678 const TCollection_AsciiString& length,
682 setMove( CurrentIndex );
683 addSegmentLength( length );
687 \brief Add segment that crosses Y axis by specified angle and X coordinate
688 \param angle angle that specifies segment direction
689 \param x X coordinate of segment end
690 \param CurrentIndex index of current operator
693 void Sketcher_Profile::ShapeFunctor::addSegmentAngleX( const TCollection_AsciiString& angle,
694 const TCollection_AsciiString& x,
698 setMove( CurrentIndex );
699 addSegmentX( x, CurrentIndex );
703 \brief Add segment that crosses X axis by specified angle and Y coordinate
704 \param angle angle that specifies segment direction
705 \param y Y coordinate of segment end
706 \param CurrentIndex index of current operator
709 void Sketcher_Profile::ShapeFunctor::addSegmentAngleY( const TCollection_AsciiString& angle,
710 const TCollection_AsciiString& y,
714 setMove( CurrentIndex );
715 addSegmentY( y, CurrentIndex );
719 \brief Add segment by specified direction and length
720 \param dx X component of direction vector
721 \param dx Y component of direction vector
722 \param length segment length
723 \param CurrentIndex index of current operator
726 void Sketcher_Profile::ShapeFunctor::addSegmentDirectionLength( const TCollection_AsciiString& dx,
727 const TCollection_AsciiString& dy,
728 const TCollection_AsciiString& length,
731 setDirection( dx, dy );
732 setMove( CurrentIndex );
733 addSegmentLength( length );
737 \brief Add segment by specified direction and X coordinate
738 \param dx X component of direction vector
739 \param dx Y component of direction vector
740 \param x X coordinate of segment end
741 \param CurrentIndex index of current operator
744 void Sketcher_Profile::ShapeFunctor::addSegmentDirectionX( const TCollection_AsciiString& dx,
745 const TCollection_AsciiString& dy,
746 const TCollection_AsciiString& x,
749 setDirection( dx, dy );
750 setMove( CurrentIndex );
751 addSegmentX( x, CurrentIndex );
755 \brief Add segment by specified direction and Y coordinate
756 \param dx X component of direction vector
757 \param dx Y component of direction vector
758 \param y Y coordinate of segment end
759 \param CurrentIndex index of current operator
762 void Sketcher_Profile::ShapeFunctor::addSegmentDirectionY( const TCollection_AsciiString& dx,
763 const TCollection_AsciiString& dy,
764 const TCollection_AsciiString& y,
767 setDirection( dx, dy );
768 setMove( CurrentIndex );
769 addSegmentY( y, CurrentIndex );
773 \brief Add arc along current direction vector by specified absolute coordinates
774 \param x X coordinate of arc end
775 \param x Y coordinate of arc end
778 void Sketcher_Profile::ShapeFunctor::addArcAbsolute( const TCollection_AsciiString& x,
779 const TCollection_AsciiString& y )
781 Standard_Real vx = x.RealValue() - myX;
782 Standard_Real vy = y.RealValue() - myY;
783 Standard_Real det = myDx * vy - myDy * vx;
784 Standard_Real c = Sqrt( ( myDx * myDx + myDy * myDy ) * ( vx * vx + vy * vy ) );
785 if ( Abs( det ) > Precision::Confusion() && Abs( c ) > Precision::Confusion() ) {
786 // Cosine of alpha = arc of angle / 2 , alpha in [0,Pi]
787 c = ( myDx * vx + myDy * vy ) / c;
788 // radius = distance between start and end point / 2 * sin(alpha)
789 // radius is > 0 or < 0
790 myRadius = ( vx * vx + vy * vy )* Sqrt( myDx * myDx + myDy * myDy ) / ( 2.0 * det );
791 if ( Abs( myRadius ) > Precision::Confusion() ) {
792 myAngle = 2.0 * acos( c ); // angle in [0,2Pi]
803 \brief Add arc along current direction vector by specified relative coordinates
804 \param dx dX value specifing arc end
805 \param dy dY value specifing arc end
808 void Sketcher_Profile::ShapeFunctor::addArcRelative( const TCollection_AsciiString& dx,
809 const TCollection_AsciiString& dy )
811 Standard_Real vx = dx.RealValue();
812 Standard_Real vy = dy.RealValue();
813 Standard_Real det = myDx * vy - myDy * vx;
814 Standard_Real c = Sqrt( ( myDx * myDx + myDy * myDy ) * ( vx * vx + vy * vy ) );
815 if ( Abs( det ) > Precision::Confusion() && Abs( c ) > Precision::Confusion() ) {
816 // Cosine of alpha = arc of angle / 2 , alpha in [0,Pi]
817 c = ( myDx * vx + myDy * vy ) / c;
818 // radius = distance between start and end point / 2 * sin(alpha)
819 // radius is > 0 or < 0
820 myRadius = ( vx * vx + vy * vy )* Sqrt( myDx * myDx + myDy * myDy ) / ( 2.0 * det );
821 if ( Abs( myRadius ) > Precision::Confusion() ) {
822 myAngle = 2.0 * acos(c); // angle in [0,2Pi]
833 \brief Add arc with given radius by specified absolute coordinates
834 \param x X coordinate of arc end
835 \param x Y coordinate of arc end
836 \param radius arc radius
837 \param flag reverse direction flag
840 void Sketcher_Profile::ShapeFunctor::addArcRadiusAbsolute( const TCollection_AsciiString& x,
841 const TCollection_AsciiString& y,
842 const TCollection_AsciiString& radius,
843 const TCollection_AsciiString& flag )
845 Standard_Real vx = x.RealValue() - myX;
846 Standard_Real vy = y.RealValue() - myY;
847 myRadius = radius.RealValue();
848 int reversed = flag.IntegerValue();
849 Standard_Real length = Sqrt( vx * vx + vy * vy );
850 if ( Abs( myRadius ) > Precision::Confusion() &&
851 ( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) >= 0.0 ) && ( length > Precision::Confusion() ) ) {
852 // Cosine of alpha = arc angle / 2 , alpha in [0,Pi/2]
853 Standard_Real c = 0.5 * Sqrt( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) );
854 myAngle = 2.0 * acos( c ); // angle in [0,Pi]
856 myAngle = myAngle - 2 * M_PI;
857 myDx = 0.5 * ( vy * 1.0 / myRadius
858 + vx * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) );
859 myDy = -0.5 * ( vx * 1.0 / myRadius
860 - vy * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) );
869 \brief Add arc with given radius by specified relative coordinates
870 \param dx dX value specifing arc end
871 \param dy dY value specifing arc end
872 \param radius arc radius
873 \param flag reverse direction flag
876 void Sketcher_Profile::ShapeFunctor::addArcRadiusRelative( const TCollection_AsciiString& dx,
877 const TCollection_AsciiString& dy,
878 const TCollection_AsciiString& radius,
879 const TCollection_AsciiString& flag )
881 Standard_Real vx = dx.RealValue();
882 Standard_Real vy = dy.RealValue();
883 myRadius = radius.RealValue();
884 int reversed = flag.IntegerValue();
885 Standard_Real length = Sqrt( vx * vx + vy * vy );
886 if ( Abs( myRadius ) > Precision::Confusion() &&
887 ( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) >= 0.0 ) && ( length > Precision::Confusion() ) ) {
888 // Cosine of alpha = arc angle / 2 , alpha in [0,Pi/2]
889 Standard_Real c = 0.5 * Sqrt( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) );
890 myAngle = 2.0 * acos( c ); // angle in [0,Pi]
892 myAngle = myAngle - 2 * M_PI;
893 myDx = 0.5 * ( vy * 1.0 / myRadius
894 + vx * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) );
895 myDy = -0.5 * ( vx * 1.0 / myRadius
896 - vy * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) );
905 \brief Add arc with given center by specified absolute coordinates
906 \param x X coordinate of arc end
907 \param x Y coordinate of arc end
908 \param xc X coordinate of arc center
909 \param yc Y coordinate of arc center
910 \param flag1 reverse direction flag
911 \param flag2 tolerance
914 void Sketcher_Profile::ShapeFunctor::addArcCenterAbsolute( const TCollection_AsciiString& x,
915 const TCollection_AsciiString& y,
916 const TCollection_AsciiString& xc,
917 const TCollection_AsciiString& yc,
918 const TCollection_AsciiString& flag1,
919 const TCollection_AsciiString& flag2 )
921 Standard_Real vx = x.RealValue() - myX;
922 Standard_Real vy = y.RealValue() - myY;
923 Standard_Real vxc = xc.RealValue() - myX;
924 Standard_Real vyc = yc.RealValue() - myY;
925 int reversed = flag1.IntegerValue();
926 int control_Tolerance = flag2.IntegerValue();
928 myRadius = Sqrt( vxc * vxc + vyc * vyc );
929 Standard_Real det = vx * vyc - vy * vxc;
930 Standard_Real length = Sqrt( vx * vx + vy * vy );
931 Standard_Real length2 = Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) );
932 Standard_Real length3 = Sqrt( vxc * vxc + vyc * vyc );
933 Standard_Real error = Abs( length2 - myRadius );
935 if ( error > Precision::Confusion() ) {
936 MESSAGE("Warning : The specified end point is not on the Arc, distance = "<<error);
938 if ( error > Precision::Confusion() && control_Tolerance == 1 ) // Don't create the arc if the end point
939 myMove = none; // is too far from it
940 else if ( ( length > Precision::Confusion() ) &&
941 ( length2 > Precision::Confusion() ) &&
942 ( length3 > Precision::Confusion() ) ) {
943 Standard_Real c = ( myRadius * myRadius - ( vx * vxc + vy * vyc ) )
944 / ( myRadius * Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) ) ) ; // Cosine of arc angle
945 myAngle = acos(c); // angle in [0,Pi]
947 myAngle = myAngle - 2 * M_PI;
950 myDx = vyc / myRadius;
951 myDy = -vxc / myRadius;
960 \brief Add arc with given center by specified relative coordinates
961 \param dx dX value specifing arc end
962 \param dy dY value specifing arc end
963 \param xc X coordinate of arc center
964 \param yc Y coordinate of arc center
965 \param flag1 reverse direction flag
966 \param flag2 tolerance
969 void Sketcher_Profile::ShapeFunctor::addArcCenterRelative( const TCollection_AsciiString& dx,
970 const TCollection_AsciiString& dy,
971 const TCollection_AsciiString& xc,
972 const TCollection_AsciiString& yc,
973 const TCollection_AsciiString& flag1,
974 const TCollection_AsciiString& flag2 )
976 Standard_Real vx = dx.RealValue();
977 Standard_Real vy = dy.RealValue();
978 Standard_Real vxc = xc.RealValue();
979 Standard_Real vyc = yc.RealValue();
980 int reversed = flag1.IntegerValue();
981 int control_Tolerance = flag2.IntegerValue();
982 myRadius = Sqrt( vxc * vxc + vyc * vyc );
983 Standard_Real det = vx * vyc - vy * vxc;
984 Standard_Real length = Sqrt( vx * vx + vy * vy );
985 Standard_Real length2 = Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) );
986 Standard_Real length3 = Sqrt( vxc * vxc + vyc * vyc );
987 Standard_Real error = Abs( length2 - myRadius );
989 if ( error > Precision::Confusion() ) {
990 MESSAGE("Warning : The specified end point is not on the Arc, distance = "<<error);
992 if ( error > Precision::Confusion() && control_Tolerance == 1 ) // Don't create the arc if the end point
993 myMove = none; // is too far from it
994 else if ( ( length > Precision::Confusion() ) &&
995 ( length2 > Precision::Confusion() ) &&
996 ( length3 > Precision::Confusion() ) ) {
997 Standard_Real c = ( myRadius * myRadius - ( vx * vxc + vy * vyc ) )
998 / ( myRadius * Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) ) ) ; // Cosine of arc angle
999 myAngle = acos( c ); // angle in [0,Pi]
1000 if ( reversed == 2 )
1001 myAngle = myAngle - 2 * M_PI;
1004 myDx = vyc / myRadius;
1005 myDy = -vxc / myRadius;
1014 \brief Add arc with given radius by specified length
1015 \param radius arc radius
1016 \param length arc length
1019 void Sketcher_Profile::ShapeFunctor::addArcRadiusLength( const TCollection_AsciiString& radius,
1020 const TCollection_AsciiString& length )
1022 myRadius = radius.RealValue();
1023 if ( Abs( myRadius ) > Precision::Confusion() ) {
1024 myAngle = length.RealValue() * M_PI / 180.;
1032 \brief Add arc with given radius by specified angle and length
1033 \param angle angle between arc start tangent and current direction
1034 \param radius arc radius
1035 \param length arc length
1036 \param CurrentIndex index of current operator
1039 void Sketcher_Profile::ShapeFunctor::addArcAngleRadiusLength( const TCollection_AsciiString& angle,
1040 const TCollection_AsciiString& radius,
1041 const TCollection_AsciiString& length ,
1045 setMove( CurrentIndex );
1046 addArcRadiusLength( radius, length );
1050 \brief Add arc with given radius by specified direction and length
1051 \param dx X component of direction vector
1052 \param dx Y component of direction vector
1053 \param radius arc radius
1054 \param length arc length
1055 \param CurrentIndex index of current operator
1058 void Sketcher_Profile::ShapeFunctor::addArcDirectionRadiusLength( const TCollection_AsciiString& dx,
1059 const TCollection_AsciiString& dy,
1060 const TCollection_AsciiString& radius,
1061 const TCollection_AsciiString& length ,
1064 setDirection( dx, dy );
1065 setMove( CurrentIndex );
1066 addArcRadiusLength( radius, length );
1073 void Sketcher_Profile::ShapeFunctor::closeWire()
1075 myClose = Standard_True;
1079 \brief Close wire and build face
1082 void Sketcher_Profile::ShapeFunctor::closeWireAndBuildFace()
1084 myClose = Standard_True;
1085 myFace = Standard_True;
1089 \brief Set internal parameters according to the current operator type
1090 \param CurrentIndex index of current operator
1093 void Sketcher_Profile::ShapeFunctor::setMove( int& CurrentIndex )
1099 if ( myLength < 0 ) {
1100 myLength = -myLength;
1104 Handle(Geom2d_Line) l = new Geom2d_Line( gp_Pnt2d( myX, myY ),gp_Dir2d( myDx, myDy ) );
1105 BRepBuilderAPI_MakeEdge ME( GeomAPI::To3d( l, myPlane ), 0, myLength );
1108 myMakeWire.Add( ME );
1109 myX += myLength * myDx;
1110 myY += myLength * myDy;
1115 Standard_Boolean sense = Standard_True;
1116 if ( myRadius < 0 ) {
1117 myRadius = -myRadius;
1122 gp_Ax2d ax( gp_Pnt2d( myX - myRadius * myDy, myY + myRadius * myDx ), gp_Dir2d( myDy, -myDx ) );
1123 if ( myAngle < 0 ) {
1127 Handle(Geom2d_Circle) c = new Geom2d_Circle( ax, myRadius, sense );
1128 BRepBuilderAPI_MakeEdge ME( GeomAPI::To3d( c, myPlane ), 0, myAngle );
1131 myMakeWire.Add( ME );
1134 c->D1( myAngle, p, v );
1137 myDx = v.X() / myRadius;
1138 myDy = v.Y() / myRadius;
1143 myVertex = BRepBuilderAPI_MakeVertex( gp_Pnt( myX, myY, 0.0 ) );
1148 CurrentIndex = myNumberOfCommand - 1;
1155 \brief Complete parsing of current operator
1156 \param CurrentIndex index of current operator
1159 void Sketcher_Profile::ShapeFunctor::nextCommand( int& CurrentIndex )
1161 setMove( CurrentIndex );
1164 myFirst = myStayFirst;
1165 myStayFirst = Standard_False;
1168 if ( ( CurrentIndex == myNumberOfCommand ) && myClose ) {
1169 // the closing segment
1172 myLength = Sqrt( myDx * myDx + myDy * myDy );
1174 if ( myLength > Precision::Confusion() ) {
1175 myDx = myDx / myLength;
1176 myDy = myDy / myLength;
1177 setMove( CurrentIndex );
1183 \brief Finish parsing and create result
1186 void Sketcher_Profile::ShapeFunctor::makeResult()
1188 // get the result, face or wire
1189 if ( myMove == none ) {
1193 else if ( myMove == point ) {
1196 else if ( myFace ) {
1197 if ( !myMakeWire.IsDone() ) {
1201 BRepBuilderAPI_MakeFace MF ( myPlane, myMakeWire.Wire() );
1202 if ( !MF.IsDone() ) {
1209 if ( !myMakeWire.IsDone() ) {
1213 myShape = myMakeWire.Shape();
1216 if ( !TheLocation.IsIdentity() )
1217 myShape.Move( TheLocation );
1221 \brief Get resulting shape
1222 \return shape resulting from parsing of sketcher command
1225 TopoDS_Shape Sketcher_Profile::ShapeFunctor::getShape()
1230 //===========================================================================
1231 // Sketcher_Profile::DumpFunctor
1232 //===========================================================================
1238 Sketcher_Profile::DumpFunctor::DumpFunctor()
1240 myFace = Standard_False;
1244 \brief Initialize functor from the script
1245 \param command sketcher command being parsed
1248 void Sketcher_Profile::DumpFunctor::init( const TCollection_AsciiString& command )
1250 // parse only first line of the script
1251 TCollection_AsciiString aSubStr = command.Token( "\n\t" );
1252 if ( aSubStr.Length() < command.Length() )
1253 myTail = command.SubString( aSubStr.Length()+1, command.Length() );
1255 mySketcherEntry = aSubStr.Token( " =" );
1256 // Using this Working Plane for Sketcher
1257 myWPEntry = myWPEntry + "[" + aSubStr.Token( "[]", 2 ) + "]";
1258 // Using this Working Plane for SketcherOnPlane
1259 if ( aSubStr.Search( "MakeSketcherOnPlane" ) != -1 ) {
1260 myWPEntry = aSubStr.Token( ",)", 2 );
1261 myWPEntry.RemoveAll( ' ' );
1263 myDescr += "sk = geompy.Sketcher2D()";
1267 \brief Prepare functor for processing of new sketcher operator
1270 void Sketcher_Profile::DumpFunctor::initCommand()
1276 \brief Add point with absolute coordinates (\a x, \a y)
1277 \param x X coordinate
1278 \param y Y coordinate
1281 void Sketcher_Profile::DumpFunctor::addPoint( const TCollection_AsciiString& x,
1282 const TCollection_AsciiString& y )
1284 myDescr += "sk.addPoint(";
1285 myDescr += x + ", " + y + ")";
1293 void Sketcher_Profile::DumpFunctor::addAngle( const TCollection_AsciiString& angle )
1295 myDescr += "sk.addAngle(";
1296 myDescr += angle + ")";
1300 \brief Add new segment of \a x length along X axis
1301 \param x length of segment
1304 void Sketcher_Profile::DumpFunctor::addSegmentParalX( const TCollection_AsciiString& x )
1306 myDescr += "sk.addSegmentParalX(";
1311 \brief Add new segment along X axis with X coordinate of end set to 0
1314 void Sketcher_Profile::DumpFunctor::addSegmentParalXToZero()
1316 myDescr += "sk.addSegmentParalXToZero()";
1320 \brief Add new segment of \a y length along Y axis
1321 \param y length of segment
1324 void Sketcher_Profile::DumpFunctor::addSegmentParalY( const TCollection_AsciiString& y )
1326 myDescr += "sk.addSegmentParalY(";
1331 \brief Add new segment along Y axis with Y coordinate of end set to 0
1334 void Sketcher_Profile::DumpFunctor::addSegmentParalYToZero()
1336 myDescr += "sk.addSegmentParalYToZero()";
1340 \brief Add segment by absolute coordinates
1341 \param x X coordinate of segment end
1342 \param y Y coordinate of segment end
1345 void Sketcher_Profile::DumpFunctor::addSegmentAbsolute( const TCollection_AsciiString& x,
1346 const TCollection_AsciiString& y )
1348 myDescr += "sk.addSegmentAbsolute(";
1349 myDescr += x + ", " + y + ")";
1353 \brief Add segment by relativ coordinates
1354 \param dx dX value specifing segment end
1355 \param dy dY value specifing segment end
1358 void Sketcher_Profile::DumpFunctor::addSegmentRelative( const TCollection_AsciiString& dx,
1359 const TCollection_AsciiString& dy )
1361 myDescr += "sk.addSegmentRelative(";
1362 myDescr += dx + ", " + dy + ")";
1366 \brief Add segment with specified length along current direction
1367 \param length segment length
1370 void Sketcher_Profile::DumpFunctor::addSegmentLength( const TCollection_AsciiString& length )
1372 myDescr += "sk.addSegmentLength(";
1373 myDescr += length + ")";
1377 \brief Add segment along X axis to reach specified X coordinate
1378 \param x X coordinate of segment end
1379 \param CurrentIndex index of current operator
1382 void Sketcher_Profile::DumpFunctor::addSegmentX( const TCollection_AsciiString& x,
1385 myDescr += "sk.addSegmentX(";
1390 \brief Add segment along Y axis to reach specified Y coordinate
1391 \param y Y coordinate of segment end
1392 \param CurrentIndex index of current operator
1395 void Sketcher_Profile::DumpFunctor::addSegmentY( const TCollection_AsciiString& y,
1398 myDescr += "sk.addSegmentY(";
1403 \brief Add segment by specified angle and length
1404 \param angle angle that specifies segment direction
1405 \param length segment length
1406 \param CurrentIndex index of current operator
1409 void Sketcher_Profile::DumpFunctor::addSegmentAngleLength( const TCollection_AsciiString& angle,
1410 const TCollection_AsciiString& length,
1413 double aAngle = angle.RealValue();
1414 if ( aAngle == 90 ) {
1415 myDescr += "sk.addSegmentPerpLength(";
1416 myDescr += length + ")";
1419 myDescr += "sk.addSegmentAngleLength(";
1420 myDescr += angle + ", " + length + ")";
1425 \brief Add segment that crosses Y axis by specified angle and X coordinate
1426 \param angle angle that specifies segment direction
1427 \param x X coordinate of segment end
1428 \param CurrentIndex index of current operator
1431 void Sketcher_Profile::DumpFunctor::addSegmentAngleX( const TCollection_AsciiString& angle,
1432 const TCollection_AsciiString& x,
1435 double aAngle = angle.RealValue();
1436 if ( aAngle == 90 ) {
1437 myDescr += "sk.addSegmentPerpX(";
1441 myDescr += "sk.addSegmentAngleX(";
1442 myDescr += angle + ", " + x + ")";
1447 \brief Add segment that crosses X axis by specified angle and Y coordinate
1448 \param angle angle that specifies segment direction
1449 \param y Y coordinate of segment end
1450 \param CurrentIndex index of current operator
1453 void Sketcher_Profile::DumpFunctor::addSegmentAngleY( const TCollection_AsciiString& angle,
1454 const TCollection_AsciiString& y,
1457 double aAngle = angle.RealValue();
1458 if ( aAngle == 90 ) {
1459 myDescr += "sk.addSegmentPerpY(";
1463 myDescr += "sk.addSegmentAngleY(";
1464 myDescr += angle + ", " + y + ")";
1469 \brief Add segment by specified direction and length
1470 \param dx X component of direction vector
1471 \param dx Y component of direction vector
1472 \param length segment length
1473 \param CurrentIndex index of current operator
1476 void Sketcher_Profile::DumpFunctor::addSegmentDirectionLength( const TCollection_AsciiString& dx,
1477 const TCollection_AsciiString& dy,
1478 const TCollection_AsciiString& length,
1481 myDescr += "sk.addSegmentDirectionLength(";
1482 myDescr += dx + ", " + dy + ", " + length + ")";
1486 \brief Add segment by specified direction and X coordinate
1487 \param dx X component of direction vector
1488 \param dx Y component of direction vector
1489 \param x X coordinate of segment end
1490 \param CurrentIndex index of current operator
1493 void Sketcher_Profile::DumpFunctor::addSegmentDirectionX( const TCollection_AsciiString& dx,
1494 const TCollection_AsciiString& dy,
1495 const TCollection_AsciiString& x,
1498 myDescr += "sk.addSegmentDirectionX(";
1499 myDescr += dx + ", " + dy + ", " + x + ")";
1503 \brief Add segment by specified direction and Y coordinate
1504 \param dx X component of direction vector
1505 \param dx Y component of direction vector
1506 \param y Y coordinate of segment end
1507 \param CurrentIndex index of current operator
1510 void Sketcher_Profile::DumpFunctor::addSegmentDirectionY( const TCollection_AsciiString& dx,
1511 const TCollection_AsciiString& dy,
1512 const TCollection_AsciiString& y,
1515 myDescr += "sk.addSegmentDirectionY(";
1516 myDescr += dx + ", " + dy + ", " + y + ")";
1520 \brief Add arc along current direction vector by specified absolute coordinates
1521 \param x X coordinate of arc end
1522 \param x Y coordinate of arc end
1525 void Sketcher_Profile::DumpFunctor::addArcAbsolute( const TCollection_AsciiString& x,
1526 const TCollection_AsciiString& y )
1528 myDescr += "sk.addArcAbsolute(";
1529 myDescr += x + ", " + y + ")";
1533 \brief Add arc along current direction vector by specified relative coordinates
1534 \param dx dX value specifing arc end
1535 \param dy dY value specifing arc end
1538 void Sketcher_Profile::DumpFunctor::addArcRelative( const TCollection_AsciiString& dx,
1539 const TCollection_AsciiString& dy )
1541 myDescr += "sk.addArcRelative(";
1542 myDescr += dx + ", " + dy + ")";
1546 \brief Add arc with given radius by specified absolute coordinates
1547 \param x X coordinate of arc end
1548 \param x Y coordinate of arc end
1549 \param radius arc radius
1550 \param flag reverse direction flag
1553 void Sketcher_Profile::DumpFunctor::addArcRadiusAbsolute( const TCollection_AsciiString& x,
1554 const TCollection_AsciiString& y,
1555 const TCollection_AsciiString& radius,
1556 const TCollection_AsciiString& flag )
1558 myDescr += "sk.addArcRadiusAbsolute(";
1559 myDescr += x + ", " + y + ", " + radius + ", " + flag + ")";
1563 \brief Add arc with given radius by specified relative coordinates
1564 \param dx dX value specifing arc end
1565 \param dy dY value specifing arc end
1566 \param radius arc radius
1567 \param flag reverse direction flag
1570 void Sketcher_Profile::DumpFunctor::addArcRadiusRelative( const TCollection_AsciiString& dx,
1571 const TCollection_AsciiString& dy,
1572 const TCollection_AsciiString& radius,
1573 const TCollection_AsciiString& flag )
1575 myDescr += "sk.addArcRadiusRelative(";
1576 myDescr += dx + ", " + dy + ", " + radius + ", " + flag + ")";
1580 \brief Add arc with given center by specified absolute coordinates
1581 \param x X coordinate of arc end
1582 \param x Y coordinate of arc end
1583 \param xc X coordinate of arc center
1584 \param yc Y coordinate of arc center
1585 \param flag1 reverse direction flag
1586 \param flag2 tolerance
1589 void Sketcher_Profile::DumpFunctor::addArcCenterAbsolute( const TCollection_AsciiString& x,
1590 const TCollection_AsciiString& y,
1591 const TCollection_AsciiString& xc,
1592 const TCollection_AsciiString& yc,
1593 const TCollection_AsciiString& flag1,
1594 const TCollection_AsciiString& flag2 )
1596 myDescr += "sk.addArcCenterAbsolute(";
1597 myDescr += xc + ", " + yc + ", " + x + ", " + y + ", " + flag1 + ", " + flag2 + ")";
1601 \brief Add arc with given center by specified relative coordinates
1602 \param dx dX value specifing arc end
1603 \param dy dY value specifing arc end
1604 \param xc X coordinate of arc center
1605 \param yc Y coordinate of arc center
1606 \param flag1 reverse direction flag
1607 \param flag2 tolerance
1610 void Sketcher_Profile::DumpFunctor::addArcCenterRelative( const TCollection_AsciiString& dx,
1611 const TCollection_AsciiString& dy,
1612 const TCollection_AsciiString& xc,
1613 const TCollection_AsciiString& yc,
1614 const TCollection_AsciiString& flag1,
1615 const TCollection_AsciiString& flag2 )
1617 myDescr += "sk.addArcCenterRelative(";
1618 myDescr += xc + ", " + yc + ", " + dx + ", " + dy + ", " + flag1 + ", " + flag2 + ")";
1622 \brief Add arc with given radius by specified length
1623 \param radius arc radius
1624 \param length arc length
1627 void Sketcher_Profile::DumpFunctor::addArcRadiusLength( const TCollection_AsciiString& radius,
1628 const TCollection_AsciiString& length )
1630 myDescr += "sk.addArcRadiusLength(";
1631 myDescr += radius + ", " + length + ")";
1635 \brief Add arc with given radius by specified angle and length
1636 \param angle angle between arc start tangent and current direction
1637 \param radius arc radius
1638 \param length arc length
1639 \param CurrentIndex index of current operator
1642 void Sketcher_Profile::DumpFunctor::addArcAngleRadiusLength( const TCollection_AsciiString& angle,
1643 const TCollection_AsciiString& radius,
1644 const TCollection_AsciiString& length ,
1647 double aAngle = angle.RealValue();
1648 if ( aAngle == 90 ) {
1649 myDescr += "sk.addArcPerpRadiusLength(";
1650 myDescr += radius + ", " + length + ")";
1653 myDescr += "sk.addArcAngleRadiusLength(";
1654 myDescr += angle + ", " + radius + ", " + length + ")";
1659 \brief Add arc with given radius by specified direction and length
1660 \param dx X component of direction vector
1661 \param dx Y component of direction vector
1662 \param radius arc radius
1663 \param length arc length
1664 \param CurrentIndex index of current operator
1667 void Sketcher_Profile::DumpFunctor::addArcDirectionRadiusLength( const TCollection_AsciiString& dx,
1668 const TCollection_AsciiString& dy,
1669 const TCollection_AsciiString& radius,
1670 const TCollection_AsciiString& length ,
1673 myDescr += "sk.addArcDirectionRadiusLength(";
1674 myDescr += dx + ", " + dy + ", " + radius + ", " + length + ")";
1681 void Sketcher_Profile::DumpFunctor::closeWire()
1683 myDescr += "sk.close()";
1687 \brief Close wire and build face
1690 void Sketcher_Profile::DumpFunctor::closeWireAndBuildFace()
1692 myDescr += "sk.close()";
1693 myFace = Standard_True;
1697 \brief Complete parsing of current operator
1698 \param CurrentIndex index of current operator
1701 void Sketcher_Profile::DumpFunctor::nextCommand( int& CurrentIndex )
1707 \brief Finish parsing and create result
1710 void Sketcher_Profile::DumpFunctor::makeResult()
1712 if ( mySketcherEntry == "" ) {
1718 myDescr += mySketcherEntry + " = sk.face(" + myWPEntry + ")";
1720 myDescr += mySketcherEntry + " = sk.wire(" + myWPEntry + ")";
1725 \brief Get python script
1726 \return string representing Python dump resulting from parsing of sketcher command
1729 TCollection_AsciiString Sketcher_Profile::DumpFunctor::getDescription()
1734 //=======================================================================
1736 //=======================================================================
1740 \brief Default constructor
1742 Sketcher_Profile::Sketcher_Profile()
1748 \param command sketcher script to parse
1750 Sketcher_Profile::Sketcher_Profile( const char* command )
1752 SetCommand( command );
1756 \brief Set sketcher script to parse
1757 \param command sketcher script to parse
1759 void Sketcher_Profile::SetCommand( const char* command )
1761 myCommand = command;
1765 \brief Parse sketcher command and get resulting shape
1766 \param isDone if specified (non-zero), result of parsing is returned via this parameter
1767 \param error if specified (non-zero), numerical error is returned via this parameter
1768 \return shape resulting from parsing of sketcher command
1770 TopoDS_Shape Sketcher_Profile::GetShape( bool* isDone, double* error )
1772 ShapeFunctor functor;
1773 parse( myCommand, &functor );
1774 TopoDS_Shape s = functor.getShape();
1776 if ( isDone ) *isDone = functor.isOk();
1777 if ( error ) *error = functor.error();
1783 \brief Parse sketcher command and get resulting Python script
1784 \param isDone if specified (non-zero), result of parsing is returned via this parameter
1785 \return string representing Python dump resulting from parsing of sketcher command
1787 TCollection_AsciiString Sketcher_Profile::GetDump( bool* isDone )
1789 DumpFunctor functor;
1790 parse( myCommand, &functor );
1791 TCollection_AsciiString d = functor.getDescription();
1793 if ( isDone ) *isDone = functor.isOk();
1799 \brief Parse sketcher script using specified functor
1800 \param cmd sketcher script to parse
1803 void Sketcher_Profile::parse( const TCollection_AsciiString& cmd, Functor* functor )
1805 int CurrentIndex = 1;
1806 int NumberOfArg = 0;
1807 int NumberOfCommand = 0;
1809 functor->init( myCommand );
1810 TCollection_AsciiString command = extractCommand( myCommand );
1812 TCollection_AsciiString aToken = command.Token( ":", 1 );
1813 TColStd_Array1OfAsciiString aTab( 0, command.Length() - 1 );
1814 if ( command.Length() ) {
1815 while ( aToken.Length() != 0 ) {
1816 TCollection_AsciiString aNewToken = command.Token( ":", NumberOfCommand + 1 );
1817 if ( aNewToken.Length() > 0 )
1818 aTab( NumberOfCommand ) = aNewToken;
1819 aToken = command.Token( ":", ++NumberOfCommand );
1824 functor->setNumberOfCommand( NumberOfCommand );
1825 if ( aTab.Length() && aTab( 0 ).Length() ) {
1826 while ( CurrentIndex < NumberOfCommand ) {
1827 functor->initCommand();
1828 TColStd_Array1OfAsciiString a( 0, aTab( 0 ).Length() );
1829 findNextCommand( aTab, a, CurrentIndex, NumberOfArg );
1830 if ( a( 0 ) == "F" ) {
1831 if ( NumberOfArg != 3 ) badArgs();
1832 functor->addPoint( a.Value( 1 ), a.Value( 2 ) );
1834 else if ( a( 0 ) == "X" ) {
1835 if ( NumberOfArg != 2 ) badArgs();
1836 functor->addSegmentParalX( a.Value( 1 ) );
1838 else if ( a( 0 ) == "XX" ) {
1839 if ( NumberOfArg != 2 ) badArgs();
1840 functor->addSegmentParalXToZero();
1842 else if ( a( 0 ) == "Y" ) {
1843 if ( NumberOfArg != 2 ) badArgs();
1844 functor->addSegmentParalY( a.Value( 1 ) );
1846 else if ( a( 0 ) == "YY" ) {
1847 if ( NumberOfArg != 2 ) badArgs();
1848 functor->addSegmentParalYToZero();
1850 else if ( a( 0 ) == "RR" ) {
1851 if ( NumberOfArg != 2 ) badArgs();
1852 functor->addAngle( a.Value( 1 ) );
1854 else if ( a( 0 ) == "TT" ) {
1855 if ( NumberOfArg != 3 ) badArgs();
1856 functor->addSegmentAbsolute( a.Value( 1 ), a.Value( 2 ) );
1858 else if ( a( 0 ) == "T" ) {
1859 if ( NumberOfArg != 3 ) badArgs();
1860 functor->addSegmentRelative( a.Value( 1 ), a.Value( 2 ) );
1862 else if ( a( 0 ) == "L" ) {
1863 if ( NumberOfArg != 2 ) badArgs();
1864 functor->addSegmentLength( a.Value( 1 ) );
1866 else if ( a( 0 ) == "IX" ) {
1867 if ( NumberOfArg != 2 ) badArgs();
1868 functor->addSegmentX( a.Value( 1 ), CurrentIndex );
1870 else if ( a( 0 ) == "IY" ) {
1871 if ( NumberOfArg != 2 ) badArgs();
1872 functor->addSegmentY( a.Value( 1 ), CurrentIndex );
1874 else if ( a( 0 ) == "R" ) {
1875 if ( NumberOfArg != 2) badArgs();
1877 TColStd_Array1OfAsciiString aNew( 0, aTab( 0 ).Length() );
1878 findNextCommand( aTab, aNew, CurrentIndex, NumberOfArg );
1879 if ( aNew( 0 ) == "L" ) {
1880 if ( NumberOfArg != 2 ) badArgs();
1881 functor->addSegmentAngleLength( a.Value( 1 ), aNew.Value( 1 ), CurrentIndex );
1883 else if ( aNew( 0 ) == "IX" ) {
1884 if ( NumberOfArg != 2 ) badArgs();
1885 functor->addSegmentAngleX( a.Value( 1 ), aNew.Value( 1 ), CurrentIndex );
1887 else if ( aNew( 0 ) == "IY" ) {
1888 if ( NumberOfArg != 2 ) badArgs();
1889 functor->addSegmentAngleY( a.Value( 1 ), aNew.Value( 1 ), CurrentIndex );
1891 else if ( aNew( 0 ) == "C" ) {
1892 if ( NumberOfArg != 3 ) badArgs();
1893 functor->addArcAngleRadiusLength( a.Value( 1 ), aNew.Value( 1 ), aNew.Value( 2 ), CurrentIndex );
1896 else if ( a( 0 ) == "D" ) {
1897 if ( NumberOfArg != 3 ) badArgs();
1899 TColStd_Array1OfAsciiString aNew ( 0, aTab( 0 ).Length() );
1900 findNextCommand( aTab, aNew, CurrentIndex, NumberOfArg );
1901 if ( aNew( 0 ) == "L" ) {
1902 if ( NumberOfArg != 2 ) badArgs();
1903 functor->addSegmentDirectionLength( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), CurrentIndex );
1905 else if ( aNew( 0 ) == "IX" ) {
1906 if ( NumberOfArg != 2 ) badArgs();
1907 functor->addSegmentDirectionX( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), CurrentIndex );
1909 else if ( aNew( 0 ) == "IY" ) {
1910 if ( NumberOfArg != 2 ) badArgs();
1911 functor->addSegmentDirectionY( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), CurrentIndex );
1913 else if ( aNew( 0 ) == "C" ) {
1914 if ( NumberOfArg != 3 ) badArgs();
1915 functor->addArcDirectionRadiusLength( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), aNew.Value( 2 ), CurrentIndex );
1918 else if ( a( 0 ) == "AA" ) {
1919 if ( NumberOfArg != 3 ) badArgs();
1920 functor->addArcAbsolute( a.Value( 1 ), a.Value( 2 ) );
1922 else if ( a( 0 ) == "A" ) {
1923 if ( NumberOfArg != 3 ) badArgs();
1924 functor->addArcRelative( a.Value( 1 ), a.Value( 2 ) );
1926 else if ( a( 0 ) == "UU" ) {
1927 if ( NumberOfArg != 5 ) badArgs();
1928 functor->addArcRadiusAbsolute( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ) );
1930 else if ( a( 0 ) == "U" ) {
1931 if ( NumberOfArg != 5 ) badArgs();
1932 functor->addArcRadiusRelative( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ) );
1934 else if ( a( 0 ) == "EE" ) {
1935 if ( NumberOfArg != 7 ) badArgs();
1936 functor->addArcCenterAbsolute( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ), a.Value( 5 ), a.Value( 6 ) );
1938 else if ( a( 0 ) == "E" ) {
1939 if ( NumberOfArg != 7 ) badArgs();
1940 functor->addArcCenterRelative( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ), a.Value( 5 ), a.Value( 6 ) );
1942 else if ( a( 0 ) == "C" ) {
1943 if ( NumberOfArg != 3 ) badArgs();
1944 functor->addArcRadiusLength( a.Value( 1 ), a.Value( 2 ) );
1946 else if ( a( 0 ) == "WW" ) {
1947 functor->closeWire();
1948 CurrentIndex = NumberOfCommand - 1;
1950 else if ( a( 0 ) == "WF" ) {
1951 functor->closeWireAndBuildFace();
1952 CurrentIndex = NumberOfCommand - 1;
1955 MESSAGE("profile : unknown code " << a(CurrentIndex));
1958 functor->nextCommand( CurrentIndex );
1962 functor->makeResult();
1966 \brief Extract sketcher command from script
1967 \param cmd sketcher script to parse
1968 \return sketcher command
1971 TCollection_AsciiString Sketcher_Profile::extractCommand( const TCollection_AsciiString& cmd )
1973 // parse only first line of the script
1974 TCollection_AsciiString aSubStr = cmd.Token( "\n\t", 1 );
1975 return aSubStr.Token( "\"", aSubStr.Search( "=" ) != -1 ? 2 : 1 );
1979 \brief Print an error message if the number of arguments of sketcher operator is wrong
1982 void Sketcher_Profile::badArgs()
1984 MESSAGE("profile : bad number of arguments");
1988 \brief Find the next sketcher operator in the input string
1989 \param aTab all sketcher command data
1990 \param a sketcher operator with parameters is returned via this parameter
1991 \param CurrentIndex current operator index
1992 \param NumberOfArg number of operator arguments is returned via this parameter
1995 void Sketcher_Profile::findNextCommand( const TColStd_Array1OfAsciiString& aTab,
1996 TColStd_Array1OfAsciiString& a, int CurrentIndex,
2000 TCollection_AsciiString aToken = aTab(CurrentIndex).Token(" ", 1);
2001 while (aToken.Length() != 0) {
2002 if (aTab(CurrentIndex).Token(" ", n1 + 1).Length() > 0)
2003 a(n1) = aTab(CurrentIndex).Token(" ", n1 + 1);
2004 aToken = aTab(CurrentIndex).Token(" ", ++n1);