0028786: Refactoring of the Warning/Error reporting system of Boolean Operations...
[occt.git] / src / BOPTest / BOPTest_DebugCommands.cxx
1 // Created by: Eugeny MALTCHIKOV
2 // Copyright (c) 2015 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <BOPTest.hxx>
17 #include <BOPTest_Objects.hxx>
18 #include <BOPTest_DrawableShape.hxx>
19
20 #include <Draw.hxx>
21 #include <Draw_Color.hxx>
22
23 #include <DBRep.hxx>
24
25 #include <BRep_Builder.hxx>
26
27 #include <TopoDS_Compound.hxx>
28
29 #include <TopExp_Explorer.hxx>
30
31 #include <BOPDS_DS.hxx>
32 #include <BOPDS_Iterator.hxx>
33 #include <BOPDS_MapOfCommonBlock.hxx>
34
35 #include <BOPAlgo_Builder.hxx>
36 #include <BOPAlgo_BuilderFace.hxx>
37 #include <BOPAlgo_BuilderSolid.hxx>
38
39 #include <BOPCol_MapOfShape.hxx>
40 #include <BOPCol_DataMapOfShapeShape.hxx>
41 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
42
43
44 static
45   void GetTypeByName(const char* theName,
46                      TopAbs_ShapeEnum& theType);
47 static
48   void GetNameByType(const TopAbs_ShapeEnum& theType,
49                      char* theName);
50
51 template <class InterfType> static
52   void DumpInterfs(const BOPCol_NCVector<InterfType>& theVInterf,
53                    Draw_Interpretor& di);
54
55 template <class InterfType> static
56   void SearchNewIndex(const char* theCType,
57                       const Standard_Integer theInd,
58                       const BOPCol_NCVector<InterfType>& theVInterf,
59                       Draw_Interpretor& di);
60 static 
61   Standard_Integer bopfinfo(Draw_Interpretor& di,
62                             Standard_Integer n,
63                             const char** a,
64                             const Standard_Integer iPriz);
65
66
67 // commands
68 // 1. filler commands
69 // 1.1 DS commands
70 static Standard_Integer bopds       (Draw_Interpretor&, Standard_Integer, const char**);
71 static Standard_Integer bopiterator (Draw_Interpretor&, Standard_Integer, const char**);
72 static Standard_Integer bopinterf   (Draw_Interpretor&, Standard_Integer, const char**);
73 static Standard_Integer bopnews     (Draw_Interpretor&, Standard_Integer, const char**);
74 static Standard_Integer bopwho      (Draw_Interpretor&, Standard_Integer, const char**);
75 static Standard_Integer bopindex    (Draw_Interpretor&, Standard_Integer, const char**);
76 static Standard_Integer bopsd       (Draw_Interpretor&, Standard_Integer, const char**);
77 static Standard_Integer bopsc       (Draw_Interpretor&, Standard_Integer, const char**);
78
79 // 1.2 pave blocks commands
80 static Standard_Integer boppb       (Draw_Interpretor&, Standard_Integer, const char**);
81 static Standard_Integer bopcb       (Draw_Interpretor&, Standard_Integer, const char**);
82 static Standard_Integer bopsp       (Draw_Interpretor&, Standard_Integer, const char**);
83
84 // 1.3 face info commands
85 static Standard_Integer bopfon      (Draw_Interpretor&, Standard_Integer, const char**);
86 static Standard_Integer bopfin      (Draw_Interpretor&, Standard_Integer, const char**);
87 static Standard_Integer bopfsc      (Draw_Interpretor&, Standard_Integer, const char**);
88 static Standard_Integer bopfav      (Draw_Interpretor&, Standard_Integer, const char**);
89
90 // 2. builder commands
91 // 2.1 images commands
92 static Standard_Integer bopimage    (Draw_Interpretor&, Standard_Integer, const char**);
93 static Standard_Integer boporigin   (Draw_Interpretor&, Standard_Integer, const char**);
94 static Standard_Integer bopfsd      (Draw_Interpretor&, Standard_Integer, const char**);
95
96 // 2.2 building faces
97 static Standard_Integer bopbface    (Draw_Interpretor&, Standard_Integer, const char**);
98 // 2.3 building solids
99 static Standard_Integer bopbsolid   (Draw_Interpretor&, Standard_Integer, const char**);
100
101
102 //=======================================================================
103 //function : DebugCommands
104 //purpose  : 
105 //=======================================================================
106 void BOPTest::DebugCommands(Draw_Interpretor& theCommands)
107 {
108   static Standard_Boolean done = Standard_False;
109   if (done) return;
110   done = Standard_True;
111   // Chapter's name
112   const char* g = "BOPTest commands";
113   // Commands
114   theCommands.Add("bopds",
115                   "Shows the shapes from DS. Use: bopds [v/e/w/f/sh/s/cs/c]",
116                   __FILE__, bopds,       g);
117   theCommands.Add("bopiterator", 
118                   "Shows the pairs of interfered shapes. Use: bopiterator [type1 type2]",
119                   __FILE__, bopiterator, g);
120   theCommands.Add("bopinterf", "Shows interferences of given type. Use: bopinterf type1 type2",
121                   __FILE__, bopinterf,   g);
122   theCommands.Add("bopnews", "Shows the newly created shapes. Use: bopnews [v,e,f]",
123                   __FILE__, bopnews,     g);
124   theCommands.Add("bopwho", "Shows where the new shape was created. Use: bopwho #",
125                   __FILE__, bopwho,      g);
126   theCommands.Add("bopindex", "Gets the index of the shape in the DS. Use: bopindex s",
127                   __FILE__, bopindex,    g);
128   theCommands.Add("bopsd", "Gets the Same domain shape. Use: bopsd #",
129                    __FILE__, bopsd,      g);
130   theCommands.Add("bopsc", "Shows the section curves. Use: bopsc [nF1 nF2]",
131                   __FILE__, bopsc,       g);
132   theCommands.Add("boppb", "Shows information about pave blocks. Use: boppb [#e]",
133                   __FILE__, boppb,       g);
134   theCommands.Add("bopcb", "Shows information about common blocks. Use: bopcb [#e]",
135                   __FILE__, bopcb,       g);
136   theCommands.Add("bopsp", "Shows the splits of edges. Use: bopsp [#e]",
137                   __FILE__, bopsp,       g);
138   theCommands.Add("bopfon", "Shows ON information for the face. Use: bopfon #f",
139                   __FILE__, bopfon,      g);
140   theCommands.Add("bopfin", "Shows IN information for the face. Use: bopfin #f",
141                   __FILE__, bopfin,      g);
142   theCommands.Add("bopfsc", "Shows SC information for the face. Use: bopfsc #f",
143                   __FILE__, bopfsc,      g);
144   theCommands.Add("bopfav", "Shows information about alone vertices for the face. Use: bopfav #f",
145                   __FILE__, bopfav,      g);
146   theCommands.Add("bopimage", "Shows split parts of the shape. Use: bopimage s",
147                   __FILE__, bopimage,    g);
148   theCommands.Add("boporigin", "Shows the original shape for the shape. Use: boporigin s",
149                   __FILE__, boporigin,   g);
150   theCommands.Add("bopfsd", "Shows SD faces for the face: Use: bopfsd f",
151                   __FILE__, bopfsd,      g);
152   theCommands.Add("bopbsolid", "Build solids from set of shared faces. Use: bopbsolid sr cx",
153                   __FILE__, bopbsolid,   g);
154   theCommands.Add("bopbface", "Splits the face by set of shared edges. Use: bopbface fr cx",
155                   __FILE__, bopbface,    g);
156 }
157
158 //=======================================================================
159 //function : bopds
160 //purpose  : 
161 //=======================================================================
162 Standard_Integer bopds (Draw_Interpretor& di,
163                         Standard_Integer n,
164                         const char** a)
165 {
166   if (n > 2) {
167     di << "Shows the shapes from DS. Use: bopds [v/e/w/f/sh/s/cs/c]\n";
168     return 1;
169   }
170   //
171   BOPDS_PDS pDS = BOPTest_Objects::PDS();
172   if (!pDS) {
173     di << " prepare PaveFiller first\n";
174     return 1;
175   }
176   //
177   char buf[32];
178   Standard_CString aText;
179   Standard_Integer i, aNbS;
180   TopAbs_ShapeEnum aType, aTypeShape;
181   Draw_Color aTextColor(Draw_cyan);
182   //
183   BOPDS_DS& aDS = *pDS;
184   aNbS = aDS.NbSourceShapes();
185   //
186   aType = TopAbs_SHAPE;
187   if (n == 2) {
188     GetTypeByName(a[1], aType);
189   }
190   //
191   for (i = 0; i < aNbS; ++i) {
192     const BOPDS_ShapeInfo& aSI = aDS.ShapeInfo(i);
193     const TopoDS_Shape& aS = aSI.Shape();
194     aTypeShape = aSI.ShapeType();
195     if (n == 1) {
196       if (aTypeShape == TopAbs_COMPOUND ||
197           aTypeShape == TopAbs_COMPSOLID ||
198           aTypeShape == TopAbs_SOLID ||
199           aTypeShape == TopAbs_SHELL || 
200           aTypeShape == TopAbs_WIRE) {
201         continue;
202       }
203     }
204     else {
205       if (aTypeShape != aType) {
206         continue;
207       }
208     }
209     //
210     Sprintf(buf, "z%d", i);
211     aText = buf;
212     Handle(BOPTest_DrawableShape) aDShape = new BOPTest_DrawableShape(aS, aText, aTextColor);
213     Draw::Set(aText, aDShape);
214   }
215   //
216   return 0;
217 }
218
219 //=======================================================================
220 //function : bopiterator
221 //purpose  : 
222 //=======================================================================
223 Standard_Integer bopiterator (Draw_Interpretor& di,
224                               Standard_Integer n,
225                               const char** a)
226 {
227   if (n != 1 && n != 3) {
228     di << "Shows the pairs of interfered shapes. Use: bopiterator [type1 type2]\n";
229     return 1;
230   }
231   //
232   BOPDS_PDS pDS = BOPTest_Objects::PDS();
233   if (!pDS) {
234     di << " prepare PaveFiller first\n";
235     return 1;
236   }
237   //
238   Standard_Integer n1, n2;
239   char buf[64], aST1[10], aST2[10];
240   BOPDS_Iterator aIt;
241   //
242   BOPDS_DS& aDS = *pDS;
243   aIt.SetDS(&aDS);
244   aIt.Prepare();
245   //
246   if (n == 1) {
247     // type has not been defined. show all pairs
248     Standard_Integer i, j;
249     TopAbs_ShapeEnum aT[4] = 
250       {TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE, TopAbs_SOLID};
251     for (i = 0; i < 4; ++i) {
252       GetNameByType(aT[i], aST1);
253       //
254       for (j = i; j < 4; ++j) {
255         GetNameByType(aT[j], aST2);
256         //
257         aIt.Initialize(aT[i], aT[j]);
258         for (; aIt.More(); aIt.Next()) {
259           aIt.Value(n1, n2);
260           //
261           Sprintf(buf, "%s/%s: (z%d z%d)\n", aST1, aST2, n1, n2);
262           di << buf;
263         }
264       }
265     }
266   }
267   else if (n == 3) {
268     TopAbs_ShapeEnum aT1, aT2;
269     //
270     GetTypeByName(a[1], aT1);
271     GetTypeByName(a[2], aT2);
272     //
273     GetNameByType(aT1, aST1);
274     GetNameByType(aT2, aST2);
275     //
276     aIt.Initialize(aT1, aT2);
277     for (; aIt.More(); aIt.Next()) {
278       aIt.Value(n1, n2);
279       //
280       Sprintf(buf, "%s/%s: (z%d z%d)\n", aST1, aST2, n1, n2);
281       di << buf;
282     }
283   }
284   //
285   return 0;
286 }
287
288 //=======================================================================
289 //function : bopinterf
290 //purpose  : 
291 //=======================================================================
292 Standard_Integer bopinterf (Draw_Interpretor& di,
293                             Standard_Integer n,
294                             const char** a)
295 {
296   if (n != 3) {
297     di << "Shows interferences of given type. Use: bopinterf type1 type2\n";
298     return 1;
299   }
300   //
301   BOPDS_PDS pDS = BOPTest_Objects::PDS();
302   if (!pDS) {
303     di << " prepare PaveFiller first\n";
304     return 1;
305   }
306   //
307   TopAbs_ShapeEnum aT1, aT2;
308   GetTypeByName(a[1], aT1);
309   GetTypeByName(a[2], aT2);
310   //
311   if (aT1 == TopAbs_VERTEX && aT2 == TopAbs_VERTEX) {
312     di << "V/V: ";
313     DumpInterfs<BOPDS_InterfVV>(pDS->InterfVV(), di);
314   }
315   else if ((aT1 == TopAbs_VERTEX && aT2 == TopAbs_EDGE) ||
316            (aT2 == TopAbs_VERTEX && aT1 == TopAbs_EDGE)) {
317     di << "V/E: ";
318     DumpInterfs<BOPDS_InterfVE>(pDS->InterfVE(), di);
319   }
320   else if (aT1 == TopAbs_EDGE && aT2 == TopAbs_EDGE) {
321     di << "E/E: ";
322     DumpInterfs<BOPDS_InterfEE>(pDS->InterfEE(), di);
323   }
324   else if ((aT1 == TopAbs_VERTEX && aT2 == TopAbs_FACE) ||
325            (aT2 == TopAbs_VERTEX && aT1 == TopAbs_FACE)) {
326     di << "V/F: ";
327     DumpInterfs<BOPDS_InterfVF>(pDS->InterfVF(), di);
328   }
329   else if ((aT1 == TopAbs_EDGE && aT2 == TopAbs_FACE) ||
330            (aT2 == TopAbs_EDGE && aT1 == TopAbs_FACE)) {
331     di << "E/F: ";
332     DumpInterfs<BOPDS_InterfEF>(pDS->InterfEF(), di);
333   }
334   else if (aT1 == TopAbs_FACE && aT2 == TopAbs_FACE) {
335     di << "F/F: ";
336     DumpInterfs<BOPDS_InterfFF>(pDS->InterfFF(), di);
337   }
338   else if ((aT1 == TopAbs_VERTEX && aT2 == TopAbs_SOLID) ||
339            (aT2 == TopAbs_VERTEX && aT1 == TopAbs_SOLID)) {
340     di << "V/S: ";
341     DumpInterfs<BOPDS_InterfVZ>(pDS->InterfVZ(), di);
342   }
343   else if ((aT1 == TopAbs_EDGE && aT2 == TopAbs_SOLID) ||
344            (aT2 == TopAbs_EDGE && aT1 == TopAbs_SOLID)) {
345     di << "E/S: ";
346     DumpInterfs<BOPDS_InterfEZ>(pDS->InterfEZ(), di);
347   }
348   else if ((aT1 == TopAbs_FACE && aT2 == TopAbs_SOLID) ||
349            (aT2 == TopAbs_FACE && aT1 == TopAbs_SOLID)) {
350     di << "F/S: ";
351     DumpInterfs<BOPDS_InterfFZ>(pDS->InterfFZ(), di);
352   }
353   else if (aT1 == TopAbs_SOLID && aT2 == TopAbs_SOLID) {
354     di << "S/S: ";
355     DumpInterfs<BOPDS_InterfZZ>(pDS->InterfZZ(), di);
356   }
357   //
358   return 0;
359 }
360
361 //=======================================================================
362 //function : bopwho
363 //purpose  : 
364 //=======================================================================
365 Standard_Integer bopwho (Draw_Interpretor& di,
366                          Standard_Integer n,
367                          const char** a)
368 {
369   if (n != 2) {
370     di << "Shows where the new shape was created. Use: bopwho #\n";
371     return 1;
372   }
373   //
374   BOPDS_PDS pDS=BOPTest_Objects::PDS();
375   if (!pDS) {
376     di << " prepare PaveFiller first\n";
377     return 0;
378   }
379   //
380   Standard_Integer ind = Draw::Atoi(a[1]);
381   if (ind <= 0) {
382     di << " Index must be grater than 0\n";
383     return 1;
384   }
385   //
386   Standard_Integer i1, i2;
387   //
388   i1 = 0;
389   i2 = pDS->NbShapes();
390   if (ind < i1 || ind > i2) {
391     di << " DS does not contain the shape\n";
392     return 1;
393   }
394   //
395   if (!pDS->IsNewShape(ind)) {
396     Standard_Integer iRank = pDS->Rank(ind);
397     di << " Rank: " << iRank << "\n";
398     return 0;
399   }
400   //
401   // the shape is new
402   di << "the shape is new\n";
403   //
404   const BOPDS_ShapeInfo& aSI = pDS->ShapeInfo(ind);
405   if (aSI.ShapeType() != TopAbs_VERTEX) {
406     return 0;
407   }
408   // search among interfs
409   BOPDS_VectorOfInterfVV& aVVs = pDS->InterfVV();
410   BOPDS_VectorOfInterfVE& aVEs = pDS->InterfVE();
411   BOPDS_VectorOfInterfEE& aEEs = pDS->InterfEE();
412   BOPDS_VectorOfInterfVF& aVFs = pDS->InterfVF();
413   BOPDS_VectorOfInterfEF& aEFs = pDS->InterfEF();
414   //
415   SearchNewIndex<BOPDS_InterfVV> ("V/V: ", ind, aVVs, di);
416   SearchNewIndex<BOPDS_InterfVE> ("V/E: ", ind, aVEs, di);
417   SearchNewIndex<BOPDS_InterfEE> ("E/E: ", ind, aEEs, di);
418   SearchNewIndex<BOPDS_InterfVF> ("V/F: ", ind, aVFs, di);
419   SearchNewIndex<BOPDS_InterfEF> ("E/F: ", ind, aEFs, di);
420   //
421   //--------------------------------------FF
422   char buf[64];
423   Standard_Boolean bFound;
424   Standard_Integer i, n1, n2, k, aNb, aNbC, aNbP, nV1, nV2;
425   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
426   //
427   bFound = Standard_False;
428   BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
429   aNb = aFFs.Extent();
430   for (i = 0; i < aNb; ++i) {
431     const BOPDS_InterfFF& anInt = aFFs(i);
432     anInt.Indices(n1, n2);
433     //
434     const BOPDS_VectorOfCurve& aVNC = anInt.Curves();
435     aNbC = aVNC.Extent();
436     for (k = 0; k < aNbC; ++k) {
437       const BOPDS_Curve& aNC = aVNC(k);
438       const BOPDS_ListOfPaveBlock& aLPB = aNC.PaveBlocks(); 
439       aItLPB.Initialize(aLPB);
440       for(; aItLPB.More(); aItLPB.Next()) {
441         const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
442         aPB->Indices(nV1, nV2);
443         if (ind == nV1 || ind == nV2) {
444           if (!bFound) {
445             di << " FF curves: ";
446             bFound = Standard_True;
447           }
448           Sprintf (buf,"(%d, %d) ", n1, n2);
449           di << buf;
450           break;
451         }
452       }
453     }//for (k=0; k<aNbC; ++k) 
454     if (bFound) {
455       di << "\n";
456     }
457     //
458     bFound = Standard_False;
459     const BOPDS_VectorOfPoint& aVNP = anInt.Points();
460     aNbP = aVNP.Extent();
461     for (k = 0; k < aNbP; ++k) {
462       const BOPDS_Point& aNP = aVNP(k);
463       nV1 = aNP.Index();
464       if (ind == nV1) {
465         if (!bFound) {
466           di << " FF points: ";
467           bFound = Standard_True;
468         }
469         sprintf (buf,"(%d, %d) ", n1, n2);
470         di << buf;
471       }
472     }//for (k=0; k<aNbP; ++k) 
473     if (bFound) {
474       di << "\n";
475     }
476   }
477   //
478   return 0;
479 }
480
481 //=======================================================================
482 //function : bopnews
483 //purpose  : 
484 //=======================================================================
485 Standard_Integer bopnews(Draw_Interpretor& di,
486                          Standard_Integer n,
487                          const char** a)
488
489   if (n != 2) {
490     di << "Shows the newly created shapes. Use: bopnews v/e/f\n";
491     return 1;
492   }
493   //
494   BOPDS_PDS pDS = BOPTest_Objects::PDS();
495   if (!pDS) {
496     di << " prepare PaveFiller first\n";
497     return 1;
498   }
499   //
500   TopAbs_ShapeEnum aType;
501   GetTypeByName(a[1], aType);
502   //
503   if (!(aType == TopAbs_VERTEX ||
504         aType == TopAbs_EDGE ||
505         aType == TopAbs_FACE)) {
506     di << "Use: bopnews v/e/f\n";
507     return 1;
508   }
509   //
510   char buf[32];
511   Standard_CString aText;
512   Standard_Boolean bFound;
513   Standard_Integer i, i1, i2;
514   Draw_Color aTextColor(Draw_cyan);
515   Handle(BOPTest_DrawableShape) aDShape;
516   //
517   bFound = Standard_False;
518   i1 = pDS->NbSourceShapes();
519   i2 = pDS->NbShapes();
520   for (i = i1; i < i2; ++i) {
521     const BOPDS_ShapeInfo& aSI = pDS->ShapeInfo(i);
522     if (aSI.ShapeType() == aType) {
523       const TopoDS_Shape& aS = aSI.Shape();
524       //
525       sprintf (buf, "z%d", i);
526       aText = buf;
527       aDShape = new BOPTest_DrawableShape(aS, aText, aTextColor);
528       Draw::Set(aText, aDShape);
529       //
530       sprintf (buf, "z%d ", i);
531       di << buf;
532       //
533       bFound = Standard_True;
534     }
535   }
536   //
537   if (bFound) {
538     di << "\n";
539   }
540   else {
541     di << " No new shapes found\n";
542   }
543   //
544   return 0;
545 }
546
547 //=======================================================================
548 //function : bopindex
549 //purpose  : 
550 //=======================================================================
551 Standard_Integer bopindex (Draw_Interpretor& di,
552                            Standard_Integer n,
553                            const char** a)
554 {
555   if (n != 2) {
556     di << "Gets the index of the shape in the DS. Use: bopindex s\n";
557     return 1;
558   }
559   //
560   BOPDS_PDS pDS=BOPTest_Objects::PDS();
561   if (!pDS) {
562     di << " prepare PaveFiller first\n";
563     return 1;
564   }
565   //
566   TopoDS_Shape aS = DBRep::Get(a[1]);
567   if (aS.IsNull()) {
568     di << a[1] << " is a null shape\n";
569     return 1;
570   }
571   //
572   Standard_Integer ind = pDS->Index(aS);
573   Standard_Boolean bFound = (ind > 0);
574   if (bFound) {
575     di << " Index: " << ind << "\n";
576   }
577   else {
578     di << " DS does not contain the shape\n";
579   }
580   //
581   return 0;
582 }
583   
584 //=======================================================================
585 //function : bopsd
586 //purpose  : 
587 //=======================================================================
588 Standard_Integer bopsd(Draw_Interpretor& di,
589                        Standard_Integer n,
590                        const char** a)
591
592   if (n != 2) {
593     di << "Gets the Same domain shape. Use: bopsd #\n";
594     return 0;
595   }
596   //
597   BOPDS_PDS pDS = BOPTest_Objects::PDS();
598   if (!pDS) {
599     di << " prepare PaveFiller first\n";
600     return 0;
601   }
602   //
603   char buf[32];
604   Standard_Boolean bHasSD;
605   Standard_Integer ind, i1, i2, iSD;
606   //
607   ind = Draw::Atoi(a[1]);
608   //
609   i1 = 0;
610   i2 = pDS->NbShapes();
611   if (ind < i1 || ind > i2) {
612     di << " DS does not contain the shape\n";
613     return 0;
614   }
615   //
616   bHasSD = pDS->HasShapeSD(ind, iSD);
617   if (bHasSD) {
618     Sprintf(buf, " Shape %d has SD shape %d\n", ind, iSD);
619     di << buf;
620   }
621   else {
622     Sprintf (buf, " Shape: %d has no SD shape\n", ind);
623     di << buf;
624   }
625   //
626   return 0;
627 }
628
629 //=======================================================================
630 //function : bopsc
631 //purpose  : 
632 //=======================================================================
633 Standard_Integer bopsc(Draw_Interpretor& di,
634                        Standard_Integer n,
635                        const char** a)
636 {
637   if (n != 1 && n != 3) {
638     di << "Shows the section curves. Use: bopsc [nF1 nF2]\n";
639     return 1;
640   }
641   //
642   BOPDS_PDS pDS=BOPTest_Objects::PDS();
643   if (!pDS) {
644     di << " prepare PaveFiller first\n";
645     return 0;
646   }
647   //
648   char buf[32];
649   Standard_CString aText;
650   Draw_Color aTextColor(Draw_cyan);
651   Standard_Integer nSF1, nSF2, nF1, nF2;
652   Standard_Integer aNb, j, iCnt, k, iPriz, aNbC, aNbP, nSp;
653   Standard_Integer iX;
654   Handle(BOPTest_DrawableShape) aDShape;
655   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
656   //
657   nSF1 = nSF2 = -1;
658   if (n == 3) {
659     nSF1 = Draw::Atoi(a[1]);
660     nSF2 = Draw::Atoi(a[2]);
661   }
662   //
663   BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
664   //
665   iCnt = 0;
666   iPriz = 0;
667   aNb = aFFs.Extent();
668   for (j = 0; j < aNb; ++j) {
669     const BOPDS_InterfFF& aFF = aFFs(j);
670     if (n == 3) {
671       if (!aFF.Contains(nSF1) || !aFF.Contains(nSF2)) {
672         continue;
673       }
674       iPriz = 1;
675     }
676     //
677     aFF.Indices(nF1, nF2);
678     //
679     iX = 0;
680     const BOPDS_VectorOfCurve& aVNC = aFF.Curves();
681     aNbC = aVNC.Extent();
682     for (k = 0; k < aNbC; ++k) {
683       const BOPDS_Curve& aNC = aVNC(k);
684       const BOPDS_ListOfPaveBlock& aLPB = aNC.PaveBlocks();
685       aItLPB.Initialize(aLPB);
686       for(; aItLPB.More(); aItLPB.Next()) {
687         const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
688         if (!aPB->HasEdge(nSp)) {
689           continue;
690         }
691         //
692         if (!iX) {
693           Sprintf (buf, "[%d %d] section edges: ", nF1, nF2);
694           di << buf;
695           iX = 1;
696         }
697         sprintf (buf, "t_%d_%d", k, nSp);
698         di << buf;
699         //
700         const TopoDS_Shape& aSp = pDS->Shape(nSp);
701         aText = buf;
702         aDShape = new BOPTest_DrawableShape(aSp, aText, aTextColor);
703         Draw::Set(aText, aDShape);
704         di << " ";
705         ++iCnt;
706       }
707     }
708     if (iX) {
709       di << "\n";
710     }
711     //
712     iX = 0;
713     const BOPDS_VectorOfPoint& aVNP = aFF.Points();
714     aNbP = aVNP.Extent();
715     for (k = 0; k < aNbP; ++k) {
716       const BOPDS_Point& aNP = aVNP(k);
717       nSp = aNP.Index();
718       if (nSp < 0) {
719         continue;
720       }
721       if (!iX) {
722         sprintf (buf, "[%d %d] section vertices: ", nF1, nF2);
723         di << buf;
724         iX = 1;
725       }
726       sprintf (buf, "p_%d_%d", k, nSp);
727       di << buf;
728       //
729       const TopoDS_Shape& aSp = pDS->Shape(nSp);
730       aText = buf;
731       aDShape = new BOPTest_DrawableShape(aSp, aText, aTextColor);
732       Draw::Set(aText, aDShape);
733       di << " ";
734       ++iCnt;
735     }
736     if (iX) {
737       di << "\n";
738     }
739     //
740     if (iPriz) {
741       break;
742     }
743   }// for (j=0; j<aNb; ++j) {
744   //
745   if (iCnt) {
746     di << "\n";
747   }
748   else {
749     di << " no sections found\n";
750   }
751   //
752   return 0;
753 }
754
755 //=======================================================================
756 //function : boppb
757 //purpose  : 
758 //=======================================================================
759 Standard_Integer boppb(Draw_Interpretor& di,
760                        Standard_Integer n,
761                        const char** a)
762
763   if (n > 2) {
764     di << "Shows information about pave blocks. Use: boppb [#e]\n";
765     return 1;
766   }
767   //
768   BOPDS_PDS pDS = BOPTest_Objects::PDS();
769   if (!pDS) {
770     di << " prepare PaveFiller first\n";
771     return 1;
772   }
773   //
774   Standard_Boolean bHasPaveBlocks;
775   Standard_Integer ind, i1, i2;
776   TopAbs_ShapeEnum aType;
777   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
778   //
779   i1 = 0;
780   i2 = pDS->NbSourceShapes();
781   if (n == 2) {
782     ind = Draw::Atoi(a[1]);
783     i1 = ind;
784     i2 = ind + 1;
785   }
786   //
787   for (ind = i1; ind < i2; ++ind) {
788     const BOPDS_ShapeInfo& aSI = pDS->ShapeInfo(ind);
789     aType = aSI.ShapeType();
790     if (aType != TopAbs_EDGE) {
791       continue;
792     }
793     //
794     bHasPaveBlocks = pDS->HasPaveBlocks(ind);
795     if (!bHasPaveBlocks) {
796       continue;
797     }
798     //
799     const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(ind);
800     aItPB.Initialize(aLPB);
801     for (; aItPB.More(); aItPB.Next()) {
802       const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
803       aPB->Dump();
804       printf("\n");
805     }
806   }
807   //
808   return 0;
809 }
810
811 //=======================================================================
812 //function : bopcb
813 //purpose  : 
814 //=======================================================================
815 Standard_Integer bopcb(Draw_Interpretor& di,
816                        Standard_Integer n,
817                        const char** a)
818
819   if (n > 2) {
820     di << "Shows information about common blocks. Use: bopcb [#e]\n";
821     return 1;
822   }
823   //
824   BOPDS_PDS pDS = BOPTest_Objects::PDS();
825   if (!pDS) {
826     di << " prepare PaveFiller first\n";
827     return 1;
828   }
829   //
830   Standard_Boolean bHasPaveBlocks;
831   Standard_Integer ind, i1, i2;
832   TopAbs_ShapeEnum aType;
833   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
834   BOPDS_MapOfCommonBlock aMCB;
835   //
836   i1 = 0;
837   i2 = pDS->NbSourceShapes();
838   if (n == 2) {
839     ind = Draw::Atoi(a[1]);
840     i1 = ind;
841     i2 = ind + 1;
842   }
843   //
844   for (ind = i1; ind < i2; ++ind) {
845     const BOPDS_ShapeInfo& aSI = pDS->ShapeInfo(ind);
846     aType = aSI.ShapeType();
847     if (aType != TopAbs_EDGE) {
848       continue;
849     }
850     //
851     bHasPaveBlocks = pDS->HasPaveBlocks(ind);
852     if (!bHasPaveBlocks) {
853       continue;
854     }
855     //
856     const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(ind);
857     aItPB.Initialize(aLPB);
858     for (; aItPB.More(); aItPB.Next()) {
859       const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
860       if (pDS->IsCommonBlock(aPB)) {
861         const Handle(BOPDS_CommonBlock)& aCB = pDS->CommonBlock(aPB);
862         if(aMCB.Add(aCB)) {
863           aCB->Dump();
864           printf("\n");
865         }
866       }
867     }
868   }
869   //
870   return 0;
871 }
872
873 //=======================================================================
874 //function : bopsp
875 //purpose  : 
876 //=======================================================================
877 Standard_Integer bopsp(Draw_Interpretor& di,
878                        Standard_Integer n,
879                        const char** a)
880 {
881   if (n > 2) {
882     di << "Shows the splits of edges. Use: bopsp [#e]\n";
883     return 1;
884   }
885   //
886   BOPDS_PDS pDS = BOPTest_Objects::PDS();
887   if (!pDS) {
888     di << " prepare PaveFiller first\n";
889     return 1;
890   }
891   //
892   char buf[32];
893   Standard_Boolean bHasPaveBlocks;
894   Standard_Integer ind, i1, i2, nSp;
895   TopAbs_ShapeEnum aType;
896   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
897   Standard_CString aText;
898   Draw_Color aTextColor(Draw_cyan);
899   Handle(BOPTest_DrawableShape) aDShape;
900   //
901   i1 = 0;
902   i2 = pDS->NbSourceShapes();
903   if (n == 2) {
904     ind = Draw::Atoi(a[1]);
905     i1 = ind;
906     i2 = ind + 1;
907   }
908   //
909   for (ind = i1; ind < i2; ++ind) {
910     const BOPDS_ShapeInfo& aSI = pDS->ShapeInfo(ind);
911     aType = aSI.ShapeType();
912     if (aType != TopAbs_EDGE) {
913       continue;
914     }
915     //
916     bHasPaveBlocks = pDS->HasPaveBlocks(ind);
917     if (!bHasPaveBlocks) {
918       continue;
919     }
920     //
921     di << "Edge " << ind << ": ";
922     //
923     const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(ind);
924     aItPB.Initialize(aLPB);
925     for (; aItPB.More(); aItPB.Next()) {
926       const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
927       nSp = aPB->Edge();
928       const TopoDS_Shape& aSp = pDS->Shape(nSp);
929       //
930       Sprintf(buf, "z%d_%d", ind, nSp);
931       aText = buf;
932       aDShape = new BOPTest_DrawableShape(aSp, aText, aTextColor);
933       Draw::Set(aText, aDShape);
934       di << buf << " ";
935     }
936     di << "\n";
937   }
938   //
939   return 0;
940 }
941
942 //=======================================================================
943 //function : bopfon
944 //purpose  : 
945 //=======================================================================
946 Standard_Integer bopfon(Draw_Interpretor& di,
947                         Standard_Integer n,
948                         const char** a)
949 {
950   return bopfinfo(di, n, a, 0);
951 }
952
953 //=======================================================================
954 //function : bopfin
955 //purpose  : 
956 //=======================================================================
957 Standard_Integer bopfin(Draw_Interpretor& di,
958                         Standard_Integer n,
959                         const char** a)
960 {
961   return bopfinfo(di, n, a, 1);
962 }
963
964 //=======================================================================
965 //function : bopfspsc
966 //purpose  : 
967 //=======================================================================
968 Standard_Integer bopfsc(Draw_Interpretor& di,
969                         Standard_Integer n,
970                         const char** a)
971 {
972   return bopfinfo(di, n, a, 2);
973 }
974
975 //=======================================================================
976 //function : bopfinfo
977 //purpose  : 
978 //=======================================================================
979 Standard_Integer bopfinfo(Draw_Interpretor& di,
980                           Standard_Integer n,
981                           const char** a,
982                           const Standard_Integer iPriz)
983 {
984   if (n != 2) {
985     di << "Shows " << ((iPriz == 0) ? "ON" : ((iPriz == 1) ? "IN" : "SC")) <<
986       " information for the face. Use: bopf* #f\n";
987     return 1;
988   }
989   //
990   BOPDS_PDS pDS = BOPTest_Objects::PDS();
991   if (!pDS) {
992     di << " prepare PaveFiller first\n";
993     return 1;
994   }
995   //
996   char aText[32];
997   Standard_Integer nF, i1, i2, nV, i, aNb;
998   Handle(BOPDS_PaveBlock) aPB;
999   //
1000   nF = Draw::Atoi(a[1]);
1001   i1 = 0;
1002   i2 = pDS->NbSourceShapes();
1003   if (nF < i1 || nF > i2) {
1004     di << " DS does not contain the shape\n";
1005     return 1;
1006   }
1007   //
1008   if (pDS->ShapeInfo(nF).ShapeType() != TopAbs_FACE) {
1009     di << " The shape is not a face\n";
1010     return 1;
1011   }
1012   //
1013   if (!pDS->HasFaceInfo(nF)) {
1014     di << " The face has no face information\n";
1015     return 0;
1016   }
1017   //
1018   BOPDS_FaceInfo& aFI = pDS->ChangeFaceInfo(nF);
1019   //
1020   BOPDS_IndexedMapOfPaveBlock aMPB;
1021   BOPCol_MapOfInteger aMI;
1022   if (iPriz == 0) {
1023     strcpy(aText, "On");
1024     aMPB = aFI.ChangePaveBlocksOn();
1025     aMI = aFI.ChangeVerticesOn();
1026   }
1027   else if (iPriz == 1) {
1028     strcpy(aText, "In");
1029     aMPB = aFI.ChangePaveBlocksIn();
1030     aMI = aFI.ChangeVerticesIn();
1031   }
1032   else if (iPriz == 2) {
1033     strcpy(aText, "Sc");
1034     aMPB = aFI.ChangePaveBlocksSc();
1035     aMI = aFI.ChangeVerticesSc();
1036   }
1037   //
1038   if (aMPB.Extent()) {
1039     printf(" pave blocks %s:\n", aText);
1040     aNb = aMPB.Extent();
1041     for (i = 1; i <= aNb; ++i) {
1042       aPB = aMPB(i);
1043       aPB->Dump();
1044       printf(" \n" );
1045     }
1046   }
1047   else {
1048     printf(" no pave blocks %s found\n", aText);
1049   }
1050   //
1051   if (aMI.Extent()) {
1052     printf(" vertices %s:\n", aText);
1053     BOPCol_MapIteratorOfMapOfInteger aItMI(aMI);
1054     for (; aItMI.More(); aItMI.Next()) {
1055       nV = aItMI.Value();
1056       printf(" %d", nV);
1057     }
1058     printf(" \n" );
1059   }
1060   else {
1061     printf(" no verts %s found\n", aText);
1062   }
1063   //
1064   return 0;
1065 }
1066
1067 //=======================================================================
1068 //function : bopfav
1069 //purpose  : alone vertices on face
1070 //=======================================================================
1071 Standard_Integer bopfav(Draw_Interpretor& di,
1072                         Standard_Integer n,
1073                         const char** a)
1074 {
1075   if (n != 2) {
1076     di << "Shows information about alone vertices for the face. Use: bopfav #f\n";
1077     return 1;
1078   }
1079   //
1080   BOPDS_PDS pDS = BOPTest_Objects::PDS();
1081   if (!pDS) {
1082     di << " prepare PaveFiller first\n";
1083     return 0;
1084   }
1085   //
1086   Standard_Integer i1, i2, nF, nV;
1087   //
1088   nF = Draw::Atoi(a[1]);
1089   i1 = 0;
1090   i2 = pDS->NbSourceShapes();
1091   if (nF < i1 || nF > i2) {
1092     di << "DS does not contain the shape\n";
1093     return 1;
1094   }
1095   //
1096   if (pDS->ShapeInfo(nF).ShapeType() != TopAbs_FACE) {
1097     di << " The shape is not a face\n";
1098     return 1;
1099   }
1100   //
1101   if (!pDS->HasFaceInfo(nF)) {
1102     di << " The face has no face information\n";
1103     return 0;
1104   }
1105   //
1106   BOPCol_ListOfInteger aLI;
1107   pDS->AloneVertices(nF, aLI);
1108   if (!aLI.Extent()) {
1109     di << " no alone vertices found\n";
1110     return 0;
1111   }
1112   //
1113   di << " alone vertices: \n";
1114   BOPCol_ListIteratorOfListOfInteger aItLI(aLI);
1115   for (; aItLI.More(); aItLI.Next()) {
1116     nV = aItLI.Value();
1117     di << nV << " ";
1118   }
1119   di <<"\n";
1120   //
1121   return 0;
1122 }
1123
1124 //=======================================================================
1125 //function : bopimage
1126 //purpose  : 
1127 //=======================================================================
1128 Standard_Integer bopimage(Draw_Interpretor& di,
1129                           Standard_Integer n,
1130                           const char** a)
1131
1132   if (n != 2) {
1133     di << "Shows split parts of the shape. Use: bopimage s\n";
1134     return 1;
1135   }
1136   //
1137   BOPDS_PDS pDS = BOPTest_Objects::PDS();
1138   if (!pDS) {
1139     di << " prepare PaveFiller first\n";
1140     return 1;
1141   }
1142   //
1143   TopoDS_Shape aS = DBRep::Get(a[1]);
1144   if (aS.IsNull()) {
1145     di << a[1] << " is a null shape\n";
1146     return 1;
1147   }
1148   //
1149   BOPAlgo_Builder& aBuilder = BOPTest_Objects::Builder();
1150   const BOPCol_DataMapOfShapeListOfShape& anImages = aBuilder.Images();
1151   if (!anImages.IsBound(aS)) {
1152     di << " no images found\n"; 
1153     return 0;
1154   }
1155   //
1156   char buf[32];
1157   Standard_Integer i;
1158   BRep_Builder aBB;
1159   TopoDS_Compound aC;
1160   //
1161   aBB.MakeCompound(aC);
1162   //
1163   const BOPCol_ListOfShape& aLSIm = anImages.Find(aS);
1164   BOPCol_ListIteratorOfListOfShape aIt(aLSIm);
1165   for (i = 0; aIt.More(); aIt.Next(), ++i) {
1166     const TopoDS_Shape& aSIm = aIt.Value();
1167     aBB.Add(aC, aSIm);
1168   }
1169   //
1170   di << i << " images found\n";
1171   sprintf(buf, "%s_im", a[1]);
1172   DBRep::Set(buf, aC);
1173   di << buf << "\n";
1174   //
1175   return 0;
1176 }
1177
1178 //=======================================================================
1179 //function : boporigin
1180 //purpose  : 
1181 //=======================================================================
1182 Standard_Integer boporigin(Draw_Interpretor& di,
1183                            Standard_Integer n,
1184                            const char** a)
1185
1186   if (n != 2) {
1187     di << "Shows the original shape for the shape. Use: boporigin s\n";
1188     return 1;
1189   }
1190   //
1191   BOPDS_PDS pDS = BOPTest_Objects::PDS();
1192   if (!pDS) {
1193     di << " prepare PaveFiller first\n";
1194     return 1;
1195   }
1196   //
1197   TopoDS_Shape aS = DBRep::Get(a[1]);
1198   if (aS.IsNull()) {
1199     di << a[1] << " is a null shape\n";
1200     return 0;
1201   }
1202   //
1203   BOPAlgo_Builder& aBuilder = BOPTest_Objects::Builder();
1204   const BOPCol_DataMapOfShapeListOfShape& aDMI = aBuilder.Origins();
1205   if (!aDMI.IsBound(aS)) {
1206     di << " no origins found\n"; 
1207     return 0;
1208   }
1209   //
1210   char buf[32];
1211   sprintf(buf, "%s_or", a[1]);
1212   //
1213   const BOPCol_ListOfShape& aLSx = aDMI.Find(aS);
1214   if (aLSx.Extent() == 1) {
1215     DBRep::Set(buf, aLSx.First());
1216     di << "1 origin found\n" << buf << "\n";
1217     return 0;
1218   }
1219   //
1220   TopoDS_Compound aCOr;
1221   BRep_Builder().MakeCompound(aCOr);
1222   //
1223   BOPCol_ListIteratorOfListOfShape aItLSx(aLSx);
1224   for (; aItLSx.More(); aItLSx.Next()) {
1225     BRep_Builder().Add(aCOr, aItLSx.Value());
1226   }
1227   //
1228   DBRep::Set(buf, aCOr);
1229   //
1230   di << aLSx.Extent() << " origins found\n";
1231   di << buf << "\n";
1232   //
1233   return 0;
1234 }
1235
1236 //=======================================================================
1237 //function : bopfsd
1238 //purpose  : 
1239 //=======================================================================
1240 Standard_Integer bopfsd(Draw_Interpretor& di,
1241                         Standard_Integer n,
1242                         const char** a)
1243
1244   if (n != 2) {
1245     di << "Shows SD faces for the face: Use: bopfsd f\n";
1246     return 1;
1247   }
1248   //
1249   BOPDS_PDS pDS = BOPTest_Objects::PDS();
1250   if (!pDS) {
1251     di << " prepare PaveFiller first\n";
1252     return 1;
1253   }
1254   //
1255   TopoDS_Shape aS = DBRep::Get(a[1]);
1256   if (aS.IsNull()) {
1257     di << a[1] << " is a null shape\n";
1258     return 1;
1259   }
1260   //
1261   BOPAlgo_Builder& aBuilder = BOPTest_Objects::Builder();
1262   const BOPCol_DataMapOfShapeShape& aDMSD = aBuilder.ShapesSD();
1263   if (!aDMSD.IsBound(aS)) {
1264     di << " shape has no sd shape\n"; 
1265     return 0;
1266   }
1267   //
1268   char buf[32];
1269   Standard_Integer i;
1270   BRep_Builder aBB;
1271   TopoDS_Compound aC;
1272   //
1273   aBB.MakeCompound(aC);
1274   //
1275   BOPCol_DataMapIteratorOfDataMapOfShapeShape aItSD;
1276   aItSD.Initialize(aDMSD);
1277   for (i = 0; aItSD.More(); aItSD.Next()) {
1278     const TopoDS_Shape& aSK = aItSD.Key();
1279     const TopoDS_Shape& aSV = aItSD.Value();
1280     if (aSK.IsEqual(aS)) {
1281       if (!aSV.IsEqual(aS)) {
1282         aBB.Add(aC, aS);
1283         ++i;
1284       }
1285     }
1286     //
1287     else if (aSV.IsEqual(aS)) {
1288       if (!aSK.IsEqual(aS)) {
1289         aBB.Add(aC, aS);
1290         ++i;
1291       }
1292     }
1293   }
1294   //
1295   di << i << " SD shapes found\n";
1296   //
1297   sprintf(buf, "%s_sd", a[1]);
1298   DBRep::Set(buf, aC);
1299   //
1300   di << buf << "\n";
1301   return 0;
1302 }
1303
1304 //=======================================================================
1305 //function : bopbface
1306 //purpose  : 
1307 //=======================================================================
1308 Standard_Integer bopbface (Draw_Interpretor& di,
1309                            Standard_Integer n,
1310                            const char** a)
1311 {
1312   if ( n!= 3) {
1313     di << "Build faces from surface and set of shared edges. Use: bopbface fr cx\n";
1314     return 1;
1315   }
1316   //
1317   TopoDS_Shape aS = DBRep::Get(a[2]);
1318   if (aS.IsNull()) {
1319     di << a[1] << " is a null shape\n";
1320     return 1;
1321   }
1322   //
1323   TopoDS_Face aF;
1324   BOPCol_ListOfShape aLE;
1325   Standard_Integer i;
1326   //
1327   TopoDS_Iterator aItS(aS);
1328   for (i=0; aItS.More(); aItS.Next(), ++i) {
1329     const TopoDS_Shape& aSx = aItS.Value();
1330     if (!i) {
1331       if (aSx.ShapeType() != TopAbs_FACE) {
1332         di << " shape " << i << " is not a face\n";
1333         return 1;
1334       }
1335       aF = *(TopoDS_Face*)&aSx;
1336     }
1337     else {
1338       if (aSx.ShapeType() != TopAbs_EDGE) {
1339         di << " shape " << i << " is not an edge\n";
1340         return 1;
1341       }
1342       aLE.Append(aSx);
1343     }
1344   }
1345   //
1346   BOPAlgo_BuilderFace aBF;
1347   aBF.SetFace(aF);
1348   aBF.SetShapes(aLE);
1349   aBF.Perform();
1350   BOPTest::ReportAlerts(aBF);
1351   if (aBF.HasErrors()) {
1352     return 0;
1353   }
1354   //
1355   char buf[128];
1356   const BOPCol_ListOfShape& aLFR = aBF.Areas();
1357   BOPCol_ListIteratorOfListOfShape aIt(aLFR);
1358   for (i = 1; aIt.More(); aIt.Next(), ++i) {
1359     const TopoDS_Shape& aFR = aIt.Value();
1360     sprintf(buf, "%s_%d", a[1], i);
1361     DBRep::Set(buf, aFR);
1362     di << " " << buf;
1363   }
1364   //
1365   i = aLFR.Extent();
1366   if (i) {
1367     di << "\n " << i << " faces were built\n";
1368   }
1369   else {
1370     di << " No faces were built\n";
1371   }
1372   //
1373   return 0;
1374 }
1375
1376 //=======================================================================
1377 //function : bopbsolid
1378 //purpose  : 
1379 //=======================================================================
1380 Standard_Integer bopbsolid (Draw_Interpretor& di,
1381                             Standard_Integer n,
1382                             const char** a)
1383 {
1384   if ( n!= 3) {
1385     di << "Build solids from set of shared faces. Use: bopbsolid sr cx\n";
1386     return 1;
1387   }
1388   //
1389   TopoDS_Shape aS = DBRep::Get(a[2]);
1390   if (aS.IsNull()) {
1391     di << a[1] << " is a null shape\n";
1392     return 1;
1393   }
1394   //
1395   BOPCol_ListOfShape aLF;
1396   TopExp_Explorer aExp(aS, TopAbs_FACE);
1397   for (; aExp.More(); aExp.Next()) {
1398     const TopoDS_Shape& aF = aExp.Current();
1399     aLF.Append(aF);
1400   }
1401   //
1402   if (aLF.IsEmpty()) {
1403     di << " No faces to build solids\n";
1404     return 1;
1405   }
1406   //
1407   BOPAlgo_BuilderSolid aBS;
1408   aBS.SetShapes(aLF);
1409   aBS.Perform();
1410   BOPTest::ReportAlerts(aBS);
1411   if (aBS.HasErrors()) {
1412     return 0;
1413   }
1414   //
1415   Standard_Integer i;
1416   TopoDS_Compound aSolids;
1417   BRep_Builder aBB;
1418   //
1419   aBB.MakeCompound(aSolids);
1420   //
1421   char buf[128];
1422   const BOPCol_ListOfShape& aLSR = aBS.Areas();
1423   BOPCol_ListIteratorOfListOfShape aIt(aLSR);
1424   for (i = 1; aIt.More(); aIt.Next(), ++i) {
1425     const TopoDS_Shape& aSR = aIt.Value();
1426     sprintf(buf, "%s_%d", a[1], i);
1427     DBRep::Set(buf, aSR);
1428     di << " " << buf;
1429   }
1430   //
1431   i = aLSR.Extent();
1432   if (i) {
1433     di << "\n " << i << " solids were built\n";
1434   }
1435   else {
1436     di << " No solids were built\n";
1437   }
1438   //
1439   return 0;
1440 }
1441
1442 //=======================================================================
1443 //function : GetTypeByName
1444 //purpose  : 
1445 //=======================================================================
1446 void GetTypeByName(const char* theName,
1447                    TopAbs_ShapeEnum& theType)
1448 {
1449   if (!strcmp (theName, "v") ||
1450       !strcmp (theName, "V")) {
1451     theType = TopAbs_VERTEX;
1452   }
1453   else if (!strcmp (theName, "e") ||
1454            !strcmp (theName, "E")) {
1455     theType = TopAbs_EDGE;
1456   }
1457   else if (!strcmp (theName, "w") ||
1458            !strcmp (theName, "W")) {
1459     theType = TopAbs_WIRE;
1460   }
1461   else if (!strcmp (theName, "f") ||
1462            !strcmp (theName, "F")) {
1463     theType = TopAbs_FACE;
1464   }
1465   else if (!strcmp (theName, "sh") ||
1466            !strcmp (theName, "Sh") ||
1467            !strcmp (theName, "SH")) {
1468     theType = TopAbs_SHELL;
1469   }
1470   else if (!strcmp (theName, "s") ||
1471            !strcmp (theName, "S")) {
1472     theType = TopAbs_SOLID;
1473   }
1474   else if (!strcmp (theName, "cs") ||
1475            !strcmp (theName, "Cs") ||
1476            !strcmp (theName, "CS")) {
1477     theType = TopAbs_COMPSOLID;
1478   }
1479   else if (!strcmp (theName, "c") ||
1480            !strcmp (theName, "C")) {
1481     theType = TopAbs_COMPOUND;
1482   }
1483   else {
1484     theType = TopAbs_SHAPE;
1485   }
1486 }
1487
1488 //=======================================================================
1489 //function : GetNameByType
1490 //purpose  : 
1491 //=======================================================================
1492 void GetNameByType(const TopAbs_ShapeEnum& theType,
1493                    char* theName)
1494 {
1495   switch (theType) {
1496   case TopAbs_VERTEX:
1497     strcpy (theName, "V");
1498     break;
1499   case TopAbs_EDGE:
1500     strcpy (theName, "E");
1501     break; 
1502   case TopAbs_WIRE:
1503     strcpy (theName, "w");
1504     break;
1505   case TopAbs_FACE:
1506     strcpy (theName, "F");
1507     break;
1508   case TopAbs_SHELL:
1509     strcpy (theName, "Sh");
1510     break; 
1511   case TopAbs_SOLID:
1512     strcpy (theName, "S");
1513     break; 
1514   case TopAbs_COMPSOLID:
1515     strcpy (theName, "Cs");
1516     break; 
1517   case TopAbs_COMPOUND:
1518     strcpy (theName, "c");
1519     break; 
1520   default:
1521     strcpy (theName, "Shape");
1522     break; 
1523   }
1524 }
1525
1526 //=======================================================================
1527 //function : DumpInterfs
1528 //purpose  : 
1529 //=======================================================================
1530 template <class InterfType> void DumpInterfs
1531   (const BOPCol_NCVector<InterfType>& theVInterf,
1532    Draw_Interpretor& di)
1533 {
1534   Standard_Integer i, aNb, n1, n2, nNew;
1535   char buf[64];
1536   //
1537   aNb = theVInterf.Extent();
1538   if (aNb == 0) {
1539     di << "Not found\n";
1540     return;
1541   }
1542   //
1543   di << aNb << " interference(s) found\n";
1544   for (i = 0; i < aNb; ++i) {
1545     const InterfType& anInt = theVInterf(i);
1546     anInt.Indices(n1, n2);
1547     if (anInt.HasIndexNew()) {
1548       nNew = anInt.IndexNew();
1549       Sprintf(buf, " (%d, %d, %d)\n", n1, n2, nNew);
1550     }
1551     else {
1552       Sprintf(buf, " (%d, %d)\n", n1, n2);
1553     }
1554     di << buf;
1555   }
1556 }
1557
1558 //=======================================================================
1559 //function : SearchNewIndex
1560 //purpose  : 
1561 //=======================================================================
1562 template <class InterfType> void SearchNewIndex
1563   (const char* theCType,
1564    const Standard_Integer theInd,
1565    const BOPCol_NCVector<InterfType>& theVInterf,
1566    Draw_Interpretor& di)
1567 {
1568   char buf[64];
1569   Standard_Boolean bFound;
1570   Standard_Integer i, aNb, n1, n2, nNew;
1571   //
1572   bFound = Standard_False;
1573   aNb = theVInterf.Extent();
1574   for (i = 0 ; i < aNb; ++i) {
1575     const InterfType& anInt = theVInterf(i);
1576     nNew = anInt.IndexNew();
1577     if (theInd == nNew) {
1578       if (!bFound) {
1579         di << theCType;
1580         bFound = Standard_True;
1581       }
1582       //
1583       anInt.Indices(n1, n2);
1584       sprintf(buf,"(%d, %d) ", n1, n2);
1585       di << buf;
1586     }
1587   }
1588   if (bFound) {
1589     di << "\n";
1590   }
1591 }