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