Salome HOME
Update mail address
[modules/geom.git] / src / GEOMImpl / GEOMImpl_PartitionDriver.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_PartitionDriver.hxx>
24 #include <GEOMImpl_IPartition.hxx>
25 #include <GEOMImpl_Types.hxx>
26
27 #include <GEOM_Object.hxx>
28 #include <GEOM_Function.hxx>
29
30 #include <NMTAlgo_Splitter1.hxx>
31
32 #include <TDataStd_IntegerArray.hxx>
33
34 #include <BRep_Tool.hxx>
35 #include <BRepAlgo.hxx>
36
37 #include <TopoDS.hxx>
38 #include <TopoDS_Shape.hxx>
39 #include <TopoDS_Vertex.hxx>
40 #include <TopoDS_Wire.hxx>
41 #include <TopAbs.hxx>
42 #include <TopExp.hxx>
43 #include <TopTools_MapOfShape.hxx>
44 #include <TopTools_ListIteratorOfListOfShape.hxx>
45
46 #include <TColStd_ListIteratorOfListOfInteger.hxx>
47 #include <TColStd_ListOfInteger.hxx>
48 #include <Standard_NullObject.hxx>
49 #include <Precision.hxx>
50 #include <gp_Pnt.hxx>
51
52 //=======================================================================
53 //function : GetID
54 //purpose  :
55 //======================================================================= 
56 const Standard_GUID& GEOMImpl_PartitionDriver::GetID()
57 {
58   static Standard_GUID aPartitionDriver("FF1BBB22-5D14-4df2-980B-3A668264EA16");
59   return aPartitionDriver; 
60 }
61
62
63 //=======================================================================
64 //function : GEOMImpl_PartitionDriver
65 //purpose  : 
66 //=======================================================================
67 GEOMImpl_PartitionDriver::GEOMImpl_PartitionDriver() 
68 {
69 }
70
71 //=======================================================================
72 //function : Execute
73 //purpose  :
74 //======================================================================= 
75 Standard_Integer GEOMImpl_PartitionDriver::Execute(TFunction_Logbook& log) const
76 {
77   if (Label().IsNull()) return 0;    
78   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
79
80   GEOMImpl_IPartition aCI (aFunction);
81   Standard_Integer aType = aFunction->GetType();
82
83   TopoDS_Shape aShape;
84   NMTAlgo_Splitter1 PS;
85
86   if (aType == PARTITION_PARTITION) {
87     Handle(TColStd_HSequenceOfTransient) aShapes  = aCI.GetShapes();
88     Handle(TColStd_HSequenceOfTransient) aTools   = aCI.GetTools();
89     Handle(TColStd_HSequenceOfTransient) aKeepIns = aCI.GetKeepIns();
90     Handle(TColStd_HSequenceOfTransient) aRemIns  = aCI.GetRemoveIns();
91     Handle(TColStd_HArray1OfInteger) aMaterials   = aCI.GetMaterials();
92     Standard_Boolean DoRemoveWebs = !aMaterials.IsNull();
93
94     unsigned int ind, nbshapes = 0;
95     nbshapes += aShapes->Length() + aTools->Length();
96     nbshapes += aKeepIns->Length() + aRemIns->Length();
97
98     TopTools_MapOfShape ShapesMap(nbshapes), ToolsMap(nbshapes);
99
100     // add object shapes that are in ListShapes;
101     for (ind = 1; ind <= aShapes->Length(); ind++) {
102       Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
103       TopoDS_Shape aShape_i = aRefShape->GetValue();
104       if (aShape_i.IsNull()) {
105         Standard_NullObject::Raise("In Partition a shape is null");
106       }
107       if (ShapesMap.Add(aShape_i)) {
108         PS.AddShape(aShape_i);
109         if (DoRemoveWebs) {
110           if (aMaterials->Length() >= ind)
111             PS.SetMaterial(aShape_i, aMaterials->Value(ind));
112         }
113       }
114     }
115
116     // add tool shapes that are in ListTools and not in ListShapes;
117     for (ind = 1; ind <= aTools->Length(); ind++) {
118       Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aTools->Value(ind));
119       TopoDS_Shape aShape_i = aRefShape->GetValue();
120       if (aShape_i.IsNull()) {
121         Standard_NullObject::Raise("In Partition a tool shape is null");
122       }
123       if (!ShapesMap.Contains(aShape_i) && ToolsMap.Add(aShape_i))
124         PS.AddTool(aShape_i);
125     }
126
127     // add shapes that are in ListKeepInside, as object shapes;
128     for (ind = 1; ind <= aKeepIns->Length(); ind++) {
129       Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aKeepIns->Value(ind));
130       TopoDS_Shape aShape_i = aRefShape->GetValue();
131       if (aShape_i.IsNull()) {
132         Standard_NullObject::Raise("In Partition a Keep Inside shape is null");
133       }
134       if (!ToolsMap.Contains(aShape_i) && ShapesMap.Add(aShape_i))
135         PS.AddShape(aShape_i);
136     }
137
138     // add shapes that are in ListRemoveInside, as object shapes;
139     for (ind = 1; ind <= aRemIns->Length(); ind++) {
140       Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aRemIns->Value(ind));
141       TopoDS_Shape aShape_i = aRefShape->GetValue();
142       if (aShape_i.IsNull()) {
143         Standard_NullObject::Raise("In Partition a Remove Inside shape is null");
144       }
145       if (!ToolsMap.Contains(aShape_i) && ShapesMap.Add(aShape_i))
146         PS.AddShape(aShape_i);
147     }
148
149     PS.Compute();
150     PS.SetRemoveWebs(DoRemoveWebs);
151     PS.Build((TopAbs_ShapeEnum) aCI.GetLimit());
152
153     // suppress result outside of shapes in KInsideMap
154     for (ind = 1; ind <= aKeepIns->Length(); ind++) {
155       Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aKeepIns->Value(ind));
156       TopoDS_Shape aShape_i = aRefShape->GetValue();
157       PS.KeepShapesInside(aShape_i);
158     }
159
160     // suppress result inside of shapes in RInsideMap
161     for (ind = 1; ind <= aRemIns->Length(); ind++) {
162       Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aRemIns->Value(ind));
163       TopoDS_Shape aShape_i = aRefShape->GetValue();
164       PS.RemoveShapesInside(aShape_i);
165     }
166
167   } else if (aType == PARTITION_HALF) {
168     Handle(GEOM_Function) aRefShape = aCI.GetShape();
169     Handle(GEOM_Function) aRefPlane = aCI.GetPlane();
170     TopoDS_Shape aShapeArg = aRefShape->GetValue();
171     TopoDS_Shape aPlaneArg = aRefPlane->GetValue();
172
173     if (aShapeArg.IsNull() || aPlaneArg.IsNull()) {
174       Standard_NullObject::Raise("In Half Partition a shape or a plane is null");
175     }
176
177     // add object shapes that are in ListShapes;
178     PS.AddShape(aShapeArg);
179
180     // add tool shapes that are in ListTools and not in ListShapes;
181     PS.AddTool(aPlaneArg);
182
183     PS.Compute();
184     PS.SetRemoveWebs(Standard_False);
185     PS.Build(aShapeArg.ShapeType());
186
187   } else {
188   }
189
190   aShape = PS.Shape();
191   if (aShape.IsNull()) return 0;
192
193   if (!BRepAlgo::IsValid(aShape)) {
194     Standard_ConstructionError::Raise("Partition aborted : non valid shape result");
195   }
196
197   aFunction->SetValue(aShape);
198
199   // Fill history to be used by GetInPlace functionality
200   TopTools_IndexedMapOfShape aResIndices;
201   TopExp::MapShapes(aShape, aResIndices);
202
203   // history for all argument shapes
204   TDF_LabelSequence aLabelSeq;
205   aFunction->GetDependency(aLabelSeq);
206   Standard_Integer nbArg = aLabelSeq.Length();
207
208   for (Standard_Integer iarg = 1; iarg <= nbArg; iarg++) {
209
210     TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
211
212     Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
213     TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
214
215     TopTools_IndexedMapOfShape anArgumentIndices;
216     TopExp::MapShapes(anArgumentShape, anArgumentIndices);
217     Standard_Integer nbArgumentEntities = anArgumentIndices.Extent();
218
219     // Find corresponding label in history
220     TDF_Label anArgumentHistoryLabel =
221       aFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_True);
222
223     for (Standard_Integer ie = 1; ie <= nbArgumentEntities; ie++) {
224       TopoDS_Shape anEntity = anArgumentIndices.FindKey(ie);
225       const TopTools_ListOfShape& aModified = PS.Modified(anEntity);
226       Standard_Integer nbModified = aModified.Extent();
227
228       if (nbModified > 0) {
229         TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(ie, Standard_True);
230         Handle(TDataStd_IntegerArray) anAttr =
231           TDataStd_IntegerArray::Set(aWhatHistoryLabel, 1, nbModified);
232
233         TopTools_ListIteratorOfListOfShape itM (aModified);
234         for (int im = 1; itM.More(); itM.Next(), ++im) {
235           int id = aResIndices.FindIndex(itM.Value());
236           anAttr->SetValue(im, id);
237         }
238       }
239     }
240   }
241
242   log.SetTouched(Label());
243
244   return 1;
245 }
246
247
248 //=======================================================================
249 //function :  GEOMImpl_PartitionDriver_Type_
250 //purpose  :
251 //======================================================================= 
252 Standard_EXPORT Handle_Standard_Type& GEOMImpl_PartitionDriver_Type_()
253 {
254
255   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
256   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
257   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
258   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared); 
259   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
260   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
261  
262
263   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
264   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_PartitionDriver",
265                                                          sizeof(GEOMImpl_PartitionDriver),
266                                                          1,
267                                                          (Standard_Address)_Ancestors,
268                                                          (Standard_Address)NULL);
269
270   return _aType;
271 }
272
273 //=======================================================================
274 //function : DownCast
275 //purpose  :
276 //======================================================================= 
277 const Handle(GEOMImpl_PartitionDriver) Handle(GEOMImpl_PartitionDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
278 {
279   Handle(GEOMImpl_PartitionDriver) _anOtherObject;
280
281   if (!AnObject.IsNull()) {
282      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_PartitionDriver))) {
283        _anOtherObject = Handle(GEOMImpl_PartitionDriver)((Handle(GEOMImpl_PartitionDriver)&)AnObject);
284      }
285   }
286
287   return _anOtherObject ;
288 }