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