1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include <Standard_Stream.hxx>
22 #include <GEOMImpl_3DSketcherDriver.hxx>
23 #include <GEOMImpl_I3DSketcher.hxx>
24 #include <GEOMImpl_Types.hxx>
25 #include <GEOM_Function.hxx>
27 #include <GEOMImpl_IMeasureOperations.hxx>
29 #include <Basics_Utils.hxx>
32 #include <BRepBuilderAPI_MakePolygon.hxx>
33 #include <BRepBuilderAPI_MakeVertex.hxx>
34 #include <BRepBuilderAPI_MakeEdge.hxx>
35 #include <BRepBuilderAPI_MakeWire.hxx>
37 #include <TopoDS_Shape.hxx>
38 #include <TopoDS_Wire.hxx>
41 #include <Standard_ConstructionError.hxx>
43 #include <utilities.h>
45 //=======================================================================
48 //=======================================================================
49 const Standard_GUID& GEOMImpl_3DSketcherDriver::GetID()
51 static Standard_GUID a3DSketcherDriver("FF2BBB54-5D24-4df3-210B-3A678263EA26");
52 return a3DSketcherDriver;
56 //=======================================================================
57 //function : GEOMImpl_3DSketcherDriver
59 //=======================================================================
60 GEOMImpl_3DSketcherDriver::GEOMImpl_3DSketcherDriver()
64 //=======================================================================
67 //=======================================================================
68 Standard_Integer GEOMImpl_3DSketcherDriver::Execute(LOGBOOK& log) const
70 if (Label().IsNull()) return 0;
71 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
73 GEOMImpl_I3DSketcher aCI (aFunction);
77 if (aFunction->GetType() == SKETCHER3D_COORDS) {
78 Handle(TColStd_HArray1OfReal) aCoordsArray = aCI.GetCoordinates();
79 int anArrayLength = aCoordsArray->Length();
81 std::list<gp_Pnt> points;
83 for (int i = 0; i <= (anArrayLength-3); i += 3) {
84 gp_Pnt aPnt = gp_Pnt(aCoordsArray->Value(i+1), aCoordsArray->Value(i+2), aCoordsArray->Value(i+3));
85 if (points.empty() || aPnt.Distance(points.back()) > gp::Resolution())
86 points.push_back(aPnt);
89 if ( points.size() == 1) { // Only Start Point
90 BRepBuilderAPI_MakeVertex mkVertex (points.back());
91 aShape = mkVertex.Shape();
93 else if ( points.size() > 1) { // Make Wire
94 BRepBuilderAPI_MakePolygon aMakePoly;
95 std::list<gp_Pnt>::iterator it;
96 for (it = points.begin(); it != points.end(); ++it) {
100 if (points.size() > 2 &&
101 points.back().X() == points.front().X() &&
102 points.back().Y() == points.front().Y() &&
103 points.back().Z() == points.front().Z())
106 if (aMakePoly.IsDone())
107 aShape = aMakePoly.Wire();
110 else if (aFunction->GetType() == SKETCHER3D_COMMAND) {
111 Kernel_Utils::Localizer loc;
113 TCollection_AsciiString aCommand = aCI.GetCommand();
114 // "3DSketcher:CMD[:CMD[:CMD...]]"
116 // Split the command string to separate CMDs
118 TColStd_SequenceOfAsciiString aSequence;
119 if (aCommand.Length()) {
120 TCollection_AsciiString aToken = aCommand.Token(":", icmd);
121 while (aToken.Length() > 0) {
122 aSequence.Append(aToken);
123 aToken = aCommand.Token(":", ++icmd);
128 bool isFirstPointSet = false;
129 gp_XYZ p = gp::Origin().XYZ();
130 BRepBuilderAPI_MakeVertex MV0 (p);
131 TopoDS_Vertex V = TopoDS::Vertex(MV0.Shape());
134 TopoDS_Vertex V0 = V;
136 bool doClose = false;
137 BRepBuilderAPI_MakeWire MW;
139 int nbCMDs = aSequence.Length();
140 for (icmd = 1; icmd <= nbCMDs; icmd++) {
141 TCollection_AsciiString aCMD = aSequence.Value(icmd);
143 // Split the CMD into string values
144 TColStd_SequenceOfAsciiString aStrVals;
146 TCollection_AsciiString aToken = aCMD.Token(" ", ival);
147 while (aToken.Length() > 0) {
148 aStrVals.Append(aToken);
149 aToken = aCMD.Token(" ", ++ival);
152 // "TT x y z" : Create segment by point at X & Y or set the first point
153 // "T dx dy dz" : Create segment by point with DX & DY
155 // "OXY angleX angle2 length" : Create segment by two angles and length
156 // "OYZ angleY angle2 length" : Create segment by two angles and length
157 // "OXZ angleX angle2 length" : Create segment by two angles and length
159 // "WW" : Close Wire (to finish)
161 switch (aStrVals.Value(1).Value(1))
165 if (aStrVals.Length() != 4)
166 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
169 vp.SetX(aStrVals.Value(2).RealValue());
170 vp.SetY(aStrVals.Value(3).RealValue());
171 vp.SetZ(aStrVals.Value(4).RealValue());
173 if (aStrVals.Value(1) == "TT") { // absolute coordinates
174 if (!isFirstPointSet) {
176 BRepBuilderAPI_MakeVertex MV (p);
177 V = TopoDS::Vertex(MV.Shape());
182 isFirstPointSet = true;
185 if ((vp - p).SquareModulus() > Precision::Confusion()) {
186 BRepBuilderAPI_MakeVertex MV (vp);
187 TopoDS_Vertex VV = TopoDS::Vertex(MV.Shape());
188 BRepBuilderAPI_MakeEdge ME (V, VV);
197 else if (aStrVals.Value(1) == "T") { // relative coordinates
198 if (vp.SquareModulus() > Precision::Confusion()) {
201 BRepBuilderAPI_MakeVertex MV (vp);
202 TopoDS_Vertex VV = TopoDS::Vertex(MV.Shape());
203 BRepBuilderAPI_MakeEdge ME (V, VV);
212 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
217 if (aStrVals.Length() != 4)
218 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
220 char type = aStrVals.Value(1).Value(4);
221 char mode = aStrVals.Value(1).Value(5);
223 double anAngle = aStrVals.Value(2).RealValue() * M_PI/180.0;
224 double anAngle2 = aStrVals.Value(3).RealValue() * M_PI/180.0;
225 double aLength = aStrVals.Value(4).RealValue();
227 double aHeight = aLength * sin(anAngle2);
230 aHeight = aStrVals.Value(3).RealValue();
234 double aProjectedLength = aLength * cos(anAngle2);
237 vp.SetX(aStrVals.Value(2).RealValue());
238 vp.SetY(aStrVals.Value(3).RealValue());
239 vp.SetZ(aStrVals.Value(4).RealValue());
241 gp_XYZ pref = gp::Origin().XYZ();
245 TCollection_AsciiString aTruncatedCommand = aStrVals.Value(1);
246 aTruncatedCommand.Trunc(3);
248 if (aTruncatedCommand == "OXY") {
249 vp.SetX(pref.X() + aProjectedLength * cos(anAngle));
250 vp.SetY(pref.Y() + aProjectedLength * sin(anAngle));
251 vp.SetZ(pref.Z() + aHeight);
253 else if (aTruncatedCommand == "OYZ") {
254 vp.SetX(pref.X() + aHeight);
255 vp.SetY(pref.Y() + aProjectedLength * cos(anAngle));
256 vp.SetZ(pref.Z() + aProjectedLength * sin(anAngle));
258 else if (aTruncatedCommand == "OXZ") {
259 vp.SetX(pref.X() + aProjectedLength * cos(anAngle));
260 vp.SetY(pref.Y() + aHeight);
261 vp.SetZ(pref.Z() + aProjectedLength * sin(anAngle));
264 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
266 if ((vp - p).SquareModulus() > Precision::Confusion()) {
267 BRepBuilderAPI_MakeVertex MV (vp);
268 TopoDS_Vertex VV = TopoDS::Vertex(MV.Shape());
269 BRepBuilderAPI_MakeEdge ME (V, VV);
280 if (aStrVals.Length() != 1)
281 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
283 if (aStrVals.Value(1) == "WW")
286 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
291 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
297 nbEdges > 1 && // as 3D sketcher has only straight edges
298 (p - p0).SquareModulus() > Precision::Confusion()) {
299 BRepBuilderAPI_MakeEdge ME (V, V0);
306 Standard_ConstructionError::Raise("3D Sketcher error: Wire construction failed.");
311 if (isFirstPointSet) {
319 if (aShape.IsNull()) return 0;
321 aFunction->SetValue(aShape);
322 #if OCC_VERSION_MAJOR < 7
323 log.SetTouched(Label());
325 log->SetTouched(Label());
330 //================================================================================
332 * \brief Returns a name of creation operation and names and values of creation parameters
334 //================================================================================
336 bool GEOMImpl_3DSketcherDriver::
337 GetCreationInformation(std::string& theOperationName,
338 std::vector<GEOM_Param>& theParams)
340 if (Label().IsNull()) return 0;
341 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
343 GEOMImpl_I3DSketcher aCI( function );
344 Standard_Integer aType = function->GetType();
346 theOperationName = "3DSKETCH";
348 if (aType == SKETCHER3D_COORDS)
350 theParams.resize( 1 );
351 theParams[0].Set( "(X,Y,Z)" );
353 Handle(TColStd_HArray1OfReal) aCoordsArray = aCI.GetCoordinates();
354 int anArrayLength = aCoordsArray->Length();
355 for (int i = 0; i <= (anArrayLength-3); i += 3)
357 << aCoordsArray->Value(i+1) << ", "
358 << aCoordsArray->Value(i+2) << ", "
359 << aCoordsArray->Value(i+3) << " ) ";
361 else if (aType == SKETCHER3D_COMMAND)
363 AddParam( theParams, "Command", aCI.GetCommand() );
372 OCCT_IMPLEMENT_STANDARD_RTTIEXT(GEOMImpl_3DSketcherDriver,GEOM_BaseDriver);