0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / BRepTest / BRepTest_OtherCommands.cxx
1 // Created on: 1995-04-13
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <BRepTest.hxx>
18
19 #include <Draw.hxx>
20 #include <Draw_Interpretor.hxx>
21 #include <DBRep.hxx>
22 #include <DrawTrSurf.hxx>
23
24 #include <string.h>
25 #include <stdio.h>
26
27 #include <Standard_ErrorHandler.hxx>
28 #include <Precision.hxx>
29 #include <TCollection_AsciiString.hxx>
30 #include <gp_Lin.hxx>
31 #include <gp_Pnt.hxx>
32 #include <gp_Dir.hxx>
33 #include <gp_Ax1.hxx>
34
35 #include <ElCLib.hxx>
36
37 #include <TColgp_SequenceOfPnt.hxx>
38
39 #include <GeomAbs_JoinType.hxx>
40 #include <Geom_Line.hxx>
41
42 #include <IntCurvesFace_Intersector.hxx>
43
44 #include <TopAbs.hxx>
45 #include <TopAbs_Orientation.hxx>
46
47 #include <TopoDS.hxx>
48 #include <TopoDS_Shape.hxx>
49 #include <TopoDS_Compound.hxx>
50 #include <TopoDS_CompSolid.hxx>
51 #include <TopoDS_Solid.hxx>
52 #include <TopoDS_Shell.hxx>
53 #include <TopoDS_Face.hxx>
54 #include <TopoDS_Wire.hxx>
55 #include <TopoDS_Edge.hxx>
56 #include <TopoDS_Vertex.hxx>
57 #include <TopoDS_Iterator.hxx>
58
59 #include <BRep_Builder.hxx>
60 #include <BRep_Tool.hxx>
61
62 #include <TopExp_Explorer.hxx>
63
64 #include <TopTools_ListOfShape.hxx>
65 #include <TopTools_ListIteratorOfListOfShape.hxx>
66 #include <TopTools_MapOfShape.hxx>
67
68 #include <LocOpe_CSIntersector.hxx>
69 #include <LocOpe_SequenceOfLin.hxx>
70 #include <LocOpe_PntFace.hxx>
71 #include <BRepFeat_MakeDPrism.hxx>
72
73 #include <BRepTools.hxx>
74 #include <BRepIntCurveSurface_Inter.hxx>
75 #include <BRepOffset_MakeOffset.hxx>
76 #include <BRepClass3d_SolidClassifier.hxx>
77 #include <GeomAdaptor_Curve.hxx>
78
79 static 
80   void SampleEdges (const TopoDS_Shape&   theShape, 
81                     TColgp_SequenceOfPnt& theSeq);
82 static 
83   TopoDS_Face NextFaceForPrism (const TopoDS_Shape& shape, 
84                                 const TopoDS_Shape& basis,
85                                 const gp_Ax1&       ax1);
86 static
87   void PrintState (Draw_Interpretor& aDI, 
88                    const TopAbs_State& aState);
89 //
90 static Standard_Integer emptyshape(Draw_Interpretor&, Standard_Integer, const char** );
91 static Standard_Integer subshape  (Draw_Interpretor&, Standard_Integer, const char** );
92 static Standard_Integer brepintcs (Draw_Interpretor&, Standard_Integer, const char** );
93 static Standard_Integer MakeBoss  (Draw_Interpretor&, Standard_Integer, const char** );
94 static Standard_Integer MakeShell (Draw_Interpretor&, Standard_Integer, const char** );
95 static Standard_Integer xbounds   (Draw_Interpretor&, Standard_Integer, const char** );
96 static Standard_Integer xclassify (Draw_Interpretor&, Standard_Integer, const char** );
97
98 //=======================================================================
99 //function : OtherCommands
100 //purpose  : 
101 //=======================================================================
102 void  BRepTest::OtherCommands(Draw_Interpretor& theCommands)
103 {
104   static Standard_Boolean done = Standard_False;
105   if (done) return;
106   done = Standard_True;
107
108   const char* g = "TOPOLOGY other commands";
109
110   theCommands.Add("shape",
111                   "shape name V/E/W/F/Sh/So/CS/C; make a empty shape",__FILE__,emptyshape,g);
112
113   theCommands.Add("subshape",
114                   "subshape name V/E/W/F/Sh/So/CS/C index; get subsshape <index> of given type"
115                   ,__FILE__,subshape,g);
116
117   theCommands.Add("BRepIntCS",
118     "Calcul d'intersection entre face et curve : BRepIntCS curve1 [curve2 ...] shape [res] [tol]"
119                   ,__FILE__,brepintcs,g);
120
121   theCommands.Add("makeboss",  "create a boss on the shape myS", __FILE__, MakeBoss, g);
122   theCommands.Add("mksh", "create a shell on Shape", __FILE__, MakeShell, g);
123   theCommands.Add("xbounds",  "xbounds face", __FILE__, xbounds, g);
124   theCommands.Add("xclassify",  "use xclassify Solid [Tolerance=1.e-7]", __FILE__, xclassify, g);
125   
126
127 }
128 //=======================================================================
129 //function : emptyshape
130 //purpose  : shape : shape name V/E/W/F/SH/SO/CS/C
131 //=======================================================================
132 Standard_Integer emptyshape(Draw_Interpretor& , Standard_Integer n, const char** a)
133 {
134   if (n <= 1) return 1;
135
136   BRep_Builder B;
137   TopoDS_Shape S;
138
139   if (n == 3) {
140     TCollection_AsciiString as(a[2]); as.LowerCase();
141     const char* a2 = as.ToCString();
142
143     if      ( ! strcmp(a2,"c") ) {
144       TopoDS_Compound SS; B.MakeCompound(SS); S = SS;
145     }
146     else if ( ! strcmp(a2,"cs") ) {
147       TopoDS_CompSolid SS; B.MakeCompSolid(SS); S = SS;
148     }
149     else if ( ! strcmp(a2,"so") ) {
150       TopoDS_Solid SS; B.MakeSolid(SS); S = SS;
151     }
152     else if ( ! strcmp(a2,"sh") ) {
153       TopoDS_Shell SS; B.MakeShell(SS); S = SS;
154     }
155     else if ( ! strcmp(a2,"f") ) {
156       TopoDS_Face SS; B.MakeFace(SS); S = SS;
157     }
158     else if ( ! strcmp(a2,"w") ) {
159       TopoDS_Wire SS; B.MakeWire(SS); S = SS;
160     }
161     else if ( ! strcmp(a2,"e") ) {
162       TopoDS_Edge SS; B.MakeEdge(SS); S = SS;
163     }
164     else if ( ! strcmp(a2,"v") ) {
165       TopoDS_Vertex SS; B.MakeVertex(SS); S = SS;
166     }
167     else {
168       return 1;
169     }
170   }
171
172   const char *shapename = a[1];
173   DBRep::Set(shapename,S);
174   return 0;
175 }
176
177 //=======================================================================
178 //function : subshape
179 //purpose  : 
180 //=======================================================================
181 Standard_Integer subshape(Draw_Interpretor& di, Standard_Integer n, const char** a)
182 {
183   if (n <= 2) return 1;
184
185   
186   TopoDS_Shape S = DBRep::Get(a[1]);
187   if (S.IsNull()) return 0;
188   char newname[1024];
189   strcpy(newname,a[1]);
190   char* p = newname;
191   while (*p != '\0') p++;
192   *p = '_';
193   p++;
194   Standard_Integer i = 0;
195   if (n == 3) {
196     Standard_Integer isub = Draw::Atoi(a[2]);
197     TopoDS_Iterator itr(S);
198     while (itr.More()) {
199       i++;
200       if ( i == isub ) {
201         Sprintf(p,"%d",i);
202         DBRep::Set(newname,itr.Value());
203         di.AppendElement(newname);
204         break;
205       }
206       itr.Next();
207     }
208   }
209   else {
210     // explode a type
211     TopAbs_ShapeEnum typ;
212     switch (a[2][0]) {
213       
214     case 'C' :
215     case 'c' :
216       typ = TopAbs_COMPSOLID;
217       break;
218       
219     case 'S' :
220     case 's' :
221       if ((a[2][1] == 'O')||(a[2][1] == 'o')) 
222         typ = TopAbs_SOLID;
223       else if ((a[2][1] == 'H')||(a[2][1] == 'h')) 
224         typ = TopAbs_SHELL;
225       else
226         return 1;
227       break;
228       
229     case 'F' :
230     case 'f' :
231       typ = TopAbs_FACE;
232       break;
233       
234     case 'W' :
235     case 'w' :
236       typ = TopAbs_WIRE;
237       break;
238       
239     case 'E' :
240     case 'e' :
241       typ = TopAbs_EDGE;
242       break;
243       
244     case 'V' :
245     case 'v' :
246       typ = TopAbs_VERTEX;
247       break;
248       
249       default :
250         return 1;
251     }
252     
253     Standard_Integer isub = Draw::Atoi(a[3]);
254     TopTools_MapOfShape M;
255     M.Add(S);
256     TopExp_Explorer ex(S,typ);
257     while (ex.More()) {
258       if (M.Add(ex.Current())) {
259         i++;
260         if ( i == isub ) {
261           Sprintf(p,"%d",i);
262           DBRep::Set(newname,ex.Current());
263           di.AppendElement(newname);
264           break;
265         }
266       }
267       ex.Next();
268     }
269   }
270   return 0;
271 }
272 //=======================================================================
273 //function : brepintcs
274 //purpose  : 
275 //=======================================================================
276 Standard_Integer brepintcs(Draw_Interpretor& di, Standard_Integer n, const char** a)
277 {
278   if (n <= 2) 
279   {
280     cout<<"Invalid input arguments. Should be: curve1 [curve2 ...] shape [result] [tol]"<<endl;
281     return 1;
282   }
283   Standard_Integer indshape = 2;
284   TopoDS_Shape S;
285   for( ; indshape <= n-1 ; indshape++)
286   {
287     S = DBRep::Get(a[indshape]);
288     if(!S.IsNull())
289       break;
290   }
291   if (S.IsNull()) 
292   {
293     cout<<"Invalid input shape"<<endl;
294     return 1;
295   }
296
297   BRepIntCurveSurface_Inter theAlg;
298   double tol=1e-6;
299   if( indshape < n-1)
300   {
301     Standard_Real preci = atof(a[n-1]);
302     if(preci >= Precision::Confusion())
303       tol = preci;
304   }
305   int nbpi=0;
306   gp_Pnt curp;
307   TopoDS_Compound aComp;
308   BRep_Builder aB;
309   aB.MakeCompound(aComp);
310   if (indshape == 2) {
311     Handle(Geom_Curve) C= DrawTrSurf::GetCurve(a[1]);
312     if (C.IsNull()) return 2;
313     GeomAdaptor_Curve acur(C);
314     theAlg.Init(S, acur, tol);
315
316     for (; theAlg.More(); theAlg.Next()) {
317       curp=theAlg.Pnt();
318       TopoDS_Vertex aV;
319
320       aB.MakeVertex(aV, curp, 0);
321       aB.Add(aComp, aV);
322       nbpi++;
323       di<<"Point "<<nbpi<<" : "<<curp.X()<<" "<<curp.Y()<<" "<<curp.Z()<<"\n";
324       char name[64];
325       char* temp = name; // pour portage WNT
326       Sprintf(temp, "%s_%d", "brics", nbpi); 
327       DrawTrSurf::Set(temp, curp);
328     }
329   }
330   else {
331     theAlg.Load(S,tol );
332     for (Standard_Integer il = 1; il<indshape ; il++) 
333     {
334       Handle(Geom_Curve) hl= DrawTrSurf::GetCurve(a[il]);
335       if (!hl.IsNull()) {
336         theAlg.Init(hl);
337         for (; theAlg.More(); theAlg.Next()) {
338           curp=theAlg.Pnt();
339           nbpi++;
340           TopoDS_Vertex aV;
341           aB.MakeVertex(aV, curp, 0);
342           aB.Add(aComp, aV);
343           di<<"Point "<<nbpi<<" : "<<curp.X()<<" "<<curp.Y()<<" "<<curp.Z()<<"\n";
344           char name[64];
345           char* temp = name; // pour portage WNT
346           Sprintf(temp, "%s_%d", "brics", nbpi); 
347           DrawTrSurf::Set(temp, curp);
348         }
349       }
350     }
351   }
352   if(!nbpi)
353     di<<"Points of intersections are not found\n";
354   if(indshape < n-1)
355     DBRep::Set(a[n-1], aComp);
356   //POP pour NT
357   return 0;
358 }
359 //=======================================================================
360 //function : MakeBoss
361 //purpose  : 
362 //=======================================================================
363 Standard_Integer MakeBoss(Draw_Interpretor& , Standard_Integer , const char** a)
364 {
365   TopoDS_Shape myS = DBRep::Get( a[2] );
366
367   TopoDS_Shape myBasis = DBRep::Get( a[3] ) ;
368
369   Standard_Real ang = -0.05235987901687622;
370
371
372   TopoDS_Face basis = TopoDS::Face(myBasis);
373
374   BRepFeat_MakeDPrism DPRISM(myS, basis, basis, ang, 1, Standard_True);
375
376   TopoDS_Shape myFaceOnShape;
377   gp_Pnt Pnt(0.0, 0.0, 50.0);
378   gp_Dir Dir(-0.0, -0.0, -1.0);
379   gp_Ax1 ax(Pnt, Dir);
380   
381   myFaceOnShape = NextFaceForPrism(myS, myBasis, ax);
382
383   DPRISM.Perform (myFaceOnShape);
384   DPRISM.Build();
385
386   if( DPRISM.IsDone() )  DBRep::Set( a[1], DPRISM.Shape() );
387
388   return 0;
389 }
390 //=======================================================================
391 //function : MakeShell
392 //purpose  : 
393 //=======================================================================
394 Standard_Integer MakeShell(Draw_Interpretor& , Standard_Integer , const char** a)
395 {
396
397   TopoDS_Shape aShape = DBRep::Get( a[1] ); 
398   TopTools_ListOfShape Lst;
399   TopExp_Explorer Exp(aShape, TopAbs_FACE);
400   TopoDS_Shape InputShape(DBRep::Get( a[2] ));
401   TopoDS_Face F = TopoDS::Face(InputShape);
402 //  TopoDS_Face F = TopoDS::Face(DBRep::Get( a[2] ));
403   
404   Standard_Real Off = -Draw::Atof( a[3] );
405
406   BRepOffset_MakeOffset Offset;
407
408   Offset.Initialize( aShape, Off,  1.0e-3, BRepOffset_Skin, 
409                                Standard_True , Standard_False , GeomAbs_Arc );
410   Offset.AddFace( F );
411   Offset.MakeThickSolid();
412
413   if( Offset.IsDone() ) {
414   //    SaveShape::Save(Offset.Shape(), "ss");
415     DBRep::Set( a[1], Offset.Shape() );
416   }
417   return 0;
418 }
419 //=======================================================================
420 //function : xbounds
421 //purpose  : 
422 //=======================================================================
423 Standard_Integer xbounds(Draw_Interpretor& di, Standard_Integer n, const char** a)
424 {
425   if (n<2) {
426     di << "Usage : " << a[0] << " face\n";
427     return 0;
428   }
429   //
430  
431   Standard_Real aUMin, aUMax, aVMin, aVMax;
432   TopoDS_Shape aS;
433   TopoDS_Face aF;
434   //
435   aS=DBRep::Get(a[1]);
436   if (aS.IsNull()) {
437     di << " null shapes is not allowed here\n";
438     return 0;
439   }
440   if (aS.ShapeType()!=TopAbs_FACE) {
441     di << " shape" << a[1] <<" must be a face\n";
442     return 0;
443   }
444   //
445   aF=*((TopoDS_Face*)&aS);
446   //
447   BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
448   //
449   TCollection_AsciiString aStr;
450   TCollection_AsciiString sUMin(aUMin);
451   TCollection_AsciiString sUMax(aUMax);
452   TCollection_AsciiString sVMin(aVMin);
453   TCollection_AsciiString sVMax(aVMax);
454   //
455   aStr=aStr+sUMin + "\n";
456   aStr=aStr+sUMax + "\n";
457   aStr=aStr+sVMin + "\n";
458   aStr=aStr+sVMax + "\n";
459   di <<aStr.ToCString();
460   //
461   return 0;
462 }
463 //=======================================================================
464 //function : xclassify
465 //purpose  : 
466 //=======================================================================
467 Standard_Integer xclassify (Draw_Interpretor& aDI, Standard_Integer n, const char** a)
468 {
469   if (n < 2) {
470     aDI<<" use xclassify Solid [Tolerance=1.e-7]\n";
471     return 1;
472   }
473   
474   TopoDS_Shape aS = DBRep::Get(a[1]);
475   if (aS.IsNull()) {
476     aDI<<" Null Shape is not allowed here\n";
477     return 0;
478   }
479   
480   if (aS.ShapeType()!=TopAbs_SOLID) {
481     aDI<< " Shape type must be SOLID\n";
482     return 0;
483   }
484   //
485   Standard_Real aTol=1.e-7;
486   TopAbs_State aState = TopAbs_UNKNOWN;
487   //
488   aTol=1.e-7; 
489   if (n==3) {
490     aTol=Draw::Atof(a[2]);
491   }
492   //
493   BRepClass3d_SolidClassifier aSC(aS);
494   aSC.PerformInfinitePoint(aTol);
495   
496   aState = aSC.State();
497   PrintState(aDI, aState);
498   //
499   return 0;
500 }
501 //=======================================================================
502 //function : PrintState
503 //purpose  : 
504 //=======================================================================
505 void PrintState (Draw_Interpretor& aDI, 
506                  const TopAbs_State& aState)
507 {
508   aDI<<"state is: ";
509   switch (aState) {
510   case TopAbs_IN:
511     aDI<<"IN\n"; 
512     break;
513   case TopAbs_OUT:
514     aDI<<"OUT\n";               
515     break;
516   case TopAbs_ON:        
517     aDI<<"ON\n";        
518     break;
519   case TopAbs_UNKNOWN:
520   default:
521     aDI<<"UNKNOWN\n";           
522     break;
523   }
524 }
525 //=======================================================================
526 //function : NextFaceForPrism
527 //purpose  : Search a face from <shape> which intersects with a line of
528 //           direction <ax1> and location a point of <basis>.
529 //=======================================================================
530 TopoDS_Face NextFaceForPrism (const TopoDS_Shape& shape, 
531                               const TopoDS_Shape& basis,
532                               const gp_Ax1&       ax1)
533 {
534   TopoDS_Face nextFace;
535
536   TColgp_SequenceOfPnt seqPnts;
537   SampleEdges(basis, seqPnts);
538   
539   for (Standard_Integer i=1; i<=seqPnts.Length(); i++) {
540     const gp_Pnt& pt = seqPnts(i);
541     // find a axis through a face
542     gp_Dir dir = ax1.Direction();
543     gp_Ax1 ax1b(pt, dir);
544     
545     LocOpe_CSIntersector ASI(shape);
546     LocOpe_SequenceOfLin slin;
547     slin.Append(ax1b);
548     ASI.Perform(slin);
549     
550     if (ASI.IsDone()) {
551       Standard_Integer no=1, IndFrom, IndTo;
552       TopAbs_Orientation theOr;
553       Standard_Real min = 1.e-04, Tol = -Precision::Confusion();
554       if (ASI.LocalizeAfter (no, min, Tol, theOr, IndFrom, IndTo))  {
555         nextFace = ASI.Point(no, IndFrom).Face();  
556         break;
557       }
558     }
559   }
560   
561   return nextFace;
562 }
563
564
565 //=======================================================================
566 //function : SampleEdges
567 //purpose  : Sampling of <theShape>.
568 //design   : Collect the vertices and points on the edges
569 //=======================================================================
570 void SampleEdges (const TopoDS_Shape&   theShape, TColgp_SequenceOfPnt& theSeq)
571 {
572
573   theSeq.Clear();
574
575    
576   TopTools_MapOfShape theMap;
577   TopExp_Explorer exp;
578   
579   // Adds all vertices/pnt
580   for (exp.Init(theShape,TopAbs_VERTEX); exp.More(); exp.Next()) {
581     if (theMap.Add(exp.Current())) {
582       theSeq.Append (BRep_Tool::Pnt(TopoDS::Vertex(exp.Current())));
583     }
584   }
585
586   // Computes points on edge, but does not take the extremities into account
587   Standard_Integer NECHANT = 5;
588   Handle(Geom_Curve) C;
589   Standard_Real f,l,prm;
590   for (exp.Init (theShape,TopAbs_EDGE); exp.More(); exp.Next()) {
591     const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
592     if (theMap.Add(edg)) {
593       if (!BRep_Tool::Degenerated(edg)) {
594         C = BRep_Tool::Curve(edg,f,l);
595         for (Standard_Integer i=1; i < NECHANT; i++) {
596           prm = ((NECHANT-i)*f+i*l)/NECHANT;
597           theSeq.Append (C->Value(prm));
598         }
599       }
600     }
601   }
602 }
603