]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMImpl/GEOMImpl_3DSketcherDriver.cxx
Salome HOME
Mantis issue 0021392: EDF 1631 GEOM: Dump study of sketcher 3D with relatives coordin...
[modules/geom.git] / src / GEOMImpl / GEOMImpl_3DSketcherDriver.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18
19 #include <Standard_Stream.hxx>
20
21 #include <GEOMImpl_3DSketcherDriver.hxx>
22 #include <GEOMImpl_I3DSketcher.hxx>
23 #include <GEOMImpl_Types.hxx>
24 #include <GEOM_Function.hxx>
25
26 #include <GEOMImpl_IMeasureOperations.hxx>
27
28 #include <Basics_Utils.hxx>
29
30 // OCCT Includes
31 #include <BRepBuilderAPI_MakePolygon.hxx>
32 #include <BRepBuilderAPI_MakeVertex.hxx>
33 #include <BRepBuilderAPI_MakeEdge.hxx>
34 #include <BRepBuilderAPI_MakeWire.hxx>
35 #include <TopoDS.hxx>
36 #include <TopoDS_Shape.hxx>
37 #include <TopoDS_Wire.hxx>
38 #include <gp_Pnt.hxx>
39
40 #include <Standard_ConstructionError.hxx>
41
42 //=======================================================================
43 //function : GetID
44 //purpose  :
45 //=======================================================================
46 const Standard_GUID& GEOMImpl_3DSketcherDriver::GetID()
47 {
48   static Standard_GUID a3DSketcherDriver("FF2BBB54-5D24-4df3-210B-3A678263EA26");
49   return a3DSketcherDriver;
50 }
51
52
53 //=======================================================================
54 //function : GEOMImpl_3DSketcherDriver
55 //purpose  :
56 //=======================================================================
57 GEOMImpl_3DSketcherDriver::GEOMImpl_3DSketcherDriver()
58 {
59 }
60
61 //=======================================================================
62 //function : Execute
63 //purpose  :
64 //=======================================================================
65 Standard_Integer GEOMImpl_3DSketcherDriver::Execute(TFunction_Logbook& log) const
66 {
67   if (Label().IsNull()) return 0;
68   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
69
70   GEOMImpl_I3DSketcher aCI (aFunction);
71
72   TopoDS_Shape aShape;
73
74   if (aFunction->GetType() == SKETCHER3D_COORDS) {
75     Handle(TColStd_HArray1OfReal) aCoordsArray = aCI.GetCoordinates();
76     int anArrayLength = aCoordsArray->Length();
77
78     std::list<gp_Pnt> points;
79
80     for (int i = 0; i <= (anArrayLength-3); i += 3) {
81       gp_Pnt aPnt = gp_Pnt(aCoordsArray->Value(i+1), aCoordsArray->Value(i+2), aCoordsArray->Value(i+3));
82       if (points.empty() || aPnt.Distance(points.back()) > gp::Resolution())
83         points.push_back(aPnt);
84     }
85
86     if ( points.size() == 1) { // Only Start Point
87       BRepBuilderAPI_MakeVertex mkVertex (points.back());
88       aShape = mkVertex.Shape();
89     }
90     else if ( points.size() > 1) { // Make Wire
91       BRepBuilderAPI_MakePolygon aMakePoly;
92       std::list<gp_Pnt>::iterator it;
93       for (it = points.begin(); it != points.end(); ++it) {
94         aMakePoly.Add(*it);
95       }
96
97       if (points.size() > 2 && 
98           points.back().X() == points.front().X() && 
99           points.back().Y() == points.front().Y() && 
100           points.back().Z() == points.front().Z())
101         aMakePoly.Close();
102
103       if (aMakePoly.IsDone())
104         aShape = aMakePoly.Wire();
105     }
106   }
107   else if (aFunction->GetType() == SKETCHER3D_COMMAND) {
108     Kernel_Utils::Localizer loc;
109
110     TCollection_AsciiString aCommand = aCI.GetCommand();
111     // "3DSketcher:CMD[:CMD[:CMD...]]"
112
113     // Split the command string to separate CMDs
114     int icmd = 2;
115     TColStd_SequenceOfAsciiString aSequence;
116     if (aCommand.Length()) {
117       TCollection_AsciiString aToken = aCommand.Token(":", icmd);
118       while (aToken.Length() > 0) {
119         aSequence.Append(aToken);
120         aToken = aCommand.Token(":", ++icmd);
121       }
122     }
123
124     int nbEdges = 0;
125     bool isFirstPointSet = false;
126     gp_XYZ p = gp::Origin().XYZ();
127     BRepBuilderAPI_MakeVertex MV0 (p);
128     TopoDS_Vertex V = TopoDS::Vertex(MV0.Shape());
129
130     gp_XYZ p0 = p;
131     TopoDS_Vertex V0 = V;
132
133     bool doClose = false;
134     BRepBuilderAPI_MakeWire MW;
135
136     int nbCMDs = aSequence.Length();
137     for (icmd = 1; icmd <= nbCMDs; icmd++) {
138       TCollection_AsciiString aCMD = aSequence.Value(icmd);
139
140       // Split the CMD into string values
141       TColStd_SequenceOfAsciiString aStrVals;
142       int ival = 1;
143       TCollection_AsciiString aToken = aCMD.Token(" ", ival);
144       while (aToken.Length() > 0) {
145         aStrVals.Append(aToken);
146         aToken = aCMD.Token(" ", ++ival);
147       }
148
149       // "TT x y z" : Create segment by point at X & Y or set the first point
150       // "T dx dy dz" : Create segment by point with DX & DY
151       //
152       // "OXY angleX angle2 length" : Create segment by two angles and length
153       // "OYZ angleY angle2 length" : Create segment by two angles and length
154       // "OXZ angleX angle2 length" : Create segment by two angles and length
155       //
156       // "WW" : Close Wire (to finish)
157
158       switch (aStrVals.Value(1).Value(1))
159       {
160       case 'T':
161         {
162           if (aStrVals.Length() != 4)
163             Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
164
165           gp_XYZ vp;
166           vp.SetX(aStrVals.Value(2).RealValue());
167           vp.SetY(aStrVals.Value(3).RealValue());
168           vp.SetZ(aStrVals.Value(4).RealValue());
169
170           if (aStrVals.Value(1) == "TT") { // absolute coordinates
171             if (!isFirstPointSet) {
172               p = vp;
173               BRepBuilderAPI_MakeVertex MV (p);
174               V = TopoDS::Vertex(MV.Shape());
175
176               p0 = p;
177               V0 = V;
178
179               isFirstPointSet = true;
180             }
181             else {
182               if ((vp - p).SquareModulus() > Precision::Confusion()) {
183                 BRepBuilderAPI_MakeVertex MV (vp);
184                 TopoDS_Vertex VV = TopoDS::Vertex(MV.Shape());
185                 BRepBuilderAPI_MakeEdge ME (V, VV);
186                 MW.Add(ME);
187                 nbEdges++;
188
189                 p = vp;
190                 V = VV;
191               }
192             }
193           }
194           else if (aStrVals.Value(1) == "T") { // relative coordinates
195             if (vp.SquareModulus() > Precision::Confusion()) {
196               vp = p + vp;
197
198               BRepBuilderAPI_MakeVertex MV (vp);
199               TopoDS_Vertex VV = TopoDS::Vertex(MV.Shape());
200               BRepBuilderAPI_MakeEdge ME (V, VV);
201               MW.Add(ME);
202               nbEdges++;
203
204               p = vp;
205               V = VV;
206             }
207           }
208           else
209             Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
210         }
211         break;
212       case 'O':
213         {
214           if (aStrVals.Length() != 4)
215             Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
216
217           double anAngle  = aStrVals.Value(2).RealValue() * M_PI/180.0;
218           double anAngle2 = aStrVals.Value(3).RealValue() * M_PI/180.0;
219           double aLength  = aStrVals.Value(4).RealValue();
220
221           double aProjectedLength = aLength * cos(anAngle2);
222
223           gp_XYZ vp;
224           vp.SetX(aStrVals.Value(2).RealValue());
225           vp.SetY(aStrVals.Value(3).RealValue());
226           vp.SetZ(aStrVals.Value(4).RealValue());
227
228           if (aStrVals.Value(1) == "OXY") {
229             vp.SetX(p.X() + aProjectedLength * cos(anAngle));
230             vp.SetY(p.Y() + aProjectedLength * sin(anAngle));
231             vp.SetZ(p.Z() + aLength * sin(anAngle2));
232           }
233           else if (aStrVals.Value(1) == "OYZ") {
234             vp.SetX(p.X() + aLength * sin(anAngle2));
235             vp.SetY(p.Y() + aProjectedLength * cos(anAngle));
236             vp.SetZ(p.Z() + aProjectedLength * sin(anAngle));
237           }
238           else if (aStrVals.Value(1) == "OXZ") {
239             vp.SetX(p.X() + aProjectedLength * cos(anAngle));
240             vp.SetY(p.Y() + aLength * sin(anAngle2));
241             vp.SetZ(p.Z() + aProjectedLength * sin(anAngle));
242           }
243           else
244             Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
245
246           BRepBuilderAPI_MakeVertex MV (vp);
247           TopoDS_Vertex VV = TopoDS::Vertex(MV.Shape());
248           BRepBuilderAPI_MakeEdge ME (V, VV);
249           MW.Add(ME);
250           nbEdges++;
251
252           p = vp;
253           V = VV;
254         }
255         break;
256       case 'W':
257         {
258           if (aStrVals.Length() != 1)
259             Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
260
261           if (aStrVals.Value(1) == "WW")
262             doClose = true;
263           else
264             Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
265         }
266         break;
267       default:
268         {
269           Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
270         }
271       }
272     }
273
274     if (doClose &&
275         nbEdges > 1 && // as 3D sketcher has only straight edges
276         (p - p0).SquareModulus() > Precision::Confusion()) {
277       BRepBuilderAPI_MakeEdge ME (V, V0);
278       MW.Add(ME);
279       nbEdges++;
280     }
281
282     if (nbEdges > 0) {
283       if (!MW.IsDone())
284         Standard_ConstructionError::Raise("3D Sketcher error: Wire construction failed.");
285
286       aShape = MW;
287     }
288     else {
289       if (isFirstPointSet) {
290         aShape = V0;
291       }
292     }
293   }
294   else {
295   }
296
297   if (aShape.IsNull()) return 0;
298
299   aFunction->SetValue(aShape);
300   log.SetTouched(Label());
301   return 1;
302 }
303
304
305 //=======================================================================
306 //function :  GEOMImpl_3DSketcherDriver_Type_
307 //purpose  :
308 //=======================================================================
309 Standard_EXPORT Handle_Standard_Type& GEOMImpl_3DSketcherDriver_Type_()
310 {
311
312   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
313   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
314   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
315   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
316   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
317   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
318
319
320   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
321   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_3DSketcherDriver",
322                                                          sizeof(GEOMImpl_3DSketcherDriver),
323                                                          1,
324                                                          (Standard_Address)_Ancestors,
325                                                          (Standard_Address)NULL);
326
327   return _aType;
328 }
329
330 //=======================================================================
331 //function : DownCast
332 //purpose  :
333 //=======================================================================
334 const Handle(GEOMImpl_3DSketcherDriver) Handle(GEOMImpl_3DSketcherDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
335 {
336   Handle(GEOMImpl_3DSketcherDriver) _anOtherObject;
337
338   if (!AnObject.IsNull()) {
339      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_3DSketcherDriver))) {
340        _anOtherObject = Handle(GEOMImpl_3DSketcherDriver)((Handle(GEOMImpl_3DSketcherDriver)&)AnObject);
341      }
342   }
343
344   return _anOtherObject ;
345 }