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