X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_3DSketcherDriver.cxx;h=3b2255a1ff10d76f749be48d5b412d184ab16745;hb=48f5c2df5815348d168fd8e80fcc9e52dd69f137;hp=8108995ce62b08bcd243c216d21ab20f93656a18;hpb=0b6826bc5f36b5420f41af1475e1a79371a25323;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_3DSketcherDriver.cxx b/src/GEOMImpl/GEOMImpl_3DSketcherDriver.cxx index 8108995ce..3b2255a1f 100755 --- a/src/GEOMImpl/GEOMImpl_3DSketcherDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_3DSketcherDriver.cxx @@ -1,22 +1,20 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either +// License as published by the Free Software Foundation; either // version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -27,9 +25,13 @@ #include +#include + // OCCT Includes #include #include +#include +#include #include #include #include @@ -37,6 +39,8 @@ #include +#include + //======================================================================= //function : GetID //purpose : @@ -64,36 +68,253 @@ Standard_Integer GEOMImpl_3DSketcherDriver::Execute(TFunction_Logbook& log) cons { if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); - + GEOMImpl_I3DSketcher aCI (aFunction); TopoDS_Shape aShape; - Handle(TColStd_HArray1OfReal) aCoordsArray = aCI.GetCoordinates(); - - BRepBuilderAPI_MakePolygon aMakePoly; - int anArrayLength = aCoordsArray->Length(); - double x, y, z; - gp_Pnt aPnt; - for (int i = 0; i <=(anArrayLength - 3); i+=3) { - x = aCoordsArray->Value(i+1); - y = aCoordsArray->Value(i+2); - z = aCoordsArray->Value(i+3); - aPnt = gp_Pnt(x, y, z); - aMakePoly.Add(aPnt); + if (aFunction->GetType() == SKETCHER3D_COORDS) { + Handle(TColStd_HArray1OfReal) aCoordsArray = aCI.GetCoordinates(); + int anArrayLength = aCoordsArray->Length(); + + std::list points; + + for (int i = 0; i <= (anArrayLength-3); i += 3) { + gp_Pnt aPnt = gp_Pnt(aCoordsArray->Value(i+1), aCoordsArray->Value(i+2), aCoordsArray->Value(i+3)); + if (points.empty() || aPnt.Distance(points.back()) > gp::Resolution()) + points.push_back(aPnt); + } + + if ( points.size() == 1) { // Only Start Point + BRepBuilderAPI_MakeVertex mkVertex (points.back()); + aShape = mkVertex.Shape(); + } + else if ( points.size() > 1) { // Make Wire + BRepBuilderAPI_MakePolygon aMakePoly; + std::list::iterator it; + for (it = points.begin(); it != points.end(); ++it) { + aMakePoly.Add(*it); + } + + if (points.size() > 2 && + points.back().X() == points.front().X() && + points.back().Y() == points.front().Y() && + points.back().Z() == points.front().Z()) + aMakePoly.Close(); + + if (aMakePoly.IsDone()) + aShape = aMakePoly.Wire(); + } } - if ( anArrayLength == 3) { // Only Start Point - BRepBuilderAPI_MakeVertex mkVertex (aPnt); - aShape = mkVertex.Shape(); + else if (aFunction->GetType() == SKETCHER3D_COMMAND) { + Kernel_Utils::Localizer loc; + + TCollection_AsciiString aCommand = aCI.GetCommand(); + // "3DSketcher:CMD[:CMD[:CMD...]]" + + // Split the command string to separate CMDs + int icmd = 2; + TColStd_SequenceOfAsciiString aSequence; + if (aCommand.Length()) { + TCollection_AsciiString aToken = aCommand.Token(":", icmd); + while (aToken.Length() > 0) { + aSequence.Append(aToken); + aToken = aCommand.Token(":", ++icmd); + } + } + + int nbEdges = 0; + bool isFirstPointSet = false; + gp_XYZ p = gp::Origin().XYZ(); + BRepBuilderAPI_MakeVertex MV0 (p); + TopoDS_Vertex V = TopoDS::Vertex(MV0.Shape()); + + gp_XYZ p0 = p; + TopoDS_Vertex V0 = V; + + bool doClose = false; + BRepBuilderAPI_MakeWire MW; + + int nbCMDs = aSequence.Length(); + for (icmd = 1; icmd <= nbCMDs; icmd++) { + TCollection_AsciiString aCMD = aSequence.Value(icmd); + + // Split the CMD into string values + TColStd_SequenceOfAsciiString aStrVals; + int ival = 1; + TCollection_AsciiString aToken = aCMD.Token(" ", ival); + while (aToken.Length() > 0) { + aStrVals.Append(aToken); + aToken = aCMD.Token(" ", ++ival); + } + + // "TT x y z" : Create segment by point at X & Y or set the first point + // "T dx dy dz" : Create segment by point with DX & DY + // + // "OXY angleX angle2 length" : Create segment by two angles and length + // "OYZ angleY angle2 length" : Create segment by two angles and length + // "OXZ angleX angle2 length" : Create segment by two angles and length + // + // "WW" : Close Wire (to finish) + + switch (aStrVals.Value(1).Value(1)) + { + case 'T': + { + if (aStrVals.Length() != 4) + Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command."); + + gp_XYZ vp; + vp.SetX(aStrVals.Value(2).RealValue()); + vp.SetY(aStrVals.Value(3).RealValue()); + vp.SetZ(aStrVals.Value(4).RealValue()); + + if (aStrVals.Value(1) == "TT") { // absolute coordinates + if (!isFirstPointSet) { + p = vp; + BRepBuilderAPI_MakeVertex MV (p); + V = TopoDS::Vertex(MV.Shape()); + + p0 = p; + V0 = V; + + isFirstPointSet = true; + } + else { + if ((vp - p).SquareModulus() > Precision::Confusion()) { + BRepBuilderAPI_MakeVertex MV (vp); + TopoDS_Vertex VV = TopoDS::Vertex(MV.Shape()); + BRepBuilderAPI_MakeEdge ME (V, VV); + MW.Add(ME); + nbEdges++; + + p = vp; + V = VV; + } + } + } + else if (aStrVals.Value(1) == "T") { // relative coordinates + if (vp.SquareModulus() > Precision::Confusion()) { + vp = p + vp; + + BRepBuilderAPI_MakeVertex MV (vp); + TopoDS_Vertex VV = TopoDS::Vertex(MV.Shape()); + BRepBuilderAPI_MakeEdge ME (V, VV); + MW.Add(ME); + nbEdges++; + + p = vp; + V = VV; + } + } + else + Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command."); + } + break; + case 'O': + { + if (aStrVals.Length() != 4) + Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command."); + + char type = aStrVals.Value(1).Value(4); + char mode = aStrVals.Value(1).Value(5); + + double anAngle = aStrVals.Value(2).RealValue() * M_PI/180.0; + double anAngle2 = aStrVals.Value(3).RealValue() * M_PI/180.0; + double aLength = aStrVals.Value(4).RealValue(); + + double aHeight = aLength * sin(anAngle2); + if (type == 'C') + { + aHeight = aStrVals.Value(3).RealValue(); + anAngle2 = 0.0; + } + + double aProjectedLength = aLength * cos(anAngle2); + + gp_XYZ vp; + vp.SetX(aStrVals.Value(2).RealValue()); + vp.SetY(aStrVals.Value(3).RealValue()); + vp.SetZ(aStrVals.Value(4).RealValue()); + + gp_XYZ pref = gp::Origin().XYZ(); + if(mode == 'R') + pref = p; + + TCollection_AsciiString aTruncatedCommand = aStrVals.Value(1); + aTruncatedCommand.Trunc(3); + + if (aTruncatedCommand == "OXY") { + vp.SetX(pref.X() + aProjectedLength * cos(anAngle)); + vp.SetY(pref.Y() + aProjectedLength * sin(anAngle)); + vp.SetZ(pref.Z() + aHeight); + } + else if (aTruncatedCommand == "OYZ") { + vp.SetX(pref.X() + aHeight); + vp.SetY(pref.Y() + aProjectedLength * cos(anAngle)); + vp.SetZ(pref.Z() + aProjectedLength * sin(anAngle)); + } + else if (aTruncatedCommand == "OXZ") { + vp.SetX(pref.X() + aProjectedLength * cos(anAngle)); + vp.SetY(pref.Y() + aHeight); + vp.SetZ(pref.Z() + aProjectedLength * sin(anAngle)); + } + else + Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command."); + + if ((vp - p).SquareModulus() > Precision::Confusion()) { + BRepBuilderAPI_MakeVertex MV (vp); + TopoDS_Vertex VV = TopoDS::Vertex(MV.Shape()); + BRepBuilderAPI_MakeEdge ME (V, VV); + MW.Add(ME); + nbEdges++; + + p = vp; + V = VV; + } + } + break; + case 'W': + { + if (aStrVals.Length() != 1) + Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command."); + + if (aStrVals.Value(1) == "WW") + doClose = true; + else + Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command."); + } + break; + default: + { + Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command."); + } + } + } + + if (doClose && + nbEdges > 1 && // as 3D sketcher has only straight edges + (p - p0).SquareModulus() > Precision::Confusion()) { + BRepBuilderAPI_MakeEdge ME (V, V0); + MW.Add(ME); + nbEdges++; + } + + if (nbEdges > 0) { + if (!MW.IsDone()) + Standard_ConstructionError::Raise("3D Sketcher error: Wire construction failed."); + + aShape = MW; + } + else { + if (isFirstPointSet) { + aShape = V0; + } + } } - else { // Make Wire - if (aCoordsArray->Value(1) == x && aCoordsArray->Value(2) == y && aCoordsArray->Value(3) == z) - aMakePoly.Close(); - - if (aMakePoly.IsDone()) - aShape = aMakePoly.Wire(); + else { } - + if (aShape.IsNull()) return 0; aFunction->SetValue(aShape);