1 // Copyright (C) 2007-2012 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.
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
19 #include <Standard_Stream.hxx>
21 #include <GEOMImpl_3DSketcherDriver.hxx>
22 #include <GEOMImpl_I3DSketcher.hxx>
23 #include <GEOMImpl_Types.hxx>
24 #include <GEOM_Function.hxx>
26 #include <GEOMImpl_IMeasureOperations.hxx>
28 #include <Basics_Utils.hxx>
31 #include <BRepBuilderAPI_MakePolygon.hxx>
32 #include <BRepBuilderAPI_MakeVertex.hxx>
33 #include <BRepBuilderAPI_MakeEdge.hxx>
34 #include <BRepBuilderAPI_MakeWire.hxx>
36 #include <TopoDS_Shape.hxx>
37 #include <TopoDS_Wire.hxx>
40 #include <Standard_ConstructionError.hxx>
42 #include <utilities.h>
44 //=======================================================================
47 //=======================================================================
48 const Standard_GUID& GEOMImpl_3DSketcherDriver::GetID()
50 static Standard_GUID a3DSketcherDriver("FF2BBB54-5D24-4df3-210B-3A678263EA26");
51 return a3DSketcherDriver;
55 //=======================================================================
56 //function : GEOMImpl_3DSketcherDriver
58 //=======================================================================
59 GEOMImpl_3DSketcherDriver::GEOMImpl_3DSketcherDriver()
63 //=======================================================================
66 //=======================================================================
67 Standard_Integer GEOMImpl_3DSketcherDriver::Execute(TFunction_Logbook& log) const
69 if (Label().IsNull()) return 0;
70 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
72 GEOMImpl_I3DSketcher aCI (aFunction);
76 if (aFunction->GetType() == SKETCHER3D_COORDS) {
77 Handle(TColStd_HArray1OfReal) aCoordsArray = aCI.GetCoordinates();
78 int anArrayLength = aCoordsArray->Length();
80 std::list<gp_Pnt> points;
82 for (int i = 0; i <= (anArrayLength-3); i += 3) {
83 gp_Pnt aPnt = gp_Pnt(aCoordsArray->Value(i+1), aCoordsArray->Value(i+2), aCoordsArray->Value(i+3));
84 if (points.empty() || aPnt.Distance(points.back()) > gp::Resolution())
85 points.push_back(aPnt);
88 if ( points.size() == 1) { // Only Start Point
89 BRepBuilderAPI_MakeVertex mkVertex (points.back());
90 aShape = mkVertex.Shape();
92 else if ( points.size() > 1) { // Make Wire
93 BRepBuilderAPI_MakePolygon aMakePoly;
94 std::list<gp_Pnt>::iterator it;
95 for (it = points.begin(); it != points.end(); ++it) {
99 if (points.size() > 2 &&
100 points.back().X() == points.front().X() &&
101 points.back().Y() == points.front().Y() &&
102 points.back().Z() == points.front().Z())
105 if (aMakePoly.IsDone())
106 aShape = aMakePoly.Wire();
109 else if (aFunction->GetType() == SKETCHER3D_COMMAND) {
110 Kernel_Utils::Localizer loc;
112 TCollection_AsciiString aCommand = aCI.GetCommand();
113 // "3DSketcher:CMD[:CMD[:CMD...]]"
115 // Split the command string to separate CMDs
117 TColStd_SequenceOfAsciiString aSequence;
118 if (aCommand.Length()) {
119 TCollection_AsciiString aToken = aCommand.Token(":", icmd);
120 while (aToken.Length() > 0) {
121 aSequence.Append(aToken);
122 aToken = aCommand.Token(":", ++icmd);
127 bool isFirstPointSet = false;
128 gp_XYZ p = gp::Origin().XYZ();
129 BRepBuilderAPI_MakeVertex MV0 (p);
130 TopoDS_Vertex V = TopoDS::Vertex(MV0.Shape());
133 TopoDS_Vertex V0 = V;
135 bool doClose = false;
136 BRepBuilderAPI_MakeWire MW;
138 int nbCMDs = aSequence.Length();
139 for (icmd = 1; icmd <= nbCMDs; icmd++) {
140 TCollection_AsciiString aCMD = aSequence.Value(icmd);
142 // Split the CMD into string values
143 TColStd_SequenceOfAsciiString aStrVals;
145 TCollection_AsciiString aToken = aCMD.Token(" ", ival);
146 while (aToken.Length() > 0) {
147 aStrVals.Append(aToken);
148 aToken = aCMD.Token(" ", ++ival);
151 // "TT x y z" : Create segment by point at X & Y or set the first point
152 // "T dx dy dz" : Create segment by point with DX & DY
154 // "OXY angleX angle2 length" : Create segment by two angles and length
155 // "OYZ angleY angle2 length" : Create segment by two angles and length
156 // "OXZ angleX angle2 length" : Create segment by two angles and length
158 // "WW" : Close Wire (to finish)
160 switch (aStrVals.Value(1).Value(1))
164 if (aStrVals.Length() != 4)
165 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
168 vp.SetX(aStrVals.Value(2).RealValue());
169 vp.SetY(aStrVals.Value(3).RealValue());
170 vp.SetZ(aStrVals.Value(4).RealValue());
172 if (aStrVals.Value(1) == "TT") { // absolute coordinates
173 if (!isFirstPointSet) {
175 BRepBuilderAPI_MakeVertex MV (p);
176 V = TopoDS::Vertex(MV.Shape());
181 isFirstPointSet = true;
184 if ((vp - p).SquareModulus() > Precision::Confusion()) {
185 BRepBuilderAPI_MakeVertex MV (vp);
186 TopoDS_Vertex VV = TopoDS::Vertex(MV.Shape());
187 BRepBuilderAPI_MakeEdge ME (V, VV);
196 else if (aStrVals.Value(1) == "T") { // relative coordinates
197 if (vp.SquareModulus() > Precision::Confusion()) {
200 BRepBuilderAPI_MakeVertex MV (vp);
201 TopoDS_Vertex VV = TopoDS::Vertex(MV.Shape());
202 BRepBuilderAPI_MakeEdge ME (V, VV);
211 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
216 if (aStrVals.Length() != 4)
217 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
219 char type = aStrVals.Value(1).Value(4);
220 char mode = aStrVals.Value(1).Value(5);
222 double anAngle = aStrVals.Value(2).RealValue() * M_PI/180.0;
223 double anAngle2 = aStrVals.Value(3).RealValue() * M_PI/180.0;
224 double aLength = aStrVals.Value(4).RealValue();
226 double aHeight = aLength * sin(anAngle2);
229 aHeight = aStrVals.Value(3).RealValue();
233 double aProjectedLength = aLength * cos(anAngle2);
236 vp.SetX(aStrVals.Value(2).RealValue());
237 vp.SetY(aStrVals.Value(3).RealValue());
238 vp.SetZ(aStrVals.Value(4).RealValue());
240 gp_XYZ pref = gp::Origin().XYZ();
244 TCollection_AsciiString aTruncatedCommand = aStrVals.Value(1);
245 aTruncatedCommand.Trunc(3);
247 if (aTruncatedCommand == "OXY") {
248 vp.SetX(pref.X() + aProjectedLength * cos(anAngle));
249 vp.SetY(pref.Y() + aProjectedLength * sin(anAngle));
250 vp.SetZ(pref.Z() + aHeight);
252 else if (aTruncatedCommand == "OYZ") {
253 vp.SetX(pref.X() + aHeight);
254 vp.SetY(pref.Y() + aProjectedLength * cos(anAngle));
255 vp.SetZ(pref.Z() + aProjectedLength * sin(anAngle));
257 else if (aTruncatedCommand == "OXZ") {
258 vp.SetX(pref.X() + aProjectedLength * cos(anAngle));
259 vp.SetY(pref.Y() + aHeight);
260 vp.SetZ(pref.Z() + aProjectedLength * sin(anAngle));
263 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
265 if ((vp - p).SquareModulus() > Precision::Confusion()) {
266 BRepBuilderAPI_MakeVertex MV (vp);
267 TopoDS_Vertex VV = TopoDS::Vertex(MV.Shape());
268 BRepBuilderAPI_MakeEdge ME (V, VV);
279 if (aStrVals.Length() != 1)
280 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
282 if (aStrVals.Value(1) == "WW")
285 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
290 Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command.");
296 nbEdges > 1 && // as 3D sketcher has only straight edges
297 (p - p0).SquareModulus() > Precision::Confusion()) {
298 BRepBuilderAPI_MakeEdge ME (V, V0);
305 Standard_ConstructionError::Raise("3D Sketcher error: Wire construction failed.");
310 if (isFirstPointSet) {
318 if (aShape.IsNull()) return 0;
320 aFunction->SetValue(aShape);
321 log.SetTouched(Label());
326 //=======================================================================
327 //function : GEOMImpl_3DSketcherDriver_Type_
329 //=======================================================================
330 Standard_EXPORT Handle_Standard_Type& GEOMImpl_3DSketcherDriver_Type_()
333 static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
334 if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
335 static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
336 if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
337 static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
338 if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
341 static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
342 static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_3DSketcherDriver",
343 sizeof(GEOMImpl_3DSketcherDriver),
345 (Standard_Address)_Ancestors,
346 (Standard_Address)NULL);
351 //=======================================================================
352 //function : DownCast
354 //=======================================================================
355 const Handle(GEOMImpl_3DSketcherDriver) Handle(GEOMImpl_3DSketcherDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
357 Handle(GEOMImpl_3DSketcherDriver) _anOtherObject;
359 if (!AnObject.IsNull()) {
360 if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_3DSketcherDriver))) {
361 _anOtherObject = Handle(GEOMImpl_3DSketcherDriver)((Handle(GEOMImpl_3DSketcherDriver)&)AnObject);
365 return _anOtherObject ;