From e4a31d66fd10c1c59295a3f7756889818d7ba218 Mon Sep 17 00:00:00 2001 From: vsr Date: Wed, 29 May 2013 16:27:24 +0000 Subject: [PATCH] 0022088: EDF 1631 GEOM : 2D sketcher interface --- doc/salome/examples/sketcher.py | 24 +- .../gui/GEOM/input/creating_sketcher.doc | 14 +- src/EntityGUI/EntityGUI_SketcherDlg.cxx | 37 +- src/GEOM/GEOM_Engine.cxx | 198 +- src/GEOM/Makefile.am | 2 + src/GEOMImpl/GEOMImpl_SketcherDriver.cxx | 15 +- src/GEOM_SWIG/geomBuilder.py | 22 +- src/GEOM_SWIG/gsketcher.py | 897 ++++++- src/SKETCHER/Sketcher_Profile.cxx | 2375 ++++++++++++++--- src/SKETCHER/Sketcher_Profile.hxx | 53 +- 10 files changed, 3045 insertions(+), 592 deletions(-) diff --git a/doc/salome/examples/sketcher.py b/doc/salome/examples/sketcher.py index 6cd355da9..a4f20a1ce 100644 --- a/doc/salome/examples/sketcher.py +++ b/doc/salome/examples/sketcher.py @@ -32,14 +32,36 @@ sketcher1 = geompy.MakeSketcher("Sketcher:F -100 -100:TT 250 -100:R 0:C 100 150: # create a sketcher (wire) on the given face sketcher2 = geompy.MakeSketcherOnPlane("Sketcher:F 10 -30:R 10:C 20 180:R 15:L 50:WW", face) +# Create the same 2D sketchers with Sketcher2D interface + +sk = geompy.Sketcher2D() +sk.addPoint(-100, -100) +sk.addSegmentAbsolute(250, -100) +sk.addArcAngleRadiusLength(0, 100, 150) +sk.addSegmentAngleLength(0, 300) +sk.close() +sketcher3 = sk.face([100, 0, 0, 1, 1, 1, -1, 1, 0]) + +sk = geompy.Sketcher2D() +sk.addPoint(10, -30) +sk.addArcAngleRadiusLength(10, 20, 180) +sk.addSegmentAngleLength(15, 50) +sk.close() +sketcher4 = sk.wire(face) + # add objects in the study id_face = geompy.addToStudy(face,"Face") id_sketcher1 = geompy.addToStudy(sketcher1,"Sketcher1") id_sketcher2 = geompy.addToStudy(sketcher2,"Sketcher2") +id_sketcher3 = geompy.addToStudy(sketcher3, 'Sketcher3' ) +id_sketcher4 = geompy.addToStudy(sketcher4, 'Sketcher4' ) # display the first sketcher and the second sketcher with its planar face gg.createAndDisplayGO(id_face) gg.setDisplayMode(id_face,1) gg.setTransparency(id_face,0.5) gg.createAndDisplayGO(id_sketcher1) -gg.createAndDisplayGO(id_sketcher2) +gg.createAndDisplayGO(id_sketcher2) +gg.createAndDisplayGO(id_sketcher3) +gg.createAndDisplayGO(id_sketcher4) + diff --git a/doc/salome/gui/GEOM/input/creating_sketcher.doc b/doc/salome/gui/GEOM/input/creating_sketcher.doc index 922f2a6aa..7f04b53e2 100644 --- a/doc/salome/gui/GEOM/input/creating_sketcher.doc +++ b/doc/salome/gui/GEOM/input/creating_sketcher.doc @@ -155,12 +155,16 @@ segments. points in the current LCS. \n WorkingPlane can be a Local CS, a plane, or a planar face. +\n Another way to create the 2D Sketcher in TUI is using Sketcher2D +interface. -Our TUI Scripts provide you with useful examples of the use of -\ref tui_sketcher_page "Sketcher". +TUI Command: sk = geompy.Sketcher2D() + +Returns an instance of Sketcher2D interface sk. -There is also a wrapper that can help in the construction of a sketcher using simple commands. -The description of this wrapper can be found in the -dedicated page of the salome.geom python package. +Use the below examples and see the \ref gsketcher.Sketcher2D "Sketcher2D" +interface documentation for more information. +Our TUI Scripts provide you with useful examples of the use of +\ref tui_sketcher_page "2D Sketcher". */ diff --git a/src/EntityGUI/EntityGUI_SketcherDlg.cxx b/src/EntityGUI/EntityGUI_SketcherDlg.cxx index ea4a4a677..9ca190195 100644 --- a/src/EntityGUI/EntityGUI_SketcherDlg.cxx +++ b/src/EntityGUI/EntityGUI_SketcherDlg.cxx @@ -1141,18 +1141,14 @@ void EntityGUI_SketcherDlg::ClickOnEnd() return; } - QString Parameters; - QString Command = myCommand.join( "" ) + GetNewCommand( Parameters ); - Sketcher_Profile aProfile( Command.toAscii() ); - - Command = myCommand.join( "" ); - aProfile = Sketcher_Profile( Command.toAscii() ); - TopoDS_Shape myShape; - if ( aProfile.IsDone() ) - myShape = aProfile.GetShape(); - - if ( myShape.ShapeType() != TopAbs_VERTEX ) - myCommand.append( ":WW" ); + QString Command = myCommand.join( "" ); + Sketcher_Profile aProfile = Sketcher_Profile( Command.toAscii() ); + bool isDone = false; + TopoDS_Shape myShape = aProfile.GetShape( &isDone ); + if ( isDone ) { + if ( myShape.ShapeType() != TopAbs_VERTEX ) + myCommand.append( ":WW" ); + } } else { /*// PAL16008 (Sketcher Validation should be equal to Apply&Close) @@ -2336,6 +2332,8 @@ bool EntityGUI_SketcherDlg::execute( ObjectList& objects ) else { //Test if the current point is the same as the last one TopoDS_Shape myShape1, myShape2; + bool isDone = false; + double error = 0.; // Set "C" numeric locale Kernel_Utils::Localizer loc; @@ -2343,18 +2341,18 @@ bool EntityGUI_SketcherDlg::execute( ObjectList& objects ) //Last Shape QString Command1 = myCommand.join( "" ); Sketcher_Profile aProfile1( Command1.toAscii() ); - if ( aProfile1.IsDone() ) - myShape1 = aProfile1.GetShape(); + myShape1 = aProfile1.GetShape(); //Current Shape QString Command2 = Command1 + GetNewCommand( aParameters ); Sketcher_Profile aProfile2( Command2.toAscii() ); + myShape2 = aProfile2.GetShape( &isDone, &error ); //Error Message if ( mySketchType == PT_ABS_CENTER || mySketchType == PT_REL_CENTER ){ - if (aProfile2.Error() > Precision::Confusion()){ + if (error > Precision::Confusion()){ Group4Spin->label->show(); - Group4Spin->label->setText( tr("GEOM_SKETCHER_WARNING") + QString::number( aProfile2.Error(), Format, DigNum)); + Group4Spin->label->setText( tr("GEOM_SKETCHER_WARNING") + QString::number( error, Format, DigNum)); } else{ Group4Spin->label->hide(); @@ -2363,9 +2361,9 @@ bool EntityGUI_SketcherDlg::execute( ObjectList& objects ) else Group4Spin->label->hide(); if ( mySketchType == PT_SEL_CENTER ){ - if (aProfile2.Error() > Precision::Confusion()){ + if (error > Precision::Confusion()){ Group2Sel->label->show(); - Group2Sel->label->setText( tr("GEOM_SKETCHER_WARNING") + QString::number( aProfile2.Error(), Format, DigNum)); + Group2Sel->label->setText( tr("GEOM_SKETCHER_WARNING") + QString::number( error, Format, DigNum)); } else{ Group2Sel->label->hide(); @@ -2374,9 +2372,6 @@ bool EntityGUI_SketcherDlg::execute( ObjectList& objects ) else Group2Sel->label->hide(); - if ( aProfile2.IsDone() ) - myShape2 = aProfile2.GetShape(); - if ( myShape2.IsNull() ) { //the current point is the same as the last one myLastX2 = myLastX1; diff --git a/src/GEOM/GEOM_Engine.cxx b/src/GEOM/GEOM_Engine.cxx index 003a55332..993b0f10a 100644 --- a/src/GEOM/GEOM_Engine.cxx +++ b/src/GEOM/GEOM_Engine.cxx @@ -32,6 +32,7 @@ #include "GEOM_SubShapeDriver.hxx" #include "GEOM_DataMapIteratorOfDataMapOfAsciiStringTransient.hxx" #include "GEOM_PythonDump.hxx" +#include "Sketcher_Profile.hxx" #include @@ -154,6 +155,7 @@ void PublishObject (TObjectData& theObjectData, namespace { + //================================================================================ /*! * \brief Fix up the name of python variable @@ -961,98 +963,15 @@ std::list GEOM_Engine::getAllTextures(int theDocID) //============================================================================= /*! - * ProcessFunction: Dump function description into script + * MakeCommandfor3DSketcher: Make new command for 3DSketcher */ //============================================================================= -bool ProcessFunction(Handle(GEOM_Function)& theFunction, - TCollection_AsciiString& theScript, - TCollection_AsciiString& theAfterScript, - const TVariablesList& theVariables, - const bool theIsPublished, - TDF_LabelMap& theProcessed, - std::set& theIgnoreObjs, - bool& theIsDumpCollected) +TCollection_AsciiString MakeCommandfor3DSketcher (const TCollection_AsciiString& theDescr ) { - theIsDumpCollected = false; - if (theFunction.IsNull()) return false; - - if (theProcessed.Contains(theFunction->GetEntry())) return false; - - // pass functions, that depends on nonexisting ones - bool doNotProcess = false; - TDF_LabelSequence aSeq; - theFunction->GetDependency(aSeq); - Standard_Integer aLen = aSeq.Length(); - for (Standard_Integer i = 1; i <= aLen && !doNotProcess; i++) { - TDF_Label aRefLabel = aSeq.Value(i); - Handle(TDF_Reference) aRef; - if (!aRefLabel.FindAttribute(TDF_Reference::GetID(), aRef)) { - doNotProcess = true; - } - else { - if (aRef.IsNull() || aRef->Get().IsNull()) { - doNotProcess = true; - } - else { - Handle(TDataStd_TreeNode) aT; - if (!TDataStd_TreeNode::Find(aRef->Get(), aT)) { - doNotProcess = true; - } - else { - TDF_Label aDepLabel = aT->Label(); - Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(aDepLabel); - - if (aFunction.IsNull()) doNotProcess = true; - else if (!theProcessed.Contains(aDepLabel)) doNotProcess = true; - } - } - } - } - - if (doNotProcess) { - TCollection_AsciiString anObjEntry; - TDF_Tool::Entry(theFunction->GetOwnerEntry(), anObjEntry); - theIgnoreObjs.insert(anObjEntry); - return false; - } - theProcessed.Add(theFunction->GetEntry()); - - TCollection_AsciiString aDescr = theFunction->GetDescription(); - if(aDescr.Length() == 0) return false; - - //Check if its internal function which doesn't requires dumping - if(aDescr == "None") return false; - - //Check the very specific case of RestoreShape function, - //which is not dumped, but the result can be published by the user. - //We do not publish such objects to decrease danger of dumped script failure. - if(aDescr.Value(1) == '#') { - TCollection_AsciiString anObjEntry; - TDF_Tool::Entry(theFunction->GetOwnerEntry(), anObjEntry); - theIgnoreObjs.insert(anObjEntry); - return false; - } - - // 0020001 PTv, check for critical functions, which require dump of objects - if (theIsPublished) - { - // currently, there is only one function "RestoreGivenSubShapes", - // later this check could be replaced by iterations on list of such functions - if (aDescr.Search( "RestoreGivenSubShapes" ) != -1) - theIsDumpCollected = true; - else if (aDescr.Search( "RestoreSubShapes" ) != -1) - theIsDumpCollected = true; - } - - //Replace parameter by notebook variables - ReplaceVariables(aDescr,theVariables); - - //Process sketcher functions, replacing string command by calls to Sketcher interface - if (aDescr.Search( "Make3DSketcher" ) != -1) { TCollection_AsciiString aNewDescr; int i = 1; - TCollection_AsciiString aSubStr = aDescr.Token("\n\t", i); - for (; !aSubStr.IsEmpty(); aSubStr = aDescr.Token("\n\t", i)) { + TCollection_AsciiString aSubStr = theDescr.Token("\n\t", i); + for (; !aSubStr.IsEmpty(); aSubStr = theDescr.Token("\n\t", i)) { if (aSubStr.Search( "Make3DSketcherCommand" ) != -1) { TCollection_AsciiString aResult = aSubStr.Token(" ", 1); // "3DSketcher:CMD[:CMD[:CMD...]]" @@ -1073,7 +992,7 @@ bool ProcessFunction(Handle(GEOM_Function)& theFunction, if (i > 1) aNewDescr += "\n\t"; - aNewDescr += "sk = geompy.Sketcher3D()"; + aNewDescr += "\nsk = geompy.Sketcher3D()"; int nbCMDs = aSequence.Length(); for (icmd = 1; icmd <= nbCMDs; icmd++) { aNewDescr += "\n\t"; @@ -1126,7 +1045,7 @@ bool ProcessFunction(Handle(GEOM_Function)& theFunction, aCommand = aCommand.Token("]", 1); if (i > 1) aNewDescr += "\n\t"; - aNewDescr += "sk = geompy.Sketcher3D()"; + aNewDescr += "\nsk = geompy.Sketcher3D()"; aNewDescr += "\n\t"; aNewDescr += "sk.addPointsAbsolute("; aNewDescr += aCommand + ")"; @@ -1138,10 +1057,107 @@ bool ProcessFunction(Handle(GEOM_Function)& theFunction, aNewDescr += "\n\t"; aNewDescr += aSubStr; } - i++; } - aDescr = aNewDescr; + return aNewDescr; +} + +//============================================================================= +/*! + * ProcessFunction: Dump function description into script + */ +//============================================================================= +bool ProcessFunction(Handle(GEOM_Function)& theFunction, + TCollection_AsciiString& theScript, + TCollection_AsciiString& theAfterScript, + const TVariablesList& theVariables, + const bool theIsPublished, + TDF_LabelMap& theProcessed, + std::set& theIgnoreObjs, + bool& theIsDumpCollected) +{ + theIsDumpCollected = false; + if (theFunction.IsNull()) return false; + + if (theProcessed.Contains(theFunction->GetEntry())) return false; + + // pass functions, that depends on nonexisting ones + bool doNotProcess = false; + TDF_LabelSequence aSeq; + theFunction->GetDependency(aSeq); + Standard_Integer aLen = aSeq.Length(); + for (Standard_Integer i = 1; i <= aLen && !doNotProcess; i++) { + TDF_Label aRefLabel = aSeq.Value(i); + Handle(TDF_Reference) aRef; + if (!aRefLabel.FindAttribute(TDF_Reference::GetID(), aRef)) { + doNotProcess = true; + } + else { + if (aRef.IsNull() || aRef->Get().IsNull()) { + doNotProcess = true; + } + else { + Handle(TDataStd_TreeNode) aT; + if (!TDataStd_TreeNode::Find(aRef->Get(), aT)) { + doNotProcess = true; + } + else { + TDF_Label aDepLabel = aT->Label(); + Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(aDepLabel); + + if (aFunction.IsNull()) doNotProcess = true; + else if (!theProcessed.Contains(aDepLabel)) doNotProcess = true; + } + } + } + } + + if (doNotProcess) { + TCollection_AsciiString anObjEntry; + TDF_Tool::Entry(theFunction->GetOwnerEntry(), anObjEntry); + theIgnoreObjs.insert(anObjEntry); + return false; + } + theProcessed.Add(theFunction->GetEntry()); + + TCollection_AsciiString aDescr = theFunction->GetDescription(); + if(aDescr.Length() == 0) return false; + + //Check if its internal function which doesn't requires dumping + if(aDescr == "None") return false; + + //Check the very specific case of RestoreShape function, + //which is not dumped, but the result can be published by the user. + //We do not publish such objects to decrease danger of dumped script failure. + if(aDescr.Value(1) == '#') { + TCollection_AsciiString anObjEntry; + TDF_Tool::Entry(theFunction->GetOwnerEntry(), anObjEntry); + theIgnoreObjs.insert(anObjEntry); + return false; + } + + // 0020001 PTv, check for critical functions, which require dump of objects + if (theIsPublished) + { + // currently, there is only one function "RestoreGivenSubShapes", + // later this check could be replaced by iterations on list of such functions + if (aDescr.Search( "RestoreGivenSubShapes" ) != -1) + theIsDumpCollected = true; + else if (aDescr.Search( "RestoreSubShapes" ) != -1) + theIsDumpCollected = true; + } + + //Replace parameter by notebook variables + ReplaceVariables(aDescr,theVariables); + + //Process sketcher functions, replacing string command by calls to Sketcher interface + if ( ( aDescr.Search( "MakeSketcherOnPlane" ) != -1 ) || ( aDescr.Search( "MakeSketcher" ) != -1 ) ) { + Sketcher_Profile aProfile( aDescr.ToCString()); + // Make new command for SketcherOnPlane and for Sketcher + aDescr = aProfile.GetDump(); + } + if (aDescr.Search( "Make3DSketcher" ) != -1) { + aDescr = MakeCommandfor3DSketcher ( aDescr ); } if ( theIsDumpCollected ) { diff --git a/src/GEOM/Makefile.am b/src/GEOM/Makefile.am index 868732e3d..872f785f9 100644 --- a/src/GEOM/Makefile.am +++ b/src/GEOM/Makefile.am @@ -66,9 +66,11 @@ libGEOMbasic_la_CPPFLAGS = \ $(CAS_CPPFLAGS) \ $(KERNEL_CXXFLAGS) \ $(BOOST_CPPFLAGS) \ + -I$(srcdir)/../SKETCHER \ -I$(top_builddir)/idl libGEOMbasic_la_LDFLAGS = \ + ../SKETCHER/libGEOMSketcher.la \ $(KERNEL_LDFLAGS) -lSALOMELocalTrace -lSALOMEBasics \ $(STDLIB) \ $(CAS_LDPATH) -lTKXSBase -lTKG3d \ diff --git a/src/GEOMImpl/GEOMImpl_SketcherDriver.cxx b/src/GEOMImpl/GEOMImpl_SketcherDriver.cxx index 428377ca3..7209552d5 100644 --- a/src/GEOMImpl/GEOMImpl_SketcherDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_SketcherDriver.cxx @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -26,8 +25,8 @@ #include #include #include - #include +#include #include @@ -38,9 +37,6 @@ #include #include #include - -#include - #include //======================================================================= @@ -79,19 +75,18 @@ Standard_Integer GEOMImpl_SketcherDriver::Execute(TFunction_Logbook& log) const if (aCommand.IsEmpty()) return 0; - TopoDS_Shape aShape; - // Set "C" numeric locale to save numbers correctly Kernel_Utils::Localizer loc; // create sketcher - Sketcher_Profile aProfile (aCommand.ToCString()); + Sketcher_Profile aProfile( aCommand.ToCString() ); + bool isDone = false; + TopoDS_Shape aShape = aProfile.GetShape( &isDone ); - if (!aProfile.IsDone()) { + if ( !isDone ) { Standard_ConstructionError::Raise("Sketcher creation failed"); } - aShape = aProfile.GetShape(); if (aShape.IsNull()) return 0; diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index e99209521..eba62b74c 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -210,7 +210,7 @@ import GEOM import math import os -from salome.geom.gsketcher import Sketcher3D +from salome.geom.gsketcher import Sketcher3D, Sketcher2D # service function def _toListOfNames(_names, _size=-1): @@ -2405,6 +2405,26 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): self._autoPublish(anObj, theName, "wire") return anObj + ## Obtain a 2D sketcher interface + # @return An instance of @ref gsketcher.Sketcher2D "Sketcher2D" interface + def Sketcher2D (self): + """ + Obtain a 2D sketcher interface. + + Example of usage: + sk = geompy.Sketcher2D() + sk.addPoint(20, 20) + sk.addSegmentRelative(15, 70) + sk.addSegmentPerpY(50) + sk.addArcRadiusRelative(25, 15, 14.5, 0) + sk.addArcCenterAbsolute(1, 1, 50, 50, 0, 0) + sk.addArcDirectionRadiusLength(20, 20, 101, 162.13) + sk.close() + Sketch_1 = sk.wire(geomObj_1) + """ + sk = Sketcher2D (self) + return sk + ## Create a sketcher wire, following the numerical description, # passed through theCoordinates argument. \n # @param theCoordinates double values, defining points to create a wire, diff --git a/src/GEOM_SWIG/gsketcher.py b/src/GEOM_SWIG/gsketcher.py index 572536307..691cb5a8e 100644 --- a/src/GEOM_SWIG/gsketcher.py +++ b/src/GEOM_SWIG/gsketcher.py @@ -23,7 +23,7 @@ """ \namespace geompy - \brief 3D Sketcher interface + \brief 2D and 3D Sketcher interfaces """ # This method is used by 3D Sketcher functionality @@ -283,3 +283,898 @@ class Sketcher3D: wire.SetParameters(Parameters) self.geompyD._autoPublish(wire, theName, "wire") return wire + +# An interface to build a 2D Sketcher step-by-step. +# Use geompy.Sketcher2D() method to obtain an instance of this class. + +class Sketcher2D: + """ + 2D sketcher interface. + + Example of usage: + sk = geompy.Sketcher2D() + sk.addPoint(20, 20) + sk.addSegmentRelative(15, 70) + sk.addSegmentPerpY(50) + sk.addArcRadiusRelative(25, 15, 14.5, 0) + sk.addArcCenterAbsolute(1, 1, 50, 50, 0, 0) + sk.addArcDirectionRadiusLength(20, 20, 101, 162.13) + sk.close() + Sketch_1 = sk.wire(geomObj_1) + """ + def __init__(self, geompyD): + self.geompyD = geompyD + self.myCommand = "Sketcher" + self.closed = False + pass + + ## Add one point. + # Used to set the starting point + # + # @param x, y - Coordinates of point + def addPoint (self, x, y): + """ + Add one point. + Used to set the starting point + + Parameters: + x, y - Coordinates of point + + Example of usage: + sk = geompy.Sketcher2D() + sk.addPoint(20, 20) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":F %s %s" % (printVar(x), printVar(y)) + pass + + ## Add angle. + # Used to set the angle for further building + # + # @param angle - angle in a plane + def addAngle (self, angle): + """ + Add angle. + Used to set the angle for further building + + Parameters: + angle - angle in a plane + + Example of usage: + sk = geompy.Sketcher2D() + sk.addAngle(70) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":RR %s" % (printVar(angle)) + pass + + # Commands for creation of segment + + ## Add segment, which sequentially connects the previous point + # with a point lying on a line parallel to the axis Ox and the value x = param x. + # The current point will be the previous value to the coordinate y and + # new value to the coordinate x. + # Coordinate is considered relative to the previous point. + # + # @param x - Coordinate of point on axis Ox + def addSegmentParalX(self, x): + """ + Add segment, which sequentially connects the previous point + with a point lying on a line parallel to the axis Ox and the value x = param x. + The current point will be the previous value to the coordinate y and + new value to the coordinate x. + Coordinate is considered relative to the previous point. + + Parameters: + x - Coordinate of point on axis Ox + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentParalX(40) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":X %s" % (printVar(x)) + pass + + ## Add segment, which sequentially connects the previous point + # with a point lying on a line parallel to the axis Ox and the value x = 0 + # The current point will be the previous value to the coordinate y. + def addSegmentParalXToZero(self): + """ + Add segment, which sequentially connects the previous point + with a point lying on a line parallel to the axis Ox and the value x = 0 + The current point will be the previous value to the coordinate y. + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentParalXToZero() + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":XX" + pass + + ## Add segment, which sequentially connects the previous point + # with a point lying on a line parallel to the axis Oy and the value y = param y. + # The current point will be the previous value to the coordinate x and + # new value to the coordinate y. + # Coordinate is considered relative to the previous point. + # + # @param y - Coordinate of point on axis Oy + def addSegmentParalY(self, y): + """ + Add segment, which sequentially connects the previous point + with a point lying on a line parallel to the axis Oy and the value y = param y. + The current point will be the previous value to the coordinate x and + new value to the coordinate y. + Coordinate is considered relative to the previous point. + + Parameters: + y - Coordinate of point on axis Oy + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentParalY(80) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":Y %s" % (printVar(y)) + pass + + ## Add segment, which sequentially connects the previous point + # with a point lying on a line parallel to the axis Ox and the value x = 0 + # The current point will be the previous value to the coordinate y. + def addSegmentParalYToZero(self): + """ + Add segment, which sequentially connects the previous point + with a point lying on a line parallel to the axis Oy and the value y = 0 + The current point will be the previous value to the coordinate x. + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentParalYToZero() + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":YY" + pass + + ## Add segment, which sequentially connects the given point with previous point + # + # Coordinates are considered as absolute. + # @param x, y - Coordinates of point + def addSegmentAbsolute (self, x, y): + """ + Add segment, which sequentially connects the starting point with the given point + Coordinates are considered as absolute. + + Parameters: + x, y - Coordinates of point + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentAbsolute(30, 50) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":TT %s %s" % (printVar(x), printVar(y)) + pass + + ## Add segment, which sequentially connects the given point with previous point + # Coordinates are considered relative to the previous point. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # + # @param dx, dy - Coordinates of point relative a previous point + def addSegmentRelative (self, dx, dy): + """ + Add segment, which sequentially connects the given point with previous point + Coordinates are considered relative to the previous point. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + + Parameters: + dx, dy - Coordinates of point relative a previous point + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentRelative(60, 10) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":T %s %s" % (printVar(dx), printVar(dy)) + pass + + ## Add one straight segment, defined by angle and length. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # The angle and length coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # + # @param angle - angle in a plane + # @param length - length of the segment + def addSegmentAngleLength (self, angle, length ): + """ + Add one straight segment, defined by angle and length. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + The radius and angles coordinates are defined + in a local coordinate system which origin is the last point of the sketch + + Parameters: + angle - angle in a plane + length - length of the segment + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentAngleLength(10, 30) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":R %s:L %s" % (printVar(angle), printVar(length)) + pass + + ## Add one straight segment, defined by angle and intersect straight x= param x. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # The angle and point's coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # + # @param angle - angle in a plane + # @param x - value on the axis Ox + def addSegmentAngleX (self, angle, x ): + """ + Add one straight segment, defined by angle and intersect straight x= param x. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + The angle and point's coordinates are defined + in a local coordinate system which origin is the last point of the sketch + + Parameters: + angle - angle in a plane + x - value on the axis Ox + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentAngleX(25, 90) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":R %s:IX %s" % (printVar(angle), printVar(x)) + pass + + ## Add one straight segment, defined by angle and intersect straight y= param y. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # The angle and point's coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # + # @param angle - angle in a plane + # @param y - value on the axis Oy + def addSegmentAngleY (self, angle, y ): + """ + Add one straight segment, defined by angle and intersect straight y= param y. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + The angle and point's coordinates are defined + in a local coordinate system which origin is the last point of the sketch + + Parameters: + angle - angle in a plane + y - value on the axis Oy + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentAngleY(40, 0) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":R %s:IY %s" % (printVar(angle), printVar(y)) + pass + + + ## Add one straight segment, defined by perpendicular(angle=90) and length. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # The length coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # + # @param length - length of the segment + def addSegmentPerpLength (self, length ): + """ + Add one straight segment, defined by perpendicular and length. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + The length coordinates are defined + in a local coordinate system which origin is the last point of the sketch + + Parameters: + length - length of the segment + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentPerpLength(100) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":R 90:L %s" % (printVar(length)) + pass + + ## Add one straight segment, defined by perpendicular(angle=90) and intersect straight x= param x. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # The point's coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # + # @param x - value on the axis Ox + def addSegmentPerpX (self, x ): + """ + Add one straight segment, defined by perpendicular(angle=90) and intersect straight x= param x. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + The point's coordinates are defined + in a local coordinate system which origin is the last point of the sketch + + Parameters: + x - value on the axis Ox + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentPerpX(30) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":R 90:IX %s" % (printVar(x)) + pass + + ## Add one straight segment, defined by perpendicular(angle=90) and intersect straight y= param y. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # The point's coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # + # @param y - value on the axis Oy + def addSegmentPerpY (self, y ): + """ + Add one straight segment, defined by perpendicular(angle=90) and intersect straight y= param y. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + The point's coordinates are defined + in a local coordinate system which origin is the last point of the sketch + + Parameters: + y - value on the axis Oy + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentPerpY(10) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":R 90:IY %s" % (printVar(y)) + pass + + + ## Add one straight segment, defined by previous direction and length. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # The length coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # + # @param length - length of the segment + def addSegmentLength (self, length ): + """ + Add one straight segment, defined by previous direction and length. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + The length coordinates are defined + in a local coordinate system which origin is the last point of the sketch + + Parameters: + length - length of the segment + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentLength(100) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":L %s" % (printVar(length)) + pass + + ## Add one straight segment, defined by previous direction and intersect straight x= param x. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # The point's coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # + # @param x - value on the axis Ox + def addSegmentX (self, x ): + """ + Add one straight segment, defined by previous direction and intersect straight x= param x. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + The point's coordinates are defined + in a local coordinate system which origin is the last point of the sketch + + Parameters: + x - value on the axis Ox + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentX(30) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":IX %s" % (printVar(x)) + pass + + ## Add one straight segment, defined by previous direction and intersect straight y= param y. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # The point's coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # + # @param y - value on the axis Oy + def addSegmentY (self, y ): + """ + Add one straight segment, defined by previous direction and intersect straight y= param y. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + The point's coordinates are defined + in a local coordinate system which origin is the last point of the sketch + + Parameters: + y - value on the axis Oy + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentY(10) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":IY %s" % (printVar(y)) + pass + + + ## Add one straight segment, defined by direction and length. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # The direction and length coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # + # @param dx, dy - direction of the segment + # @param length - length of the segment + def addSegmentDirectionLength (self, dx, dy, length ): + """ + Add one straight segment, defined by direction and length. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + The direction and length coordinates are defined + in a local coordinate system which origin is the last point of the sketch + + Parameters: + dx, dy - direction of the segment + length - length of the segment + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentDirectionLength(20, 40, 30) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":D %s %s:L %s" % (printVar(dx), printVar(dy), printVar(length)) + pass + + ## Add one straight segment, defined by direction and intersect straight x= param x. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # The direction and point's coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # + # @param dx, dy - direction of the segment + # @param x - value on the axis Ox + def addSegmentDirectionX (self, dx, dy, x ): + """ + Add one straight segment, defined by direction and intersect straight x= param x. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + The direction and point's coordinates are defined + in a local coordinate system which origin is the last point of the sketch + + Parameters: + dx, dy - direction of the segment + x - value on the axis Ox + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentDirectionX(10, -40, 20) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":D %s %s:IX %s" % (printVar(dx), printVar(dy), printVar(x)) + pass + + ## Add one straight segment, defined by direction and intersect straight y= param y. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # The direction and point's coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # + # @param dx, dy - direction of the segment + # @param y - value on the axis Oy + def addSegmentDirectionY (self, dx, dy, y ): + """ + Add one straight segment, defined by direction and intersect straight y= param y. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + The direction and point's coordinates are defined + in a local coordinate system which origin is the last point of the sketch + + Parameters: + dx, dy - direction of the segment + y - value on the axis Oy + + Example of usage: + sk = geompy.Sketcher2D() + sk.addSegmentDirectionY(-10, -50, 20) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":D %s %s:IY %s" % (printVar(dx), printVar(dy), printVar(y)) + pass + + # Commands for creation of arc + + ## Add arc, which connects the given point with previous point + # Coordinates are considered as absolute. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # + # @param x, y - Coordinates of second point of arc + def addArcAbsolute (self, x, y ): + """ + Add arc, which connects the given point with previous point + Coordinates are considered as absolute. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + + Parameters: + param x, y - Coordinates of second point of arc + + Example of usage: + sk = geompy.Sketcher2D() + sk.addArcAbsolute(50, 10) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":AA %s %s" % (printVar(x), printVar(y)) + pass + + ## Add arc, which connects the given point with previous point + # Coordinates are considered relative to the previous point. + # + # @param dx, dy - Coordinates of second point of arc relative to the previous point + def addArcRelative (self, dx, dy ): + """ + Add arc, which connects the given point with previous point + Coordinates are considered relative to the previous point. + + Parameters: + param dx, dy - Coordinates of second point of arc + + Example of usage: + sk = geompy.Sketcher2D() + sk.addArcRelative(50, 10) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":A %s %s" % (printVar(dx), printVar(dy)) + pass + + ## Add arc, defined by radius and coordinates of next point. + # Coordinates are considered as absolute. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # + # @param x, y - Coordinates of second point of arc + # @param radius - radius of arc + # @param flag - is 0 or 2 + # if 0 the drawn arc is the one of lower angle (Pi) + def addArcRadiusAbsolute (self, x, y, radius, flag ): + """ + Add arc, defined by radius and coordinates of next point. + Coordinates are considered as absolute. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + + Parameters: + param x, y - Coordinates of second point of arc + param radius - radius of arc + param flag - is 0 or 2 + if 0 the drawn arc is the one of lower angle (Pi) + + Example of usage: + sk = geompy.Sketcher2D() + sk.addArcRadiusAbsolute(50, 10, 20, 0) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":UU %s %s %s %s" % (printVar(x), printVar(y), printVar(radius), printVar(flag)) + pass + + ## Add arc, defined by radius and coordinates of next point. + # Coordinates are considered relative to the previous point. + # + # @param dx, dy - Coordinates of second point of arc + # @param radius - radius of arc + # @param flag - is 0 or 2 + # if 0 the drawn arc is the one of lower angle (Pi) + def addArcRadiusRelative (self, dx, dy, radius, flag ): + """ + Add arc, defined by radius and coordinates of next point. + Coordinates are considered relative to the previous point. + + Parameters: + param dx, dy - Coordinates of second point of arc + param radius - radius of arc + param flag - is 0 or 2 + if 0 the drawn arc is the one of lower angle (Pi) + + Example of usage: + sk = geompy.Sketcher2D() + sk.addArcRadiusRelative(-30, -15, 20, 2) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":U %s %s %s %s" % (printVar(dx), printVar(dy), printVar(radius), printVar(flag)) + pass + + ## Add arc, defined by coordinates of next point and coordinates of center. + # Coordinates are considered as absolute. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # + # @param x, y - Coordinates of second point of arc + # @param xc, yc - Coordinates of center + # @param flag1 - (reverse) is 0 or 2 + # if 0 the drawn arc is the one of lower angle (Pi) + # @param flag2 - (control tolerance) is 0 or 1 + # if 0 the specified end point can be at a distance of the arc + def addArcCenterAbsolute (self, x, y, xc, yc, flag1, flag2 ): + """ + Add arc, defined by coordinates of next point and coordinates of center. + Coordinates are considered as absolute. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + + Parameters: + param x, y - Coordinates of second point of arc + param xc, yc - Coordinates of center + param flag1 - is 0 or 2 + if 0 the drawn arc is the one of lower angle (Pi) + param flag2 - (control tolerance) is 0 or 1 + if 0 the specified end point can be at a distance of the arc + + Example of usage: + sk = geompy.Sketcher2D() + sk.addArcCenterAbsolute(-30, -15, 20, 10, 0, 0) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":EE %s %s %s %s %s %s" % (printVar(xc), printVar(yc), printVar(x), printVar(y), + printVar(flag1), printVar(flag2)) + pass + + ## Add arc, defined by coordinates of next point and coordinates of center. + # Coordinates are considered relative to the previous point. + # + # @param dx, dy - Coordinates of second point of arc + # @param xc, yc - Coordinates of center + # @param flag1 - (reverse) is 0 or 2 + # if 0 the drawn arc is the one of lower angle (Pi) + # @param flag2 - (control tolerance) is 0 or 1 + # if 0 the specified end point can be at a distance of the arc + def addArcCenterRelative (self, dx, dy, xc, yc, flag1, flag2 ): + """ + Add arc, defined by coordinates of next point and coordinates of center. + Coordinates are considered relative to the previous point. + + Parameters: + param dx, dy - Coordinates of second point of arc + param xc, yc - Coordinates of center + param flag1 - is 0 or 2 + if 0 the drawn arc is the one of lower angle (Pi) + param flag2 - (control tolerance) is 0 or 1 + if 0 the specified end point can be at a distance of the arc + + Example of usage: + sk = geompy.Sketcher2D() + sk.addArcCenterRelative(-30, -15, 20, 10, 2, 1) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":E %s %s %s %s %s %s" % (printVar(xc), printVar(yc), printVar(dx), printVar(dy), + printVar(flag1), printVar(flag2)) + pass + + ## Add arc, defined by angle, radius and length. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # + # @param angle - angle in a plane + # @param radius - radius of the arc + # @param length - length of the arc + def addArcAngleRadiusLength (self, angle, radius, length ): + """ + Add arc, defined by angle, radius and length. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + + Parameters: + param angle - angle in a plane + param radius - radius of the arc + param length - length of the arc + + Example of usage: + sk = geompy.Sketcher2D() + sk.addArcAngleRadiusLength(30, 15, 40) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":R %s:C %s %s" % (printVar(angle), printVar(radius), printVar(length)) + pass + + ## Add arc, defined by perpendicular(angle=90), radius and length. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # + # @param radius - radius of the arc + # @param length - length of the arc + def addArcPerpRadiusLength (self, radius, length ): + """ + Add arc, defined by perpendicular(angle=90), radius and length. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + + Parameters: + param radius - radius of the arc + param length - length of the arc + + Example of usage: + sk = geompy.Sketcher2D() + sk.addArcPerpRadiusLength(15, 40) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":R 90:C %s %s" % (printVar(radius), printVar(length)) + pass + + ## Add arc, defined by previous direction, radius and length. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # + # @param radius - radius of the arc + # @param length - length of the arc + def addArcRadiusLength (self, radius, length ): + """ + Add arc, defined by previous direction, radius and length. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + + Parameters: + param radius - radius of the arc + param length - length of the arc + + Example of usage: + sk = geompy.Sketcher2D() + sk.addArcRadiusLength(15, 40) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":C %s %s" % (printVar(radius), printVar(length)) + pass + + ## Add arc, defined by direction, radius and length. + # If the first point of sketcher is not yet defined, the + # origin (0, 0) will become the first sketcher point. + # + # @param dx, dy - direction of the arc + # @param radius - radius of the arc + # @param length - length of the arc + def addArcDirectionRadiusLength (self, dx, dy, radius, length ): + """ + Add arc, defined by direction, radius and length. + If the first point of sketcher is not yet defined, the + origin (0, 0) will become the first sketcher point. + + Parameters: + param dx, dy - direction of the arc + param radius - radius of the arc + param length - length of the arc + + Example of usage: + sk = geompy.Sketcher2D() + sk.addArcDirectionRadiusLength(-50, 40, 20, 3.5) + Sketcher_1 = sk.wire(geomObj_1) + """ + self.myCommand = self.myCommand + ":D %s %s:C %s %s" % (printVar(dx), printVar(dy), printVar(radius), printVar(length)) + pass + + ## Set to close the wire + def close (self): + """ + Set to close the wire + + Example of usage: + sk = geompy.Sketcher2D() + sk.addPoint(15, 85.6) + sk.close() + Sketcher_1 = sk.wire(geomObj_1) + """ + self.closed = True + pass + + ## Obtain the sketcher result as a wire. + # + # @param WorkingPlane - current Working Plane used for this 2DSketcher + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @return New GEOM_Object, containing the created wire + def wire (self, WorkingPlane=[0, 0, 0, 0, 0, 1, 1, 0, 0], theName=None): + """ + Obtain the sketcher result as a wire. + + Parameters: + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name + param WorkingPlane - current Working Plane used for this 2DSketcher + + Returns: + New GEOM_Object, containing the created wire. + + Example of usage: + sk = geompy.Sketcher2D() + sk.addPoint(30, 70) + a3D_Sketcher_1 = sk.wire(geomObj_1) + """ + + if self.closed: + self.myCommand = self.myCommand + ":WW" + + import GEOM + if isinstance(WorkingPlane, list): wire = self.geompyD.CurvesOp.MakeSketcher(self.myCommand, WorkingPlane) + if isinstance(WorkingPlane, GEOM._objref_GEOM_Object): wire = self.geompyD.CurvesOp.MakeSketcherOnPlane(self.myCommand, WorkingPlane) + + self.myCommand = "Sketcher" + self.geompyD._autoPublish(wire, theName, "wire") + return wire + + ## Obtain the sketcher result as a face. + # + # @param WorkingPlane - current Working Plane used for this 2DSketcher + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @return New GEOM_Object, containing the created face + def face (self, WorkingPlane=[0, 0, 0, 0, 0, 1, 1, 0, 0], theName=None): + """ + Obtain the sketcher result as a face. + + Parameters: + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name + param WorkingPlane - current Working Plane used for this 2DSketcher + + Returns: + New GEOM_Object, containing the created face. + + Example of usage: + sk = geompy.Sketcher2D() + sk.addPoint(0, 0) + sk.addSegment(100, 0) + sk.addSegment(100, 100) + sk.addSegment(0, 100) + sk.close() + a3D_Sketcher_1 = sk.face(geomObj_1) + """ + + if self.closed: + self.myCommand = self.myCommand + ":WF" + else: + raise RuntimeError, "Sketcher2D.close() : can't build face on unclosed wire" + + import GEOM + if isinstance(WorkingPlane, list): face = self.geompyD.CurvesOp.MakeSketcher(self.myCommand, WorkingPlane) + if isinstance(WorkingPlane, GEOM._objref_GEOM_Object): face = self.geompyD.CurvesOp.MakeSketcherOnPlane(self.myCommand, WorkingPlane) + + self.myCommand = "Sketcher" + self.geompyD._autoPublish(face, theName, "face") + return face diff --git a/src/SKETCHER/Sketcher_Profile.cxx b/src/SKETCHER/Sketcher_Profile.cxx index 32b142fcf..3fa50263e 100644 --- a/src/SKETCHER/Sketcher_Profile.cxx +++ b/src/SKETCHER/Sketcher_Profile.cxx @@ -25,13 +25,9 @@ // Author : Damien COQUERET // Module : GEOM -#include - -#include +#include "Sketcher_Profile.hxx" #include -#include -#include #include #include #include @@ -40,475 +36,1976 @@ #include #include #include -#include #include #include #include -#include -#include - #include "utilities.h" -//======================================================================= -// profile -// command to build a profile -//======================================================================= -Sketcher_Profile::Sketcher_Profile() +/*! + \class Sketcher_Profile::Functor + \brief Generic functor class to process sketcher command + \internal +*/ + +class Sketcher_Profile::Functor +{ +public: + Functor(); + virtual ~Functor(); + + virtual void init( const TCollection_AsciiString& ); + + virtual void initCommand() = 0; + virtual void addPoint( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) = 0; + virtual void addAngle( const TCollection_AsciiString& angle ) = 0; + virtual void addSegmentParalX( const TCollection_AsciiString& x ) = 0; + virtual void addSegmentParalXToZero() = 0; + virtual void addSegmentParalY( const TCollection_AsciiString& y ) = 0; + virtual void addSegmentParalYToZero() = 0; + virtual void addSegmentAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) = 0; + virtual void addSegmentRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) = 0; + virtual void addSegmentLength( const TCollection_AsciiString& length ) = 0; + virtual void addSegmentX( const TCollection_AsciiString& x, + int CurrentIndex ) = 0; + virtual void addSegmentY( const TCollection_AsciiString& y, + int CurrentIndex ) = 0; + virtual void addSegmentAngleLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& length, + int& CurrentIndex ) = 0; + virtual void addSegmentAngleX( const TCollection_AsciiString& angle, + const TCollection_AsciiString& x, + int& CurrentIndex ) = 0; + virtual void addSegmentAngleY( const TCollection_AsciiString& angle, + const TCollection_AsciiString& y, + int& CurrentIndex ) = 0; + virtual void addSegmentDirectionLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& length, + int& CurrentIndex ) = 0; + virtual void addSegmentDirectionX( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& x, + int& CurrentIndex ) = 0; + virtual void addSegmentDirectionY( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& y, + int& CurrentIndex ) = 0; + virtual void addArcAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) = 0; + virtual void addArcRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) = 0; + virtual void addArcRadiusAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ) = 0; + virtual void addArcRadiusRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ) = 0; + virtual void addArcCenterAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ) = 0; + virtual void addArcCenterRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ) = 0; + virtual void addArcRadiusLength( const TCollection_AsciiString& radius, + const TCollection_AsciiString& length ) = 0; + virtual void addArcAngleRadiusLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ) = 0; + virtual void addArcDirectionRadiusLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ) = 0; + virtual void closeWire() = 0; + virtual void closeWireAndBuildFace() = 0; + + virtual void nextCommand( int& CurrentIndex ) = 0; + virtual void makeResult() = 0; + + void setNumberOfCommand( int n ); + double error(); + bool isOk(); + +protected: + int myNumberOfCommand; + double myError; + bool myOk; +}; + +/*! + \class Sketcher_Profile::ShapeFunctor + \brief Functor that creates a shape from sketcher command + \internal +*/ + +class Sketcher_Profile::ShapeFunctor : public Functor +{ +public: + ShapeFunctor(); + + virtual void initCommand(); + virtual void addPoint( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ); + virtual void addAngle( const TCollection_AsciiString& angle ); + virtual void addSegmentParalX( const TCollection_AsciiString& x ); + virtual void addSegmentParalXToZero(); + virtual void addSegmentParalY( const TCollection_AsciiString& y ); + virtual void addSegmentParalYToZero(); + virtual void setAngle( const TCollection_AsciiString& angle ); + virtual void setDirection( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ); + virtual void addSegmentAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ); + virtual void addSegmentRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ); + virtual void addSegmentLength( const TCollection_AsciiString& length ); + virtual void addSegmentX( const TCollection_AsciiString& x, + int CurrentIndex ); + virtual void addSegmentY( const TCollection_AsciiString& y, + int CurrentIndex ); + virtual void addSegmentAngleLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& length, + int& CurrentIndex ); + virtual void addSegmentAngleX( const TCollection_AsciiString& angle, + const TCollection_AsciiString& x, + int& CurrentIndex ); + virtual void addSegmentAngleY( const TCollection_AsciiString& angle, + const TCollection_AsciiString& y, + int& CurrentIndex ); + virtual void addSegmentDirectionLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& length, + int& CurrentIndex ); + virtual void addSegmentDirectionX( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& x, + int& CurrentIndex ); + virtual void addSegmentDirectionY( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& y, + int& CurrentIndex ); + virtual void addArcAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ); + virtual void addArcRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ); + virtual void addArcRadiusAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ); + virtual void addArcRadiusRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ); + virtual void addArcCenterAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ); + virtual void addArcCenterRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ); + virtual void addArcRadiusLength( const TCollection_AsciiString& radius, + const TCollection_AsciiString& length ); + virtual void addArcAngleRadiusLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ); + virtual void addArcDirectionRadiusLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ); + virtual void closeWire(); + virtual void closeWireAndBuildFace(); + + virtual void nextCommand( int& CurrentIndex ); + virtual void makeResult(); + + TopoDS_Shape getShape(); + +private: + void setMove( int& CurrentIndex ); + +private: + Standard_Real myX0, myY0, myX, myY, myDx, myDy; + Standard_Boolean myFirst, myStayFirst, myFace, myClose; + Standard_Real myLength, myRadius, myAngle; + + enum {line, circle, point, none} myMove; + + TopLoc_Location TheLocation; // ????????? + gp_Pln myPlane; + TopoDS_Vertex myVertex; + BRepBuilderAPI_MakeWire myMakeWire; + + TopoDS_Shape myShape; +}; + +/*! + \class Sketcher_Profile::ShapeFunctor + \brief Functor that generates a Python script from sketcher command + \internal +*/ + +class Sketcher_Profile::DumpFunctor : public Functor +{ +public: + DumpFunctor(); + + virtual void init( const TCollection_AsciiString& ); + + virtual void initCommand(); + virtual void addPoint( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ); + virtual void addAngle( const TCollection_AsciiString& angle ); + virtual void addSegmentParalX( const TCollection_AsciiString& x ); + virtual void addSegmentParalXToZero(); + virtual void addSegmentParalY( const TCollection_AsciiString& y ); + virtual void addSegmentParalYToZero(); + virtual void addSegmentAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ); + virtual void addSegmentRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ); + virtual void addSegmentLength( const TCollection_AsciiString& length ); + virtual void addSegmentX( const TCollection_AsciiString& x, + int CurrentIndex ); + virtual void addSegmentY( const TCollection_AsciiString& y, + int CurrentIndex ); + virtual void addSegmentAngleLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& length, + int& CurrentIndex ); + virtual void addSegmentAngleX( const TCollection_AsciiString& angle, + const TCollection_AsciiString& x, + int& CurrentIndex ); + virtual void addSegmentAngleY( const TCollection_AsciiString& angle, + const TCollection_AsciiString& y, + int& CurrentIndex ); + virtual void addSegmentDirectionLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& length, + int& CurrentIndex ); + virtual void addSegmentDirectionX( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& x, + int& CurrentIndex ); + virtual void addSegmentDirectionY( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& y, + int& CurrentIndex ); + virtual void addArcAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ); + virtual void addArcRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ); + virtual void addArcRadiusAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ); + virtual void addArcRadiusRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ); + virtual void addArcCenterAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ); + virtual void addArcCenterRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ); + virtual void addArcRadiusLength( const TCollection_AsciiString& radius, + const TCollection_AsciiString& length ); + virtual void addArcAngleRadiusLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ); + virtual void addArcDirectionRadiusLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ); + virtual void closeWire(); + virtual void closeWireAndBuildFace(); + + virtual void nextCommand( int& CurrentIndex ); + virtual void makeResult(); + + TCollection_AsciiString getDescription(); + +private: + TCollection_AsciiString myDescr; + TCollection_AsciiString mySketcherEntry; + TCollection_AsciiString myWPEntry; + TCollection_AsciiString myTail; + Standard_Boolean myFace; +}; + +//=========================================================================== +// Sketcher_Profile::Functor +//=========================================================================== + +/*! + \brief Constructor + \internal +*/ +Sketcher_Profile::Functor::Functor() : myError( 0 ), myNumberOfCommand( 0 ), myOk( true ) { } +/*! + \brief Destructor + \internal +*/ +Sketcher_Profile::Functor::~Functor() +{ +} -//======================================================================= -// profile -// command to build a profile -//======================================================================= -Sketcher_Profile::Sketcher_Profile(const char* aCmd) -{ - enum {line, circle, point, none} move; - - Standard_Integer i = 1; - Standard_Real x0, y0, x, y, dx, dy; - x0 = y0 = x = y = dy = 0; - dx = 1; - - Standard_Boolean first, stayfirst, face, close; - first = Standard_True; - stayfirst = face = close = Standard_False; - - Standard_Integer reversed = 0; - Standard_Integer control_Tolerance = 0; - - TopoDS_Shape S; - TopoDS_Vertex MP; - BRepBuilderAPI_MakeWire MW; - gp_Ax3 DummyHP(gp::XOY()); - gp_Pln P(DummyHP); - TopLoc_Location TheLocation; - Handle(Geom_Surface) Surface; - - myOK = Standard_False; - myError = 0; - - //TCollection_AsciiString aCommand(CORBA::string_dup(aCmd)); - TCollection_AsciiString aCommand ((char*)aCmd); - TCollection_AsciiString aToken = aCommand.Token(":", 1); - int n = 0; - // porting to WNT - TColStd_Array1OfAsciiString aTab (0, aCommand.Length() - 1); - if ( aCommand.Length() ) - { - while(aToken.Length() != 0) { - if(aCommand.Token(":", n + 1).Length() > 0) - aTab(n) = aCommand.Token(":", n + 1); - aToken = aCommand.Token(":", ++n); +/*! + \brief Initialize functor from the script + \param command sketcher command being parsed + \internal +*/ +void Sketcher_Profile::Functor::init( const TCollection_AsciiString& /*command*/ ) +{ +} + +/*! + \brief Set total number of sketcher operators + \param n total number of sketcher operators + \internal +*/ +void Sketcher_Profile::Functor::setNumberOfCommand( int n ) +{ + myNumberOfCommand = n; +} + +/*! + \brief Get error (numerical value that describes, e.g. a deviation of point from the specified arc) + \return numerical error + \internal +*/ +double Sketcher_Profile::Functor::error() +{ + return myError; +} + +/*! + \brief Get result of parsing + \return \c true if parsing is successful or \c false otherwise + \internal +*/ +bool Sketcher_Profile::Functor::isOk() +{ + return myOk; +} + +//=========================================================================== +// Sketcher_Profile::ShapeFunctor +//=========================================================================== + +/*! + \brief Constructor + \internal +*/ +Sketcher_Profile::ShapeFunctor::ShapeFunctor() : Functor() +{ + myX0 = myY0 = 0; + myX = myY = 0; + myDy = 0; + myDx = 1; + + myFirst = Standard_True; + myStayFirst = myFace = myClose = Standard_False; + + myLength = myRadius = myAngle = 0; + + myMove = point; + + myPlane = gp_Pln( gp_Ax3( gp::XOY() ) ); +} + +/*! + \brief Prepare functor for processing of new sketcher operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::initCommand() +{ + myLength = myRadius = myAngle = 0; + myMove = point; +} + +/*! + \brief Add point with absolute coordinates (\a x, \a y) + \param x X coordinate + \param y Y coordinate + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addPoint( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) +{ + if ( !myFirst ) { + MESSAGE("profile : The addPoint instruction must precede all moves"); + return; + } + myX0 = myX = x.RealValue(); + myY0 = myY = y.RealValue(); + myStayFirst = Standard_True; +} + +/*! + \brief Add angle + \param angle angle + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addAngle( const TCollection_AsciiString& angle ) +{ + myAngle = angle.RealValue() * M_PI / 180.; + myDx = Cos( myAngle ); + myDy = Sin( myAngle ); +} + +/*! + \brief Add new segment of \a x length along X axis + \param x length of segment + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentParalX( const TCollection_AsciiString& x ) +{ + myLength = x.RealValue(); + myDx = 1; + myDy = 0; + myMove = line; +} + +/*! + \brief Add new segment along X axis with X coordinate of end set to 0 + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentParalXToZero() +{ + myLength -= myX; + myDx = 1; + myDy = 0; + myMove = line; +} + +/*! + \brief Add new segment of \a y length along Y axis + \param y length of segment + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentParalY( const TCollection_AsciiString& y ) +{ + myLength = y.RealValue(); + myDx = 0; + myDy = 1; + myMove = line; +} + +/*! + \brief Add new segment along Y axis with Y coordinate of end set to 0 + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentParalYToZero() +{ + myLength -= myY; + myDx = 0; + myDy = 1; + myMove = line; +} + +/*! + \brief Set current angle + \param angle current working angle + \internal +*/ +void Sketcher_Profile::ShapeFunctor::setAngle( const TCollection_AsciiString& angle ) +{ + myAngle = angle.RealValue(); + Standard_Real alpha = myAngle * M_PI / 180.; + Standard_Real c = Cos( alpha ); + Standard_Real s = Sin( alpha ); + Standard_Real t = c * myDx - s * myDy; + myDy = s * myDx + c * myDy; + myDx = t; +} + +/*! + \brief Set current direction + \param dx X component of direction vector + \param dy Y component of direction vector + \internal +*/ +void Sketcher_Profile::ShapeFunctor::setDirection( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) +{ + Standard_Real vx = dx.RealValue(); + Standard_Real vy = dy.RealValue(); + myLength = Sqrt( vx * vx + vy * vy ); + if ( myLength > Precision::Confusion() ) { + myDx = vx / myLength; + myDy = vy / myLength; + } + else + myMove = none; +} + +/*! + \brief Add segment by absolute coordinates + \param x X coordinate of segment end + \param y Y coordinate of segment end + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) +{ + Standard_Real vx = x.RealValue() - myX; + Standard_Real vy = y.RealValue() - myY; + myLength = Sqrt( vx * vx + vy * vy ); + if ( myLength > Precision::Confusion() ) { + myMove = line; + myDx = vx / myLength; + myDy = vy / myLength; + } + else + myMove = none; +} + +/*! + \brief Add segment by relativ coordinates + \param dx dX value specifing segment end + \param dy dY value specifing segment end + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) +{ + Standard_Real vx = dx.RealValue(); + Standard_Real vy = dy.RealValue(); + myLength = Sqrt( vx * vx + vy * vy ); + if ( myLength > Precision::Confusion() ) { + myMove = line; + myDx = vx / myLength; + myDy = vy / myLength; + } + else + myMove = none; +} + +/*! + \brief Add segment with specified length along current direction + \param length segment length + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentLength( const TCollection_AsciiString& length ) +{ + myLength = length.RealValue(); + if ( Abs( myLength ) > Precision::Confusion() ) + myMove = line; + else + myMove = none; +} + +/*! + \brief Add segment along X axis to reach specified X coordinate + \param x X coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentX( const TCollection_AsciiString& x, + int CurrentIndex ) +{ + myLength = x.RealValue(); + if ( Abs( myDx ) < Precision::Confusion() ) { + MESSAGE("profile : cannot intersect, arg "< Precision::Confusion() ) + myMove = line; + else + myMove = none; +} + +/*! + \brief Add segment along Y axis to reach specified Y coordinate + \param y Y coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentY( const TCollection_AsciiString& y, + int CurrentIndex ) +{ + myLength = y.RealValue(); + if ( Abs( myDy ) < Precision::Confusion() ) { + MESSAGE("profile : cannot intersect, arg "< Precision::Confusion() ) + myMove = line; + else + myMove = none; +} + +/*! + \brief Add segment by specified angle and length + \param angle angle that specifies segment direction + \param length segment length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentAngleLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& length, + int& CurrentIndex ) +{ + setAngle( angle ); + setMove( CurrentIndex ); + addSegmentLength( length ); +} + +/*! + \brief Add segment that crosses Y axis by specified angle and X coordinate + \param angle angle that specifies segment direction + \param x X coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentAngleX( const TCollection_AsciiString& angle, + const TCollection_AsciiString& x, + int& CurrentIndex ) +{ + setAngle( angle ); + setMove( CurrentIndex ); + addSegmentX( x, CurrentIndex ); +} + +/*! + \brief Add segment that crosses X axis by specified angle and Y coordinate + \param angle angle that specifies segment direction + \param y Y coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentAngleY( const TCollection_AsciiString& angle, + const TCollection_AsciiString& y, + int& CurrentIndex ) +{ + setAngle( angle ); + setMove( CurrentIndex ); + addSegmentY( y, CurrentIndex ); +} + +/*! + \brief Add segment by specified direction and length + \param dx X component of direction vector + \param dx Y component of direction vector + \param length segment length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentDirectionLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& length, + int& CurrentIndex ) +{ + setDirection( dx, dy ); + setMove( CurrentIndex ); + addSegmentLength( length ); +} + +/*! + \brief Add segment by specified direction and X coordinate + \param dx X component of direction vector + \param dx Y component of direction vector + \param x X coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentDirectionX( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& x, + int& CurrentIndex ) +{ + setDirection( dx, dy ); + setMove( CurrentIndex ); + addSegmentX( x, CurrentIndex ); +} + +/*! + \brief Add segment by specified direction and Y coordinate + \param dx X component of direction vector + \param dx Y component of direction vector + \param y Y coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addSegmentDirectionY( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& y, + int& CurrentIndex ) +{ + setDirection( dx, dy ); + setMove( CurrentIndex ); + addSegmentY( y, CurrentIndex ); +} + +/*! + \brief Add arc along current direction vector by specified absolute coordinates + \param x X coordinate of arc end + \param x Y coordinate of arc end + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) +{ + Standard_Real vx = x.RealValue() - myX; + Standard_Real vy = y.RealValue() - myY; + Standard_Real det = myDx * vy - myDy * vx; + Standard_Real c = Sqrt( ( myDx * myDx + myDy * myDy ) * ( vx * vx + vy * vy ) ); + if ( Abs( det ) > Precision::Confusion() && Abs( c ) > Precision::Confusion() ) { + // Cosine of alpha = arc of angle / 2 , alpha in [0,Pi] + c = ( myDx * vx + myDy * vy ) / c; + // radius = distance between start and end point / 2 * sin(alpha) + // radius is > 0 or < 0 + myRadius = ( vx * vx + vy * vy )* Sqrt( myDx * myDx + myDy * myDy ) / ( 2.0 * det ); + if ( Abs( myRadius ) > Precision::Confusion() ) { + myAngle = 2.0 * acos( c ); // angle in [0,2Pi] + myMove = circle; } - n = n - 1; - } - if ( aTab.Length() && aTab(0).Length() ) - while(i < n) { - Standard_Real length = 0, radius = 0, angle = 0; - move = point; - - int n1 = 0; - TColStd_Array1OfAsciiString a (0, aTab(0).Length()); - aToken = aTab(i).Token(" ", 1); - while (aToken.Length() != 0) { - if (aTab(i).Token(" ", n1 + 1).Length() > 0) - a(n1) = aTab(i).Token(" ", n1 + 1); - aToken = aTab(i).Token(" ", ++n1); - } - n1 = n1 - 1; - - switch(a(0).Value(1)) - { - case 'F': - { - if (n1 != 3) goto badargs; - if (!first) { - MESSAGE("profile : The F instruction must precede all moves"); - return; - } - x0 = x = a(1).RealValue(); - y0 = y = a(2).RealValue(); - stayfirst = Standard_True; - break; - } - case 'O': - { - if (n1 != 4) goto badargs; - P.SetLocation(gp_Pnt(a(1).RealValue(), a(2).RealValue(), a(3).RealValue())); - stayfirst = Standard_True; - break; - } - case 'P': - { - if (n1 != 7) goto badargs; - gp_Vec vn(a(1).RealValue(), a(2).RealValue(), a(3).RealValue()); - gp_Vec vx(a(4).RealValue(), a(5).RealValue(), a(6).RealValue()); - if (vn.Magnitude() <= Precision::Confusion() || vx.Magnitude() <= Precision::Confusion()) { - MESSAGE("profile : null direction"); - return; - } - gp_Ax2 ax(P.Location(), vn, vx); - P.SetPosition(ax); - stayfirst = Standard_True; - break; - } - case 'X': - { - if (n1 != 2) goto badargs; - length = a(1).RealValue(); - if (a(0) == "XX") - length -= x; - dx = 1; dy = 0; - move = line; - break; - } - case 'Y': - { - if (n1 != 2) goto badargs; - length = a(1).RealValue(); - if (a(0) == "YY") - length -= y; - dx = 0; dy = 1; - move = line; - break; - } - case 'L': - { - if (n1 != 2) goto badargs; - length = a(1).RealValue(); - if (Abs(length) > Precision::Confusion()) - move = line; - else - move = none; - break; - } - case 'T': - { - if (n1 != 3) goto badargs; - Standard_Real vx = a(1).RealValue(); - Standard_Real vy = a(2).RealValue(); - if (a(0) == "TT") { - vx -= x; - vy -= y; - } - length = Sqrt(vx * vx + vy * vy); - if (length > Precision::Confusion()) { - move = line; - dx = vx / length; - dy = vy / length; - } - else - move = none; - break; - } - case 'R': - { - if (n1 != 2) goto badargs; - angle = a(1).RealValue() * M_PI / 180.; - if (a(0) == "RR") { - dx = Cos(angle); - dy = Sin(angle); - } - else { - Standard_Real c = Cos(angle); - Standard_Real s = Sin(angle); - Standard_Real t = c * dx - s * dy; - dy = s * dx + c * dy; - dx = t; - } - break; - } - case 'D': - { - if (n1 != 3) goto badargs; - Standard_Real vx = a(1).RealValue(); - Standard_Real vy = a(2).RealValue(); - length = Sqrt(vx * vx + vy * vy); - if (length > Precision::Confusion()) { - dx = vx / length; - dy = vy / length; - } - else - move = none; - break; - } - case 'C': - { - if (n1 != 3) goto badargs; - radius = a(1).RealValue(); - if (Abs(radius) > Precision::Confusion()) { - angle = a(2).RealValue() * M_PI / 180.; - move = circle; - } - else - move = none; - break; - } - case 'A': // TAngential arc by end point - { - if (n1 != 3) goto badargs; - Standard_Real vx = a(1).RealValue(); - Standard_Real vy = a(2).RealValue(); - if (a(0) == "AA") { - vx -= x; - vy -= y; - } - Standard_Real det = dx * vy - dy * vx; - if ( Abs(det) > Precision::Confusion()) { - // Cosine of alpha = arc of angle / 2 , alpha in [0,Pi] - Standard_Real c = (dx * vx + dy * vy) / Sqrt((dx * dx + dy * dy) * (vx * vx + vy * vy)); - // radius = distance between start and end point / 2 * sin(alpha) - // radius is > 0 or < 0 - radius = (vx * vx + vy * vy)* Sqrt(dx * dx + dy * dy) / (2.0 * det); - if (Abs(radius) > Precision::Confusion()) { - angle = 2.0 * acos(c); // angle in [0,2Pi] - move = circle; - } - else - move = none; - break; - } - else - move = none; - break; - } - case 'U': // Arc by end point and radiUs - { - if (n1 != 5) goto badargs; - Standard_Real vx = a(1).RealValue(); - Standard_Real vy = a(2).RealValue(); - radius = a(3).RealValue(); - reversed = a(4).IntegerValue(); - if (a(0) == "UU") { // Absolute - vx -= x; - vy -= y; - } - Standard_Real length = Sqrt(vx * vx + vy * vy); - if ( (4.0 - (vx * vx + vy * vy) / (radius * radius) >= 0.0 ) && (length > Precision::Confusion()) ) { - // Cosine of alpha = arc angle / 2 , alpha in [0,Pi/2] - Standard_Real c = 0.5 * Sqrt(4.0 - (vx * vx + vy * vy) / (radius * radius)); - angle = 2.0 * acos(c); // angle in [0,Pi] - if ( reversed == 2 ) - angle = angle - 2 * M_PI; - dx = 0.5 * ( vy * 1.0/radius - + vx * Sqrt(4.0 / (vx * vx + vy * vy) - 1.0 / (radius * radius))); - dy = - 0.5 * ( vx * 1.0/radius - - vy * Sqrt(4.0 / (vx * vx + vy * vy) - 1.0 / (radius * radius))); - move = circle; - } - else{ - move = none; - } - break; - } - case 'E': // Arc by end point and cEnter - { - if (n1 != 7) goto badargs; - Standard_Real vx = a(1).RealValue(); - Standard_Real vy = a(2).RealValue(); - Standard_Real vxc = a(3).RealValue(); - Standard_Real vyc = a(4).RealValue(); - reversed = a(5).IntegerValue(); - control_Tolerance = a(6).IntegerValue(); - - if (a(0) == "EE") { // Absolute - vx -= x; - vy -= y; - vxc -= x; - vyc -= y; - } - radius = Sqrt( vxc * vxc + vyc * vyc ); - Standard_Real det = vx * vyc - vy * vxc; - Standard_Real length = Sqrt(vx * vx + vy * vy); - Standard_Real length2 = Sqrt((vx-vxc) * (vx-vxc) + (vy-vyc) * (vy-vyc)); - Standard_Real length3 = Sqrt(vxc * vxc + vyc * vyc); - Standard_Real error = Abs(length2 - radius); - myError = error; - if ( error > Precision::Confusion() ){ - MESSAGE("Warning : The specified end point is not on the Arc, distance = "< Precision::Confusion() && control_Tolerance == 1) // Don't create the arc if the end point - move = none; // is too far from it - else if ( (length > Precision::Confusion()) && - (length2 > Precision::Confusion()) && - (length3 > Precision::Confusion()) ) { - Standard_Real c = ( radius * radius - (vx * vxc + vy * vyc) ) - / ( radius * Sqrt((vx-vxc) * (vx-vxc) + (vy-vyc) * (vy-vyc)) ) ; // Cosine of arc angle - angle = acos(c); // angle in [0,Pi] - if ( reversed == 2 ) - angle = angle - 2 * M_PI; - if (det < 0) - angle = -angle; - dx = vyc / radius; - dy = -vxc / radius; - move = circle; - } - else { - move = none; - } - break; - } - case 'I': - { - if (n1 != 2) goto badargs; - length = a(1).RealValue(); - if (a(0) == "IX") { - if (Abs(dx) < Precision::Confusion()) { - MESSAGE("profile : cannot intersect, arg "< Precision::Confusion()) - move = line; - else - move = none; - break; - } - case 'W': - { - if (a(0) == "WW") - close = Standard_True; - else if(a(0) == "WF") { - close = Standard_True; - face = Standard_True; - } - i = n - 1; - break; - } - default: - { - MESSAGE("profile : unknown code " << a(i)); - return; - } + else + myMove = none; + } + else + myMove = none; +} + +/*! + \brief Add arc along current direction vector by specified relative coordinates + \param dx dX value specifing arc end + \param dy dY value specifing arc end + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) +{ + Standard_Real vx = dx.RealValue(); + Standard_Real vy = dy.RealValue(); + Standard_Real det = myDx * vy - myDy * vx; + Standard_Real c = Sqrt( ( myDx * myDx + myDy * myDy ) * ( vx * vx + vy * vy ) ); + if ( Abs( det ) > Precision::Confusion() && Abs( c ) > Precision::Confusion() ) { + // Cosine of alpha = arc of angle / 2 , alpha in [0,Pi] + c = ( myDx * vx + myDy * vy ) / c; + // radius = distance between start and end point / 2 * sin(alpha) + // radius is > 0 or < 0 + myRadius = ( vx * vx + vy * vy )* Sqrt( myDx * myDx + myDy * myDy ) / ( 2.0 * det ); + if ( Abs( myRadius ) > Precision::Confusion() ) { + myAngle = 2.0 * acos(c); // angle in [0,2Pi] + myMove = circle; } + else + myMove = none; + } + else + myMove = none; +} -again : - switch (move) +/*! + \brief Add arc with given radius by specified absolute coordinates + \param x X coordinate of arc end + \param x Y coordinate of arc end + \param radius arc radius + \param flag reverse direction flag + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcRadiusAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ) +{ + Standard_Real vx = x.RealValue() - myX; + Standard_Real vy = y.RealValue() - myY; + myRadius = radius.RealValue(); + int reversed = flag.IntegerValue(); + Standard_Real length = Sqrt( vx * vx + vy * vy ); + if ( Abs( myRadius ) > Precision::Confusion() && + ( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) >= 0.0 ) && ( length > Precision::Confusion() ) ) { + // Cosine of alpha = arc angle / 2 , alpha in [0,Pi/2] + Standard_Real c = 0.5 * Sqrt( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) ); + myAngle = 2.0 * acos( c ); // angle in [0,Pi] + if ( reversed == 2 ) + myAngle = myAngle - 2 * M_PI; + myDx = 0.5 * ( vy * 1.0 / myRadius + + vx * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) ); + myDy = -0.5 * ( vx * 1.0 / myRadius + - vy * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) ); + myMove = circle; + } + else { + myMove = none; + } +} + +/*! + \brief Add arc with given radius by specified relative coordinates + \param dx dX value specifing arc end + \param dy dY value specifing arc end + \param radius arc radius + \param flag reverse direction flag + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcRadiusRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ) +{ + Standard_Real vx = dx.RealValue(); + Standard_Real vy = dy.RealValue(); + myRadius = radius.RealValue(); + int reversed = flag.IntegerValue(); + Standard_Real length = Sqrt( vx * vx + vy * vy ); + if ( Abs( myRadius ) > Precision::Confusion() && + ( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) >= 0.0 ) && ( length > Precision::Confusion() ) ) { + // Cosine of alpha = arc angle / 2 , alpha in [0,Pi/2] + Standard_Real c = 0.5 * Sqrt( 4.0 - ( vx * vx + vy * vy ) / ( myRadius * myRadius ) ); + myAngle = 2.0 * acos( c ); // angle in [0,Pi] + if ( reversed == 2 ) + myAngle = myAngle - 2 * M_PI; + myDx = 0.5 * ( vy * 1.0 / myRadius + + vx * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) ); + myDy = -0.5 * ( vx * 1.0 / myRadius + - vy * Sqrt( 4.0 / ( vx * vx + vy * vy ) - 1.0 / ( myRadius * myRadius ) ) ); + myMove = circle; + } + else { + myMove = none; + } +} + +/*! + \brief Add arc with given center by specified absolute coordinates + \param x X coordinate of arc end + \param x Y coordinate of arc end + \param xc X coordinate of arc center + \param yc Y coordinate of arc center + \param flag1 reverse direction flag + \param flag2 tolerance + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcCenterAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ) +{ + Standard_Real vx = x.RealValue() - myX; + Standard_Real vy = y.RealValue() - myY; + Standard_Real vxc = xc.RealValue() - myX; + Standard_Real vyc = yc.RealValue() - myY; + int reversed = flag1.IntegerValue(); + int control_Tolerance = flag2.IntegerValue(); + + myRadius = Sqrt( vxc * vxc + vyc * vyc ); + Standard_Real det = vx * vyc - vy * vxc; + Standard_Real length = Sqrt( vx * vx + vy * vy ); + Standard_Real length2 = Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) ); + Standard_Real length3 = Sqrt( vxc * vxc + vyc * vyc ); + Standard_Real error = Abs( length2 - myRadius ); + myError = error; + if ( error > Precision::Confusion() ) { + MESSAGE("Warning : The specified end point is not on the Arc, distance = "< Precision::Confusion() && control_Tolerance == 1 ) // Don't create the arc if the end point + myMove = none; // is too far from it + else if ( ( length > Precision::Confusion() ) && + ( length2 > Precision::Confusion() ) && + ( length3 > Precision::Confusion() ) ) { + Standard_Real c = ( myRadius * myRadius - ( vx * vxc + vy * vyc ) ) + / ( myRadius * Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) ) ) ; // Cosine of arc angle + myAngle = acos(c); // angle in [0,Pi] + if ( reversed == 2 ) + myAngle = myAngle - 2 * M_PI; + if ( det < 0 ) + myAngle = -myAngle; + myDx = vyc / myRadius; + myDy = -vxc / myRadius; + myMove = circle; + } + else { + myMove = none; + } +} + +/*! + \brief Add arc with given center by specified relative coordinates + \param dx dX value specifing arc end + \param dy dY value specifing arc end + \param xc X coordinate of arc center + \param yc Y coordinate of arc center + \param flag1 reverse direction flag + \param flag2 tolerance + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcCenterRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ) +{ + Standard_Real vx = dx.RealValue(); + Standard_Real vy = dy.RealValue(); + Standard_Real vxc = xc.RealValue(); + Standard_Real vyc = yc.RealValue(); + int reversed = flag1.IntegerValue(); + int control_Tolerance = flag2.IntegerValue(); + myRadius = Sqrt( vxc * vxc + vyc * vyc ); + Standard_Real det = vx * vyc - vy * vxc; + Standard_Real length = Sqrt( vx * vx + vy * vy ); + Standard_Real length2 = Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) ); + Standard_Real length3 = Sqrt( vxc * vxc + vyc * vyc ); + Standard_Real error = Abs( length2 - myRadius ); + myError = error; + if ( error > Precision::Confusion() ) { + MESSAGE("Warning : The specified end point is not on the Arc, distance = "< Precision::Confusion() && control_Tolerance == 1 ) // Don't create the arc if the end point + myMove = none; // is too far from it + else if ( ( length > Precision::Confusion() ) && + ( length2 > Precision::Confusion() ) && + ( length3 > Precision::Confusion() ) ) { + Standard_Real c = ( myRadius * myRadius - ( vx * vxc + vy * vyc ) ) + / ( myRadius * Sqrt( ( vx - vxc ) * ( vx - vxc ) + ( vy - vyc ) * ( vy - vyc ) ) ) ; // Cosine of arc angle + myAngle = acos( c ); // angle in [0,Pi] + if ( reversed == 2 ) + myAngle = myAngle - 2 * M_PI; + if ( det < 0 ) + myAngle = -myAngle; + myDx = vyc / myRadius; + myDy = -vxc / myRadius; + myMove = circle; + } + else { + myMove = none; + } +} + +/*! + \brief Add arc with given radius by specified length + \param radius arc radius + \param length arc length + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcRadiusLength( const TCollection_AsciiString& radius, + const TCollection_AsciiString& length ) +{ + myRadius = radius.RealValue(); + if ( Abs( myRadius ) > Precision::Confusion() ) { + myAngle = length.RealValue() * M_PI / 180.; + myMove = circle; + } + else + myMove = none; +} + +/*! + \brief Add arc with given radius by specified angle and length + \param angle angle between arc start tangent and current direction + \param radius arc radius + \param length arc length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcAngleRadiusLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ) +{ + setAngle( angle ); + setMove( CurrentIndex ); + addArcRadiusLength( radius, length ); +} + +/*! + \brief Add arc with given radius by specified direction and length + \param dx X component of direction vector + \param dx Y component of direction vector + \param radius arc radius + \param length arc length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::addArcDirectionRadiusLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ) +{ + setDirection( dx, dy ); + setMove( CurrentIndex ); + addArcRadiusLength( radius, length ); +} + +/*! + \brief Close wire + \internal +*/ +void Sketcher_Profile::ShapeFunctor::closeWire() +{ + myClose = Standard_True; +} + +/*! + \brief Close wire and build face + \internal +*/ +void Sketcher_Profile::ShapeFunctor::closeWireAndBuildFace() +{ + myClose = Standard_True; + myFace = Standard_True; +} + +/*! + \brief Set internal parameters according to the current operator type + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::setMove( int& CurrentIndex ) +{ + switch ( myMove ) + { + case line : { - case line : - { - if (length < 0) { - length = -length; - dx = -dx; - dy = -dy; - } - Handle(Geom2d_Line) l = new Geom2d_Line(gp_Pnt2d(x,y),gp_Dir2d(dx,dy)); - BRepBuilderAPI_MakeEdge ME (GeomAPI::To3d(l,P),0,length); - if (!ME.IsDone()) - return; - MW.Add(ME); - x += length*dx; - y += length*dy; - break; - } - case circle : - { - Standard_Boolean sense = Standard_True; - if (radius < 0) { - radius = -radius; - sense = !sense; - dx = -dx; - dy = -dy; - } - gp_Ax2d ax(gp_Pnt2d(x-radius*dy,y+radius*dx),gp_Dir2d(dy,-dx)); - if (angle < 0) { - angle = -angle; - sense = !sense; - } - Handle(Geom2d_Circle) c = new Geom2d_Circle(ax,radius,sense); - BRepBuilderAPI_MakeEdge ME (GeomAPI::To3d(c,P),0,angle); - if (!ME.IsDone()) - return; - MW.Add(ME); - gp_Pnt2d p; - gp_Vec2d v; - c->D1(angle,p,v); - x = p.X(); - y = p.Y(); - dx = v.X() / radius; - dy = v.Y() / radius; - break; + if ( myLength < 0 ) { + myLength = -myLength; + myDx = -myDx; + myDy = -myDy; } - case point: - { - MP = BRepBuilderAPI_MakeVertex(gp_Pnt(x, y, 0.0)); - break; + Handle(Geom2d_Line) l = new Geom2d_Line( gp_Pnt2d( myX, myY ),gp_Dir2d( myDx, myDy ) ); + BRepBuilderAPI_MakeEdge ME( GeomAPI::To3d( l, myPlane ), 0, myLength ); + if ( !ME.IsDone() ) + return; + myMakeWire.Add( ME ); + myX += myLength * myDx; + myY += myLength * myDy; + break; + } + case circle : + { + Standard_Boolean sense = Standard_True; + if ( myRadius < 0 ) { + myRadius = -myRadius; + sense = !sense; + myDx = -myDx; + myDy = -myDy; } - case none: - { - i = n - 1; - break; + gp_Ax2d ax( gp_Pnt2d( myX - myRadius * myDy, myY + myRadius * myDx ), gp_Dir2d( myDy, -myDx ) ); + if ( myAngle < 0 ) { + myAngle = -myAngle; + sense = !sense; } + Handle(Geom2d_Circle) c = new Geom2d_Circle( ax, myRadius, sense ); + BRepBuilderAPI_MakeEdge ME( GeomAPI::To3d( c, myPlane ), 0, myAngle ); + if ( !ME.IsDone() ) + return; + myMakeWire.Add( ME ); + gp_Pnt2d p; + gp_Vec2d v; + c->D1( myAngle, p, v ); + myX = p.X(); + myY = p.Y(); + myDx = v.X() / myRadius; + myDy = v.Y() / myRadius; + break; + } + case point: + { + myVertex = BRepBuilderAPI_MakeVertex( gp_Pnt( myX, myY, 0.0 ) ); + break; + } + case none: + { + CurrentIndex = myNumberOfCommand - 1; + break; } + } +} - // update first - first = stayfirst; - stayfirst = Standard_False; +/*! + \brief Complete parsing of current operator + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::ShapeFunctor::nextCommand( int& CurrentIndex ) +{ + setMove( CurrentIndex ); + CurrentIndex ++; + // update first + myFirst = myStayFirst; + myStayFirst = Standard_False; - if(!(dx == 0 && dy == 0)) - myLastDir.SetCoord(dx, dy, 0.0); - else - return; - myLastPoint.SetX(x); - myLastPoint.SetY(y); - - // next segment.... - i++; - if ((i == n) && close) { - // the closing segment - dx = x0 - x; - dy = y0 - y; - length = Sqrt(dx * dx + dy * dy); - move = line; - if (length > Precision::Confusion()) { - dx = dx / length; - dy = dy / length; - goto again; - } + // next segment.... + if ( ( CurrentIndex == myNumberOfCommand ) && myClose ) { + // the closing segment + myDx = myX0 - myX; + myDy = myY0 - myY; + myLength = Sqrt( myDx * myDx + myDy * myDy ); + myMove = line; + if ( myLength > Precision::Confusion() ) { + myDx = myDx / myLength; + myDy = myDy / myLength; + setMove( CurrentIndex ); } } +} +/*! + \brief Finish parsing and create result + \internal +*/ +void Sketcher_Profile::ShapeFunctor::makeResult() +{ // get the result, face or wire - if (move == none) { + if ( myMove == none ) { + myOk = false; return; - } else if (move == point) { - S = MP; - } else if (face) { - if (!MW.IsDone()) { + } + else if ( myMove == point ) { + myShape = myVertex; + } + else if ( myFace ) { + if ( !myMakeWire.IsDone() ) { + myOk = false; return; } - BRepBuilderAPI_MakeFace MF (P, MW.Wire()); - if (!MF.IsDone()) { + BRepBuilderAPI_MakeFace MF ( myPlane, myMakeWire.Wire() ); + if ( !MF.IsDone() ) { + myOk = false; return; } - S = MF; - } else { - if (!MW.IsDone()) { + myShape = MF; + } + else { + if ( !myMakeWire.IsDone() ) { + myOk = false; return; } - S = MW; + myShape = myMakeWire.Shape(); + } + + if ( !TheLocation.IsIdentity() ) + myShape.Move( TheLocation ); +} + +/*! + \brief Get resulting shape + \return shape resulting from parsing of sketcher command + \internal +*/ +TopoDS_Shape Sketcher_Profile::ShapeFunctor::getShape() +{ + return myShape; +} + +//=========================================================================== +// Sketcher_Profile::DumpFunctor +//=========================================================================== + +/*! + \brief Constructor + \internal +*/ +Sketcher_Profile::DumpFunctor::DumpFunctor() +{ + myFace = Standard_False; +} + +/*! + \brief Initialize functor from the script + \param command sketcher command being parsed + \internal +*/ +void Sketcher_Profile::DumpFunctor::init( const TCollection_AsciiString& command ) +{ + // parse only first line of the script + TCollection_AsciiString aSubStr = command.Token( "\n\t" ); + if ( aSubStr.Length() < command.Length() ) + myTail = command.SubString( aSubStr.Length()+1, command.Length() ); + // get sketch entry + mySketcherEntry = aSubStr.Token( " =" ); + // Using this Working Plane for Sketcher + myWPEntry = myWPEntry + "[" + aSubStr.Token( "[]", 2 ) + "]"; + // Using this Working Plane for SketcherOnPlane + if ( aSubStr.Search( "MakeSketcherOnPlane" ) != -1 ) { + myWPEntry = aSubStr.Token( ",)", 2 ); + myWPEntry.RemoveAll( ' ' ); } + myDescr += "sk = geompy.Sketcher2D()"; +} + +/*! + \brief Prepare functor for processing of new sketcher operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::initCommand() +{ + myDescr += "\n\t"; +} + +/*! + \brief Add point with absolute coordinates (\a x, \a y) + \param x X coordinate + \param y Y coordinate + \internal +*/ +void Sketcher_Profile::DumpFunctor::addPoint( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) +{ + myDescr += "sk.addPoint("; + myDescr += x + ", " + y + ")"; +} + +/*! + \brief Add angle + \param angle angle + \internal +*/ +void Sketcher_Profile::DumpFunctor::addAngle( const TCollection_AsciiString& angle ) +{ + myDescr += "sk.addAngle("; + myDescr += angle + ")"; +} + +/*! + \brief Add new segment of \a x length along X axis + \param x length of segment + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentParalX( const TCollection_AsciiString& x ) +{ + myDescr += "sk.addSegmentParalX("; + myDescr += x + ")"; +} + +/*! + \brief Add new segment along X axis with X coordinate of end set to 0 + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentParalXToZero() +{ + myDescr += "sk.addSegmentParalXToZero()"; +} + +/*! + \brief Add new segment of \a y length along Y axis + \param y length of segment + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentParalY( const TCollection_AsciiString& y ) +{ + myDescr += "sk.addSegmentParalY("; + myDescr += y + ")"; +} + +/*! + \brief Add new segment along Y axis with Y coordinate of end set to 0 + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentParalYToZero() +{ + myDescr += "sk.addSegmentParalYToZero()"; +} + +/*! + \brief Add segment by absolute coordinates + \param x X coordinate of segment end + \param y Y coordinate of segment end + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) +{ + myDescr += "sk.addSegmentAbsolute("; + myDescr += x + ", " + y + ")"; +} + +/*! + \brief Add segment by relativ coordinates + \param dx dX value specifing segment end + \param dy dY value specifing segment end + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) +{ + myDescr += "sk.addSegmentRelative("; + myDescr += dx + ", " + dy + ")"; +} - if(!TheLocation.IsIdentity()) - S.Move(TheLocation); +/*! + \brief Add segment with specified length along current direction + \param length segment length + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentLength( const TCollection_AsciiString& length ) +{ + myDescr += "sk.addSegmentLength("; + myDescr += length + ")"; +} - myShape = S; - myOK = true; - return; +/*! + \brief Add segment along X axis to reach specified X coordinate + \param x X coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentX( const TCollection_AsciiString& x, + int CurrentIndex ) +{ + myDescr += "sk.addSegmentX("; + myDescr += x + ")"; +} + +/*! + \brief Add segment along Y axis to reach specified Y coordinate + \param y Y coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentY( const TCollection_AsciiString& y, + int CurrentIndex ) +{ + myDescr += "sk.addSegmentY("; + myDescr += y + ")"; +} + +/*! + \brief Add segment by specified angle and length + \param angle angle that specifies segment direction + \param length segment length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentAngleLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& length, + int& CurrentIndex ) +{ + double aAngle = angle.RealValue(); + if ( aAngle == 90 ) { + myDescr += "sk.addSegmentPerpLength("; + myDescr += length + ")"; + } + else { + myDescr += "sk.addSegmentAngleLength("; + myDescr += angle + ", " + length + ")"; + } +} + +/*! + \brief Add segment that crosses Y axis by specified angle and X coordinate + \param angle angle that specifies segment direction + \param x X coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentAngleX( const TCollection_AsciiString& angle, + const TCollection_AsciiString& x, + int& CurrentIndex ) +{ + double aAngle = angle.RealValue(); + if ( aAngle == 90 ) { + myDescr += "sk.addSegmentPerpX("; + myDescr += x + ")"; + } + else { + myDescr += "sk.addSegmentAngleX("; + myDescr += angle + ", " + x + ")"; + } +} + +/*! + \brief Add segment that crosses X axis by specified angle and Y coordinate + \param angle angle that specifies segment direction + \param y Y coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentAngleY( const TCollection_AsciiString& angle, + const TCollection_AsciiString& y, + int& CurrentIndex ) +{ + double aAngle = angle.RealValue(); + if ( aAngle == 90 ) { + myDescr += "sk.addSegmentPerpY("; + myDescr += y + ")"; + } + else { + myDescr += "sk.addSegmentAngleY("; + myDescr += angle + ", " + y + ")"; + } +} + +/*! + \brief Add segment by specified direction and length + \param dx X component of direction vector + \param dx Y component of direction vector + \param length segment length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentDirectionLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& length, + int& CurrentIndex ) +{ + myDescr += "sk.addSegmentDirectionLength("; + myDescr += dx + ", " + dy + ", " + length + ")"; +} + +/*! + \brief Add segment by specified direction and X coordinate + \param dx X component of direction vector + \param dx Y component of direction vector + \param x X coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentDirectionX( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& x, + int& CurrentIndex ) +{ + myDescr += "sk.addSegmentDirectionX("; + myDescr += dx + ", " + dy + ", " + x + ")"; +} + +/*! + \brief Add segment by specified direction and Y coordinate + \param dx X component of direction vector + \param dx Y component of direction vector + \param y Y coordinate of segment end + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addSegmentDirectionY( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& y, + int& CurrentIndex ) +{ + myDescr += "sk.addSegmentDirectionY("; + myDescr += dx + ", " + dy + ", " + y + ")"; +} + +/*! + \brief Add arc along current direction vector by specified absolute coordinates + \param x X coordinate of arc end + \param x Y coordinate of arc end + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y ) +{ + myDescr += "sk.addArcAbsolute("; + myDescr += x + ", " + y + ")"; +} + +/*! + \brief Add arc along current direction vector by specified relative coordinates + \param dx dX value specifing arc end + \param dy dY value specifing arc end + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy ) +{ + myDescr += "sk.addArcRelative("; + myDescr += dx + ", " + dy + ")"; +} + +/*! + \brief Add arc with given radius by specified absolute coordinates + \param x X coordinate of arc end + \param x Y coordinate of arc end + \param radius arc radius + \param flag reverse direction flag + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcRadiusAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ) +{ + myDescr += "sk.addArcRadiusAbsolute("; + myDescr += x + ", " + y + ", " + radius + ", " + flag + ")"; +} + +/*! + \brief Add arc with given radius by specified relative coordinates + \param dx dX value specifing arc end + \param dy dY value specifing arc end + \param radius arc radius + \param flag reverse direction flag + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcRadiusRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& flag ) +{ + myDescr += "sk.addArcRadiusRelative("; + myDescr += dx + ", " + dy + ", " + radius + ", " + flag + ")"; +} + +/*! + \brief Add arc with given center by specified absolute coordinates + \param x X coordinate of arc end + \param x Y coordinate of arc end + \param xc X coordinate of arc center + \param yc Y coordinate of arc center + \param flag1 reverse direction flag + \param flag2 tolerance + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcCenterAbsolute( const TCollection_AsciiString& x, + const TCollection_AsciiString& y, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ) +{ + myDescr += "sk.addArcCenterAbsolute("; + myDescr += xc + ", " + yc + ", " + x + ", " + y + ", " + flag1 + ", " + flag2 + ")"; +} + +/*! + \brief Add arc with given center by specified relative coordinates + \param dx dX value specifing arc end + \param dy dY value specifing arc end + \param xc X coordinate of arc center + \param yc Y coordinate of arc center + \param flag1 reverse direction flag + \param flag2 tolerance + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcCenterRelative( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& xc, + const TCollection_AsciiString& yc, + const TCollection_AsciiString& flag1, + const TCollection_AsciiString& flag2 ) +{ + myDescr += "sk.addArcCenterRelative("; + myDescr += xc + ", " + yc + ", " + dx + ", " + dy + ", " + flag1 + ", " + flag2 + ")"; +} - badargs : - MESSAGE("profile : bad number of arguments"); +/*! + \brief Add arc with given radius by specified length + \param radius arc radius + \param length arc length + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcRadiusLength( const TCollection_AsciiString& radius, + const TCollection_AsciiString& length ) +{ + myDescr += "sk.addArcRadiusLength("; + myDescr += radius + ", " + length + ")"; +} + +/*! + \brief Add arc with given radius by specified angle and length + \param angle angle between arc start tangent and current direction + \param radius arc radius + \param length arc length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcAngleRadiusLength( const TCollection_AsciiString& angle, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ) +{ + double aAngle = angle.RealValue(); + if ( aAngle == 90 ) { + myDescr += "sk.addArcPerpRadiusLength("; + myDescr += radius + ", " + length + ")"; + } + else { + myDescr += "sk.addArcAngleRadiusLength("; + myDescr += angle + ", " + radius + ", " + length + ")"; + } +} + +/*! + \brief Add arc with given radius by specified direction and length + \param dx X component of direction vector + \param dx Y component of direction vector + \param radius arc radius + \param length arc length + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::addArcDirectionRadiusLength( const TCollection_AsciiString& dx, + const TCollection_AsciiString& dy, + const TCollection_AsciiString& radius, + const TCollection_AsciiString& length , + int& CurrentIndex ) +{ + myDescr += "sk.addArcDirectionRadiusLength("; + myDescr += dx + ", " + dy + ", " + radius + ", " + length + ")"; +} + +/*! + \brief Close wire + \internal +*/ +void Sketcher_Profile::DumpFunctor::closeWire() +{ + myDescr += "sk.close()"; +} + +/*! + \brief Close wire and build face + \internal +*/ +void Sketcher_Profile::DumpFunctor::closeWireAndBuildFace() +{ + myDescr += "sk.close()"; + myFace = Standard_True; +} + +/*! + \brief Complete parsing of current operator + \param CurrentIndex index of current operator + \internal +*/ +void Sketcher_Profile::DumpFunctor::nextCommand( int& CurrentIndex ) +{ + CurrentIndex++; +} + +/*! + \brief Finish parsing and create result + \internal +*/ +void Sketcher_Profile::DumpFunctor::makeResult() +{ + if ( mySketcherEntry == "" ) { + myOk = false; return; + } + myDescr += "\n\t"; + if ( myFace ) + myDescr += mySketcherEntry + " = sk.face(" + myWPEntry + ")"; + else + myDescr += mySketcherEntry + " = sk.wire(" + myWPEntry + ")"; + myDescr += myTail; +} + +/*! + \brief Get python script + \return string representing Python dump resulting from parsing of sketcher command + \internal +*/ +TCollection_AsciiString Sketcher_Profile::DumpFunctor::getDescription() +{ + return myDescr; +} + +//======================================================================= +// Sketcher_Profile +//======================================================================= + + +/*! + \brief Default constructor +*/ +Sketcher_Profile::Sketcher_Profile() +{ +} + +/*! + \brief Constructor + \param command sketcher script to parse +*/ +Sketcher_Profile::Sketcher_Profile( const char* command ) +{ + SetCommand( command ); +} + +/*! + \brief Set sketcher script to parse + \param command sketcher script to parse +*/ +void Sketcher_Profile::SetCommand( const char* command ) +{ + myCommand = command; +} + +/*! + \brief Parse sketcher command and get resulting shape + \param isDone if specified (non-zero), result of parsing is returned via this parameter + \param error if specified (non-zero), numerical error is returned via this parameter + \return shape resulting from parsing of sketcher command +*/ +TopoDS_Shape Sketcher_Profile::GetShape( bool* isDone, double* error ) +{ + ShapeFunctor functor; + parse( myCommand, &functor ); + TopoDS_Shape s = functor.getShape(); + + if ( isDone ) *isDone = functor.isOk(); + if ( error ) *error = functor.error(); + + return s; +} + +/*! + \brief Parse sketcher command and get resulting Python script + \param isDone if specified (non-zero), result of parsing is returned via this parameter + \return string representing Python dump resulting from parsing of sketcher command +*/ +TCollection_AsciiString Sketcher_Profile::GetDump( bool* isDone ) +{ + DumpFunctor functor; + parse( myCommand, &functor ); + TCollection_AsciiString d = functor.getDescription(); + + if ( isDone ) *isDone = functor.isOk(); + + return d; } + +/*! + \brief Parse sketcher script using specified functor + \param cmd sketcher script to parse + \internal +*/ +void Sketcher_Profile::parse( const TCollection_AsciiString& cmd, Functor* functor ) +{ + int CurrentIndex = 1; + int NumberOfArg = 0; + int NumberOfCommand = 0; + + functor->init( myCommand ); + TCollection_AsciiString command = extractCommand( myCommand ); + + TCollection_AsciiString aToken = command.Token( ":", 1 ); + TColStd_Array1OfAsciiString aTab( 0, command.Length() - 1 ); + if ( command.Length() ) { + while ( aToken.Length() != 0 ) { + TCollection_AsciiString aNewToken = command.Token( ":", NumberOfCommand + 1 ); + if ( aNewToken.Length() > 0 ) + aTab( NumberOfCommand ) = aNewToken; + aToken = command.Token( ":", ++NumberOfCommand ); + } + --NumberOfCommand; + } + + functor->setNumberOfCommand( NumberOfCommand ); + if ( aTab.Length() && aTab( 0 ).Length() ) { + while ( CurrentIndex < NumberOfCommand ) { + functor->initCommand(); + TColStd_Array1OfAsciiString a( 0, aTab( 0 ).Length() ); + findNextCommand( aTab, a, CurrentIndex, NumberOfArg ); + if ( a( 0 ) == "F" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addPoint( a.Value( 1 ), a.Value( 2 ) ); + } + else if ( a( 0 ) == "X" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentParalX( a.Value( 1 ) ); + } + else if ( a( 0 ) == "XX" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentParalXToZero(); + } + else if ( a( 0 ) == "Y" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentParalY( a.Value( 1 ) ); + } + else if ( a( 0 ) == "YY" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentParalYToZero(); + } + else if ( a( 0 ) == "RR" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addAngle( a.Value( 1 ) ); + } + else if ( a( 0 ) == "TT" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addSegmentAbsolute( a.Value( 1 ), a.Value( 2 ) ); + } + else if ( a( 0 ) == "T" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addSegmentRelative( a.Value( 1 ), a.Value( 2 ) ); + } + else if ( a( 0 ) == "L" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentLength( a.Value( 1 ) ); + } + else if ( a( 0 ) == "IX" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentX( a.Value( 1 ), CurrentIndex ); + } + else if ( a( 0 ) == "IY" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentY( a.Value( 1 ), CurrentIndex ); + } + else if ( a( 0 ) == "R" ) { + if ( NumberOfArg != 2) badArgs(); + CurrentIndex++; + TColStd_Array1OfAsciiString aNew( 0, aTab( 0 ).Length() ); + findNextCommand( aTab, aNew, CurrentIndex, NumberOfArg ); + if ( aNew( 0 ) == "L" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentAngleLength( a.Value( 1 ), aNew.Value( 1 ), CurrentIndex ); + } + else if ( aNew( 0 ) == "IX" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentAngleX( a.Value( 1 ), aNew.Value( 1 ), CurrentIndex ); + } + else if ( aNew( 0 ) == "IY" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentAngleY( a.Value( 1 ), aNew.Value( 1 ), CurrentIndex ); + } + else if ( aNew( 0 ) == "C" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addArcAngleRadiusLength( a.Value( 1 ), aNew.Value( 1 ), aNew.Value( 2 ), CurrentIndex ); + } + } + else if ( a( 0 ) == "D" ) { + if ( NumberOfArg != 3 ) badArgs(); + CurrentIndex++; + TColStd_Array1OfAsciiString aNew ( 0, aTab( 0 ).Length() ); + findNextCommand( aTab, aNew, CurrentIndex, NumberOfArg ); + if ( aNew( 0 ) == "L" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentDirectionLength( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), CurrentIndex ); + } + else if ( aNew( 0 ) == "IX" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentDirectionX( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), CurrentIndex ); + } + else if ( aNew( 0 ) == "IY" ) { + if ( NumberOfArg != 2 ) badArgs(); + functor->addSegmentDirectionY( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), CurrentIndex ); + } + else if ( aNew( 0 ) == "C" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addArcDirectionRadiusLength( a.Value( 1 ), a.Value( 2 ), aNew.Value( 1 ), aNew.Value( 2 ), CurrentIndex ); + } + } + else if ( a( 0 ) == "AA" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addArcAbsolute( a.Value( 1 ), a.Value( 2 ) ); + } + else if ( a( 0 ) == "A" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addArcRelative( a.Value( 1 ), a.Value( 2 ) ); + } + else if ( a( 0 ) == "UU" ) { + if ( NumberOfArg != 5 ) badArgs(); + functor->addArcRadiusAbsolute( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ) ); + } + else if ( a( 0 ) == "U" ) { + if ( NumberOfArg != 5 ) badArgs(); + functor->addArcRadiusRelative( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ) ); + } + else if ( a( 0 ) == "EE" ) { + if ( NumberOfArg != 7 ) badArgs(); + functor->addArcCenterAbsolute( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ), a.Value( 5 ), a.Value( 6 ) ); + } + else if ( a( 0 ) == "E" ) { + if ( NumberOfArg != 7 ) badArgs(); + functor->addArcCenterRelative( a.Value( 1 ), a.Value( 2 ), a.Value( 3 ), a.Value( 4 ), a.Value( 5 ), a.Value( 6 ) ); + } + else if ( a( 0 ) == "C" ) { + if ( NumberOfArg != 3 ) badArgs(); + functor->addArcRadiusLength( a.Value( 1 ), a.Value( 2 ) ); + } + else if ( a( 0 ) == "WW" ) { + functor->closeWire(); + CurrentIndex = NumberOfCommand - 1; + } + else if ( a( 0 ) == "WF" ) { + functor->closeWireAndBuildFace(); + CurrentIndex = NumberOfCommand - 1; + } + else { + MESSAGE("profile : unknown code " << a(CurrentIndex)); + return; + } + functor->nextCommand( CurrentIndex ); + } + } + + functor->makeResult(); +} + +/*! + \brief Extract sketcher command from script + \param cmd sketcher script to parse + \return sketcher command + \internal +*/ +TCollection_AsciiString Sketcher_Profile::extractCommand( const TCollection_AsciiString& cmd ) +{ + // parse only first line of the script + TCollection_AsciiString aSubStr = cmd.Token( "\n\t", 1 ); + return aSubStr.Token( "\"", aSubStr.Search( "=" ) != -1 ? 2 : 1 ); +} + +/*! + \brief Print an error message if the number of arguments of sketcher operator is wrong + \internal +*/ +void Sketcher_Profile::badArgs() +{ + MESSAGE("profile : bad number of arguments"); +} + +/*! + \brief Find the next sketcher operator in the input string + \param aTab all sketcher command data + \param a sketcher operator with parameters is returned via this parameter + \param CurrentIndex current operator index + \param NumberOfArg number of operator arguments is returned via this parameter + \internal +*/ +void Sketcher_Profile::findNextCommand( const TColStd_Array1OfAsciiString& aTab, + TColStd_Array1OfAsciiString& a, int CurrentIndex, + int& NumberOfArg) +{ + int n1 = 0; + TCollection_AsciiString aToken = aTab(CurrentIndex).Token(" ", 1); + while (aToken.Length() != 0) { + if (aTab(CurrentIndex).Token(" ", n1 + 1).Length() > 0) + a(n1) = aTab(CurrentIndex).Token(" ", n1 + 1); + aToken = aTab(CurrentIndex).Token(" ", ++n1); + } + n1 = n1 - 1; + NumberOfArg = n1; +} + diff --git a/src/SKETCHER/Sketcher_Profile.hxx b/src/SKETCHER/Sketcher_Profile.hxx index 99ee2f63d..5b66eb6ab 100644 --- a/src/SKETCHER/Sketcher_Profile.hxx +++ b/src/SKETCHER/Sketcher_Profile.hxx @@ -20,39 +20,46 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// GEOM SKETCHER : basic sketcher // File : Sketcher_Profile.h // Author : Damien COQUERET -// Module : GEOM -// -#include -#include + +#if defined WIN32 +# if defined SKETCHER_SALOME_EXPORTS || defined SKETCHER_EXPORTS +# define SKETCHER_SALOME_EXPORT _declspec( dllexport ) +# else +# define SKETCHER_SALOME_EXPORT _declspec( dllimport ) +# endif +#else +# define SKETCHER_SALOME_EXPORT +#endif + #include +#include +#include + #include -class Sketcher_Profile +class SKETCHER_SALOME_EXPORT Sketcher_Profile { + class Functor; + class ShapeFunctor; + class DumpFunctor; public: - Standard_EXPORT Sketcher_Profile(); - Standard_EXPORT Sketcher_Profile(const char* aCmd); + Sketcher_Profile(); + Sketcher_Profile( const char* ); -private: - gp_Pnt myLastPoint; - gp_Dir myLastDir; + void SetCommand( const char* ); - TopoDS_Shape myShape; - bool myOK; - std::string myErrMsg; - double myError; + TopoDS_Shape GetShape( bool* = 0, double* = 0 ); + TCollection_AsciiString GetDump( bool* = 0 ); -public: - Standard_EXPORT gp_Pnt GetLastPoint(){return myLastPoint;}; - Standard_EXPORT gp_Dir GetLastDir(){return myLastDir;}; - - Standard_EXPORT const TopoDS_Shape& GetShape(){return myShape;}; - Standard_EXPORT bool IsDone(){return myOK;}; - Standard_EXPORT std::string ErrMsg(){return myErrMsg;}; - Standard_EXPORT double Error(){return myError;}; +private: + void parse( const TCollection_AsciiString&, Functor* ); + void badArgs(); + void findNextCommand( const TColStd_Array1OfAsciiString&, TColStd_Array1OfAsciiString&, int, int& ); + TCollection_AsciiString extractCommand( const TCollection_AsciiString& ); +private: + TCollection_AsciiString myCommand; }; -- 2.39.2