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