e065895d9a1389aefec76efdff8cd16fb5e9024f
[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);
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       gp_Pnt aDebPoint = BRep_Tool::Pnt(TopoDS::Vertex(aShape1));
122       //        cout << aCounter << " X = " <<  aDebPoint.X() << " Y = " <<  aDebPoint.Y() << " Z = " <<  aDebPoint.Z() << endl;
123     } else
124       cout << " Line3DDriver:: NS1 is empty" << endl;
125     if(!aNS2->IsEmpty()) {
126       aShape2 = aNS2->Get();
127       gp_Pnt aDebPoint = BRep_Tool::Pnt(TopoDS::Vertex(aShape2));
128       //      cout << aCounter+1 << " X = " <<  aDebPoint.X() << " Y = " <<  aDebPoint.Y() << " Z = " <<  aDebPoint.Z() << endl;
129     } else
130       cout << " Line3DDriver:: NS2 is empty" << endl;
131 #endif
132     if(aNS1->IsEmpty() || aNS2->IsEmpty() || 
133        aNS1->Get().IsNull() || aNS2->Get().IsNull()) {
134       aFunction->SetFailure(WRONG_ARGUMENT);
135       return -1;
136     }
137     aShape1 = aNS1->Get();
138     aShape2 = aNS2->Get();
139 #ifdef OCCT_DEBUG
140     gp_Pnt aDebPoint = BRep_Tool::Pnt(TopoDS::Vertex(aShape1));
141     //      cout << aCounter << " X = " <<  aDebPoint.X() << " Y = " <<  aDebPoint.Y() << " Z = " <<  aDebPoint.Z() << endl;
142     aDebPoint = BRep_Tool::Pnt(TopoDS::Vertex(aShape2));
143     //      cout << aCounter+1 << " X = " <<  aDebPoint.X() << " Y = " <<  aDebPoint.Y() << " Z = " <<  aDebPoint.Z() << endl;
144 #endif 
145     if(aShape1.ShapeType() != TopAbs_VERTEX || aShape2.ShapeType() != TopAbs_VERTEX) {
146       aFunction->SetFailure(WRONG_ARGUMENT);
147       return -1;
148     }
149     BRepBuilderAPI_MakeEdge aMakeEdge(TopoDS::Vertex(aShape1), TopoDS::Vertex(aShape2));
150     if(aMakeEdge.IsDone()) {
151       anArV.SetValue(aCounter,   aShape1);
152       anArV.SetValue(aCounter+1, aShape2);
153       aMakeWire.Add(aMakeEdge.Edge());
154     }
155   }
156 //  } else // closed
157   if(isClosed) { 
158     Handle(TDataStd_UAttribute) aRefP1 = DNaming::GetObjectArg(aFunction, (LINE3D_TYPE + 1));
159     aNS1 = DNaming::GetObjectValue(aRefP1);
160     aShape1 = aNS1->Get();
161     BRepBuilderAPI_MakeEdge aMakeEdge(TopoDS::Vertex(aShape2), TopoDS::Vertex(aShape1));
162     if(aMakeEdge.IsDone()) aMakeWire.Add(aMakeEdge.Edge());
163   }
164   if(aMakeWire.IsDone()) aWire = aMakeWire.Wire(); 
165   
166
167   if(aWire.IsNull()) {
168     aFunction->SetFailure(ALGO_FAILED);
169     return -1;
170   }
171
172   if (!BRepAlgo::IsValid(aWire)) {
173     aFunction->SetFailure(RESULT_NOT_VALID);
174     return -1;
175   }
176
177   TDF_Label aResultLabel = RESPOSITION(aFunction); //aFunction->GetResult()->Label();
178   try {  
179     LoadNamingDS(aResultLabel, aWire, anArV, isClosed);
180
181   } catch (Standard_Failure) {
182     aFunction->SetFailure(NAMING_FAILED);
183     return -1;
184   }
185
186   // restore location
187   if(!aLocation.IsIdentity())
188     TNaming::Displace(aResultLabel, aLocation, Standard_True);
189
190   theLog->SetValid(aResultLabel, Standard_True);  
191
192   aFunction->SetFailure(DONE);
193   return 0;
194 }
195
196 //=======================================================================
197 //function : LoadNamingDS
198 //purpose  : Loads a Line3D in a data framework
199 //=======================================================================
200 void DNaming_Line3DDriver::LoadNamingDS (const TDF_Label& theResultLabel, 
201                                          const TopoDS_Wire& theWire, 
202                                          const TopTools_Array1OfShape& theArV,
203                                          const Standard_Boolean isClosed) const
204 {
205   if(theWire.IsNull()) return;
206 //Wire
207   TNaming_Builder aWBuilder(theResultLabel);
208   aWBuilder.Generated(theWire);
209 #ifdef OCCT_DEBUG
210   TDataStd_Name::Set(theResultLabel, "Line3DCurve");
211 #endif
212   Standard_Integer aLength = theArV.Length();
213   if(aLength < 2) return;
214   TopoDS_Shape aShape;
215   TopTools_Array1OfShape anArE(1,aLength);
216   TopoDS_Vertex aFirst, aLast;
217   for(Standard_Integer i = 1;i < aLength;i++) {
218     gp_Pnt aP1  = BRep_Tool::Pnt(TopoDS::Vertex(theArV.Value(i)));
219     gp_Pnt aP2  = BRep_Tool::Pnt(TopoDS::Vertex(theArV.Value(i+1)));
220     Standard_Boolean aFound = Standard_False;
221     TopExp_Explorer anExp(theWire,TopAbs_EDGE);
222     for(;anExp.More();anExp.Next()) {
223       const TopoDS_Edge& anE = TopoDS::Edge(anExp.Current());
224       TopoDS_Vertex aV, aV1, aV2;
225       TopExp::Vertices(anE, aV1, aV2);
226       gp_Pnt aPE1 = BRep_Tool::Pnt(aV1);
227       gp_Pnt aPE2 = BRep_Tool::Pnt(aV2);
228       if(aP1.IsEqual(aPE1, Precision::Confusion()) && aP2.IsEqual(aPE2, Precision::Confusion())) {
229         anArE.SetValue(i, anE);
230         aFound = Standard_True;
231         break;
232       }
233     }
234     if(!aFound)
235       anArE.SetValue(i, aShape);
236     else aFound = Standard_False;
237   }
238   if(isClosed) {
239     Standard_Boolean aFound = Standard_False;
240     gp_Pnt aP1  = BRep_Tool::Pnt(TopoDS::Vertex(theArV.Value(aLength)));
241     gp_Pnt aP2  = BRep_Tool::Pnt(TopoDS::Vertex(theArV.Value(1)));
242     TopExp_Explorer anExp(theWire,TopAbs_EDGE);
243     for(;anExp.More();anExp.Next()) {
244       const TopoDS_Edge& anE = TopoDS::Edge(anExp.Current());
245       TopoDS_Vertex aV, aV1, aV2;
246       TopExp::Vertices(anE, aV1, aV2);
247       gp_Pnt aPE1 = BRep_Tool::Pnt(aV1);
248       gp_Pnt aPE2 = BRep_Tool::Pnt(aV2);
249       if(aP1.IsEqual(aPE1, Precision::Confusion()) && aP2.IsEqual(aPE2, Precision::Confusion())) {
250         anArE.SetValue(aLength, anE);
251         aFound = Standard_True;
252      // closed case
253         aFirst = aV2;
254         aLast  = aV1;
255         break;
256       }
257     }
258     if(!aFound)
259       anArE.SetValue(aLength, aShape);
260   } else {
261     // open
262     anArE.SetValue(aLength, aShape); // last edge
263     TopExp::Vertices(theWire, aFirst, aLast);
264   }
265
266   // put edges
267   // from 1:aLength - edges
268   for(Standard_Integer i1 = 1;i1 <= aLength ;i1++) {
269     TDF_Label aLab = theResultLabel.FindChild(i1);
270     if(!anArE.Value(i1).IsNull()) {
271       TNaming_Builder aBuilder(aLab);
272       aBuilder.Generated(anArE.Value(i1));
273     } else {
274       Handle(TNaming_NamedShape) aNS;
275       if(aLab.FindAttribute(TNaming_NamedShape::GetID(), aNS))
276         TNaming_Builder aB(aLab);
277     }
278   }
279   //put vertexes
280   // aLength +1 - first vertex
281   // aLength +2 - last vertex
282   TDF_Label aLab1 = theResultLabel.FindChild(aLength+1);
283   TDF_Label aLab2 = theResultLabel.FindChild(aLength+2);
284   if(!aFirst.IsNull()) {
285     TNaming_Builder aBuilder(aLab1);
286     aBuilder.Generated(aFirst);
287   } else {
288     Handle(TNaming_NamedShape) aNS;
289     if(aLab1.FindAttribute(TNaming_NamedShape::GetID(), aNS))
290       TNaming_Builder aB(aLab1);
291   }
292   if(!aLast.IsNull()) {
293     TNaming_Builder aBuilder(aLab2);
294     aBuilder.Generated(aLast);
295   } else {
296     Handle(TNaming_NamedShape) aNS;
297     if(aLab2.FindAttribute(TNaming_NamedShape::GetID(), aNS))
298       TNaming_Builder aB(aLab2);
299   }
300 }