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