0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / DNaming / DNaming_Line3DDriver.cxx
1 // Created on: 2010-02-26
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 2010-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BRep_Builder.hxx>
18 #include <BRep_Tool.hxx>
19 #include <BRepAlgo.hxx>
20 #include <BRepBuilderAPI_MakeEdge.hxx>
21 #include <BRepBuilderAPI_MakeWire.hxx>
22 #include <DNaming.hxx>
23 #include <DNaming_Line3DDriver.hxx>
24 #include <Geom_BSplineCurve.hxx>
25 #include <GeomAPI_Interpolate.hxx>
26 #include <gp_Pnt.hxx>
27 #include <gp_Trsf.hxx>
28 #include <gp_Vec.hxx>
29 #include <ModelDefinitions.hxx>
30 #include <Precision.hxx>
31 #include <Standard_GUID.hxx>
32 #include <Standard_Type.hxx>
33 #include <TColgp_HArray1OfPnt.hxx>
34 #include <TDataStd_Integer.hxx>
35 #include <TDataStd_Name.hxx>
36 #include <TDataStd_Real.hxx>
37 #include <TDF_AttributeMap.hxx>
38 #include <TDF_Label.hxx>
39 #include <TDF_MapIteratorOfAttributeMap.hxx>
40 #include <TFunction_Function.hxx>
41 #include <TFunction_Logbook.hxx>
42 #include <TNaming.hxx>
43 #include <TNaming_Builder.hxx>
44 #include <TNaming_NamedShape.hxx>
45 #include <TopAbs.hxx>
46 #include <TopExp.hxx>
47 #include <TopExp_Explorer.hxx>
48 #include <TopLoc_Location.hxx>
49 #include <TopoDS.hxx>
50 #include <TopoDS_Shape.hxx>
51 #include <TopoDS_Vertex.hxx>
52 #include <TopoDS_Wire.hxx>
53 #include <TopTools_Array1OfShape.hxx>
54 #include <TopTools_HSequenceOfShape.hxx>
55
56 IMPLEMENT_STANDARD_RTTIEXT(DNaming_Line3DDriver,TFunction_Driver)
57
58 //=======================================================================
59 //function : DNaming_Line3DDriver
60 //purpose  : Constructor
61 //=======================================================================
62 DNaming_Line3DDriver::DNaming_Line3DDriver()
63 {}
64
65 //=======================================================================
66 //function : Validate
67 //purpose  : Validates labels of a function in <theLog>.
68 //=======================================================================
69 void DNaming_Line3DDriver::Validate(Handle(TFunction_Logbook)&) const
70 {}
71
72 //=======================================================================
73 //function : MustExecute
74 //purpose  : Analyse in <theLog> if the loaded function must be executed
75 //=======================================================================
76 Standard_Boolean DNaming_Line3DDriver::MustExecute(const Handle(TFunction_Logbook)&) const
77 {
78   return Standard_True;
79 }
80
81 //=======================================================================
82 //function : Execute
83 //purpose  : Execute the function
84 //=======================================================================
85 Standard_Integer DNaming_Line3DDriver::Execute(Handle(TFunction_Logbook)& theLog) const
86 {
87   Handle(TFunction_Function) aFunction;
88   Label().FindAttribute(TFunction_Function::GetID(),aFunction);
89   if(aFunction.IsNull()) return -1;
90
91   aFunction->SetFailure(NOTDONE);  
92   Handle(TNaming_NamedShape) aPrevILine3D = DNaming::GetFunctionResult(aFunction);
93 // Save location
94   TopLoc_Location aLocation;
95   if (!aPrevILine3D.IsNull() && !aPrevILine3D->IsEmpty()) {
96     aLocation = aPrevILine3D->Get().Location();
97   }
98
99   const Standard_Integer aType = DNaming::GetInteger(aFunction, LINE3D_TYPE)->Get();
100   Standard_Boolean isClosed = (aType != 0);
101   Standard_Integer aCounter(0), aLength  = DNaming::GetInteger(aFunction, LINE3D_PNTNB)->Get();
102   if(aLength < 2) {
103     aFunction->SetFailure(WRONG_ARGUMENT);
104     return -1;
105   }
106
107   Handle(TNaming_NamedShape) aNS1, aNS2;
108   BRepBuilderAPI_MakeWire aMakeWire;
109   TopoDS_Wire aWire;
110   TopoDS_Shape aShape1, aShape2;
111   
112   TopTools_Array1OfShape anArV(1,aLength); //aLength - number of points
113   for(aCounter = 1; aCounter <= aLength-1; aCounter++) {       
114     Handle(TDataStd_UAttribute) aRefP1 = DNaming::GetObjectArg(aFunction, (LINE3D_TYPE + aCounter));
115     aNS1 = DNaming::GetObjectValue(aRefP1);
116     Handle(TDataStd_UAttribute) aRefP2 = DNaming::GetObjectArg(aFunction, (LINE3D_TYPE + aCounter +1));
117     aNS2 =  DNaming::GetObjectValue(aRefP2);
118 #ifdef OCCT_DEBUG
119     if(!aNS1->IsEmpty()) {
120       aShape1 = aNS1->Get();
121       const gp_Pnt aDebPoint = BRep_Tool::Pnt(TopoDS::Vertex(aShape1));
122       (void )aDebPoint;
123       //        std::cout << aCounter << " X = " <<  aDebPoint.X() << " Y = " <<  aDebPoint.Y() << " Z = " <<  aDebPoint.Z() << std::endl;
124     } else
125       std::cout << " Line3DDriver:: NS1 is empty" << std::endl;
126     if(!aNS2->IsEmpty()) {
127       aShape2 = aNS2->Get();
128       const gp_Pnt aDebPoint = BRep_Tool::Pnt(TopoDS::Vertex(aShape2));
129       (void )aDebPoint;
130       //      std::cout << aCounter+1 << " X = " <<  aDebPoint.X() << " Y = " <<  aDebPoint.Y() << " Z = " <<  aDebPoint.Z() << std::endl;
131     } else
132       std::cout << " Line3DDriver:: NS2 is empty" << std::endl;
133 #endif
134     if(aNS1->IsEmpty() || aNS2->IsEmpty() || 
135        aNS1->Get().IsNull() || aNS2->Get().IsNull()) {
136       aFunction->SetFailure(WRONG_ARGUMENT);
137       return -1;
138     }
139     aShape1 = aNS1->Get();
140     aShape2 = aNS2->Get();
141 #ifdef OCCT_DEBUG
142     const gp_Pnt aDebPoint1 = BRep_Tool::Pnt(TopoDS::Vertex(aShape1));
143     const gp_Pnt aDebPoint2 = BRep_Tool::Pnt(TopoDS::Vertex(aShape2));
144     //      std::cout << aCounter   << " X = " <<  aDebPoint1.X() << " Y = " <<  aDebPoint1.Y() << " Z = " <<  aDebPoint1.Z() << std::endl;
145     //      std::cout << aCounter+1 << " X = " <<  aDebPoint2.X() << " Y = " <<  aDebPoint2.Y() << " Z = " <<  aDebPoint2.Z() << std::endl;
146     (void )aDebPoint1;
147     (void )aDebPoint2;
148 #endif 
149     if(aShape1.ShapeType() != TopAbs_VERTEX || aShape2.ShapeType() != TopAbs_VERTEX) {
150       aFunction->SetFailure(WRONG_ARGUMENT);
151       return -1;
152     }
153     BRepBuilderAPI_MakeEdge aMakeEdge(TopoDS::Vertex(aShape1), TopoDS::Vertex(aShape2));
154     if(aMakeEdge.IsDone()) {
155       anArV.SetValue(aCounter,   aShape1);
156       anArV.SetValue(aCounter+1, aShape2);
157       aMakeWire.Add(aMakeEdge.Edge());
158     }
159   }
160 //  } else // closed
161   if(isClosed) { 
162     Handle(TDataStd_UAttribute) aRefP1 = DNaming::GetObjectArg(aFunction, (LINE3D_TYPE + 1));
163     aNS1 = DNaming::GetObjectValue(aRefP1);
164     aShape1 = aNS1->Get();
165     BRepBuilderAPI_MakeEdge aMakeEdge(TopoDS::Vertex(aShape2), TopoDS::Vertex(aShape1));
166     if(aMakeEdge.IsDone()) aMakeWire.Add(aMakeEdge.Edge());
167   }
168   if(aMakeWire.IsDone()) aWire = aMakeWire.Wire(); 
169   
170
171   if(aWire.IsNull()) {
172     aFunction->SetFailure(ALGO_FAILED);
173     return -1;
174   }
175
176   if (!BRepAlgo::IsValid(aWire)) {
177     aFunction->SetFailure(RESULT_NOT_VALID);
178     return -1;
179   }
180
181   TDF_Label aResultLabel = RESPOSITION(aFunction); //aFunction->GetResult()->Label();
182   try {  
183     LoadNamingDS(aResultLabel, aWire, anArV, isClosed);
184
185   } catch (Standard_Failure const&) {
186     aFunction->SetFailure(NAMING_FAILED);
187     return -1;
188   }
189
190   // restore location
191   if(!aLocation.IsIdentity())
192     TNaming::Displace(aResultLabel, aLocation, Standard_True);
193
194   theLog->SetValid(aResultLabel, Standard_True);  
195
196   aFunction->SetFailure(DONE);
197   return 0;
198 }
199
200 //=======================================================================
201 //function : LoadNamingDS
202 //purpose  : Loads a Line3D in a data framework
203 //=======================================================================
204 void DNaming_Line3DDriver::LoadNamingDS (const TDF_Label& theResultLabel, 
205                                          const TopoDS_Wire& theWire, 
206                                          const TopTools_Array1OfShape& theArV,
207                                          const Standard_Boolean isClosed) const
208 {
209   if(theWire.IsNull()) return;
210 //Wire
211   TNaming_Builder aWBuilder(theResultLabel);
212   aWBuilder.Generated(theWire);
213 #ifdef OCCT_DEBUG
214   TDataStd_Name::Set(theResultLabel, "Line3DCurve");
215 #endif
216   Standard_Integer aLength = theArV.Length();
217   if(aLength < 2) return;
218   TopoDS_Shape aShape;
219   TopTools_Array1OfShape anArE(1,aLength);
220   TopoDS_Vertex aFirst, aLast;
221   for(Standard_Integer i = 1;i < aLength;i++) {
222     gp_Pnt aP1  = BRep_Tool::Pnt(TopoDS::Vertex(theArV.Value(i)));
223     gp_Pnt aP2  = BRep_Tool::Pnt(TopoDS::Vertex(theArV.Value(i+1)));
224     Standard_Boolean aFound = Standard_False;
225     TopExp_Explorer anExp(theWire,TopAbs_EDGE);
226     for(;anExp.More();anExp.Next()) {
227       const TopoDS_Edge& anE = TopoDS::Edge(anExp.Current());
228       TopoDS_Vertex aV, aV1, aV2;
229       TopExp::Vertices(anE, aV1, aV2);
230       gp_Pnt aPE1 = BRep_Tool::Pnt(aV1);
231       gp_Pnt aPE2 = BRep_Tool::Pnt(aV2);
232       if(aP1.IsEqual(aPE1, Precision::Confusion()) && aP2.IsEqual(aPE2, Precision::Confusion())) {
233         anArE.SetValue(i, anE);
234         aFound = Standard_True;
235         break;
236       }
237     }
238     if(!aFound)
239       anArE.SetValue(i, aShape);
240     else aFound = Standard_False;
241   }
242   if(isClosed) {
243     Standard_Boolean aFound = Standard_False;
244     gp_Pnt aP1  = BRep_Tool::Pnt(TopoDS::Vertex(theArV.Value(aLength)));
245     gp_Pnt aP2  = BRep_Tool::Pnt(TopoDS::Vertex(theArV.Value(1)));
246     TopExp_Explorer anExp(theWire,TopAbs_EDGE);
247     for(;anExp.More();anExp.Next()) {
248       const TopoDS_Edge& anE = TopoDS::Edge(anExp.Current());
249       TopoDS_Vertex aV, aV1, aV2;
250       TopExp::Vertices(anE, aV1, aV2);
251       gp_Pnt aPE1 = BRep_Tool::Pnt(aV1);
252       gp_Pnt aPE2 = BRep_Tool::Pnt(aV2);
253       if(aP1.IsEqual(aPE1, Precision::Confusion()) && aP2.IsEqual(aPE2, Precision::Confusion())) {
254         anArE.SetValue(aLength, anE);
255         aFound = Standard_True;
256      // closed case
257         aFirst = aV2;
258         aLast  = aV1;
259         break;
260       }
261     }
262     if(!aFound)
263       anArE.SetValue(aLength, aShape);
264   } else {
265     // open
266     anArE.SetValue(aLength, aShape); // last edge
267     TopExp::Vertices(theWire, aFirst, aLast);
268   }
269
270   // put edges
271   // from 1:aLength - edges
272   for(Standard_Integer i1 = 1;i1 <= aLength ;i1++) {
273     TDF_Label aLab = theResultLabel.FindChild(i1);
274     if(!anArE.Value(i1).IsNull()) {
275       TNaming_Builder aBuilder(aLab);
276       aBuilder.Generated(anArE.Value(i1));
277     } else {
278       Handle(TNaming_NamedShape) aNS;
279       if(aLab.FindAttribute(TNaming_NamedShape::GetID(), aNS))
280         TNaming_Builder aB(aLab);
281     }
282   }
283   //put vertexes
284   // aLength +1 - first vertex
285   // aLength +2 - last vertex
286   TDF_Label aLab1 = theResultLabel.FindChild(aLength+1);
287   TDF_Label aLab2 = theResultLabel.FindChild(aLength+2);
288   if(!aFirst.IsNull()) {
289     TNaming_Builder aBuilder(aLab1);
290     aBuilder.Generated(aFirst);
291   } else {
292     Handle(TNaming_NamedShape) aNS;
293     if(aLab1.FindAttribute(TNaming_NamedShape::GetID(), aNS))
294       TNaming_Builder aB(aLab1);
295   }
296   if(!aLast.IsNull()) {
297     TNaming_Builder aBuilder(aLab2);
298     aBuilder.Generated(aLast);
299   } else {
300     Handle(TNaming_NamedShape) aNS;
301     if(aLab2.FindAttribute(TNaming_NamedShape::GetID(), aNS))
302       TNaming_Builder aB(aLab2);
303   }
304 }