3 #include "GEOMImpl_IGroupOperations.hxx"
5 #include "GEOMImpl_Types.hxx"
7 #include "GEOM_Function.hxx"
8 #include "GEOM_ISubShape.hxx"
10 #include "utilities.h"
12 #include "Utils_ExceptHandlers.hxx"
14 #include <TFunction_DriverTable.hxx>
15 #include <TFunction_Driver.hxx>
16 #include <TFunction_Logbook.hxx>
17 #include <TDF_Tool.hxx>
18 #include <TDataStd_Integer.hxx>
21 #include <TopTools_IndexedMapOfShape.hxx>
23 #include <TColStd_HArray1OfInteger.hxx>
24 #include <TColStd_MapOfInteger.hxx>
25 #include <TColStd_ListOfInteger.hxx>
26 #include <TColStd_ListIteratorOfListOfInteger.hxx>
28 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
30 //=============================================================================
34 //=============================================================================
35 GEOMImpl_IGroupOperations::GEOMImpl_IGroupOperations (GEOM_Engine* theEngine, int theDocID)
36 : GEOM_IOperations(theEngine, theDocID)
38 MESSAGE("GEOMImpl_IGroupOperations::GEOMImpl_IGroupOperations");
41 //=============================================================================
45 //=============================================================================
46 GEOMImpl_IGroupOperations::~GEOMImpl_IGroupOperations()
48 MESSAGE("GEOMImpl_IGroupOperations::~GEOMImpl_IGroupOperations");
52 //=============================================================================
56 //=============================================================================
57 Handle(GEOM_Object) GEOMImpl_IGroupOperations::CreateGroup(Handle(GEOM_Object) theMainShape, TopAbs_ShapeEnum theShapeType)
61 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
62 anArray->SetValue(1, -1);
64 //Add a new Fillet object
65 Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(theMainShape, anArray);
68 aGroup->SetType(GEOM_GROUP);
70 //Set a sub shape type
71 TDF_Label aFreeLabel = aGroup->GetFreeLabel();
72 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)theShapeType);
74 //Make a Python command
75 TCollection_AsciiString anEntry, aDescr("");
76 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
77 aDescr = anEntry + " = IGroupOperations.CreateGroup(";
78 TDF_Tool::Entry(theMainShape->GetEntry(), anEntry);
79 aDescr += (anEntry+", ");
80 aDescr += (TCollection_AsciiString((int)theShapeType)+")");
82 Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
83 aFunction->SetDescription(aDescr);
89 //=============================================================================
93 //=============================================================================
94 void GEOMImpl_IGroupOperations::AddObject(Handle(GEOM_Object) theGroup, int theSubShapeID)
97 if(theGroup.IsNull()) return;
99 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
100 if(aFunction.IsNull()) return;
102 GEOM_ISubShape aSSI(aFunction);
103 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
104 if(aSeq.IsNull()) return;
105 if(aSeq->Length() == 1 && aSeq->Value(1) == -1) {
106 aSeq->SetValue(1, theSubShapeID);
109 Standard_Integer aLength = aSeq->Length();
110 Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aLength+1);
111 for(Standard_Integer i = 1; i<=aLength; i++) {
112 aNewSeq->SetValue(i, aSeq->Value(i));
113 if(aSeq->Value(i) == theSubShapeID) {
114 SetErrorCode(ALREADY_PRESENT);
118 aNewSeq->SetValue(aLength+1, theSubShapeID);
119 aSSI.SetIndices(aNewSeq);
126 //=============================================================================
130 //=============================================================================
131 void GEOMImpl_IGroupOperations::RemoveObject(Handle(GEOM_Object) theGroup, int theSubShapeID)
134 if(theGroup.IsNull()) return;
136 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
137 if(aFunction.IsNull()) return;
139 GEOM_ISubShape aSSI(aFunction);
140 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
141 if(aSeq.IsNull()) return;
142 if(aSeq->Length() == 1 && aSeq->Value(1) == -1) {
143 SetErrorCode(NOT_EXISTS);
147 Handle(TColStd_HArray1OfInteger) aNewSeq;
148 Standard_Integer aLength = aSeq->Length();
150 if(aSeq->Value(1) != theSubShapeID) {
151 SetErrorCode(NOT_EXISTS);
154 aNewSeq = new TColStd_HArray1OfInteger(1,1);
155 aNewSeq->SetValue(1, -1);
158 aNewSeq = new TColStd_HArray1OfInteger(1, aLength-1);
159 Standard_Boolean isFound = Standard_False;
160 for(Standard_Integer i = 1, k=1; i<=aLength; i++) {
161 if(i == aLength && !isFound) {
162 SetErrorCode(NOT_EXISTS);
165 if(aSeq->Value(i) == theSubShapeID) {
166 isFound = Standard_True;
169 aNewSeq->SetValue(k, aSeq->Value(i));
174 SetErrorCode(NOT_EXISTS);
179 aSSI.SetIndices(aNewSeq);
186 //=============================================================================
190 //=============================================================================
191 void GEOMImpl_IGroupOperations::UnionList (Handle(GEOM_Object) theGroup,
192 const Handle(TColStd_HSequenceOfTransient)& theSubShapes)
195 if (theGroup.IsNull()) return;
197 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
198 if (aFunction.IsNull()) return;
200 GEOM_ISubShape aSSI (aFunction);
202 // New contents of the group
203 TColStd_ListOfInteger aNewIDs;
204 TColStd_MapOfInteger mapIDs;
206 // Add current IDs to the list
207 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
208 if (aSeq.IsNull()) return;
209 Standard_Integer val_j, aLength = aSeq->Length();
211 for (Standard_Integer j = 1; j <= aLength; j++) {
212 val_j = aSeq->Value(j);
213 if (val_j > 0 && mapIDs.Add(val_j)) {
214 aNewIDs.Append(val_j);
219 Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
220 if (aMainShapeFunc.IsNull()) return;
221 TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
222 if (aLabel.IsRoot()) return;
223 Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
224 if (aMainObj.IsNull()) return;
225 TopoDS_Shape aMainShape = aMainObj->GetValue();
226 if (aMainShape.IsNull()) return;
228 TopTools_IndexedMapOfShape mapIndices;
229 TopExp::MapShapes(aMainShape, mapIndices);
231 // Get IDs of sub-shapes to add
232 Standard_Integer i, new_id, aLen = theSubShapes->Length();
233 for (i = 1; i <= aLen; i++) {
234 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
236 if (anObj_i->IsMainShape()) {
237 TopoDS_Shape aShape_i = anObj_i->GetValue();
238 if (mapIndices.Contains(aShape_i)) {
239 new_id = mapIndices.FindIndex(aShape_i);
240 if (mapIDs.Add(new_id)) {
241 aNewIDs.Append(new_id);
244 SetErrorCode("One of given objects can not be added to the group, because it is not a sub-shape of the group's main shape");
248 // Check main shape of sub-shape to add
249 Handle(GEOM_Function) aFunc_i = anObj_i->GetFunction(1);
250 if (aFunc_i.IsNull()) return;
252 GEOM_ISubShape aSSI_i (aFunc_i);
254 Handle(GEOM_Function) aMainShapeFunc_i = aSSI_i.GetMainShape();
255 if (aMainShapeFunc_i.IsNull()) return;
256 TDF_Label aLabel_i = aMainShapeFunc_i->GetOwnerEntry();
257 if (aLabel_i.IsRoot()) return;
258 Handle(GEOM_Object) aMainObj_i = GEOM_Object::GetObject(aLabel);
259 if (aMainObj_i.IsNull()) return;
260 TopoDS_Shape aMainShape_i = aMainObj_i->GetValue();
261 if (aMainShape_i.IsNull()) return;
263 if (aMainShape_i.IsSame(aMainShape)) {
264 // add all sub-shape IDs to the list
267 Handle(TColStd_HArray1OfInteger) aSeq_i = aSSI_i.GetIndices();
268 if (aSeq_i.IsNull()) return;
269 Standard_Integer aLength_i = aSeq_i->Length();
271 for (Standard_Integer i_j = 1; i_j <= aLength_i; i_j++) {
272 new_id = aSeq_i->Value(i_j);
274 if (mapIDs.Add(new_id)) {
275 aNewIDs.Append(new_id);
280 } else if (mapIndices.Contains(aMainShape_i)) {
281 // compute new IDs and add them to the list
282 TopTools_IndexedMapOfShape mapIndices_i;
283 TopExp::MapShapes(aMainShape_i, mapIndices_i);
286 Handle(TColStd_HArray1OfInteger) aSeq_i = aSSI_i.GetIndices();
287 if (aSeq_i.IsNull()) return;
288 Standard_Integer aLength_i = aSeq_i->Length();
290 for (Standard_Integer i_j = 1; i_j <= aLength_i; i_j++) {
291 if (aSeq_i->Value(i_j) > 0) {
292 TopoDS_Shape aShape_i_j = mapIndices_i.FindKey(i_j);
293 new_id = mapIndices.FindIndex(aShape_i_j);
294 if (mapIDs.Add(new_id)) {
295 aNewIDs.Append(new_id);
301 SetErrorCode("One of given objects can not be added to the group, because it is not a sub-shape of the group's main shape");
307 if (aNewIDs.Extent() > 0) {
308 Standard_Integer k = 1;
309 TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
310 Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aNewIDs.Extent());
311 for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
312 aNewSeq->SetValue(k, aNewIDsIter.Value());
315 aSSI.SetIndices(aNewSeq);
321 //=============================================================================
325 //=============================================================================
326 void GEOMImpl_IGroupOperations::DifferenceList (Handle(GEOM_Object) theGroup,
327 const Handle(TColStd_HSequenceOfTransient)& theSubShapes)
330 if (theGroup.IsNull()) return;
332 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
333 if (aFunction.IsNull()) return;
335 GEOM_ISubShape aSSI (aFunction);
337 // Map of IDs to be removed
338 TColStd_MapOfInteger mapIDsToRemove;
340 // Map of current IDs
341 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
342 if (aSeq.IsNull()) return;
343 Standard_Integer aLength = aSeq->Length();
345 if (aLength == 1 && aSeq->Value(1) == -1) // empty group
348 TColStd_MapOfInteger mapIDsCurrent;
349 Standard_Integer j = 1;
350 for (; j <= aLength; j++) {
351 mapIDsCurrent.Add(aSeq->Value(j));
355 Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
356 if (aMainShapeFunc.IsNull()) return;
357 TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
358 if (aLabel.IsRoot()) return;
359 Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
360 if (aMainObj.IsNull()) return;
361 TopoDS_Shape aMainShape = aMainObj->GetValue();
362 if (aMainShape.IsNull()) return;
364 TopTools_IndexedMapOfShape mapIndices;
365 TopExp::MapShapes(aMainShape, mapIndices);
367 // Get IDs of sub-shapes to be removed
368 Standard_Integer i, rem_id, aLen = theSubShapes->Length();
369 for (i = 1; i <= aLen; i++) {
370 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
372 if (anObj_i->IsMainShape()) {
373 TopoDS_Shape aShape_i = anObj_i->GetValue();
374 if (mapIndices.Contains(aShape_i)) {
375 rem_id = mapIndices.FindIndex(aShape_i);
376 if (mapIDsCurrent.Contains(rem_id)) {
377 mapIDsToRemove.Add(rem_id);
380 SetErrorCode("One of given objects can not be removed from the group, because it is not a sub-shape of the group's main shape");
384 // Check main shape of sub-shape to be removed
385 Handle(GEOM_Function) aFunc_i = anObj_i->GetFunction(1);
386 if (aFunc_i.IsNull()) return;
388 GEOM_ISubShape aSSI_i (aFunc_i);
390 Handle(GEOM_Function) aMainShapeFunc_i = aSSI_i.GetMainShape();
391 if (aMainShapeFunc_i.IsNull()) return;
392 TDF_Label aLabel_i = aMainShapeFunc_i->GetOwnerEntry();
393 if (aLabel_i.IsRoot()) return;
394 Handle(GEOM_Object) aMainObj_i = GEOM_Object::GetObject(aLabel);
395 if (aMainObj_i.IsNull()) return;
396 TopoDS_Shape aMainShape_i = aMainObj_i->GetValue();
397 if (aMainShape_i.IsNull()) return;
399 if (aMainShape_i.IsSame(aMainShape)) {
400 // remove all sub-shapes
403 Handle(TColStd_HArray1OfInteger) aSeq_i = aSSI_i.GetIndices();
404 if (aSeq_i.IsNull()) return;
405 Standard_Integer aLength_i = aSeq_i->Length();
407 for (Standard_Integer i_j = 1; i_j <= aLength_i; i_j++) {
408 rem_id = aSeq_i->Value(i_j);
410 if (mapIDsCurrent.Contains(rem_id)) {
411 mapIDsToRemove.Add(rem_id);
416 } else if (mapIndices.Contains(aMainShape_i)) {
417 // compute new IDs and add them to the map of ids to be removed
418 TopTools_IndexedMapOfShape mapIndices_i;
419 TopExp::MapShapes(aMainShape_i, mapIndices_i);
422 Handle(TColStd_HArray1OfInteger) aSeq_i = aSSI_i.GetIndices();
423 if (aSeq_i.IsNull()) return;
424 Standard_Integer aLength_i = aSeq_i->Length();
426 for (Standard_Integer i_j = 1; i_j <= aLength_i; i_j++) {
427 if (aSeq_i->Value(i_j) > 0) {
428 TopoDS_Shape aShape_i_j = mapIndices_i.FindKey(i_j);
429 rem_id = mapIndices.FindIndex(aShape_i_j);
430 if (mapIDsCurrent.Contains(rem_id)) {
431 mapIDsToRemove.Add(rem_id);
437 SetErrorCode("One of given objects can not be removed from the group, because it is not a sub-shape of the group's main shape");
443 if (mapIDsToRemove.Extent() > 0) {
444 Standard_Integer k = 1, aRemLength = mapIDsToRemove.Extent();
445 Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aLength - aRemLength);
447 for (j = 1; j <= aLength; j++) {
448 if (!mapIDsToRemove.Contains(aSeq->Value(j))) {
449 aNewSeq->SetValue(k, aSeq->Value(j));
454 aSSI.SetIndices(aNewSeq);
460 //=============================================================================
464 //=============================================================================
465 TopAbs_ShapeEnum GEOMImpl_IGroupOperations::GetType(Handle(GEOM_Object) theGroup)
469 TDF_Label aFreeLabel = theGroup->GetFreeLabel();
470 Handle(TDataStd_Integer) anAttrib;
471 if(!aFreeLabel.FindAttribute(TDataStd_Integer::GetID(), anAttrib)) return TopAbs_SHAPE;
474 return (TopAbs_ShapeEnum) anAttrib->Get();
477 //=============================================================================
481 //=============================================================================
482 Handle(GEOM_Object) GEOMImpl_IGroupOperations::GetMainShape(Handle(GEOM_Object) theGroup)
486 if(theGroup.IsNull()) return NULL;
488 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
489 if(aFunction.IsNull()) return NULL;
491 GEOM_ISubShape aSSI(aFunction);
492 aFunction = aSSI.GetMainShape();
493 if(aFunction.IsNull()) return NULL;
495 TDF_Label aLabel = aFunction->GetOwnerEntry();
496 Handle(GEOM_Object) aMainShape = GEOM_Object::GetObject(aLabel);
497 if(aMainShape.IsNull()) return NULL;
503 //=============================================================================
507 //=============================================================================
508 Handle(TColStd_HArray1OfInteger) GEOMImpl_IGroupOperations::GetObjects(Handle(GEOM_Object) theGroup)
512 if(theGroup.IsNull()) return NULL;
514 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
515 if(aFunction.IsNull()) return NULL;
517 GEOM_ISubShape aSSI(aFunction);
518 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
519 if(aSeq.IsNull()) return NULL;
521 if(aSeq->Length() == 1 && aSeq->Value(1) == -1) {