Salome HOME
PAL7508: Development of GetInPlace() functionality
[modules/geom.git] / src / GEOMImpl / GEOMImpl_GlueDriver.cxx
1
2 using namespace std;
3 #include "GEOMImpl_GlueDriver.hxx"
4 #include "GEOMImpl_IGlue.hxx"
5 #include "GEOMImpl_Types.hxx"
6
7 #include "GEOM_Object.hxx"
8 #include "GEOM_Function.hxx"
9
10 #include "GEOMAlgo_Gluer.hxx"
11
12 #include "utilities.h"
13
14 #include <TDataStd_IntegerArray.hxx>
15
16 #include <TopExp.hxx>
17 #include <TopoDS_Shape.hxx>
18 #include <TopTools_ListOfShape.hxx>
19 #include <TopTools_IndexedMapOfShape.hxx>
20 #include <TopTools_ListIteratorOfListOfShape.hxx>
21
22 #include <Standard_NullObject.hxx>
23 #include <Standard_Failure.hxx>
24
25 //=======================================================================
26 //function : GEOMImpl_GlueDriver
27 //purpose  :
28 //=======================================================================
29 GEOMImpl_GlueDriver::GEOMImpl_GlueDriver()
30 {
31 }
32
33 //=======================================================================
34 //function : GetID
35 //purpose  :
36 //=======================================================================
37 const Standard_GUID& GEOMImpl_GlueDriver::GetID()
38 {
39   static Standard_GUID aGlueDriver("FF1BBB63-5D14-4df2-980B-3A668264EA16");
40   return aGlueDriver;
41 }
42
43 //=======================================================================
44 //function : GlueFacesWithWarnings
45 //purpose  :
46 //=======================================================================
47 TopoDS_Shape GEOMImpl_GlueDriver::GlueFacesWithWarnings (const TopoDS_Shape& theShape,
48                                                          const Standard_Real theTolerance,
49                                                          TCollection_AsciiString& theWarning) const
50 {
51   Standard_Integer iErr, iWrn;
52   TopoDS_Shape aRes;
53   GEOMAlgo_Gluer aGluer;
54
55   aGluer.SetShape(theShape);
56   aGluer.SetTolerance(theTolerance);
57   aGluer.SetCheckGeometry(Standard_True);
58
59   aGluer.Perform();
60
61   iErr = aGluer.ErrorStatus();
62   if (iErr) {
63     switch (iErr) {
64     case 2:
65       Standard_Failure::Raise("No vertices found in source shape");
66       break;
67     case 5:
68       Standard_Failure::Raise("Source shape is Null");
69       break;
70     case 6:
71       Standard_Failure::Raise("Result shape is Null");
72       break;
73     case 200:
74       Standard_Failure::Raise("Error occured during check of geometric coincidence");
75       break;
76     default:
77       {
78         // description of all errors see in GEOMAlgo_Gluer.cxx
79         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer with code ");
80         aMsg += TCollection_AsciiString(iErr);
81         Standard_Failure::Raise(aMsg.ToCString());
82         break;
83       }
84     }
85     return aRes;
86   }
87
88   iWrn = aGluer.WarningStatus();
89   if (iWrn) {
90     switch (iWrn) {
91     case 1:
92       {
93         Standard_Integer nbAlone = aGluer.AloneShapes();
94         theWarning = TCollection_AsciiString(nbAlone);
95         theWarning += " solid(s) can not be glued by faces";
96       }
97       break;
98     default:
99       // description of all warnings see in GEOMAlgo_Gluer.cxx
100       theWarning = "Warning in GEOMAlgo_Gluer with code ";
101       theWarning += TCollection_AsciiString(iWrn);
102       break;
103     }
104   }
105
106   aRes = aGluer.Result();
107
108   // Fill history to be used by GetInPlace functionality
109   TopTools_IndexedMapOfShape aResIndices;
110   TopExp::MapShapes(aRes, aResIndices);
111
112   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
113
114   // history for all argument shapes
115   TDF_LabelSequence aLabelSeq;
116   aFunction->GetDependency(aLabelSeq);
117   Standard_Integer nbArg = aLabelSeq.Length();
118
119   for (Standard_Integer iarg = 1; iarg <= nbArg; iarg++) {
120
121     TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
122
123     Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
124     TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
125
126     TopTools_IndexedMapOfShape anArgumentIndices;
127     TopExp::MapShapes(anArgumentShape, anArgumentIndices);
128     Standard_Integer nbArgumentEntities = anArgumentIndices.Extent();
129
130     // Find corresponding label in history
131     TDF_Label anArgumentHistoryLabel =
132       aFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_True);
133
134     for (Standard_Integer ie = 1; ie <= nbArgumentEntities; ie++) {
135       TopoDS_Shape anEntity = anArgumentIndices.FindKey(ie);
136       const TopTools_ListOfShape& aModified = aGluer.Modified(anEntity);
137       Standard_Integer nbModified = aModified.Extent();
138
139       if (nbModified > 0) {
140         TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(ie, Standard_True);
141         Handle(TDataStd_IntegerArray) anAttr =
142           TDataStd_IntegerArray::Set(aWhatHistoryLabel, 1, nbModified);
143
144         TopTools_ListIteratorOfListOfShape itM (aModified);
145         for (int im = 1; itM.More(); itM.Next(), ++im) {
146           int id = aResIndices.FindIndex(itM.Value());
147           anAttr->SetValue(im, id);
148         }
149       }
150     }
151   }
152
153   return aRes;
154 }
155
156 //=======================================================================
157 //function : GlueFaces
158 //purpose  :
159 //=======================================================================
160 TopoDS_Shape GEOMImpl_GlueDriver::GlueFaces (const TopoDS_Shape& theShape,
161                                              const Standard_Real theTolerance)
162 {
163   Standard_Integer iErr, iWrn;
164   TopoDS_Shape aRes;
165   GEOMAlgo_Gluer aGluer;
166
167   aGluer.SetShape(theShape);
168   aGluer.SetTolerance(theTolerance);
169   aGluer.SetCheckGeometry(Standard_True);
170
171   aGluer.Perform();
172
173   iErr = aGluer.ErrorStatus();
174   if (iErr) {
175     switch (iErr) {
176     case 2:
177       Standard_Failure::Raise("No vertices found in source shape");
178       break;
179     case 5:
180       Standard_Failure::Raise("Source shape is Null");
181       break;
182     case 6:
183       Standard_Failure::Raise("Result shape is Null");
184       break;
185     case 200:
186       Standard_Failure::Raise("Error occured during check of geometric coincidence");
187       break;
188     default:
189       {
190         // description of all errors see in GEOMAlgo_Gluer.cxx
191         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer with code ");
192         aMsg += TCollection_AsciiString(iErr);
193         Standard_Failure::Raise(aMsg.ToCString());
194         break;
195       }
196     }
197     return aRes;
198   }
199
200   iWrn = aGluer.WarningStatus();
201   if (iWrn) {
202     switch (iWrn) {
203     case 1:
204       MESSAGE("Some shapes can not be glued by faces");
205       break;
206     default:
207       // description of all warnings see in GEOMAlgo_Gluer.cxx
208       MESSAGE("Warning in GEOMAlgo_Gluer with code " << iWrn);
209       break;
210     }
211   }
212
213   aRes = aGluer.Result();
214
215   return aRes;
216 }
217
218 //=======================================================================
219 //function : Execute
220 //purpose  :
221 //=======================================================================
222 Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const
223 {
224   if (Label().IsNull()) return 0;
225   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
226
227   GEOMImpl_IGlue aCI (aFunction);
228   Standard_Integer aType = aFunction->GetType();
229
230   TopoDS_Shape aShape;
231   TCollection_AsciiString aWrn;
232
233   if (aType == GLUE_FACES) {
234     Handle(GEOM_Function) aRefBase = aCI.GetBase();
235     TopoDS_Shape aShapeBase = aRefBase->GetValue();
236     if (aShapeBase.IsNull()) {
237       Standard_NullObject::Raise("Shape for gluing is null");
238     }
239
240     Standard_Real tol3d = aCI.GetTolerance();
241     aShape = GlueFacesWithWarnings(aShapeBase, tol3d, aWrn);
242   } else {
243   }
244
245   if (aShape.IsNull()) return 0;
246
247   aFunction->SetValue(aShape);
248
249   log.SetTouched(Label());
250
251   if (!aWrn.IsEmpty()) {
252     Standard_Failure::Raise(aWrn.ToCString());
253   }
254
255   return 1;
256 }
257
258 //=======================================================================
259 //function :  GEOMImpl_GlueDriver_Type_
260 //purpose  :
261 //=======================================================================
262 Standard_EXPORT Handle_Standard_Type& GEOMImpl_GlueDriver_Type_()
263 {
264
265   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
266   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
267   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
268   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
269   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
270   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
271
272
273   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
274   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_GlueDriver",
275                                                          sizeof(GEOMImpl_GlueDriver),
276                                                          1,
277                                                          (Standard_Address)_Ancestors,
278                                                          (Standard_Address)NULL);
279
280   return _aType;
281 }
282
283 //=======================================================================
284 //function : DownCast
285 //purpose  :
286 //=======================================================================
287 const Handle(GEOMImpl_GlueDriver) Handle(GEOMImpl_GlueDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
288 {
289   Handle(GEOMImpl_GlueDriver) _anOtherObject;
290
291   if (!AnObject.IsNull()) {
292      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_GlueDriver))) {
293        _anOtherObject = Handle(GEOMImpl_GlueDriver)((Handle(GEOMImpl_GlueDriver)&)AnObject);
294      }
295   }
296
297   return _anOtherObject ;
298 }