Salome HOME
Optimization of GetShapesOn<xxx> functionality
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IShapesOperations.cxx
1 using namespace std;
2
3 #include "GEOMImpl_IShapesOperations.hxx"
4
5 #include "GEOMImpl_Types.hxx"
6
7 #include "GEOMImpl_VectorDriver.hxx"
8 #include "GEOMImpl_ShapeDriver.hxx"
9 #include "GEOMImpl_CopyDriver.hxx"
10 #include "GEOMImpl_GlueDriver.hxx"
11
12 #include "GEOMImpl_IVector.hxx"
13 #include "GEOMImpl_IShapes.hxx"
14 #include "GEOMImpl_IGlue.hxx"
15
16 #include "GEOMImpl_Block6Explorer.hxx"
17
18 #include "GEOM_Function.hxx"
19
20 #include "GEOMAlgo_FinderShapeOn1.hxx"
21
22 #include "utilities.h"
23 #include "OpUtil.hxx"
24 #include "Utils_ExceptHandlers.hxx"
25
26 #include <TFunction_DriverTable.hxx>
27 #include <TFunction_Driver.hxx>
28 #include <TFunction_Logbook.hxx>
29 #include <TDataStd_Integer.hxx>
30 #include <TDataStd_IntegerArray.hxx>
31 #include <TDF_Tool.hxx>
32
33 #include <BRepExtrema_ExtCF.hxx>
34
35 #include <BRep_Tool.hxx>
36 #include <BRepGProp.hxx>
37 #include <BRepAdaptor_Curve.hxx>
38 #include <BRepBndLib.hxx>
39 #include <BRepBuilderAPI_MakeFace.hxx>
40 #include <BRepMesh_IncrementalMesh.hxx>
41
42 #include <TopAbs.hxx>
43 #include <TopExp.hxx>
44 #include <TopoDS.hxx>
45 #include <TopoDS_Shape.hxx>
46 #include <TopoDS_Face.hxx>
47 #include <TopoDS_Edge.hxx>
48 #include <TopoDS_Vertex.hxx>
49 #include <TopoDS_Iterator.hxx>
50 #include <TopExp_Explorer.hxx>
51 #include <TopLoc_Location.hxx>
52 #include <TopTools_MapOfShape.hxx>
53 #include <TopTools_Array1OfShape.hxx>
54 #include <TopTools_ListIteratorOfListOfShape.hxx>
55 #include <TopTools_IndexedMapOfShape.hxx>
56
57 #include <Geom_Surface.hxx>
58 #include <Geom_Plane.hxx>
59 #include <Geom_SphericalSurface.hxx>
60 #include <Geom_CylindricalSurface.hxx>
61 #include <GeomAdaptor_Surface.hxx>
62
63 #include <Geom2d_Curve.hxx>
64
65 #include <Bnd_Box.hxx>
66 #include <GProp_GProps.hxx>
67 #include <gp_Pnt.hxx>
68 #include <gp_Lin.hxx>
69 #include <TColStd_Array1OfReal.hxx>
70 #include <TColStd_HArray1OfInteger.hxx>
71 #include <TColStd_ListOfInteger.hxx>
72 #include <TColStd_ListIteratorOfListOfInteger.hxx>
73
74 //#include <OSD_Timer.hxx>
75
76 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
77
78 //=============================================================================
79 /*!
80  *   constructor:
81  */
82 //=============================================================================
83 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
84 : GEOM_IOperations(theEngine, theDocID)
85 {
86   MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
87 }
88
89 //=============================================================================
90 /*!
91  *  destructor
92  */
93 //=============================================================================
94 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
95 {
96   MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
97 }
98
99
100 //=============================================================================
101 /*!
102  *  MakeEdge
103  */
104 //=============================================================================
105 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
106                      (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
107 {
108   SetErrorCode(KO);
109
110   if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
111
112   //Add a new Edge object
113   Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
114
115   //Add a new Vector function
116   Handle(GEOM_Function) aFunction =
117     anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
118
119   //Check if the function is set correctly
120   if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
121
122   GEOMImpl_IVector aPI (aFunction);
123
124   Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
125   Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
126   if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
127
128   aPI.SetPoint1(aRef1);
129   aPI.SetPoint2(aRef2);
130
131   //Compute the Edge value
132   try {
133     if (!GetSolver()->ComputeFunction(aFunction)) {
134       SetErrorCode("Vector driver failed");
135       return NULL;
136     }
137   }
138   catch (Standard_Failure) {
139     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
140     SetErrorCode(aFail->GetMessageString());
141     return NULL;
142   }
143
144   //Make a Python command
145   TCollection_AsciiString anEntry, aDescr;
146   TDF_Tool::Entry(anEdge->GetEntry(), anEntry);
147   aDescr += (anEntry+" = IShapesOperations.MakeEdge(");
148   TDF_Tool::Entry(thePnt1->GetEntry(), anEntry);
149   aDescr += (anEntry+", ");
150   TDF_Tool::Entry(thePnt2->GetEntry(), anEntry);
151   aDescr += (anEntry+")");
152
153   aFunction->SetDescription(aDescr);
154
155   SetErrorCode(OK);
156   return anEdge;
157 }
158
159 //=============================================================================
160 /*!
161  *  MakeWire
162  */
163 //=============================================================================
164 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
165                              (list<Handle(GEOM_Object)> theShapes)
166 {
167   return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
168 }
169
170 //=============================================================================
171 /*!
172  *  MakeFace
173  */
174 //=============================================================================
175 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
176                                                           const bool isPlanarWanted)
177 {
178   SetErrorCode(KO);
179
180   if (theWire.IsNull()) return NULL;
181
182   //Add a new Face object
183   Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
184
185   //Add a new Shape function for creation of a face from a wire
186   Handle(GEOM_Function) aFunction =
187     aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
188   if (aFunction.IsNull()) return NULL;
189
190   //Check if the function is set correctly
191   if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
192
193   GEOMImpl_IShapes aCI (aFunction);
194
195   Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
196
197   if (aRefWire.IsNull()) return NULL;
198
199   aCI.SetBase(aRefWire);
200   aCI.SetIsPlanar(isPlanarWanted);
201
202   //Compute the Face value
203   try {
204     if (!GetSolver()->ComputeFunction(aFunction)) {
205       SetErrorCode("Shape driver failed to compute a face");
206       return NULL;
207     }
208   }
209   catch (Standard_Failure) {
210     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
211     SetErrorCode(aFail->GetMessageString());
212     return NULL;
213   }
214
215   //Make a Python command
216   TCollection_AsciiString anEntry, aDescr;
217   TDF_Tool::Entry(aFace->GetEntry(), anEntry);
218   aDescr += anEntry;
219   aDescr += " = IShapesOperations.MakeFace(";
220   TDF_Tool::Entry(theWire->GetEntry(), anEntry);
221   aDescr += anEntry;
222   if (isPlanarWanted)
223     aDescr += ", 1)";
224
225   else
226     aDescr += ", 0)";
227
228   aFunction->SetDescription(aDescr);
229
230   SetErrorCode(OK);
231   return aFace;
232 }
233
234 //=============================================================================
235 /*!
236  *  MakeFaceWires
237  */
238 //=============================================================================
239 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
240                              (list<Handle(GEOM_Object)> theShapes,
241                               const bool isPlanarWanted)
242 {
243   SetErrorCode(KO);
244
245   //Add a new object
246   Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
247
248   //Add a new function
249   Handle(GEOM_Function) aFunction =
250     aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
251   if (aFunction.IsNull()) return NULL;
252
253   //Check if the function is set correctly
254   if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
255
256   GEOMImpl_IShapes aCI (aFunction);
257
258   Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
259
260   // Shapes
261   list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
262   for (; it != theShapes.end(); it++) {
263     Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
264     if (aRefSh.IsNull()) {
265       SetErrorCode("NULL argument shape for the face construction");
266       return NULL;
267     }
268     aShapesSeq->Append(aRefSh);
269   }
270   aCI.SetShapes(aShapesSeq);
271
272   aCI.SetIsPlanar(isPlanarWanted);
273
274   //Compute the shape
275   try {
276     if (!GetSolver()->ComputeFunction(aFunction)) {
277       SetErrorCode("Shape driver failed");
278       return NULL;
279     }
280   }
281   catch (Standard_Failure) {
282     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
283     SetErrorCode(aFail->GetMessageString());
284     return NULL;
285   }
286
287   //Make a Python command
288   TCollection_AsciiString anEntry, aDescr;
289   TDF_Tool::Entry(aShape->GetEntry(), anEntry);
290   aDescr += (anEntry + " = IShapesOperations.MakeFaceWires([");
291   // Shapes
292   it = theShapes.begin();
293   if (it != theShapes.end()) {
294     TDF_Tool::Entry((*it)->GetEntry(), anEntry);
295     it++;
296     aDescr += (anEntry+", ");
297     for (; it != theShapes.end(); it++) {
298       aDescr += ", ";
299       TDF_Tool::Entry((*it)->GetEntry(), anEntry);
300       aDescr += anEntry;
301     }
302   }
303   if (isPlanarWanted)
304     aDescr += "], 1)";
305
306   else
307     aDescr += "], 0)";
308
309   aFunction->SetDescription(aDescr);
310
311   SetErrorCode(OK);
312   return aShape;
313 }
314
315 //=============================================================================
316 /*!
317  *  MakeShell
318  */
319 //=============================================================================
320 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
321                              (list<Handle(GEOM_Object)> theShapes)
322 {
323   return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
324 }
325
326 //=============================================================================
327 /*!
328  *  MakeSolidShells
329  */
330 //=============================================================================
331 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
332                              (list<Handle(GEOM_Object)> theShapes)
333 {
334   return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolidShells");
335 }
336
337 //=============================================================================
338 /*!
339  *  MakeSolidShell
340  */
341 //=============================================================================
342 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
343 {
344   SetErrorCode(KO);
345
346   if (theShell.IsNull()) return NULL;
347
348   //Add a new Solid object
349   Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
350
351   //Add a new Solid function for creation of a solid from a shell
352   Handle(GEOM_Function) aFunction =
353     aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
354   if (aFunction.IsNull()) return NULL;
355
356   //Check if the function is set correctly
357   if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
358
359   GEOMImpl_IShapes aCI (aFunction);
360
361   Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
362
363   if (aRefShell.IsNull()) return NULL;
364
365   aCI.SetBase(aRefShell);
366
367   //Compute the Solid value
368   try {
369     if (!GetSolver()->ComputeFunction(aFunction)) {
370       SetErrorCode("Solid driver failed");
371       return NULL;
372     }
373   }
374   catch (Standard_Failure) {
375     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
376     SetErrorCode(aFail->GetMessageString());
377     return NULL;
378   }
379
380   //Make a Python command
381   TCollection_AsciiString anEntry, aDescr("");
382   TDF_Tool::Entry(aSolid->GetEntry(), anEntry);
383   aDescr += anEntry;
384   aDescr += " = IShapesOperations.MakeSolidShell(";
385   TDF_Tool::Entry(theShell->GetEntry(), anEntry);
386   aDescr += (anEntry+")");
387
388   aFunction->SetDescription(aDescr);
389
390   SetErrorCode(OK);
391   return aSolid;
392 }
393
394 //=============================================================================
395 /*!
396  *  MakeCompound
397  */
398 //=============================================================================
399 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
400                              (list<Handle(GEOM_Object)> theShapes)
401 {
402   return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
403 }
404
405 //=============================================================================
406 /*!
407  *  MakeShape
408  */
409 //=============================================================================
410 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
411                              (list<Handle(GEOM_Object)>     theShapes,
412                               const Standard_Integer        theObjectType,
413                               const Standard_Integer        theFunctionType,
414                               const TCollection_AsciiString theMethodName)
415 {
416   SetErrorCode(KO);
417
418   //Add a new object
419   Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
420
421   //Add a new function
422   Handle(GEOM_Function) aFunction =
423     aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
424   if (aFunction.IsNull()) return NULL;
425
426   //Check if the function is set correctly
427   if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
428
429   GEOMImpl_IShapes aCI (aFunction);
430
431   Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
432
433   // Shapes
434   list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
435   for (; it != theShapes.end(); it++) {
436     Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
437     if (aRefSh.IsNull()) {
438       SetErrorCode("NULL argument shape for the shape construction");
439       return NULL;
440     }
441     aShapesSeq->Append(aRefSh);
442   }
443   aCI.SetShapes(aShapesSeq);
444
445   //Compute the shape
446   try {
447     if (!GetSolver()->ComputeFunction(aFunction)) {
448       SetErrorCode("Shape driver failed");
449       return NULL;
450     }
451   }
452   catch (Standard_Failure) {
453     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
454     SetErrorCode(aFail->GetMessageString());
455     return NULL;
456   }
457
458   //Make a Python command
459   TCollection_AsciiString anEntry, aDescr("");
460   TDF_Tool::Entry(aShape->GetEntry(), anEntry);
461   aDescr += (anEntry + " = IShapesOperations.");
462   aDescr += (theMethodName + "([");
463   // Shapes
464   it = theShapes.begin();
465   if (it != theShapes.end()) {
466     TDF_Tool::Entry((*it)->GetEntry(), anEntry);
467     it++;
468     aDescr += (anEntry+", ");
469     for (; it != theShapes.end(); it++) {
470       aDescr += ", ";
471       TDF_Tool::Entry((*it)->GetEntry(), anEntry);
472       aDescr += anEntry;
473     }
474   }
475   aDescr += "])";
476
477   aFunction->SetDescription(aDescr);
478
479   SetErrorCode(OK);
480   return aShape;
481 }
482
483 //=============================================================================
484 /*!
485  *  MakeGlueFaces
486  */
487 //=============================================================================
488 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
489                                                 (Handle(GEOM_Object) theShape,
490                                                  const Standard_Real theTolerance)
491 {
492   SetErrorCode(KO);
493
494   if (theShape.IsNull()) return NULL;
495
496   //Add a new Glued object
497   Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
498
499   //Add a new Glue function
500   Handle(GEOM_Function) aFunction;
501   aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
502   if (aFunction.IsNull()) return NULL;
503
504   //Check if the function is set correctly
505   if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
506
507   GEOMImpl_IGlue aCI (aFunction);
508
509   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
510   if (aRefShape.IsNull()) return NULL;
511
512   aCI.SetBase(aRefShape);
513   aCI.SetTolerance(theTolerance);
514
515   //Compute the sub-shape value
516   Standard_Boolean isWarning = Standard_False;
517   try {
518     if (!GetSolver()->ComputeFunction(aFunction)) {
519       SetErrorCode("Shape driver failed to glue faces");
520       return NULL;
521     }
522   }
523   catch (Standard_Failure) {
524     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
525     SetErrorCode(aFail->GetMessageString());
526     // to provide warning
527     if (!aFunction->GetValue().IsNull()) {
528       isWarning = Standard_True;
529     } else {
530       return NULL;
531     }
532   }
533
534   //Make a Python command
535   TCollection_AsciiString anEntry, aDescr;
536   TDF_Tool::Entry(aGlued->GetEntry(), anEntry);
537   aDescr += anEntry;
538   aDescr += " = IShapesOperations.MakeGlueFaces(";
539   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
540   aDescr += anEntry + ", ";
541   aDescr += TCollection_AsciiString(theTolerance) + ")";
542
543   aFunction->SetDescription(aDescr);
544
545   // to provide warning
546   if (!isWarning) SetErrorCode(OK);
547   return aGlued;
548 }
549
550 //=============================================================================
551 /*!
552  *  MakeExplode
553  */
554 //=============================================================================
555 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
556                                           (Handle(GEOM_Object)    theShape,
557                                            const Standard_Integer theShapeType,
558                                            const Standard_Boolean isSorted)
559 {
560 //  OSD_Timer timer1, timer2, timer3, timer4;
561 //  timer1.Start();
562
563   SetErrorCode(KO);
564
565   if (theShape.IsNull()) return NULL;
566   TopoDS_Shape aShape = theShape->GetValue();
567   if (aShape.IsNull()) return NULL;
568
569   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
570   Handle(GEOM_Object) anObj;
571   Handle(GEOM_Function) aFunction;
572   TopTools_MapOfShape mapShape;
573   TopTools_ListOfShape listShape;
574
575   if (aShape.ShapeType() == TopAbs_COMPOUND &&
576       (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
577        TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
578        TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
579     TopoDS_Iterator It (aShape, Standard_True, Standard_True);
580     for (; It.More(); It.Next()) {
581       if (mapShape.Add(It.Value())) {
582         if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
583             TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
584           listShape.Append(It.Value());
585         }
586       }
587     }
588   } else {
589     TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
590     for (; exp.More(); exp.Next())
591       if (mapShape.Add(exp.Current()))
592         listShape.Append(exp.Current());
593   }
594
595   if (listShape.IsEmpty()) {
596     SetErrorCode("The given shape has no sub-shapes of the requested type");
597     return aSeq;
598   }
599
600 //  timer1.Stop();
601 //  timer2.Start();
602
603   if (isSorted)
604     SortShapes(listShape);
605
606 //  timer2.Stop();
607 //  timer3.Start();
608
609   TopTools_IndexedMapOfShape anIndices;
610   TopExp::MapShapes(aShape, anIndices);
611   Handle(TColStd_HArray1OfInteger) anArray;
612
613   TopTools_ListIteratorOfListOfShape itSub (listShape);
614   TCollection_AsciiString anAsciiList = "[", anEntry;
615   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
616     TopoDS_Shape aValue = itSub.Value();
617     anArray = new TColStd_HArray1OfInteger(1,1);
618     anArray->SetValue(1, anIndices.FindIndex(aValue));
619     anObj = GetEngine()->AddSubShape(theShape, anArray);
620     aSeq->Append(anObj);
621
622     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
623     anAsciiList += anEntry;
624     anAsciiList += ",";
625   }
626
627 //  timer3.Stop();
628 //  timer4.Start();
629
630   anAsciiList.Trunc(anAsciiList.Length() - 1);
631   anAsciiList += "]";
632
633   anAsciiList = TCollection_AsciiString("\n") + anAsciiList;
634
635   //The explode doesn't change object so no new function is requiered.
636   aFunction = theShape->GetLastFunction();
637
638   //Make a Python command
639   TCollection_AsciiString aDescr(anAsciiList);
640   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
641   aDescr += " = IShapesOperations.MakeExplode(";
642   aDescr += (anEntry + ",");
643   if (isSorted)
644     aDescr += (TCollection_AsciiString(theShapeType) + ", 1)");
645   else
646     aDescr += (TCollection_AsciiString(theShapeType) + ", 0)");
647
648   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
649   anOldDescr = anOldDescr + aDescr;
650   aFunction->SetDescription(anOldDescr);
651
652   SetErrorCode(OK);
653
654 //  timer4.Stop();
655
656 //  cout << "Explosure takes:" << endl;
657 //  timer1.Show();
658 //  cout << "Sorting takes:" << endl;
659 //  timer2.Show();
660 //  cout << "Sub-shapes addition takes:" << endl;
661 //  timer3.Show();
662 //  cout << "Update Description takes:" << endl;
663 //  timer4.Show();
664
665   return aSeq;
666 }
667
668 //=============================================================================
669 /*!
670  *  GetSubShapeAllIDs
671  */
672 //=============================================================================
673 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
674                                           (Handle(GEOM_Object)    theShape,
675                                            const Standard_Integer theShapeType,
676                                            const Standard_Boolean isSorted)
677 {
678   SetErrorCode(KO);
679
680   if (theShape.IsNull()) return NULL;
681   TopoDS_Shape aShape = theShape->GetValue();
682   if (aShape.IsNull()) return NULL;
683
684   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
685   TopTools_MapOfShape mapShape;
686   TopTools_ListOfShape listShape;
687
688   if (aShape.ShapeType() == TopAbs_COMPOUND &&
689       (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
690        TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
691        TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
692     TopoDS_Iterator It (aShape, Standard_True, Standard_True);
693     for (; It.More(); It.Next()) {
694       if (mapShape.Add(It.Value())) {
695         if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
696             TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
697           listShape.Append(It.Value());
698         }
699       }
700     }
701   } else {
702     TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
703     for (; exp.More(); exp.Next())
704       if (mapShape.Add(exp.Current()))
705         listShape.Append(exp.Current());
706   }
707
708   if (listShape.IsEmpty()) {
709     SetErrorCode("The given shape has no sub-shapes of the requested type");
710     return aSeq;
711   }
712
713   if (isSorted)
714     SortShapes(listShape);
715
716   TopTools_IndexedMapOfShape anIndices;
717   TopExp::MapShapes(aShape, anIndices);
718   Handle(TColStd_HArray1OfInteger) anArray;
719
720   TopTools_ListIteratorOfListOfShape itSub (listShape);
721   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
722     TopoDS_Shape aValue = itSub.Value();
723     aSeq->Append(anIndices.FindIndex(aValue));
724   }
725
726   //The explode doesn't change object so no new function is required.
727   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
728
729   //Make a Python command
730   TCollection_AsciiString aDescr
731     ("\nlistSubShapeAllIDs = IShapesOperations.SubShapeAllIDs(");
732   TCollection_AsciiString anEntry;
733   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
734   aDescr += (anEntry + ",");
735   if (isSorted)
736     aDescr += (TCollection_AsciiString(theShapeType) + ", 1)");
737   else
738     aDescr += (TCollection_AsciiString(theShapeType) + ", 0)");
739
740   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
741   anOldDescr = anOldDescr + aDescr;
742   aFunction->SetDescription(anOldDescr);
743
744   SetErrorCode(OK);
745   return aSeq;
746 }
747
748 //=============================================================================
749 /*!
750  *  GetSubShape
751  */
752 //=============================================================================
753 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
754                                           (Handle(GEOM_Object)    theMainShape,
755                                            const Standard_Integer theID)
756 {
757   SetErrorCode(KO);
758
759   if (theMainShape.IsNull()) return NULL;
760
761   Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
762   anArray->SetValue(1, theID);
763   Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray);
764   if (anObj.IsNull()) {
765     SetErrorCode("Can not get a sub-shape with the given ID");
766     return NULL;
767   }
768
769   //The GetSubShape() doesn't change object so no new function is requiered.
770   Handle(GEOM_Function) aFunction = theMainShape->GetLastFunction();
771
772   //Make a Python command
773   TCollection_AsciiString aDescr ("\n");
774   TCollection_AsciiString anEntry;
775   TDF_Tool::Entry(anObj->GetEntry(), anEntry);
776   aDescr += anEntry + " = IShapesOperations.GetSubShape(";
777   TDF_Tool::Entry(theMainShape->GetEntry(), anEntry);
778   aDescr += anEntry + ", ";
779   aDescr += TCollection_AsciiString(theID) + ")";
780
781   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
782   anOldDescr = anOldDescr + aDescr;
783   aFunction->SetDescription(anOldDescr);
784
785   SetErrorCode(OK);
786   return anObj;
787 }
788
789
790 //=============================================================================
791 /*!
792  *  NumberOfFaces
793  */
794 //=============================================================================
795 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
796 {
797   SetErrorCode(KO);
798
799   Standard_Integer nb = 0;
800
801   if (theShape.IsNull()) return -1;
802   TopoDS_Shape aShape = theShape->GetValue();
803   if (aShape.IsNull()) return -1;
804
805   TopTools_MapOfShape mapShape;
806
807   TopExp_Explorer exp (aShape, TopAbs_FACE);
808   for (; exp.More(); exp.Next())
809     if (mapShape.Add(exp.Current()))
810       nb++;
811
812   SetErrorCode(OK);
813   return nb;
814 }
815
816 //=============================================================================
817 /*!
818  *  NumberOfEdges
819  */
820 //=============================================================================
821 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
822 {
823   SetErrorCode(KO);
824
825   Standard_Integer nb = 0;
826
827   if (theShape.IsNull()) return -1;
828   TopoDS_Shape aShape = theShape->GetValue();
829   if (aShape.IsNull()) return -1;
830
831   TopTools_MapOfShape mapShape;
832
833   TopExp_Explorer exp (aShape, TopAbs_EDGE);
834   for (; exp.More(); exp.Next())
835     if (mapShape.Add(exp.Current()))
836       nb++;
837
838   SetErrorCode(OK);
839   return nb;
840 }
841
842 //=============================================================================
843 /*!
844  *  ReverseShape
845  */
846 //=============================================================================
847 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
848 {
849   SetErrorCode(KO);
850
851   if (theShape.IsNull()) return NULL;
852
853   //Add a new reversed object
854   Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
855
856   //Add a new Revese function
857   Handle(GEOM_Function) aFunction;
858   aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
859   if (aFunction.IsNull()) return NULL;
860
861   //Check if the function is set correctly
862   if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
863
864   GEOMImpl_IShapes aSI (aFunction);
865
866   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
867   if (aRefShape.IsNull()) return NULL;
868
869   aSI.SetBase(aRefShape);
870
871   //Compute the sub-shape value
872   try {
873     if (!GetSolver()->ComputeFunction(aFunction)) {
874       SetErrorCode("Shape driver failed to reverse shape");
875       return NULL;
876     }
877   }
878   catch (Standard_Failure) {
879     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
880     SetErrorCode(aFail->GetMessageString());
881     return NULL;
882   }
883
884   //Make a Python command
885   TCollection_AsciiString anEntry, aDescr;
886   TDF_Tool::Entry(aReversed->GetEntry(), anEntry);
887   aDescr += anEntry;
888   aDescr += " = IShapesOperations.ReverseShape(";
889   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
890   aDescr += anEntry + ")";
891
892   aFunction->SetDescription(aDescr);
893
894   SetErrorCode(OK);
895   return aReversed;
896 }
897
898 //=============================================================================
899 /*!
900  *  GetFreeFacesIDs
901  */
902 //=============================================================================
903 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
904                                                  (Handle(GEOM_Object) theShape)
905 {
906   SetErrorCode(KO);
907
908   if (theShape.IsNull()) return NULL;
909   TopoDS_Shape aShape = theShape->GetValue();
910   if (aShape.IsNull()) return NULL;
911
912   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
913
914   TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
915   GEOMImpl_Block6Explorer::MapShapesAndAncestors
916     (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
917
918   Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
919
920   if (nbFaces == 0) {
921     SetErrorCode("The given shape has no faces");
922     return aSeq;
923   }
924
925   TopTools_IndexedMapOfShape anIndices;
926   TopExp::MapShapes(aShape, anIndices);
927
928   Standard_Integer id;
929   for (; ind <= nbFaces; ind++) {
930     if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
931       id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
932       aSeq->Append(id);
933     }
934   }
935
936   //The explode doesn't change object so no new function is required.
937   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
938
939   //Make a Python command
940   TCollection_AsciiString aDescr ("\nlistFreeFacesIDs = IShapesOperations.GetFreeFacesIDs(");
941   TCollection_AsciiString anEntry;
942   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
943   aDescr += (anEntry + ")");
944
945   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
946   anOldDescr = anOldDescr + aDescr;
947   aFunction->SetDescription(anOldDescr);
948
949   SetErrorCode(OK);
950   return aSeq;
951 }
952
953 //=============================================================================
954 /*!
955  *  GetSharedShapes
956  */
957 //=============================================================================
958 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
959                                                 (Handle(GEOM_Object)    theShape1,
960                                                  Handle(GEOM_Object)    theShape2,
961                                                  const Standard_Integer theShapeType)
962 {
963   SetErrorCode(KO);
964
965   if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
966
967   TopoDS_Shape aShape1 = theShape1->GetValue();
968   TopoDS_Shape aShape2 = theShape2->GetValue();
969
970   if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
971
972   TopTools_IndexedMapOfShape anIndices;
973   TopExp::MapShapes(aShape1, anIndices);
974   Handle(TColStd_HArray1OfInteger) anArray;
975
976   TopTools_IndexedMapOfShape mapShape1;
977   TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
978
979   Handle(GEOM_Object) anObj;
980   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
981
982   TopTools_MapOfShape mapShape2;
983   TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
984   for (; exp.More(); exp.Next()) {
985     TopoDS_Shape aSS = exp.Current();
986     if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
987       anArray = new TColStd_HArray1OfInteger(1,1);
988       anArray->SetValue(1, anIndices.FindIndex(aSS));
989       anObj = GetEngine()->AddSubShape(theShape1, anArray);
990       aSeq->Append(anObj);
991     }
992   }
993
994   if (aSeq->IsEmpty()) {
995     SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
996     return aSeq;
997   }
998
999   //The explode doesn't change object so no new function is required.
1000   Handle(GEOM_Function) aFunction = theShape1->GetLastFunction();
1001
1002   //Make a Python command
1003   TCollection_AsciiString aDescr
1004     ("\nlistSharedShapes = IShapesOperations.GetSharedShapes(");
1005   TCollection_AsciiString anEntry;
1006   TDF_Tool::Entry(theShape1->GetEntry(), anEntry);
1007   aDescr += (anEntry + ",");
1008   TDF_Tool::Entry(theShape2->GetEntry(), anEntry);
1009   aDescr += (anEntry + ",");
1010   aDescr += TCollection_AsciiString(theShapeType) + ")";
1011
1012   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
1013   anOldDescr = anOldDescr + aDescr;
1014   aFunction->SetDescription(anOldDescr);
1015
1016   SetErrorCode(OK);
1017   return aSeq;
1018 }
1019
1020 //=============================================================================
1021 /*!
1022  *  GetShapesOnPlane
1023  */
1024 //=============================================================================
1025 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
1026                                         (const Handle(GEOM_Object)& theShape,
1027                                          const Standard_Integer     theShapeType,
1028                                          const Handle(GEOM_Object)& theAx1,
1029                                          const GEOMAlgo_State       theState)
1030 {
1031   SetErrorCode(KO);
1032
1033 //  MESSAGE("--------------------------- GetShapesOnPlane phase 1 takes:");
1034 //  OSD_Timer timer1;
1035 //  timer1.Start();
1036
1037   if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1038
1039   TopoDS_Shape aShape = theShape->GetValue();
1040   TopoDS_Shape anAx1  = theAx1->GetValue();
1041
1042   if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1043
1044   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1045   if (aShapeType != TopAbs_VERTEX &&
1046       aShapeType != TopAbs_EDGE &&
1047       aShapeType != TopAbs_FACE &&
1048       aShapeType != TopAbs_SOLID) {
1049     SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1050     return NULL;
1051   }
1052
1053   // Create plane
1054   if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1055   TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1056   TopoDS_Vertex V1, V2;
1057   TopExp::Vertices(anEdge, V1, V2, Standard_True);
1058   if (V1.IsNull() || V2.IsNull()) {
1059     SetErrorCode("Bad edge given for the plane normal vector");
1060     return NULL;
1061   }
1062   gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1063   gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1064   if (aVec.Magnitude() < Precision::Confusion()) {
1065     SetErrorCode("Vector with null magnitude given");
1066     return NULL;
1067   }
1068
1069   Handle(Geom_Plane) aPlane = new Geom_Plane(aLoc, aVec);
1070
1071   // Check presence of triangulation, build if need
1072   if (!CheckTriangulation(aShape))
1073     return NULL;
1074
1075   // Call algo
1076   GEOMAlgo_FinderShapeOn1 aFinder;
1077   Standard_Real aTol = 0.0001; // default value
1078
1079   aFinder.SetShape(aShape);
1080   aFinder.SetTolerance(aTol);
1081   aFinder.SetSurface(aPlane);
1082   aFinder.SetShapeType(aShapeType);
1083   aFinder.SetState(theState);
1084
1085   // Sets the minimal number of inner points for the faces that do not have own
1086   // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1087   // Default value=3
1088   aFinder.SetNbPntsMin(3);
1089   // Sets the maximal number of inner points for edges or faces.
1090   // It is usefull for the cases when this number is very big (e.g =2000) to improve
1091   // the performance. If this value =0, all inner points will be taken into account.
1092   // Default value=0
1093   aFinder.SetNbPntsMax(100);
1094
1095 //  timer1.Stop();
1096 //  timer1.Show();
1097
1098 //  MESSAGE("--------------------------- Perform on Plane takes:");
1099 //  timer1.Reset();
1100 //  timer1.Start();
1101   aFinder.Perform();
1102 //  timer1.Stop();
1103 //  timer1.Show();
1104
1105 //  MESSAGE("--------------------------- GetShapesOnPlane phase 3 takes:");
1106 //  timer1.Reset();
1107 //  timer1.Start();
1108
1109   // Interprete results
1110   Standard_Integer iErr = aFinder.ErrorStatus();
1111   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1112   if (iErr) {
1113     MESSAGE(" iErr : " << iErr);
1114     TCollection_AsciiString aMsg (" iErr : ");
1115     aMsg += TCollection_AsciiString(iErr);
1116     SetErrorCode(aMsg);
1117     return NULL;
1118   }
1119   Standard_Integer iWrn = aFinder.WarningStatus();
1120   // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1121   if (iWrn) {
1122     MESSAGE(" *** iWrn : " << iWrn);
1123   }
1124
1125   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1126
1127   if (listSS.Extent() < 1) {
1128     SetErrorCode("Not a single sub-shape of the requested type found on the given plane");
1129     return NULL;
1130   }
1131
1132 //  timer1.Stop();
1133 //  timer1.Show();
1134
1135 //  MESSAGE("--------------------------- GetShapesOnPlane phase 4 takes:");
1136 //  timer1.Reset();
1137 //  timer1.Start();
1138
1139   // Fill sequence of objects
1140   TopTools_IndexedMapOfShape anIndices;
1141   TopExp::MapShapes(aShape, anIndices);
1142
1143   Handle(GEOM_Object) anObj;
1144   Handle(TColStd_HArray1OfInteger) anArray;
1145   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1146
1147   TopTools_ListIteratorOfListOfShape itSub (listSS);
1148   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1149     int id = anIndices.FindIndex(itSub.Value());
1150     anArray = new TColStd_HArray1OfInteger(1,1);
1151     anArray->SetValue(1, id);
1152     anObj = GetEngine()->AddSubShape(theShape, anArray);
1153     aSeq->Append(anObj);
1154   }
1155
1156 //  timer1.Stop();
1157 //  timer1.Show();
1158
1159 //  MESSAGE("--------------------------- GetShapesOnPlane phase 5 takes:");
1160 //  timer1.Reset();
1161 //  timer1.Start();
1162   
1163   // The GetShapesOnPlane() doesn't change object so no new function is required.
1164   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1165
1166   // Make a Python command
1167   TCollection_AsciiString anEntry, aDescr
1168     ("\nlistShapesOnPlane = IShapesOperations.GetShapesOnPlane(");
1169   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
1170   aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
1171   TDF_Tool::Entry(theAx1->GetEntry(), anEntry);
1172   aDescr += anEntry + ",";
1173   aDescr += TCollection_AsciiString(theState) + ")";
1174
1175   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
1176   anOldDescr += aDescr;
1177   aFunction->SetDescription(anOldDescr);
1178
1179 //  timer1.Stop();
1180 //  timer1.Show();
1181
1182   SetErrorCode(OK);
1183   return aSeq;
1184 }
1185
1186 //=============================================================================
1187 /*!
1188  *  GetShapesOnCylinder
1189  */
1190 //=============================================================================
1191 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
1192                                           (const Handle(GEOM_Object)& theShape,
1193                                            const Standard_Integer     theShapeType,
1194                                            const Handle(GEOM_Object)& theAxis,
1195                                            const Standard_Real        theRadius,
1196                                            const GEOMAlgo_State       theState)
1197 {
1198   SetErrorCode(KO);
1199
1200   if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1201
1202   TopoDS_Shape aShape = theShape->GetValue();
1203   TopoDS_Shape anAxis = theAxis->GetValue();
1204
1205   if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1206
1207   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1208   if (aShapeType != TopAbs_VERTEX &&
1209       aShapeType != TopAbs_EDGE &&
1210       aShapeType != TopAbs_FACE &&
1211       aShapeType != TopAbs_SOLID) {
1212     SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1213     return NULL;
1214   }
1215
1216   //Axis of the cylinder
1217   if (anAxis.ShapeType() != TopAbs_EDGE) {
1218     SetErrorCode("Not an edge given for the axis");
1219     return NULL;
1220   }
1221   TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1222   TopoDS_Vertex V1, V2;
1223   TopExp::Vertices(anEdge, V1, V2, Standard_True);
1224   if (V1.IsNull() || V2.IsNull()) {
1225     SetErrorCode("Bad edge given for the axis");
1226     return NULL;
1227   }
1228   gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1229   gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1230   if (aVec.Magnitude() < Precision::Confusion()) {
1231     SetErrorCode("Vector with null magnitude given");
1232     return NULL;
1233   }
1234
1235   gp_Ax3 anAx3 (aLoc, aVec);
1236   Handle(Geom_CylindricalSurface) aCylinder =
1237     new Geom_CylindricalSurface(anAx3, theRadius);
1238
1239   // Check presence of triangulation, build if need
1240   if (!CheckTriangulation(aShape))
1241     return NULL;
1242
1243   // Call algo
1244   GEOMAlgo_FinderShapeOn1 aFinder;
1245   Standard_Real aTol = 0.0001; // default value
1246
1247   aFinder.SetShape(aShape);
1248   aFinder.SetTolerance(aTol);
1249   aFinder.SetSurface(aCylinder);
1250   aFinder.SetShapeType(aShapeType);
1251   aFinder.SetState(theState);
1252
1253   aFinder.SetNbPntsMin(3);
1254   aFinder.SetNbPntsMax(100);
1255
1256   aFinder.Perform();
1257
1258   // Interprete results
1259   Standard_Integer iErr = aFinder.ErrorStatus();
1260   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1261   if (iErr) {
1262     MESSAGE(" iErr : " << iErr);
1263     TCollection_AsciiString aMsg (" iErr : ");
1264     aMsg += TCollection_AsciiString(iErr);
1265     SetErrorCode(aMsg);
1266     return NULL;
1267   }
1268   Standard_Integer iWrn = aFinder.WarningStatus();
1269   // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1270   if (iWrn) {
1271     MESSAGE(" *** iWrn : " << iWrn);
1272   }
1273
1274   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1275
1276   if (listSS.Extent() < 1) {
1277     SetErrorCode("Not a single sub-shape of the requested type found on the given cylinder");
1278     return NULL;
1279   }
1280
1281   // Fill sequence of objects
1282   TopTools_IndexedMapOfShape anIndices;
1283   TopExp::MapShapes(aShape, anIndices);
1284
1285   Handle(GEOM_Object) anObj;
1286   Handle(TColStd_HArray1OfInteger) anArray;
1287   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1288
1289   TopTools_ListIteratorOfListOfShape itSub (listSS);
1290   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1291     int id = anIndices.FindIndex(itSub.Value());
1292     anArray = new TColStd_HArray1OfInteger(1,1);
1293     anArray->SetValue(1, id);
1294     anObj = GetEngine()->AddSubShape(theShape, anArray);
1295     aSeq->Append(anObj);
1296   }
1297   
1298   // The GetShapesOnCylinder() doesn't change object so no new function is required.
1299   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1300
1301   // Make a Python command
1302   TCollection_AsciiString anEntry, aDescr
1303     ("\nlistShapesOnCylinder = IShapesOperations.GetShapesOnCylinder(");
1304   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
1305   aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
1306   TDF_Tool::Entry(theAxis->GetEntry(), anEntry);
1307   aDescr += anEntry + ",";
1308   aDescr += TCollection_AsciiString(theRadius) + ",";
1309   aDescr += TCollection_AsciiString(theState) + ")";
1310
1311   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
1312   anOldDescr += aDescr;
1313   aFunction->SetDescription(anOldDescr);
1314
1315   SetErrorCode(OK);
1316   return aSeq;
1317 }
1318
1319 //=============================================================================
1320 /*!
1321  *  GetShapesOnSphere
1322  */
1323 //=============================================================================
1324 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
1325                                           (const Handle(GEOM_Object)& theShape,
1326                                            const Standard_Integer     theShapeType,
1327                                            const Handle(GEOM_Object)& theCenter,
1328                                            const Standard_Real        theRadius,
1329                                            const GEOMAlgo_State       theState)
1330 {
1331   SetErrorCode(KO);
1332
1333   if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1334
1335   TopoDS_Shape aShape  = theShape->GetValue();
1336   TopoDS_Shape aCenter = theCenter->GetValue();
1337
1338   if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1339
1340   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1341   if (aShapeType != TopAbs_VERTEX &&
1342       aShapeType != TopAbs_EDGE &&
1343       aShapeType != TopAbs_FACE &&
1344       aShapeType != TopAbs_SOLID) {
1345     SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1346     return NULL;
1347   }
1348
1349   // Center of the sphere
1350   if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1351   gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1352
1353   gp_Ax3 anAx3 (aLoc, gp::DZ());
1354   Handle(Geom_SphericalSurface) aSphere =
1355     new Geom_SphericalSurface(anAx3, theRadius);
1356
1357   // Check presence of triangulation, build if need
1358   if (!CheckTriangulation(aShape))
1359     return NULL;
1360
1361   // Call algo
1362   GEOMAlgo_FinderShapeOn1 aFinder;
1363   Standard_Real aTol = 0.0001; // default value
1364
1365   aFinder.SetShape(aShape);
1366   aFinder.SetTolerance(aTol);
1367   aFinder.SetSurface(aSphere);
1368   aFinder.SetShapeType(aShapeType);
1369   aFinder.SetState(theState);
1370
1371   aFinder.SetNbPntsMin(3);
1372   aFinder.SetNbPntsMax(100);
1373
1374   aFinder.Perform();
1375
1376   // Interprete results
1377   Standard_Integer iErr = aFinder.ErrorStatus();
1378   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1379   if (iErr) {
1380     MESSAGE(" iErr : " << iErr);
1381     TCollection_AsciiString aMsg (" iErr : ");
1382     aMsg += TCollection_AsciiString(iErr);
1383     SetErrorCode(aMsg);
1384     return NULL;
1385   }
1386   Standard_Integer iWrn = aFinder.WarningStatus();
1387   // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1388   if (iWrn) {
1389     MESSAGE(" *** iWrn : " << iWrn);
1390   }
1391
1392   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1393
1394   if (listSS.Extent() < 1) {
1395     SetErrorCode("Not a single sub-shape of the requested type found on the given sphere");
1396     return NULL;
1397   }
1398
1399   // Fill sequence of objects
1400   TopTools_IndexedMapOfShape anIndices;
1401   TopExp::MapShapes(aShape, anIndices);
1402
1403   Handle(GEOM_Object) anObj;
1404   Handle(TColStd_HArray1OfInteger) anArray;
1405   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1406
1407   TopTools_ListIteratorOfListOfShape itSub (listSS);
1408   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1409     int id = anIndices.FindIndex(itSub.Value());
1410     anArray = new TColStd_HArray1OfInteger(1,1);
1411     anArray->SetValue(1, id);
1412     anObj = GetEngine()->AddSubShape(theShape, anArray);
1413     aSeq->Append(anObj);
1414   }
1415   
1416   // The GetShapesOnSphere() doesn't change object so no new function is required.
1417   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1418
1419   // Make a Python command
1420   TCollection_AsciiString anEntry, aDescr
1421     ("\nlistShapesOnSphere = IShapesOperations.GetShapesOnSphere(");
1422   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
1423   aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
1424   TDF_Tool::Entry(theCenter->GetEntry(), anEntry);
1425   aDescr += anEntry + ",";
1426   aDescr += TCollection_AsciiString(theRadius) + ",";
1427   aDescr += TCollection_AsciiString(theState) + ")";
1428
1429   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
1430   anOldDescr += aDescr;
1431   aFunction->SetDescription(anOldDescr);
1432
1433   SetErrorCode(OK);
1434   return aSeq;
1435 }
1436
1437 //=============================================================================
1438 /*!
1439  *  GetShapesOnPlaneIDs
1440  */
1441 //=============================================================================
1442 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
1443                                         (const Handle(GEOM_Object)& theShape,
1444                                          const Standard_Integer     theShapeType,
1445                                          const Handle(GEOM_Object)& theAx1,
1446                                          const GEOMAlgo_State       theState)
1447 {
1448   SetErrorCode(KO);
1449
1450   if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1451
1452   TopoDS_Shape aShape = theShape->GetValue();
1453   TopoDS_Shape anAx1  = theAx1->GetValue();
1454
1455   if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1456
1457   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1458   if (aShapeType != TopAbs_VERTEX &&
1459       aShapeType != TopAbs_EDGE &&
1460       aShapeType != TopAbs_FACE &&
1461       aShapeType != TopAbs_SOLID) {
1462     SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1463     return NULL;
1464   }
1465
1466   // Create plane
1467   if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1468   TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1469   TopoDS_Vertex V1, V2;
1470   TopExp::Vertices(anEdge, V1, V2, Standard_True);
1471   if (V1.IsNull() || V2.IsNull()) {
1472     SetErrorCode("Bad edge given for the plane normal vector");
1473     return NULL;
1474   }
1475   gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1476   gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1477   if (aVec.Magnitude() < Precision::Confusion()) {
1478     SetErrorCode("Vector with null magnitude given");
1479     return NULL;
1480   }
1481
1482   Handle(Geom_Plane) aPlane = new Geom_Plane(aLoc, aVec);
1483
1484   // Check presence of triangulation, build if need
1485   if (!CheckTriangulation(aShape))
1486     return NULL;
1487
1488   // Call algo
1489   GEOMAlgo_FinderShapeOn1 aFinder;
1490   Standard_Real aTol = 0.0001; // default value
1491
1492   aFinder.SetShape(aShape);
1493   aFinder.SetTolerance(aTol);
1494   aFinder.SetSurface(aPlane);
1495   aFinder.SetShapeType(aShapeType);
1496   aFinder.SetState(theState);
1497
1498   aFinder.SetNbPntsMin(3);
1499   aFinder.SetNbPntsMax(100);
1500
1501   aFinder.Perform();
1502
1503   // Interprete results
1504   Standard_Integer iErr = aFinder.ErrorStatus();
1505   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1506   if (iErr) {
1507     MESSAGE(" iErr : " << iErr);
1508     TCollection_AsciiString aMsg (" iErr : ");
1509     aMsg += TCollection_AsciiString(iErr);
1510     SetErrorCode(aMsg);
1511     return NULL;
1512   }
1513   Standard_Integer iWrn = aFinder.WarningStatus();
1514   // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1515   if (iWrn) {
1516     MESSAGE(" *** iWrn : " << iWrn);
1517   }
1518
1519   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1520
1521   if (listSS.Extent() < 1) {
1522     SetErrorCode("Not a single sub-shape of the requested type found on the given plane");
1523     return NULL;
1524   }
1525
1526   // Fill sequence of objects
1527   TopTools_IndexedMapOfShape anIndices;
1528   TopExp::MapShapes(aShape, anIndices);
1529
1530   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1531
1532   TopTools_ListIteratorOfListOfShape itSub (listSS);
1533   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1534     int id = anIndices.FindIndex(itSub.Value());
1535     aSeq->Append(id);
1536   }
1537
1538   // The GetShapesOnPlane() doesn't change object so no new function is required.
1539   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1540
1541   // Make a Python command
1542   TCollection_AsciiString anEntry, aDescr
1543     ("\nlistShapesOnPlane = IShapesOperations.GetShapesOnPlaneIDs(");
1544   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
1545   aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
1546   TDF_Tool::Entry(theAx1->GetEntry(), anEntry);
1547   aDescr += anEntry + ",";
1548   aDescr += TCollection_AsciiString(theState) + ")";
1549
1550   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
1551   anOldDescr += aDescr;
1552   aFunction->SetDescription(anOldDescr);
1553
1554   SetErrorCode(OK);
1555   return aSeq;
1556 }
1557
1558 //=============================================================================
1559 /*!
1560  *  GetShapesOnCylinderIDs
1561  */
1562 //=============================================================================
1563 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
1564                                           (const Handle(GEOM_Object)& theShape,
1565                                            const Standard_Integer     theShapeType,
1566                                            const Handle(GEOM_Object)& theAxis,
1567                                            const Standard_Real        theRadius,
1568                                            const GEOMAlgo_State       theState)
1569 {
1570   SetErrorCode(KO);
1571
1572   if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1573
1574   TopoDS_Shape aShape = theShape->GetValue();
1575   TopoDS_Shape anAxis = theAxis->GetValue();
1576
1577   if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1578
1579   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1580   if (aShapeType != TopAbs_VERTEX &&
1581       aShapeType != TopAbs_EDGE &&
1582       aShapeType != TopAbs_FACE &&
1583       aShapeType != TopAbs_SOLID) {
1584     SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1585     return NULL;
1586   }
1587
1588   //Axis of the cylinder
1589   if (anAxis.ShapeType() != TopAbs_EDGE) {
1590     SetErrorCode("Not an edge given for the axis");
1591     return NULL;
1592   }
1593   TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1594   TopoDS_Vertex V1, V2;
1595   TopExp::Vertices(anEdge, V1, V2, Standard_True);
1596   if (V1.IsNull() || V2.IsNull()) {
1597     SetErrorCode("Bad edge given for the axis");
1598     return NULL;
1599   }
1600   gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1601   gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1602   if (aVec.Magnitude() < Precision::Confusion()) {
1603     SetErrorCode("Vector with null magnitude given");
1604     return NULL;
1605   }
1606
1607   gp_Ax3 anAx3 (aLoc, aVec);
1608   Handle(Geom_CylindricalSurface) aCylinder =
1609     new Geom_CylindricalSurface(anAx3, theRadius);
1610
1611   // Check presence of triangulation, build if need
1612   if (!CheckTriangulation(aShape))
1613     return NULL;
1614
1615   // Call algo
1616   GEOMAlgo_FinderShapeOn1 aFinder;
1617   Standard_Real aTol = 0.0001; // default value
1618
1619   aFinder.SetShape(aShape);
1620   aFinder.SetTolerance(aTol);
1621   aFinder.SetSurface(aCylinder);
1622   aFinder.SetShapeType(aShapeType);
1623   aFinder.SetState(theState);
1624
1625   aFinder.SetNbPntsMin(3);
1626   aFinder.SetNbPntsMax(100);
1627
1628   aFinder.Perform();
1629
1630   // Interprete results
1631   Standard_Integer iErr = aFinder.ErrorStatus();
1632   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1633   if (iErr) {
1634     MESSAGE(" iErr : " << iErr);
1635     TCollection_AsciiString aMsg (" iErr : ");
1636     aMsg += TCollection_AsciiString(iErr);
1637     SetErrorCode(aMsg);
1638     return NULL;
1639   }
1640   Standard_Integer iWrn = aFinder.WarningStatus();
1641   // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1642   if (iWrn) {
1643     MESSAGE(" *** iWrn : " << iWrn);
1644   }
1645
1646   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1647
1648   if (listSS.Extent() < 1) {
1649     SetErrorCode("Not a single sub-shape of the requested type found on the given cylinder");
1650     return NULL;
1651   }
1652
1653   // Fill sequence of objects
1654   TopTools_IndexedMapOfShape anIndices;
1655   TopExp::MapShapes(aShape, anIndices);
1656
1657   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1658
1659   TopTools_ListIteratorOfListOfShape itSub (listSS);
1660   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1661     int id = anIndices.FindIndex(itSub.Value());
1662     aSeq->Append(id);
1663   }
1664   
1665   // The GetShapesOnCylinder() doesn't change object so no new function is required.
1666   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1667
1668   // Make a Python command
1669   TCollection_AsciiString anEntry, aDescr
1670     ("\nlistShapesOnCylinder = IShapesOperations.GetShapesOnCylinderIDs(");
1671   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
1672   aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
1673   TDF_Tool::Entry(theAxis->GetEntry(), anEntry);
1674   aDescr += anEntry + ",";
1675   aDescr += TCollection_AsciiString(theRadius) + ",";
1676   aDescr += TCollection_AsciiString(theState) + ")";
1677
1678   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
1679   anOldDescr += aDescr;
1680   aFunction->SetDescription(anOldDescr);
1681
1682   SetErrorCode(OK);
1683   return aSeq;
1684 }
1685
1686 //=============================================================================
1687 /*!
1688  *  GetShapesOnSphereIDs
1689  */
1690 //=============================================================================
1691 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
1692                                           (const Handle(GEOM_Object)& theShape,
1693                                            const Standard_Integer     theShapeType,
1694                                            const Handle(GEOM_Object)& theCenter,
1695                                            const Standard_Real        theRadius,
1696                                            const GEOMAlgo_State       theState)
1697 {
1698   SetErrorCode(KO);
1699
1700   if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1701
1702   TopoDS_Shape aShape  = theShape->GetValue();
1703   TopoDS_Shape aCenter = theCenter->GetValue();
1704
1705   if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1706
1707   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1708   if (aShapeType != TopAbs_VERTEX &&
1709       aShapeType != TopAbs_EDGE &&
1710       aShapeType != TopAbs_FACE &&
1711       aShapeType != TopAbs_SOLID) {
1712     SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1713     return NULL;
1714   }
1715
1716   // Center of the sphere
1717   if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1718   gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1719
1720   gp_Ax3 anAx3 (aLoc, gp::DZ());
1721   Handle(Geom_SphericalSurface) aSphere =
1722     new Geom_SphericalSurface(anAx3, theRadius);
1723
1724   // Check presence of triangulation, build if need
1725   if (!CheckTriangulation(aShape))
1726     return NULL;
1727
1728   // Call algo
1729   GEOMAlgo_FinderShapeOn1 aFinder;
1730   Standard_Real aTol = 0.0001; // default value
1731
1732   aFinder.SetShape(aShape);
1733   aFinder.SetTolerance(aTol);
1734   aFinder.SetSurface(aSphere);
1735   aFinder.SetShapeType(aShapeType);
1736   aFinder.SetState(theState);
1737
1738   aFinder.SetNbPntsMin(3);
1739   aFinder.SetNbPntsMax(100);
1740
1741   aFinder.Perform();
1742
1743   // Interprete results
1744   Standard_Integer iErr = aFinder.ErrorStatus();
1745   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1746   if (iErr) {
1747     MESSAGE(" iErr : " << iErr);
1748     TCollection_AsciiString aMsg (" iErr : ");
1749     aMsg += TCollection_AsciiString(iErr);
1750     SetErrorCode(aMsg);
1751     return NULL;
1752   }
1753   Standard_Integer iWrn = aFinder.WarningStatus();
1754   // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1755   if (iWrn) {
1756     MESSAGE(" *** iWrn : " << iWrn);
1757   }
1758
1759   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1760
1761   if (listSS.Extent() < 1) {
1762     SetErrorCode("Not a single sub-shape of the requested type found on the given sphere");
1763     return NULL;
1764   }
1765
1766   // Fill sequence of objects
1767   TopTools_IndexedMapOfShape anIndices;
1768   TopExp::MapShapes(aShape, anIndices);
1769
1770   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1771
1772   TopTools_ListIteratorOfListOfShape itSub (listSS);
1773   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1774     int id = anIndices.FindIndex(itSub.Value());
1775     aSeq->Append(id);
1776   }
1777   
1778   // The GetShapesOnSphere() doesn't change object so no new function is required.
1779   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1780
1781   // Make a Python command
1782   TCollection_AsciiString anEntry, aDescr
1783     ("\nlistShapesOnSphere = IShapesOperations.GetShapesOnSphereIDs(");
1784   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
1785   aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
1786   TDF_Tool::Entry(theCenter->GetEntry(), anEntry);
1787   aDescr += anEntry + ",";
1788   aDescr += TCollection_AsciiString(theRadius) + ",";
1789   aDescr += TCollection_AsciiString(theState) + ")";
1790
1791   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
1792   anOldDescr += aDescr;
1793   aFunction->SetDescription(anOldDescr);
1794
1795   SetErrorCode(OK);
1796   return aSeq;
1797 }
1798
1799 //=============================================================================
1800 /*!
1801  *  GetInPlace
1802  */
1803 //=============================================================================
1804 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
1805                                           (Handle(GEOM_Object) theShapeWhere,
1806                                            Handle(GEOM_Object) theShapeWhat)
1807 {
1808   SetErrorCode(KO);
1809
1810   if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
1811
1812   TopoDS_Shape aWhere = theShapeWhere->GetValue();
1813   TopoDS_Shape aWhat  = theShapeWhat->GetValue();
1814
1815   if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
1816
1817   //Fill array of indices
1818   Handle(TColStd_HArray1OfInteger) aModifiedArray;
1819
1820   Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
1821
1822   TopTools_IndexedMapOfShape aWhereIndices;
1823   TopExp::MapShapes(aWhere, aWhereIndices);
1824
1825   if (aWhereIndices.Contains(aWhat)) {
1826
1827     // entity was not changed by the operation
1828     Standard_Integer aWhatIndex = aWhereIndices.FindIndex(aWhat);
1829     aModifiedArray = new TColStd_HArray1OfInteger(1,1);
1830     aModifiedArray->SetValue(1, aWhatIndex);
1831
1832   } else {
1833
1834     TDF_Label aHistoryLabel = aWhereFunction->GetHistoryEntry(Standard_False);
1835     if (aHistoryLabel.IsNull()) {
1836       SetErrorCode("Modifications history does not exist for the shape under consideration.");
1837       return NULL;
1838     }
1839
1840     // search in history for all argument shapes
1841     Standard_Boolean isFound = Standard_False;
1842
1843     TDF_LabelSequence aLabelSeq;
1844     aWhereFunction->GetDependency(aLabelSeq);
1845     Standard_Integer nbArg = aLabelSeq.Length();
1846
1847     for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
1848
1849       TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
1850
1851       Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
1852       TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
1853
1854       TopTools_IndexedMapOfShape anArgumentIndices;
1855       TopExp::MapShapes(anArgumentShape, anArgumentIndices);
1856
1857       if (anArgumentIndices.Contains(aWhat)) {
1858         isFound = Standard_True;
1859         Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(aWhat);
1860
1861         // Find corresponding label in history
1862         TDF_Label anArgumentHistoryLabel =
1863           aWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
1864         if (anArgumentHistoryLabel.IsNull()) {
1865           // Lost History of operation argument. Possibly, all its entities was removed.
1866           SetErrorCode(OK);
1867           return NULL;
1868         }
1869
1870         TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
1871         if (aWhatHistoryLabel.IsNull()) {
1872           // Removed entity
1873           SetErrorCode(OK);
1874           return NULL;
1875         }
1876
1877         Handle(TDataStd_IntegerArray) anIntegerArray;
1878         if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
1879           SetErrorCode("Error: Empty modifications history for the sought shape.");
1880           return NULL;
1881         }
1882
1883         aModifiedArray = anIntegerArray->Array();
1884         if (aModifiedArray->Length() == 0) {
1885           SetErrorCode("Error: Empty modifications history for the sought shape.");
1886           return NULL;
1887         }
1888       }
1889     }
1890
1891     if (!isFound) {
1892       SetErrorCode("The sought shape does not belong to any operation argument.");
1893       return NULL;
1894     }
1895   }
1896
1897   //Add a new object
1898   Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
1899
1900   if (aModifiedArray->Length() > 1) {
1901     //Set a GROUP type
1902     aResult->SetType(GEOM_GROUP);
1903
1904     //Set a sub shape type
1905     TDF_Label aFreeLabel = aResult->GetFreeLabel();
1906     TopAbs_ShapeEnum aShapeType = aWhat.ShapeType();
1907     TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
1908   }
1909
1910   //Make a Python command
1911   TCollection_AsciiString anEntry, aDescr;
1912   TDF_Tool::Entry(aResult->GetEntry(), anEntry);
1913   aDescr += anEntry;
1914   aDescr += " = IShapesOperations.GetInPlace(";
1915   TDF_Tool::Entry(theShapeWhere->GetEntry(), anEntry);
1916   aDescr += anEntry + ",";
1917   TDF_Tool::Entry(theShapeWhat->GetEntry(), anEntry);
1918   aDescr += anEntry + ")";
1919
1920   Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
1921   aFunction->SetDescription(aDescr);
1922
1923   SetErrorCode(OK);
1924   return aResult;
1925 }
1926
1927 //=======================================================================
1928 //function : SortShapes
1929 //purpose  :
1930 //=======================================================================
1931 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
1932 {
1933   Standard_Integer MaxShapes = SL.Extent();
1934   TopTools_Array1OfShape  aShapes (1,MaxShapes);
1935   TColStd_Array1OfInteger OrderInd(1,MaxShapes);
1936   TColStd_Array1OfReal    MidXYZ  (1,MaxShapes); //X,Y,Z;
1937   TColStd_Array1OfReal    Length  (1,MaxShapes); //X,Y,Z;
1938
1939   // Computing of CentreOfMass
1940   Standard_Integer Index;
1941   GProp_GProps GPr;
1942   gp_Pnt GPoint;
1943   TopTools_ListIteratorOfListOfShape it(SL);
1944   for (Index=1;  it.More();  Index++)
1945   {
1946     TopoDS_Shape S = it.Value();
1947     SL.Remove( it ); // == it.Next()
1948     aShapes(Index) = S;
1949     OrderInd.SetValue (Index, Index);
1950     if (S.ShapeType() == TopAbs_VERTEX)
1951     {
1952       GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
1953       Length.SetValue( Index, (Standard_Real) S.Orientation());
1954     }
1955     else
1956     {
1957       BRepGProp::LinearProperties (S, GPr);
1958       GPoint = GPr.CentreOfMass();
1959       Length.SetValue( Index, GPr.Mass() );
1960     }
1961     MidXYZ.SetValue(Index,
1962                     GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
1963   }
1964   // Sorting
1965   Standard_Integer aTemp;
1966   Standard_Boolean exchange, Sort = Standard_True;
1967   while (Sort)
1968   {
1969     Sort = Standard_False;
1970     for (Index=1; Index < MaxShapes; Index++)
1971     {
1972       if (MidXYZ(OrderInd(Index)) > MidXYZ(OrderInd(Index+1)))
1973         exchange = Standard_True;
1974       else if (MidXYZ(OrderInd(Index)) == MidXYZ(OrderInd(Index+1)) &&
1975                Length(OrderInd(Index)) >  Length(OrderInd(Index+1)) )
1976         exchange = Standard_True;
1977       else
1978         exchange = Standard_False;
1979       if (exchange)
1980       {
1981         aTemp = OrderInd(Index);
1982         OrderInd(Index) = OrderInd(Index+1);
1983         OrderInd(Index+1) = aTemp;
1984         Sort = Standard_True;
1985       }
1986     }
1987   }
1988   for (Index=1; Index <= MaxShapes; Index++)
1989     SL.Append( aShapes( OrderInd(Index) ));
1990 }
1991
1992 //=======================================================================
1993 //function : CheckTriangulation
1994 //purpose  :
1995 //=======================================================================
1996 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
1997 {
1998 //  MESSAGE("CheckTriangulation");
1999 //
2000 //  OSD_Timer timer1;
2001 //  timer1.Start();
2002
2003   TopExp_Explorer exp (aShape, TopAbs_FACE);
2004   if (!exp.More()) {
2005     SetErrorCode("Shape without faces given");
2006     return false;
2007   }
2008
2009   TopLoc_Location aTopLoc;
2010   Handle(Poly_Triangulation) aTRF;
2011   aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
2012   if (aTRF.IsNull()) {
2013     // calculate deflection
2014     Standard_Real aDeviationCoefficient = 0.001;
2015
2016     Bnd_Box B;
2017     BRepBndLib::Add(aShape, B);
2018     Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2019     B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2020
2021     Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
2022     Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
2023
2024 //    MESSAGE("Deflection = " << aDeflection);
2025
2026     Standard_Real aHLRAngle = 0.349066;
2027
2028     BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
2029   }
2030 //  timer1.Stop();
2031 //  timer1.Show();
2032
2033   return true;
2034 }